diff options
| -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 {          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 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 {          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;      };  }; 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  /// 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 | 
