155 lines
5.4 KiB
Plaintext
Raw Normal View History

2025-06-20 18:14:38 +08:00
Shader "Hidden/HizCull"
{
SubShader
{
2025-06-23 19:18:41 +08:00
ZTest Off
ZWrite Off
2025-06-20 18:14:38 +08:00
Pass
{
HLSLPROGRAM
#pragma vertex Vertex
#pragma fragment CullFrag
#pragma enable_d3d11_debug_symbols
2025-06-24 21:26:55 +08:00
#pragma target 5.0
2025-06-20 18:14:38 +08:00
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct Attributes
{
2025-06-23 19:18:41 +08:00
float4 positionOS : POSITION;
float2 texcoord : TEXCOORD0;
2025-06-20 18:14:38 +08:00
};
struct Varyings
{
2025-06-23 19:18:41 +08:00
float2 uv : TEXCOORD0;
float4 positionCS : SV_POSITION;
2025-06-20 18:14:38 +08:00
};
Varyings Vertex(Attributes input)
{
Varyings output = (Varyings)0;
output.positionCS = TransformObjectToHClip(input.positionOS.xyz);
output.uv = input.texcoord;
return output;
}
2025-06-23 19:18:41 +08:00
2025-06-20 18:14:38 +08:00
TEXTURE2D(_ObjectAABBTexture0);
SAMPLER(sampler_ObjectAABBTexture0);
TEXTURE2D(_ObjectAABBTexture1);
SAMPLER(sampler_ObjectAABBTexture1);
2025-06-23 19:18:41 +08:00
2025-06-20 18:14:38 +08:00
TEXTURE2D(_DepthPyramidTexture);
SAMPLER(sampler_DepthPyramidTexture);
float4x4 _GPUCullingVP;
float2 _MipmapLevelMinMaxIndex;
float2 _Mip0Size;
float4 _MipOffsetAndSize[16];
2025-06-23 19:18:41 +08:00
2025-06-20 18:14:38 +08:00
static const float3 aggressiveExtentArray[8] =
{
float3(1, 1, 1),
float3(1, 1, -1),
float3(1, -1, 1),
float3(1, -1, -1),
float3(-1, 1, 1),
float3(-1, 1, -1),
float3(-1, -1, 1),
float3(-1, -1, -1)
};
2025-06-23 19:18:41 +08:00
float3 TransferNDC(float3 pos)
{
float4 ndc = mul(_GPUCullingVP, float4(pos, 1.0));
ndc.xyz /= ndc.w;
ndc.xy = ndc.xy * 0.5f + 0.5f;
ndc.y = 1 - ndc.y;
return ndc.xyz;
}
2025-06-20 18:14:38 +08:00
half CullFrag(Varyings input) : SV_Target
{
float2 uv = input.uv;
2025-06-23 19:18:41 +08:00
float4 aabbCenter = SAMPLE_TEXTURE2D_LOD(_ObjectAABBTexture0, sampler_ObjectAABBTexture0, uv, 0.0);
2025-06-20 18:14:38 +08:00
float4 aabbSize = SAMPLE_TEXTURE2D_LOD(_ObjectAABBTexture1, sampler_ObjectAABBTexture1, uv, 0.0);
2025-06-23 19:18:41 +08:00
float3 aabbExtent = aabbSize.xyz;
2025-06-20 18:14:38 +08:00
UNITY_BRANCH
2025-06-23 19:18:41 +08:00
if (aabbCenter.a == 0.0)
2025-06-20 18:14:38 +08:00
{
return 1;
}
2025-06-23 19:18:41 +08:00
2025-06-20 18:14:38 +08:00
#ifdef UNITY_REVERSED_Z
float minZ = 0;
#else
float minZ = 1;
#endif
float2 maxXY = 0;
float2 minXY = 1;
2025-06-23 19:18:41 +08:00
for (uint i = 0; i < 8; ++i)
2025-06-20 18:14:38 +08:00
{
2025-06-23 19:18:41 +08:00
float3 boxCorner = aabbCenter + aabbExtent * aggressiveExtentArray[i];
float4 clipPos = mul(_GPUCullingVP, float4(boxCorner, 1));
clipPos /= clipPos.w;
clipPos.xy = clipPos.xy * 0.5f + 0.5f;
#if UNITY_UV_STARTS_AT_TOP
clipPos.y = 1 - clipPos.y;
#endif
minXY = min(clipPos.xy, minXY);
maxXY = max(clipPos.xy, maxXY);
#ifdef UNITY_REVERSED_Z
minZ = max(minZ, clipPos.z);
#else
minZ = min(minZ, clipPos.z);
#endif
2025-06-20 18:14:38 +08:00
}
2025-06-25 15:01:58 +08:00
if(maxXY.x < 0 || maxXY.y < 0 || minXY.x > 1 || minXY.y > 1)
{
return 1;
}
2025-06-20 18:14:38 +08:00
float4 boxUVs = float4(minXY, maxXY);
2025-06-23 19:18:41 +08:00
2025-06-20 18:14:38 +08:00
float2 size = (boxUVs.zw - boxUVs.xy) * _Mip0Size.xy;
2025-06-23 19:18:41 +08:00
float mip = (log2(max(size.x, size.y)));
2025-06-24 21:26:55 +08:00
mip = ceil(mip);
2025-06-20 18:14:38 +08:00
mip = clamp(mip, _MipmapLevelMinMaxIndex.x, _MipmapLevelMinMaxIndex.y);
2025-06-23 19:18:41 +08:00
2025-06-20 18:14:38 +08:00
// float level_lower = max(mip - 1, 0);
// float2 scale = exp2(-level_lower) / _Mip0Size.xy;
// float2 a = floor(boxUVs.xy*scale);
// float2 b = ceil(boxUVs.zw*scale);
// float2 dims = b - a;
//
// // Use the lower level if we only touch <= 2 texels in both dimensions
// if (dims.x <= 2 && dims.y <= 2)
// mip = level_lower;
2025-06-24 21:26:55 +08:00
2025-06-20 18:14:38 +08:00
float4 offsetAndSize = _MipOffsetAndSize[mip];
int4 pxMinMax = boxUVs * offsetAndSize.zwzw + offsetAndSize.xyxy;
2025-06-23 19:18:41 +08:00
float4 depth = float4(LOAD_TEXTURE2D_LOD(_DepthPyramidTexture, pxMinMax.xy, 0).r,
LOAD_TEXTURE2D_LOD(_DepthPyramidTexture, pxMinMax.zy, 0).r,
LOAD_TEXTURE2D_LOD(_DepthPyramidTexture, pxMinMax.xw, 0).r,
LOAD_TEXTURE2D_LOD(_DepthPyramidTexture, pxMinMax.zw, 0).r
2025-06-20 18:14:38 +08:00
);
2025-06-23 19:18:41 +08:00
2025-06-20 18:14:38 +08:00
#ifdef UNITY_REVERSED_Z
depth.xy = min(depth.xy, depth.zw);
depth.x = min(depth.x, depth.y);
2025-06-23 19:18:41 +08:00
return minZ > depth.x ? 0 : 1;
2025-06-20 18:14:38 +08:00
#else
depth.xy = max(depth.xy, depth.zw);
depth.x = max(depth.x, depth.y);
2025-06-23 19:18:41 +08:00
return minZ < depth.x ? 1 : 0;
2025-06-20 18:14:38 +08:00
#endif
}
ENDHLSL
}
}
2025-06-23 19:18:41 +08:00
}