Quick answer: GameMaker shader_get_uniform returning -1 even though the uniform exists in the shader? The uniform was optimized out because nothing uses it — reference it in the shader code path or it’s stripped.
A water shader takes u_amplitude but shader_get_uniform returns -1. The variable is declared but never read in the fragment, so the compiler dropped it.
Optimizer Drops Unused
GLSL/HLSL compilers strip unused uniforms. If u_amplitude isn’t referenced in any code path, the linker sees no use and removes it. shader_get_uniform can’t find what isn’t there.
Reference It
Make sure the uniform is actually read — even gl_FragColor.r += u_amplitude * 0.0001; keeps it alive for testing. Once you wire it for real, it stays.
Cache Locations
// in Create
u_amp_loc = shader_get_uniform(shd_water, "u_amplitude");
// in Draw
shader_set_uniform_f(u_amp_loc, amp);Looking up per-frame is wasted work — cache once.
Verifying
The uniform location is ≥ 0, shader_set_uniform_f takes effect, and the shader visibly responds.
“Unused uniforms get optimized out. Reference them in a real code path.”
Don’t guess — log uniform locations at startup. If one is −1 you know immediately, not after the artist reports a broken effect.