diff options
| -rw-r--r-- | src/video_core/pica.h | 27 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 8 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_gen.cpp | 17 | 
3 files changed, 41 insertions, 11 deletions
diff --git a/src/video_core/pica.h b/src/video_core/pica.h index 5d27da5d1..83af6a127 100644 --- a/src/video_core/pica.h +++ b/src/video_core/pica.h @@ -713,6 +713,16 @@ struct Regs {          }      }; +    static bool IsLightingSamplerSupported(LightingConfig config, LightingSampler sampler) { +        switch (sampler) { +        case LightingSampler::Distribution0: +            return (config != LightingConfig::Config1); +        case LightingSampler::Distribution1: +            return (config != LightingConfig::Config0) && (config != LightingConfig::Config1) && (config != LightingConfig::Config5); +        } +        return false; +    } +      struct {          struct LightSrc {              LightColor specular_0;  // material.specular_0 * light.specular_0 @@ -751,12 +761,13 @@ struct Regs {          BitField<0, 3, u32> src_num; // number of enabled lights - 1          union { -            BitField< 4, 4, u32> config; +            BitField< 4, 4, LightingConfig> config;              BitField<27, 1, u32> clamp_highlights; // 1: GL_TRUE, 0: GL_FALSE          };          union {              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              // Each bit specifies whether distance attenuation should be applied for the              // corresponding light @@ -804,13 +815,13 @@ struct Regs {          } abs_lut_input;          union { -            BitField< 0, 3, u32> d0; -            BitField< 4, 3, u32> d1; -            BitField< 8, 3, u32> sp; -            BitField<12, 3, u32> fr; -            BitField<16, 3, u32> rb; -            BitField<20, 3, u32> rg; -            BitField<24, 3, u32> rr; +            BitField< 0, 3, LightingLutInput> d0; +            BitField< 4, 3, LightingLutInput> d1; +            BitField< 8, 3, LightingLutInput> sp; +            BitField<12, 3, LightingLutInput> fr; +            BitField<16, 3, LightingLutInput> rb; +            BitField<20, 3, LightingLutInput> rg; +            BitField<24, 3, LightingLutInput> rr;          } lut_input;          union { diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 72ded8f22..788618ed2 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -91,6 +91,13 @@ struct PicaShaderConfig {          res.lighting.lut_d0.abs_input = regs.lighting.abs_lut_input.d0 == 0;          res.lighting.lut_d0.type = (Pica::Regs::LightingLutInput)regs.lighting.lut_input.d0.Value();          res.lighting.lut_d0.scale = regs.lighting.lut_scale.GetScale(regs.lighting.lut_scale.d0); + +        res.lighting.lut_d1.enable = regs.lighting.lut_enable_d1 == 0; +        res.lighting.lut_d1.abs_input = regs.lighting.abs_lut_input.d1 == 0; +        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.config = regs.lighting.config;          res.lighting.clamp_highlights = regs.lighting.clamp_highlights != 0;          return res; @@ -126,6 +133,7 @@ struct PicaShaderConfig {              bool enable = false;              unsigned src_num = 0;              bool clamp_highlights = false; +            Pica::Regs::LightingConfig config = Pica::Regs::LightingConfig::Config0;              struct {                  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 9044a3813..4f8b675bf 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp @@ -408,15 +408,26 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) {          // 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"; -        // Lookup specular "distribution 0" LUT value +        // Specular 0 component          std::string d0_lut_value = "1.0"; -        if (config.lighting.lut_d0.enable) { +        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 specular_0 = "(" + d0_lut_value + " * " + light_src + ".specular_0)"; + +        // 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 specular_1 = "(" + d1_lut_value + " * " + light_src + ".specular_1)";          // Compute secondary fragment color (specular lighting) function -        out += "specular_sum += " + clamp_highlights + " * " + d0_lut_value + " * " + light_src + ".specular_0 * " + dist_atten + ";\n"; +        out += "specular_sum += (" + specular_0 + " + " + specular_1 + ") * " + clamp_highlights + " * " + dist_atten + ";\n";      }      // Sum final lighting result  | 
