Accessing Shader Globals in GLSL

Godot Version

4.3beta1

Question

Hello!
Is there any way to access Shader Global variables inside pure GLSL code?
I need to use GLSL to make a CompositorEffect which in turn needs a Shader Global variable but I can’t seem to find a way to do this.

Or alternatively, is there a way to use gdshaders in a RenderingDevice and then use global uniforms there?

Do I really need to add the variable manually as a push constant?

Check out the global uniform section.

The section doesn’t even mention GLSL, that’s the reason I’m asking in the forums. global uniform is GDShader syntax and as far as I know there is no equivalent in GLSL.

I’m not sure I understand your confusion.

In GLSL you typically draw your scene from scratch. and typical c like program syntax rules apply. Godot does it per object with materials.

There is two types of globals in gdshader. A variable defined outside the vertex/fragment/light function.

varying keyword to save values between those functions.

uniform keyword to pass CPU side data

And the second type, which is a basically an extension of the first from CPU land

global uniform same as uniform but allows you to utilize the project settings defined value for shaders that any need to use the same value.

This can be found in the shader reference manual in the Godot docs.

1 Like

My question is whether there is a way to automatically (with preprocessor instructions or something akin to that) get shader globals in GLSL or if I’m gonna need to manually push them to the shader, which is what I’m doing right now.

Alternatively If there is no such way, is there a way to use GDShaders instead of GLSL for use with RenderingDevice, such as when making Compute Shaders? I’m pretty sure there isn’t but I may be wrong.

I’m still a little confused by the ask. Have you seen these docs?

Yes I have, that is the reason I am asking here, once again.

I am simply trying to access the shader variables defined in the Shader Globals Project Settings in a GLSL Compute Buffer.
Right now I am using push constants which work, however, I feel as if there is a better way.

I have read pretty much all the documentation concerning Godot’s usage of GLSL, I have even dug into the Godot Source Code, However I cannot find any example of getting global shader variables in a Compute Shader in a similar way to using

global uniform

in GDShader.

To put it bluntly, I am trying to be lazy and avoid pushing the variables manually every time I want to use them in a Compute Shader.

For example, if I create new Shader Globals and want to use them in the Compute Shader, I have to manually add them like this:

float[] computePushConstant = [
	renderSize.X, renderSize.Y, 0, 0,
	waterColor.R, waterColor.G, waterColor.B, 0,
];
byte[] computePushConstantBytes = new byte[computePushConstant.Length * sizeof(float)];
Buffer.BlockCopy(computePushConstant, 0, computePushConstantBytes, 0, computePushConstantBytes.Length);

RenderingDevice.DrawCommandBeginLabel("Render Underwater Effect", new Color(1f, 1f, 1f));
long computeList = RenderingDevice.ComputeListBegin();
RenderingDevice.ComputeListBindComputePipeline(computeList, computePipeline);
RenderingDevice.ComputeListBindColor(computeList, computeShader, sceneBuffers, view, 0);
RenderingDevice.ComputeListBindDepth(computeList, computeShader, sceneBuffers, view, nearestSampler, 1);
RenderingDevice.ComputeListBindImage(computeList, computeShader, waterMap, 2);
RenderingDevice.ComputeListSetPushConstant(computeList, computePushConstantBytes, (uint)computePushConstantBytes.Length);
RenderingDevice.ComputeListDispatch(computeList, xGroups, yGroups, 1);
RenderingDevice.ComputeListEnd();
RenderingDevice.DrawCommandEndLabel();

And Getting them in the shader like this:

layout(push_constant, std430) uniform Params {
	vec2 render_size; // Size of the Screen
	vec3 water_color; // Color of the Water
} params;

However, I want to try and avoid doing that as it adds a potential for Human Error if I end up doing this again later.

Is it possible yes or no?

No,

That seems like the only way to do it. And it might be the best way because you can’t make assumptions about the data types being represented in Godot, vs what you need/want to use in the compute shader.