summaryrefslogtreecommitdiff
path: root/src/video_core
diff options
context:
space:
mode:
authorGravatar bunnei2015-11-23 20:26:09 -0500
committerGravatar bunnei2016-02-05 17:20:13 -0500
commitc37de30cfc21cd6d742eed27a996a273f5ec2ca1 (patch)
tree44757e1d0fd83110229e7fad641a54f2e6353baf /src/video_core
parentgl_shader_gen: Implement fragment lighting specular 1 component. (diff)
downloadyuzu-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.h5
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h7
-rw-r--r--src/video_core/renderer_opengl/gl_shader_gen.cpp35
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
322static void WriteLighting(std::string& out, const PicaShaderConfig& config) { 322static 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
439std::string GenerateFragmentShader(const PicaShaderConfig& config) { 456std::string GenerateFragmentShader(const PicaShaderConfig& config) {