Game Development Reference
In-Depth Information
To write a pixel shader, we created “building blocks” of common operations
for different shaders. This design makes it easy to write shaders, as we will show
now. The most important building blocks are the following two, implemented as
int tileIndex = GetTileIndex(screenPos);
uint startIndex, endIndex;
GetTileOffsets( tileIndex, startIndex, endIndex );
for ( uint lightListIdx = startIdx;
lightListIdx < endIdx;
lightListIdx++ )
int lightIdx = LightIndexBuffer[lightListIdx];
LightParams directLight;
LightParams indirectLight;
if ( isIndirectLight( lightIdx ) )
FetchIndirectLight(lightIdx , indirectLight);
FetchDirectLight( lightIndex, directLight );
LIGHT_LOOP_BEGIN first calculates the tile index of the pixel using its screen-space
position. Then it opens a loop to iterate all the lights overlapping the tile and
fills light parameters for direct and indirect light. LIGHT_LOOP_END is a macro to
close the loop.
By using these building blocks, an implementation of a pixel shader is simple
and looks almost the same as a pixel shader used in forward rendering.
example, a shader for a microfacet surface is implemented as follows:
float4 PS ( PSInput i ) : SV_TARGET
float3 colorOut = 0;
colorOut += EvaluateMicrofacet ( directLight , indirectLight );
return float4(colorOut, 1.f );
Other shaders can be implemented by just changing the lines between the two
macros. This building block also allows us to change the implementation easily
Search Nedrilad ::

Custom Search