Eevee: Fix SSR in orthographic view.
authorClément Foucault <foucault.clem@gmail.com>
Sat, 23 Sep 2017 23:25:21 +0000 (01:25 +0200)
committerClément Foucault <foucault.clem@gmail.com>
Mon, 25 Sep 2017 18:14:42 +0000 (20:14 +0200)
The problem was that orthographic views can have hit position that are negative. Thus we cannot encode the hit in the sign of the Z component.

The workaround is to store the hit position in screenspace. But since we are using floating point render target, we are loosing quite a bit of precision.
TODO: use RGBA16 instead of RGBA16F. But that means encoding the pdf value somehow.

source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl
source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
source/blender/draw/engines/eevee/shaders/ssr_lib.glsl

index 355c2038dd22dd469a04b213681fcc700957d15d..520dc7b962422a4ef307692dbc7c9c40fc8587fc 100644 (file)
@@ -252,12 +252,13 @@ vec4 get_ssr_sample(
         inout float weight_acc)
 {
        vec4 hit_co_pdf = texelFetch(hitBuffer, target_texel, 0).rgba;
-       bool has_hit = (hit_co_pdf.z < 0.0);
+       bool has_hit = (hit_co_pdf.z > 0.0);
        bool is_planar = (hit_co_pdf.w < 0.0);
-       hit_co_pdf.z = -abs(hit_co_pdf.z);
+       hit_co_pdf.z = abs(hit_co_pdf.z);
        hit_co_pdf.w = abs(hit_co_pdf.w);
 
        /* Hit position in world space. */
+       hit_co_pdf.xyz = get_view_space_from_depth(hit_co_pdf.xy, hit_co_pdf.z);
        vec3 hit_pos = transform_point(ViewMatrixInverse, hit_co_pdf.xyz);
 
        vec2 ref_uvs;
index d0fc14f8a2943faa661839024325df07acede28a..b9aacde264d224bc9b46a5d38fa77519127ae947 100644 (file)
@@ -211,11 +211,10 @@ vec3 raycast(int index, vec3 ray_origin, vec3 ray_dir, float thickness, float ra
        ray_time = max(0.001, min(ray_time, max_time - 1.5));
 
        vec4 ss_ray = ss_start + ss_step * ray_time;
-       vec3 hit_pos = get_view_space_from_depth(ss_ray.xy, ss_ray.z);
 
        /* Tag Z if ray failed. */
-       hit_pos.z *= (hit) ? 1.0 : -1.0;
-       return hit_pos;
+       ss_ray.z *= (hit) ? 1.0 : -1.0;
+       return ss_ray.xyz;
 }
 
 float screen_border_mask(vec2 hit_co)
index 68e0c2a682fec703600baa1474422c33fa0af6a4..6dbd761ba8d759da32ef65b03d7a0583dcef5049 100644 (file)
@@ -36,6 +36,7 @@ vec4 screen_space_refraction(vec3 viewPosition, vec3 N, vec3 V, float ior, float
        vec3 hit_pos = raycast(-1, viewPosition, R, ssrThickness, jitter, roughnessSquared);
 
        if ((hit_pos.z < 0.0) && (F_eta(ior, dot(H, V)) < 1.0)) {
+               hit_pos = get_view_space_from_depth(hit_pos.xy, hit_pos.z);
                float hit_dist = distance(hit_pos, viewPosition);
 
                float cone_cos = cone_cosine(roughnessSquared);