diff options
| author | wwylele <wwylele@gmail.com> | 2017-05-25 21:13:33 +0300 | 
|---|---|---|
| committer | wwylele <wwylele@gmail.com> | 2017-06-11 21:30:53 +0300 | 
| commit | 40b7d0bf3f7bf4f29c1866231a79e0a751e30274 (patch) | |
| tree | 7f5eb14962979041c168f3c00a88e27d3f98c2d6 | |
| parent | 39c7c1f580a1c40a12e65b6c9c65215826e73efb (diff) | |
gl_rasterizer/lighting: implement lut input 5 (CP)
| -rw-r--r-- | src/video_core/regs_lighting.h | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_gen.cpp | 27 | 
2 files changed, 26 insertions, 3 deletions
diff --git a/src/video_core/regs_lighting.h b/src/video_core/regs_lighting.h index fbfebc0a7..f383b8b4f 100644 --- a/src/video_core/regs_lighting.h +++ b/src/video_core/regs_lighting.h @@ -84,7 +84,7 @@ struct LightingRegs {          NV = 2, // Cosine of the angle between the normal and the view vector          LN = 3, // Cosine of the angle between the light and the normal vectors          SP = 4, // Cosine of the angle between the light and the inverse spotlight vectors -        CP = 5, // TODO: document and implement +        CP = 5, // Cosine of the angle between the tangent and projection of half-angle vectors      };      enum class LightingBumpMode : u32 { diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index db53710aa..89977a62b 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp @@ -534,18 +534,24 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) {                  "(1.0 - (surface_normal.x*surface_normal.x + surface_normal.y*surface_normal.y))";              out += "surface_normal.z = sqrt(max(" + val + ", 0.0));\n";          } + +        // The tangent vector is not perturbed by the normal map and is just a unit vector. +        out += "vec3 surface_tangent = vec3(1.0, 0.0, 0.0);\n";      } else if (lighting.bump_mode == LightingRegs::LightingBumpMode::TangentMap) {          // Bump mapping is enabled using a tangent map          LOG_CRITICAL(HW_GPU, "unimplemented bump mapping mode (tangent mapping)");          UNIMPLEMENTED();      } else { -        // No bump mapping - surface local normal is just a unit normal +        // No bump mapping - surface local normal and tangent are just unit vectors          out += "vec3 surface_normal = vec3(0.0, 0.0, 1.0);\n"; +        out += "vec3 surface_tangent = vec3(1.0, 0.0, 0.0);\n";      }      // Rotate the surface-local normal by the interpolated normal quaternion to convert it to      // eyespace. -    out += "vec3 normal = quaternion_rotate(normalize(normquat), surface_normal);\n"; +    out += "vec4 normalized_normquat = normalize(normquat);\n"; +    out += "vec3 normal = quaternion_rotate(normalized_normquat, surface_normal);\n"; +    out += "vec3 tangent = quaternion_rotate(normalized_normquat, surface_tangent);\n";      // Gets the index into the specified lookup table for specular lighting      auto GetLutIndex = [&lighting](unsigned light_num, LightingRegs::LightingLutInput input, @@ -573,6 +579,23 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) {              index = std::string("dot(light_vector, spot_dir)");              break; +        case LightingRegs::LightingLutInput::CP: +            // CP input is only available with configuration 7 +            if (lighting.config == LightingRegs::LightingConfig::Config7) { +                // Note: even if the normal vector is modified by normal map, which is not the +                // normal of the tangent plane anymore, the half angle vector is still projected +                // using the modified normal vector. +                std::string half_angle_proj = half_angle + +                                              " - normal / dot(normal, normal) * dot(normal, " + +                                              half_angle + ")"; +                // Note: the half angle vector projection is confirmed not normalized before the dot +                // product. The result is in fact not cos(phi) as the name suggested. +                index = "dot(" + half_angle_proj + ", tangent)"; +            } else { +                index = "0.0"; +            } +            break; +          default:              LOG_CRITICAL(HW_GPU, "Unknown lighting LUT input %d\n", (int)input);              UNIMPLEMENTED();  | 
