diff options
Diffstat (limited to 'servers/rendering/renderer_rd/shaders')
| -rw-r--r-- | servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl | 89 | ||||
| -rw-r--r-- | servers/rendering/renderer_rd/shaders/light_data_inc.glsl | 4 | 
2 files changed, 49 insertions, 44 deletions
diff --git a/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl b/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl index 6f79b9e771..07d5223472 100644 --- a/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl @@ -270,6 +270,9 @@ const vec3 halton_map[TEMPORAL_FRAMES] = vec3[](  		vec3(0.9375, 0.25925926, 0.12),  		vec3(0.03125, 0.59259259, 0.32)); +// Higher values will make light in volumetric fog fade out sooner when it's occluded by shadow. +const float INV_FOG_FADE = 10.0; +  void main() {  	vec3 fog_cell_size = 1.0 / vec3(params.fog_volume_size); @@ -375,46 +378,48 @@ void main() {  	if (total_density > 0.001) {  		for (uint i = 0; i < params.directional_light_count; i++) { -			vec3 shadow_attenuation = vec3(1.0); - -			if (directional_lights.data[i].shadow_opacity > 0.001) { -				float depth_z = -view_pos.z; - -				vec4 pssm_coord; -				vec3 light_dir = directional_lights.data[i].direction; -				vec4 v = vec4(view_pos, 1.0); -				float z_range; - -				if (depth_z < directional_lights.data[i].shadow_split_offsets.x) { -					pssm_coord = (directional_lights.data[i].shadow_matrix1 * v); -					pssm_coord /= pssm_coord.w; -					z_range = directional_lights.data[i].shadow_z_range.x; - -				} else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { -					pssm_coord = (directional_lights.data[i].shadow_matrix2 * v); -					pssm_coord /= pssm_coord.w; -					z_range = directional_lights.data[i].shadow_z_range.y; - -				} else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { -					pssm_coord = (directional_lights.data[i].shadow_matrix3 * v); -					pssm_coord /= pssm_coord.w; -					z_range = directional_lights.data[i].shadow_z_range.z; - -				} else { -					pssm_coord = (directional_lights.data[i].shadow_matrix4 * v); -					pssm_coord /= pssm_coord.w; -					z_range = directional_lights.data[i].shadow_z_range.w; -				} +			if (directional_lights.data[i].volumetric_fog_energy > 0.001) { +				vec3 shadow_attenuation = vec3(1.0); + +				if (directional_lights.data[i].shadow_opacity > 0.001) { +					float depth_z = -view_pos.z; + +					vec4 pssm_coord; +					vec3 light_dir = directional_lights.data[i].direction; +					vec4 v = vec4(view_pos, 1.0); +					float z_range; + +					if (depth_z < directional_lights.data[i].shadow_split_offsets.x) { +						pssm_coord = (directional_lights.data[i].shadow_matrix1 * v); +						pssm_coord /= pssm_coord.w; +						z_range = directional_lights.data[i].shadow_z_range.x; + +					} else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { +						pssm_coord = (directional_lights.data[i].shadow_matrix2 * v); +						pssm_coord /= pssm_coord.w; +						z_range = directional_lights.data[i].shadow_z_range.y; + +					} else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { +						pssm_coord = (directional_lights.data[i].shadow_matrix3 * v); +						pssm_coord /= pssm_coord.w; +						z_range = directional_lights.data[i].shadow_z_range.z; + +					} else { +						pssm_coord = (directional_lights.data[i].shadow_matrix4 * v); +						pssm_coord /= pssm_coord.w; +						z_range = directional_lights.data[i].shadow_z_range.w; +					} -				float depth = texture(sampler2D(directional_shadow_atlas, linear_sampler), pssm_coord.xy).r; -				float shadow = exp(min(0.0, (depth - pssm_coord.z)) * z_range * directional_lights.data[i].shadow_volumetric_fog_fade); +					float depth = texture(sampler2D(directional_shadow_atlas, linear_sampler), pssm_coord.xy).r; +					float shadow = exp(min(0.0, (depth - pssm_coord.z)) * z_range * INV_FOG_FADE); -				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 +					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 -				shadow_attenuation = mix(vec3(0.0), vec3(1.0), shadow); -			} +					shadow_attenuation = mix(vec3(1.0 - directional_lights.data[i].shadow_opacity), vec3(1.0), shadow); +				} -			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); +				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; +			}  		}  		// Compute light from sky @@ -481,7 +486,7 @@ void main() {  					float d = distance(omni_lights.data[light_index].position, view_pos);  					float shadow_attenuation = 1.0; -					if (d * omni_lights.data[light_index].inv_radius < 1.0) { +					if (omni_lights.data[light_index].volumetric_fog_energy > 0.001 && d * omni_lights.data[light_index].inv_radius < 1.0) {  						float attenuation = get_omni_attenuation(d, omni_lights.data[light_index].inv_radius, omni_lights.data[light_index].attenuation);  						vec3 light = omni_lights.data[light_index].color; @@ -509,9 +514,9 @@ void main() {  							float depth = texture(sampler2D(shadow_atlas, linear_sampler), pos.xy).r; -							shadow_attenuation = exp(min(0.0, (depth - pos.z)) / omni_lights.data[light_index].inv_radius * omni_lights.data[light_index].shadow_volumetric_fog_fade); +							shadow_attenuation = mix(1.0 - omni_lights.data[light_index].shadow_opacity, 1.0, exp(min(0.0, (depth - pos.z)) / omni_lights.data[light_index].inv_radius * INV_FOG_FADE));  						} -						total_light += light * attenuation * shadow_attenuation * henyey_greenstein(dot(normalize(light_pos - view_pos), normalize(view_pos)), params.phase_g); +						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;  					}  				}  			} @@ -562,7 +567,7 @@ void main() {  					float d = length(light_rel_vec);  					float shadow_attenuation = 1.0; -					if (d * spot_lights.data[light_index].inv_radius < 1.0) { +					if (spot_lights.data[light_index].volumetric_fog_energy > 0.001 && d * spot_lights.data[light_index].inv_radius < 1.0) {  						float attenuation = get_omni_attenuation(d, spot_lights.data[light_index].inv_radius, spot_lights.data[light_index].attenuation);  						vec3 spot_dir = spot_lights.data[light_index].direction; @@ -595,9 +600,9 @@ void main() {  							float depth = texture(sampler2D(shadow_atlas, linear_sampler), pos.xy).r; -							shadow_attenuation = exp(min(0.0, (depth - pos.z)) / spot_lights.data[light_index].inv_radius * spot_lights.data[light_index].shadow_volumetric_fog_fade); +							shadow_attenuation = mix(1.0 - spot_lights.data[light_index].shadow_opacity, 1.0, exp(min(0.0, (depth - pos.z)) / spot_lights.data[light_index].inv_radius * INV_FOG_FADE));  						} -						total_light += light * attenuation * shadow_attenuation * henyey_greenstein(dot(normalize(light_rel_vec), normalize(view_pos)), params.phase_g); +						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;  					}  				}  			} diff --git a/servers/rendering/renderer_rd/shaders/light_data_inc.glsl b/servers/rendering/renderer_rd/shaders/light_data_inc.glsl index 799f7087b6..a7fca25a6b 100644 --- a/servers/rendering/renderer_rd/shaders/light_data_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/light_data_inc.glsl @@ -25,7 +25,7 @@ struct LightData { //this structure needs to be as packed as possible  	highp float soft_shadow_size; // for spot, it's the size in uv coordinates of the light, for omni it's the span angle  	highp float soft_shadow_scale; // scales the shadow kernel for blurrier shadows  	uint mask; -	mediump float shadow_volumetric_fog_fade; +	mediump float volumetric_fog_energy;  	uint bake_mode;  	highp vec4 projector_rect; //projector rect in srgb decal atlas  }; @@ -65,7 +65,7 @@ struct DirectionalLightData {  	highp float fade_to;  	uvec2 pad;  	uint bake_mode; -	mediump float shadow_volumetric_fog_fade; +	mediump float volumetric_fog_energy;  	highp vec4 shadow_bias;  	highp vec4 shadow_normal_bias;  	highp vec4 shadow_transmittance_bias;  |