mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	swrasterizer/lighting: implement shadow attenuation
This commit is contained in:
		
							parent
							
								
									6c63bb11d9
								
							
						
					
					
						commit
						ce2ad7436e
					
				
					 2 changed files with 54 additions and 4 deletions
				
			
		|  | @ -187,9 +187,15 @@ struct LightingRegs { | ||||||
|     BitField<0, 3, u32> max_light_index; // Number of enabled lights - 1
 |     BitField<0, 3, u32> max_light_index; // Number of enabled lights - 1
 | ||||||
| 
 | 
 | ||||||
|     union { |     union { | ||||||
|  |         BitField<0, 1, u32> enable_shadow; | ||||||
|         BitField<2, 2, LightingFresnelSelector> fresnel_selector; |         BitField<2, 2, LightingFresnelSelector> fresnel_selector; | ||||||
|         BitField<4, 4, LightingConfig> config; |         BitField<4, 4, LightingConfig> config; | ||||||
|  |         BitField<16, 1, u32> shadow_primary; | ||||||
|  |         BitField<17, 1, u32> shadow_secondary; | ||||||
|  |         BitField<18, 1, u32> shadow_invert; | ||||||
|  |         BitField<19, 1, u32> shadow_alpha; | ||||||
|         BitField<22, 2, u32> bump_selector; // 0: Texture 0, 1: Texture 1, 2: Texture 2
 |         BitField<22, 2, u32> bump_selector; // 0: Texture 0, 1: Texture 1, 2: Texture 2
 | ||||||
|  |         BitField<24, 2, u32> shadow_selector; | ||||||
|         BitField<27, 1, u32> clamp_highlights; |         BitField<27, 1, u32> clamp_highlights; | ||||||
|         BitField<28, 2, LightingBumpMode> bump_mode; |         BitField<28, 2, LightingBumpMode> bump_mode; | ||||||
|         BitField<30, 1, u32> disable_bump_renorm; |         BitField<30, 1, u32> disable_bump_renorm; | ||||||
|  | @ -198,6 +204,9 @@ struct LightingRegs { | ||||||
|     union { |     union { | ||||||
|         u32 raw; |         u32 raw; | ||||||
| 
 | 
 | ||||||
|  |         // Each bit specifies whether shadow should be applied for the corresponding light.
 | ||||||
|  |         BitField<0, 8, u32> disable_shadow; | ||||||
|  | 
 | ||||||
|         // Each bit specifies whether spot light attenuation should be applied for the corresponding
 |         // Each bit specifies whether spot light attenuation should be applied for the corresponding
 | ||||||
|         // light.
 |         // light.
 | ||||||
|         BitField<8, 8, u32> disable_spot_atten; |         BitField<8, 8, u32> disable_spot_atten; | ||||||
|  | @ -224,6 +233,10 @@ struct LightingRegs { | ||||||
|         return (config1.disable_spot_atten & (1 << index)) != 0; |         return (config1.disable_spot_atten & (1 << index)) != 0; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     bool IsShadowDisabled(unsigned index) const { | ||||||
|  |         return (config1.disable_shadow & (1 << index)) != 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     union { |     union { | ||||||
|         BitField<0, 8, u32> index; ///< Index at which to set data in the LUT
 |         BitField<0, 8, u32> index; ///< Index at which to set data in the LUT
 | ||||||
|         BitField<8, 5, u32> type;  ///< Type of LUT for which to set data
 |         BitField<8, 5, u32> type;  ///< Type of LUT for which to set data
 | ||||||
|  |  | ||||||
|  | @ -25,6 +25,16 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors( | ||||||
|     const Math::Quaternion<float>& normquat, const Math::Vec3<float>& view, |     const Math::Quaternion<float>& normquat, const Math::Vec3<float>& view, | ||||||
|     const Math::Vec4<u8> (&texture_color)[4]) { |     const Math::Vec4<u8> (&texture_color)[4]) { | ||||||
| 
 | 
 | ||||||
|  |     Math::Vec4<float> shadow; | ||||||
|  |     if (lighting.config0.enable_shadow) { | ||||||
|  |         shadow = texture_color[lighting.config0.shadow_selector].Cast<float>() / 255.0f; | ||||||
|  |         if (lighting.config0.shadow_invert) { | ||||||
|  |             shadow = Math::MakeVec(1.0f, 1.0f, 1.0f, 1.0f) - shadow; | ||||||
|  |         } | ||||||
|  |     } else { | ||||||
|  |         shadow = Math::MakeVec(1.0f, 1.0f, 1.0f, 1.0f); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     Math::Vec3<float> surface_normal; |     Math::Vec3<float> surface_normal; | ||||||
|     Math::Vec3<float> surface_tangent; |     Math::Vec3<float> surface_tangent; | ||||||
| 
 | 
 | ||||||
|  | @ -284,11 +294,38 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors( | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         auto diffuse = |         auto diffuse = | ||||||
|             light_config.diffuse.ToVec3f() * dot_product + light_config.ambient.ToVec3f(); |             (light_config.diffuse.ToVec3f() * dot_product + light_config.ambient.ToVec3f()) * | ||||||
|         diffuse_sum += Math::MakeVec(diffuse * dist_atten * spot_atten, 0.0f); |             dist_atten * spot_atten; | ||||||
|  |         auto specular = (specular_0 + specular_1) * clamp_highlights * dist_atten * spot_atten; | ||||||
| 
 | 
 | ||||||
|         specular_sum += Math::MakeVec( |         if (!lighting.IsShadowDisabled(num)) { | ||||||
|             (specular_0 + specular_1) * clamp_highlights * dist_atten * spot_atten, 0.0f); |             if (lighting.config0.shadow_primary) { | ||||||
|  |                 diffuse = diffuse * shadow.xyz(); | ||||||
|  |             } | ||||||
|  |             if (lighting.config0.shadow_secondary) { | ||||||
|  |                 specular = specular * shadow.xyz(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         diffuse_sum += Math::MakeVec(diffuse, 0.0f); | ||||||
|  |         specular_sum += Math::MakeVec(specular, 0.0f); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (lighting.config0.shadow_alpha) { | ||||||
|  |         // Alpha shadow also uses the Fresnel selecotr to determine which alpha to apply
 | ||||||
|  |         // Enabled for diffuse lighting alpha component
 | ||||||
|  |         if (lighting.config0.fresnel_selector == | ||||||
|  |                 LightingRegs::LightingFresnelSelector::PrimaryAlpha || | ||||||
|  |             lighting.config0.fresnel_selector == LightingRegs::LightingFresnelSelector::Both) { | ||||||
|  |             diffuse_sum.a() *= shadow.w; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // Enabled for the specular lighting alpha component
 | ||||||
|  |         if (lighting.config0.fresnel_selector == | ||||||
|  |                 LightingRegs::LightingFresnelSelector::SecondaryAlpha || | ||||||
|  |             lighting.config0.fresnel_selector == LightingRegs::LightingFresnelSelector::Both) { | ||||||
|  |             specular_sum.a() *= shadow.w; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     diffuse_sum += Math::MakeVec(lighting.global_ambient.ToVec3f(), 0.0f); |     diffuse_sum += Math::MakeVec(lighting.global_ambient.ToVec3f(), 0.0f); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue