#include "CoreRP/ShaderLibrary/Common.hlsl" #pragma only_renderers d3d11 ps4 xboxone vulkan metal switch #pragma kernel KDepthDownsample8DualUav KERNEL_SIZE=8 KERNEL_NAME=KDepthDownsample8DualUav RW_TEXTURE2D(float, _Destination); RW_TEXTURE2D(float, _Source); CBUFFER_START(cb) float4 _Size; // x: src width, y: src height, zw: unused CBUFFER_END #if UNITY_REVERSED_Z # define MIN_DEPTH(l, r) max(l, r) #else # define MIN_DEPTH(l, r) min(l, r) #endif // Downsample a depth texture by taking the min value of sampled pixels // The size of the dispatch is (DstMipSize / KernelSize). [numthreads(KERNEL_SIZE, KERNEL_SIZE, 1)] void KERNEL_NAME(uint2 dispatchThreadId : SV_DispatchThreadID) { // Upper-left pixel coordinate of quad that this thread will read uint2 srcPixelUL = dispatchThreadId << 1; // '_Source' and '_Destination' are two different MIP levels of the same texture. // TODO: Use Gather here instead of 4 loads uint2 size = uint2(_Size.xy) - 1u; float p00 = _Source[min(srcPixelUL + uint2(0u, 0u), size)]; float p10 = _Source[min(srcPixelUL + uint2(1u, 0u), size)]; float p01 = _Source[min(srcPixelUL + uint2(0u, 1u), size)]; float p11 = _Source[min(srcPixelUL + uint2(1u, 1u), size)]; float4 depths = float4(p00, p10, p01, p11); // Select the nearest sample float minDepth = MIN_DEPTH(MIN_DEPTH(depths.x, depths.y), MIN_DEPTH(depths.z, depths.w)); // Write to the final target _Destination[dispatchThreadId] = minDepth; } #undef MIN_DEPTH