Fix WebGPU error when sampling depth texture in shader which requires explicit UnfilterableFloat sampler type

This commit is contained in:
2026-02-26 16:59:25 +01:00
parent 63f19aa4d6
commit b36c757753
11 changed files with 167 additions and 134 deletions
+12
View File
@@ -136,6 +136,18 @@ SamplerComparisonState ShadowSamplerLinear : register(s5);
// General purpose macros
#define SAMPLE_RT(rt, texCoord) rt.SampleLevel(SamplerPointClamp, texCoord, 0)
#define SAMPLE_RT_LINEAR(rt, texCoord) rt.SampleLevel(SamplerLinearClamp, texCoord, 0)
#if defined(WGSL)
// WebGPU doesn't allow to sample depth texture with regular sampler, need to use Load instead of Sample and get texture size for UV to pixel coordinate conversion
float4 LoadTextureWGSL(Texture2D tex, float2 uv)
{
uint2 size;
tex.GetDimensions(size.x, size.y);
return tex.Load(uint3(size * uv, 0));
}
#define SAMPLE_RT_LOAD(rt, texCoord) LoadTextureWGSL(rt, texCoord)
#else
#define SAMPLE_RT_LOAD(rt, texCoord) SAMPLE_RT(rt, texCoord)
#endif
#define HDR_CLAMP_MAX 65472.0
#define PI 3.1415926535897932
+1 -1
View File
@@ -34,7 +34,7 @@ META_PERMUTATION_1(VOLUMETRIC_FOG=1)
float4 PS_Fog(Quad_VS2PS input) : SV_Target0
{
// Get world space position at given pixel coordinate
float rawDepth = SAMPLE_RT(Depth, input.TexCoord).r;
float rawDepth = SAMPLE_RT_LOAD(Depth, input.TexCoord).r;
GBufferData gBufferData = GetGBufferData();
float3 viewPos = GetViewPos(gBufferData, input.TexCoord, rawDepth);
float3 worldPos = mul(float4(viewPos, 1), gBufferData.InvViewMatrix).xyz;
+1 -20
View File
@@ -56,7 +56,7 @@ float3 GetWorldPos(GBufferData gBuffer, float2 uv, float deviceDepth)
// Sample raw device depth buffer
float SampleZ(float2 uv)
{
return SAMPLE_RT(Depth, uv).r;
return SAMPLE_RT_LOAD(Depth, uv).r;
}
// Sample linear depth
@@ -125,25 +125,6 @@ GBufferSample SampleGBuffer(GBufferData gBuffer, float2 uv)
return result;
}
// Sample GBuffer (fast - only few parameters are being sampled)
GBufferSample SampleGBufferFast(GBufferData gBuffer, float2 uv)
{
GBufferSample result;
// Sample GBuffer
float4 gBuffer1 = SAMPLE_RT(GBuffer1, uv);
// Decode normal and shading model
result.Normal = DecodeNormal(gBuffer1.rgb);
result.ShadingModel = (int)(gBuffer1.a * 3.999);
// Calculate view space position
result.ViewPos = GetViewPos(gBuffer, uv);
result.WorldPos = mul(float4(result.ViewPos, 1), gBuffer.InvViewMatrix).xyz;
return result;
}
#if defined(USE_GBUFFER_CUSTOM_DATA)
// Sample GBuffer custom data only
+3 -3
View File
@@ -204,7 +204,7 @@ float4 PS_MotionBlur(Quad_VS2PS input) : SV_Target
// Sample pixel depth
GBufferData gBufferData = GetGBufferData();
float pixelDepth = LinearizeZ(gBufferData, SAMPLE_RT(Input3, input.TexCoord).x);
float pixelDepth = LinearizeZ(gBufferData, SAMPLE_RT_LOAD(Input3, input.TexCoord).x);
// Calculate noise to make it look better with less samples per pixel
float noise = FullscreenGradientNoise(input.TexCoord);
@@ -229,12 +229,12 @@ float4 PS_MotionBlur(Quad_VS2PS input) : SV_Target
float weight1 = 1;
float weight2 = 1;
#else
float depth1 = LinearizeZ(gBufferData, SAMPLE_RT(Input3, sampleUV1).x);
float depth1 = LinearizeZ(gBufferData, SAMPLE_RT_LOAD(Input3, sampleUV1).x);
float2 velocity1 = Input1.SampleLevel(SamplerPointClamp, sampleUV1, 0).xy;
velocity1 = ClampVelocity(velocity1);
float velocityLength1 = length(velocity1);
float depth2 = LinearizeZ(gBufferData, SAMPLE_RT(Input3, sampleUV2).x);
float depth2 = LinearizeZ(gBufferData, SAMPLE_RT_LOAD(Input3, sampleUV2).x);
float2 velocity2 = Input1.SampleLevel(SamplerPointClamp, sampleUV2, 0).xy;
velocity2 = ClampVelocity(velocity2);
float velocityLength2 = length(velocity2);
+1 -1
View File
@@ -116,7 +116,7 @@ float3 TraceScreenSpaceReflection(
while (currSampleIndex < numSamples)
{
// Sample depth buffer and calculate depth difference
float currSample = SAMPLE_RT(depthBuffer, currOffset.xy).r;
float currSample = SAMPLE_RT_LOAD(depthBuffer, currOffset.xy).r;
float depthDiff = currOffset.z - currSample;
// Check intersection
+2 -2
View File
@@ -35,7 +35,7 @@ float4 PS(Quad_VS2PS input) : SV_Target0
float2 velocity = SAMPLE_RT_LINEAR(MotionVectors, input.TexCoord).xy;
float velocityLength = length(velocity);
float2 prevUV = input.TexCoord - velocity;
float prevDepth = LinearizeZ(GBuffer, SAMPLE_RT(Depth, prevUV).r);
float prevDepth = LinearizeZ(GBuffer, SAMPLE_RT_LOAD(Depth, prevUV).r);
// Find the closest pixel in 3x3 neighborhood
float currentDepth = 1;
@@ -55,7 +55,7 @@ float4 PS(Quad_VS2PS input) : SV_Target0
neighborhoodMax = max(neighborhoodMax, neighbor);
neighborhoodSum += neighbor;
float neighborDepth = LinearizeZ(GBuffer, SAMPLE_RT(Depth, sampleUV).r);
float neighborDepth = LinearizeZ(GBuffer, SAMPLE_RT_LOAD(Depth, sampleUV).r);
float depthDiff = abs(max(neighborDepth - prevDepth, 0));
minDepthDiff = min(minDepthDiff, depthDiff);
if (x == 0 && y == 0)