Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2017-07-22 00:48:48 +0300
committerClément Foucault <foucault.clem@gmail.com>2017-07-24 16:28:27 +0300
commita3732412ad5b2adda8e820088fba76d3c8f6ea00 (patch)
tree0e7b8dd9fd16c143bd550d6af77171c546fa2219 /source/blender/draw
parent18aa6cf1cc66ace97f23d984d8cce528ebc9f77d (diff)
Eevee: SSR: Add stride and thickness parameters.
Also polished the raytracing algorithm.
Diffstat (limited to 'source/blender/draw')
-rw-r--r--source/blender/draw/engines/eevee/eevee_effects.c3
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h2
-rw-r--r--source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl69
4 files changed, 43 insertions, 33 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c
index 13c6bf4ee44..245dc19ab85 100644
--- a/source/blender/draw/engines/eevee/eevee_effects.c
+++ b/source/blender/draw/engines/eevee/eevee_effects.c
@@ -549,6 +549,8 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
effects->enabled_effects |= EFFECT_DOUBLE_BUFFER;
effects->reflection_trace_full = true;
+ effects->ssr_stride = (float)BKE_collection_engine_property_value_get_int(props, "ssr_stride");
+ effects->ssr_thickness = BKE_collection_engine_property_value_get_float(props, "ssr_thickness");
const int divisor = (effects->reflection_trace_full) ? 1 : 2;
int tracing_res[2] = {(int)viewport_size[0] / divisor, (int)viewport_size[1] / divisor};
@@ -723,6 +725,7 @@ void EEVEE_effects_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_buffer(grp, "specroughBuffer", &txl->ssr_specrough_input);
DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)stl->g_data->viewvecs, 2);
+ DRW_shgroup_uniform_vec2(grp, "ssrParameters", &effects->ssr_stride, 1);
DRW_shgroup_uniform_mat4(grp, "PixelProjMatrix", (float *)&e_data.pixelprojmat);
DRW_shgroup_call_add(grp, quad, NULL);
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index 4ee3dee655f..6ca120a7a9b 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -212,6 +212,8 @@ static void EEVEE_scene_layer_settings_create(RenderEngine *UNUSED(engine), IDPr
props->subtype == IDP_GROUP_SUB_ENGINE_RENDER);
BKE_collection_engine_property_add_bool(props, "ssr_enable", false);
+ BKE_collection_engine_property_add_int(props, "ssr_stride", 16);
+ BKE_collection_engine_property_add_float(props, "ssr_thickness", 0.5f);
BKE_collection_engine_property_add_bool(props, "volumetric_enable", false);
BKE_collection_engine_property_add_float(props, "volumetric_start", 0.1f);
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 22d100ba13e..50db5365d2b 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -321,6 +321,8 @@ typedef struct EEVEE_EffectsInfo {
/* SSR */
bool use_ssr;
bool reflection_trace_full;
+ float ssr_stride;
+ float ssr_thickness;
/* Ambient Occlusion */
bool use_ao, use_bent_normals;
diff --git a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
index 1e10311bf35..36787153afc 100644
--- a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
@@ -4,8 +4,13 @@
* http://casual-effects.blogspot.fr/2014/08/screen-space-ray-tracing.html */
#define MAX_STEP 256
+#define MAX_REFINE_STEP 32 /* Should be max allowed stride */
uniform mat4 PixelProjMatrix; /* View > NDC > Texel : maps view coords to texel coord */
+uniform vec2 ssrParameters;
+
+#define ssrStride ssrParameters.x
+#define ssrThickness ssrParameters.y
void swapIfBigger(inout float a, inout float b)
{
@@ -48,9 +53,6 @@ float raycast(sampler2D depth_texture, vec3 ray_origin, vec3 ray_dir)
/* [Optional clipping to frustum sides here] */
- /* Initialize to off screen */
- vec2 hitpixel = vec2(-1.0, -1.0);
-
/* If the line is degenerate, make it cover at least one pixel
* to not have to handle zero-pixel extent as a special case later */
P1 += vec2((distance_squared(P0, P1) < 0.0001) ? 0.01 : 0.0);
@@ -80,82 +82,83 @@ float raycast(sampler2D depth_texture, vec3 ray_origin, vec3 ray_dir)
vec4 pqk = vec4(P0, Q0.z, k0);
/* Scale derivatives by the desired pixel stride */
- vec4 dPQK = vec4(dP, dQ.z, dk) * 8.0;
+ vec4 dPQK = vec4(dP, dQ.z, dk) * ssrStride;
/* We track the ray depth at +/- 1/2 pixel to treat pixels as clip-space solid
* voxels. Because the depth at -1/2 for a given pixel will be the same as at
* +1/2 for the previous iteration, we actually only have to compute one value
* per iteration. */
float prev_zmax = ray_origin.z;
- float zmax, zmin;
+ float zmax;
/* P1.x is never modified after this point, so pre-scale it by
* the step direction for a signed comparison */
float end = P1.x * step_sign;
bool hit = false;
- float hitstep, raw_depth, view_depth;
- for (hitstep = 0.0; hitstep < MAX_STEP && !hit; hitstep++) {
+ float raw_depth;
+ for (float hitstep = 0.0; hitstep < MAX_STEP && !hit; hitstep++) {
/* Ray finished & no hit*/
if ((pqk.x * step_sign) > end) break;
/* step through current cell */
pqk += dPQK;
- hitpixel = permute ? pqk.yx : pqk.xy;
- zmin = prev_zmax;
+ ivec2 hitpixel = ivec2(permute ? pqk.yx : pqk.xy);
+ raw_depth = texelFetch(depth_texture, ivec2(hitpixel), 0).r;
+
+ float zmin = prev_zmax;
zmax = (dPQK.z * 0.5 + pqk.z) / (dPQK.w * 0.5 + pqk.w);
prev_zmax = zmax;
- swapIfBigger(zmin, zmax);
+ swapIfBigger(zmin, zmax); /* ??? why don't we need this ??? */
- raw_depth = texelFetch(depth_texture, ivec2(hitpixel), 0).r;
- view_depth = get_view_z_from_depth(raw_depth);
+ float vmax = get_view_z_from_depth(raw_depth);
+ float vmin = vmax - ssrThickness;
- /* 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)) {
+ /* Note: we consider hitting the screen borders (raw_depth == 0.0)
+ * as valid to check for occluder in the refine pass */
+ if (!((zmin > vmax) || (zmax < vmin)) || (raw_depth == 0.0)) {
/* Below surface, cannot trace further */
hit = true;
}
}
if (hit) {
- /* Rewind back a step */
+ /* Rewind back a step. */
pqk -= dPQK;
- /* And do a finer trace over this segment */
- dPQK /= 16.0;
+ /* And do a finer trace over this segment. */
+ dPQK /= ssrStride;
+
+ prev_zmax = (dPQK.z * -0.5 + pqk.z) / (dPQK.w * -0.5 + pqk.w);
- for (float refinestep = 0.0; refinestep < 16.0; refinestep++) {
+ for (float refinestep = 0.0; refinestep < ssrStride * 2.0 && refinestep < MAX_REFINE_STEP * 2.0; refinestep++) {
/* step through current cell */
pqk += dPQK;
- hitpixel = permute ? pqk.yx : pqk.xy;
- zmin = prev_zmax;
+ ivec2 hitpixel = ivec2(permute ? pqk.yx : pqk.xy);
+ raw_depth = texelFetch(depth_texture, hitpixel, 0).r;
+
+ float zmin = prev_zmax;
zmax = (dPQK.z * 0.5 + pqk.z) / (dPQK.w * 0.5 + pqk.w);
prev_zmax = zmax;
swapIfBigger(zmin, zmax);
- raw_depth = texelFetch(depth_texture, ivec2(hitpixel), 0).r;
- view_depth = get_view_z_from_depth(raw_depth);
+ float vmax = get_view_z_from_depth(raw_depth);
+ float vmin = vmax - ssrThickness;
- /* 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)) {
+ if (!((zmin > vmax) || (zmax < vmin)) || (raw_depth == 0.0)) {
/* Below surface, cannot trace further */
break;
}
}
}
- /* Check failure cases (out of screen, hit background) */
- if (hit && (raw_depth != 1.0) && (raw_depth != 0.0)) {
- /* Return length */
- return (zmax - ray_origin.z) / ray_dir.z;
- }
+ /* Background case. */
+ hit = hit && (raw_depth != 1.0);
- /* Failure, return no hit */
- return -1.0;
+ /* Return length */
+ return (hit) ? (zmax - ray_origin.z) / ray_dir.z : -1.0;
}