summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Yuri Kunde Schlesner2017-06-18 14:18:48 -0700
committerGravatar GitHub2017-06-18 14:18:48 -0700
commitd0888f85485c4e064371e03f34facc1990553114 (patch)
tree5d9e74c6197496fe90834c96d6c6580336538812 /src
parentMerge pull request #2785 from yuriks/compile-flags (diff)
parentgl_rasterizer/lighting: use the formula from the paper for germetic factor (diff)
downloadyuzu-d0888f85485c4e064371e03f34facc1990553114.tar.gz
yuzu-d0888f85485c4e064371e03f34facc1990553114.tar.xz
yuzu-d0888f85485c4e064371e03f34facc1990553114.zip
Merge pull request #2776 from wwylele/geo-factor
Fragment lighting: implement geometric factor
Diffstat (limited to '')
-rw-r--r--src/video_core/regs_lighting.h2
-rw-r--r--src/video_core/renderer_opengl/gl_shader_gen.cpp29
-rw-r--r--src/video_core/renderer_opengl/gl_shader_gen.h2
3 files changed, 26 insertions, 7 deletions
diff --git a/src/video_core/regs_lighting.h b/src/video_core/regs_lighting.h
index f383b8b4f..7221d1688 100644
--- a/src/video_core/regs_lighting.h
+++ b/src/video_core/regs_lighting.h
@@ -168,6 +168,8 @@ struct LightingRegs {
168 union { 168 union {
169 BitField<0, 1, u32> directional; 169 BitField<0, 1, u32> directional;
170 BitField<1, 1, u32> two_sided_diffuse; // When disabled, clamp dot-product to 0 170 BitField<1, 1, u32> two_sided_diffuse; // When disabled, clamp dot-product to 0
171 BitField<2, 1, u32> geometric_factor_0;
172 BitField<3, 1, u32> geometric_factor_1;
171 } config; 173 } config;
172 174
173 BitField<0, 20, u32> dist_atten_bias; 175 BitField<0, 20, u32> dist_atten_bias;
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp
index 14be1201f..540cbb9d0 100644
--- a/src/video_core/renderer_opengl/gl_shader_gen.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp
@@ -73,6 +73,8 @@ PicaShaderConfig PicaShaderConfig::BuildFromRegs(const Pica::Regs& regs) {
73 state.lighting.light[light_index].num = num; 73 state.lighting.light[light_index].num = num;
74 state.lighting.light[light_index].directional = light.config.directional != 0; 74 state.lighting.light[light_index].directional = light.config.directional != 0;
75 state.lighting.light[light_index].two_sided_diffuse = light.config.two_sided_diffuse != 0; 75 state.lighting.light[light_index].two_sided_diffuse = light.config.two_sided_diffuse != 0;
76 state.lighting.light[light_index].geometric_factor_0 = light.config.geometric_factor_0 != 0;
77 state.lighting.light[light_index].geometric_factor_1 = light.config.geometric_factor_1 != 0;
76 state.lighting.light[light_index].dist_atten_enable = 78 state.lighting.light[light_index].dist_atten_enable =
77 !regs.lighting.IsDistAttenDisabled(num); 79 !regs.lighting.IsDistAttenDisabled(num);
78 state.lighting.light[light_index].spot_atten_enable = 80 state.lighting.light[light_index].spot_atten_enable =
@@ -518,7 +520,9 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) {
518 "vec4 specular_sum = vec4(0.0, 0.0, 0.0, 1.0);\n" 520 "vec4 specular_sum = vec4(0.0, 0.0, 0.0, 1.0);\n"
519 "vec3 light_vector = vec3(0.0);\n" 521 "vec3 light_vector = vec3(0.0);\n"
520 "vec3 refl_value = vec3(0.0);\n" 522 "vec3 refl_value = vec3(0.0);\n"
521 "vec3 spot_dir = vec3(0.0);\n;"; 523 "vec3 spot_dir = vec3(0.0);\n"
524 "vec3 half_vector = vec3(0.0);\n"
525 "float geo_factor = 1.0;\n";
522 526
523 // Compute fragment normals and tangents 527 // Compute fragment normals and tangents
524 const std::string pertubation = 528 const std::string pertubation =
@@ -561,15 +565,14 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) {
561 // Gets the index into the specified lookup table for specular lighting 565 // Gets the index into the specified lookup table for specular lighting
562 auto GetLutIndex = [&lighting](unsigned light_num, LightingRegs::LightingLutInput input, 566 auto GetLutIndex = [&lighting](unsigned light_num, LightingRegs::LightingLutInput input,
563 bool abs) { 567 bool abs) {
564 const std::string half_angle = "normalize(normalize(view) + light_vector)";
565 std::string index; 568 std::string index;
566 switch (input) { 569 switch (input) {
567 case LightingRegs::LightingLutInput::NH: 570 case LightingRegs::LightingLutInput::NH:
568 index = "dot(normal, " + half_angle + ")"; 571 index = "dot(normal, normalize(half_vector))";
569 break; 572 break;
570 573
571 case LightingRegs::LightingLutInput::VH: 574 case LightingRegs::LightingLutInput::VH:
572 index = std::string("dot(normalize(view), " + half_angle + ")"); 575 index = std::string("dot(normalize(view), normalize(half_vector))");
573 break; 576 break;
574 577
575 case LightingRegs::LightingLutInput::NV: 578 case LightingRegs::LightingLutInput::NV:
@@ -590,9 +593,8 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) {
590 // Note: even if the normal vector is modified by normal map, which is not the 593 // Note: even if the normal vector is modified by normal map, which is not the
591 // normal of the tangent plane anymore, the half angle vector is still projected 594 // normal of the tangent plane anymore, the half angle vector is still projected
592 // using the modified normal vector. 595 // using the modified normal vector.
593 std::string half_angle_proj = half_angle + 596 std::string half_angle_proj = "normalize(half_vector) - normal / dot(normal, "
594 " - normal / dot(normal, normal) * dot(normal, " + 597 "normal) * dot(normal, normalize(half_vector))";
595 half_angle + ")";
596 // Note: the half angle vector projection is confirmed not normalized before the dot 598 // Note: the half angle vector projection is confirmed not normalized before the dot
597 // product. The result is in fact not cos(phi) as the name suggested. 599 // product. The result is in fact not cos(phi) as the name suggested.
598 index = "dot(" + half_angle_proj + ", tangent)"; 600 index = "dot(" + half_angle_proj + ", tangent)";
@@ -638,6 +640,7 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) {
638 out += "light_vector = normalize(" + light_src + ".position + view);\n"; 640 out += "light_vector = normalize(" + light_src + ".position + view);\n";
639 641
640 out += "spot_dir = " + light_src + ".spot_direction;\n"; 642 out += "spot_dir = " + light_src + ".spot_direction;\n";
643 out += "half_vector = normalize(view) + light_vector;\n";
641 644
642 // Compute dot product of light_vector and normal, adjust if lighting is one-sided or 645 // Compute dot product of light_vector and normal, adjust if lighting is one-sided or
643 // two-sided 646 // two-sided
@@ -671,6 +674,12 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) {
671 std::string clamp_highlights = 674 std::string clamp_highlights =
672 lighting.clamp_highlights ? "(dot(light_vector, normal) <= 0.0 ? 0.0 : 1.0)" : "1.0"; 675 lighting.clamp_highlights ? "(dot(light_vector, normal) <= 0.0 ? 0.0 : 1.0)" : "1.0";
673 676
677 if (light_config.geometric_factor_0 || light_config.geometric_factor_1) {
678 out += "geo_factor = dot(half_vector, half_vector);\n"
679 "geo_factor = geo_factor == 0.0 ? 0.0 : min(" +
680 dot_product + " / geo_factor, 1.0);\n";
681 }
682
674 // Specular 0 component 683 // Specular 0 component
675 std::string d0_lut_value = "1.0"; 684 std::string d0_lut_value = "1.0";
676 if (lighting.lut_d0.enable && 685 if (lighting.lut_d0.enable &&
@@ -683,6 +692,9 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) {
683 GetLutValue(LightingRegs::LightingSampler::Distribution0, index) + ")"; 692 GetLutValue(LightingRegs::LightingSampler::Distribution0, index) + ")";
684 } 693 }
685 std::string specular_0 = "(" + d0_lut_value + " * " + light_src + ".specular_0)"; 694 std::string specular_0 = "(" + d0_lut_value + " * " + light_src + ".specular_0)";
695 if (light_config.geometric_factor_0) {
696 specular_0 = "(" + specular_0 + " * geo_factor)";
697 }
686 698
687 // If enabled, lookup ReflectRed value, otherwise, 1.0 is used 699 // If enabled, lookup ReflectRed value, otherwise, 1.0 is used
688 if (lighting.lut_rr.enable && 700 if (lighting.lut_rr.enable &&
@@ -738,6 +750,9 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) {
738 } 750 }
739 std::string specular_1 = 751 std::string specular_1 =
740 "(" + d1_lut_value + " * refl_value * " + light_src + ".specular_1)"; 752 "(" + d1_lut_value + " * refl_value * " + light_src + ".specular_1)";
753 if (light_config.geometric_factor_1) {
754 specular_1 = "(" + specular_1 + " * geo_factor)";
755 }
741 756
742 // Fresnel 757 // Fresnel
743 if (lighting.lut_fr.enable && 758 if (lighting.lut_fr.enable &&
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.h b/src/video_core/renderer_opengl/gl_shader_gen.h
index 9c90eadf9..2302ae453 100644
--- a/src/video_core/renderer_opengl/gl_shader_gen.h
+++ b/src/video_core/renderer_opengl/gl_shader_gen.h
@@ -94,6 +94,8 @@ union PicaShaderConfig {
94 bool two_sided_diffuse; 94 bool two_sided_diffuse;
95 bool dist_atten_enable; 95 bool dist_atten_enable;
96 bool spot_atten_enable; 96 bool spot_atten_enable;
97 bool geometric_factor_0;
98 bool geometric_factor_1;
97 } light[8]; 99 } light[8];
98 100
99 bool enable; 101 bool enable;