mihu

bake spot light to 3D light texture

Aug 26th, 2012
229
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. cbuffer cbPerLightVolume
  2. {
  3.     float3 gLightVolPos;
  4.     float3 gLightVolScale;
  5. };
  6.  
  7. RWTexture3D<uint> gLightTex0;
  8. RWTexture3D<uint> gLightTex1;
  9. RWTexture3D<uint> gLightTex2;
  10. RWTexture3D<uint> gLightTex3;
  11. RWTexture3D<uint> gLightTex4;
  12.  
  13. float4 rgba8_as_uint_to_float4(uint input)  
  14. {  
  15.     float4 output;  
  16.     output.x = (float)  (input      & 0x000000ff)  / 255;  
  17.     output.y = (float)(((input>> 8) & 0x000000ff)) / 255;  
  18.     output.z = (float)(((input>>16) & 0x000000ff)) / 255;  
  19.     output.w = (float)  (input>>24)                / 255;  
  20.     return output;  
  21. }
  22.  
  23. uint float_to_uint(float value, float scale)  
  24. {  
  25.     return (uint)floor(value * scale + 0.5f);
  26. }  
  27.  
  28. uint float4_to_rgba8_as_uint(float4 input)  
  29. {  
  30.     uint output =  ( (float_to_uint(saturate(input.x), 255))     |  
  31.                      (float_to_uint(saturate(input.y), 255)<< 8) |  
  32.                      (float_to_uint(saturate(input.z), 255)<<16) |  
  33.                      (float_to_uint(saturate(input.w), 255)<<24) );  
  34.     return output;  
  35. }
  36.  
  37. void read6Axes(in int3 texCoord, out float3 xPos, out float3 xNeg, out float3 yPos, out float3 yNeg, out float3 zPos, out float3 zNeg)
  38. {
  39.     float4 sample0 = rgba8_as_uint_to_float4(gLightTex0[texCoord]);
  40.     float4 sample1 = rgba8_as_uint_to_float4(gLightTex1[texCoord]);
  41.     float4 sample2 = rgba8_as_uint_to_float4(gLightTex2[texCoord]);
  42.     float4 sample3 = rgba8_as_uint_to_float4(gLightTex3[texCoord]);
  43.     float4 sample4 = rgba8_as_uint_to_float4(gLightTex4[texCoord]);
  44.  
  45.     xPos = sample0.xyz;
  46.     xNeg = sample1.xyz;
  47.     yPos = sample2.xyz;
  48.     yNeg = sample3.xyz;
  49.     zPos = sample4.xyz;
  50.     zNeg = float3(sample0.w, sample1.w, sample2.w);
  51. }
  52.  
  53. void write6Axes(int3 texCoord, float3 xPos, float3 xNeg, float3 yPos, float3 yNeg, float3 zPos, float3 zNeg)
  54. {
  55.     gLightTex0[texCoord] = float4_to_rgba8_as_uint(float4(xPos, zNeg.x));
  56.     gLightTex1[texCoord] = float4_to_rgba8_as_uint(float4(xNeg, zNeg.y));
  57.     gLightTex2[texCoord] = float4_to_rgba8_as_uint(float4(yPos, zNeg.z));
  58.     gLightTex3[texCoord] = float4_to_rgba8_as_uint(float4(yNeg, 0));
  59.     gLightTex4[texCoord] = float4_to_rgba8_as_uint(float4(zPos, 0));
  60. }
  61.  
  62. cbuffer cbPerLight
  63. {
  64.     float4 gLightPosWAndRadius;
  65.     float4 gLightColorAndIntens;
  66.     float4 gLightDirAndCosAngle;
  67. };
  68.  
  69. void storeLighting(int3 texCoord, float3 lightStrengthDir, float3 lightColor)
  70. {
  71.     float3 xPos, xNeg, yPos, yNeg, zPos, zNeg;
  72.     read6Axes(texCoord, xPos, xNeg, yPos, yNeg, zPos, zNeg);
  73.  
  74.     xPos += lightColor * max( lightStrengthDir.x, 0);
  75.     xNeg += lightColor * max(-lightStrengthDir.x, 0);
  76.     yPos += lightColor * max( lightStrengthDir.y, 0);
  77.     yNeg += lightColor * max(-lightStrengthDir.y, 0);
  78.     zPos += lightColor * max( lightStrengthDir.z, 0);
  79.     zNeg += lightColor * max(-lightStrengthDir.z, 0);
  80.  
  81.     write6Axes(texCoord, xPos, xNeg, yPos, yNeg, zPos, zNeg);
  82. }
  83.  
  84. [numthreads(8, 8, 8)]
  85. void CS(    uint3 GroupID : SV_GroupID,
  86.             uint3 DispatchThreadID : SV_DispatchThreadID,
  87.             uint3 GroupThreadID : SV_GroupThreadID,
  88.             uint GroupIndex : SV_GroupIndex )
  89. {
  90.     const float3 lightPos = gLightPosWAndRadius.xyz;
  91.     const float lightRadius = gLightPosWAndRadius.w;
  92.  
  93.     const float3 lightColor = gLightColorAndIntens.rgb;
  94.     const float lightIntensity = gLightColorAndIntens.a;
  95.  
  96.     const float3 spotDir = gLightDirAndCosAngle.xyz;
  97.     const float coneCosAngle = gLightDirAndCosAngle.w;
  98.  
  99.     float3 samplePos = gLightVolPos + (float3(DispatchThreadID) + float3(0.5f, 0.5f, 0.5f)) * gLightVolScale;
  100.     float3 lightDir = lightPos - samplePos;
  101.     float dist = length(lightDir);
  102.     lightDir = normalize(lightDir);
  103.  
  104.     float spotAngleCos = saturate(dot( -spotDir, lightDir ));
  105.  
  106.     if(spotAngleCos < coneCosAngle)
  107.         return;
  108.  
  109.     float atten = saturate((lightRadius - dist) / lightRadius);
  110.     float angleAtten = (spotAngleCos - coneCosAngle) / (1.0 - coneCosAngle);
  111.  
  112.     float3 lightStrengthDir = lightDir * atten * angleAtten * lightIntensity;
  113.  
  114.     storeLighting(DispatchThreadID, lightStrengthDir, lightColor);
  115. }
  116.  
  117. technique11 tech
  118. {
  119.     pass P0
  120.     {
  121.         SetComputeShader(CompileShader(cs_5_0, CS()));
  122.     }
  123. }
RAW Paste Data