mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	lighting: compute highlight clamp after one-/two-sided diffuse pass
This commit is contained in:
		
							parent
							
								
									33a0e87ac2
								
							
						
					
					
						commit
						0d6db4a0b3
					
				
					 2 changed files with 21 additions and 24 deletions
				
			
		|  | @ -562,6 +562,8 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) { | ||||||
|            "vec3 refl_value = vec3(0.0);\n" |            "vec3 refl_value = vec3(0.0);\n" | ||||||
|            "vec3 spot_dir = vec3(0.0);\n" |            "vec3 spot_dir = vec3(0.0);\n" | ||||||
|            "vec3 half_vector = vec3(0.0);\n" |            "vec3 half_vector = vec3(0.0);\n" | ||||||
|  |            "float dot_product = 0.0;\n" | ||||||
|  |            "float clamp_highlights = 1.0;\n" | ||||||
|            "float geo_factor = 1.0;\n"; |            "float geo_factor = 1.0;\n"; | ||||||
| 
 | 
 | ||||||
|     // Compute fragment normals and tangents
 |     // Compute fragment normals and tangents
 | ||||||
|  | @ -680,9 +682,14 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) { | ||||||
| 
 | 
 | ||||||
|         // Compute dot product of light_vector and normal, adjust if lighting is one-sided or
 |         // Compute dot product of light_vector and normal, adjust if lighting is one-sided or
 | ||||||
|         // two-sided
 |         // two-sided
 | ||||||
|         std::string dot_product = light_config.two_sided_diffuse |         out += std::string("dot_product = ") + (light_config.two_sided_diffuse | ||||||
|                                       ? "abs(dot(light_vector, normal))" |                                                     ? "abs(dot(light_vector, normal));\n" | ||||||
|                                       : "max(dot(light_vector, normal), 0.0)"; |                                                     : "max(dot(light_vector, normal), 0.0);\n"); | ||||||
|  | 
 | ||||||
|  |         // If enabled, clamp specular component if lighting result is zero
 | ||||||
|  |         if (lighting.clamp_highlights) { | ||||||
|  |             out += "clamp_highlights = dot_product == 0.0 ? 0.0 : 1.0;\n"; | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         // If enabled, compute spot light attenuation value
 |         // If enabled, compute spot light attenuation value
 | ||||||
|         std::string spot_atten = "1.0"; |         std::string spot_atten = "1.0"; | ||||||
|  | @ -706,14 +713,10 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) { | ||||||
|                          std::to_string(static_cast<unsigned>(sampler)) + "," + index + ")"; |                          std::to_string(static_cast<unsigned>(sampler)) + "," + index + ")"; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // If enabled, clamp specular component if lighting result is negative
 |  | ||||||
|         std::string clamp_highlights = |  | ||||||
|             lighting.clamp_highlights ? "(dot(light_vector, normal) <= 0.0 ? 0.0 : 1.0)" : "1.0"; |  | ||||||
| 
 |  | ||||||
|         if (light_config.geometric_factor_0 || light_config.geometric_factor_1) { |         if (light_config.geometric_factor_0 || light_config.geometric_factor_1) { | ||||||
|             out += "geo_factor = dot(half_vector, half_vector);\n" |             out += "geo_factor = dot(half_vector, half_vector);\n" | ||||||
|                    "geo_factor = geo_factor == 0.0 ? 0.0 : min(" + |                    "geo_factor = geo_factor == 0.0 ? 0.0 : min(" | ||||||
|                    dot_product + " / geo_factor, 1.0);\n"; |                    "dot_product / geo_factor, 1.0);\n"; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // Specular 0 component
 |         // Specular 0 component
 | ||||||
|  | @ -814,12 +817,12 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) { | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // Compute primary fragment color (diffuse lighting) function
 |         // Compute primary fragment color (diffuse lighting) function
 | ||||||
|         out += "diffuse_sum.rgb += ((" + light_src + ".diffuse * " + dot_product + ") + " + |         out += "diffuse_sum.rgb += ((" + light_src + ".diffuse * dot_product) + " + light_src + | ||||||
|                light_src + ".ambient) * " + dist_atten + " * " + spot_atten + ";\n"; |                ".ambient) * " + dist_atten + " * " + spot_atten + ";\n"; | ||||||
| 
 | 
 | ||||||
|         // Compute secondary fragment color (specular lighting) function
 |         // Compute secondary fragment color (specular lighting) function
 | ||||||
|         out += "specular_sum.rgb += (" + specular_0 + " + " + specular_1 + ") * " + |         out += "specular_sum.rgb += (" + specular_0 + " + " + specular_1 + | ||||||
|                clamp_highlights + " * " + dist_atten + " * " + spot_atten + ";\n"; |                ") * clamp_highlights * " + dist_atten + " * " + spot_atten + ";\n"; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Sum final lighting result
 |     // Sum final lighting result
 | ||||||
|  |  | ||||||
|  | @ -256,22 +256,16 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors( | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         auto dot_product = Math::Dot(light_vector, normal); |         auto dot_product = Math::Dot(light_vector, normal); | ||||||
| 
 |  | ||||||
|         // Calculate clamp highlights before applying the two-sided diffuse configuration to the dot
 |  | ||||||
|         // product.
 |  | ||||||
|         float clamp_highlights = 1.0f; |  | ||||||
|         if (lighting.config0.clamp_highlights) { |  | ||||||
|             if (dot_product <= 0.0f) |  | ||||||
|                 clamp_highlights = 0.0f; |  | ||||||
|             else |  | ||||||
|                 clamp_highlights = 1.0f; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (light_config.config.two_sided_diffuse) |         if (light_config.config.two_sided_diffuse) | ||||||
|             dot_product = std::abs(dot_product); |             dot_product = std::abs(dot_product); | ||||||
|         else |         else | ||||||
|             dot_product = std::max(dot_product, 0.0f); |             dot_product = std::max(dot_product, 0.0f); | ||||||
| 
 | 
 | ||||||
|  |         float clamp_highlights = 1.0f; | ||||||
|  |         if (lighting.config0.clamp_highlights) { | ||||||
|  |             clamp_highlights = dot_product == 0.0f ? 0.0f : 1.0f; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         if (light_config.config.geometric_factor_0 || light_config.config.geometric_factor_1) { |         if (light_config.config.geometric_factor_0 || light_config.config.geometric_factor_1) { | ||||||
|             float geo_factor = half_vector.Length2(); |             float geo_factor = half_vector.Length2(); | ||||||
|             geo_factor = geo_factor == 0.0f ? 0.0f : std::min(dot_product / geo_factor, 1.0f); |             geo_factor = geo_factor == 0.0f ? 0.0f : std::min(dot_product / geo_factor, 1.0f); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue