forked from eden-emu/eden
		
	gl_shader_gen: Implement fragment lighting fresnel effect.
This commit is contained in:
		
							parent
							
								
									0e67c21c9e
								
							
						
					
					
						commit
						c37de30cfc
					
				
					 3 changed files with 38 additions and 9 deletions
				
			
		|  | @ -713,12 +713,15 @@ struct Regs { | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  |     /// Returns true if the specified lighting sampler is supported by the current Pica lighting configuration
 | ||||||
|     static bool IsLightingSamplerSupported(LightingConfig config, LightingSampler sampler) { |     static bool IsLightingSamplerSupported(LightingConfig config, LightingSampler sampler) { | ||||||
|         switch (sampler) { |         switch (sampler) { | ||||||
|         case LightingSampler::Distribution0: |         case LightingSampler::Distribution0: | ||||||
|             return (config != LightingConfig::Config1); |             return (config != LightingConfig::Config1); | ||||||
|         case LightingSampler::Distribution1: |         case LightingSampler::Distribution1: | ||||||
|             return (config != LightingConfig::Config0) && (config != LightingConfig::Config1) && (config != LightingConfig::Config5); |             return (config != LightingConfig::Config0) && (config != LightingConfig::Config1) && (config != LightingConfig::Config5); | ||||||
|  |         case LightingSampler::Fresnel: | ||||||
|  |             return (config != LightingConfig::Config0) && (config != LightingConfig::Config2) && (config != LightingConfig::Config4); | ||||||
|         } |         } | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  | @ -761,6 +764,7 @@ struct Regs { | ||||||
|         BitField<0, 3, u32> src_num; // number of enabled lights - 1
 |         BitField<0, 3, u32> src_num; // number of enabled lights - 1
 | ||||||
| 
 | 
 | ||||||
|         union { |         union { | ||||||
|  |             BitField< 2, 2, LightingFresnelSelector> fresnel_selector; | ||||||
|             BitField< 4, 4, LightingConfig> config; |             BitField< 4, 4, LightingConfig> config; | ||||||
|             BitField<27, 1, u32> clamp_highlights; // 1: GL_TRUE, 0: GL_FALSE
 |             BitField<27, 1, u32> clamp_highlights; // 1: GL_TRUE, 0: GL_FALSE
 | ||||||
|         }; |         }; | ||||||
|  | @ -768,6 +772,7 @@ struct Regs { | ||||||
|         union { |         union { | ||||||
|             BitField<16, 1, u32> lut_enable_d0; // 0: GL_TRUE, 1: GL_FALSE
 |             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<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
 | ||||||
| 
 | 
 | ||||||
|             // Each bit specifies whether distance attenuation should be applied for the
 |             // Each bit specifies whether distance attenuation should be applied for the
 | ||||||
|             // corresponding light
 |             // corresponding light
 | ||||||
|  |  | ||||||
|  | @ -97,7 +97,13 @@ struct PicaShaderConfig { | ||||||
|         res.lighting.lut_d1.type = (Pica::Regs::LightingLutInput)regs.lighting.lut_input.d1.Value(); |         res.lighting.lut_d1.type = (Pica::Regs::LightingLutInput)regs.lighting.lut_input.d1.Value(); | ||||||
|         res.lighting.lut_d1.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.d1); |         res.lighting.lut_d1.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.d1); | ||||||
| 
 | 
 | ||||||
|  |         res.lighting.lut_fr.enable = regs.lighting.lut_enable_fr == 0; | ||||||
|  |         res.lighting.lut_fr.abs_input = regs.lighting.abs_lut_input.fr == 0; | ||||||
|  |         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.config = regs.lighting.config; |         res.lighting.config = regs.lighting.config; | ||||||
|  |         res.lighting.fresnel_selector = regs.lighting.fresnel_selector; | ||||||
|         res.lighting.clamp_highlights = regs.lighting.clamp_highlights != 0; |         res.lighting.clamp_highlights = regs.lighting.clamp_highlights != 0; | ||||||
| 
 | 
 | ||||||
|         return res; |         return res; | ||||||
|  | @ -134,6 +140,7 @@ struct PicaShaderConfig { | ||||||
|             unsigned src_num = 0; |             unsigned src_num = 0; | ||||||
|             bool clamp_highlights = false; |             bool clamp_highlights = false; | ||||||
|             Pica::Regs::LightingConfig config = Pica::Regs::LightingConfig::Config0; |             Pica::Regs::LightingConfig config = Pica::Regs::LightingConfig::Config0; | ||||||
|  |             Pica::Regs::LightingFresnelSelector fresnel_selector = Pica::Regs::LightingFresnelSelector::None; | ||||||
| 
 | 
 | ||||||
|             struct { |             struct { | ||||||
|                 bool enable = false; |                 bool enable = false; | ||||||
|  |  | ||||||
|  | @ -321,8 +321,8 @@ static void WriteTevStage(std::string& out, const PicaShaderConfig& config, unsi | ||||||
| /// Writes the code to emulate fragment lighting
 | /// Writes the code to emulate fragment lighting
 | ||||||
| static void WriteLighting(std::string& out, const PicaShaderConfig& config) { | static void WriteLighting(std::string& out, const PicaShaderConfig& config) { | ||||||
|     // Define lighting globals
 |     // Define lighting globals
 | ||||||
|     out += "vec3 diffuse_sum = vec3(0.0);\n"; |     out += "vec4 diffuse_sum = vec4(0.0, 0.0, 0.0, 1.0);\n"; | ||||||
|     out += "vec3 specular_sum = vec3(0.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 += "vec3 light_vector = vec3(0.0);\n"; | ||||||
| 
 | 
 | ||||||
|     // Convert interpolated quaternion to a GL fragment normal
 |     // Convert interpolated quaternion to a GL fragment normal
 | ||||||
|  | @ -402,9 +402,6 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) { | ||||||
|             dist_atten = GetLutValue((Regs::LightingSampler)lut_num, lut_index); |             dist_atten = GetLutValue((Regs::LightingSampler)lut_num, lut_index); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // Compute primary fragment color (diffuse lighting) function
 |  | ||||||
|         out += "diffuse_sum += ((" + light_src + ".diffuse * " + dot_product + ") + " + light_src + ".ambient) * " + dist_atten + ";\n"; |  | ||||||
| 
 |  | ||||||
|         // If enabled, clamp specular component if lighting result is negative
 |         // If enabled, clamp specular component if lighting result is negative
 | ||||||
|         std::string clamp_highlights = config.lighting.clamp_highlights ? "(dot(light_vector, normal) <= 0.0 ? 0.0 : 1.0)" : "1.0"; |         std::string clamp_highlights = config.lighting.clamp_highlights ? "(dot(light_vector, normal) <= 0.0 ? 0.0 : 1.0)" : "1.0"; | ||||||
| 
 | 
 | ||||||
|  | @ -426,14 +423,34 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) { | ||||||
|         } |         } | ||||||
|         std::string specular_1 = "(" + d1_lut_value + " * " + light_src + ".specular_1)"; |         std::string specular_1 = "(" + d1_lut_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) + ")"; | ||||||
|  | 
 | ||||||
|  |             // 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"; | ||||||
|  | 
 | ||||||
|  |             // 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"; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // Compute primary fragment color (diffuse lighting) function
 | ||||||
|  |         out += "diffuse_sum.rgb += ((" + light_src + ".diffuse * " + dot_product + ") + " + light_src + ".ambient) * " + dist_atten + ";\n"; | ||||||
|  | 
 | ||||||
|         // Compute secondary fragment color (specular lighting) function
 |         // Compute secondary fragment color (specular lighting) function
 | ||||||
|         out += "specular_sum += (" + specular_0 + " + " + specular_1 + ") * " + clamp_highlights + " * " + dist_atten + ";\n"; |         out += "specular_sum.rgb += (" + specular_0 + " + " + specular_1 + ") * " + clamp_highlights + " * " + dist_atten + ";\n"; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Sum final lighting result
 |     // Sum final lighting result
 | ||||||
|     out += "diffuse_sum += lighting_global_ambient;\n"; |     out += "diffuse_sum.rgb += lighting_global_ambient;\n"; | ||||||
|     out += "primary_fragment_color = vec4(clamp(diffuse_sum, vec3(0.0), vec3(1.0)), 1.0);\n"; |     out += "primary_fragment_color = clamp(diffuse_sum, vec4(0.0), vec4(1.0));\n"; | ||||||
|     out += "secondary_fragment_color = vec4(clamp(specular_sum, vec3(0.0), vec3(1.0)), 1.0);\n"; |     out += "secondary_fragment_color = clamp(specular_sum, vec4(0.0), vec4(1.0));\n"; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::string GenerateFragmentShader(const PicaShaderConfig& config) { | std::string GenerateFragmentShader(const PicaShaderConfig& config) { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 bunnei
						bunnei