1
\$\begingroup\$

In Godot 4.1.1, I'm trying to use ViewportTextures to capture values generated by some shaders for use in another shader. One SubViewport is capturing the result of an unshaded spatial shader on a full-screen quad. However, when I sample the texture, I don't get exactly what the shader produced. It looks like the colors are adjusted. How can I prevent that?

Here's a simplified setup to show the issue:

Node3D
  MeshInstance3D(QuadMesh, postprocess.gdshader)
  Camera3D
  SubViewport2D(disable_3d = true)
    ColorRect(Full Rect, 2d.gdshader)
  SubViewport3D(own_world_3d = true)
    MeshInstance3D(QuadMesh, 3d.gdshader)
    Camera3D

// 2d.gdshader
shader_type canvas_item;
void fragment() { COLOR = vec4(UV, 0.4, 1.0); }

// 3d.gdshader
shader_type spatial;
render_mode unshaded;
void vertex() { POSITION = vec4(VERTEX, 1.0); }
void fragment() { ALBEDO = vec3(SCREEN_UV, 0.4); }

// postprocess.gdshader
shader_type spatial;
render_mode unshaded;

uniform sampler2D SubViewport2D;
uniform sampler2D SubViewport3D;

void vertex() { POSITION = vec4(VERTEX, 1.0); }
void fragment() {
    vec3 col1 = vec3(SCREEN_UV, 0.4);
    vec3 col2 = texture(SubViewport2D, SCREEN_UV).rgb;
    vec3 col3 = texture(SubViewport3D, SCREEN_UV).rgb;
    // Put col2 on the left, col3 on the right.
    bool left = SCREEN_UV.x < 0.5;
    // Put col1 on even pixels.
    bool even = fract((SCREEN_UV * VIEWPORT_SIZE).x * 0.5) < 0.5;
    ALBEDO = even ? col1 : (left ? col2 : col3);
}

In the last shader, I expect col2 and col3 to equal col1. The output indicates that col2 = col1, while col3 is visually similar but not the same:

enter image description here

I tried adding a WorldEnvironment to SubViewport3D but it didn't make a difference. This issue looks relevant but I'm not sure.

\$\endgroup\$
1
  • \$\begingroup\$ This looks like it might be the difference between linear and gamma-corrected (sRGB) colour space. Do you see any options with those keywords in them? \$\endgroup\$
    – DMGregory
    Nov 8, 2023 at 21:16

1 Answer 1

1
\$\begingroup\$

If this is due color conversion (as DMGregory guesses), then I think your sampler2D need source_color. Example:

uniform sampler2D image : source_color;

The source_color hint is the replacement of Godot 3 hint_albedo for Godot 4.

Quote from the documentation:

It's important to understand that textures that are supplied as color require hints for proper sRGB->linear conversion (i.e. source_color), as Godot's 3D engine renders in linear color space.

Note: The hint source_color also works vector colors.


You might also want to check the WorldEnviroment, in particular if there is any color correction set. And I don't know if Tone mapping could be an issue.

\$\endgroup\$
1
  • \$\begingroup\$ source_color did the trick, thanks! \$\endgroup\$
    – stewbasic
    Nov 9, 2023 at 10:03

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .