First up: I'm using the Compatibility Renderer because I need a web build. I know there are simpler solutions with the other renderers, but they're not options for me. I'm currently using Godot 4.3
I am trying to write a value to a "buffer" (a viewport with a camera that gets the same view as my "main" camera, but writes out different values via an if-statement in the shader), and then in another shader read out that value for use. The viewport is linked to a "Shader Global" sampler2D. I have the Shader Global created in the Project settings, and link them up via code (because linking them through the GUI didn't always seem to work.)
RenderingServer.global_shader_parameter_set("buffer_texture", bufferViewport.get_texture())
That all works fine. I followed the Advanced Post Processing tutorial and have a "post processing" quad so I can see what's in the buffer, and that part seems ok.
Normal View
Post-Processing Overlay
You can see that the spider (on the ground, ignore the one in the upper left for this) is a lighter green than the walls/floor, which is good. I should be writing 255 for the spider and 128 for the walls/floor (and the "sky" is just whatever for now), so that's as expected. (Just using green for now, I have plans for the other values later.)
So, I can write something to the buffer, and read it back out again. Yay!
I also have another shader that does screen-space decals. This also works fine. We can draw with a decal on the spider and floor/walls.
What I would like, is for the decal to draw on the floor/walls but not the spider. That's what the buffer is for, I can look in there and see if that pixel is the floor/walls or spider. I can read a value out of the buffer in my decal shader, but it's not the value I put in.
In the shader that writes TO the buffer I have:
ALBEDO.y = (float(number)/256.0);
The other two values are 0.0. We divide the actual number by 256 to make it fit into the 0-1 that albedo wants (I think?)
Then, in the decal shader we read OUT the value and multiple by 256:
global uniform sampler2D buffer_texture : filter_nearest, repeat_disable;
...
vec2 cull_xy = texture(buffer_texture, SCREEN_UV).xy;
float number = cull_xy.y * 256.0;
If I use "number" in an if-statement to determine if I should draw or discard the decal pixel, have to "guess" at what number I'll get out.
For example, discarding the decal when the buffer is > 76.0 && < 78.0 does what I want:
Discarding if > 34.5 || < 33.5 also works. So 255 seems to be 77 and 128 is seems to be 34. Some sort of scaling going on, but I don't know what. I'd like to be able to just put in a number and get the same number back out, so I don't have to guess each time. Anybody know what's happening here?
I've tried some of the srgb to linear mappings I've found via web-searches, but they also don't seem to give me the number I put in. Maybe this has changed recently? Maybe I'm doing things in the wrong order?