DirectLightAccumulator.bslinc 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. //
  2. // Contains helper mixin used for initializing different forms of light accumulation. Can be removed
  3. // when template/specialization support for mixins is added to BSL.
  4. //
  5. #ifdef USE_UNIFORM_BUFFER
  6. mixin LightAccumulatorDirect
  7. #else
  8. mixin LightAccumulatorIndexed
  9. #endif
  10. {
  11. code
  12. {
  13. #ifdef USE_UNIFORM_BUFFER
  14. #define MAX_LIGHTS 8
  15. [internal]
  16. cbuffer Lights
  17. {
  18. LightData gLights[MAX_LIGHTS];
  19. }
  20. #else
  21. #define MAX_LIGHTS 512 // Arbitrary limit, increase if needed
  22. #ifdef USE_COMPUTE_INDICES
  23. groupshared uint gLightIndices[MAX_LIGHTS];
  24. StructuredBuffer<LightData> gLights;
  25. #endif
  26. #ifdef USE_LIGHT_GRID_INDICES
  27. Buffer<uint> gLightIndices;
  28. StructuredBuffer<LightData> gLights;
  29. #endif
  30. #endif
  31. float4 getDirectLighting(float3 worldPos, float3 V, float3 R, SurfaceData surfaceData, uint4 lightOffsets)
  32. {
  33. float3 N = surfaceData.worldNormal.xyz;
  34. float roughness2 = max(surfaceData.roughness, 0.08f);
  35. roughness2 *= roughness2;
  36. float3 outLuminance = 0;
  37. float alpha = 0.0f;
  38. if(surfaceData.worldNormal.w > 0.0f)
  39. {
  40. // Handle directional lights
  41. [loop]
  42. for(uint i = 0; i < lightOffsets.x; ++i)
  43. {
  44. LightData lightData = gLights[i];
  45. outLuminance += getLuminanceDirectional(lightData, worldPos, V, R, surfaceData);
  46. }
  47. // Handle radial lights
  48. [loop]
  49. for (uint j = lightOffsets.y; j < lightOffsets.z; ++j)
  50. {
  51. #ifdef USE_UNIFORM_BUFFER
  52. uint lightIdx = j;
  53. #else
  54. uint lightIdx = gLightIndices[j];
  55. #endif
  56. LightData lightData = gLights[lightIdx];
  57. outLuminance += getLuminanceRadial(lightData, worldPos, V, R, roughness2, surfaceData);
  58. }
  59. // Handle spot lights
  60. [loop]
  61. for(uint k = lightOffsets.z; k < lightOffsets.w; ++k)
  62. {
  63. #ifdef USE_UNIFORM_BUFFER
  64. uint lightIdx = k;
  65. #else
  66. uint lightIdx = gLightIndices[k];
  67. #endif
  68. LightData lightData = gLights[lightIdx];
  69. outLuminance += getLuminanceSpot(lightData, worldPos, V, R, roughness2, surfaceData);
  70. }
  71. // Ambient term for in-editor visualization, not used in actual lighting
  72. outLuminance += surfaceData.albedo.rgb * gAmbientFactor / PI;
  73. alpha = 1.0f;
  74. }
  75. return float4(outLuminance, alpha);
  76. }
  77. };
  78. };