mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	renderer_opengl: Implement HW fragment lighting distance attenuation.
This commit is contained in:
		
							parent
							
								
									e9af70eaf3
								
							
						
					
					
						commit
						e34fa6365f
					
				
					 2 changed files with 37 additions and 16 deletions
				
			
		|  | @ -78,9 +78,13 @@ struct PicaShaderConfig { | |||
| 
 | ||||
|         for (unsigned light_index = 0; light_index < res.num_lights; ++light_index) { | ||||
|             unsigned num = regs.lighting.light_enable.GetNum(light_index); | ||||
|             const auto& light = regs.lighting.light[num]; | ||||
|             res.light_src[light_index].num = num; | ||||
|             res.light_src[light_index].directional = regs.lighting.light[num].w; | ||||
|             res.light_src[light_index].two_sided_diffuse = regs.lighting.light[num].two_sided_diffuse; | ||||
|             res.light_src[light_index].directional = light.w; | ||||
|             res.light_src[light_index].two_sided_diffuse = light.two_sided_diffuse; | ||||
|             res.light_src[light_index].dist_atten_enabled = regs.lighting.dist_atten_enable.IsEnabled(num); | ||||
|             res.light_src[light_index].dist_atten_bias = Pica::float20::FromRawFloat20(light.dist_atten_bias).ToFloat32(); | ||||
|             res.light_src[light_index].dist_atten_scale = Pica::float20::FromRawFloat20(light.dist_atten_scale).ToFloat32(); | ||||
|         } | ||||
| 
 | ||||
|         return res; | ||||
|  | @ -98,19 +102,23 @@ struct PicaShaderConfig { | |||
|         return std::memcmp(this, &o, sizeof(PicaShaderConfig)) == 0; | ||||
|     }; | ||||
| 
 | ||||
|     Pica::Regs::CompareFunc alpha_test_func; | ||||
|     std::array<Pica::Regs::TevStageConfig, 6> tev_stages = {}; | ||||
|     u8 combiner_buffer_input; | ||||
| 
 | ||||
|     struct { | ||||
|         unsigned num; | ||||
|         bool directional; | ||||
|         bool two_sided_diffuse; | ||||
|         bool dist_atten_enabled; | ||||
|     } light_src[8]; | ||||
|         Pica::Regs::CompareFunc alpha_test_func = Pica::Regs::CompareFunc::Never; | ||||
|         std::array<Pica::Regs::TevStageConfig, 6> tev_stages = {}; | ||||
|         u8 combiner_buffer_input = 0; | ||||
| 
 | ||||
|     bool lighting_enabled; | ||||
|     unsigned num_lights; | ||||
|         struct { | ||||
|             unsigned num = 0; | ||||
|             bool directional = false; | ||||
|             bool two_sided_diffuse = false; | ||||
|             bool dist_atten_enabled = false; | ||||
|             GLfloat dist_atten_scale = 0.0f; | ||||
|             GLfloat dist_atten_bias = 0.0f; | ||||
|         } light_src[8]; | ||||
| 
 | ||||
|         bool lighting_enabled = false; | ||||
|         unsigned num_lights = 0; | ||||
|     }; | ||||
| }; | ||||
| 
 | ||||
| namespace std { | ||||
|  |  | |||
|  | @ -371,12 +371,13 @@ vec4 primary_fragment_color = vec4(0.0); | |||
| 
 | ||||
|         for (unsigned light_index = 0; light_index < config.num_lights; ++light_index) { | ||||
|             unsigned num = config.light_src[light_index].num; | ||||
|             std::string light_src = "light_src[" + std::to_string(num) + "]"; | ||||
| 
 | ||||
|             std::string light_vector; | ||||
|             if (config.light_src[light_index].directional) | ||||
|                 light_vector = "normalize(-light_src[" + std::to_string(num) + "].position)"; | ||||
|                 light_vector = "normalize(-" + light_src + ".position)"; | ||||
|             else | ||||
|                 light_vector = "normalize(light_src[" + std::to_string(num) + "].position - fragment_position)"; | ||||
|                 light_vector = "normalize(" + light_src + ".position - fragment_position)"; | ||||
| 
 | ||||
|             std::string dot_product; | ||||
|             if (config.light_src[light_index].two_sided_diffuse) | ||||
|  | @ -384,7 +385,19 @@ vec4 primary_fragment_color = vec4(0.0); | |||
|             else | ||||
|                 dot_product = "max(dot(" + light_vector + ", normal), 0.0)"; | ||||
| 
 | ||||
|             out += "diffuse_sum += ((light_src[" + std::to_string(num) + "].diffuse * " + dot_product + ") + light_src[" + std::to_string(num) + "].ambient) * 1.0;\n"; | ||||
|             std::string dist_atten = "1.0"; | ||||
|             if (config.light_src[light_index].dist_atten_enabled) { | ||||
|                 std::string scale = std::to_string(config.light_src[light_index].dist_atten_scale); | ||||
|                 std::string bias = std::to_string(config.light_src[light_index].dist_atten_bias); | ||||
|                 std::string lut_index = "(" + scale + " * length(fragment_position - " + light_src + ".position) + " + bias + ")"; | ||||
|                 std::string clamped_lut_index = "((clamp(int(" + lut_index + " * 256.0), 0, 255)))"; | ||||
| 
 | ||||
|                 unsigned lut_num = ((unsigned)Regs::LightingSampler::DistanceAttenuation + num); | ||||
| 
 | ||||
|                 dist_atten = "lighting_lut_" + std::to_string(lut_num /4) + "[" + clamped_lut_index + "][" + std::to_string(lut_num & 3) + "]"; | ||||
|             } | ||||
| 
 | ||||
|             out += "diffuse_sum += ((light_src[" + std::to_string(num) + "].diffuse * " + dot_product + ") + light_src[" + std::to_string(num) + "].ambient) * " + dist_atten + ";\n"; | ||||
|         } | ||||
| 
 | ||||
|         out += "diffuse_sum += lighting_global_ambient;\n"; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue