summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/pica.h18
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h18
-rw-r--r--src/video_core/renderer_opengl/gl_shader_gen.cpp62
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
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 += "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