Skip to content

#include-ing a file with functions inside it into a vertex shader causes glsl-transformer to output broken code #2247

Open

Description

What happened?

I'm not sure if this is an issue in glsl-transformer itself, or in Iris' usage of it, or if it's even caused by glsl-transform at all (maybe it's whatever handles #include itself?). This is just what I could find without digging too deep.

When a shaderpack uses a "modern" version of GLSL (>=150, #version 330 core in my case), #including a glsl file that contains functions into a terrain pass vertex shader causes the final generated shader source to have its const/in/out/uniform declarations placed after the generated functions that use them, which causes shader compilation to fail and crashes the game.

This is a minimal shaderpack for triggering the bug, only including gbuffers_terrain.fsh/vsh, and a common.glsl file that only contains void a_function() {}: crash.zip
Simply load any world with the shaderpack enabled (or enable it while already in a world), and the game will crash,
with

[xx:xx:xx] [Render thread/WARN]: Shader compilation log for iris:sodium-terrain-gbuffer_solid.vsh: 0(15) : error C1503: undefined variable "a_LightCoord"

shown in the log.

Screenshots

No response

Log output

latest.log

Minecraft Version

Minecraft 1.20.1/Quilt Loader 0.23.1

Iris Version

iris-mc1.20.1-1.6.17

Operating System

Artix Linux

What is your GPU?

Nvidia GeForce GTX 1070

Additional context

I've attached the complete log just in case, but from what I can tell the only relevant part is this:

[21:27:51] [Render thread/WARN]: Shader compilation log for iris:sodium-terrain-gbuffer_solid.vsh: 0(15) : error C1503: undefined variable "a_LightCoord"

[21:27:51] [Render thread/ERROR]: Unreported exception thrown!
java.lang.RuntimeException: Shader compilation failed, see log for details
	at me.jellysquid.mods.sodium.client.gl.shader.GlShader.<init>(GlShader.java:34) ~[sodium-0.5.8mc1.20.1.i0:0/:?]
	at net.coderbot.iris.compat.sodium.impl.shader_overrides.IrisChunkProgramOverrides.createVertexShader(IrisChunkProgramOverrides.java:58) ~[iris-1.6.17.i0:0/:?]
	at net.coderbot.iris.compat.sodium.impl.shader_overrides.IrisChunkProgramOverrides.createShader(IrisChunkProgramOverrides.java:143) ~[iris-1.6.17.i0:0/:?]
	at net.coderbot.iris.compat.sodium.impl.shader_overrides.IrisChunkProgramOverrides.createShaders(IrisChunkProgramOverrides.java:237) ~[iris-1.6.17.i0:0/:?]
	at net.coderbot.iris.compat.sodium.impl.shader_overrides.IrisChunkProgramOverrides.getProgramOverride(IrisChunkProgramOverrides.java:266) ~[iris-1.6.17.i0:0/:?]
	at me.jellysquid.mods.sodium.client.render.chunk.ShaderChunkRenderer.handler$bfg000$iris$begin(ShaderChunkRenderer.java:562) ~[sodium-0.5.8mc1.20.1.i0:0/:?]
	at me.jellysquid.mods.sodium.client.render.chunk.ShaderChunkRenderer.begin(ShaderChunkRenderer.java) ~[sodium-0.5.8mc1.20.1.i0:0/:?]
	at me.jellysquid.mods.sodium.client.render.chunk.DefaultChunkRenderer.render(DefaultChunkRenderer.java:48) ~[sodium-0.5.8mc1.20.1.i0:0/:?]
	at me.jellysquid.mods.sodium.client.render.chunk.RenderSectionManager.renderLayer(RenderSectionManager.java:217) ~[sodium-0.5.8mc1.20.1.i0:0/:?]
	at me.jellysquid.mods.sodium.client.render.SodiumWorldRenderer.drawChunkLayer(SodiumWorldRenderer.java:226) ~[sodium-0.5.8mc1.20.1.i0:0/:?]
	at net.minecraft.class_761.method_3251(class_761.java:10015) ~[minecraft-1.20.1.i0:0/:?]
	at net.minecraft.class_761.method_22710(class_761.java:1253) ~[minecraft-1.20.1.i0:0/:?]
	at net.minecraft.class_757.method_3188(class_757.java:1110) ~[minecraft-1.20.1.i0:0/:?]
	at net.minecraft.class_757.method_3192(class_757.java:880) ~[minecraft-1.20.1.i0:0/:?]
	at net.minecraft.class_310.method_1523(class_310.java:1219) ~[minecraft-1.20.1.i0:0/:?]
	at net.minecraft.class_310.method_1514(class_310.java:802) ~[minecraft-1.20.1.i0:0/:?]
	at net.minecraft.client.main.Main.main(Main.java:250) ~[minecraft-1.20.1-client.jar:?]
	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[?:?]
	at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
	at java.lang.reflect.Method.invoke(Method.java:568) ~[?:?]
	at org.quiltmc.loader.impl.game.minecraft.MinecraftGameProvider.launch(MinecraftGameProvider.java:551) ~[quilt-loader-0.23.1.jar:?]
	at org.quiltmc.loader.impl.launch.knot.Knot.launch(Knot.java:84) ~[quilt-loader-0.23.1.jar:?]
	at org.quiltmc.loader.impl.launch.knot.KnotClient.main(KnotClient.java:28) ~[quilt-loader-0.23.1.jar:?]
	at org.prismlauncher.launcher.impl.StandardLauncher.launch(StandardLauncher.java:87) ~[NewLaunch.jar:?]
	at org.prismlauncher.EntryPoint.listen(EntryPoint.java:130) ~[NewLaunch.jar:?]
	at org.prismlauncher.EntryPoint.main(EntryPoint.java:70) ~[NewLaunch.jar:?]

which is what led me to discover the broken glsl-transformer generated code.

The contents of the minimal shaderpack's gbuffers_terrain.vsh are:

#version 330 core

#include "common.glsl"

const mat4 TEXTURE_MATRIX_2 = mat4(vec4(0.00390625, 0.0, 0.0, 0.0), vec4(0.0, 0.00390625, 0.0, 0.0), vec4(0.0, 0.0, 0.00390625, 0.0), vec4(0.03125, 0.03125, 0.03125, 1.0));

in vec3 vaPosition;
in vec4 vaColor;

in vec2 vaUV0;
in ivec2 vaUV2;

uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;
uniform mat4 textureMatrix;

uniform vec3 chunkOffset;

out vec2 lmcoord;
out vec2 texcoord;
out vec4 glcolor;

void main() {
	gl_Position = projectionMatrix * modelViewMatrix * vec4(vaPosition + chunkOffset, 1.0);
	texcoord = (textureMatrix * vec4(vaUV0, 0.0, 1.0)).xy;
	lmcoord  = (TEXTURE_MATRIX_2 * vec4(vaUV2, 0.0, 1.0)).xy;
	glcolor = vaColor;
}

and the generated code (with comments added to highlight the issue) is:

#version 330 core
// Generated by glsl-transformer
in vec4 a_Color;
in vec2 a_TexCoord;
in uvec4 a_PosId;
vec3 _vert_position;
vec2 _vert_tex_diffuse_coord;
ivec2 _vert_tex_light_coord;
vec4 _vert_color;
uint _draw_id;
const uint MATERIAL_USE_MIP_OFFSET = 0u;
void _vert_init() {
_vert_position = (vec3(a_PosId.xyz) * 4.8828125E-4f + -8.0f);
_vert_tex_diffuse_coord = (a_TexCoord * 1.52587891E-5f);
// a_LightCoord first used here!
_vert_tex_light_coord = a_LightCoord;
_vert_color = vec4(a_Color.rgb * a_Color.a, 1.0f);
_draw_id = (a_PosId.w >> 8u) & 0xffu;
}
uvec3 _get_relative_chunk_coord(uint pos) {
return uvec3(pos) >> uvec3(5u, 0u, 2u) & uvec3(7u, 3u, 7u);
}
vec3 _get_draw_translation(uint pos) {
return _get_relative_chunk_coord(pos) * vec3(16.0f);
}
const mat4 TEXTURE_MATRIX_2 = mat4(vec4(0.00390625f, 0.0f, 0.0f, 0.0f), vec4(0.0f, 0.00390625f, 0.0f, 0.0f), vec4(0.0f, 0.0f, 0.00390625f, 0.0f), vec4(0.03125f, 0.03125f, 0.03125f, 1.0f));
in vec3 vaPosition;
in vec4 vaColor;
in vec2 vaUV0;
// ...but first defined here. 
in ivec2 a_LightCoord;
uniform mat4 iris_ProjectionMatrix;
uniform mat4 iris_ModelViewMatrix;
uniform mat4 textureMatrix;
uniform vec3 u_RegionOffset;
out vec2 lmcoord;
out vec2 texcoord;
out vec4 glcolor;
void main() {
_vert_init();
gl_Position = iris_ProjectionMatrix * iris_ModelViewMatrix * vec4(_vert_position + _get_draw_translation(_draw_id) + u_RegionOffset, 1.0f);
texcoord = (mat4(1.0f) * vec4(_vert_tex_diffuse_coord, 0.0f, 1.0f)).xy;
lmcoord = (TEXTURE_MATRIX_2 * vec4(a_LightCoord, 0.0f, 1.0f)).xy;
glcolor = _vert_color;
}

Removing the #include "common.glsl" line, the generated code becomes:

#version 330 core
// Generated by glsl-transformer
in vec4 a_Color;
in vec2 a_TexCoord;
in uvec4 a_PosId;
+ const mat4 TEXTURE_MATRIX_2 = mat4(vec4(0.00390625f, 0.0f, 0.0f, 0.0f), vec4(0.0f, 0.00390625f, 0.0f, 0.0f), vec4(0.0f, 0.0f, 0.00390625f, 0.0f), vec4(0.03125f, 0.03125f, 0.03125f, 1.0f));
+ in vec3 vaPosition;
+ in vec4 vaColor;
+ in vec2 vaUV0;
+ in ivec2 a_LightCoord;
+ uniform mat4 iris_ProjectionMatrix;
+ uniform mat4 iris_ModelViewMatrix;
+ uniform mat4 textureMatrix;
+ uniform vec3 u_RegionOffset;
+ out vec2 lmcoord;
+ out vec2 texcoord;
+ out vec4 glcolor;
vec3 _vert_position;
vec2 _vert_tex_diffuse_coord;
ivec2 _vert_tex_light_coord;
vec4 _vert_color;
uint _draw_id;
const uint MATERIAL_USE_MIP_OFFSET = 0u;
void _vert_init() {
_vert_position = (vec3(a_PosId.xyz) * 4.8828125E-4f + -8.0f);
_vert_tex_diffuse_coord = (a_TexCoord * 1.52587891E-5f);
_vert_tex_light_coord = a_LightCoord;
_vert_color = vec4(a_Color.rgb * a_Color.a, 1.0f);
_draw_id = (a_PosId.w >> 8u) & 0xffu;
}
uvec3 _get_relative_chunk_coord(uint pos) {
return uvec3(pos) >> uvec3(5u, 0u, 2u) & uvec3(7u, 3u, 7u);
}
vec3 _get_draw_translation(uint pos) {
return _get_relative_chunk_coord(pos) * vec3(16.0f);
}
- const mat4 TEXTURE_MATRIX_2 = mat4(vec4(0.00390625f, 0.0f, 0.0f, 0.0f), vec4(0.0f, 0.00390625f, 0.0f, 0.0f), vec4(0.0f, 0.0f, 0.00390625f, 0.0f), vec4(0.03125f, 0.03125f, 0.03125f, 1.0f));
- in vec3 vaPosition;
- in vec4 vaColor;
- in vec2 vaUV0;
- in ivec2 a_LightCoord;
- uniform mat4 iris_ProjectionMatrix;
- uniform mat4 iris_ModelViewMatrix;
- uniform mat4 textureMatrix;
- uniform vec3 u_RegionOffset;
- out vec2 lmcoord;
- out vec2 texcoord;
- out vec4 glcolor;
void main() {
_vert_init();
gl_Position = iris_ProjectionMatrix * iris_ModelViewMatrix * vec4(_vert_position + _get_draw_translation(_draw_id) + u_RegionOffset, 1.0f);
texcoord = (mat4(1.0f) * vec4(_vert_tex_diffuse_coord, 0.0f, 1.0f)).xy;
lmcoord = (TEXTURE_MATRIX_2 * vec4(a_LightCoord, 0.0f, 1.0f)).xy;
glcolor = _vert_color;
}

Mostly identical, but it correctly places all const/in/out/uniform declarations, including the problematic a_LightCoord, near the top of the file. Putting anything that isn't a function inside common.glsl also seems to produce this correct generated code, so for whatever reason it's just functions that cause this, even if they're unused and not even included in the generated code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    bugSomething is implemented incorrectly

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions