diff options
| -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 {          }      }; +    /// Returns true if the specified lighting sampler is supported by the current Pica lighting configuration      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); +        case LightingSampler::Fresnel: +            return (config != LightingConfig::Config0) && (config != LightingConfig::Config2) && (config != LightingConfig::Config4);          }          return false;      } @@ -761,6 +764,7 @@ struct Regs {          BitField<0, 3, u32> src_num; // number of enabled lights - 1          union { +            BitField< 2, 2, LightingFresnelSelector> fresnel_selector;              BitField< 4, 4, LightingConfig> config;              BitField<27, 1, u32> clamp_highlights; // 1: GL_TRUE, 0: GL_FALSE          }; @@ -768,6 +772,7 @@ struct Regs {          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 +            BitField<19, 1, u32> lut_enable_fr; // 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 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 {          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_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.fresnel_selector = regs.lighting.fresnel_selector;          res.lighting.clamp_highlights = regs.lighting.clamp_highlights != 0;          return res; @@ -134,6 +140,7 @@ struct PicaShaderConfig {              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;              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 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  /// Writes the code to emulate fragment lighting  static void WriteLighting(std::string& out, const PicaShaderConfig& config) {      // Define lighting globals -    out += "vec3 diffuse_sum = vec3(0.0);\n"; -    out += "vec3 specular_sum = vec3(0.0);\n"; +    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";      // 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);          } -        // 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          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)"; +        // 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 -        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 -    out += "diffuse_sum += lighting_global_ambient;\n"; -    out += "primary_fragment_color = vec4(clamp(diffuse_sum, vec3(0.0), vec3(1.0)), 1.0);\n"; -    out += "secondary_fragment_color = vec4(clamp(specular_sum, vec3(0.0), vec3(1.0)), 1.0);\n"; +    out += "diffuse_sum.rgb += lighting_global_ambient;\n"; +    out += "primary_fragment_color = clamp(diffuse_sum, vec4(0.0), vec4(1.0));\n"; +    out += "secondary_fragment_color = clamp(specular_sum, vec4(0.0), vec4(1.0));\n";  }  std::string GenerateFragmentShader(const PicaShaderConfig& config) { | 
