naga icon indicating copy to clipboard operation
naga copied to clipboard

Unable to sample depth texture

Open dristic opened this issue 2 years ago • 5 comments

Hello! I'm trying the challenge from https://sotrh.github.io/learn-wgpu/beginner/tutorial8-depth/#a-pixels-depth

Running WASM in Chrome

I saw there is an overload for textureSample that returns a f32 when passing in a depth texture: https://www.w3.org/TR/WGSL/#texturesample, but this fragment shader fails to run:

@group(0) @binding(0)
var t_depth: texture_depth_2d;
@group(0)@binding(1)
var s_depth: sampler;

@fragment
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
    let depth = textureSample(t_depth, s_depth, in.tex_coords);
    return vec4<f32>(vec3<f32>(depth), 1.0);
}

naga is telling me there is no valid overload for texture which I assume is the textureSample function parameters.

I got it to work using a textureSampleCompare along with a sampler_comparison but that function only seems to return 1.0 or 0.0 if the function passes or fails so I get a solid black/white texture instead of a gradient one based on the depth distance.

Is this currently supported?

dristic avatar Jul 09 '22 23:07 dristic

This code should totally work, can you share some more information about your environment, the back-end you are using and also the VertexOutput that's missing from your code snippet.

Also the w3 link is the old specification, the new one lives at https://gpuweb.github.io/gpuweb/wgsl

JCapucho avatar Aug 06 '22 22:08 JCapucho

The site is hosted on npm after using wasm pack. I tried this on a Windows machine using Chrome. I also tried this on Chrome on my iPad with the same results. Other than that I have been following the tutorials as closely as possible.

I have changed the shader code around since then but I believe this is the rest of the shader:

struct VertexInput {
    @location(0) position: vec3<f32>,
    @location(1) tex_coords: vec2<f32>,
}

struct VertexOutput {
    @builtin(position) clip_position: vec4<f32>,
    @location(0) tex_coords: vec2<f32>,
};

@vertex
fn vs_main(
    model: VertexInput,
) -> VertexOutput {
    var out: VertexOutput;
    out.tex_coords = model.tex_coords;
    out.clip_position = vec4<f32>(model.position, 1.0);
    return out;
}

Let me know if you need any more info!

dristic avatar Aug 12 '22 03:08 dristic

Okay I see the problem, the wgsl is correct but the glsl produced is invalid

#version 310 es

precision highp float;
precision highp int;

struct VertexInput {
    vec3 position;
    vec2 tex_coords;
};
struct VertexOutput {
    vec4 clip_position;
    vec2 tex_coords;
};
uniform highp sampler2DShadow _group_0_binding_0_fs;

layout(location = 0) smooth in vec2 _vs2fs_location0;
layout(location = 0) out vec4 _fs2p_location0;

void main() {
    VertexOutput in_ = VertexOutput(gl_FragCoord, _vs2fs_location0);
    float depth = texture(_group_0_binding_0_fs, vec2(in_.tex_coords)); // <-- Problem is here
    _fs2p_location0 = vec4(vec3(depth), 1.0);
    return;
}

The texture call is invalid because the correct form is

float texture (sampler2DShadow sampler, vec3 P [, float bias] )

The third component of the coordinates vector is the depth reference, this is a problem because glsl doesn't support sampling shadow textures only comparing.

JCapucho avatar Aug 16 '22 11:08 JCapucho

Ah good find! What would the ideal fix be? Using a constant for the bias on ES glsl? I could open up the library and try my hand at a fix if I knew where to start.

dristic avatar Aug 19 '22 03:08 dristic

This problem is more complicated than setting the bias, OpenGL and by consequence glsl don't allow sampling depth textures only comparison operations.

To fix this wgpu or whoever is consuming the shader, would need to orchestrate with naga to bind the same texture as a normal texture so that naga could sample from that image instead

JCapucho avatar Aug 21 '22 22:08 JCapucho