Graphics Reference
In-Depth Information
The Snowfall compute shader applies the force that has been passed into the
ParticleConstants constant buffer with a call to ApplyForces . This simply computes
the current force vector and applies it to the particle's position, based on the current
FrameTime value. Then, the Snowfall shader clamps the Particle.Position.y value
to DomainBoundsMin.y ; if the old and new Y positions are the same (that is, the particle
is sitting on the ground), the Particle.Energy property is set to 1.0f . To ensure that
we do not try to create too many particles, we decreased their Energy property by the
current FrameTime value. Once the amount of energy reaches zero, the particle is
removed; otherwise, it is added into the NewState buffer.
The DeviceContext.DrawInstancedIndirect method allows us to generate our
sprites or billboards by passing in a GPU-generated parameter list; the first two being the
instance vertex count (always four for our quads) and number of instances. The instance
count comes directly from the current consume buffer with a call to the DeviceContext.
CopyStructureCount method. This allows our compute shaders to control the number
of particles to be rendered.
By utilizing the vertex shader system value input semantics SV_InstanceID and
SV_VertexID , we are able to index into the particle buffer directly and generate our
camera-aligned quads without passing any additional information into the vertex shader.
We compute the vertex UV coordinates and their positions based on the incoming
SV_VertexID value. Another approach is to use a lookup table, saving approximately
two instructions. The resulting camera-aligned quads (also known as sprites or billboards)
will always face the camera.
Once the quad is rasterized and the fragments are sent to the pixel shader, we sample the
texture and return the value. The texture used in the recipe is a white dot or snowflake shape
with transparency. Multiplying this with any other color allows us to control the particle's final
color. We also fade out the alpha as the particle approaches the near-clip plane, and during
its final second of life.
To allow the particles to perform alpha-blending correctly, we have created an additive
BlendState instance within our particle renderer. By setting the blendDesc.
RenderTarget[0].SourceBlend to BlendOption.SourceAlpha , and blendDesc.
RenderTarget[0].DestinationBlend to BlendOption.InverseSourceAlpha , we
are telling the output merger stage to use the alpha component returned by the pixel shader,
and merge with the render target accordingly. Given a source color of (1, 1, 1, 0.5) and
destination color of (0.6, 0.0, 0.6, 0.9) , the blending calculation is as follows:
Final Color = (Source Color * BlendOption.SourceAlpha)
BlendOperation.Add (Dest Color * BlendOption.InverseSourceAlpha)
Final Color = ((1, 1, 1) * 0.7) + ((0.6, 0.0, 0.6) * (1 - 0.7))
= (0.7, 0.7, 0.7) + (0.18, 0.0, 0.18)
= (0.88, 0.7, 0.88)
 
Search WWH ::




Custom Search