| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- #define USES_GS
- #include "$ENGINE$\ShadowDepthBase.bslinc"
- technique ShadowDepth
- {
- mixin ShadowDepthBase;
-
- code
- {
- struct GSToPS
- {
- float4 position : SV_Position;
- uint targetIdx : SV_RenderTargetArrayIndex;
- };
- cbuffer ShadowCubeMatrices
- {
- float4x4 gFaceVPMatrices[6];
- };
-
- cbuffer ShadowCubeMasks
- {
- uint gFaceMasks[6];
- };
-
- [maxvertexcount(18)]
- void gsmain(triangle ShadowVStoFS inputs[3], inout TriangleStream<GSToPS> outStream)
- {
- // Output a triangle to all relevant faces
- [unroll]
- for (int faceIdx = 0; faceIdx < 6; faceIdx++)
- {
- // Check the per-object masks that were determined based on CPU frustum culling
- [branch]
- if (gFaceMasks[faceIdx] > 0)
- {
- float4 clipPos[3];
-
- [unroll]
- for (int vertIdx = 0; vertIdx < 3; vertIdx++)
- clipPos[vertIdx] = mul(gFaceVPMatrices[faceIdx], inputs[vertIdx].worldPos);
- // Per-triangle frustum culling
- // Note: Test if this helps or hurts performance
- float4 testMask = saturate(clipPos[0].xyxy * float4(-1, -1, 1, 1) - clipPos[0].w);
- testMask *= saturate(clipPos[1].xyxy * float4(-1, -1, 1, 1) - clipPos[1].w);
- testMask *= saturate(clipPos[2].xyxy * float4(-1, -1, 1, 1) - clipPos[2].w);
- [branch]
- if (all(testMask == 0))
- {
- GSToPS output;
- output.targetIdx = faceIdx;
- // Note: I'm reversing the order here because otherwise the triangle order is reversed
- // (not sure why, but GS seems like it could be the only culprit). This doesn't happen in
- // OpenGL, because we flip the projection matrix Y axis due to upside-down UV coordinates
- [unroll]
- #ifdef OPENGL
- for (int vertIdx = 0; vertIdx < 3; vertIdx++)
- #else
- for (int vertIdx = 2; vertIdx >= 0; vertIdx--)
- #endif
- {
- output.position = clipPos[vertIdx];
- outStream.Append(output);
- }
-
- outStream.RestartStrip();
- }
- }
- }
- }
- };
- };
|