mirror of
				https://github.com/godotengine/godot.git
				synced 2025-11-04 07:31:16 +00:00 
			
		
		
		
	Merge pull request #93448 from clayjohn/transmittance-fixes
Various fixes for transmittance effect
This commit is contained in:
		
						commit
						667778cf4d
					
				
					 3 changed files with 37 additions and 29 deletions
				
			
		| 
						 | 
					@ -2065,7 +2065,7 @@ void fragment_shader(in SceneData scene_data) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef LIGHT_TRANSMITTANCE_USED
 | 
					#ifdef LIGHT_TRANSMITTANCE_USED
 | 
				
			||||||
			float transmittance_z = transmittance_depth;
 | 
								float transmittance_z = transmittance_depth;
 | 
				
			||||||
 | 
					#ifndef SHADOWS_DISABLED
 | 
				
			||||||
			if (directional_lights.data[i].shadow_opacity > 0.001) {
 | 
								if (directional_lights.data[i].shadow_opacity > 0.001) {
 | 
				
			||||||
				float depth_z = -vertex.z;
 | 
									float depth_z = -vertex.z;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2112,7 +2112,8 @@ void fragment_shader(in SceneData scene_data) {
 | 
				
			||||||
					transmittance_z = z - shadow_z;
 | 
										transmittance_z = z - shadow_z;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
#endif
 | 
					#endif // !SHADOWS_DISABLED
 | 
				
			||||||
 | 
					#endif // LIGHT_TRANSMITTANCE_USED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			float shadow = 1.0;
 | 
								float shadow = 1.0;
 | 
				
			||||||
#ifndef SHADOWS_DISABLED
 | 
					#ifndef SHADOWS_DISABLED
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -582,34 +582,39 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
 | 
				
			||||||
#ifdef LIGHT_TRANSMITTANCE_USED
 | 
					#ifdef LIGHT_TRANSMITTANCE_USED
 | 
				
			||||||
	float transmittance_z = transmittance_depth; //no transmittance by default
 | 
						float transmittance_z = transmittance_depth; //no transmittance by default
 | 
				
			||||||
	transmittance_color.a *= light_attenuation;
 | 
						transmittance_color.a *= light_attenuation;
 | 
				
			||||||
	{
 | 
					#ifndef SHADOWS_DISABLED
 | 
				
			||||||
		vec4 clamp_rect = omni_lights.data[idx].atlas_rect;
 | 
						if (omni_lights.data[idx].shadow_opacity > 0.001) {
 | 
				
			||||||
 | 
							// Redo shadowmapping, but shrink the model a bit to avoid artifacts.
 | 
				
			||||||
 | 
							vec2 texel_size = scene_data_block.data.shadow_atlas_pixel_size;
 | 
				
			||||||
 | 
							vec4 uv_rect = omni_lights.data[idx].atlas_rect;
 | 
				
			||||||
 | 
							uv_rect.xy += texel_size;
 | 
				
			||||||
 | 
							uv_rect.zw -= texel_size * 2.0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		//redo shadowmapping, but shrink the model a bit to avoid artifacts
 | 
							// Omni lights use direction.xy to store to store the offset between the two paraboloid regions
 | 
				
			||||||
		vec4 splane = (omni_lights.data[idx].shadow_matrix * vec4(vertex - normalize(normal_interp) * omni_lights.data[idx].transmittance_bias, 1.0));
 | 
							vec2 flip_offset = omni_lights.data[idx].direction.xy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		float shadow_len = length(splane.xyz);
 | 
							vec3 local_vert = (omni_lights.data[idx].shadow_matrix * vec4(vertex - normalize(normal) * omni_lights.data[idx].transmittance_bias, 1.0)).xyz;
 | 
				
			||||||
		splane.xyz = normalize(splane.xyz);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (splane.z >= 0.0) {
 | 
							float shadow_len = length(local_vert); //need to remember shadow len from here
 | 
				
			||||||
			splane.z += 1.0;
 | 
							vec3 shadow_sample = normalize(local_vert);
 | 
				
			||||||
			clamp_rect.y += clamp_rect.w;
 | 
					
 | 
				
			||||||
		} else {
 | 
							if (shadow_sample.z >= 0.0) {
 | 
				
			||||||
			splane.z = 1.0 - splane.z;
 | 
								uv_rect.xy += flip_offset;
 | 
				
			||||||
 | 
								flip_offset *= -1.0;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		splane.xy /= splane.z;
 | 
							shadow_sample.z = 1.0 + abs(shadow_sample.z);
 | 
				
			||||||
 | 
							vec2 pos = shadow_sample.xy / shadow_sample.z;
 | 
				
			||||||
 | 
							float depth = shadow_len * omni_lights.data[idx].inv_radius;
 | 
				
			||||||
 | 
							depth = 1.0 - depth;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		splane.xy = splane.xy * 0.5 + 0.5;
 | 
							pos = pos * 0.5 + 0.5;
 | 
				
			||||||
		splane.z = shadow_len * omni_lights.data[idx].inv_radius;
 | 
							pos = uv_rect.xy + pos * uv_rect.zw;
 | 
				
			||||||
		splane.xy = clamp_rect.xy + splane.xy * clamp_rect.zw;
 | 
							float shadow_z = textureLod(sampler2D(shadow_atlas, SAMPLER_LINEAR_CLAMP), pos, 0.0).r;
 | 
				
			||||||
		//		splane.xy = clamp(splane.xy,clamp_rect.xy + scene_data_block.data.shadow_atlas_pixel_size,clamp_rect.xy + clamp_rect.zw - scene_data_block.data.shadow_atlas_pixel_size );
 | 
							transmittance_z = (depth - shadow_z) / omni_lights.data[idx].inv_radius;
 | 
				
			||||||
		splane.w = 1.0; //needed? i think it should be 1 already
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		float shadow_z = textureLod(sampler2D(shadow_atlas, SAMPLER_LINEAR_CLAMP), splane.xy, 0.0).r;
 | 
					 | 
				
			||||||
		transmittance_z = (splane.z - shadow_z) / omni_lights.data[idx].inv_radius;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
#endif
 | 
					#endif // !SHADOWS_DISABLED
 | 
				
			||||||
 | 
					#endif // LIGHT_TRANSMITTANCE_USED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (sc_use_light_projector && omni_lights.data[idx].projector_rect != vec4(0.0)) {
 | 
						if (sc_use_light_projector && omni_lights.data[idx].projector_rect != vec4(0.0)) {
 | 
				
			||||||
		vec3 local_v = (omni_lights.data[idx].shadow_matrix * vec4(vertex, 1.0)).xyz;
 | 
							vec3 local_v = (omni_lights.data[idx].shadow_matrix * vec4(vertex, 1.0)).xyz;
 | 
				
			||||||
| 
						 | 
					@ -834,12 +839,13 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
 | 
				
			||||||
#ifdef LIGHT_TRANSMITTANCE_USED
 | 
					#ifdef LIGHT_TRANSMITTANCE_USED
 | 
				
			||||||
	float transmittance_z = transmittance_depth;
 | 
						float transmittance_z = transmittance_depth;
 | 
				
			||||||
	transmittance_color.a *= light_attenuation;
 | 
						transmittance_color.a *= light_attenuation;
 | 
				
			||||||
	{
 | 
					#ifndef SHADOWS_DISABLED
 | 
				
			||||||
		vec4 splane = (spot_lights.data[idx].shadow_matrix * vec4(vertex - normalize(normal_interp) * spot_lights.data[idx].transmittance_bias, 1.0));
 | 
						if (spot_lights.data[idx].shadow_opacity > 0.001) {
 | 
				
			||||||
 | 
							vec4 splane = (spot_lights.data[idx].shadow_matrix * vec4(vertex - normalize(normal) * spot_lights.data[idx].transmittance_bias, 1.0));
 | 
				
			||||||
		splane /= splane.w;
 | 
							splane /= splane.w;
 | 
				
			||||||
		splane.xy = splane.xy * spot_lights.data[idx].atlas_rect.zw + spot_lights.data[idx].atlas_rect.xy;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		float shadow_z = textureLod(sampler2D(shadow_atlas, SAMPLER_LINEAR_CLAMP), splane.xy, 0.0).r;
 | 
							vec3 shadow_uv = vec3(splane.xy * spot_lights.data[idx].atlas_rect.zw + spot_lights.data[idx].atlas_rect.xy, splane.z);
 | 
				
			||||||
 | 
							float shadow_z = textureLod(sampler2D(shadow_atlas, SAMPLER_LINEAR_CLAMP), shadow_uv.xy, 0.0).r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		shadow_z = shadow_z * 2.0 - 1.0;
 | 
							shadow_z = shadow_z * 2.0 - 1.0;
 | 
				
			||||||
		float z_far = 1.0 / spot_lights.data[idx].inv_radius;
 | 
							float z_far = 1.0 / spot_lights.data[idx].inv_radius;
 | 
				
			||||||
| 
						 | 
					@ -850,6 +856,7 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
 | 
				
			||||||
		float z = dot(spot_dir, -light_rel_vec);
 | 
							float z = dot(spot_dir, -light_rel_vec);
 | 
				
			||||||
		transmittance_z = z - shadow_z;
 | 
							transmittance_z = z - shadow_z;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					#endif // !SHADOWS_DISABLED
 | 
				
			||||||
#endif // LIGHT_TRANSMITTANCE_USED
 | 
					#endif // LIGHT_TRANSMITTANCE_USED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (sc_use_light_projector && spot_lights.data[idx].projector_rect != vec4(0.0)) {
 | 
						if (sc_use_light_projector && spot_lights.data[idx].projector_rect != vec4(0.0)) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -685,7 +685,7 @@ void LightStorage::update_light_buffers(RenderDataRD *p_render_data, const Paged
 | 
				
			||||||
						float bias_scale = light_instance->shadow_transform[j].bias_scale * light_data.soft_shadow_scale;
 | 
											float bias_scale = light_instance->shadow_transform[j].bias_scale * light_data.soft_shadow_scale;
 | 
				
			||||||
						light_data.shadow_bias[j] = light->param[RS::LIGHT_PARAM_SHADOW_BIAS] / 100.0 * bias_scale;
 | 
											light_data.shadow_bias[j] = light->param[RS::LIGHT_PARAM_SHADOW_BIAS] / 100.0 * bias_scale;
 | 
				
			||||||
						light_data.shadow_normal_bias[j] = light->param[RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS] * light_instance->shadow_transform[j].shadow_texel_size;
 | 
											light_data.shadow_normal_bias[j] = light->param[RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS] * light_instance->shadow_transform[j].shadow_texel_size;
 | 
				
			||||||
						light_data.shadow_transmittance_bias[j] = light->param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS] * bias_scale;
 | 
											light_data.shadow_transmittance_bias[j] = light->param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS] / 100.0 * bias_scale;
 | 
				
			||||||
						light_data.shadow_z_range[j] = light_instance->shadow_transform[j].farplane;
 | 
											light_data.shadow_z_range[j] = light_instance->shadow_transform[j].farplane;
 | 
				
			||||||
						light_data.shadow_range_begin[j] = light_instance->shadow_transform[j].range_begin;
 | 
											light_data.shadow_range_begin[j] = light_instance->shadow_transform[j].range_begin;
 | 
				
			||||||
						RendererRD::MaterialStorage::store_camera(shadow_mtx, light_data.shadow_matrices[j]);
 | 
											RendererRD::MaterialStorage::store_camera(shadow_mtx, light_data.shadow_matrices[j]);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue