OpenGL ES (2.0) Shading Language: How to input boolean into vertex shader and pass to fragment shader?

KomodoDave picture KomodoDave · Jan 14, 2012 · Viewed 19.7k times · Source

I'm trying to pass a boolean into my vertex shader for the first time; I've only been using floats until now.

The boolean in question is primitive-specific so cannot be passed as a uniform. However it has the same value for all vertices of any given primitive.

It seems from the Khronos spec that 'varying' is the only way to pass data into the fragment shader, but unsurprisingly declaring 'varying bool my_bool;' causes a parser error when defined in my vertex shader.

I'm passing the boolean into my vertex shader as:

attribute bool a_my_bool;

I define a varying in an attempt to pass to the fragment shader:

varying bool v_my_bool;
void main() {
    // ...
    v_my_bool = a_my_bool;
}

Could someone please tell me how I can achieve what I intend?

Answer

Laurence Gonsalves picture Laurence Gonsalves · Mar 21, 2012

From §4.3.5 of The OpenGL® ES Shading Language version 1.0.17 (PDF):

The varying qualifier can be used only with the data types float, vec2, vec3, vec4, mat2, mat3, and mat4, or arrays of these.

And from §4.3.3:

The attribute qualifier can be used only with the data types float, vec2, vec3, vec4, mat2, mat3, and mat4. Attribute variables cannot be declared as arrays or structures.

So you can't have an attribute bool, let alone a varying bool, according to the spec.

If you really need a boolean value per vertex you could use 0.0 for false and 1.0 for true. When testing, check for x > 0.5. eg:

// vertex shader
attribute float a_my_bool;
varying float v_my_bool;
void main() {
    // ...
    v_my_bool = a_my_bool;
}

// fragment shader
varying float v_my_bool;
void main() {
    if (v_my_bool > 0.5) {
        // my_bool is true
        // ...
    } else {
        // my_bool is false
        // ...
    }
}

As long as all vertices in each triangle have the same value this should work. If they aren't consistent, then you'll end up with different fragments for the same triangle behaving differently. (If you stick to 0.0 and 1.0 the quarter of the triangle closest to the "odd" corner will behave differently from the rest.)