Ingen beskrivning
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

OcclusionCullingCommon.hlsl 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. #ifndef _OCCLUSION_CULLING_COMMON_H
  2. #define _OCCLUSION_CULLING_COMMON_H
  3. // If using this the shader should add
  4. // #pragma multi_compile _ OCCLUSION_DEBUG
  5. // before including this file
  6. #include "Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/OcclusionCullingCommon.cs.hlsl"
  7. #include "Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/OcclusionCullingCommonShaderVariables.cs.hlsl"
  8. #include "Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/OcclusionTestCommon.hlsl"
  9. #include "Packages/com.unity.render-pipelines.core/Runtime/GPUDriven/GeometryUtilities.hlsl"
  10. #define OCCLUSION_ENABLE_GATHER_TRIM 1
  11. TEXTURE2D(_OccluderDepthPyramid);
  12. SAMPLER(s_linear_clamp_sampler);
  13. #ifdef OCCLUSION_DEBUG
  14. RWStructuredBuffer<uint> _OcclusionDebugOverlay;
  15. uint OcclusionDebugOverlayOffset(uint2 coord)
  16. {
  17. return OCCLUSIONCULLINGCOMMONCONFIG_DEBUG_PYRAMID_OFFSET + coord.x + _OccluderMipLayoutSizeX * coord.y;
  18. }
  19. #endif
  20. bool IsOcclusionVisible(float3 frontCenterPosRWS, float2 centerPosNDC, float2 radialPosNDC, int subviewIndex)
  21. {
  22. bool isVisible = true;
  23. float queryClosestDepth = ComputeNormalizedDeviceCoordinatesWithZ(frontCenterPosRWS, _ViewProjMatrix[subviewIndex]).z;
  24. bool isBehindCamera = dot(frontCenterPosRWS, _FacingDirWorldSpace[subviewIndex].xyz) >= 0.f;
  25. float2 centerCoordInTopMip = centerPosNDC * _DepthSizeInOccluderPixels.xy;
  26. float radiusInPixels = length((radialPosNDC - centerPosNDC) * _DepthSizeInOccluderPixels.xy);
  27. // log2 of the radius in pixels for the gather4 mip level
  28. int mipLevel = 0;
  29. float mipPartUnused = frexp(radiusInPixels, mipLevel);
  30. mipLevel = max(mipLevel + 1, 0);
  31. if (mipLevel < OCCLUSIONCULLINGCOMMONCONFIG_MAX_OCCLUDER_MIPS && !isBehindCamera)
  32. {
  33. // scale our coordinate to this mip
  34. float2 centerCoordInChosenMip = ldexp(centerCoordInTopMip, -mipLevel);
  35. int4 mipBounds = _OccluderMipBounds[mipLevel];
  36. mipBounds.y += subviewIndex * _OccluderMipLayoutSizeY;
  37. if ((_OcclusionTestDebugFlags & OCCLUSIONTESTDEBUGFLAG_ALWAYS_PASS) == 0)
  38. {
  39. // gather4 occluder depths to cover this radius
  40. float2 gatherUv = (float2(mipBounds.xy) + clamp(centerCoordInChosenMip, .5f, float2(mipBounds.zw) - .5f)) * _OccluderDepthPyramidSize.zw;
  41. float4 gatherDepths = GATHER_TEXTURE2D(_OccluderDepthPyramid, s_linear_clamp_sampler, gatherUv);
  42. float occluderDepth = FarthestDepth(gatherDepths);
  43. isVisible = IsVisibleAfterOcclusion(occluderDepth, queryClosestDepth);
  44. }
  45. #ifdef OCCLUSION_DEBUG
  46. // show footprint of gather4 in debug output
  47. bool countForOverlay = ((_OcclusionTestDebugFlags & OCCLUSIONTESTDEBUGFLAG_COUNT_VISIBLE) != 0);
  48. if (!isVisible)
  49. countForOverlay = !countForOverlay;
  50. if (countForOverlay)
  51. {
  52. uint2 debugCoord = mipBounds.xy + uint2(clamp(int2(centerCoordInChosenMip - .5f), 0, mipBounds.zw - 2));
  53. InterlockedAdd(_OcclusionDebugOverlay[OcclusionDebugOverlayOffset(debugCoord + uint2(0, 0))], 1);
  54. InterlockedAdd(_OcclusionDebugOverlay[OcclusionDebugOverlayOffset(debugCoord + uint2(1, 0))], 1);
  55. InterlockedAdd(_OcclusionDebugOverlay[OcclusionDebugOverlayOffset(debugCoord + uint2(0, 1))], 1);
  56. InterlockedAdd(_OcclusionDebugOverlay[OcclusionDebugOverlayOffset(debugCoord + uint2(1, 1))], 1);
  57. // accumulate the total in the first slot
  58. InterlockedAdd(_OcclusionDebugOverlay[0], 1);
  59. }
  60. #endif
  61. }
  62. return isVisible;
  63. }
  64. bool IsOcclusionVisible(BoundingObjectData data, int subviewIndex)
  65. {
  66. return IsOcclusionVisible(data.frontCenterPosRWS, data.centerPosNDC, data.radialPosNDC, subviewIndex);
  67. }
  68. bool IsOcclusionVisible(SphereBound boundingSphere, int subviewIndex)
  69. {
  70. BoundingObjectData data = CalculateBoundingObjectData(
  71. boundingSphere,
  72. _ViewProjMatrix[subviewIndex],
  73. _ViewOriginWorldSpace[subviewIndex],
  74. _RadialDirWorldSpace[subviewIndex],
  75. _FacingDirWorldSpace[subviewIndex]);
  76. return IsOcclusionVisible(data, subviewIndex);
  77. }
  78. bool IsOcclusionVisible(CylinderBound cylinderBound, int subviewIndex)
  79. {
  80. BoundingObjectData data = CalculateBoundingObjectData(
  81. cylinderBound,
  82. _ViewProjMatrix[subviewIndex],
  83. _ViewOriginWorldSpace[subviewIndex],
  84. _RadialDirWorldSpace[subviewIndex],
  85. _FacingDirWorldSpace[subviewIndex]);
  86. return IsOcclusionVisible(data, subviewIndex);
  87. }
  88. #endif