Godot version
4.0.dev (db028ac700)
System information
Windows 10, Vulkan (Clustered), RTX 2060
Issue description
As it stands, the advanced post processing tutorial suggests to use the following code to get the linear depth from the depth texture:
void fragment() {
float depth = texture(DEPTH_TEXTURE, SCREEN_UV).x;
vec3 ndc = vec3(SCREEN_UV, depth) * 2.0 - 1.0;
vec4 view = INV_PROJECTION_MATRIX * vec4(ndc, 1.0);
view.xyz /= view.w;
float linear_depth = -view.z;
}
This was correct in Godot 3.x, but this is not longer true with Vulkan. (Tested with the clustered renderer, haven't tested mobile renderer.)
The correct code, as tested, is now:
void fragment() {
float depth = texture(DEPTH_TEXTURE, SCREEN_UV).x;
vec3 ndc = vec3(SCREEN_UV * 2.0 - 1.0, depth); // <<< This line changed!
vec4 view = INV_PROJECTION_MATRIX * vec4(ndc, 1.0);
view.xyz /= view.w;
float linear_depth = -view.z;
}
It looks like the depth texture in 3.x was mapped between 0.5 and 1.0 (seems very strange), while in 4.0 it is now mapped between 0.0 and 1.0, as I would normally expect.
I believe this is just a documentation issue, but it would be good to have someone familiar with the renderer give some assurance.
Steps to reproduce
This issue is best demonstrated by a post processing shader (screen filling mesh) to compare the normalized device coordinates by overlaying the world position of existing geometry as a color.
When working correctly, the colors should not move when you spin the camera. They should appear like a texture.
Code to showcase this:
shader_type spatial;
render_mode cull_disabled, unshaded;
void vertex() {
POSITION = vec4(VERTEX, 0.0);
}
void fragment() {
float depth = texture(DEPTH_TEXTURE, SCREEN_UV).x;
//vec3 ndc = vec3(SCREEN_UV, depth) * 2.0 - 1.0; // bad
vec3 ndc = vec3(SCREEN_UV * 2.0 - 1.0, depth); // good
vec4 view = INV_PROJECTION_MATRIX * vec4(ndc, 1.0);
view.xyz /= view.w;
float linear_depth = -view.z;
vec4 world = CAMERA_MATRIX * INV_PROJECTION_MATRIX * vec4(ndc, 1.0);
vec3 world_position = world.xyz / world.w;
if (linear_depth > 100.0) // just to prevent coloring the sky
discard;
ALBEDO = world_position;
}
Comparison between correct and incorrect results:
Good:

Bad:

Minimal reproduction project
DepthLinearizationReprod.zip
Godot version
4.0.dev (db028ac700)
System information
Windows 10, Vulkan (Clustered), RTX 2060
Issue description
As it stands, the advanced post processing tutorial suggests to use the following code to get the linear depth from the depth texture:
This was correct in Godot 3.x, but this is not longer true with Vulkan. (Tested with the clustered renderer, haven't tested mobile renderer.)
The correct code, as tested, is now:
It looks like the depth texture in 3.x was mapped between 0.5 and 1.0 (seems very strange), while in 4.0 it is now mapped between 0.0 and 1.0, as I would normally expect.
I believe this is just a documentation issue, but it would be good to have someone familiar with the renderer give some assurance.
Steps to reproduce
This issue is best demonstrated by a post processing shader (screen filling mesh) to compare the normalized device coordinates by overlaying the world position of existing geometry as a color.
When working correctly, the colors should not move when you spin the camera. They should appear like a texture.
Code to showcase this:
Comparison between correct and incorrect results:
Good:

Bad:

Minimal reproduction project
DepthLinearizationReprod.zip