marcelb / GodotSSRWater

Godot SSR Shader that also supports transparency and fake refraction
MIT License
61 stars 4 forks source link

Screen Border Fade-Out #5

Closed ulfbiallas closed 3 months ago

ulfbiallas commented 4 months ago

Changes

This PR adds a new parameter ssr_screen_border_fadeout. It can be used to control a fade-out effect of reflections close to the screen borders and supports a range from 0 (fade-out disabled) to 1 (max fade-out). The default value is 0.

If you move the camera so that a reflected object is no longer visible, its reflection on the water also disappears, even though it should still be visible. This is a general weakness of SSR, as only objects that are visible can be reflected. Enabling screen border fade-out mitigates this to some degree and helps to make it less distracting.

This implementation is based on https://github.com/marcelb/GodotSSRWater/pull/3 by @Xtarsia and another variant, which was proposed in https://github.com/marcelb/GodotSSRWater/issues/2 by @farfalk.

I decided to change a couple of things to make it easier to use and also the code easier to understand:

Xtarsia commented 4 months ago
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    // Normalized pixel coordinates (from 0 to 1)
    vec2 uv = fragCoord/iResolution.xy;

    uv *= 1.0 - uv;

    float edgeFade = 2.0; // Range 0.0 (Fade disabled) to 8.0~ (Fully faded out..)
    float col = smoothstep(0.0, edgeFade, uv.x * uv.y * 64.0);

    fragColor = vec4(col, 0.0, 0.0, 1.0);
}

smoothstep version, a tad more square and the fade is disabled with a value of 0.0

marcelb commented 3 months ago

0.5 chrome_zDuuKnoNjq

2.0 chrome_5UD0JMqOmw

0.0 chrome_EulrKhl19Y

Looks amazing. @Xtarsia

ulfbiallas commented 3 months ago

Yes, that looks much better! I see the advantage of this variant: The fading behaves more similar at the corners as well as at the edges of the screen. I updated this PR to implement this with some adjustments: The parameter now ranges exactly from 0 to 1.

Here is the shadertoy code to try yourself. I mapped the parameter to the x-position of the mouse. You can play with it by dragging the mouse over the canvas.

void mainImage( out vec4 fragColor, in vec2 fragCoord ) {

    vec2 uv = fragCoord/iResolution.xy;

    float edgeFade = iMouse.x / iResolution.x;

    vec2 shiftedUv = 4.0 * uv * (1.0 - uv);
    float factor = shiftedUv.x*shiftedUv.y;
    float offset = mix(0.0, 0.5, (clamp(edgeFade, 0.75, 1.0) - 0.75) / 0.25);

    float alpha = smoothstep(0.0, 2.0*edgeFade, factor) - offset;

    fragColor = vec4(alpha, 0.0, 0.0, 1.0);
}
ulfbiallas commented 3 months ago

@marcelb I just updated the branch with your feedback and also added a check to skip the calculation in the case when ssr_screen_border_fadeout == 0.0

marcelb commented 3 months ago

Thank you everyone @ulfbiallas @ulfbiallas @farfalk, I merged this!