diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2017-10-07 00:38:31 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2017-10-07 00:44:22 +0300 |
commit | 9ab18d14f6f1cfe510a2b06ee477498502d1c887 (patch) | |
tree | 1600baa94e45aa9462efe5afcea2d563b84c5059 /source/blender | |
parent | 321f773ca65921f6cb1ba13562bf9e942a30c455 (diff) |
Eevee: Modify the raycast function to be more flexible.
Make quality a parameter, and modify the ray end to be premultiplied so that the raytrace is done on a range.
This is in order to add contact shadows.
Diffstat (limited to 'source/blender')
6 files changed, 30 insertions, 25 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c index 8faa4fca937..5d2c9303865 100644 --- a/source/blender/draw/engines/eevee/eevee_effects.c +++ b/source/blender/draw/engines/eevee/eevee_effects.c @@ -749,6 +749,10 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata) } } + /* Compute pixel size, (shared with contact shadows) */ + copy_v2_v2(effects->ssr_pixelsize, viewport_size); + invert_v2(effects->ssr_pixelsize); + if (BKE_collection_engine_property_value_get_bool(props, "ssr_enable")) { effects->enabled_effects |= EFFECT_SSR; @@ -803,10 +807,6 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata) {&stl->g_data->ssr_hit_output[3], DRW_TEX_RGBA_16, DRW_TEX_TEMP}}; DRW_framebuffer_init(&fbl->screen_tracing_fb, &draw_engine_eevee_type, tracing_res[0], tracing_res[1], tex_output, effects->ssr_ray_count); - - /* Compute pixel size */ - copy_v2_v2(effects->ssr_pixelsize, viewport_size); - invert_v2(effects->ssr_pixelsize); } else { /* Cleanup to release memory */ diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index a3375c91ea1..0073d975507 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -390,17 +390,15 @@ static void add_standard_uniforms( DRW_shgroup_uniform_buffer(shgrp, "shadowTexture", &sldata->shadow_pool); DRW_shgroup_uniform_int(shgrp, "outputSsrId", ssr_id, 1); DRW_shgroup_uniform_vec4(shgrp, "aoParameters[0]", &vedata->stl->effects->ao_dist, 2); + DRW_shgroup_uniform_vec4(shgrp, "viewvecs[0]", (float *)vedata->stl->g_data->viewvecs, 2); + DRW_shgroup_uniform_buffer(shgrp, "maxzBuffer", &vedata->txl->maxzbuffer); + DRW_shgroup_uniform_vec2(shgrp, "mipRatio[0]", (float *)vedata->stl->g_data->mip_ratio, 10); + DRW_shgroup_uniform_vec4(shgrp, "ssrParameters", &vedata->stl->effects->ssr_quality, 1); if (refract_depth != NULL) { DRW_shgroup_uniform_float(shgrp, "refractionDepth", refract_depth, 1); } - if (vedata->stl->effects->use_ao || use_ssrefraction) { - DRW_shgroup_uniform_vec4(shgrp, "viewvecs[0]", (float *)vedata->stl->g_data->viewvecs, 2); - DRW_shgroup_uniform_buffer(shgrp, "maxzBuffer", &vedata->txl->maxzbuffer); - DRW_shgroup_uniform_vec2(shgrp, "mipRatio[0]", (float *)vedata->stl->g_data->mip_ratio, 10); - } if (use_ssrefraction) { DRW_shgroup_uniform_buffer(shgrp, "colorBuffer", &vedata->txl->refract_color); - DRW_shgroup_uniform_vec4(shgrp, "ssrParameters", &vedata->stl->effects->ssr_quality, 1); DRW_shgroup_uniform_float(shgrp, "borderFadeFactor", &vedata->stl->effects->ssr_border_fac, 1); DRW_shgroup_uniform_float(shgrp, "maxRoughness", &vedata->stl->effects->ssr_max_roughness, 1); DRW_shgroup_uniform_int(shgrp, "rayCount", &vedata->stl->effects->ssr_ray_count, 1); 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 7d142e50013..7a501964fae 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl @@ -10,6 +10,9 @@ uniform sampler2DArray utilTex; #define BRDF_BIAS 0.7 #define MAX_MIP 9.0 +uniform float fireflyFactor; +uniform float maxRoughness; + #ifdef STEP_RAYTRACE uniform sampler2D normalBuffer; @@ -54,7 +57,7 @@ vec4 do_planar_ssr(int index, vec3 V, vec3 N, vec3 T, vec3 B, vec3 planeNormal, * 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 = raycast(index, viewPosition, R, 1e16, jitter, a2); + vec3 hit_pos = raycast(index, viewPosition, R * 1e16, 1e16, jitter, ssrQuality, a2); return vec4(hit_pos, pdf); } @@ -73,7 +76,7 @@ vec4 do_ssr(vec3 V, vec3 N, vec3 T, vec3 B, vec3 viewPosition, float a2, vec3 ra vec3 R = reflect(-V, H); pdf = min(1024e32, pdf); /* Theoretical limit of 16bit float */ - vec3 hit_pos = raycast(-1, viewPosition, R, ssrThickness, jitter, a2); + vec3 hit_pos = raycast(-1, viewPosition, R * 1e16, ssrThickness, jitter, ssrQuality, a2); return vec4(hit_pos, pdf); } diff --git a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl index e23effb854c..5f4a4c9f89f 100644 --- a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl @@ -25,6 +25,9 @@ in vec3 worldNormal; in vec3 viewNormal; #endif +uniform float maxRoughness; +uniform int rayCount; + /* ----------- default ----------- */ vec3 eevee_surface_lit(vec3 N, vec3 albedo, vec3 f0, float roughness, float ao, int ssr_id, out vec3 ssr_spec) diff --git a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl index b9aacde264d..c1d6b7537ff 100644 --- a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl @@ -1,16 +1,12 @@ #define MAX_STEP 256 -#define MAX_REFINE_STEP 32 /* Should be max allowed stride */ uniform vec4 ssrParameters; -uniform int rayCount; #define ssrQuality ssrParameters.x #define ssrThickness ssrParameters.y #define ssrPixelSize ssrParameters.zw -uniform float maxRoughness; uniform float borderFadeFactor; -uniform float fireflyFactor; float sample_depth(vec2 uv, int index, float lod) { @@ -62,13 +58,13 @@ float refine_isect(float prev_delta, float curr_delta) return saturate(prev_delta / (prev_delta - 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) +void prepare_raycast(vec3 ray_origin, vec3 ray_end, float thickness, 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 * is behind the near plane. */ - float z_sign = -sign(ray_dir.z); - vec3 ray_end = z_sign * ray_dir * 1e16 + ray_origin; + float z_sign = -sign(ray_end.z); + ray_end = z_sign * ray_end + ray_origin; /* Project into screen space. */ vec4 ss_start, ss_end; @@ -89,6 +85,7 @@ void prepare_raycast(vec3 ray_origin, vec3 ray_dir, float thickness, out vec4 ss ss_end.w = 2.0 * ss_end.z - ss_end.w; ss_step = ss_end - ss_start; + max_time = length(ss_step.xyz); ss_step = z_sign * ss_step / length(ss_step.xyz); /* If the line is degenerate, make it cover at least one pixel @@ -99,8 +96,11 @@ void prepare_raycast(vec3 ray_origin, vec3 ray_dir, float thickness, out vec4 ss ss_step /= max(abs(ss_step.x), abs(ss_step.y)); ss_step *= ((abs(ss_step.x) > abs(ss_step.y)) ? ssrPixelSize.x : ssrPixelSize.y); + /* Clip to segment's end. */ + max_time /= length(ss_step.xyz); + /* Clipping to frustum sides. */ - max_time = line_unit_box_intersect_dist(ss_start.xyz, ss_step.xyz); + max_time = min(max_time, line_unit_box_intersect_dist(ss_start.xyz, ss_step.xyz)); /* Convert to texture coords. Z component included * since this is how it's stored in the depth buffer. @@ -117,11 +117,12 @@ void prepare_raycast(vec3 ray_origin, vec3 ray_dir, float thickness, out vec4 ss // #define GROUPED_FETCHES /* is still slower, need to see where is the bottleneck. */ /* Return the hit position, and negate the z component (making it positive) if not hit occured. */ -vec3 raycast(int index, vec3 ray_origin, vec3 ray_dir, float thickness, float ray_jitter, float roughness) +/* __ray_end__ is the ray direction premultiplied by it's maximum length */ +vec3 raycast(int index, vec3 ray_origin, vec3 ray_end, float thickness, float ray_jitter, float trace_quality, float roughness) { 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_end, thickness, ss_step, ss_start, max_time); float max_trace_time = max(0.001, max_time - 0.01); @@ -141,8 +142,8 @@ vec3 raycast(int index, vec3 ray_origin, vec3 ray_dir, float thickness, float ra float iter; for (iter = 1.0; !hit && (ray_time < max_time) && (iter < MAX_STEP); iter++) { /* Minimum stride of 2 because we are using half res minmax zbuffer. */ - float stride = max(1.0, iter * ssrQuality) * 2.0; - float lod = log2(stride * 0.5 * ssrQuality) * lod_fac; + float stride = max(1.0, iter * trace_quality) * 2.0; + float lod = log2(stride * 0.5 * trace_quality) * lod_fac; ray_time += stride; /* Save previous values. */ diff --git a/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl b/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl index 5b7ca8cdfa5..d3d6b8dc80f 100644 --- a/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl @@ -33,7 +33,7 @@ vec4 screen_space_refraction(vec3 viewPosition, vec3 N, vec3 V, float ior, float R = transform_direction(ViewMatrix, R); - vec3 hit_pos = raycast(-1, viewPosition, R, ssrThickness, jitter, roughnessSquared); + vec3 hit_pos = raycast(-1, viewPosition, R * 1e16, ssrThickness, jitter, ssrQuality, roughnessSquared); if ((hit_pos.z > 0.0) && (F_eta(ior, dot(H, V)) < 1.0)) { hit_pos = get_view_space_from_depth(hit_pos.xy, hit_pos.z); |