[Bf-blender-cvs] [4fd70c99a5a] blender2.8: Eevee: SSR: Add support for planar probes.

Clément Foucault noreply at git.blender.org
Tue Jul 25 22:10:56 CEST 2017


Commit: 4fd70c99a5a37db00ea26b8e5efa7d351e5e1e2b
Author: Clément Foucault
Date:   Tue Jul 25 19:03:07 2017 +0200
Branches: blender2.8
https://developer.blender.org/rB4fd70c99a5a37db00ea26b8e5efa7d351e5e1e2b

Eevee: SSR: Add support for planar probes.

This add the possibility to use planar probe informations to create SSR.
This has 2 advantages:
- Tracing is less expensive since the hit is found much quicker.
- We have much less artifact due to missing information.

There is still area for improvement.

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

M	source/blender/draw/engines/eevee/eevee_effects.c
M	source/blender/draw/engines/eevee/eevee_lightprobes.c
M	source/blender/draw/engines/eevee/eevee_materials.c
M	source/blender/draw/engines/eevee/eevee_private.h
M	source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
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_downsample_frag.glsl
M	source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
M	source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl

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

diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c
index 0ddced10ae0..95280c5f206 100644
--- a/source/blender/draw/engines/eevee/eevee_effects.c
+++ b/source/blender/draw/engines/eevee/eevee_effects.c
@@ -766,6 +766,9 @@ void EEVEE_effects_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
 		DRW_shgroup_uniform_vec2(grp, "ssrParameters", &effects->ssr_stride, 1);
 		DRW_shgroup_uniform_mat4(grp, "PixelProjMatrix", (float *)&e_data.pixelprojmat);
 		DRW_shgroup_uniform_int(grp, "rayCount", &effects->ssr_ray_count, 1);
+		DRW_shgroup_uniform_int(grp, "planar_count", &sldata->probes->num_planar, 1);
+		DRW_shgroup_uniform_buffer(grp, "planarDepth", &vedata->txl->planar_depth);
+		DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
 		DRW_shgroup_call_add(grp, quad, NULL);
 
 		psl->ssr_resolve = DRW_pass_create("SSR Resolve", DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE);
@@ -777,6 +780,7 @@ void EEVEE_effects_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
 		DRW_shgroup_uniform_buffer(grp, "colorBuffer", &txl->color_double_buffer);
 		DRW_shgroup_uniform_mat4(grp, "PastViewProjectionMatrix", (float *)stl->g_data->prev_persmat);
 		DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)stl->g_data->viewvecs, 2);
+		DRW_shgroup_uniform_int(grp, "planar_count", &sldata->probes->num_planar, 1);
 		DRW_shgroup_uniform_int(grp, "probe_count", &sldata->probes->num_render_cube, 1);
 		DRW_shgroup_uniform_float(grp, "borderFadeFactor", &effects->ssr_border_fac, 1);
 		DRW_shgroup_uniform_float(grp, "lodCubeMax", &sldata->probes->lod_cube_max, 1);
diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c
index 151efefcda1..869a9798ce2 100644
--- a/source/blender/draw/engines/eevee/eevee_lightprobes.c
+++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c
@@ -276,6 +276,7 @@ void EEVEE_lightprobes_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *UNUSED(ved
 	if (!sldata->probes) {
 		sldata->probes = MEM_callocN(sizeof(EEVEE_LightProbesInfo), "EEVEE_LightProbesInfo");
 		sldata->probes->specular_toggle = true;
+		sldata->probes->ssr_toggle = true;
 		sldata->probe_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_LightProbe) * MAX_PROBE, NULL);
 		sldata->grid_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_LightGrid) * MAX_GRID, NULL);
 		sldata->planar_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_PlanarReflection) * MAX_PLANAR, NULL);
@@ -962,6 +963,7 @@ static void render_scene_to_probe(
 
 	/* Disable specular lighting when rendering probes to avoid feedback loops (looks bad). */
 	sldata->probes->specular_toggle = false;
+	sldata->probes->ssr_toggle = false;
 
 	/* Disable AO until we find a way to hide really bad discontinuities between cubefaces. */
 	tmp_ao_dist = stl->effects->ao_dist;
@@ -1045,7 +1047,7 @@ static void render_scene_to_probe(
 }
 
 static void render_scene_to_planar(
-        EEVEE_Data *vedata, int layer,
+        EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata, int layer,
         float (*viewmat)[4], float (*persmat)[4],
         float clip_plane[4])
 {
@@ -1066,6 +1068,9 @@ static void render_scene_to_planar(
 
 	DRW_framebuffer_clear(false, true, false, NULL, 1.0);
 
+	/* Turn off ssr to avoid black specular */
+	sldata->probes->ssr_toggle = false;
+
 	/* Avoid using the texture attached to framebuffer when rendering. */
 	/* XXX */
 	GPUTexture *tmp_planar_pool = txl->planar_pool;
@@ -1103,6 +1108,7 @@ static void render_scene_to_planar(
 	DRW_state_clip_planes_reset();
 
 	/* Restore */
+	sldata->probes->ssr_toggle = true;
 	txl->planar_pool = tmp_planar_pool;
 	txl->planar_depth = tmp_planar_depth;
 	DRW_viewport_matrix_override_unset(DRW_MAT_PERS);
@@ -1323,7 +1329,7 @@ update_planar:
 			int tmp_num_planar = pinfo->num_planar;
 			pinfo->num_planar = 0;
 
-			render_scene_to_planar(vedata, i, ped->viewmat, ped->persmat, ped->planer_eq_offset);
+			render_scene_to_planar(sldata, vedata, i, ped->viewmat, ped->persmat, ped->planer_eq_offset);
 
 			/* Restore */
 			pinfo->num_planar = tmp_num_planar;
@@ -1335,7 +1341,7 @@ update_planar:
 
 	/* If there is at least one planar probe */
 	if (pinfo->num_planar > 0) {
-		const int max_lod = 5;
+		const int max_lod = 9;
 		DRW_framebuffer_recursive_downsample(vedata->fbl->downsample_fb, txl->planar_pool, max_lod, &downsample_planar, vedata);
 		/* For shading, save max level of the planar map */
 		pinfo->lod_planar_max = (float)(max_lod);
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index eae9331fedc..c1112eedf0d 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -272,6 +272,7 @@ static void add_standard_uniforms(DRWShadingGroup *shgrp, EEVEE_SceneLayerData *
 	DRW_shgroup_uniform_int(shgrp, "grid_count", &sldata->probes->num_render_grid, 1);
 	DRW_shgroup_uniform_int(shgrp, "planar_count", &sldata->probes->num_planar, 1);
 	DRW_shgroup_uniform_bool(shgrp, "specToggle", &sldata->probes->specular_toggle, 1);
+	DRW_shgroup_uniform_bool(shgrp, "ssrToggle", &sldata->probes->ssr_toggle, 1);
 	DRW_shgroup_uniform_float(shgrp, "lodCubeMax", &sldata->probes->lod_cube_max, 1);
 	DRW_shgroup_uniform_float(shgrp, "lodPlanarMax", &sldata->probes->lod_planar_max, 1);
 	DRW_shgroup_uniform_texture(shgrp, "utilTex", e_data.util_tex);
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 55fb550d940..0b1fc2f5dff 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -299,6 +299,7 @@ typedef struct EEVEE_LightProbesInfo {
 	int shres;
 	int shnbr;
 	bool specular_toggle;
+	bool ssr_toggle;
 	/* List of probes in the scene. */
 	/* XXX This is fragile, can get out of sync quickly. */
 	struct Object *probes_cube_ref[MAX_PROBE];
diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
index e6cbcde77c7..99e2132277d 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
@@ -153,6 +153,12 @@ vec3 line_plane_intersect(vec3 lineorigin, vec3 linedirection, vec3 planeorigin,
 	return lineorigin + linedirection * dist;
 }
 
+vec3 line_plane_intersect(vec3 lineorigin, vec3 linedirection, vec4 plane)
+{
+	float dist = line_plane_intersect_dist(lineorigin, linedirection, plane);
+	return lineorigin + linedirection * dist;
+}
+
 float line_aligned_plane_intersect_dist(vec3 lineorigin, vec3 linedirection, vec3 planeorigin)
 {
 	/* aligned plane normal */
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 7b516f27ec9..901d1fa4aea 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl
@@ -30,10 +30,11 @@ vec3 generate_ray(vec3 V, vec3 N, float a2, vec3 rand, out float pdf)
 
 #ifdef STEP_RAYTRACE
 
-uniform sampler2D depthBuffer;
 uniform sampler2D normalBuffer;
 uniform sampler2D specroughBuffer;
 
+uniform int planar_count;
+
 uniform mat4 ViewProjectionMatrix;
 
 layout(location = 0) out vec4 hitData0;
@@ -48,14 +49,53 @@ bool has_hit_backface(vec3 hit_pos, vec3 R, vec3 V)
 	return (dot(-R, hit_N) < 0.0);
 }
 
-vec4 do_ssr(sampler2D depthBuffer, vec3 V, vec3 N, vec3 viewPosition, float a2, vec3 rand)
+vec4 do_planar_ssr(int index, vec3 V, vec3 N, vec3 planeNormal, vec3 viewPosition, float a2, vec3 rand)
+{
+	float pdf;
+	vec3 R = generate_ray(V, N, a2, rand, pdf);
+
+	R = reflect(R, planeNormal);
+	pdf *= -1.0; /* Tag as planar ray. */
+
+	/* If ray is bad (i.e. going below the plane) do not trace. */
+	if (dot(R, planeNormal) > 0.0) {
+		vec3 R = generate_ray(V, N, a2, rand, pdf);
+	}
+
+	float hit_dist;
+	if (abs(dot(-R, V)) < 0.9999) {
+		hit_dist = raycast(index, viewPosition, R, rand.x);
+	}
+	else {
+		float z = get_view_z_from_depth(texelFetch(planarDepth, ivec3(project_point(PixelProjMatrix, viewPosition).xy, index), 0).r);
+		hit_dist = (z - viewPosition.z) / R.z;
+	}
+
+	/* Since viewspace hit position can land behind the camera in this case,
+	 * we save the reflected view position (visualize it as the hit position
+	 * below the reflection plane). This way it's garanted that the hit will
+	 * be in front of the camera. That let us tag the bad rays with a negative
+	 * sign in the Z component. */
+	vec3 hit_pos = viewPosition + R * abs(hit_dist);
+
+	/* Ray did not hit anything. No backface test because it's not possible
+	 * to hit a backface in this case. */
+	if (hit_dist <= 0.0) {
+		hit_pos.z *= -1.0;
+	}
+
+	return vec4(hit_pos, pdf);
+}
+
+vec4 do_ssr(vec3 V, vec3 N, vec3 viewPosition, float a2, vec3 rand)
 {
 	float pdf;
 	vec3 R = generate_ray(V, N, a2, rand, pdf);
 
-	float hit_dist = raycast(depthBuffer, viewPosition, R, rand.x);
+	float hit_dist = raycast(-1, viewPosition, R, rand.x);
 	vec3 hit_pos = viewPosition + R * abs(hit_dist);
 
+	/* Ray did not hit anything. Tag it as failled. */
 	if (has_hit_backface(hit_pos, R, V) || (hit_dist <= 0.0)) {
 		hit_pos.z *= -1.0;
 	}
@@ -102,17 +142,41 @@ void main()
 
 	vec3 rand = texelFetch(utilTex, ivec3(halfres_texel % LUT_SIZE, 2), 0).rba;
 
+	vec3 worldPosition = transform_point(ViewMatrixInverse, viewPosition);
+	vec3 wN = mat3(ViewMatrixInverse) * N;
+
+	/* Planar Reflections */
+	for (int i = 0; i < MAX_PLANAR && i < planar_count; ++i) {
+		PlanarData pd = planars_data[i];
+
+		float fade = probe_attenuation_planar(pd, worldPosition, wN);
+
+		if (fade > 0.5) {
+			/* Find view vector / reflection plane intersection. */
+			/* TODO optimize, use view space for all. */
+			vec3 tracePosition = line_plane_intersect(worldPosition, cameraVec, pd.pl_plane_eq);
+			tracePosition = transform_point(ViewMatrix, tracePosition);
+			vec3 planeNormal = mat3(ViewMatrix) * pd.pl_normal;
+
+			/* TODO : Raytrace together if textureGather is supported. */
+			hit

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list