summaryrefslogtreecommitdiff
path: root/servers/rendering
diff options
context:
space:
mode:
authorreduz <reduzio@gmail.com>2021-02-07 21:08:59 -0300
committerreduz <reduzio@gmail.com>2021-02-07 21:30:12 -0300
commit3e2281a3470dc83272643a316ba814e19bfef575 (patch)
treeb94f22d3a61314edfab9425fe830b33de4a91adf /servers/rendering
parent57e2822a05c29db3980ad243c37a34acf6c4d14b (diff)
Improve SDFGI indirect light feedback loop
-Use occlusion for feedback, further reduces light leaking. -More control on feedback, now its a slider.
Diffstat (limited to 'servers/rendering')
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.cpp23
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.h10
-rw-r--r--servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl53
-rw-r--r--servers/rendering/renderer_scene.h2
-rw-r--r--servers/rendering/renderer_scene_cull.h2
-rw-r--r--servers/rendering/renderer_scene_render.h2
-rw-r--r--servers/rendering/rendering_server_default.h2
-rw-r--r--servers/rendering/rendering_server_wrap_mt.h2
8 files changed, 62 insertions, 34 deletions
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
index 09d2c032a8..6cc32a9bde 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
@@ -667,6 +667,13 @@ void RendererSceneRenderRD::sdfgi_update(RID p_render_buffers, RID p_environment
u.ids.push_back(rb->sdfgi->lightprobe_texture);
uniforms.push_back(u);
}
+ {
+ RD::Uniform u;
+ u.binding = 11;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.ids.push_back(rb->sdfgi->occlusion_texture);
+ uniforms.push_back(u);
+ }
cascade.sdf_direct_light_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sdfgi_shader.direct_light.version_get_shader(sdfgi_shader.direct_light_shader, 0), 0);
}
@@ -949,7 +956,7 @@ void RendererSceneRenderRD::sdfgi_update(RID p_render_buffers, RID p_environment
sdfgi->cascades[i].integrate_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, sdfgi_shader.integrate.version_get_shader(sdfgi_shader.integrate_shader, 0), 0);
}
- sdfgi->uses_multibounce = env->sdfgi_use_multibounce;
+ sdfgi->bounce_feedback = env->sdfgi_bounce_feedback;
sdfgi->energy = env->sdfgi_energy;
sdfgi->normal_bias = env->sdfgi_normal_bias;
sdfgi->probe_bias = env->sdfgi_probe_bias;
@@ -962,7 +969,7 @@ void RendererSceneRenderRD::sdfgi_update(RID p_render_buffers, RID p_environment
//check for updates
- sdfgi->uses_multibounce = env->sdfgi_use_multibounce;
+ sdfgi->bounce_feedback = env->sdfgi_bounce_feedback;
sdfgi->energy = env->sdfgi_energy;
sdfgi->normal_bias = env->sdfgi_normal_bias;
sdfgi->probe_bias = env->sdfgi_probe_bias;
@@ -1172,8 +1179,9 @@ void RendererSceneRenderRD::_sdfgi_update_light(RID p_render_buffers, RID p_envi
push_constant.grid_size[2] = rb->sdfgi->cascade_size;
push_constant.max_cascades = rb->sdfgi->cascades.size();
push_constant.probe_axis_size = rb->sdfgi->probe_axis_count;
- push_constant.multibounce = rb->sdfgi->uses_multibounce;
+ push_constant.bounce_feedback = rb->sdfgi->bounce_feedback;
push_constant.y_mult = rb->sdfgi->y_mult;
+ push_constant.use_occlusion = rb->sdfgi->uses_occlusion;
for (uint32_t i = 0; i < rb->sdfgi->cascades.size(); i++) {
SDFGI::Cascade &cascade = rb->sdfgi->cascades[i];
@@ -3073,7 +3081,7 @@ void RendererSceneRenderRD::environment_glow_set_use_high_quality(bool p_enable)
glow_high_quality = p_enable;
}
-void RendererSceneRenderRD::environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) {
+void RendererSceneRenderRD::environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
@@ -3085,7 +3093,7 @@ void RendererSceneRenderRD::environment_set_sdfgi(RID p_env, bool p_enable, RS::
env->sdfgi_cascades = p_cascades;
env->sdfgi_min_cell_size = p_min_cell_size;
env->sdfgi_use_occlusion = p_use_occlusion;
- env->sdfgi_use_multibounce = p_use_multibounce;
+ env->sdfgi_bounce_feedback = p_bounce_feedback;
env->sdfgi_read_sky_light = p_read_sky;
env->sdfgi_energy = p_energy;
env->sdfgi_normal_bias = p_normal_bias;
@@ -7782,7 +7790,7 @@ void RendererSceneRenderRD::_render_sdfgi_region(RID p_render_buffers, int p_reg
RD::get_singleton()->compute_list_add_barrier(compute_list);
- if (rb->sdfgi->uses_multibounce) {
+ if (rb->sdfgi->bounce_feedback > 0.0) {
//multibounce requires this to be stored so direct light can read from it
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sdfgi_shader.integrate_pipeline[SDGIShader::INTEGRATE_MODE_STORE]);
@@ -8120,8 +8128,9 @@ void RendererSceneRenderRD::_render_sdfgi_static_lights(RID p_render_buffers, ui
dl_push_constant.grid_size[2] = rb->sdfgi->cascade_size;
dl_push_constant.max_cascades = rb->sdfgi->cascades.size();
dl_push_constant.probe_axis_size = rb->sdfgi->probe_axis_count;
- dl_push_constant.multibounce = false; // this is static light, do not multibounce yet
+ dl_push_constant.bounce_feedback = 0.0; // this is static light, do not multibounce yet
dl_push_constant.y_mult = rb->sdfgi->y_mult;
+ dl_push_constant.use_occlusion = rb->sdfgi->uses_occlusion;
//all must be processed
dl_push_constant.process_offset = 0;
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
index cdcdb73132..ac567e9bdc 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
@@ -778,7 +778,7 @@ private:
RS::EnvironmentSDFGICascades sdfgi_cascades;
float sdfgi_min_cell_size = 0.2;
bool sdfgi_use_occlusion = false;
- bool sdfgi_use_multibounce = false;
+ float sdfgi_bounce_feedback = 0.0;
bool sdfgi_read_sky_light = false;
float sdfgi_energy = 1.0;
float sdfgi_normal_bias = 1.1;
@@ -1028,7 +1028,7 @@ private:
RID cascades_ubo;
bool uses_occlusion = false;
- bool uses_multibounce = false;
+ float bounce_feedback = 0.0;
bool reads_sky = false;
float energy = 1.0;
float normal_bias = 1.1;
@@ -1163,9 +1163,9 @@ private:
uint32_t process_increment;
int32_t probe_axis_size;
- uint32_t multibounce;
+ float bounce_feedback;
float y_mult;
- uint32_t pad;
+ uint32_t use_occlusion;
};
enum {
@@ -1721,7 +1721,7 @@ public:
bool environment_is_ssr_enabled(RID p_env) const;
bool environment_is_sdfgi_enabled(RID p_env) const;
- virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias);
+ virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias);
virtual void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count);
virtual void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames);
virtual void environment_set_sdfgi_frames_to_update_light(RS::EnvironmentSDFGIFramesToUpdateLight p_update);
diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl
index 5e8934adb4..dc7238abed 100644
--- a/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl
+++ b/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl
@@ -80,6 +80,7 @@ layout(set = 0, binding = 9, std140) buffer restrict readonly Lights {
lights;
layout(set = 0, binding = 10) uniform texture2DArray lightprobe_texture;
+layout(set = 0, binding = 11) uniform texture3D occlusion_texture;
layout(push_constant, binding = 0, std430) uniform Params {
vec3 grid_size;
@@ -91,9 +92,9 @@ layout(push_constant, binding = 0, std430) uniform Params {
uint process_increment;
int probe_axis_size;
- bool multibounce;
+ float bounce_feedback;
float y_mult;
- uint pad;
+ bool use_occlusion;
}
params;
@@ -159,7 +160,8 @@ void main() {
// Add indirect light first, in order to save computation resources
#ifdef MODE_PROCESS_DYNAMIC
- if (params.multibounce) {
+ if (params.bounce_feedback > 0.001) {
+ vec3 feedback = (params.bounce_feedback < 1.0) ? (albedo * params.bounce_feedback) : mix(albedo, vec3(1.0), params.bounce_feedback - 1.0);
vec3 pos = (vec3(positioni) + vec3(0.5)) * float(params.probe_axis_size - 1) / params.grid_size;
ivec3 probe_base_pos = ivec3(pos);
@@ -172,7 +174,7 @@ void main() {
vec3 base_tex_posf = vec3(tex_pos);
vec2 tex_pixel_size = 1.0 / vec2(ivec2((OCT_SIZE + 2) * params.probe_axis_size * params.probe_axis_size, (OCT_SIZE + 2) * params.probe_axis_size));
- vec3 probe_uv_offset = (ivec3(OCT_SIZE + 2, OCT_SIZE + 2, (OCT_SIZE + 2) * params.probe_axis_size)) * tex_pixel_size.xyx;
+ vec3 probe_uv_offset = vec3(ivec3(OCT_SIZE + 2, OCT_SIZE + 2, (OCT_SIZE + 2) * params.probe_axis_size)) * tex_pixel_size.xyx;
for (uint j = 0; j < 8; j++) {
ivec3 offset = (ivec3(j) >> ivec3(0, 1, 2)) & ivec3(1, 1, 1);
@@ -192,18 +194,35 @@ void main() {
for (uint k = 0; k < 6; k++) {
if (bool(valid_aniso & (1 << k))) {
vec3 n = aniso_dir[k];
- float weight = trilinear.x * trilinear.y * trilinear.z * max(0.005, dot(n, probe_dir));
-
- vec3 tex_posf = base_tex_posf + vec3(octahedron_encode(n) * float(OCT_SIZE), 0.0);
- tex_posf.xy *= tex_pixel_size;
-
- vec3 pos_uvw = tex_posf;
- pos_uvw.xy += vec2(offset.xy) * probe_uv_offset.xy;
- pos_uvw.x += float(offset.z) * probe_uv_offset.z;
- vec3 indirect_light = textureLod(sampler2DArray(lightprobe_texture, linear_sampler), pos_uvw, 0.0).rgb;
-
- light_accum[k] += indirect_light * weight;
- weight_accum[k] += weight;
+ float weight = trilinear.x * trilinear.y * trilinear.z * max(0, dot(n, probe_dir));
+
+ if (weight > 0.0 && params.use_occlusion) {
+ ivec3 occ_indexv = abs((cascades.data[params.cascade].probe_world_offset + probe_posi) & ivec3(1, 1, 1)) * ivec3(1, 2, 4);
+ vec4 occ_mask = mix(vec4(0.0), vec4(1.0), equal(ivec4(occ_indexv.x | occ_indexv.y), ivec4(0, 1, 2, 3)));
+
+ vec3 occ_pos = (vec3(positioni) + aniso_dir[k] + vec3(0.5)) / params.grid_size;
+ occ_pos.z += float(params.cascade);
+ if (occ_indexv.z != 0) { //z bit is on, means index is >=4, so make it switch to the other half of textures
+ occ_pos.x += 1.0;
+ }
+ occ_pos *= vec3(0.5, 1.0, 1.0 / float(params.max_cascades)); //renormalize
+ float occlusion = dot(textureLod(sampler3D(occlusion_texture, linear_sampler), occ_pos, 0.0), occ_mask);
+
+ weight *= occlusion;
+ }
+
+ if (weight > 0.0) {
+ vec3 tex_posf = base_tex_posf + vec3(octahedron_encode(n) * float(OCT_SIZE), 0.0);
+ tex_posf.xy *= tex_pixel_size;
+
+ vec3 pos_uvw = tex_posf;
+ pos_uvw.xy += vec2(offset.xy) * probe_uv_offset.xy;
+ pos_uvw.x += float(offset.z) * probe_uv_offset.z;
+ vec3 indirect_light = textureLod(sampler2DArray(lightprobe_texture, linear_sampler), pos_uvw, 0.0).rgb;
+
+ light_accum[k] += indirect_light * weight;
+ weight_accum[k] += weight;
+ }
}
}
}
@@ -211,7 +230,7 @@ void main() {
for (uint k = 0; k < 6; k++) {
if (weight_accum[k] > 0.0) {
light_accum[k] /= weight_accum[k];
- light_accum[k] *= albedo;
+ light_accum[k] *= feedback;
}
}
}
diff --git a/servers/rendering/renderer_scene.h b/servers/rendering/renderer_scene.h
index e8966414ab..d1379da045 100644
--- a/servers/rendering/renderer_scene.h
+++ b/servers/rendering/renderer_scene.h
@@ -134,7 +134,7 @@ public:
virtual void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) = 0;
- virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) = 0;
+ virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) = 0;
virtual void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) = 0;
virtual void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) = 0;
diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h
index d6d730af15..a422eb8def 100644
--- a/servers/rendering/renderer_scene_cull.h
+++ b/servers/rendering/renderer_scene_cull.h
@@ -996,7 +996,7 @@ public:
PASS2(environment_set_volumetric_fog_volume_size, int, int)
PASS1(environment_set_volumetric_fog_filter_active, bool)
- PASS11(environment_set_sdfgi, RID, bool, RS::EnvironmentSDFGICascades, float, RS::EnvironmentSDFGIYScale, bool, bool, bool, float, float, float)
+ PASS11(environment_set_sdfgi, RID, bool, RS::EnvironmentSDFGICascades, float, RS::EnvironmentSDFGIYScale, bool, float, bool, float, float, float)
PASS1(environment_set_sdfgi_ray_count, RS::EnvironmentSDFGIRayCount)
PASS1(environment_set_sdfgi_frames_to_converge, RS::EnvironmentSDFGIFramesToConverge)
PASS1(environment_set_sdfgi_frames_to_update_light, RS::EnvironmentSDFGIFramesToUpdateLight)
diff --git a/servers/rendering/renderer_scene_render.h b/servers/rendering/renderer_scene_render.h
index 72fcdd3758..06664b84f3 100644
--- a/servers/rendering/renderer_scene_render.h
+++ b/servers/rendering/renderer_scene_render.h
@@ -128,7 +128,7 @@ public:
virtual void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to) = 0;
- virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, bool p_use_multibounce, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) = 0;
+ virtual void environment_set_sdfgi(RID p_env, bool p_enable, RS::EnvironmentSDFGICascades p_cascades, float p_min_cell_size, RS::EnvironmentSDFGIYScale p_y_scale, bool p_use_occlusion, float p_bounce_feedback, bool p_read_sky, float p_energy, float p_normal_bias, float p_probe_bias) = 0;
virtual void environment_set_sdfgi_ray_count(RS::EnvironmentSDFGIRayCount p_ray_count) = 0;
virtual void environment_set_sdfgi_frames_to_converge(RS::EnvironmentSDFGIFramesToConverge p_frames) = 0;
diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h
index 823d28c669..16bdc3deb1 100644
--- a/servers/rendering/rendering_server_default.h
+++ b/servers/rendering/rendering_server_default.h
@@ -620,7 +620,7 @@ public:
BIND2(environment_set_volumetric_fog_volume_size, int, int)
BIND1(environment_set_volumetric_fog_filter_active, bool)
- BIND11(environment_set_sdfgi, RID, bool, EnvironmentSDFGICascades, float, EnvironmentSDFGIYScale, bool, bool, bool, float, float, float)
+ BIND11(environment_set_sdfgi, RID, bool, EnvironmentSDFGICascades, float, EnvironmentSDFGIYScale, bool, float, bool, float, float, float)
BIND1(environment_set_sdfgi_ray_count, EnvironmentSDFGIRayCount)
BIND1(environment_set_sdfgi_frames_to_converge, EnvironmentSDFGIFramesToConverge)
BIND1(environment_set_sdfgi_frames_to_update_light, EnvironmentSDFGIFramesToUpdateLight)
diff --git a/servers/rendering/rendering_server_wrap_mt.h b/servers/rendering/rendering_server_wrap_mt.h
index 81e202780e..f57dbbe8ae 100644
--- a/servers/rendering/rendering_server_wrap_mt.h
+++ b/servers/rendering/rendering_server_wrap_mt.h
@@ -505,7 +505,7 @@ public:
FUNC6(environment_set_ssao_quality, EnvironmentSSAOQuality, bool, float, int, float, float)
- FUNC11(environment_set_sdfgi, RID, bool, EnvironmentSDFGICascades, float, EnvironmentSDFGIYScale, bool, bool, bool, float, float, float)
+ FUNC11(environment_set_sdfgi, RID, bool, EnvironmentSDFGICascades, float, EnvironmentSDFGIYScale, bool, float, bool, float, float, float)
FUNC1(environment_set_sdfgi_ray_count, EnvironmentSDFGIRayCount)
FUNC1(environment_set_sdfgi_frames_to_converge, EnvironmentSDFGIFramesToConverge)
FUNC1(environment_set_sdfgi_frames_to_update_light, EnvironmentSDFGIFramesToUpdateLight)