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
 | ||||
| 
 | ||||
|     union { | ||||
|         BitField<0, 1, u32> enable_shadow; | ||||
|         BitField<2, 2, LightingFresnelSelector> fresnel_selector; | ||||
|         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<24, 2, u32> shadow_selector; | ||||
|         BitField<27, 1, u32> clamp_highlights; | ||||
|         BitField<28, 2, LightingBumpMode> bump_mode; | ||||
|         BitField<30, 1, u32> disable_bump_renorm; | ||||
|  | @ -198,6 +204,9 @@ struct LightingRegs { | |||
|     union { | ||||
|         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
 | ||||
|         // light.
 | ||||
|         BitField<8, 8, u32> disable_spot_atten; | ||||
|  | @ -224,6 +233,10 @@ struct LightingRegs { | |||
|         return (config1.disable_spot_atten & (1 << index)) != 0; | ||||
|     } | ||||
| 
 | ||||
|     bool IsShadowDisabled(unsigned index) const { | ||||
|         return (config1.disable_shadow & (1 << index)) != 0; | ||||
|     } | ||||
| 
 | ||||
|     union { | ||||
|         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
 | ||||
|  |  | |||
|  | @ -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::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_tangent; | ||||
| 
 | ||||
|  | @ -284,11 +294,38 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors( | |||
|         } | ||||
| 
 | ||||
|         auto diffuse = | ||||
|             light_config.diffuse.ToVec3f() * dot_product + light_config.ambient.ToVec3f(); | ||||
|         diffuse_sum += Math::MakeVec(diffuse * dist_atten * spot_atten, 0.0f); | ||||
|             (light_config.diffuse.ToVec3f() * dot_product + light_config.ambient.ToVec3f()) * | ||||
|             dist_atten * spot_atten; | ||||
|         auto specular = (specular_0 + specular_1) * clamp_highlights * dist_atten * spot_atten; | ||||
| 
 | ||||
|         specular_sum += Math::MakeVec( | ||||
|             (specular_0 + specular_1) * clamp_highlights * dist_atten * spot_atten, 0.0f); | ||||
|         if (!lighting.IsShadowDisabled(num)) { | ||||
|             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); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue