Skip to content

Commit 483f245

Browse files
committed
Added atlas texture srgb and projector sampler in the fog shaders
Added computation of the projector in the fog
1 parent 7a1d375 commit 483f245

5 files changed

Lines changed: 97 additions & 13 deletions

File tree

servers/rendering/renderer_rd/environment/fog.cpp

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "fog.h"
3232

3333
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
34+
#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
3435
#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
3536
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
3637
#include "servers/rendering/rendering_server_default.h"
@@ -513,7 +514,7 @@ Vector3i Fog::_point_get_position_in_froxel_volume(const Vector3 &p_point, float
513514
return Vector3i(fog_position);
514515
}
515516

516-
void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const Projection &p_cam_projection, const Transform3D &p_cam_transform, const Transform3D &p_prev_cam_inv_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes) {
517+
void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const Projection &p_cam_projection, const Transform3D &p_cam_transform, const Transform3D &p_prev_cam_inv_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes, const RendererRD::MaterialStorage::Samplers &p_samplers) {
517518
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
518519
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
519520

@@ -956,6 +957,47 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P
956957
uniforms.push_back(u);
957958
}
958959

960+
{
961+
RD::Uniform u;
962+
u.binding = 20;
963+
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
964+
RID decal_atlas = RendererRD::TextureStorage::get_singleton()->decal_atlas_get_texture_srgb();
965+
u.append_id(decal_atlas);
966+
uniforms.push_back(u);
967+
copy_uniforms.push_back(u);
968+
}
969+
970+
{
971+
RD::Uniform u;
972+
u.binding = 21;
973+
u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
974+
RID sampler;
975+
switch (RendererSceneRenderRD::get_singleton()->light_projectors_get_filter()) {
976+
case RS::LIGHT_PROJECTOR_FILTER_NEAREST: {
977+
sampler = p_samplers.get_sampler(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
978+
} break;
979+
case RS::LIGHT_PROJECTOR_FILTER_LINEAR: {
980+
sampler = p_samplers.get_sampler(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
981+
} break;
982+
case RS::LIGHT_PROJECTOR_FILTER_NEAREST_MIPMAPS: {
983+
sampler = p_samplers.get_sampler(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
984+
} break;
985+
case RS::LIGHT_PROJECTOR_FILTER_LINEAR_MIPMAPS: {
986+
sampler = p_samplers.get_sampler(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
987+
} break;
988+
case RS::LIGHT_PROJECTOR_FILTER_NEAREST_MIPMAPS_ANISOTROPIC: {
989+
sampler = p_samplers.get_sampler(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
990+
} break;
991+
case RS::LIGHT_PROJECTOR_FILTER_LINEAR_MIPMAPS_ANISOTROPIC: {
992+
sampler = p_samplers.get_sampler(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
993+
} break;
994+
}
995+
996+
u.append_id(sampler);
997+
uniforms.push_back(u);
998+
copy_uniforms.push_back(u);
999+
}
1000+
9591001
if (fog->copy_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(fog->copy_uniform_set)) {
9601002
RD::get_singleton()->free(fog->copy_uniform_set);
9611003
}

servers/rendering/renderer_rd/environment/fog.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ class Fog : public RendererFog {
350350
RID env;
351351
SkyRD *sky;
352352
};
353-
void volumetric_fog_update(const VolumetricFogSettings &p_settings, const Projection &p_cam_projection, const Transform3D &p_cam_transform, const Transform3D &p_prev_cam_inv_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes);
353+
void volumetric_fog_update(const VolumetricFogSettings &p_settings, const Projection &p_cam_projection, const Transform3D &p_cam_transform, const Transform3D &p_prev_cam_inv_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes, const RendererRD::MaterialStorage::Samplers &p_samplers);
354354
};
355355

356356
} // namespace RendererRD

servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,7 +1260,7 @@ void RenderForwardClustered::_debug_draw_cluster(Ref<RenderSceneBuffersRD> p_ren
12601260
////////////////////////////////////////////////////////////////////////////////
12611261
// FOG SHADER
12621262

1263-
void RenderForwardClustered::_update_volumetric_fog(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, const Projection &p_cam_projection, const Transform3D &p_cam_transform, const Transform3D &p_prev_cam_inv_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes) {
1263+
void RenderForwardClustered::_update_volumetric_fog(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, const Projection &p_cam_projection, const Transform3D &p_cam_transform, const Transform3D &p_prev_cam_inv_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes, const RendererRD::MaterialStorage::Samplers &p_samplers) {
12641264
ERR_FAIL_COND(p_render_buffers.is_null());
12651265

12661266
Ref<RenderBufferDataForwardClustered> rb_data = p_render_buffers->get_custom_data(RB_SCOPE_FORWARD_CLUSTERED);
@@ -1328,7 +1328,7 @@ void RenderForwardClustered::_update_volumetric_fog(Ref<RenderSceneBuffersRD> p_
13281328
settings.sky = &sky;
13291329
settings.gi = &gi;
13301330

1331-
RendererRD::Fog::get_singleton()->volumetric_fog_update(settings, p_cam_projection, p_cam_transform, p_prev_cam_inv_transform, p_shadow_atlas, p_directional_light_count, p_use_directional_shadows, p_positional_light_count, p_voxel_gi_count, p_fog_volumes);
1331+
RendererRD::Fog::get_singleton()->volumetric_fog_update(settings, p_cam_projection, p_cam_transform, p_prev_cam_inv_transform, p_shadow_atlas, p_directional_light_count, p_use_directional_shadows, p_positional_light_count, p_voxel_gi_count, p_fog_volumes, p_samplers);
13321332
}
13331333
}
13341334

@@ -1441,7 +1441,7 @@ void RenderForwardClustered::_copy_framebuffer_to_ssil(Ref<RenderSceneBuffersRD>
14411441
}
14421442
}
14431443

1444-
void RenderForwardClustered::_pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_ssil, bool p_use_gi, const RID *p_normal_roughness_slices, RID p_voxel_gi_buffer) {
1444+
void RenderForwardClustered::_pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_ssil, bool p_use_gi, const RID *p_normal_roughness_slices, RID p_voxel_gi_buffer, const RendererRD::MaterialStorage::Samplers &p_samplers) {
14451445
// Render shadows while GI is rendering, due to how barriers are handled, this should happen at the same time
14461446
RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();
14471447
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
@@ -1592,7 +1592,7 @@ void RenderForwardClustered::_pre_opaque_render(RenderDataRD *p_render_data, boo
15921592
if (rb_data.is_valid()) {
15931593
RENDER_TIMESTAMP("Update Volumetric Fog");
15941594
bool directional_shadows = RendererRD::LightStorage::get_singleton()->has_directional_shadows(directional_light_count);
1595-
_update_volumetric_fog(rb, p_render_data->environment, p_render_data->scene_data->cam_projection, p_render_data->scene_data->cam_transform, p_render_data->scene_data->prev_cam_transform.affine_inverse(), p_render_data->shadow_atlas, directional_light_count, directional_shadows, positional_light_count, p_render_data->voxel_gi_count, *p_render_data->fog_volumes);
1595+
_update_volumetric_fog(rb, p_render_data->environment, p_render_data->scene_data->cam_projection, p_render_data->scene_data->cam_transform, p_render_data->scene_data->prev_cam_transform.affine_inverse(), p_render_data->shadow_atlas, directional_light_count, directional_shadows, positional_light_count, p_render_data->voxel_gi_count, *p_render_data->fog_volumes, p_samplers);
15961596
}
15971597
}
15981598

@@ -2111,7 +2111,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
21112111
normal_roughness_views[v] = rb_data->get_normal_roughness(v);
21122112
}
21132113
}
2114-
_pre_opaque_render(p_render_data, using_ssao, using_ssil, using_sdfgi || using_voxelgi, normal_roughness_views, rb_data.is_valid() && rb_data->has_voxelgi() ? rb_data->get_voxelgi() : RID());
2114+
_pre_opaque_render(p_render_data, using_ssao, using_ssil, using_sdfgi || using_voxelgi, normal_roughness_views, rb_data.is_valid() && rb_data->has_voxelgi() ? rb_data->get_voxelgi() : RID(), samplers);
21152115

21162116
RENDER_TIMESTAMP("Render Opaque Pass");
21172117

servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -737,7 +737,7 @@ class RenderForwardClustered : public RendererSceneRenderRD {
737737
/* Volumetric fog */
738738
RID shadow_sampler;
739739

740-
void _update_volumetric_fog(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, const Projection &p_cam_projection, const Transform3D &p_cam_transform, const Transform3D &p_prev_cam_inv_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes);
740+
void _update_volumetric_fog(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, const Projection &p_cam_projection, const Transform3D &p_cam_transform, const Transform3D &p_prev_cam_inv_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes, const RendererRD::MaterialStorage::Samplers &p_samplers);
741741

742742
/* Render shadows */
743743

@@ -751,7 +751,7 @@ class RenderForwardClustered : public RendererSceneRenderRD {
751751
void _process_ssao(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, const RID *p_normal_buffers, const Projection *p_projections);
752752
void _process_ssil(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, const RID *p_normal_buffers, const Projection *p_projections, const Transform3D &p_transform);
753753
void _copy_framebuffer_to_ssil(Ref<RenderSceneBuffersRD> p_render_buffers);
754-
void _pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_ssil, bool p_use_gi, const RID *p_normal_roughness_slices, RID p_voxel_gi_buffer);
754+
void _pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_ssil, bool p_use_gi, const RID *p_normal_roughness_slices, RID p_voxel_gi_buffer, const RendererRD::MaterialStorage::Samplers &p_samplers);
755755
void _process_ssr(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_dest_framebuffer, const RID *p_normal_buffer_slices, RID p_specular_buffer, const RID *p_metallic_slices, RID p_environment, const Projection *p_projections, const Vector3 *p_eye_offsets, bool p_use_additive);
756756
void _process_sss(Ref<RenderSceneBuffersRD> p_render_buffers, const Projection &p_camera);
757757

servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,9 @@ layout(set = 0, binding = 19) uniform textureCube sky_texture;
213213
#endif
214214
#endif // MODE_COPY
215215

216+
layout(set = 0, binding = 20) uniform texture2D decal_atlas_srgb;
217+
layout(set = 0, binding = 21) uniform sampler light_projector_sampler;
218+
216219
float get_depth_at_pos(float cell_depth_size, int z) {
217220
float d = float(z) * cell_depth_size + cell_depth_size * 0.5; //center of voxels
218221
d = pow(d, params.detail_spread);
@@ -276,7 +279,7 @@ const vec3 halton_map[TEMPORAL_FRAMES] = vec3[](
276279
vec3(0.03125, 0.59259259, 0.32));
277280

278281
// Higher values will make light in volumetric fog fade out sooner when it's occluded by shadow.
279-
const float INV_FOG_FADE = 10.0;
282+
const float INV_FOG_FADE = 300.0; //TODO: We should change this constant to a user setting
280283

281284
void main() {
282285
vec3 fog_cell_size = 1.0 / vec3(params.fog_volume_size);
@@ -385,6 +388,7 @@ void main() {
385388
for (uint i = 0; i < params.directional_light_count; i++) {
386389
if (directional_lights.data[i].volumetric_fog_energy > 0.001) {
387390
vec3 shadow_attenuation = vec3(1.0);
391+
vec3 light_color = directional_lights.data[i].color;
388392

389393
if (directional_lights.data[i].shadow_opacity > 0.001) {
390394
float depth_z = -view_pos.z;
@@ -420,10 +424,24 @@ void main() {
420424

421425
shadow = mix(shadow, 1.0, smoothstep(directional_lights.data[i].fade_from, directional_lights.data[i].fade_to, view_pos.z)); //done with negative values for performance
422426

427+
// Compute projector color
428+
if (directional_lights.data[i].projector_rect != vec4(0.0)) {
429+
vec4 splane = (directional_lights.data[i].projector_matrix * v);
430+
splane /= splane.w;
431+
432+
splane.xy = (splane.xy * 0.5 + 0.5) * directional_lights.data[i].projector_scale.xy + directional_lights.data[i].projector_offset.xy;
433+
splane.xy = fract(splane.xy);
434+
vec2 proj_uv = splane.xy * directional_lights.data[i].projector_rect.zw;
435+
436+
vec4 proj = textureLod(sampler2D(decal_atlas_srgb, light_projector_sampler), proj_uv + directional_lights.data[i].projector_rect.xy, 0.0);
437+
438+
light_color *= proj.rgb * proj.a;
439+
}
440+
423441
shadow_attenuation = mix(vec3(1.0 - directional_lights.data[i].shadow_opacity), vec3(1.0), shadow);
424442
}
425443

426-
total_light += shadow_attenuation * directional_lights.data[i].color * directional_lights.data[i].energy * henyey_greenstein(dot(normalize(view_pos), normalize(directional_lights.data[i].direction)), params.phase_g) * directional_lights.data[i].volumetric_fog_energy;
444+
total_light += shadow_attenuation * light_color * directional_lights.data[i].energy * henyey_greenstein(dot(normalize(view_pos), normalize(directional_lights.data[i].direction)), params.phase_g) * directional_lights.data[i].volumetric_fog_energy;
427445
}
428446
}
429447

@@ -505,13 +523,16 @@ void main() {
505523

506524
float shadow_len = length(local_vert); //need to remember shadow len from here
507525
vec3 shadow_sample = normalize(local_vert);
526+
float original_shadow_sample_z = shadow_sample.z;
508527

509-
if (shadow_sample.z >= 0.0) {
528+
if (original_shadow_sample_z >= 0.0) {
510529
uv_rect.xy += flip_offset;
511530
}
512531

513532
shadow_sample.z = 1.0 + abs(shadow_sample.z);
514-
vec3 pos = vec3(shadow_sample.xy / shadow_sample.z, shadow_len - omni_lights.data[light_index].shadow_bias);
533+
shadow_sample.xy /= shadow_sample.z;
534+
535+
vec3 pos = vec3(shadow_sample.xy, shadow_len - omni_lights.data[light_index].shadow_bias);
515536
pos.z *= omni_lights.data[light_index].inv_radius;
516537
pos.z = 1.0 - pos.z;
517538

@@ -520,6 +541,19 @@ void main() {
520541

521542
float depth = texture(sampler2D(shadow_atlas, linear_sampler), pos.xy).r;
522543

544+
// Compute projector color
545+
if (omni_lights.data[light_index].projector_rect != vec4(0.0)) {
546+
vec4 atlas_rect = omni_lights.data[light_index].projector_rect;
547+
if (original_shadow_sample_z >= 0.0) {
548+
atlas_rect.y += atlas_rect.w;
549+
}
550+
551+
vec2 proj_uv = (shadow_sample.xy * 0.5 + 0.5) * atlas_rect.zw;
552+
553+
vec4 proj = textureLod(sampler2D(decal_atlas_srgb, light_projector_sampler), proj_uv + atlas_rect.xy, 0.0);
554+
light *= proj.rgb * proj.a;
555+
}
556+
523557
shadow_attenuation = mix(1.0 - omni_lights.data[light_index].shadow_opacity, 1.0, exp(min(0.0, (pos.z - depth)) / omni_lights.data[light_index].inv_radius * INV_FOG_FADE));
524558
}
525559
total_light += light * attenuation * shadow_attenuation * henyey_greenstein(dot(normalize(light_pos - view_pos), normalize(view_pos)), params.phase_g) * omni_lights.data[light_index].volumetric_fog_energy;
@@ -598,6 +632,14 @@ void main() {
598632

599633
float depth = texture(sampler2D(shadow_atlas, linear_sampler), pos.xy).r;
600634

635+
// Compute projector color
636+
if (spot_lights.data[light_index].projector_rect != vec4(0.0)) {
637+
vec2 proj_uv = splane.xy * spot_lights.data[light_index].projector_rect.zw;
638+
639+
vec4 proj = textureLod(sampler2D(decal_atlas_srgb, light_projector_sampler), proj_uv + spot_lights.data[light_index].projector_rect.xy, 0.0);
640+
light *= proj.rgb * proj.a;
641+
}
642+
601643
shadow_attenuation = mix(1.0 - spot_lights.data[light_index].shadow_opacity, 1.0, exp(min(0.0, (pos.z - depth)) / spot_lights.data[light_index].inv_radius * INV_FOG_FADE));
602644
}
603645
total_light += light * attenuation * shadow_attenuation * henyey_greenstein(dot(normalize(light_rel_vec), normalize(view_pos)), params.phase_g) * spot_lights.data[light_index].volumetric_fog_energy;

0 commit comments

Comments
 (0)