Search code examples
opengl-esglslmali

What are the rules for the precision of casting operations in GLSL


I have a GL_R16UI texture in OpenGL ES 3.0 on an Android device (Google Pixel 6). I'm then drawing a screen rect, and copying the texture to the RGBA8 output using the following fragment shader:

uniform mediump usampler2D texture_sampler;
in highp vec2 texcoords;
out lowp vec4 out_color;
void main() {
    mediump uint v = texture(texture_sampler, vec2(0.5, 0.5)).r;
    highp float v2 = float(v);  // need temporary for android
    out_color = vec4(v2 / 65535.0, 0, 0, 1);
    // out_color = vec4(float(v) / 65535.0, 0, 0, 1); // works only on desktop
}

v is set to 120 * 256. no errors are shown for vec4(float(v) / 65535.0, .., the result simply goes to 0. it also goes to zero when i replace highp float v2 with mediump float v2.

  • What are the rules of casting? Which precision will a float(v) without temporary yield?
  • Why is it, that using mediump float v2 yields a 0? I would think that mediump should be enough to yield something != 0.

Solution

  • The max value of a 16-bit float is 65504.0. The divisor for x/65535.0 is x/+INF in fp16, so you get zero.

    // works only on desktop

    Desktop is probably ignoring the mediump and giving you fp32 anyway.