Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clarify invariant gl_FragCoord for WebGL2 #3518

Closed
grovesNL opened this issue Feb 15, 2023 · 2 comments
Closed

Clarify invariant gl_FragCoord for WebGL2 #3518

grovesNL opened this issue Feb 15, 2023 · 2 comments

Comments

@grovesNL
Copy link

Is invariant gl_FragCoord allowed under a fragment shader for both WebGL1 and WebGL2? WebGL1 and WebGL2 seem to disagree currently.

Under

vShaderId: "vertexShaderInvariantGlPosition",
vShaderSuccess: true,
fShaderId: "fragmentShaderInvariantGlFragCoord",
fShaderSuccess: true,
linkSuccess: true,
passMsg: "vertex shader with invariant gl_Position and fragment shader with invariant gl_FragCoord must succeed",
we test that a combination of invariant gl_Position in the vertex shader and invariant gl_FragCoord in the fragment shader under WebGL1 succeeds.

If we port the same test case to WebGL2 it will currently fail under Chrome and Firefox on Windows, e.g. adding a test case with

<script id="vertexShaderInvariantGlPosition" type="text/something-not-javascript">#version 300 es
precision mediump float;
invariant gl_Position;

void main()
{
    gl_Position = vec4(0, 0, 0, 0);
}
</script>
<script id="fragmentShaderInvariantGlFragCoord" type="text/something-not-javascript">#version 300 es
precision mediump float;
invariant gl_FragCoord;
out vec4 my_color;

void main()
{
    my_color = gl_FragCoord;
}
</script>

..results in the following error:

Error compiling FRAGMENT_SHADER '[object WebGLShader]':ERROR: 0:3: 'invariant' : Cannot be qualified as invariant.

(full test case at grovesNL@afe0a53 for convenience)

The ESSL specs both seem to say (under "Invariance" header, ESSL 1.00 10.18 or ESSL 3.00 12.13):

RESOLUTION: Add an invariance qualifier to variables but permit its use only for outputs from the
vertex and fragment shaders. Add a global invariance option for use when complete invariance is
required.

ESSL 3.00 restricts this a little further, which is probably where the shader compiler error originates from:

RESOLUTION: Only allow invariant declarations on outputs.

..but both ESSL 1.00 and ESSL 3.00 also mention gl_FragCoord invariance as a special variable:

How does this rule apply to the built-in special variables.
Option 1: It should be the same as for varyings. But gl_Position is used internally by the rasterizer as
well as for gl_FragCoord so there may be cases where rasterization is required to be invariant but
gl_FragCoord is not.
Option 2: gl_FragCoord and gl_PointCoord can be qualified as invariance if and only if gl_Position and
gl_PointSize are qualified invariant, respectively.

(there's no resolution for these options unfortunately)

gl_FragCoord is an input so it's restricted based on Only allow invariant declarations on outputs. However the line about gl_FragCoord and gl_PointCoord can be qualified as invariance implies that it should be allowed - just restricted so that it can only be specified when gl_Position is also invariant.

@kdashg
Copy link
Contributor

kdashg commented Mar 16, 2023

The essl300 spec is missing the text, but the essl310 spec has it:

How does this rule apply to the built-in special variables?

Option 1: It should be the same as for varyings. But gl_Position is used internally by the rasterizer as
well as for gl_FragCoord so there may be cases where rasterization is required to be invariant but
gl_FragCoord is not.

Option 2: gl_FragCoord and gl_PointCoord can be qualified as invariance if and only if gl_Position and
gl_PointSize are qualified invariant, respectively.

RESOLUTION: Option 1.

I believe that the intent is actually:

How does this rule apply to the built-in special variables?

Option 1: It should be the same as for varyings.

But [because] gl_Position is used internally by the rasterizer as
well as for gl_FragCoord so there may be cases where rasterization is required to be invariant but
gl_FragCoord is not [, consider:]

Option 2: gl_FragCoord and gl_PointCoord can be qualified as invariance if and only if gl_Position and
gl_PointSize are qualified invariant, respectively.

RESOLUTION: Option 1. [but we acknowledge here the gap in flexibility that this leaves]

That's how I'm going to rule this.
Thanks for bringing this to our attention!

@kdashg kdashg closed this as completed Mar 16, 2023
@grovesNL
Copy link
Author

Sounds great, thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants