IrradianceComputeSHFrag.bsl 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. #include "$ENGINE$\ReflectionCubemapCommon.bslinc"
  2. #define SH_ORDER 3
  3. #include "$ENGINE$\SHCommon.bslinc"
  4. #include "$ENGINE$\PPBase.bslinc"
  5. shader IrradianceComputeSHFrag
  6. {
  7. mixin PPBase;
  8. mixin ReflectionCubemapCommon;
  9. mixin SHCommon;
  10. code
  11. {
  12. SamplerState gInputSamp;
  13. TextureCube gInputTex;
  14. [internal]
  15. cbuffer Params
  16. {
  17. uint gCubeFace;
  18. uint gFaceSize;
  19. uint gCoeffEntryIdx;
  20. uint gCoeffComponentIdx;
  21. }
  22. float4 fsmain(VStoFS input) : SV_Target0
  23. {
  24. // Move to [-1,1] range
  25. float2 uv = input.uv0 * 2.0f - 1.0f;
  26. float3 dir = getDirFromCubeFace(gCubeFace, float2(uv.x, uv.y));
  27. dir = normalize(dir);
  28. // Need to calculate solid angle (weight) of the texel, as cube face corners have
  29. // much smaller solid angle, meaning many of them occupy the same area when projected
  30. // on a sphere. Without weighing that area would look too bright.
  31. float invFaceSize = 1.0f / gFaceSize;
  32. float weight = texelSolidAngle(uv.x, uv.y, invFaceSize);
  33. SHVector b = SHBasis(dir);
  34. // Copy to array of float4’s because of a driver bug on macOS that causes
  35. // non-const indexing of an array of floats to return incorrect values
  36. float4 v[3];
  37. v[0] = float4(b.v[0], b.v[1], b.v[2], b.v[3]);
  38. v[1] = float4(b.v[4], b.v[5], b.v[6], b.v[7]);
  39. v[2] = float4(b.v[8], 0.0f, 0.0f, 0.0f);
  40. float3 radiance = gInputTex.SampleLevel(gInputSamp, dir, 0).rgb;
  41. float shCoeff = v[gCoeffEntryIdx][gCoeffComponentIdx];
  42. float4 output;
  43. output.r = shCoeff * radiance.r * weight;
  44. output.g = shCoeff * radiance.g * weight;
  45. output.b = shCoeff * radiance.b * weight;
  46. output.a = weight;
  47. return output;
  48. }
  49. };
  50. };