diff options
| author | 2015-11-23 20:26:09 -0500 | |
|---|---|---|
| committer | 2016-02-05 17:20:13 -0500 | |
| commit | c37de30cfc21cd6d742eed27a996a273f5ec2ca1 (patch) | |
| tree | 44757e1d0fd83110229e7fad641a54f2e6353baf /src/video_core | |
| parent | gl_shader_gen: Implement fragment lighting specular 1 component. (diff) | |
| download | yuzu-c37de30cfc21cd6d742eed27a996a273f5ec2ca1.tar.gz yuzu-c37de30cfc21cd6d742eed27a996a273f5ec2ca1.tar.xz yuzu-c37de30cfc21cd6d742eed27a996a273f5ec2ca1.zip | |
gl_shader_gen: Implement fragment lighting fresnel effect.
Diffstat (limited to 'src/video_core')
| -rw-r--r-- | src/video_core/pica.h | 5 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 7 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_gen.cpp | 35 |
3 files changed, 38 insertions, 9 deletions
diff --git a/src/video_core/pica.h b/src/video_core/pica.h index 83af6a127..76db51038 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h | |||
| @@ -713,12 +713,15 @@ struct Regs { | |||
| 713 | } | 713 | } |
| 714 | }; | 714 | }; |
| 715 | 715 | ||
| 716 | /// Returns true if the specified lighting sampler is supported by the current Pica lighting configuration | ||
| 716 | static bool IsLightingSamplerSupported(LightingConfig config, LightingSampler sampler) { | 717 | static bool IsLightingSamplerSupported(LightingConfig config, LightingSampler sampler) { |
| 717 | switch (sampler) { | 718 | switch (sampler) { |
| 718 | case LightingSampler::Distribution0: | 719 | case LightingSampler::Distribution0: |
| 719 | return (config != LightingConfig::Config1); | 720 | return (config != LightingConfig::Config1); |
| 720 | case LightingSampler::Distribution1: | 721 | case LightingSampler::Distribution1: |
| 721 | return (config != LightingConfig::Config0) && (config != LightingConfig::Config1) && (config != LightingConfig::Config5); | 722 | return (config != LightingConfig::Config0) && (config != LightingConfig::Config1) && (config != LightingConfig::Config5); |
| 723 | case LightingSampler::Fresnel: | ||
| 724 | return (config != LightingConfig::Config0) && (config != LightingConfig::Config2) && (config != LightingConfig::Config4); | ||
| 722 | } | 725 | } |
| 723 | return false; | 726 | return false; |
| 724 | } | 727 | } |
| @@ -761,6 +764,7 @@ struct Regs { | |||
| 761 | BitField<0, 3, u32> src_num; // number of enabled lights - 1 | 764 | BitField<0, 3, u32> src_num; // number of enabled lights - 1 |
| 762 | 765 | ||
| 763 | union { | 766 | union { |
| 767 | BitField< 2, 2, LightingFresnelSelector> fresnel_selector; | ||
| 764 | BitField< 4, 4, LightingConfig> config; | 768 | BitField< 4, 4, LightingConfig> config; |
| 765 | BitField<27, 1, u32> clamp_highlights; // 1: GL_TRUE, 0: GL_FALSE | 769 | BitField<27, 1, u32> clamp_highlights; // 1: GL_TRUE, 0: GL_FALSE |
| 766 | }; | 770 | }; |
| @@ -768,6 +772,7 @@ struct Regs { | |||
| 768 | union { | 772 | union { |
| 769 | BitField<16, 1, u32> lut_enable_d0; // 0: GL_TRUE, 1: GL_FALSE | 773 | BitField<16, 1, u32> lut_enable_d0; // 0: GL_TRUE, 1: GL_FALSE |
| 770 | BitField<17, 1, u32> lut_enable_d1; // 0: GL_TRUE, 1: GL_FALSE | 774 | BitField<17, 1, u32> lut_enable_d1; // 0: GL_TRUE, 1: GL_FALSE |
| 775 | BitField<19, 1, u32> lut_enable_fr; // 0: GL_TRUE, 1: GL_FALSE | ||
| 771 | 776 | ||
| 772 | // Each bit specifies whether distance attenuation should be applied for the | 777 | // Each bit specifies whether distance attenuation should be applied for the |
| 773 | // corresponding light | 778 | // corresponding light |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 788618ed2..1d4d73ae1 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -97,7 +97,13 @@ struct PicaShaderConfig { | |||
| 97 | res.lighting.lut_d1.type = (Pica::Regs::LightingLutInput)regs.lighting.lut_input.d1.Value(); | 97 | res.lighting.lut_d1.type = (Pica::Regs::LightingLutInput)regs.lighting.lut_input.d1.Value(); |
| 98 | res.lighting.lut_d1.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.d1); | 98 | res.lighting.lut_d1.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.d1); |
| 99 | 99 | ||
| 100 | res.lighting.lut_fr.enable = regs.lighting.lut_enable_fr == 0; | ||
| 101 | res.lighting.lut_fr.abs_input = regs.lighting.abs_lut_input.fr == 0; | ||
| 102 | res.lighting.lut_fr.type = (Pica::Regs::LightingLutInput)regs.lighting.lut_input.fr.Value(); | ||
| 103 | res.lighting.lut_fr.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.fr); | ||
| 104 | |||
| 100 | res.lighting.config = regs.lighting.config; | 105 | res.lighting.config = regs.lighting.config; |
| 106 | res.lighting.fresnel_selector = regs.lighting.fresnel_selector; | ||
| 101 | res.lighting.clamp_highlights = regs.lighting.clamp_highlights != 0; | 107 | res.lighting.clamp_highlights = regs.lighting.clamp_highlights != 0; |
| 102 | 108 | ||
| 103 | return res; | 109 | return res; |
| @@ -134,6 +140,7 @@ struct PicaShaderConfig { | |||
| 134 | unsigned src_num = 0; | 140 | unsigned src_num = 0; |
| 135 | bool clamp_highlights = false; | 141 | bool clamp_highlights = false; |
| 136 | Pica::Regs::LightingConfig config = Pica::Regs::LightingConfig::Config0; | 142 | Pica::Regs::LightingConfig config = Pica::Regs::LightingConfig::Config0; |
| 143 | Pica::Regs::LightingFresnelSelector fresnel_selector = Pica::Regs::LightingFresnelSelector::None; | ||
| 137 | 144 | ||
| 138 | struct { | 145 | struct { |
| 139 | bool enable = false; | 146 | bool enable = false; |
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index 4f8b675bf..6487172b4 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp | |||
| @@ -321,8 +321,8 @@ static void WriteTevStage(std::string& out, const PicaShaderConfig& config, unsi | |||
| 321 | /// Writes the code to emulate fragment lighting | 321 | /// Writes the code to emulate fragment lighting |
| 322 | static void WriteLighting(std::string& out, const PicaShaderConfig& config) { | 322 | static void WriteLighting(std::string& out, const PicaShaderConfig& config) { |
| 323 | // Define lighting globals | 323 | // Define lighting globals |
| 324 | out += "vec3 diffuse_sum = vec3(0.0);\n"; | 324 | out += "vec4 diffuse_sum = vec4(0.0, 0.0, 0.0, 1.0);\n"; |
| 325 | out += "vec3 specular_sum = vec3(0.0);\n"; | 325 | out += "vec4 specular_sum = vec4(0.0, 0.0, 0.0, 1.0);\n"; |
| 326 | out += "vec3 light_vector = vec3(0.0);\n"; | 326 | out += "vec3 light_vector = vec3(0.0);\n"; |
| 327 | 327 | ||
| 328 | // Convert interpolated quaternion to a GL fragment normal | 328 | // Convert interpolated quaternion to a GL fragment normal |
| @@ -402,9 +402,6 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) { | |||
| 402 | dist_atten = GetLutValue((Regs::LightingSampler)lut_num, lut_index); | 402 | dist_atten = GetLutValue((Regs::LightingSampler)lut_num, lut_index); |
| 403 | } | 403 | } |
| 404 | 404 | ||
| 405 | // Compute primary fragment color (diffuse lighting) function | ||
| 406 | out += "diffuse_sum += ((" + light_src + ".diffuse * " + dot_product + ") + " + light_src + ".ambient) * " + dist_atten + ";\n"; | ||
| 407 | |||
| 408 | // If enabled, clamp specular component if lighting result is negative | 405 | // If enabled, clamp specular component if lighting result is negative |
| 409 | std::string clamp_highlights = config.lighting.clamp_highlights ? "(dot(light_vector, normal) <= 0.0 ? 0.0 : 1.0)" : "1.0"; | 406 | std::string clamp_highlights = config.lighting.clamp_highlights ? "(dot(light_vector, normal) <= 0.0 ? 0.0 : 1.0)" : "1.0"; |
| 410 | 407 | ||
| @@ -426,14 +423,34 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) { | |||
| 426 | } | 423 | } |
| 427 | std::string specular_1 = "(" + d1_lut_value + " * " + light_src + ".specular_1)"; | 424 | std::string specular_1 = "(" + d1_lut_value + " * " + light_src + ".specular_1)"; |
| 428 | 425 | ||
| 426 | // Fresnel | ||
| 427 | if (config.lighting.lut_fr.enable && Pica::Regs::IsLightingSamplerSupported(config.lighting.config, Pica::Regs::LightingSampler::Fresnel)) { | ||
| 428 | // Lookup fresnel LUT value | ||
| 429 | std::string fr_lut_index = GetLutIndex(light_config.num, config.lighting.lut_fr.type, config.lighting.lut_fr.abs_input); | ||
| 430 | std::string fr_lut_value = "(" + std::to_string(config.lighting.lut_fr.scale) + " * " + GetLutValue(Regs::LightingSampler::Fresnel, fr_lut_index) + ")"; | ||
| 431 | |||
| 432 | // Enabled for difffuse lighting alpha component | ||
| 433 | if (config.lighting.fresnel_selector == Pica::Regs::LightingFresnelSelector::PrimaryAlpha || | ||
| 434 | config.lighting.fresnel_selector == Pica::Regs::LightingFresnelSelector::BothAlpha) | ||
| 435 | out += "diffuse_sum.a *= " + fr_lut_value + ";\n"; | ||
| 436 | |||
| 437 | // Enabled for the specular lighting alpha component | ||
| 438 | if (config.lighting.fresnel_selector == Pica::Regs::LightingFresnelSelector::SecondaryAlpha || | ||
| 439 | config.lighting.fresnel_selector == Pica::Regs::LightingFresnelSelector::BothAlpha) | ||
| 440 | out += "specular_sum.a *= " + fr_lut_value + ";\n"; | ||
| 441 | } | ||
| 442 | |||
| 443 | // Compute primary fragment color (diffuse lighting) function | ||
| 444 | out += "diffuse_sum.rgb += ((" + light_src + ".diffuse * " + dot_product + ") + " + light_src + ".ambient) * " + dist_atten + ";\n"; | ||
| 445 | |||
| 429 | // Compute secondary fragment color (specular lighting) function | 446 | // Compute secondary fragment color (specular lighting) function |
| 430 | out += "specular_sum += (" + specular_0 + " + " + specular_1 + ") * " + clamp_highlights + " * " + dist_atten + ";\n"; | 447 | out += "specular_sum.rgb += (" + specular_0 + " + " + specular_1 + ") * " + clamp_highlights + " * " + dist_atten + ";\n"; |
| 431 | } | 448 | } |
| 432 | 449 | ||
| 433 | // Sum final lighting result | 450 | // Sum final lighting result |
| 434 | out += "diffuse_sum += lighting_global_ambient;\n"; | 451 | out += "diffuse_sum.rgb += lighting_global_ambient;\n"; |
| 435 | out += "primary_fragment_color = vec4(clamp(diffuse_sum, vec3(0.0), vec3(1.0)), 1.0);\n"; | 452 | out += "primary_fragment_color = clamp(diffuse_sum, vec4(0.0), vec4(1.0));\n"; |
| 436 | out += "secondary_fragment_color = vec4(clamp(specular_sum, vec3(0.0), vec3(1.0)), 1.0);\n"; | 453 | out += "secondary_fragment_color = clamp(specular_sum, vec4(0.0), vec4(1.0));\n"; |
| 437 | } | 454 | } |
| 438 | 455 | ||
| 439 | std::string GenerateFragmentShader(const PicaShaderConfig& config) { | 456 | std::string GenerateFragmentShader(const PicaShaderConfig& config) { |