LightGridCommon.bslinc 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. mixin LightGridCommon
  2. {
  3. code
  4. {
  5. cbuffer GridParams : register(b4)
  6. {
  7. // Number of lights per type in the lights buffer
  8. // x - directional lights, y - radial lights, z - spot lights, w - total number of lights
  9. uint4 gLightCounts;
  10. // Strides between different light types in the light buffer
  11. // x - stride to radial lights, y - stride to spot lights. Directional lights are assumed to start at 0.
  12. uint2 gLightStrides;
  13. uint gNumReflProbes;
  14. uint gNumCells;
  15. uint3 gGridSize;
  16. uint gMaxNumLightsPerCell;
  17. uint2 gGridPixelSize;
  18. }
  19. float calcViewZFromCellZ(uint cellZ)
  20. {
  21. // We don't want to subdivide depth uniformly because XY sizes will be much
  22. // smaller closer to the near plane, and larger towards far plane. We want
  23. // our cells to be as close to cube shape as possible, so that width/height/depth
  24. // are all similar. Ideally we would use either width or height as calculated for
  25. // purposes of the projection matrix, for the depth. But since we'll be splitting
  26. // the depth range into multiple slices, in practice this ends up with many tiny
  27. // cells close to the near plane. Instead we use a square function, which is
  28. // somewhere between the two extremes:
  29. // view = slice^2
  30. // We need it in range [near, far] so we normalize and scale
  31. // view = slice^2 / maxSlices^2 * (far - near) + near
  32. // Note: Some of these calculations could be moved to CPU
  33. float viewZ = (pow(cellZ, 2) / pow(gGridSize.z, 2)) * (gNearFar.y - gNearFar.x) + gNearFar.x;
  34. return -viewZ;
  35. }
  36. uint calcCellZFromViewZ(float viewZ)
  37. {
  38. // Inverse of calculation in calcViewZFromCellZ
  39. uint cellZ = min((uint)floor(sqrt(((-viewZ - gNearFar.x)*pow(gGridSize.z, 2))/(gNearFar.y - gNearFar.x))), gGridSize.z);
  40. return cellZ;
  41. }
  42. uint calcCellIdx(uint2 pixelPos, float deviceZ)
  43. {
  44. // OpenGL uses lower left for window space origin
  45. #ifdef OPENGL
  46. pixelPos.y = gViewportRectangle.w - pixelPos.y;
  47. #endif
  48. // Note: Use bitshift to divide since gGridPixelSize will be a power of 2
  49. uint2 cellXY = pixelPos / gGridPixelSize;
  50. uint cellZ = calcCellZFromViewZ(convertFromDeviceZ(deviceZ));
  51. uint cellIdx = (cellZ * gGridSize.y + cellXY.y) * gGridSize.x + cellXY.x;
  52. return cellIdx;
  53. }
  54. };
  55. };