Files
UnrealEngineUWP/Engine/Shaders/ParticleSimulationShader.usf
Gil Gribb 0b102492a9 Copying //UE4/Dev-Rendering to //UE4/Dev-Main (Source: //UE4/Dev-Rendering @ 3028916)
#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

Change 3009815 on 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.

Change 3016289 on 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)

Change 3020561 on 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]
2016-06-27 13:42:20 -04:00

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