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:
Diffstat (limited to 'source/blender/draw')
-rw-r--r--source/blender/draw/engines/eevee/eevee_effects.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_materials.c3
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h5
-rw-r--r--source/blender/draw/engines/eevee/eevee_renderpasses.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_screen_raytrace.c29
-rw-r--r--source/blender/draw/engines/eevee/shaders/common_uniforms_lib.glsl2
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl514
-rw-r--r--source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl7
-rw-r--r--source/blender/draw/engines/eevee/shaders/ssr_lib.glsl8
-rw-r--r--source/blender/draw/engines/eevee/shaders/surface_lib.glsl7
10 files changed, 190 insertions, 389 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c
index d1d7c67d16c..f4f7acb8862 100644
--- a/source/blender/draw/engines/eevee/eevee_effects.c
+++ b/source/blender/draw/engines/eevee/eevee_effects.c
@@ -149,8 +149,6 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata,
*/
common_data->hiz_uv_scale[0] = viewport_size[0] / effects->hiz_size[0];
common_data->hiz_uv_scale[1] = viewport_size[1] / effects->hiz_size[1];
- common_data->hiz_uv_scale[2] = 1.0f / effects->hiz_size[0];
- common_data->hiz_uv_scale[3] = 1.0f / effects->hiz_size[1];
/* Compute pixel size. Size is multiplied by 2 because it is applied in NDC [-1..1] range. */
sldata->common_data.ssr_pixelsize[0] = 2.0f / size_fs[0];
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index bc7db4b5df6..042fa621117 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -128,7 +128,8 @@ void EEVEE_material_bind_resources(DRWShadingGroup *shgrp,
DRW_shgroup_uniform_float_copy(
shgrp, "refractionDepth", (refract_depth) ? *refract_depth : 0.0);
if (use_ssrefraction) {
- DRW_shgroup_uniform_texture_ref(shgrp, "colorBuffer", &vedata->txl->filtered_radiance);
+ DRW_shgroup_uniform_texture_ref(
+ shgrp, "refractColorBuffer", &vedata->txl->filtered_radiance);
}
}
if (use_alpha_blend) {
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 45afee31591..eb1c51f49dd 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -737,7 +737,6 @@ typedef struct EEVEE_EffectsInfo {
struct GPUTexture *ssr_normal_input; /* Textures from pool */
struct GPUTexture *ssr_specrough_input;
struct GPUTexture *ssr_hit_output;
- struct GPUTexture *ssr_pdf_output;
/* Temporal Anti Aliasing */
int taa_reproject_sample;
int taa_current_sample;
@@ -854,8 +853,8 @@ typedef struct EEVEE_EffectsInfo {
* - Arrays of vec2/vec3 are padded as arrays of vec4.
* - sizeof(bool) == sizeof(int) in GLSL so use int in C */
typedef struct EEVEE_CommonUniformBuffer {
- float prev_persmat[4][4]; /* mat4 */
- float hiz_uv_scale[4]; /* vec4 */
+ float prev_persmat[4][4]; /* mat4 */
+ float hiz_uv_scale[2], ssr_uv_scale[2]; /* vec4 */
/* Ambient Occlusion */
/* -- 16 byte aligned -- */
float ao_dist, pad1, ao_factor, pad2; /* vec4 */
diff --git a/source/blender/draw/engines/eevee/eevee_renderpasses.c b/source/blender/draw/engines/eevee/eevee_renderpasses.c
index 0e16037f42d..5739024993e 100644
--- a/source/blender/draw/engines/eevee/eevee_renderpasses.c
+++ b/source/blender/draw/engines/eevee/eevee_renderpasses.c
@@ -490,7 +490,7 @@ void EEVEE_renderpasses_draw_debug(EEVEE_Data *vedata)
tx = txl->maxzbuffer;
break;
case 2:
- tx = effects->ssr_pdf_output;
+ /* UNUSED */
break;
case 3:
tx = effects->ssr_normal_input;
diff --git a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c
index 80a1c9fcbe5..00004b28ef3 100644
--- a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c
+++ b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c
@@ -77,6 +77,7 @@ int EEVEE_screen_raytrace_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
common_data->ssr_firefly_fac = FLT_MAX;
}
+ void *owner = (void *)EEVEE_screen_raytrace_init;
const int divisor = (effects->reflection_trace_full) ? 1 : 2;
int tracing_res[2] = {(int)viewport_size[0] / divisor, (int)viewport_size[1] / divisor};
const int size_fs[2] = {(int)viewport_size[0], (int)viewport_size[1]};
@@ -86,22 +87,22 @@ int EEVEE_screen_raytrace_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
tracing_res[0] = max_ii(1, tracing_res[0]);
tracing_res[1] = max_ii(1, tracing_res[1]);
+ common_data->ssr_uv_scale[0] = size_fs[0] / ((float)tracing_res[0] * divisor);
+ common_data->ssr_uv_scale[1] = size_fs[1] / ((float)tracing_res[1] * divisor);
+
/* MRT for the shading pass in order to output needed data for the SSR pass. */
- effects->ssr_specrough_input = DRW_texture_pool_query_2d(
- size_fs[0], size_fs[1], format, &draw_engine_eevee_type);
+ effects->ssr_specrough_input = DRW_texture_pool_query_2d(UNPACK2(size_fs), format, owner);
GPU_framebuffer_texture_attach(fbl->main_fb, effects->ssr_specrough_input, 2, 0);
/* Ray-tracing output. */
- effects->ssr_hit_output = DRW_texture_pool_query_2d(
- tracing_res[0], tracing_res[1], GPU_RG16I, &draw_engine_eevee_type);
- effects->ssr_pdf_output = DRW_texture_pool_query_2d(
- tracing_res[0], tracing_res[1], GPU_R16F, &draw_engine_eevee_type);
+ effects->ssr_hit_output = DRW_texture_pool_query_2d(UNPACK2(tracing_res), GPU_RGBA16F, owner);
GPU_framebuffer_ensure_config(&fbl->screen_tracing_fb,
- {GPU_ATTACHMENT_NONE,
- GPU_ATTACHMENT_TEXTURE(effects->ssr_hit_output),
- GPU_ATTACHMENT_TEXTURE(effects->ssr_pdf_output)});
+ {
+ GPU_ATTACHMENT_NONE,
+ GPU_ATTACHMENT_TEXTURE(effects->ssr_hit_output),
+ });
return EFFECT_SSR | EFFECT_NORMAL_BUFFER | EFFECT_RADIANCE_BUFFER | EFFECT_DOUBLE_BUFFER |
((use_refraction) ? EFFECT_REFRACT : 0);
@@ -111,7 +112,6 @@ int EEVEE_screen_raytrace_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
GPU_FRAMEBUFFER_FREE_SAFE(fbl->screen_tracing_fb);
effects->ssr_specrough_input = NULL;
effects->ssr_hit_output = NULL;
- effects->ssr_pdf_output = NULL;
return 0;
}
@@ -148,7 +148,6 @@ void EEVEE_screen_raytrace_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *v
*/
DRW_PASS_CREATE(psl->ssr_raytrace, DRW_STATE_WRITE_COLOR);
DRWShadingGroup *grp = DRW_shgroup_create(trace_shader, psl->ssr_raytrace);
- DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &e_data.depth_src);
DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input);
DRW_shgroup_uniform_texture_ref(grp, "specroughBuffer", &effects->ssr_specrough_input);
DRW_shgroup_uniform_texture_ref(grp, "maxzBuffer", &txl->maxzbuffer);
@@ -164,17 +163,17 @@ void EEVEE_screen_raytrace_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *v
}
DRW_shgroup_call(grp, quad, NULL);
+ eGPUSamplerState no_filter = GPU_SAMPLER_DEFAULT;
+
DRW_PASS_CREATE(psl->ssr_resolve, DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ADD);
grp = DRW_shgroup_create(resolve_shader, psl->ssr_resolve);
- DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &e_data.depth_src);
DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input);
DRW_shgroup_uniform_texture_ref(grp, "specroughBuffer", &effects->ssr_specrough_input);
DRW_shgroup_uniform_texture_ref(grp, "probeCubes", &lcache->cube_tx.tex);
DRW_shgroup_uniform_texture_ref(grp, "probePlanars", &vedata->txl->planar_pool);
DRW_shgroup_uniform_texture_ref(grp, "planarDepth", &vedata->txl->planar_depth);
- DRW_shgroup_uniform_texture_ref(grp, "hitBuffer", &effects->ssr_hit_output);
- DRW_shgroup_uniform_texture_ref(grp, "pdfBuffer", &effects->ssr_pdf_output);
- DRW_shgroup_uniform_texture_ref(grp, "prevColorBuffer", &txl->filtered_radiance);
+ DRW_shgroup_uniform_texture_ref_ex(grp, "hitBuffer", &effects->ssr_hit_output, no_filter);
+ DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", &txl->filtered_radiance);
DRW_shgroup_uniform_texture_ref(grp, "maxzBuffer", &txl->maxzbuffer);
DRW_shgroup_uniform_texture_ref(grp, "shadowCubeTexture", &sldata->shadow_cube_pool);
DRW_shgroup_uniform_texture_ref(grp, "shadowCascadeTexture", &sldata->shadow_cascade_pool);
diff --git a/source/blender/draw/engines/eevee/shaders/common_uniforms_lib.glsl b/source/blender/draw/engines/eevee/shaders/common_uniforms_lib.glsl
index 24de4520207..b3174afc799 100644
--- a/source/blender/draw/engines/eevee/shaders/common_uniforms_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/common_uniforms_lib.glsl
@@ -69,3 +69,5 @@ layout(std140) uniform common_block
#define ssrQuality ssrParameters.x
#define ssrThickness ssrParameters.y
#define ssrPixelSize ssrParameters.zw
+
+#define ssrUvScale hizUvScale.zw
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 66183e1bc02..a9139b7a146 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl
@@ -6,32 +6,55 @@
#pragma BLENDER_REQUIRE(closure_eval_lib.glsl)
#pragma BLENDER_REQUIRE(raytrace_lib.glsl)
#pragma BLENDER_REQUIRE(lightprobe_lib.glsl)
-#pragma BLENDER_REQUIRE(ssr_lib.glsl)
-
-/* Based on Stochastic Screen Space Reflections
- * https://www.ea.com/frostbite/news/stochastic-screen-space-reflections */
-
-#define MAX_MIP 9.0
+#pragma BLENDER_REQUIRE(bsdf_common_lib.glsl)
+#pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl)
+#pragma BLENDER_REQUIRE(surface_lib.glsl)
+
+/* Based on:
+ * "Stochastic Screen Space Reflections"
+ * by Tomasz Stachowiak.
+ * https://www.ea.com/frostbite/news/stochastic-screen-space-reflections
+ * and
+ * "Stochastic all the things: raytracing in hybrid real-time rendering"
+ * by Tomasz Stachowiak.
+ * https://media.contentapi.ea.com/content/dam/ea/seed/presentations/dd18-seed-raytracing-in-hybrid-real-time-rendering.pdf
+ */
uniform ivec2 halfresOffset;
-ivec2 encode_hit_data(vec2 hit_pos, bool has_hit, bool is_planar)
+struct HitData {
+ /** Hit direction scaled by intersection time. */
+ vec3 hit_dir;
+ /** Inverse probability of ray spawning in this direction. */
+ float ray_pdf_inv;
+ /** True if ray has hit valid geometry. */
+ bool is_hit;
+ /** True if ray was generated from a planar reflection probe. */
+ bool is_planar;
+};
+
+vec4 encode_hit_data(HitData data)
{
- ivec2 hit_data = ivec2(saturate(hit_pos) * 32767.0); /* 16bit signed int limit */
- hit_data.x *= (is_planar) ? -1 : 1;
- hit_data.y *= (has_hit) ? 1 : -1;
- return hit_data;
+ vec4 encoded_data;
+ encoded_data.xyz = data.hit_dir;
+ /* Encode planar in Z sign. */
+ /* TODO fixme */
+ // encoded_data.z = data.is_planar ? -encoded_data.z : encoded_data.z;
+ /* Record 1.0 / pdf to reduce the computation in the resolve phase. */
+ /* Encode hit validity in sign. */
+ encoded_data.w = data.ray_pdf_inv * ((data.is_hit) ? 1.0 : -1.0);
+ return encoded_data;
}
-vec2 decode_hit_data(vec2 hit_data, out bool has_hit, out bool is_planar)
+HitData decode_hit_data(vec4 encoded_data)
{
- is_planar = (hit_data.x < 0);
- has_hit = (hit_data.y > 0);
- 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;
+ HitData data;
+ data.hit_dir.xyz = encoded_data.xyz;
+ /* TODO fixme */
+ data.is_planar = false;
+ data.ray_pdf_inv = abs(encoded_data.w);
+ data.is_hit = (encoded_data.w > 0.0);
+ return data;
}
#ifdef STEP_RAYTRACE
@@ -39,30 +62,29 @@ vec2 decode_hit_data(vec2 hit_data, out bool has_hit, out bool is_planar)
uniform sampler2D normalBuffer;
uniform sampler2D specroughBuffer;
-layout(location = 0) out ivec2 hitData;
-layout(location = 1) out float pdfData;
+layout(location = 0) out vec4 hitData;
void do_planar_ssr(
- int index, vec3 V, vec3 N, vec3 T, vec3 B, vec3 planeNormal, vec3 vP, float a2, vec4 rand)
+ int index, vec3 V, vec3 N, vec3 T, vec3 B, vec3 viewPlaneNormal, vec3 vP, float a2, vec4 rand)
{
float NH;
- vec3 H = sample_ggx(rand.xzw, a2, N, T, B, NH); /* Microfacet normal */
+ /* Microfacet normal */
+ vec3 H = sample_ggx(rand.xzw, a2, N, T, B, NH);
float pdf = pdf_ggx_reflect(NH, a2);
vec3 R = reflect(-V, H);
- R = reflect(R, planeNormal);
+ R = reflect(R, viewPlaneNormal);
/* If ray is bad (i.e. going below the plane) regenerate. */
- if (dot(R, planeNormal) > 0.0) {
- vec3 H = sample_ggx(rand.xzw * vec3(1.0, -1.0, -1.0), a2, N, T, B, NH); /* Microfacet normal */
+ if (dot(R, viewPlaneNormal) > 0.0) {
+ /* Microfacet normal */
+ vec3 H = sample_ggx(rand.xzw * vec3(1.0, -1.0, -1.0), a2, N, T, B, NH);
pdf = pdf_ggx_reflect(NH, a2);
R = reflect(-V, H);
- R = reflect(R, planeNormal);
+ R = reflect(R, viewPlaneNormal);
}
- pdfData = min(1024e32, pdf); /* Theoretical limit of 16bit float */
-
Ray ray;
ray.origin = vP;
ray.direction = R * 1e16;
@@ -72,10 +94,14 @@ void do_planar_ssr(
params.trace_quality = ssrQuality;
params.roughness = a2;
- vec3 hit_pos;
- bool hit = raytrace_planar(ray, params, index, hit_pos);
+ HitData data;
+ data.is_planar = true;
+ data.ray_pdf_inv = safe_rcp(pdf);
+ data.is_hit = raytrace_planar(ray, params, index, data.hit_dir);
+ data.hit_dir = get_view_space_from_depth(data.hit_dir.xy, data.hit_dir.z);
+ data.hit_dir -= ray.origin;
- hitData = encode_hit_data(hit_pos.xy, hit, true);
+ hitData = encode_hit_data(data);
}
void do_ssr(vec3 V, vec3 N, vec3 T, vec3 B, vec3 vP, float a2, vec4 rand)
@@ -85,32 +111,6 @@ void do_ssr(vec3 V, vec3 N, vec3 T, vec3 B, vec3 vP, float a2, vec4 rand)
vec3 H = sample_ggx(rand.xzw, a2, N, T, B, NH);
vec3 R = reflect(-V, H);
- const float bad_ray_threshold = 0.01;
-
- vec3 vNg = safe_normalize(cross(dFdx(vP), dFdy(vP)));
-
- /* If ray is bad (i.e. going below the surface) regenerate. */
- if (dot(R, vNg) < bad_ray_threshold) {
- H = sample_ggx(rand.xzw * vec3(1.0, -1.0, -1.0), a2, N, T, B, NH);
- R = reflect(-V, H);
- }
- if (dot(R, vNg) < bad_ray_threshold) {
- H = sample_ggx(rand.xzw * vec3(1.0, 1.0, -1.0), a2, N, T, B, NH);
- R = reflect(-V, H);
- }
- if (dot(R, vNg) < bad_ray_threshold) {
- H = sample_ggx(rand.xzw * vec3(1.0, -1.0, 1.0), a2, N, T, B, NH);
- R = reflect(-V, H);
- }
- if (dot(R, vNg) < bad_ray_threshold) {
- /* Not worth tracing. */
- return;
- }
-
- pdfData = min(1024e32, pdf_ggx_reflect(NH, a2)); /* Theoretical limit of 16bit float */
-
- vP = raytrace_offset(vP, vNg);
-
Ray ray;
ray.origin = vP;
ray.direction = R * 1e16;
@@ -121,10 +121,14 @@ void do_ssr(vec3 V, vec3 N, vec3 T, vec3 B, vec3 vP, float a2, vec4 rand)
params.trace_quality = ssrQuality;
params.roughness = a2;
- vec3 hit_pos;
- bool hit = raytrace(ray, params, true, hit_pos);
+ HitData data;
+ data.is_planar = true;
+ data.ray_pdf_inv = safe_rcp(pdf_ggx_reflect(NH, a2));
+ data.is_hit = raytrace(ray, params, true, data.hit_dir);
+ data.hit_dir = get_view_space_from_depth(data.hit_dir.xy, data.hit_dir.z);
+ data.hit_dir -= ray.origin;
- hitData = encode_hit_data(hit_pos.xy, hit, false);
+ hitData = encode_hit_data(data);
}
in vec4 uvcoordsvar;
@@ -132,11 +136,16 @@ in vec4 uvcoordsvar;
void main()
{
vec2 uvs = uvcoordsvar.xy;
- float depth = textureLod(depthBuffer, uvs, 0.0).r;
+ float depth = textureLod(maxzBuffer, uvs * hizUvScale.xy, 0.0).r;
+
+ HitData data;
+ data.is_planar = false;
+ data.ray_pdf_inv = safe_rcp(0.0);
+ data.is_hit = false;
+ data.hit_dir = vec3(0.0, 0.0, 0.0);
/* Default: not hits. */
- hitData = encode_hit_data(vec2(0.5), false, false);
- pdfData = 0.0;
+ hitData = encode_hit_data(data);
/* Early out */
/* We can't do discard because we don't clear the render target. */
@@ -193,9 +202,9 @@ void main()
/* TODO optimize, use view space for all. */
vec3 tracePosition = line_plane_intersect(P, V, pd.pl_plane_eq);
tracePosition = transform_point(ViewMatrix, tracePosition);
- vec3 planeNormal = transform_direction(ViewMatrix, pd.pl_normal);
+ vec3 viewPlaneNormal = transform_direction(ViewMatrix, pd.pl_normal);
- do_planar_ssr(i, vV, vN, vT, vB, planeNormal, tracePosition, a2, rand);
+ do_planar_ssr(i, vV, vN, vT, vB, viewPlaneNormal, tracePosition, a2, rand);
return;
}
}
@@ -205,270 +214,92 @@ void main()
#else /* STEP_RESOLVE */
-uniform sampler2D prevColorBuffer; /* previous frame */
+uniform sampler2D colorBuffer; /* previous frame */
uniform sampler2D normalBuffer;
uniform sampler2D specroughBuffer;
-
-uniform isampler2D hitBuffer;
-uniform sampler2D pdfBuffer;
-
-uniform int neighborOffset;
+uniform sampler2D hitBuffer;
in vec4 uvcoordsvar;
-const ivec2 neighbors[32] = ivec2[32](ivec2(0, 0),
- ivec2(1, 1),
- ivec2(-2, 0),
- ivec2(0, -2),
- ivec2(0, 0),
- ivec2(1, -1),
- ivec2(-2, 0),
- ivec2(0, 2),
- ivec2(0, 0),
- ivec2(-1, -1),
- ivec2(2, 0),
- ivec2(0, 2),
- ivec2(0, 0),
- ivec2(-1, 1),
- ivec2(2, 0),
- ivec2(0, -2),
-
- ivec2(0, 0),
- ivec2(2, 2),
- ivec2(-2, 2),
- ivec2(0, -1),
- ivec2(0, 0),
- ivec2(2, -2),
- ivec2(-2, -2),
- ivec2(0, 1),
- ivec2(0, 0),
- ivec2(-2, -2),
- ivec2(-2, 2),
- ivec2(1, 0),
- ivec2(0, 0),
- ivec2(2, 2),
- ivec2(2, -2),
- ivec2(-1, 0));
-
out vec4 fragColor;
-# if 0 /* Finish reprojection with motion vectors */
-vec3 get_motion_vector(vec3 pos)
-{
-}
-
-/* http://bitsquid.blogspot.fr/2017/06/reprojecting-reflections_22.html */
-vec3 find_reflection_incident_point(vec3 cam, vec3 hit, vec3 pos, vec3 N)
-{
- float d_cam = point_plane_projection_dist(cam, pos, N);
- float d_hit = point_plane_projection_dist(hit, pos, N);
-
- if (d_hit < d_cam) {
- /* Swap */
- float tmp = d_cam;
- d_cam = d_hit;
- d_hit = tmp;
- }
-
- vec3 proj_cam = cam - (N * d_cam);
- vec3 proj_hit = hit - (N * d_hit);
-
- return (proj_hit - proj_cam) * d_cam / (d_cam + d_hit) + proj_cam;
-}
-# endif
-
float brightness(vec3 c)
{
return max(max(c.r, c.g), c.b);
}
-vec2 get_reprojected_reflection(vec3 hit, vec3 pos, vec3 N)
+vec4 ssr_get_scene_color_and_mask(vec3 hit_vP, int planar_index, float mip)
{
- /* TODO real reprojection with motion vectors, etc... */
- return project_point(pastViewProjectionMatrix, hit).xy * 0.5 + 0.5;
-}
-
-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;
+ vec2 uv;
+ if (planar_index != -1) {
+ uv = get_uvs_from_view(hit_vP);
+ /* Planar X axis is flipped. */
+ uv.x = 1.0 - uv.x;
}
else {
- return textureLod(depthBuffer, hit_co, 0.0).r;
+ /* Find hit position in previous frame. */
+ /* TODO Combine matrices. */
+ vec3 hit_P = transform_point(ViewMatrixInverse, hit_vP);
+ /* TODO real reprojection with motion vectors, etc... */
+ uv = project_point(pastViewProjectionMatrix, hit_P).xy * 0.5 + 0.5;
}
-}
-vec3 get_hit_vector(vec3 hit_pos,
- PlanarData pd,
- vec3 P,
- vec3 N,
- vec3 V,
- bool is_planar,
- inout vec2 hit_co,
- inout float mask)
-{
- vec3 hit_vec;
-
- if (is_planar) {
- /* Reflect back the hit position to have it in non-reflected world space */
- vec3 trace_pos = line_plane_intersect(P, 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;
+ vec3 color;
+ if (planar_index != -1) {
+ color = textureLod(probePlanars, vec3(uv, planar_index), mip).rgb;
}
else {
- /* Find hit position in previous frame. */
- hit_co = get_reprojected_reflection(hit_pos, P, N);
- hit_vec = hit_pos - P;
+ color = textureLod(colorBuffer, uv * hizUvScale.xy, mip).rgb;
}
- mask = screen_border_mask(hit_co);
- return hit_vec;
-}
+ /* Clamped brightness. */
+ float luma = brightness(color);
+ color *= 1.0 - max(0.0, luma - ssrFireflyFac) * safe_rcp(luma);
-vec3 get_scene_color(vec2 ref_uvs, float mip, float planar_index, bool is_planar)
-{
- if (is_planar) {
- return textureLod(probePlanars, vec3(ref_uvs, planar_index), mip).rgb;
- }
- else {
- return textureLod(prevColorBuffer, ref_uvs * hizUvScale.xy, mip).rgb;
- }
+ float mask = screen_border_mask(uv);
+ return vec4(color, mask);
}
-vec4 get_ssr_samples(vec4 hit_pdf,
- ivec4 hit_data[2],
- PlanarData pd,
- float planar_index,
- vec3 P,
- vec3 N,
- vec3 V,
- float roughnessSquared,
- float cone_tan,
- vec2 source_uvs,
- inout float weight_acc)
+void resolve_reflection_sample(int planar_index,
+ vec2 sample_uv,
+ vec3 vP,
+ vec3 vN,
+ vec3 vV,
+ float roughness_squared,
+ float cone_tan,
+ inout float weight_accum,
+ inout vec4 ssr_accum)
{
- bvec4 is_planar, has_hit;
- vec4 hit_co[2];
- hit_co[0].xy = decode_hit_data(hit_data[0].xy, has_hit.x, is_planar.x);
- hit_co[0].zw = decode_hit_data(hit_data[0].zw, has_hit.y, is_planar.y);
- hit_co[1].xy = decode_hit_data(hit_data[1].xy, has_hit.z, is_planar.z);
- hit_co[1].zw = decode_hit_data(hit_data[1].zw, has_hit.w, is_planar.w);
-
- /* TODO/FIXME(fclem) This is giving precision issues due to refined intersection. This is most
- * noticeable on rough surfaces. */
- vec4 hit_depth;
- hit_depth.x = get_sample_depth(hit_co[0].xy, is_planar.x, planar_index);
- hit_depth.y = get_sample_depth(hit_co[0].zw, is_planar.y, planar_index);
- hit_depth.z = get_sample_depth(hit_co[1].xy, is_planar.z, planar_index);
- hit_depth.w = get_sample_depth(hit_co[1].zw, is_planar.w, planar_index);
-
- /* Hit position in view space. */
- vec3 hit_view[4];
- hit_view[0] = get_view_space_from_depth(hit_co[0].xy, hit_depth.x);
- hit_view[1] = get_view_space_from_depth(hit_co[0].zw, hit_depth.y);
- hit_view[2] = get_view_space_from_depth(hit_co[1].xy, hit_depth.z);
- hit_view[3] = get_view_space_from_depth(hit_co[1].zw, hit_depth.w);
-
- vec4 homcoord = vec4(hit_view[0].z, hit_view[1].z, hit_view[2].z, hit_view[3].z);
- homcoord = ProjectionMatrix[2][3] * homcoord + ProjectionMatrix[3][3];
-
- /* Hit position in world space. */
- vec3 hit_pos[4];
- hit_pos[0] = transform_point(ViewMatrixInverse, hit_view[0]);
- hit_pos[1] = transform_point(ViewMatrixInverse, hit_view[1]);
- hit_pos[2] = transform_point(ViewMatrixInverse, hit_view[2]);
- hit_pos[3] = transform_point(ViewMatrixInverse, hit_view[3]);
-
- /* Get actual hit vector and hit coordinate (from last frame). */
- vec4 mask = vec4(1.0);
- hit_pos[0] = get_hit_vector(hit_pos[0], pd, P, N, V, is_planar.x, hit_co[0].xy, mask.x);
- hit_pos[1] = get_hit_vector(hit_pos[1], pd, P, N, V, is_planar.y, hit_co[0].zw, mask.y);
- hit_pos[2] = get_hit_vector(hit_pos[2], pd, P, N, V, is_planar.z, hit_co[1].xy, mask.z);
- hit_pos[3] = get_hit_vector(hit_pos[3], pd, P, N, V, is_planar.w, hit_co[1].zw, mask.w);
-
- vec4 hit_dist;
- hit_dist.x = length(hit_pos[0]);
- hit_dist.y = length(hit_pos[1]);
- hit_dist.z = length(hit_pos[2]);
- hit_dist.w = length(hit_pos[3]);
- hit_dist = max(vec4(1e-8), hit_dist);
-
- /* Normalize */
- hit_pos[0] /= hit_dist.x;
- hit_pos[1] /= hit_dist.y;
- hit_pos[2] /= hit_dist.z;
- hit_pos[3] /= hit_dist.w;
+ HitData data = decode_hit_data(texture(hitBuffer, sample_uv * ssrUvScale));
- /* Compute cone footprint in screen space. */
- vec4 cone_footprint = hit_dist * cone_tan;
- cone_footprint = ssrBrdfBias * 0.5 * cone_footprint *
- max(ProjectionMatrix[0][0], ProjectionMatrix[1][1]) / homcoord;
+ float hit_dist = length(data.hit_dir);
- /* Estimate a cone footprint to sample a corresponding mipmap level. */
- vec4 mip = log2(cone_footprint * max_v2(vec2(textureSize(depthBuffer, 0))));
- mip = clamp(mip, 0.0, MAX_MIP);
+ /* Slide 54. */
+ float bsdf = bsdf_ggx(vN, data.hit_dir / hit_dist, vV, roughness_squared);
- /* Slide 54 */
- vec4 bsdf;
- bsdf.x = bsdf_ggx(N, hit_pos[0], V, roughnessSquared);
- bsdf.y = bsdf_ggx(N, hit_pos[1], V, roughnessSquared);
- bsdf.z = bsdf_ggx(N, hit_pos[2], V, roughnessSquared);
- bsdf.w = bsdf_ggx(N, hit_pos[3], V, roughnessSquared);
+ float weight = bsdf * data.ray_pdf_inv;
- vec4 weight = step(1e-8, hit_pdf) * bsdf / max(vec4(1e-8), hit_pdf);
+ /* Do not add light if ray has failed but still weight it. */
+ if (!data.is_hit || (planar_index == -1 && data.is_planar) ||
+ (planar_index != -1 && !data.is_planar)) {
+ weight_accum += weight;
+ return;
+ }
- vec3 sample[4];
- sample[0] = get_scene_color(hit_co[0].xy, mip.x, planar_index, is_planar.x);
- sample[1] = get_scene_color(hit_co[0].zw, mip.y, planar_index, is_planar.y);
- sample[2] = get_scene_color(hit_co[1].xy, mip.z, planar_index, is_planar.z);
- sample[3] = get_scene_color(hit_co[1].zw, mip.w, planar_index, is_planar.w);
+ vec3 hit_vP = vP + data.hit_dir;
- /* Clamped brightness. */
- vec4 luma;
- luma.x = brightness(sample[0]);
- luma.y = brightness(sample[1]);
- luma.z = brightness(sample[2]);
- luma.w = brightness(sample[3]);
- luma = max(vec4(1e-8), luma);
- luma = 1.0 - max(vec4(0.0), luma - ssrFireflyFac) / luma;
-
- sample[0] *= luma.x;
- sample[1] *= luma.y;
- sample[2] *= luma.z;
- sample[3] *= luma.w;
-
- /* Protection against NaNs in the history buffer.
- * This could be removed if some previous pass has already
- * sanitized the input. */
- if (any(isnan(sample[0]))) {
- sample[0] = vec3(0.0);
- weight.x = 0.0;
- }
- if (any(isnan(sample[1]))) {
- sample[1] = vec3(0.0);
- weight.y = 0.0;
- }
- if (any(isnan(sample[2]))) {
- sample[2] = vec3(0.0);
- weight.z = 0.0;
- }
- if (any(isnan(sample[3]))) {
- sample[3] = vec3(0.0);
- weight.w = 0.0;
- }
+ /* Compute cone footprint in screen space. */
+ float cone_footprint = hit_dist * cone_tan;
+ float homcoord = ProjectionMatrix[2][3] * hit_vP.z + ProjectionMatrix[3][3];
+ cone_footprint *= max(ProjectionMatrix[0][0], ProjectionMatrix[1][1]) / homcoord;
+ cone_footprint *= ssrBrdfBias * 0.5;
+ /* Estimate a cone footprint to sample a corresponding mipmap level. */
+ float mip = log2(cone_footprint * max_v2(vec2(textureSize(specroughBuffer, 0))));
- weight_acc += sum(weight);
+ vec4 radiance_mask = ssr_get_scene_color_and_mask(hit_vP, planar_index, mip);
- /* Do not add light if ray has failed. */
- vec4 accum;
- accum = vec4(sample[0], mask.x) * weight.x * float(has_hit.x);
- accum += vec4(sample[1], mask.y) * weight.y * float(has_hit.y);
- accum += vec4(sample[2], mask.z) * weight.z * float(has_hit.z);
- accum += vec4(sample[3], mask.w) * weight.w * float(has_hit.w);
- return accum;
+ ssr_accum += radiance_mask * weight;
+ weight_accum += weight;
}
void raytrace_resolve(ClosureInputGlossy cl_in,
@@ -476,74 +307,55 @@ void raytrace_resolve(ClosureInputGlossy cl_in,
inout ClosureEvalCommon cl_common,
inout ClosureOutputGlossy cl_out)
{
-# ifdef FULLRES
- ivec2 texel = ivec2(gl_FragCoord.xy);
-# else
- ivec2 texel = ivec2(gl_FragCoord.xy / 2.0);
-# endif
- /* Using world space */
- vec3 V = cl_common.V;
- vec3 N = cl_in.N;
- vec3 P = cl_common.P;
-
float roughness = cl_in.roughness;
- float roughnessSquared = max(1e-3, sqr(roughness));
-
- /* Resolve SSR */
- float cone_cos = cone_cosine(roughnessSquared);
- float cone_tan = sqrt(1 - cone_cos * cone_cos) / cone_cos;
- cone_tan *= mix(saturate(dot(N, -V) * 2.0), 1.0, roughness); /* Elongation fit */
-
- vec2 source_uvs = project_point(pastViewProjectionMatrix, P).xy * 0.5 + 0.5;
vec4 ssr_accum = vec4(0.0);
float weight_acc = 0.0;
if (roughness < ssrMaxRoughness + 0.2) {
- /* TODO optimize with textureGather */
- /* Doing these fetches early to hide latency. */
- vec4 hit_pdf;
- hit_pdf.x = texelFetch(pdfBuffer, texel + neighbors[0 + neighborOffset], 0).r;
- hit_pdf.y = texelFetch(pdfBuffer, texel + neighbors[1 + neighborOffset], 0).r;
- hit_pdf.z = texelFetch(pdfBuffer, texel + neighbors[2 + neighborOffset], 0).r;
- hit_pdf.w = texelFetch(pdfBuffer, texel + neighbors[3 + neighborOffset], 0).r;
-
- ivec4 hit_data[2];
- hit_data[0].xy = texelFetch(hitBuffer, texel + neighbors[0 + neighborOffset], 0).rg;
- hit_data[0].zw = texelFetch(hitBuffer, texel + neighbors[1 + neighborOffset], 0).rg;
- hit_data[1].xy = texelFetch(hitBuffer, texel + neighbors[2 + neighborOffset], 0).rg;
- hit_data[1].zw = texelFetch(hitBuffer, texel + neighbors[3 + neighborOffset], 0).rg;
-
/* Find Planar Reflections affecting this pixel */
- PlanarData pd;
- float planar_index;
+ int planar_index = -1;
for (int i = 0; i < MAX_PLANAR && i < prbNumPlanar; i++) {
- pd = planars_data[i];
-
- float fade = probe_attenuation_planar(pd, P);
- fade *= probe_attenuation_planar_normal_roughness(pd, N, 0.0);
-
+ float fade = probe_attenuation_planar(planars_data[i], cl_common.P);
+ fade *= probe_attenuation_planar_normal_roughness(planars_data[i], cl_in.N, 0.0);
if (fade > 0.5) {
- planar_index = float(i);
+ planar_index = i;
break;
}
}
- ssr_accum += get_ssr_samples(hit_pdf,
- hit_data,
- pd,
- planar_index,
- P,
- N,
- V,
- roughnessSquared,
- cone_tan,
- source_uvs,
- weight_acc);
+ vec3 V, P, N;
+ if (planar_index != -1) {
+ PlanarData pd = planars_data[planar_index];
+ /* Evaluate everything in refected space. */
+ P = line_plane_intersect(cl_common.P, cl_common.V, pd.pl_plane_eq);
+ V = reflect(cl_common.V, pd.pl_normal);
+ N = reflect(cl_in.N, pd.pl_normal);
+ }
+ else {
+ V = cl_common.V;
+ P = cl_common.P;
+ N = cl_in.N;
+ }
+
+ /* Using view space */
+ vec3 vV = transform_direction(ViewMatrix, cl_common.V);
+ vec3 vP = transform_point(ViewMatrix, cl_common.P);
+ vec3 vN = transform_direction(ViewMatrix, cl_in.N);
+
+ float roughness_squared = max(1e-3, sqr(roughness));
+ float cone_cos = cone_cosine(roughness_squared);
+ float cone_tan = sqrt(1.0 - cone_cos * cone_cos) / cone_cos;
+ cone_tan *= mix(saturate(dot(vN, -vV) * 2.0), 1.0, roughness); /* Elongation fit */
+
+ vec2 sample_uv = uvcoordsvar.xy;
+
+ resolve_reflection_sample(
+ planar_index, sample_uv, vP, vN, vV, roughness_squared, cone_tan, weight_acc, ssr_accum);
}
/* Compute SSR contribution */
- ssr_accum *= (weight_acc == 0.0) ? 0.0 : (1.0 / weight_acc);
+ ssr_accum *= safe_rcp(weight_acc);
/* fade between 0.5 and 1.0 roughness */
ssr_accum.a *= smoothstep(ssrMaxRoughness + 0.2, ssrMaxRoughness, roughness);
@@ -555,13 +367,13 @@ CLOSURE_EVAL_FUNCTION_DECLARE_1(ssr_resolve, Glossy)
void main()
{
- ivec2 texel = ivec2(gl_FragCoord.xy);
- float depth = texelFetch(depthBuffer, texel, 0).r;
+ float depth = textureLod(maxzBuffer, uvcoordsvar.xy * hizUvScale.xy, 0.0).r;
if (depth == 1.0) {
discard;
}
+ ivec2 texel = ivec2(gl_FragCoord.xy);
vec4 speccol_roughness = texelFetch(specroughBuffer, texel, 0).rgba;
vec3 brdf = speccol_roughness.rgb;
float roughness = speccol_roughness.a;
diff --git a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
index 7c375aabb62..dce50a7051e 100644
--- a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
@@ -15,13 +15,6 @@ struct Ray {
vec3 direction;
};
-vec3 raytrace_offset(vec3 P, vec3 Ng)
-{
- /* TODO(fclem) better offset */
- const float epsilon_f = 1e-4;
- return P + epsilon_f * Ng;
-}
-
/* Inputs expected to be in viewspace. */
void raytrace_clip_ray_to_near_plane(inout Ray ray)
{
diff --git a/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl b/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl
index 5a09120916a..37624fc31ea 100644
--- a/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl
@@ -9,6 +9,10 @@
#define BTDF_BIAS 0.85
+uniform sampler2D refractColorBuffer;
+
+uniform float refractionDepth;
+
vec4 screen_space_refraction(vec3 vP, vec3 N, vec3 V, float ior, float roughnessSquared, vec4 rand)
{
float a2 = max(5e-6, roughnessSquared * roughnessSquared);
@@ -75,10 +79,10 @@ vec4 screen_space_refraction(vec3 vP, vec3 N, vec3 V, float ior, float roughness
vec2 hit_uvs = project_point(ProjectionMatrix, hit_pos).xy * 0.5 + 0.5;
/* Texel footprint */
- vec2 texture_size = vec2(textureSize(colorBuffer, 0).xy);
+ vec2 texture_size = vec2(textureSize(refractColorBuffer, 0).xy) / hizUvScale.xy;
float mip = clamp(log2(cone_footprint * max(texture_size.x, texture_size.y)), 0.0, 9.0);
- vec3 spec = textureLod(colorBuffer, hit_uvs * hizUvScale.xy, mip).xyz;
+ vec3 spec = textureLod(refractColorBuffer, hit_uvs * hizUvScale.xy, mip).xyz;
float mask = screen_border_mask(hit_uvs);
return vec4(spec, mask);
diff --git a/source/blender/draw/engines/eevee/shaders/surface_lib.glsl b/source/blender/draw/engines/eevee/shaders/surface_lib.glsl
index e80dc1761f0..0acb35b2399 100644
--- a/source/blender/draw/engines/eevee/shaders/surface_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/surface_lib.glsl
@@ -1,12 +1,5 @@
/** This describe the entire interface of the shader. */
-/* Samplers */
-uniform sampler2D colorBuffer;
-uniform sampler2D depthBuffer;
-
-/* Uniforms */
-uniform float refractionDepth;
-
#define SURFACE_INTERFACE \
vec3 worldPosition; \
vec3 viewPosition; \