godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
89.27k stars 20.23k forks source link

POSITION in Vertex Spatial Shader does not appear to work (full screen overlay) #58337

Closed cybereality closed 1 year ago

cybereality commented 2 years ago

Godot version

v4.0.alpha2.official [79077e6c1]

System information

Ubuntu 21.10 AMD 6800XT Mesa Drivers GLES3

Issue description

I am trying to write a full screen overlay shader in Godot 4.0 and I'm using the same code that was working on Godot 3.x. There are no errors, however the shader displays nothing. I believe there is something wrong with using POSITION in a vertex shader. If I remove that line of code, then the color displays, but it is not full screen.

shader_type spatial;

void vertex() {
    POSITION = vec4(VERTEX, 1.0);
}

void fragment() {
    ALBEDO = vec3(1.0, 0.0, 0.0);
}

Steps to reproduce

Please download the reproduction project. You can see there is nothing on the screen (it should be totally red). If you comment out the POSITION line in the vertex shader, then the red does display, but only on the quad's local size.

Minimal reproduction project

Overlay40.zip

Chaosus commented 2 years ago

I think, the POSITION built-in is used to construct a vertex from "scratch" and you need to multiply it by some matrixes:

POSITION = PROJECTION_MATRIX * MODELVIEW_MATRIX * vec4(VERTEX, 1.0);

if you don't need it - simply modify a VERTEX built-in instead.

cybereality commented 2 years ago

In this case, I am not trying to get a 3D position. I want a full screen quad, so I am working in NDC. The idea is that the POSITION value should result in a quad that is from (-1, -1), to (1, 1) and thus covers the whole screen. This works fine in Godot 3.x and there is nothing in the docs that suggests this behavior has changed.

Chaosus commented 2 years ago

I'm not entirely sure that it is shader related it may be caused by the incorrect working of culling algorithm on infinite surfaces: bug

Scony commented 1 year ago

@cybereality the QuadMesh vertices changed I think and therefore you either need to tick flip_faces on the QuadMesh, or change culling in the shader. Btw. Please note there are some changes regarding NDC calculation under Vulkan (https://docs.godotengine.org/en/latest/tutorials/shaders/advanced_postprocessing.html#depth-texture) as Vulkan's projection space is different than OpenGL's - see https://vincent-p.github.io/posts/vulkan_perspective_matrix/

Dan2552 commented 1 year ago

Was trying to follow https://docs.godotengine.org/en/latest/tutorials/shaders/advanced_postprocessing.html, spent hours thinking I followed it wrong and trying from scratch again and again, and indeed it seems you need the flip_faces in order to achieve "Full screen quad". Thanks

celyk commented 1 year ago

People on the OpenGL renderer will still need to do it the old way. A script is needed to flip the faces appropriately, something like that:

if ProjectSettings.get_setting("rendering/renderer/rendering_method") == "gl_compatibility":
    mesh.flip_faces = false
else:
    mesh.flip_faces = true

or they can just disable face culling.

clayjohn commented 1 year ago

@celyk Are you sure? I just tested the tutorial on the OpenGL renderer and it works the same as the other renderers (i.e. flip_faces needs to be true)

celyk commented 1 year ago

@celyk Are you sure? I just tested the tutorial on the OpenGL renderer and it works the same as the other renderers (i.e. flip_faces needs to be true)

You are right. I wasn't aware that it renders upside-down, and not before faces are flipped by glFrontFace(GL_CCW). Effectively, the OpenGL renderer uses a right-handed NDC space with the fragment origin appearing in the upper left.

It would be worth clarifying this in the doc, but I think the issue above is solved.