You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
#lockdown nick.penwarden ========================== MAJOR FEATURES + CHANGES ========================== Change 3006483 on 2016/06/08 by Simon.Tovey Fix for UE-31653 Instance params from the Spawn, Required and TypeData modules were not being autopopulated. Change 3006514 on 2016/06/08 by Zabir.Hoque MIGRATING FIX @ Request Off by 1 error on reflection roughness calculation affecting 4.12. When I hoisted the max mip index i did a -1 on both sides(c++ & hlsl). This is the simplest hotfix. In 4.13 I'll remove the shader instruction and only do the "-1" in c++ this 1 less shader instruction. #CodeReview: Marcus.Wassmer, Daniel.Wright Change 3006605 on 2016/06/08 by Rolando.Caloca DR - vk - Remove a bunch of unused code, clean up some todos Change 3006969 on 2016/06/08 by HaarmPieter.Duiker Add #ifdefs around inverse tonemapping to avoid performance hit in normal use Change 3007240 on 2016/06/09 by Chris.Bunner Made a pass at fixing global shader compile warnings and errors. Change 3007242 on 2016/06/09 by Chris.Bunner Don't force unlit mode when re-loading a map. #jira UE-31247 Change 3007243 on 2016/06/09 by Chris.Bunner Cache InvalidLightmapSettings material for instanced meshes. #jira UE-31182 Change 3007258 on 2016/06/09 by Chris.Bunner Fixed refractive depth bias material parameter. Change 3007466 on 2016/06/09 by Rolando.Caloca DR - Use vulkan debug marker extension directly from header Change 3007504 on 2016/06/09 by Martin.Mittring added refresh button to ImageVerifier Change 3007528 on 2016/06/09 by Martin.Mittring ALU optimization to SSR, minor perf difference on NVTitan, needs to to be profiled on lower end make render more deterministic Change 3007551 on 2016/06/09 by Chris.Bunner Reverted constant type change in previous commit. Change 3007559 on 2016/06/09 by Martin.Mittring updated ImageValidator Change 3007584 on 2016/06/09 by Rolando.Caloca DR - Fix case when not running under RD Change 3007668 on 2016/06/09 by Rolando.Caloca DR - vk - Split layers/extensions by required/optional Change 3007820 on 2016/06/09 by Rolando.Caloca DR - Android compile fix Change 3007926 on 2016/06/09 by Martin.Mittring fixed UI scaling in ImageVerifyer Change 3007931 on 2016/06/09 by John.Billon -Fixed cutouts not working for certain sized texture/subUV size combinations. -Also fixed issue with subUV module not being postloaded consistently on startup. #Jira UE-31583 Change 3008023 on 2016/06/09 by Martin.Mittring refactor noise code in shaders Change 3008127 on 2016/06/09 by Zabir.Hoque Merging back hot fixes: 1. Fix DX12 crashing due to oclusion queries waiting on incorrect sync point. Integrating change from MS. 2. Immediate context should flush directly and not attempt to flush the immediate context, ie. itself. Change 3008129 on 2016/06/09 by Daniel.Wright Disabled r.ProfileGPU.PrintAssetSummary by default due to spam Change 3008169 on 2016/06/09 by Rolando.Caloca DR - Fix mobile rendering not freeing resource when using RHI thread Change 3008429 on 2016/06/09 by Uriel.Doyon Enabled texture streaming new metrics. Added progress bar while texture streaming is being built. Added debug shader validation to prevent crashes when there are uniform expression set mismatches. Added texture streaming build to "Build All" Change 3008436 on 2016/06/09 by Uriel.Doyon Fixed shipping build Change 3008833 on 2016/06/10 by Rolando.Caloca DR - Allow RenderTargets to be easily shared via GPU to other DX or OpenGL applications Submitted by Allar PR #1864 #jira UE-24545 Change 3008842 on 2016/06/10 by Rolando.Caloca DR - Remove vertex densities view mode Change 3008857 on 2016/06/10 by John.Billon Added a PostLoad to ParticleModuleSubUV to call postload on the SubUV animation to ensure that the animation is loaded in time for caching. Change 3008870 on 2016/06/10 by Rolando.Caloca DR - Rebuild hlslcc libs (missing from last merge) Change 3008925 on 2016/06/10 by John.Billon Fixed r.ScreenPercentage.Editor #Jira UE-31549 Change 3009028 on 2016/06/10 by Daniel.Wright Shadow depth refactor * Shadow setup and render target allocation now happens in InitViews, and shadow depth rendering happens at one spot in the frame * This provides control over where shadow depths are rendered for things like async compute, and allows easy atlasing of shadowmaps for forward shading * The 33Mb of shadow depth buffers in FSceneRenderTargets has been removed, and shadow depth buffers are now allocated as needed * A large amount of duplicated code to handle each shadow type has been combined * Cleaner parallel rendering: no more view hacking for the shadow depth pass, no more shadow depths in the middle of translucency * 'vis ShadowDepthAtlas' or 'vis WholeSceneShadowMap' must now be used to visualize the shadow depth textures Change 3009032 on 2016/06/10 by Daniel.Wright Fixed crash with simple forward shading in the material editor Change 3009178 on 2016/06/10 by Rolando.Caloca DR - Add support for multi callbacks on HlslParser, added a write to string callback Change 3009268 on 2016/06/10 by Daniel.Wright Warning fixes Change 3009416 on 2016/06/10 by Martin.Mittring moved decal rendering code in common spot for upcoming MeshDecal rendering Change 3009433 on 2016/06/10 by John.Billon Adding ensures for translucency lighting volume render target acesses. #Jira UE-31578 Change 3009449 on 2016/06/10 by Daniel.Wright Fixed whole scene point light shadow depths getting rendered redundantly Change 3009675 on 2016/06/10 by Martin.Mittring fixed Clang compiling Change3009815on 2016/06/10 by Martin.Mittring renamed IsUsedWithDeferredDecal to IsDeferredDecal to be more correct Change 3009946 on 2016/06/10 by Martin.Mittring minor optimization Change 3010270 on 2016/06/11 by HaarmPieter.Duiker Update gamut transformations used when dumping EXRs to account for bug UE-29935 Change 3011423 on 2016/06/13 by Martin.Mittring fixed default of bOutputsVelocityInBasePass #code_review:Rolando.Caloca #test:PC Change 3011448 on 2016/06/13 by Martin.Mittring minor engine code cleanup #code_review:Olaf.Piesche #test:PC Change 3011991 on 2016/06/13 by Daniel.Wright Fixed downsampled translucency crash in VR Change 3011993 on 2016/06/13 by Daniel.Wright Stationary Mobility for primitive components is allowed again, with the meaning 'moves rarely' Mobility tooltips now reflect whether a primitive component or light component is being inspected Change 3012096 on 2016/06/13 by Daniel.Wright Missing file from cl 3011993 Change 3012546 on 2016/06/14 by John.Billon Added r.ContactShadows.Enable CVar to allow contact shadows to be globally disabled/enabled #Jira OR-23282 Change 3012706 on 2016/06/14 by John.Billon Renamed r.ContactShadows.Enable to r.ContactShadows Change 3012992 on 2016/06/14 by Rolando.Caloca DR - vk - Fixed backbuffer/swapchain order with RHI thread enabled - Added support for CustomPresent Change 3013030 on 2016/06/14 by Rolando.Caloca DR - vk - Fix dev issue Change 3013423 on 2016/06/14 by Martin.Mittring removed code redundancy for easier upcoming changes #test:PC Change 3013451 on 2016/06/14 by Martin.Mittring removed no longer needed debug cvar #test:PC Change 3013643 on 2016/06/14 by Zabir.Hoque Fix API only being inlined in the cpp and not avaialble in the .h Change 3013696 on 2016/06/14 by Olaf.Piesche Adding missing quality level spawn rate scaling on GPU emitters Change 3013736 on 2016/06/14 by Daniel.Wright Cached shadowmaps for whole scene point and spot light shadows * Controlled by 'r.Shadow.CacheWholeSceneShadows', defaults to enabled (7ms -> 1.5ms of shadow depths on Titan for ~20 lights) * Primitives with Static or Stationary mobility have their depths cached, as long as the light is not moving * Primitives with Movable mobility or using World Position Offset in their materials will not have their depths cached * Cached shadowmaps are copied each frame and then movable primitive depths composited * Fast paths exist for when there were no static primitives (skip cached shadowmap) or movable primitives (project directly from cached shadowmap) * 'r.Shadow.CacheWPOPrimitives' controls whether materials using WPO can be cached (default is off for correctness) * 'r.Shadow.CachedShadowsCastFromMovablePrimitives' can be used to force off all support for movable primitives, skipping the shadowmap copies (1.5ms -> 0ms of shadow depths for ~20 lights) Change 3014103 on 2016/06/15 by Daniel.Wright Compile fix Change 3014507 on 2016/06/15 by Simon.Tovey Resurrected Niagara playground and moved to Samples/NotForLicencees Change 3014931 on 2016/06/15 by Martin.Mittring moved r.RenderInternals code into renderer to be able to access more low level data #test:PC, paragon Change 3014933 on 2016/06/15 by Martin.Mittring nicer text Change 3014956 on 2016/06/15 by Daniel.Wright Fixed HLOD and mesh LODs getting hit by Lightmass ray traces that didn't originate from a mesh Volume lighting samples and precomputed visibility cells are now only placed on LOD0 (of both mesh LODs and HLOD) Change 3014985 on 2016/06/15 by Uriel.Doyon Enabled Texture Build shaders on Mac Exposed IStreamingManager::AddViewSlaveLocation in ENGINE_API Fixed issue FStreamingManagerTexture::ConditionalUpdateStaticData which would to update some data in shipping. Fixed r.Streaming.MipBias not affecting maximum allowed resolution, showing warnings of texture streaming overbudgets #jira UE-30566 #jira UE-31098 Change 3014995 on 2016/06/15 by Rolando.Caloca DR - vk - Removed RHI thread wait on acquire image - Move Descriptor pool into context Change 3015002 on 2016/06/15 by Rolando.Caloca DR - Add (disabled) additional cvar for r.DumpShaderDebugWorkerCommandLine Change 3015041 on 2016/06/15 by Martin.Mittring fixed ImageValidator crashing when using files that exist only in ref or test folder Change 3015309 on 2016/06/15 by Rolando.Caloca DR - vk - Enable fence re-use on SDKs >= 1.0.16.0 Change 3015356 on 2016/06/15 by Rolando.Caloca DR - vk - Prep for staging buffer refactor Change 3015430 on 2016/06/15 by Martin.Mittring minor optimization for subsurfacescatteringprofile Change 3016097 on 2016/06/16 by Simon.Tovey Enabling Niagara by default in the Niagara playground Change 3016098 on 2016/06/16 by Simon.Tovey Some misc fixup to get niagara working again Change 3016183 on 2016/06/16 by Rolando.Caloca DR - vk - Recreate buffer view for volatile buffers Change 3016225 on 2016/06/16 by Marcus.Wassmer Duplicate reflection fixes from 4.12 hotfixes. Change3016289on 2016/06/16 by Chris.Bunner Always gather MP_Normal definitions as they can be shared by other material properties. #jira UE-31792 Change 3016294 on 2016/06/16 by Daniel.Wright Fix for ensure accessing CVarCacheWPOPrimitives in game Change 3016305 on 2016/06/16 by Daniel.Wright Raised r.Shadow.CSM.MaxCascades to 10 on Epic scalability level, which it should have always been Change 3016330 on 2016/06/16 by Daniel.Wright Cached shadowmaps are tossed after 5s of not being used for rendering - helps in the case where you fly through a bunch of lights and never look back Skipping shadow depth cubemap clear if there will be a cached shadowmap copy later - saves .4ms on PS4 for a close up point light Stats for shadowmap memory used under 'stat shadowrendering' Change 3016506 on 2016/06/16 by Daniel.Wright Fixed crash building map in SunTemple due to null access Change 3016703 on 2016/06/16 by Uriel.Doyon Fixed warning due to floating point imprecision when building texture streaming Change 3016718 on 2016/06/16 by Daniel.Wright Volume lighting samples use adaptive sampling final gather * Increases their build time by 2x but improves quality in difficult cases (small bright sources of bounce lighting) Change 3016871 on 2016/06/16 by Max.Chen Sequencer: Added support for the named "PerformanceCapture" event which like Matinee, calls GEngine->PerformanceCapture to output a screenshot when the event fires. Refactor event track/sections so that the player is passed to the trigger events evaluation. Copy from Dev-Sequencer #jira UE-32093 Change 3017189 on 2016/06/16 by Zabir.Hoque Fix GBuffer format selection type-o. #CodeReview: Marcus.Wassmer Change 3017241 on 2016/06/16 by Martin.Mittring optimized and cleaned up rendering in transluceny, distortion, custom mesh drawing #code_review:Daniel.Wright, Marcus.Wassmer, Nick.Penwarden Change 3017856 on 2016/06/17 by Rolando.Caloca DR - Missing GL enum Change 3017910 on 2016/06/17 by Ben.Woodhouse - Added a Video Buffer to ensure smooth submission of frames from CEF. Without this, we can get multiple texture updates per engine frame, which causes stuttering at high framerates - Disable hardware acceleration on Windows, since this causes severe performance issues with video rendering Please note: To actually see 60fps video, you need to ensure the browser frame rate passed into FWebBrowserSingleton::CreateBrowserWindow is set to 60 (default is 24) #RB:Keli.Hloedversson,Martin.Mittring Change 3018126 on 2016/06/17 by Ben.Woodhouse Fix build warning on Mac #RB:David.Hill Change 3018167 on 2016/06/17 by Chris.Bunner Handle case when float4 is passed to TransformPosition material node. #jira UE-24980 Change 3018246 on 2016/06/17 by Benjamin.Hyder Submitting Preliminary ShadowRefactor TestMap Change 3018330 on 2016/06/17 by Benjamin.Hyder labeled ShadowRefactor map Change 3018377 on 2016/06/17 by Chris.Bunner Removed additional node creation when initializing a RotateAboutAxis node. #jira UE-8034 Change 3018433 on 2016/06/17 by Rolando.Caloca DR - Fix some clang warnings on Vulkan Change 3018664 on 2016/06/17 by Martin.Mittring unified some code for easier maintainance, fixed missing multiply from former change (CL 2933812) #test:PC #code_review:Marcus.Wassmer,Brian.Karis Change 3019023 on 2016/06/19 by Benjamin.Hyder Re-Labeled ShadowRefactor map Change 3019024 on 2016/06/19 by Benjamin.Hyder Correcting Translucent Volume (Non-Directional) settings Change 3019026 on 2016/06/19 by Benjamin.Hyder Correcting Lighting ShadowRefactor map Change 3019414 on 2016/06/20 by Allan.Bentham Refactor mobile shadows Change 3019494 on 2016/06/20 by Gil.Gribb Merging //UE4/Dev-Main@3018959 to Dev-Rendering (//UE4/Dev-Rendering) Change 3019504 on 2016/06/20 by John.Billon -Created a blueprint node (ExportRenderTarget and ExportTexture2D) to export render targets/textures as HDR images to disk. -Moved HDR export code(FHDRExportHelper and CubemapUnwrapUtils) to runtime from editor to allow access from blueprints. -Created a small common interface for blueprints and the editor itself to use for exporting. #Jira UE-31429 Change 3019561 on 2016/06/20 by Gil.Gribb UE4 - Worked around afulness of windows scheduler. This would occasionally cause hitches on quad core machines with additional load in the tick task manager. Change 3019616 on 2016/06/20 by Rolando.Caloca DR - Replicate change in DevRendering to fix splotches on characters with morph targets Change: 3019599 O - Fix flickering on heroes with morph targets Change 3019627 on 2016/06/20 by Rolando.Caloca DR - Doh! Compile fix Change 3019674 on 2016/06/20 by Simon.Tovey Ripped out the quick hacky VM debugger I wrote a while back. Over complicated the VM and didn't do enough work to justify it. Will revisit debugging and profiling of VM scripts in future. Change 3019691 on 2016/06/20 by Ben.Woodhouse Add a per-object shadow setting for directional lights (r.Shadow.PerObjectDirectionalDepthBias), which is independent of the CSM setting. Often a smaller bias is desirable on per-object shadows, where detailed self-shadowing is needed. This change also makes the CSM naming consistent with what the setting actually does (the old setting was named r.shadow.csm, although it affects per-object shadows as well as CSMs). #RB:Martin.Mittring, Daniel.Wright Change 3019741 on 2016/06/20 by John.Billon Fixed compile error on mac. Change 3019984 on 2016/06/20 by Martin.Mittring minor optimization Change 3020172 on 2016/06/20 by Zachary.Wilson Fixing mesh distance fields for engine content cube and cylinder by setting distance field resolution to 2. for UE-26783 #rb: none Change 3020195 on 2016/06/20 by Zachary.Wilson Fixing engine coontent sphere's distance fields for UE-26783, distance fields resolution set to 2. #rb: none Change 3020196 on 2016/06/20 by Rolando.Caloca DR - Appease static analysis Change 3020231 on 2016/06/20 by Zachary.Wilson Making basic shapes consistent distance field resolution scale. #rb: none Change 3020468 on 2016/06/20 by David.Hill CameraWS UE-29146 Change 3020502 on 2016/06/20 by Benjamin.Hyder Adding AutomationMatinee Camera for RenderOutputValidation Change 3020508 on 2016/06/20 by Benjamin.Hyder Adding AutomationMatinee for RenderOutputValidation Change 3020514 on 2016/06/20 by Benjamin.Hyder Setting Autoplay for AutomationMatinee (sequence) Change3020561on 2016/06/20 by Daniel.Wright Removed outdated comment on uniform expression assert Change 3021268 on 2016/06/21 by Daniel.Wright Scaled sphere intersection for indirect capsule shadows * Fixes the discontinuity when capsule axis points close to the light direction * GPU cost is effectively the same (more expensive to compute, but tighter culling) Change 3021325 on 2016/06/21 by Daniel.Wright Split ShadowRendering.cpp into ShadowDepthRendering.cpp Change 3021355 on 2016/06/21 by Daniel.Wright Fixed RTDF shadows (broken by shadowmap caching) Change 3021444 on 2016/06/21 by Daniel.Wright Fixed crash due to Depth drawing policy not using the default material shader map properly Change 3021543 on 2016/06/21 by Daniel.Wright Fixed drawing to a Canvas after EndDrawCanvasToRenderTarget causing a crash Fixed DrawMaterialToRenderTarget breaking the Canvas object that BeginDrawCanvasToRenderTarget returns Change 3021749 on 2016/06/21 by Daniel.Wright Moved RenderBasePass and dependencies into BasePassRendering.cpp Moved RenderPrePass and dependencies into DepthRendering.cpp Change 3021766 on 2016/06/21 by Benjamin.Hyder Adding 150dynamiclights level to Dev-Folder Change 3021971 on 2016/06/21 by Daniel.Wright Removed the CPU-culled light grid which is used to implement TLM_SurfacePerPixelLighting, in preparation for a GPU-culled light grid implementation * TLM_SurfacePerPixelLighting now behaves like TLM_Surface Change 3022760 on 2016/06/22 by Chris.Bunner Merge fixup. Change 3022911 on 2016/06/22 by Rolando.Caloca DR - Added r.D3DDumpD3DAsmFile to enable dumping the fxc disassembly when dumping shaders Change 3023037 on 2016/06/22 by Rolando.Caloca DR - Fix for the case of global destructors calling FlushRenderingCommands() after the RHI has been destroyed Change 3023139 on 2016/06/22 by Daniel.Wright Added on screen message for when VisualizeMeshDistanceFields is requested but engine scalability settings have DFAO disabled Change 3023231 on 2016/06/22 by Daniel.Wright Only allowing opaque per-object shadows or CSM in the mobile renderer Change 3023415 on 2016/06/22 by Daniel.Wright Fix crash in dx12 trying to clear stencil when there is no stencil in the depth target Change 3024888 on 2016/06/23 by Daniel.Wright Fixed preshadows being rendered redundantly with multiple lights Change 3025119 on 2016/06/23 by Martin.Mittring added MeshDecal content to RenderTest Change 3025122 on 2016/06/23 by Martin.Mittring enabled DBuffer for RenderTest Change 3025153 on 2016/06/23 by Marc.Olano Fix Spherical Particle Opacity. Particles using this stopped rendering sometime after 4.10. Needed to use world space without shader offsets, not absolute world space. Change 3025180 on 2016/06/23 by Marc.Olano Use translated world space for particle centers. Better fix for Spherical Particle Opacity problems, but with fingers in more pies. Includes rename of particle center vertex factory variables. Change 3025265 on 2016/06/23 by David.Hill Bilbords translucent during PIE - lighting model was incorrectly set in gbuffer #jira UE-26165 Change 3025269 on 2016/06/23 by Ryan.Brucks Adding new Testmap for Pixel Depth Offset velocities with Temporal AA Change 3025345 on 2016/06/23 by Benjamin.Hyder Submitting MeshDecal Content Change 3025444 on 2016/06/23 by Benjamin.Hyder updating content for MeshDecal Change 3025491 on 2016/06/23 by Benjamin.Hyder Updating DecalMesh Textures Change 3025802 on 2016/06/23 by Martin.Mittring added to readme Change 3026475 on 2016/06/24 by Rolando.Caloca DR - Show current state of r.RHIThread.Enable when not using param Change 3026479 on 2016/06/24 by Rolando.Caloca DR - Upgrade glslang to 1.0.17.0 Change 3026480 on 2016/06/24 by Rolando.Caloca DR - Vulkan headers to 1.0.17.0 Change 3026481 on 2016/06/24 by Rolando.Caloca DR - Vulkan wrapper for extra logging Change 3026491 on 2016/06/24 by Rolando.Caloca DR - Missed file Change 3026574 on 2016/06/24 by Rolando.Caloca DR - vk - Enabled fence reuse on 1.0.17.0 - Added more logging info Change 3026656 on 2016/06/24 by Frank.Fella Niagara - Prevent sequencer uobjects from being garbage collected. Change 3026657 on 2016/06/24 by Benjamin.Hyder Updating Rendertestmap to latest Change 3026723 on 2016/06/24 by Rolando.Caloca DR - Fix for ES3.1 RHIs Change 3026784 on 2016/06/24 by Martin.Mittring New feature: Mesh Decals / Material layers (Chris.Bunner is the goto person on MeshDecals from now on) Change 3026866 on 2016/06/24 by Olaf.Piesche #jira OR-18363 #jira UE-27780 fix distortion in particle macro uvs [CL 3028922 by Gil Gribb in Main branch]
616 lines
23 KiB
Plaintext
616 lines
23 KiB
Plaintext
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
|
|
|
|
/*==============================================================================
|
|
ParticleSimulationShader.usf: Shaders for simulating particles on the GPU.
|
|
==============================================================================*/
|
|
|
|
#include "Common.usf"
|
|
|
|
#if DISTANCE_FIELD_COLLISION
|
|
#include "GlobalDistanceFieldShared.usf"
|
|
#endif
|
|
|
|
#define IMPROVED_DEPTH_BUFFER_COLLISION 1
|
|
|
|
/*------------------------------------------------------------------------------
|
|
Shared declarations and functions.
|
|
------------------------------------------------------------------------------*/
|
|
|
|
struct FShaderInterpolants
|
|
{
|
|
/** The texture coordinate at which to sample. */
|
|
float2 TexCoord : TEXCOORD0;
|
|
};
|
|
|
|
/*------------------------------------------------------------------------------
|
|
Vertex shader.
|
|
|
|
Compile time parameters:
|
|
TILE_SIZE_X - The width of a particle tile in the texture.
|
|
TILE_SIZE_Y - The height of a particle tile in the texture.
|
|
------------------------------------------------------------------------------*/
|
|
#if VERTEXSHADER
|
|
|
|
struct FVertexInput
|
|
{
|
|
/** Unique vertex ID. */
|
|
uint VertexId : SV_VertexID;
|
|
/** Unique instance ID. */
|
|
uint InstanceId : SV_InstanceID;
|
|
/** The texture coordinate. */
|
|
float2 TexCoord : ATTRIBUTE0;
|
|
};
|
|
|
|
/** Buffer from which to read tile offsets. */
|
|
Buffer<float2> TileOffsets;
|
|
|
|
void VertexMain(
|
|
in FVertexInput Input,
|
|
out FShaderInterpolants Interpolants,
|
|
out float4 OutPosition : SV_POSITION
|
|
)
|
|
{
|
|
uint InstanceId = Input.InstanceId * TILES_PER_INSTANCE + Input.VertexId / 4;
|
|
|
|
float2 TileCoord = Input.TexCoord.xy * float2(TILE_SIZE_X,TILE_SIZE_Y) + TileOffsets[InstanceId];
|
|
|
|
OutPosition = float4(
|
|
TileCoord.xy * float2(2.0f,-2.0f) + float2(-1.0f,1.0f),
|
|
0,
|
|
1
|
|
);
|
|
Interpolants.TexCoord.xy = TileCoord.xy;
|
|
}
|
|
|
|
#endif // #if VERTEXSHADER
|
|
|
|
/*------------------------------------------------------------------------------
|
|
Particle simulation pixel shader.
|
|
------------------------------------------------------------------------------*/
|
|
#if PARTICLE_SIMULATION_PIXELSHADER
|
|
|
|
/** Define to 1 to force no collision in the shader. */
|
|
#define FORCE_NO_COLLISION 0
|
|
|
|
#if FORCE_NO_COLLISION || FEATURE_LEVEL < FEATURE_LEVEL_SM4
|
|
#undef DEPTH_BUFFER_COLLISION
|
|
#define DEPTH_BUFFER_COLLISION 0
|
|
#undef DISTANCE_FIELD_COLLISION
|
|
#define DISTANCE_FIELD_COLLISION 0
|
|
#endif
|
|
|
|
/** Position (XYZ) and squared radius (W) of the point attractor. */
|
|
float4 PointAttractor;
|
|
/** Position offset (XYZ) to add to particles and strength of the attractor (W). */
|
|
float4 PositionOffsetAndAttractorStrength;
|
|
/** Amount by which to scale bounds for collision purposes. */
|
|
float2 LocalToWorldScale;
|
|
/** Amount of time by which to simulate particles. */
|
|
float DeltaSeconds;
|
|
/** Number of iterations, each applying DeltaSeconds. */
|
|
int NumIterations;
|
|
|
|
/** Texture from which to read particle position. */
|
|
Texture2D PositionTexture;
|
|
SamplerState PositionTextureSampler;
|
|
|
|
/** Texture from which to read particle velocity. */
|
|
Texture2D VelocityTexture;
|
|
SamplerState VelocityTextureSampler;
|
|
/** Texture from which to read particle attributes. */
|
|
Texture2D AttributesTexture;
|
|
SamplerState AttributesTextureSampler;
|
|
/** Texture from which curves can be sampled. */
|
|
Texture2D CurveTexture;
|
|
SamplerState CurveTextureSampler;
|
|
|
|
/** Textures from which to sample vector forces. */
|
|
#if MAX_VECTOR_FIELDS != 4
|
|
#error This must match MAX_VECTOR_FIELDS in C++ land
|
|
#endif
|
|
Texture3D VectorFieldTextures0;
|
|
Texture3D VectorFieldTextures1;
|
|
Texture3D VectorFieldTextures2;
|
|
Texture3D VectorFieldTextures3;
|
|
//Texture3D VectorFieldTextures4;
|
|
//Texture3D VectorFieldTextures5;
|
|
//Texture3D VectorFieldTextures6;
|
|
//Texture3D VectorFieldTextures7;
|
|
//Texture3D VectorFieldTextures8;
|
|
//Texture3D VectorFieldTextures9;
|
|
|
|
SamplerState VectorFieldTexturesSampler0;
|
|
SamplerState VectorFieldTexturesSampler1;
|
|
SamplerState VectorFieldTexturesSampler2;
|
|
SamplerState VectorFieldTexturesSampler3;
|
|
//SamplerState VectorFieldTexturesSampler4;
|
|
//SamplerState VectorFieldTexturesSampler5;
|
|
//SamplerState VectorFieldTexturesSampler6;
|
|
//SamplerState VectorFieldTexturesSampler7;
|
|
//SamplerState VectorFieldTexturesSampler8;
|
|
//SamplerState VectorFieldTexturesSampler9;
|
|
|
|
/**
|
|
* Computes the orbit velocity to apply to the particle based on time.
|
|
* @param Time - The time at which to evaluate the velocity.
|
|
* @param RandomOrbit - Random value used to add variation to orbit.
|
|
*/
|
|
float3 ComputeOrbitVelocity(float Time, float RandomOrbit)
|
|
{
|
|
float3 Sines, Cosines;
|
|
|
|
// Read parameters.
|
|
const float3 Offset = Simulation.OrbitOffsetBase.xyz + Simulation.OrbitOffsetRange.xyz * RandomOrbit;
|
|
const float3 Frequency = Simulation.OrbitFrequencyBase.xyz + Simulation.OrbitFrequencyRange.xyz * RandomOrbit;
|
|
const float3 Phase = Simulation.OrbitPhaseBase.xyz + Simulation.OrbitPhaseRange.xyz * RandomOrbit;
|
|
|
|
// Compute angles along with cos + sin of those angles.
|
|
const float3 Angles = Frequency.xyz * Time.xxx + Phase.xyz;
|
|
sincos(Angles, Sines, Cosines);
|
|
|
|
// Compute velocity required to follow orbit path.
|
|
return Offset.xyz * (Frequency.zxy * Cosines.zxy - Frequency.yzx * Sines.yzx);
|
|
}
|
|
|
|
/**
|
|
* While the VectorFieldTextures array is split into flat textures, we need a way to
|
|
* sample a texture by index, this function wraps
|
|
*
|
|
* // @todo compat hack - remove this function
|
|
*/
|
|
float3 SampleVectorFieldTexture(int Index, float3 UV)
|
|
{
|
|
if (Index == 0) return Texture3DSample(VectorFieldTextures0, VectorFieldTexturesSampler0, UV).xyz;
|
|
if (Index == 1) return Texture3DSample(VectorFieldTextures1, VectorFieldTexturesSampler1, UV).xyz;
|
|
if (Index == 2) return Texture3DSample(VectorFieldTextures2, VectorFieldTexturesSampler2, UV).xyz;
|
|
return Texture3DSample(VectorFieldTextures3, VectorFieldTexturesSampler3, UV).xyz;
|
|
|
|
// if (Index == 3) return Texture3DSample(VectorFieldTextures3, VectorFieldTexturesSampler3, UV).xyz;
|
|
// if (Index == 4) return Texture3DSample(VectorFieldTextures4, VectorFieldTexturesSampler4, UV).xyz;
|
|
// if (Index == 5) return Texture3DSample(VectorFieldTextures5, VectorFieldTexturesSampler5, UV).xyz;
|
|
// if (Index == 6) return Texture3DSample(VectorFieldTextures6, VectorFieldTexturesSampler6, UV).xyz;
|
|
// if (Index == 7) return Texture3DSample(VectorFieldTextures7, VectorFieldTexturesSampler7, UV).xyz;
|
|
// if (Index == 8) return Texture3DSample(VectorFieldTextures8, VectorFieldTexturesSampler8, UV).xyz;
|
|
//
|
|
// return Texture3DSample(VectorFieldTextures9, VectorFieldTexturesSampler9, UV).xyz;
|
|
}
|
|
|
|
/**
|
|
* Compute the influence of vector fields on a particle at the given position.
|
|
* @param OutForce - Force to apply to the particle.
|
|
* @param OutVelocity - Direct velocity influence on the particle.
|
|
* @param Position - Position of the particle.
|
|
* @param PerParticleScale - Amount by which to scale the influence on this particle.
|
|
*/
|
|
void EvaluateVectorFields(out float3 OutForce, out float4 OutVelocity, float3 Position, float PerParticleScale)
|
|
{
|
|
float3 TotalForce = 0;
|
|
float3 WeightedVelocity = 0;
|
|
float TotalWeight = 0;
|
|
float FinalWeight = 0;
|
|
|
|
for (int VectorFieldIndex = 0; VectorFieldIndex < VectorFields.Count; ++VectorFieldIndex)
|
|
{
|
|
float2 IntensityAndTightness = VectorFields.IntensityAndTightness[VectorFieldIndex].xy;
|
|
float Intensity = IntensityAndTightness.x * PerParticleScale;
|
|
float Tightness = IntensityAndTightness.y;
|
|
float3 VolumeSize = VectorFields.VolumeSize[VectorFieldIndex].xyz;
|
|
float3 VolumeUV = mul(float4(Position.xyz,1), VectorFields.WorldToVolume[VectorFieldIndex]).xyz;
|
|
//Tile the UVs if needed. TilingAxes will be 1.0 or 0.0 in each channel depending on which axes are being tiled, if any.
|
|
VolumeUV -= floor(VolumeUV * VectorFields.TilingAxes[VectorFieldIndex].xyz);
|
|
|
|
float3 AxisWeights =
|
|
saturate(VolumeUV * VolumeSize.xyz) *
|
|
saturate((1.0f - VolumeUV) * VolumeSize.xyz);
|
|
float DistanceWeight = min(AxisWeights.x, min(AxisWeights.y, AxisWeights.z));
|
|
|
|
// @todo compat hack: Some compilers only allow constant indexing into a texture array
|
|
// float3 VectorSample = Texture3DSample(VectorFieldTextures[VectorFieldIndex], VectorFieldTexturesSampler, saturate(VolumeUV)).xyz;
|
|
float3 VectorSample = SampleVectorFieldTexture(VectorFieldIndex, saturate(VolumeUV));
|
|
|
|
float3 Vec = mul(float4(VectorSample,0), VectorFields.VolumeToWorld[VectorFieldIndex]).xyz;
|
|
TotalForce += (Vec * DistanceWeight * Intensity);
|
|
WeightedVelocity += (Vec * Intensity * DistanceWeight * Tightness);
|
|
TotalWeight += (DistanceWeight * Tightness);
|
|
FinalWeight = max(FinalWeight, DistanceWeight * Tightness);
|
|
}
|
|
|
|
// Forces are additive.
|
|
OutForce = TotalForce;
|
|
// Velocities use a weighted average.
|
|
OutVelocity.xyz = WeightedVelocity / (TotalWeight + 0.001f);
|
|
OutVelocity.w = FinalWeight;
|
|
}
|
|
|
|
/**
|
|
* Compute the force due to drag.
|
|
* @param Velocity - Velocity of the particle.
|
|
* @param DragCoefficient - Coefficient of drag to apply to the particle.
|
|
*/
|
|
float3 ComputeDrag(float3 Velocity, float DragCoefficient)
|
|
{
|
|
return -DragCoefficient * Velocity;
|
|
}
|
|
|
|
/**
|
|
* Compute the force on the particle due to a point of attraction.
|
|
* @param Position - The position of the particle.
|
|
*/
|
|
float3 ComputeAttractionForce(float3 Position)
|
|
{
|
|
float3 PointLoc = PointAttractor.xyz;
|
|
float RadiusSq = PointAttractor.w;
|
|
float Strength = PositionOffsetAndAttractorStrength.w;
|
|
|
|
float3 DirectionToPoint = PointLoc - Position + float3(0, 0, 0.0001f);
|
|
float DistSq = max(dot(DirectionToPoint,DirectionToPoint), RadiusSq);
|
|
float Attraction = Strength / DistSq;
|
|
return Attraction * normalize(DirectionToPoint);
|
|
}
|
|
|
|
/** For retrieving the size of a particle. */
|
|
Texture2D RenderAttributesTexture;
|
|
SamplerState RenderAttributesTextureSampler;
|
|
|
|
#if DEPTH_BUFFER_COLLISION
|
|
/** For retrieving the world-space normal. */
|
|
Texture2D GBufferATexture;
|
|
SamplerState GBufferATextureSampler;
|
|
|
|
/** Limits the depth bounds for which to search for a collision plane. */
|
|
float CollisionDepthBounds;
|
|
|
|
/**
|
|
* Compute collision with the depth buffer.
|
|
*/
|
|
void CollideWithDepthBuffer(
|
|
out float3 NewPosition,
|
|
out float3 NewVelocity,
|
|
inout float RelativeTime,
|
|
in float3 InPosition,
|
|
in float3 InVelocity,
|
|
in float3 Acceleration,
|
|
in float CollisionRadius,
|
|
in float Resilience
|
|
)
|
|
{
|
|
// Integration assuming no collision.
|
|
float3 MidVelocity = InVelocity.xyz + 0.5f * Acceleration;
|
|
float3 DeltaPosition = DeltaSeconds * MidVelocity;
|
|
NewPosition = InPosition.xyz + DeltaPosition;
|
|
NewVelocity = InVelocity.xyz + Acceleration;
|
|
|
|
// Figure out where to sample the depth buffer.
|
|
#if IMPROVED_DEPTH_BUFFER_COLLISION
|
|
float3 CollisionOffset = normalize(DeltaPosition*0.5f) * CollisionRadius;
|
|
#else
|
|
float3 CollisionOffset = normalize(DeltaPosition) * CollisionRadius;
|
|
#endif
|
|
|
|
float3 CollisionPosition = InPosition + CollisionOffset;
|
|
float4 SamplePosition = float4(CollisionPosition + View.PreViewTranslation,1);
|
|
float4 ClipPosition = mul(SamplePosition, View.TranslatedWorldToClip);
|
|
float2 ScreenPosition = ClipPosition.xy / ClipPosition.w;
|
|
|
|
// Don't try to collide if the particle falls outside the view.
|
|
if (all(abs(ScreenPosition.xy) <= float2(1,1)))
|
|
{
|
|
// Sample the depth buffer to get a world position near the particle.
|
|
float2 ScreenUV = ScreenPosition * View.ScreenPositionScaleBias.xy + View.ScreenPositionScaleBias.wz;
|
|
float SceneDepth = CalcSceneDepth(ScreenUV);
|
|
|
|
if (abs(ClipPosition.w - SceneDepth) < CollisionDepthBounds)
|
|
{
|
|
// Reconstruct world position.
|
|
float4 HomogeneousWorldPosition = mul(float4(ScreenPosition.xy * SceneDepth, SceneDepth, 1), View.ScreenToWorld);
|
|
float3 WorldPosition = HomogeneousWorldPosition.xyz / HomogeneousWorldPosition.w;
|
|
|
|
// Sample the normal buffer to create a plane to collide against.
|
|
float4 WorldNormal = Texture2DSampleLevel(GBufferATexture, GBufferATextureSampler, ScreenUV, 0) * float4(2,2,2,1) - float4(1,1,1,0);
|
|
float4 CollisionPlane = float4(WorldNormal.xyz, dot(WorldPosition.xyz,WorldNormal.xyz));
|
|
|
|
// Compute the portion of velocity normal to the collision plane.
|
|
float VelocityDot = dot(CollisionPlane.xyz, DeltaPosition.xyz);
|
|
|
|
|
|
|
|
#if IMPROVED_DEPTH_BUFFER_COLLISION
|
|
// distance to the plane from current and predicted position
|
|
float d_back = ( dot(CollisionPlane.xyz, InPosition.xyz)+CollisionRadius - CollisionPlane.w );
|
|
float d_front = ( dot(CollisionPlane.xyz, NewPosition.xyz)-CollisionRadius - CollisionPlane.w );
|
|
|
|
if (d_back >= 0.0f && d_front <= 0.0f && VelocityDot<0.0f)
|
|
{
|
|
// Separate velocity in to the components perpendicular and tangent to the collision plane.
|
|
float3 PerpVelocity = dot(MidVelocity,CollisionPlane.xyz) * CollisionPlane.xyz;
|
|
float3 TanVelocity = MidVelocity - PerpVelocity;
|
|
|
|
// Compute the new velocity accounting for resilience and friction.
|
|
NewVelocity = Simulation.OneMinusFriction * TanVelocity - Resilience * PerpVelocity;
|
|
|
|
// If the particle lies approximately on the collision plane, don't jump to the point of collision.
|
|
d_back *= step(VelocityDot,-1);
|
|
|
|
// Integrate position taking the collision in to account.
|
|
float PositionAdjustment = ( dot(CollisionPlane.xyz, InPosition.xyz)-CollisionRadius - CollisionPlane.w );
|
|
NewPosition = InPosition + PositionAdjustment*CollisionPlane.xyz + NewVelocity * DeltaSeconds*0.1;
|
|
|
|
// Update the relative time. Usually this does nothing, but if the
|
|
// user has elected to kill the particle upon collision this will do
|
|
// so.
|
|
RelativeTime += Simulation.CollisionTimeBias;
|
|
}
|
|
else if (d_front < 0.0f && d_back < 0.0f)
|
|
{
|
|
RelativeTime = 1.1f;
|
|
}
|
|
#else
|
|
float InvVelocityDot = rcp(VelocityDot + 0.0001f); // Add a small amount to avoid division by zero.
|
|
// Distance to the plane from the center of the particle.
|
|
float DistanceToPlane = dot(CollisionPlane.xyz, InPosition.xyz) - CollisionPlane.w;
|
|
|
|
// Find out the time of intersection for both the front and back of the sphere.
|
|
float t_back = -(DistanceToPlane + CollisionRadius) * InvVelocityDot;
|
|
float t_front = -(DistanceToPlane - CollisionRadius) * InvVelocityDot;
|
|
|
|
if (step(0, t_back) * step(t_front, 1) * step(0, DistanceToPlane))
|
|
{
|
|
// Separate velocity in to the components perpendicular and tangent to the collision plane.
|
|
float3 PerpVelocity = dot(MidVelocity,CollisionPlane.xyz) * CollisionPlane.xyz;
|
|
float3 TanVelocity = MidVelocity - PerpVelocity;
|
|
|
|
// Compute the new velocity accounting for resilience and friction.
|
|
NewVelocity = Simulation.OneMinusFriction * TanVelocity - Resilience * PerpVelocity;
|
|
|
|
// If the particle lies approximately on the collision plane, don't jump to the point of collision.
|
|
t_front *= step(VelocityDot,-1);
|
|
|
|
// Integrate position taking the collision in to account.
|
|
NewPosition = InPosition + DeltaPosition * t_front + NewVelocity * (1.0f - t_front) * DeltaSeconds;
|
|
|
|
// Update the relative time. Usually this does nothing, but if the
|
|
// user has elected to kill the particle upon collision this will do
|
|
// so.
|
|
RelativeTime += Simulation.CollisionTimeBias;
|
|
}
|
|
//else if (t_front > 0 && t_back < 1 && DistanceToPlane < 0)
|
|
else if (step(0, t_front) * step(t_back, 1) * step(DistanceToPlane,0))
|
|
{
|
|
// The particle has collided against a backface, kill it by setting
|
|
// relative time to a value > 1.0.
|
|
RelativeTime = 1.1f;
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
#endif // #if DEPTH_BUFFER_COLLISION
|
|
|
|
#if DISTANCE_FIELD_COLLISION
|
|
|
|
/**
|
|
* Compute collision with the global signed distance field
|
|
*/
|
|
void CollideWithDistanceField(
|
|
out float3 NewPosition,
|
|
out float3 NewVelocity,
|
|
inout float RelativeTime,
|
|
in float3 InPosition,
|
|
in float3 InVelocity,
|
|
in float3 Acceleration,
|
|
in float CollisionRadius,
|
|
in float Resilience
|
|
)
|
|
{
|
|
// Integration assuming no collision.
|
|
float3 MidVelocity = InVelocity.xyz + 0.5f * Acceleration;
|
|
float3 DeltaPosition = DeltaSeconds * MidVelocity;
|
|
NewPosition = InPosition.xyz + DeltaPosition;
|
|
NewVelocity = InVelocity.xyz + Acceleration;
|
|
|
|
float DistanceToNearestSurface = GetDistanceToNearestSurfaceGlobal(InPosition);
|
|
float MaxCollisionDistance = CollisionRadius + length(DeltaPosition.xyz);
|
|
|
|
if (DistanceToNearestSurface < MaxCollisionDistance)
|
|
{
|
|
float3 CollisionWorldNormal = normalize(GetDistanceFieldGradientGlobal(InPosition));
|
|
float3 CollisionWorldPosition = InPosition - CollisionWorldNormal * DistanceToNearestSurface;
|
|
|
|
float4 CollisionPlane = float4(CollisionWorldNormal.xyz, dot(CollisionWorldPosition.xyz, CollisionWorldNormal.xyz));
|
|
|
|
// Compute the portion of velocity normal to the collision plane.
|
|
float VelocityDot = dot(CollisionPlane.xyz, DeltaPosition.xyz);
|
|
float InvVelocityDot = rcp(VelocityDot + 0.0001f); // Add a small amount to avoid division by zero.
|
|
|
|
// Distance to the plane from the center of the particle.
|
|
float DistanceToPlane = dot(CollisionPlane.xyz, InPosition.xyz) - CollisionPlane.w;
|
|
|
|
// Find out the time of intersection for both the front and back of the sphere.
|
|
float t_back = -(DistanceToPlane + CollisionRadius) * InvVelocityDot;
|
|
float t_front = -(DistanceToPlane - CollisionRadius) * InvVelocityDot;
|
|
|
|
//if (t_back >= 0 && t_front <= 1 && DistanceToPlane >= 0)
|
|
if (step(0, t_back) * step(t_front, 1) * step(0, DistanceToPlane))
|
|
{
|
|
// Separate velocity in to the components perpendicular and tangent to the collision plane.
|
|
float3 PerpVelocity = dot(MidVelocity,CollisionPlane.xyz) * CollisionPlane.xyz;
|
|
float3 TanVelocity = MidVelocity - PerpVelocity;
|
|
|
|
// Compute the new velocity accounting for resilience and friction.
|
|
NewVelocity = Simulation.OneMinusFriction * TanVelocity - Resilience * PerpVelocity;
|
|
|
|
// If the particle lies approximately on the collision plane, don't jump to the point of collision.
|
|
t_front *= step(VelocityDot,-1);
|
|
|
|
// Integrate position taking the collision in to account.
|
|
NewPosition = InPosition + DeltaPosition * t_front + NewVelocity * (1.0f - t_front) * DeltaSeconds;
|
|
|
|
// Update the relative time. Usually this does nothing, but if the
|
|
// user has elected to kill the particle upon collision this will do
|
|
// so.
|
|
RelativeTime += Simulation.CollisionTimeBias;
|
|
}
|
|
//else if (t_front > 0 && t_back < 1 && DistanceToPlane < 0)
|
|
else if (step(0, t_front) * step(t_back, 1) * step(DistanceToPlane,0))
|
|
{
|
|
// The particle has collided against a backface, kill it by setting
|
|
// relative time to a value > 1.0.
|
|
RelativeTime = 1.1f;
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
void PixelMain(
|
|
in FShaderInterpolants Interpolants,
|
|
out float4 OutPosition : SV_Target0,
|
|
out float4 OutVelocity : SV_Target1
|
|
)
|
|
{
|
|
// Initialize force to the constant acceleration.
|
|
float3 Force = Simulation.Acceleration;
|
|
|
|
// Sample the current position, velocity, and attributes for this particle.
|
|
const float4 PositionSample = Texture2DSample(PositionTexture, PositionTextureSampler, Interpolants.TexCoord.xy);
|
|
const float4 VelocitySample = Texture2DSample(VelocityTexture, VelocityTextureSampler, Interpolants.TexCoord.xy );
|
|
const float4 InitialAttributes = Texture2DSample(AttributesTexture, AttributesTextureSampler, Interpolants.TexCoord.xy ) *
|
|
Simulation.AttributeScale + Simulation.AttributeBias;
|
|
|
|
// Velocity.w holds the time scale for this particle.
|
|
float3 Velocity = VelocitySample.xyz;
|
|
const float TimeScale = VelocitySample.w;
|
|
|
|
// Position.w holds the relative time of the particle.
|
|
float3 Position = PositionSample.xyz;
|
|
float RelativeTime = PositionSample.w;
|
|
|
|
for (int IterationIndex = 0; IterationIndex < NumIterations; ++IterationIndex)
|
|
{
|
|
RelativeTime += DeltaSeconds * TimeScale;
|
|
|
|
// Sample the attribute curve.
|
|
const float2 AttributeCurveTexCoord = Simulation.AttributeCurve.xy +
|
|
Simulation.AttributeCurve.zw * RelativeTime;
|
|
const float4 AttributeCurve = Texture2DSample(CurveTexture, CurveTextureSampler, AttributeCurveTexCoord ) *
|
|
Simulation.AttributeCurveScale + Simulation.AttributeCurveBias;
|
|
|
|
// Simulation attributes.
|
|
const float4 Attributes = InitialAttributes * AttributeCurve;
|
|
const float DragCoefficient = Attributes.r;
|
|
const float PerParticleVectorFieldScale = Attributes.g;
|
|
const float Resilience = Attributes.b;
|
|
const float OrbitRandom = Attributes.a;
|
|
|
|
// Evalute vector fields.
|
|
float3 FieldForce = 0;
|
|
float4 FieldVelocity = 0;
|
|
EvaluateVectorFields(FieldForce, FieldVelocity, Position.xyz, PerParticleVectorFieldScale);
|
|
|
|
// Add in force from vector fields.
|
|
Force += FieldForce;
|
|
|
|
// Account for direct velocity.
|
|
const float DirectVelocityAmount = FieldVelocity.w;
|
|
Velocity.xyz = lerp(Velocity.xyz, FieldVelocity.xyz, DirectVelocityAmount);
|
|
|
|
// Compute force due to drag.
|
|
Force += ComputeDrag(Velocity.xyz, DragCoefficient);
|
|
|
|
// Compute force to a point gravity source.
|
|
Force += ComputeAttractionForce(Position.xyz);
|
|
|
|
// Compute the acceleration to apply to the particle this frame.
|
|
float3 Acceleration = Force * DeltaSeconds;
|
|
|
|
#if DEPTH_BUFFER_COLLISION || DISTANCE_FIELD_COLLISION
|
|
// We need to look up render attributes for this particle to figure out how big it is.
|
|
float4 RenderAttributeSample = Texture2DSampleLevel(RenderAttributesTexture, RenderAttributesTextureSampler, Interpolants.TexCoord.xy, 0);
|
|
|
|
// Sample the misc render attributes curve.
|
|
float2 MiscCurveTexCoord = Simulation.MiscCurve.xy + Simulation.MiscCurve.zw * RelativeTime;
|
|
float4 MiscCurveSample = Texture2DSampleLevel(CurveTexture, CurveTextureSampler, MiscCurveTexCoord, 0 );
|
|
float4 MiscCurve = MiscCurveSample * Simulation.MiscScale + Simulation.MiscBias;
|
|
|
|
// Compute the size of the sprite. Note it is (0,0) if the sprite is dead.
|
|
float2 InitialSize = abs(RenderAttributeSample.xy);
|
|
float2 SizeScale = MiscCurve.xy;
|
|
float2 Size = InitialSize * SizeScale * LocalToWorldScale;
|
|
|
|
// Compute the radius with which to perform collision checks.
|
|
float CollisionRadius = min(Size.x,Size.y) * Simulation.CollisionRadiusScale + Simulation.CollisionRadiusBias;
|
|
#endif
|
|
|
|
float3 NewPosition, NewVelocity;
|
|
|
|
#if DEPTH_BUFFER_COLLISION
|
|
|
|
// Compute the new position and velocity of the particle by colliding against
|
|
// the scene's depth buffer.
|
|
CollideWithDepthBuffer(
|
|
NewPosition.xyz,
|
|
NewVelocity.xyz,
|
|
RelativeTime,
|
|
Position.xyz,
|
|
Velocity.xyz,
|
|
Acceleration,
|
|
CollisionRadius,
|
|
Resilience
|
|
);
|
|
#elif DISTANCE_FIELD_COLLISION
|
|
|
|
CollideWithDistanceField(
|
|
NewPosition.xyz,
|
|
NewVelocity.xyz,
|
|
RelativeTime,
|
|
Position.xyz,
|
|
Velocity.xyz,
|
|
Acceleration,
|
|
CollisionRadius,
|
|
Resilience
|
|
);
|
|
|
|
#else
|
|
// Integrate position and velocity forward.
|
|
float3 DeltaPosition = DeltaSeconds * (Velocity.xyz + 0.5f * Acceleration);
|
|
NewPosition = Position.xyz + DeltaPosition;
|
|
NewVelocity = Velocity.xyz + Acceleration;
|
|
#endif
|
|
|
|
// Apply orbit.
|
|
const float3 OrbitVelocity = ComputeOrbitVelocity(RelativeTime, OrbitRandom);
|
|
NewPosition += OrbitVelocity * DeltaSeconds;
|
|
|
|
// Update values for new iteration.
|
|
Velocity = NewVelocity;
|
|
Position = NewPosition;
|
|
}
|
|
|
|
// Store the new position, time, and velocity for the particle.
|
|
OutPosition.xyz = Position + PositionOffsetAndAttractorStrength.xyz;
|
|
OutPosition.w = RelativeTime;
|
|
OutVelocity.xyz = Velocity;
|
|
OutVelocity.w = TimeScale;
|
|
}
|
|
|
|
#endif // #if PARTICLE_SIMULATION_PIXELSHADER
|
|
|
|
/*------------------------------------------------------------------------------
|
|
Clear particle simulation pixel shader.
|
|
------------------------------------------------------------------------------*/
|
|
#if PARTICLE_CLEAR_PIXELSHADER
|
|
|
|
void PixelMain(
|
|
in FShaderInterpolants Interpolants,
|
|
out float4 OutPosition : SV_Target0,
|
|
out float4 OutVelocity : SV_Target1
|
|
)
|
|
{
|
|
// Relative time just needs to be >1.0f so the particle is considered dead.
|
|
OutPosition = float4(0,0,0,2.0f);
|
|
OutVelocity = float4(0,0,0,0);
|
|
}
|
|
|
|
#endif // #if PARTICLE_CLEAR_PIXELSHADER
|
|
|