[Bf-blender-cvs] [aaeca5d8724] master: Eevee: Planar Ref.: Invert view matrix to remove triangle front face flip

Clément Foucault noreply at git.blender.org
Tue Mar 12 16:01:29 CET 2019


Commit: aaeca5d87244bca2832b86d60457f0568acf1427
Author: Clément Foucault
Date:   Tue Mar 12 15:45:44 2019 +0100
Branches: master
https://developer.blender.org/rBaaeca5d87244bca2832b86d60457f0568acf1427

Eevee: Planar Ref.: Invert view matrix to remove triangle front face flip

This was the cause of some issue with normal mapping. This way is cleaner
since it does not modify the state of the drawcalls and other ad-hoc
solutions to fix the problems down the road. Unfortunately, it does require
to fix every sampling coordinate for this texture.

Fix T62215: flipped normals in reflection plane

===================================================================

M	source/blender/draw/engines/eevee/eevee_lightprobes.c
M	source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl
M	source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl
M	source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_frag.glsl
M	source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl

===================================================================

diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c
index dfd8a048276..1f46fee7398 100644
--- a/source/blender/draw/engines/eevee/eevee_lightprobes.c
+++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c
@@ -654,23 +654,19 @@ void EEVEE_lightprobes_planar_data_from_object(Object *ob, EEVEE_PlanarReflectio
 }
 
 static void lightbake_planar_compute_render_matrices(
-        EEVEE_PlanarReflection *eplanar, DRWMatrixState *r_matstate, const float viewmat[4][4])
+        EEVEE_PlanarReflection *eplanar, DRWMatrixState *r_matstate,
+        const float viewmat[4][4], const float winmat[4][4])
 {
 	/* Reflect Camera Matrix. */
 	mul_m4_m4m4(r_matstate->viewmat, viewmat, eplanar->mtx);
-	/* TODO FOV margin */
-	/* Temporal sampling jitter should be already applied to the DRW_MAT_WIN. */
-	DRW_viewport_matrix_get(r_matstate->winmat, DRW_MAT_WIN);
+	/* Invert X to avoid flipping the triangle facing direction. */
+	r_matstate->viewmat[0][0] = -r_matstate->viewmat[0][0];
+	r_matstate->viewmat[1][0] = -r_matstate->viewmat[1][0];
+	r_matstate->viewmat[2][0] = -r_matstate->viewmat[2][0];
+	r_matstate->viewmat[3][0] = -r_matstate->viewmat[3][0];
 	/* Apply Projection Matrix. */
-	mul_m4_m4m4(r_matstate->persmat, r_matstate->winmat, r_matstate->viewmat);
-
-	/* This is the matrix used to reconstruct texture coordinates.
-	 * We use the original view matrix because it does not create
-	 * visual artifacts if receiver is not perfectly aligned with
-	 * the planar reflection probe. */
-	mul_m4_m4m4(eplanar->reflectionmat, r_matstate->winmat, viewmat); /* TODO FOV margin */
-	/* Convert from [-1, 1] to [0, 1] (NDC to Texture coord). */
-	mul_m4_m4m4(eplanar->reflectionmat, texcomat, eplanar->reflectionmat);
+	/* Temporal sampling jitter should be already applied to the DRW_MAT_WIN. */
+	mul_m4_m4m4(r_matstate->persmat, winmat, r_matstate->viewmat);
 }
 
 static void eevee_lightprobes_extract_from_cache(EEVEE_LightProbesInfo *pinfo, LightCache *lcache)
@@ -783,12 +779,13 @@ static void render_reflections(
 {
 	DRWMatrixState matstate;
 
-	float original_viewmat[4][4];
+	float original_viewmat[4][4], original_winmat[4][4];
 	DRW_viewport_matrix_get(original_viewmat, DRW_MAT_VIEW);
+	DRW_viewport_matrix_get(original_winmat, DRW_MAT_WIN);
 
 	for (int i = 0; i < ref_count; ++i) {
 		/* Setup custom matrices */
-		lightbake_planar_compute_render_matrices(planar_data + i, &matstate, original_viewmat);
+		lightbake_planar_compute_render_matrices(planar_data + i, &matstate, original_viewmat, original_winmat);
 		invert_m4_m4(matstate.persinv, matstate.persmat);
 		invert_m4_m4(matstate.viewinv, matstate.viewmat);
 		invert_m4_m4(matstate.wininv, matstate.winmat);
@@ -884,9 +881,7 @@ static void lightbake_render_scene_reflected(int layer, EEVEE_BakeRenderData *us
 
 	/* Be sure that cascaded shadow maps are updated. */
 	EEVEE_draw_shadows(sldata, vedata);
-	/* Since we are rendering with an inverted view matrix, we need
-	 * to invert the facing for backface culling to be the same. */
-	DRW_state_invert_facing();
+
 	/* Compute offset plane equation (fix missing texels near reflection plane). */
 	copy_v4_v4(sldata->clip_data.clip_planes[0], eplanar->plane_equation);
 	sldata->clip_data.clip_planes[0][3] += eplanar->clipsta;
@@ -924,7 +919,6 @@ static void lightbake_render_scene_reflected(int layer, EEVEE_BakeRenderData *us
 	}
 	DRW_draw_pass(psl->transparent_pass);
 
-	DRW_state_invert_facing();
 	DRW_state_clip_planes_reset();
 
 	DRW_stats_group_end();
diff --git a/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl
index d44cf5e3518..2178b15a753 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl
@@ -18,7 +18,11 @@ vec2 decode_hit_data(vec2 hit_data, out bool has_hit, out bool is_planar)
 {
 	is_planar = (hit_data.x < 0);
 	has_hit = (hit_data.y > 0);
-	return vec2(abs(hit_data)) / 32767.0; /* 16bit signed int limit */
+	vec2 hit_co = vec2(abs(hit_data)) / 32767.0; /* 16bit signed int limit */
+	if (is_planar) {
+		hit_co.x = 1.0 - hit_co.x;
+	}
+	return hit_co;
 }
 
 #ifdef STEP_RAYTRACE
@@ -219,6 +223,7 @@ vec2 get_reprojected_reflection(vec3 hit, vec3 pos, vec3 N)
 float get_sample_depth(vec2 hit_co, bool is_planar, float planar_index)
 {
 	if (is_planar) {
+		hit_co.x = 1.0 - hit_co.x;
 		return textureLod(planarDepth, vec3(hit_co, planar_index), 0.0).r;
 	}
 	else {
@@ -237,6 +242,8 @@ vec3 get_hit_vector(
 		vec3 trace_pos = line_plane_intersect(worldPosition, V, pd.pl_plane_eq);
 		hit_vec = hit_pos - trace_pos;
 		hit_vec = reflect(hit_vec, pd.pl_normal);
+		/* Modify here so mip texel alignment is correct. */
+		hit_co.x = 1.0 - hit_co.x;
 	}
 	else {
 		/* Find hit position in previous frame. */
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl
index a991e640a79..7881079e258 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl
@@ -200,7 +200,8 @@ vec3 probe_evaluate_planar(
 
 	/* TODO: If we support non-ssr planar reflection, we should blur them with gaussian
 	 * and chose the right mip depending on the cone footprint after projection */
-	vec3 sample = textureLod(probePlanars, vec3(refco.xy * 0.5 + 0.5, id), 0.0).rgb;
+	/* NOTE: X is inverted here to compensate inverted drawing.  */
+	vec3 sample = textureLod(probePlanars, vec3(refco.xy * vec2(-0.5, 0.5) + 0.5, id), 0.0).rgb;
 
 	return sample;
 }
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_frag.glsl
index 3808b59761f..afffccc3751 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_frag.glsl
@@ -10,5 +10,5 @@ void main()
 {
 	vec4 refco = ViewProjectionMatrix * vec4(worldPosition, 1.0);
 	refco.xy /= refco.w;
-	FragColor = vec4(textureLod(probePlanars, vec3(refco.xy * 0.5 + 0.5, float(probeIdx)), 0.0).rgb, 1.0);
+	FragColor = vec4(textureLod(probePlanars, vec3(refco.xy * vec2(-0.5, 0.5) + 0.5, float(probeIdx)), 0.0).rgb, 1.0);
 }
diff --git a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
index c9f2d64f30b..d5a51f89e81 100644
--- a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
@@ -59,7 +59,7 @@ float refine_isect(float prev_delta, float curr_delta)
 }
 
 void prepare_raycast(
-        vec3 ray_origin, vec3 ray_dir, float thickness, out vec4 ss_step, out vec4 ss_ray, out float max_time)
+        vec3 ray_origin, vec3 ray_dir, float thickness, int index, out vec4 ss_step, out vec4 ss_ray, out float max_time)
 {
 	/* Negate the ray direction if it goes towards the camera.
 	 * This way we don't need to care if the projected point
@@ -106,10 +106,16 @@ void prepare_raycast(
 	/* Convert to texture coords. Z component included
 	 * since this is how it's stored in the depth buffer.
 	 * 4th component how far we are on the ray */
-	ss_ray = ss_start * 0.5 + 0.5;
-	ss_step *= 0.5;
+#ifdef PLANAR_PROBE_RAYTRACE
+	/* Planar Reflections have X mirrored. */
+	vec2 m = (index > -1) ? vec2(-0.5, 0.5) : vec2(0.5);
+#else
+	const vec2 m = vec2(0.5);
+#endif
+	ss_ray = ss_start * m.xyyy + 0.5;
+	ss_step *= m.xyyy;
 
-	ss_ray.xy += 0.5 * ssrPixelSize * 2.0; /* take the center of the texel. * 2 because halfres. */
+	ss_ray.xy += m * ssrPixelSize * 2.0; /* take the center of the texel. * 2 because halfres. */
 }
 
 /* See times_and_deltas. */
@@ -127,7 +133,7 @@ vec3 raycast(
 {
 	vec4 ss_step, ss_start;
 	float max_time;
-	prepare_raycast(ray_origin, ray_dir, thickness, ss_step, ss_start, max_time);
+	prepare_raycast(ray_origin, ray_dir, thickness, index, ss_step, ss_start, max_time);
 
 	float max_trace_time = max(0.001, max_time - 0.01);



More information about the Bf-blender-cvs mailing list