Hello,
I'm working on WebVR Servo for Android and couldn't get some basic WebGL canvas to show on a simple html. It also happens with other non WebGL simple elements as images. After some debugging found that the textures from images and WebGL canvases are ok but the problem is related to the clipping implementation.
In the ps_image.fs.gl shader, the textureLod(sColor0, st, 0.0) gives the correct color but it's multiplied by a 0 alpha. The alpha 0 is set by the call to do_clip() function.
**alpha = min(alpha, do_clip());**
// We calculate the particular tile this fragment belongs to, taking into
// account the spacing in between tiles. We only paint if our fragment does
// not fall into that spacing.
vec2 position_in_tile = mod(relative_pos_in_rect, vStretchSize + vTileSpacing);
// We clamp the texture coordinates to the half-pixel offset from the borders
// in order to avoid sampling outside of the texture area.
vec2 st = vTextureOffset + ((position_in_tile / vStretchSize) * vTextureSize);
st = clamp(st, vStRect.xy, vStRect.zw);
alpha = alpha * float(all(bvec2(step(position_in_tile, vStretchSize))));
oFragColor = vec4(1.0, 1.0, 1.0, alpha) * textureLod(sColor0, st, 0.0);
write_clip() function is correctly called in the vertex shader. The problem seems to be that textureSize(sCache, 0).xy returns a vec(0, 0) value, which leads to an invalid alpha value. In the same demo run on my desktop machine, textureSize(sCache, 0).xy returns a vec(1, 1) value, which leads to a correct alpha value.
Thanks @MortimerGoro !
So basically we are not setting sCache properly in some cases. Do you mind sharing the test case?
I see that we are setting it in load_program, which seems fine:
let u_cache = gl::get_uniform_location(program.id, "sCache");
if u_cache != -1 {
gl::uniform_1i(u_cache, TextureSampler::Cache as i32);
}
And indeed we are not always actually binding it. We only bind it for the passes following the first one. I suggest we bind a dummy texture for the first pass each time.
@kvark the testcase I've using is the test_webgl_triangle.html file on Servo tests/html folder. It also happens with a plain<img src="test.png"> in a simple html page, with no javascript.
I see that we are setting it in load_program, which seems fine:
let u_cache = gl::get_uniform_location(program.id, "sCache"); if u_cache != -1 { gl::uniform_1i(u_cache, TextureSampler::Cache as i32); }
Yes that uniform is correctly set on Android. I think that the texture bind wasn't done on Desktop OpenGL too. I put some log calls and only saw that 0 texture_id was bound. But it seems that textureSize(texure_id = 0) leads to undefined behavior on the shader, gives (1,1) on desktop and (0,0) on Android.
Hold tight, fix is coming ;)
FYI, this is one of the cases that a bind-less API like gfx-rs would prevent at compile time.
Most helpful comment
Hold tight, fix is coming ;)
FYI, this is one of the cases that a bind-less API like gfx-rs would prevent at compile time.