diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/pica.h | 18 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 18 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_gen.cpp | 62 |
3 files changed, 77 insertions, 21 deletions
diff --git a/src/video_core/pica.h b/src/video_core/pica.h index 76db51038..267070e45 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h | |||
| @@ -650,9 +650,9 @@ struct Regs { | |||
| 650 | Distribution0 = 0, | 650 | Distribution0 = 0, |
| 651 | Distribution1 = 1, | 651 | Distribution1 = 1, |
| 652 | Fresnel = 3, | 652 | Fresnel = 3, |
| 653 | Blue = 4, | 653 | ReflectBlue = 4, |
| 654 | Green = 5, | 654 | ReflectGreen = 5, |
| 655 | Red = 6, | 655 | ReflectRed = 6, |
| 656 | SpotlightAttenuation = 8, | 656 | SpotlightAttenuation = 8, |
| 657 | DistanceAttenuation = 16, | 657 | DistanceAttenuation = 16, |
| 658 | }; | 658 | }; |
| @@ -718,10 +718,19 @@ struct Regs { | |||
| 718 | switch (sampler) { | 718 | switch (sampler) { |
| 719 | case LightingSampler::Distribution0: | 719 | case LightingSampler::Distribution0: |
| 720 | return (config != LightingConfig::Config1); | 720 | return (config != LightingConfig::Config1); |
| 721 | |||
| 721 | case LightingSampler::Distribution1: | 722 | case LightingSampler::Distribution1: |
| 722 | return (config != LightingConfig::Config0) && (config != LightingConfig::Config1) && (config != LightingConfig::Config5); | 723 | return (config != LightingConfig::Config0) && (config != LightingConfig::Config1) && (config != LightingConfig::Config5); |
| 724 | |||
| 723 | case LightingSampler::Fresnel: | 725 | case LightingSampler::Fresnel: |
| 724 | return (config != LightingConfig::Config0) && (config != LightingConfig::Config2) && (config != LightingConfig::Config4); | 726 | return (config != LightingConfig::Config0) && (config != LightingConfig::Config2) && (config != LightingConfig::Config4); |
| 727 | |||
| 728 | case LightingSampler::ReflectRed: | ||
| 729 | return (config != LightingConfig::Config3); | ||
| 730 | |||
| 731 | case LightingSampler::ReflectGreen: | ||
| 732 | case LightingSampler::ReflectBlue: | ||
| 733 | return (config == LightingConfig::Config4) || (config == LightingConfig::Config5) || (config == LightingConfig::Config7); | ||
| 725 | } | 734 | } |
| 726 | return false; | 735 | return false; |
| 727 | } | 736 | } |
| @@ -773,6 +782,9 @@ struct Regs { | |||
| 773 | BitField<16, 1, u32> lut_enable_d0; // 0: GL_TRUE, 1: GL_FALSE | 782 | BitField<16, 1, u32> lut_enable_d0; // 0: GL_TRUE, 1: GL_FALSE |
| 774 | BitField<17, 1, u32> lut_enable_d1; // 0: GL_TRUE, 1: GL_FALSE | 783 | 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 | 784 | BitField<19, 1, u32> lut_enable_fr; // 0: GL_TRUE, 1: GL_FALSE |
| 785 | BitField<20, 1, u32> lut_enable_rr; // 0: GL_TRUE, 1: GL_FALSE | ||
| 786 | BitField<21, 1, u32> lut_enable_rg; // 0: GL_TRUE, 1: GL_FALSE | ||
| 787 | BitField<22, 1, u32> lut_enable_rb; // 0: GL_TRUE, 1: GL_FALSE | ||
| 776 | 788 | ||
| 777 | // Each bit specifies whether distance attenuation should be applied for the | 789 | // Each bit specifies whether distance attenuation should be applied for the |
| 778 | // corresponding light | 790 | // corresponding light |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 1d4d73ae1..62a4d8953 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -102,6 +102,21 @@ struct PicaShaderConfig { | |||
| 102 | res.lighting.lut_fr.type = (Pica::Regs::LightingLutInput)regs.lighting.lut_input.fr.Value(); | 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); | 103 | res.lighting.lut_fr.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.fr); |
| 104 | 104 | ||
| 105 | res.lighting.lut_rr.enable = regs.lighting.lut_enable_rr == 0; | ||
| 106 | res.lighting.lut_rr.abs_input = regs.lighting.abs_lut_input.rr == 0; | ||
| 107 | res.lighting.lut_rr.type = (Pica::Regs::LightingLutInput)regs.lighting.lut_input.rr.Value(); | ||
| 108 | res.lighting.lut_rr.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.rr); | ||
| 109 | |||
| 110 | res.lighting.lut_rg.enable = regs.lighting.lut_enable_rg == 0; | ||
| 111 | res.lighting.lut_rg.abs_input = regs.lighting.abs_lut_input.rg == 0; | ||
| 112 | res.lighting.lut_rg.type = (Pica::Regs::LightingLutInput)regs.lighting.lut_input.rg.Value(); | ||
| 113 | res.lighting.lut_rg.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.rg); | ||
| 114 | |||
| 115 | res.lighting.lut_rb.enable = regs.lighting.lut_enable_rb == 0; | ||
| 116 | res.lighting.lut_rb.abs_input = regs.lighting.abs_lut_input.rb == 0; | ||
| 117 | res.lighting.lut_rb.type = (Pica::Regs::LightingLutInput)regs.lighting.lut_input.rb.Value(); | ||
| 118 | res.lighting.lut_rb.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.rb); | ||
| 119 | |||
| 105 | res.lighting.config = regs.lighting.config; | 120 | res.lighting.config = regs.lighting.config; |
| 106 | res.lighting.fresnel_selector = regs.lighting.fresnel_selector; | 121 | res.lighting.fresnel_selector = regs.lighting.fresnel_selector; |
| 107 | res.lighting.clamp_highlights = regs.lighting.clamp_highlights != 0; | 122 | res.lighting.clamp_highlights = regs.lighting.clamp_highlights != 0; |
| @@ -139,6 +154,7 @@ struct PicaShaderConfig { | |||
| 139 | bool enable = false; | 154 | bool enable = false; |
| 140 | unsigned src_num = 0; | 155 | unsigned src_num = 0; |
| 141 | bool clamp_highlights = false; | 156 | bool clamp_highlights = false; |
| 157 | |||
| 142 | Pica::Regs::LightingConfig config = Pica::Regs::LightingConfig::Config0; | 158 | Pica::Regs::LightingConfig config = Pica::Regs::LightingConfig::Config0; |
| 143 | Pica::Regs::LightingFresnelSelector fresnel_selector = Pica::Regs::LightingFresnelSelector::None; | 159 | Pica::Regs::LightingFresnelSelector fresnel_selector = Pica::Regs::LightingFresnelSelector::None; |
| 144 | 160 | ||
| @@ -147,7 +163,7 @@ struct PicaShaderConfig { | |||
| 147 | bool abs_input = false; | 163 | bool abs_input = false; |
| 148 | Pica::Regs::LightingLutInput type = Pica::Regs::LightingLutInput::NH; | 164 | Pica::Regs::LightingLutInput type = Pica::Regs::LightingLutInput::NH; |
| 149 | float scale = 1.0f; | 165 | float scale = 1.0f; |
| 150 | } lut_d0, lut_d1, lut_fr; | 166 | } lut_d0, lut_d1, lut_fr, lut_rr, lut_rg, lut_rb; |
| 151 | } lighting; | 167 | } lighting; |
| 152 | }; | 168 | }; |
| 153 | }; | 169 | }; |
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index 4f87c5846..984aef586 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp | |||
| @@ -321,9 +321,10 @@ 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 += "vec4 diffuse_sum = vec4(0.0, 0.0, 0.0, 1.0);\n"; | 324 | out += "vec4 diffuse_sum = vec4(0.0, 0.0, 0.0, 1.0);\n" |
| 325 | out += "vec4 specular_sum = vec4(0.0, 0.0, 0.0, 1.0);\n"; | 325 | "vec4 specular_sum = vec4(0.0, 0.0, 0.0, 1.0);\n" |
| 326 | out += "vec3 light_vector = vec3(0.0);\n"; | 326 | "vec3 light_vector = vec3(0.0);\n" |
| 327 | "vec3 refl_value = vec3(0.0);\n"; | ||
| 327 | 328 | ||
| 328 | // Convert interpolated quaternion to a GL fragment normal | 329 | // Convert interpolated quaternion to a GL fragment normal |
| 329 | out += "vec3 normal = normalize(vec3(\n"; | 330 | out += "vec3 normal = normalize(vec3(\n"; |
| @@ -396,10 +397,10 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) { | |||
| 396 | if (light_config.dist_atten_enable) { | 397 | if (light_config.dist_atten_enable) { |
| 397 | std::string scale = std::to_string(light_config.dist_atten_scale); | 398 | std::string scale = std::to_string(light_config.dist_atten_scale); |
| 398 | std::string bias = std::to_string(light_config.dist_atten_bias); | 399 | std::string bias = std::to_string(light_config.dist_atten_bias); |
| 399 | std::string lut_index = "(" + scale + " * length(-view - " + light_src + ".position) + " + bias + ")"; | 400 | std::string index = "(" + scale + " * length(-view - " + light_src + ".position) + " + bias + ")"; |
| 400 | lut_index = "((clamp(" + lut_index + ", 0.0, FLOAT_255)))"; | 401 | index = "((clamp(" + index + ", 0.0, FLOAT_255)))"; |
| 401 | const unsigned lut_num = ((unsigned)Regs::LightingSampler::DistanceAttenuation + light_config.num); | 402 | const unsigned lut_num = ((unsigned)Regs::LightingSampler::DistanceAttenuation + light_config.num); |
| 402 | dist_atten = GetLutValue((Regs::LightingSampler)lut_num, lut_index); | 403 | dist_atten = GetLutValue((Regs::LightingSampler)lut_num, index); |
| 403 | } | 404 | } |
| 404 | 405 | ||
| 405 | // If enabled, clamp specular component if lighting result is negative | 406 | // If enabled, clamp specular component if lighting result is negative |
| @@ -409,35 +410,62 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) { | |||
| 409 | std::string d0_lut_value = "1.0"; | 410 | std::string d0_lut_value = "1.0"; |
| 410 | if (config.lighting.lut_d0.enable && Pica::Regs::IsLightingSamplerSupported(config.lighting.config, Pica::Regs::LightingSampler::Distribution0)) { | 411 | if (config.lighting.lut_d0.enable && Pica::Regs::IsLightingSamplerSupported(config.lighting.config, Pica::Regs::LightingSampler::Distribution0)) { |
| 411 | // Lookup specular "distribution 0" LUT value | 412 | // Lookup specular "distribution 0" LUT value |
| 412 | std::string d0_lut_index = GetLutIndex(light_config.num, config.lighting.lut_d0.type, config.lighting.lut_d0.abs_input); | 413 | std::string index = GetLutIndex(light_config.num, config.lighting.lut_d0.type, config.lighting.lut_d0.abs_input); |
| 413 | d0_lut_value = "(" + std::to_string(config.lighting.lut_d0.scale) + " * " + GetLutValue(Regs::LightingSampler::Distribution0, d0_lut_index) + ")"; | 414 | d0_lut_value = "(" + std::to_string(config.lighting.lut_d0.scale) + " * " + GetLutValue(Regs::LightingSampler::Distribution0, index) + ")"; |
| 414 | } | 415 | } |
| 415 | std::string specular_0 = "(" + d0_lut_value + " * " + light_src + ".specular_0)"; | 416 | std::string specular_0 = "(" + d0_lut_value + " * " + light_src + ".specular_0)"; |
| 416 | 417 | ||
| 418 | // If enabled, lookup ReflectRed value, otherwise, 1.0 is used | ||
| 419 | if (config.lighting.lut_rr.enable && Pica::Regs::IsLightingSamplerSupported(config.lighting.config, Pica::Regs::LightingSampler::ReflectRed)) { | ||
| 420 | std::string index = GetLutIndex(light_config.num, config.lighting.lut_rr.type, config.lighting.lut_rr.abs_input); | ||
| 421 | std::string value = "(" + std::to_string(config.lighting.lut_rr.scale) + " * " + GetLutValue(Regs::LightingSampler::ReflectRed, index) + ")"; | ||
| 422 | out += "refl_value.r = " + value + ";\n"; | ||
| 423 | } else { | ||
| 424 | out += "refl_value.r = 1.0;\n"; | ||
| 425 | } | ||
| 426 | |||
| 427 | // If enabled, lookup ReflectGreen value, otherwise, ReflectRed value is used | ||
| 428 | if (config.lighting.lut_rg.enable && Pica::Regs::IsLightingSamplerSupported(config.lighting.config, Pica::Regs::LightingSampler::ReflectGreen)) { | ||
| 429 | std::string index = GetLutIndex(light_config.num, config.lighting.lut_rg.type, config.lighting.lut_rg.abs_input); | ||
| 430 | std::string value = "(" + std::to_string(config.lighting.lut_rg.scale) + " * " + GetLutValue(Regs::LightingSampler::ReflectGreen, index) + ")"; | ||
| 431 | out += "refl_value.g = " + value + ";\n"; | ||
| 432 | } else { | ||
| 433 | out += "refl_value.g = refl_value.r;\n"; | ||
| 434 | } | ||
| 435 | |||
| 436 | // If enabled, lookup ReflectBlue value, otherwise, ReflectRed value is used | ||
| 437 | if (config.lighting.lut_rb.enable && Pica::Regs::IsLightingSamplerSupported(config.lighting.config, Pica::Regs::LightingSampler::ReflectBlue)) { | ||
| 438 | std::string index = GetLutIndex(light_config.num, config.lighting.lut_rb.type, config.lighting.lut_rb.abs_input); | ||
| 439 | std::string value = "(" + std::to_string(config.lighting.lut_rb.scale) + " * " + GetLutValue(Regs::LightingSampler::ReflectBlue, index) + ")"; | ||
| 440 | out += "refl_value.b = " + value + ";\n"; | ||
| 441 | } else { | ||
| 442 | out += "refl_value.b = refl_value.r;\n"; | ||
| 443 | } | ||
| 444 | |||
| 417 | // Specular 1 component | 445 | // Specular 1 component |
| 418 | std::string d1_lut_value = "1.0"; | 446 | std::string d1_lut_value = "1.0"; |
| 419 | if (config.lighting.lut_d1.enable && Pica::Regs::IsLightingSamplerSupported(config.lighting.config, Pica::Regs::LightingSampler::Distribution1)) { | 447 | if (config.lighting.lut_d1.enable && Pica::Regs::IsLightingSamplerSupported(config.lighting.config, Pica::Regs::LightingSampler::Distribution1)) { |
| 420 | // Lookup specular "distribution 1" LUT value | 448 | // Lookup specular "distribution 1" LUT value |
| 421 | std::string d1_lut_index = GetLutIndex(light_config.num, config.lighting.lut_d1.type, config.lighting.lut_d1.abs_input); | 449 | std::string index = GetLutIndex(light_config.num, config.lighting.lut_d1.type, config.lighting.lut_d1.abs_input); |
| 422 | d1_lut_value = "(" + std::to_string(config.lighting.lut_d1.scale) + " * " + GetLutValue(Regs::LightingSampler::Distribution1, d1_lut_index) + ")"; | 450 | d1_lut_value = "(" + std::to_string(config.lighting.lut_d1.scale) + " * " + GetLutValue(Regs::LightingSampler::Distribution1, index) + ")"; |
| 423 | } | 451 | } |
| 424 | std::string specular_1 = "(" + d1_lut_value + " * " + light_src + ".specular_1)"; | 452 | std::string specular_1 = "(" + d1_lut_value + " * refl_value * " + light_src + ".specular_1)"; |
| 425 | 453 | ||
| 426 | // Fresnel | 454 | // Fresnel |
| 427 | if (config.lighting.lut_fr.enable && Pica::Regs::IsLightingSamplerSupported(config.lighting.config, Pica::Regs::LightingSampler::Fresnel)) { | 455 | if (config.lighting.lut_fr.enable && Pica::Regs::IsLightingSamplerSupported(config.lighting.config, Pica::Regs::LightingSampler::Fresnel)) { |
| 428 | // Lookup fresnel LUT value | 456 | // 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); | 457 | std::string 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) + ")"; | 458 | std::string value = "(" + std::to_string(config.lighting.lut_fr.scale) + " * " + GetLutValue(Regs::LightingSampler::Fresnel, index) + ")"; |
| 431 | 459 | ||
| 432 | // Enabled for difffuse lighting alpha component | 460 | // Enabled for difffuse lighting alpha component |
| 433 | if (config.lighting.fresnel_selector == Pica::Regs::LightingFresnelSelector::PrimaryAlpha || | 461 | if (config.lighting.fresnel_selector == Pica::Regs::LightingFresnelSelector::PrimaryAlpha || |
| 434 | config.lighting.fresnel_selector == Pica::Regs::LightingFresnelSelector::BothAlpha) | 462 | config.lighting.fresnel_selector == Pica::Regs::LightingFresnelSelector::Both) |
| 435 | out += "diffuse_sum.a *= " + fr_lut_value + ";\n"; | 463 | out += "diffuse_sum.a *= " + value + ";\n"; |
| 436 | 464 | ||
| 437 | // Enabled for the specular lighting alpha component | 465 | // Enabled for the specular lighting alpha component |
| 438 | if (config.lighting.fresnel_selector == Pica::Regs::LightingFresnelSelector::SecondaryAlpha || | 466 | if (config.lighting.fresnel_selector == Pica::Regs::LightingFresnelSelector::SecondaryAlpha || |
| 439 | config.lighting.fresnel_selector == Pica::Regs::LightingFresnelSelector::BothAlpha) | 467 | config.lighting.fresnel_selector == Pica::Regs::LightingFresnelSelector::Both) |
| 440 | out += "specular_sum.a *= " + fr_lut_value + ";\n"; | 468 | out += "specular_sum.a *= " + value + ";\n"; |
| 441 | } | 469 | } |
| 442 | 470 | ||
| 443 | // Compute primary fragment color (diffuse lighting) function | 471 | // Compute primary fragment color (diffuse lighting) function |