Eevee: SSR: Don't block the ray if tracing behind object.
authorClément Foucault <foucault.clem@gmail.com>
Wed, 19 Jul 2017 21:40:14 +0000 (23:40 +0200)
committerClément Foucault <foucault.clem@gmail.com>
Mon, 24 Jul 2017 13:28:27 +0000 (15:28 +0200)
This requires to check for backface after a hit.

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

index 3c0b1952e7a35c8638ceaf192e4d2518fa14dfd1..7337ec792c97c1037916b26b4975d1e3df4d1046 100644 (file)
@@ -67,11 +67,14 @@ void main()
        /* Raycast over screen */
        float hit_dist = raycast(depthBuffer, viewPosition, R);
 
-       /* TODO Check if has hit a backface */
-
        vec2 hit_co = project_point(ProjectionMatrix, viewPosition + R * hit_dist).xy * 0.5 + 0.5;
+
+       /* Check if has hit a backface */
+       vec3 hit_N = normal_decode(textureLod(normalBuffer, hit_co, 0.0).rg, V);
+       pdf *= step(0.0, dot(-R, hit_N));
+
        hitData = hit_co.xyxy;
-       pdfData = vec4(pdf) * step(-0.1, hit_dist);
+       pdfData = vec4(pdf) * step(0.0, hit_dist);
 }
 
 #else /* STEP_RESOLVE */
index d53c0a276e81738ab49bf9ae1fff2567d5ddf5c8..1e10311bf359ac4207f421f889bdb749a65d1963 100644 (file)
@@ -111,7 +111,10 @@ float raycast(sampler2D depth_texture, vec3 ray_origin, vec3 ray_dir)
                raw_depth = texelFetch(depth_texture, ivec2(hitpixel), 0).r;
                view_depth = get_view_z_from_depth(raw_depth);
 
-               if (zmax < view_depth) {
+               /* TODO user threshold */
+               const float threshold = 0.5; /* In view space */
+               /* Check if we are somewhere near the surface. */
+               if ((zmax < view_depth) && (zmax > view_depth - threshold)) {
                        /* Below surface, cannot trace further */
                        hit = true;
                }
@@ -137,20 +140,16 @@ float raycast(sampler2D depth_texture, vec3 ray_origin, vec3 ray_dir)
                        raw_depth = texelFetch(depth_texture, ivec2(hitpixel), 0).r;
                        view_depth = get_view_z_from_depth(raw_depth);
 
-                       if (zmax < view_depth) {
+                       /* TODO user threshold */
+                       const float threshold = 0.5; /* In view space */
+                       /* Check if we are somewhere near the surface. */
+                       if ((zmax < view_depth) && (zmax > view_depth - threshold)) {
                                /* Below surface, cannot trace further */
                                break;
                        }
                }
        }
 
-       /* Check if we are somewhere near the surface. */
-       /* TODO user threshold */
-       float threshold = 0.1; /* In clip space */
-       if (zmax < view_depth - threshold) {
-               hit = false;
-       }
-
        /* Check failure cases (out of screen, hit background) */
        if (hit && (raw_depth != 1.0) && (raw_depth != 0.0)) {
                /* Return length */