diff options
5 files changed, 35 insertions, 27 deletions
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); |