| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 |
- #include "$ENGINE$\DeferredLightPass.bslinc"
- Technique
- : inherits("DeferredLightPass") =
- {
- Language = "HLSL11";
-
- Pass =
- {
- DepthWrite = false;
-
- #ifdef INSIDE_GEOMETRY
-
- DepthRead = false;
- Cull = CW;
-
- #else
-
- DepthRead = true;
- Cull = CCW;
-
- #endif
-
- Common =
- {
- struct VStoFS
- {
- float4 position : SV_POSITION;
- float4 screenPos : TEXCOORD0;
- };
- };
-
- Vertex =
- {
- struct VertexInput
- {
- float3 position : POSITION;
- uint vertexIdx : SV_VERTEXID;
- };
-
- VStoFS main(VertexInput input)
- {
- VStoFS output;
-
- float3 worldPosition;
- uint numSides = gLightGeometry.x;
- if(numSides > 0) // Generate spot light geometry
- {
- uint numSlices = gLightGeometry.y;
- float radius = gLightGeometry.w;
- float angle = gLightSpotAnglesAndSqrdInvRadius.x;
-
- // Extra scale to ensure edges lie on the circle, not inside it
- // TODO - These can be precomputed
- float extraRadiusScale = 1.0f / cos(PI / (float)numSides);
- float angleTan = tan(angle);
- float height = radius / angleTan;
-
- uint sphereStartIdx = numSides * numSlices;
- // Cone vertices
- if (input.vertexIdx < sphereStartIdx)
- {
- uint sliceIdx = input.vertexIdx / numSides;
- uint sideIdx = input.vertexIdx % numSides;
- float curAngle = sideIdx * 2 * PI / (float)numSides;
- float sliceOffset = height * sliceIdx / (float)(numSlices - 1);
- float sliceRadius = sliceOffset * angleTan * extraRadiusScale;
- float4 localPos = float4(sliceRadius * cos(curAngle),
- sliceRadius * sin(curAngle), -sliceOffset, 1.0f);
- worldPosition = (mul(gMatConeTransform, localPos)).xyz;
- }
- else // Sphere cap vertices
- {
- uint sphereVertexIdx = input.vertexIdx - sphereStartIdx;
- uint sliceIdx = sphereVertexIdx / numSides;
- uint sideIdx = sphereVertexIdx % numSides;
- float curAngle = sideIdx * 2 * PI / (float)numSides;
- float sliceOffset = radius * sliceIdx / (float)(numSlices - 1);
- float sliceRadius = sqrt(max(0.0f, radius * radius - sliceOffset * sliceOffset)) * extraRadiusScale;
- float4 localPos = float4(sliceRadius * cos(curAngle),
- sliceRadius * sin(curAngle), -height - sliceOffset, 1.0f);
- worldPosition = (mul(gMatConeTransform, localPos)).xyz;
- }
- }
- else // Scale and position pre-generated sphere geometry
- {
- worldPosition = input.position * gLightGeometry.z + gLightPositionAndType.xyz;
- }
-
- output.screenPos = mul(gMatViewProj, float4(worldPosition, 1));
- output.position = output.screenPos;
-
- return output;
- }
- };
-
- Fragment =
- {
- float4 main(VStoFS input) : SV_Target0
- {
- float2 correctedPos = input.screenPos.xy / input.screenPos.w;
- float2 screenUV = correctedPos * gClipToUVScaleOffset.xy + gClipToUVScaleOffset.zw;
- GBufferData gBufferData = getGBufferData(screenUV);
-
- if(gBufferData.worldNormal.w > 0.0f)
- {
- // x, y are now in clip space, z, w are in view space
- // We multiply them by a special inverse view-projection matrix, that had the projection entries that effect
- // z, w eliminated (since they are already in view space)
- float4 mixedSpacePos = float4(correctedPos.xy * -gBufferData.depth, gBufferData.depth, 1);
- float4 worldPosition4D = mul(gMatScreenToWorld, mixedSpacePos);
- float3 worldPosition = worldPosition4D.xyz / worldPosition4D.w;
- LightData lightData = getLightData();
- return getLighting(worldPosition, screenUV, gBufferData, lightData);
- }
- else
- return float4(0.0f, 0.0f, 0.0f, 0.0f);
- }
- };
- };
- };
- Technique
- : inherits("DeferredLightPass") =
- {
- Language = "GLSL";
-
- Pass =
- {
- DepthWrite = false;
-
- #ifdef INSIDE_GEOMETRY
-
- DepthRead = false;
- Cull = CW;
-
- #else
-
- DepthRead = true;
- Cull = CCW;
-
- #endif
-
- Vertex =
- {
- varying vec4 position;
- varying vec4 screenPos;
-
- in vec3 bs_position;
- in int gl_VertexID;
-
- out gl_PerVertex
- {
- vec4 gl_Position;
- };
-
- void main()
- {
- vec3 worldPosition;
- uint numSides = uint(gLightGeometry.x);
- if(numSides > 0) // Generate spot light geometry
- {
- uint numSlices = uint(gLightGeometry.y);
- float radius = gLightGeometry.w;
- float angle = gLightSpotAnglesAndSqrdInvRadius.x;
-
- // Extra scale to ensure edges lie on the circle, not inside it
- // TODO - These can be precomputed
- float extraRadiusScale = 1.0f / cos(PI / float(numSides));
- float angleTan = tan(angle);
- float height = radius / angleTan;
-
- uint sphereStartIdx = numSides * numSlices;
- // Cone vertices
- if (gl_VertexID < sphereStartIdx)
- {
- uint sliceIdx = gl_VertexID / numSides;
- uint sideIdx = gl_VertexID % numSides;
- float curAngle = float(sideIdx) * 2 * PI / float(numSides);
- float sliceOffset = height * sliceIdx / float(numSlices - 1);
- float sliceRadius = sliceOffset * angleTan * extraRadiusScale;
- vec4 localPos = vec4(sliceRadius * cos(curAngle),
- sliceRadius * sin(curAngle), -sliceOffset, 1.0f);
- worldPosition = (gMatConeTransform * localPos).xyz;
- }
- else // Sphere cap vertices
- {
- uint sphereVertexIdx = gl_VertexID - sphereStartIdx;
- uint sliceIdx = sphereVertexIdx / numSides;
- uint sideIdx = sphereVertexIdx % numSides;
- float curAngle = float(sideIdx) * 2 * PI / float(numSides);
- float sliceOffset = radius * sliceIdx / float(numSlices - 1);
- float sliceRadius = sqrt(max(0.0f, radius * radius - sliceOffset * sliceOffset)) * extraRadiusScale;
- vec4 localPos = vec4(sliceRadius * cos(curAngle),
- sliceRadius * sin(curAngle), -height - sliceOffset, 1.0f);
- worldPosition = (gMatConeTransform * localPos).xyz;
- }
- }
- else // Scale and position pre-generated sphere geometry
- {
- worldPosition = bs_position * gLightGeometry.z + gLightPositionAndType.xyz;
- }
-
- screenPos = gMatViewProj * vec4(worldPosition, 1);
- position = screenPos;
-
- gl_Position = position;
- }
- };
-
- Fragment =
- {
- in vec4 position;
- in vec4 screenPos;
-
- out vec4 fragColor;
-
- void main()
- {
- vec2 correctedPos = screenPos.xy / screenPos.w;
- vec2 screenUV = correctedPos * gClipToUVScaleOffset.xy + gClipToUVScaleOffset.zw;
- GBufferData gBufferData = getGBufferData(screenUV);
-
- if(gBufferData.worldNormal.w > 0.0f)
- {
- // x, y are now in clip space, z, w are in view space
- // We multiply them by a special inverse view-projection matrix, that had the projection entries that effect
- // z, w eliminated (since they are already in view space)
- vec4 mixedSpacePos = vec4(correctedPos.xy * -gBufferData.depth, gBufferData.depth, 1);
- vec4 worldPosition4D = gMatScreenToWorld * mixedSpacePos;
- vec3 worldPosition = worldPosition4D.xyz / worldPosition4D.w;
- LightData lightData = getLightData();
- fragColor = getLighting(worldPosition, screenUV, gBufferData, lightData);
- }
- else
- fragColor = vec4(0.0f, 0.0f, 0.0f, 0.0f);
- }
- };
- };
- };
|