forked from eden-emu/eden
		
	gl_shader_gen: Implement lighting red, green, and blue reflection.
This commit is contained in:
		
							parent
							
								
									01b407638c
								
							
						
					
					
						commit
						348c9c9ff3
					
				
					 3 changed files with 77 additions and 21 deletions
				
			
		|  | @ -650,9 +650,9 @@ struct Regs { | |||
|         Distribution0 = 0, | ||||
|         Distribution1 = 1, | ||||
|         Fresnel = 3, | ||||
|         Blue = 4, | ||||
|         Green = 5, | ||||
|         Red = 6, | ||||
|         ReflectBlue = 4, | ||||
|         ReflectGreen = 5, | ||||
|         ReflectRed = 6, | ||||
|         SpotlightAttenuation = 8, | ||||
|         DistanceAttenuation = 16, | ||||
|     }; | ||||
|  | @ -718,10 +718,19 @@ struct Regs { | |||
|         switch (sampler) { | ||||
|         case LightingSampler::Distribution0: | ||||
|             return (config != LightingConfig::Config1); | ||||
| 
 | ||||
|         case LightingSampler::Distribution1: | ||||
|             return (config != LightingConfig::Config0) && (config != LightingConfig::Config1) && (config != LightingConfig::Config5); | ||||
| 
 | ||||
|         case LightingSampler::Fresnel: | ||||
|             return (config != LightingConfig::Config0) && (config != LightingConfig::Config2) && (config != LightingConfig::Config4); | ||||
| 
 | ||||
|         case LightingSampler::ReflectRed: | ||||
|             return (config != LightingConfig::Config3); | ||||
| 
 | ||||
|         case LightingSampler::ReflectGreen: | ||||
|         case LightingSampler::ReflectBlue: | ||||
|             return (config == LightingConfig::Config4) || (config == LightingConfig::Config5) || (config == LightingConfig::Config7); | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | @ -773,6 +782,9 @@ struct Regs { | |||
|             BitField<16, 1, u32> lut_enable_d0; // 0: GL_TRUE, 1: GL_FALSE
 | ||||
|             BitField<17, 1, u32> lut_enable_d1; // 0: GL_TRUE, 1: GL_FALSE
 | ||||
|             BitField<19, 1, u32> lut_enable_fr; // 0: GL_TRUE, 1: GL_FALSE
 | ||||
|             BitField<20, 1, u32> lut_enable_rr; // 0: GL_TRUE, 1: GL_FALSE
 | ||||
|             BitField<21, 1, u32> lut_enable_rg; // 0: GL_TRUE, 1: GL_FALSE
 | ||||
|             BitField<22, 1, u32> lut_enable_rb; // 0: GL_TRUE, 1: GL_FALSE
 | ||||
| 
 | ||||
|             // Each bit specifies whether distance attenuation should be applied for the
 | ||||
|             // corresponding light
 | ||||
|  |  | |||
|  | @ -102,6 +102,21 @@ struct PicaShaderConfig { | |||
|         res.lighting.lut_fr.type = (Pica::Regs::LightingLutInput)regs.lighting.lut_input.fr.Value(); | ||||
|         res.lighting.lut_fr.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.fr); | ||||
| 
 | ||||
|         res.lighting.lut_rr.enable = regs.lighting.lut_enable_rr == 0; | ||||
|         res.lighting.lut_rr.abs_input = regs.lighting.abs_lut_input.rr == 0; | ||||
|         res.lighting.lut_rr.type = (Pica::Regs::LightingLutInput)regs.lighting.lut_input.rr.Value(); | ||||
|         res.lighting.lut_rr.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.rr); | ||||
| 
 | ||||
|         res.lighting.lut_rg.enable = regs.lighting.lut_enable_rg == 0; | ||||
|         res.lighting.lut_rg.abs_input = regs.lighting.abs_lut_input.rg == 0; | ||||
|         res.lighting.lut_rg.type = (Pica::Regs::LightingLutInput)regs.lighting.lut_input.rg.Value(); | ||||
|         res.lighting.lut_rg.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.rg); | ||||
| 
 | ||||
|         res.lighting.lut_rb.enable = regs.lighting.lut_enable_rb == 0; | ||||
|         res.lighting.lut_rb.abs_input = regs.lighting.abs_lut_input.rb == 0; | ||||
|         res.lighting.lut_rb.type = (Pica::Regs::LightingLutInput)regs.lighting.lut_input.rb.Value(); | ||||
|         res.lighting.lut_rb.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.rb); | ||||
| 
 | ||||
|         res.lighting.config = regs.lighting.config; | ||||
|         res.lighting.fresnel_selector = regs.lighting.fresnel_selector; | ||||
|         res.lighting.clamp_highlights = regs.lighting.clamp_highlights != 0; | ||||
|  | @ -139,6 +154,7 @@ struct PicaShaderConfig { | |||
|             bool enable = false; | ||||
|             unsigned src_num = 0; | ||||
|             bool clamp_highlights = false; | ||||
| 
 | ||||
|             Pica::Regs::LightingConfig config = Pica::Regs::LightingConfig::Config0; | ||||
|             Pica::Regs::LightingFresnelSelector fresnel_selector = Pica::Regs::LightingFresnelSelector::None; | ||||
| 
 | ||||
|  | @ -147,7 +163,7 @@ struct PicaShaderConfig { | |||
|                 bool abs_input = false; | ||||
|                 Pica::Regs::LightingLutInput type = Pica::Regs::LightingLutInput::NH; | ||||
|                 float scale = 1.0f; | ||||
|             } lut_d0, lut_d1, lut_fr; | ||||
|             } lut_d0, lut_d1, lut_fr, lut_rr, lut_rg, lut_rb; | ||||
|         } lighting; | ||||
|     }; | ||||
| }; | ||||
|  |  | |||
|  | @ -321,9 +321,10 @@ static void WriteTevStage(std::string& out, const PicaShaderConfig& config, unsi | |||
| /// Writes the code to emulate fragment lighting
 | ||||
| static void WriteLighting(std::string& out, const PicaShaderConfig& config) { | ||||
|     // Define lighting globals
 | ||||
|     out += "vec4 diffuse_sum = vec4(0.0, 0.0, 0.0, 1.0);\n"; | ||||
|     out += "vec4 specular_sum = vec4(0.0, 0.0, 0.0, 1.0);\n"; | ||||
|     out += "vec3 light_vector = vec3(0.0);\n"; | ||||
|     out += "vec4 diffuse_sum = vec4(0.0, 0.0, 0.0, 1.0);\n" | ||||
|            "vec4 specular_sum = vec4(0.0, 0.0, 0.0, 1.0);\n" | ||||
|            "vec3 light_vector = vec3(0.0);\n" | ||||
|            "vec3 refl_value = vec3(0.0);\n"; | ||||
| 
 | ||||
|     // Convert interpolated quaternion to a GL fragment normal
 | ||||
|     out += "vec3 normal = normalize(vec3(\n"; | ||||
|  | @ -396,10 +397,10 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) { | |||
|         if (light_config.dist_atten_enable) { | ||||
|             std::string scale = std::to_string(light_config.dist_atten_scale); | ||||
|             std::string bias = std::to_string(light_config.dist_atten_bias); | ||||
|             std::string lut_index = "(" + scale + " * length(-view - " + light_src + ".position) + " + bias + ")"; | ||||
|             lut_index = "((clamp(" + lut_index + ", 0.0, FLOAT_255)))"; | ||||
|             std::string index = "(" + scale + " * length(-view - " + light_src + ".position) + " + bias + ")"; | ||||
|             index = "((clamp(" + index + ", 0.0, FLOAT_255)))"; | ||||
|             const unsigned lut_num = ((unsigned)Regs::LightingSampler::DistanceAttenuation + light_config.num); | ||||
|             dist_atten = GetLutValue((Regs::LightingSampler)lut_num, lut_index); | ||||
|             dist_atten = GetLutValue((Regs::LightingSampler)lut_num, index); | ||||
|         } | ||||
| 
 | ||||
|         // If enabled, clamp specular component if lighting result is negative
 | ||||
|  | @ -409,35 +410,62 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) { | |||
|         std::string d0_lut_value = "1.0"; | ||||
|         if (config.lighting.lut_d0.enable && Pica::Regs::IsLightingSamplerSupported(config.lighting.config, Pica::Regs::LightingSampler::Distribution0)) { | ||||
|             // Lookup specular "distribution 0" LUT value
 | ||||
|             std::string d0_lut_index = GetLutIndex(light_config.num, config.lighting.lut_d0.type, config.lighting.lut_d0.abs_input); | ||||
|             d0_lut_value = "(" + std::to_string(config.lighting.lut_d0.scale) + " * " + GetLutValue(Regs::LightingSampler::Distribution0, d0_lut_index) + ")"; | ||||
|             std::string index = GetLutIndex(light_config.num, config.lighting.lut_d0.type, config.lighting.lut_d0.abs_input); | ||||
|             d0_lut_value = "(" + std::to_string(config.lighting.lut_d0.scale) + " * " + GetLutValue(Regs::LightingSampler::Distribution0, index) + ")"; | ||||
|         } | ||||
|         std::string specular_0 = "(" + d0_lut_value + " * " + light_src + ".specular_0)"; | ||||
| 
 | ||||
|         // If enabled, lookup ReflectRed value, otherwise, 1.0 is used
 | ||||
|         if (config.lighting.lut_rr.enable && Pica::Regs::IsLightingSamplerSupported(config.lighting.config, Pica::Regs::LightingSampler::ReflectRed)) { | ||||
|             std::string index = GetLutIndex(light_config.num, config.lighting.lut_rr.type, config.lighting.lut_rr.abs_input); | ||||
|             std::string value = "(" + std::to_string(config.lighting.lut_rr.scale) + " * " + GetLutValue(Regs::LightingSampler::ReflectRed, index) + ")"; | ||||
|             out += "refl_value.r = " + value + ";\n"; | ||||
|         } else { | ||||
|             out += "refl_value.r = 1.0;\n"; | ||||
|         } | ||||
| 
 | ||||
|         // If enabled, lookup ReflectGreen value, otherwise, ReflectRed value is used
 | ||||
|         if (config.lighting.lut_rg.enable && Pica::Regs::IsLightingSamplerSupported(config.lighting.config, Pica::Regs::LightingSampler::ReflectGreen)) { | ||||
|             std::string index = GetLutIndex(light_config.num, config.lighting.lut_rg.type, config.lighting.lut_rg.abs_input); | ||||
|             std::string value = "(" + std::to_string(config.lighting.lut_rg.scale) + " * " + GetLutValue(Regs::LightingSampler::ReflectGreen, index) + ")"; | ||||
|             out += "refl_value.g = " + value + ";\n"; | ||||
|         } else { | ||||
|             out += "refl_value.g = refl_value.r;\n"; | ||||
|         } | ||||
| 
 | ||||
|         // If enabled, lookup ReflectBlue value, otherwise, ReflectRed value is used
 | ||||
|         if (config.lighting.lut_rb.enable && Pica::Regs::IsLightingSamplerSupported(config.lighting.config, Pica::Regs::LightingSampler::ReflectBlue)) { | ||||
|             std::string index = GetLutIndex(light_config.num, config.lighting.lut_rb.type, config.lighting.lut_rb.abs_input); | ||||
|             std::string value = "(" + std::to_string(config.lighting.lut_rb.scale) + " * " + GetLutValue(Regs::LightingSampler::ReflectBlue, index) + ")"; | ||||
|             out += "refl_value.b = " + value + ";\n"; | ||||
|         } else { | ||||
|             out += "refl_value.b = refl_value.r;\n"; | ||||
|         } | ||||
| 
 | ||||
|         // Specular 1 component
 | ||||
|         std::string d1_lut_value = "1.0"; | ||||
|         if (config.lighting.lut_d1.enable && Pica::Regs::IsLightingSamplerSupported(config.lighting.config, Pica::Regs::LightingSampler::Distribution1)) { | ||||
|             // Lookup specular "distribution 1" LUT value
 | ||||
|             std::string d1_lut_index = GetLutIndex(light_config.num, config.lighting.lut_d1.type, config.lighting.lut_d1.abs_input); | ||||
|             d1_lut_value = "(" + std::to_string(config.lighting.lut_d1.scale) + " * " + GetLutValue(Regs::LightingSampler::Distribution1, d1_lut_index) + ")"; | ||||
|             std::string index = GetLutIndex(light_config.num, config.lighting.lut_d1.type, config.lighting.lut_d1.abs_input); | ||||
|             d1_lut_value = "(" + std::to_string(config.lighting.lut_d1.scale) + " * " + GetLutValue(Regs::LightingSampler::Distribution1, index) + ")"; | ||||
|         } | ||||
|         std::string specular_1 = "(" + d1_lut_value + " * " + light_src + ".specular_1)"; | ||||
|         std::string specular_1 = "(" + d1_lut_value + " * refl_value * " + light_src + ".specular_1)"; | ||||
| 
 | ||||
|         // Fresnel
 | ||||
|         if (config.lighting.lut_fr.enable && Pica::Regs::IsLightingSamplerSupported(config.lighting.config, Pica::Regs::LightingSampler::Fresnel)) { | ||||
|             // Lookup fresnel LUT value
 | ||||
|             std::string fr_lut_index = GetLutIndex(light_config.num, config.lighting.lut_fr.type, config.lighting.lut_fr.abs_input); | ||||
|             std::string fr_lut_value = "(" + std::to_string(config.lighting.lut_fr.scale) + " * " + GetLutValue(Regs::LightingSampler::Fresnel, fr_lut_index) + ")"; | ||||
|             std::string index = GetLutIndex(light_config.num, config.lighting.lut_fr.type, config.lighting.lut_fr.abs_input); | ||||
|             std::string value = "(" + std::to_string(config.lighting.lut_fr.scale) + " * " + GetLutValue(Regs::LightingSampler::Fresnel, index) + ")"; | ||||
| 
 | ||||
|             // Enabled for difffuse lighting alpha component
 | ||||
|             if (config.lighting.fresnel_selector == Pica::Regs::LightingFresnelSelector::PrimaryAlpha || | ||||
|                 config.lighting.fresnel_selector == Pica::Regs::LightingFresnelSelector::BothAlpha) | ||||
|                 out += "diffuse_sum.a  *= " + fr_lut_value + ";\n"; | ||||
|                 config.lighting.fresnel_selector == Pica::Regs::LightingFresnelSelector::Both) | ||||
|                 out += "diffuse_sum.a  *= " + value + ";\n"; | ||||
| 
 | ||||
|             // Enabled for the specular lighting alpha component
 | ||||
|             if (config.lighting.fresnel_selector == Pica::Regs::LightingFresnelSelector::SecondaryAlpha || | ||||
|                 config.lighting.fresnel_selector == Pica::Regs::LightingFresnelSelector::BothAlpha) | ||||
|                 out += "specular_sum.a *= " + fr_lut_value + ";\n"; | ||||
|                 config.lighting.fresnel_selector == Pica::Regs::LightingFresnelSelector::Both) | ||||
|                 out += "specular_sum.a *= " + value + ";\n"; | ||||
|         } | ||||
| 
 | ||||
|         // Compute primary fragment color (diffuse lighting) function
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 bunnei
						bunnei