[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