diff options
| author | 2017-06-18 14:18:48 -0700 | |
|---|---|---|
| committer | 2017-06-18 14:18:48 -0700 | |
| commit | d0888f85485c4e064371e03f34facc1990553114 (patch) | |
| tree | 5d9e74c6197496fe90834c96d6c6580336538812 | |
| parent | Merge pull request #2785 from yuriks/compile-flags (diff) | |
| parent | gl_rasterizer/lighting: use the formula from the paper for germetic factor (diff) | |
| download | yuzu-d0888f85485c4e064371e03f34facc1990553114.tar.gz yuzu-d0888f85485c4e064371e03f34facc1990553114.tar.xz yuzu-d0888f85485c4e064371e03f34facc1990553114.zip | |
Merge pull request #2776 from wwylele/geo-factor
Fragment lighting: implement geometric factor
| -rw-r--r-- | src/video_core/regs_lighting.h | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_gen.cpp | 29 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_gen.h | 2 |
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; |