gdquest-demos / godot-shaders

A large library of free and open-source shaders for the Godot game engine. Here, you'll get 2D and 3D shaders with playable demos.
Other
3.17k stars 192 forks source link

Update force field shader #57

Closed tetrapod00 closed 1 month ago

tetrapod00 commented 1 month ago

3.5: Godot_v3 5-stable_win64_0hvlq3b66g 4.3 Compatibility: Godot_v4 3-stable_win64_JNBgG9Y3EA 4.3 Forward+: Godot_v4 3-stable_win64_twdlYTAuIb

Changes:

Sliders

Godot_v4 3-stable_win64_EDqFL9AVgH

Linear depth:

The new linear depth calculation looks like this:

float get_linear_depth(sampler2D depth_texture, vec2 screen_uv, mat4 inv_projection_matrix, bool use_opengl_ndc) {
    float depth_raw = texture(depth_texture, screen_uv).x;
    vec3 ndc;
    if (use_opengl_ndc){
        // Compatibility. Uses OpenGL NDC space: range of [-1,1] for NDC.xy, range of [-1,1] for NDC.z
        ndc = vec3(screen_uv, depth_raw) * 2.0 - 1.0;
    } else {
        // Forward+ or Mobile. Uses Vulkan NDC space: range of [-1,1] for NDC.xy, range of [0,1] for NDC.z
        ndc = vec3(screen_uv * 2.0 - 1.0, depth_raw); 
    }
    vec4 position_view = inv_projection_matrix * vec4(ndc, 1.0);
    position_view.xyz /= position_view.w;
    return -position_view.z;
}

Call site:

    // Get the linear depth.
    float depth = get_linear_depth(DEPTH_TEXTURE, SCREEN_UV, INV_PROJECTION_MATRIX, OUTPUT_IS_SRGB);

This is the same one used by the official Advanced Postprocessing tutorial, and the official VisualShader node LinearSceneDepth. It may be more expensive than the 3.x version. To be honest, I don't fully understand the 3.x version. Relying on the internals of the matrices, like the 3.x version was doing, may be wrong for code like this that also functions partially as a tutorial. I may come back and see if there's a simpler or more efficient way to get the linear depth in 4.3, but as is this functions.

OUTPUT_IS_SRGB is a proxy for whether the renderer is Compatibility or Forward+/Mobile. I confirmed with clayjohn that it for this purpose it won't change until 5.0. Ideally this would be an explicit #define for the renderer, but that's not actually currently available. I am a little wary of putting a snippet like this, with the branching, into code that will be copied and pasted a lot. But as is, code that is copied and pasted just assumes Vulkan NDC space, which is incorrect.

We need to check the renderer because Compatibility and Forward+/Mobile use different NDC spaces.

Compatibility, if we don't check, and assume Vulkan Forward+ NDC: Godot_v4 3-stable_win64_Cknr3ISe5k

Compatibility if we check: Godot_v4 3-stable_win64_XJWWK3Y4Mc

NathanLovato commented 1 month ago

Excellent work, thank you so much for going the extra mile! The experience using the shader is great. Also, thank you for all the details.

For next PRs, please note that you don't have to bother taking many screenshots. But, I always test directly in Godot, take the time to read the code, and it's already very clear and even commented so it already makes reviewing very easy. So, you don't have to use more of your time to present things neatly on GitHub. I really appreciate your thoughtfulness and attention to detail.