jmonkeyengine icon indicating copy to clipboard operation
jmonkeyengine copied to clipboard

Use interface blocks instead of raw varyings

Open codex128 opened this issue 8 months ago • 1 comments

I think it would be a good idea to begin using interface blocks rather than directly using varying/in/out variables to pass data between shader stages.

So instead of this:

out vec3 wPosition;
out vec3 wNormal;
...
wPosition = ...

We would use this:

out VERTEX_OUT {
    vec3 wPosition;
    vec3 wNormal;
} vsout;
...
vsout.wPosition = ...

Using interface blocks has two advantages. One is that it will make the shader code much more organized, and secondly it will also help immensely with inserting more stages between two existing ones. For example, inserting a geometry shader between PBRLighting.vert and PBRLighting.frag is difficult, if not impossible, because the names of the vertex shader output variables and fragment shader input variables necessarily conflict.

in vec3 wPosition[]; // input from vertex shader
out vec3 wPosition; // output to fragment shader
// cannot publish wPosition to the fragment shader due to name conflict

With interface blocks, this is much easier to do.

in VERTEX_OUT {
    vec3 wPosition;
} gsin;
out GEOMETRY_OUT {
    vec3 wPosition;
} gsout;
...
gsout.wPosition = gsin.wPosition;

A disadvantage of switching to interface blocks is that it may break compatibility with older OpenGL versions. Perhaps this could be circumvented using #ifdef or declaring seperate shader files for different OpenGL versions.

codex128 avatar May 23 '25 17:05 codex128

If people like the idea, I can begin on a PR for this as my time allows, unless someone beats me to it.

codex128 avatar May 23 '25 17:05 codex128