diff options
-rw-r--r-- | src/video_core/swrasterizer/lighting.cpp | 28 | ||||
-rw-r--r-- | src/video_core/swrasterizer/lighting.h | 3 | ||||
-rw-r--r-- | src/video_core/swrasterizer/rasterizer.cpp | 4 |
3 files changed, 27 insertions, 8 deletions
diff --git a/src/video_core/swrasterizer/lighting.cpp b/src/video_core/swrasterizer/lighting.cpp index 39a3e396d..4f16bac07 100644 --- a/src/video_core/swrasterizer/lighting.cpp +++ b/src/video_core/swrasterizer/lighting.cpp @@ -22,14 +22,32 @@ static float LookupLightingLut(const Pica::State::Lighting& lighting, size_t lut std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors( const Pica::LightingRegs& lighting, const Pica::State::Lighting& lighting_state, - const Math::Quaternion<float>& normquat, const Math::Vec3<float>& view) { + const Math::Quaternion<float>& normquat, const Math::Vec3<float>& view, + const Math::Vec4<u8> (&texture_color)[4]) { - // TODO(Subv): Bump mapping - Math::Vec3<float> surface_normal = {0.0f, 0.0f, 1.0f}; + Math::Vec3<float> surface_normal; + Math::Vec3<float> surface_tangent; if (lighting.config0.bump_mode != LightingRegs::LightingBumpMode::None) { - LOG_CRITICAL(HW_GPU, "unimplemented bump mapping"); - UNIMPLEMENTED(); + Math::Vec3<float> perturbation = + texture_color[lighting.config0.bump_selector].xyz().Cast<float>() / 127.5f - + Math::MakeVec(1.0f, 1.0f, 1.0f); + if (lighting.config0.bump_mode == LightingRegs::LightingBumpMode::NormalMap) { + if (!lighting.config0.disable_bump_renorm) { + const float z_square = 1 - perturbation.xy().Length2(); + perturbation.z = std::sqrt(std::max(z_square, 0.0f)); + } + surface_normal = perturbation; + surface_tangent = Math::MakeVec(1.0f, 0.0f, 0.0f); + } else if (lighting.config0.bump_mode == LightingRegs::LightingBumpMode::TangentMap) { + surface_normal = Math::MakeVec(0.0f, 0.0f, 1.0f); + surface_tangent = perturbation; + } else { + LOG_ERROR(HW_GPU, "Unknown bump mode %u", lighting.config0.bump_mode.Value()); + } + } else { + surface_normal = Math::MakeVec(0.0f, 0.0f, 1.0f); + surface_tangent = Math::MakeVec(1.0f, 0.0f, 0.0f); } // Use the normalized the quaternion when performing the rotation diff --git a/src/video_core/swrasterizer/lighting.h b/src/video_core/swrasterizer/lighting.h index 438dca926..d807a3d94 100644 --- a/src/video_core/swrasterizer/lighting.h +++ b/src/video_core/swrasterizer/lighting.h @@ -13,6 +13,7 @@ namespace Pica { std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors( const Pica::LightingRegs& lighting, const Pica::State::Lighting& lighting_state, - const Math::Quaternion<float>& normquat, const Math::Vec3<float>& view); + const Math::Quaternion<float>& normquat, const Math::Vec3<float>& view, + const Math::Vec4<u8> (&texture_color)[4]); } // namespace Pica diff --git a/src/video_core/swrasterizer/rasterizer.cpp b/src/video_core/swrasterizer/rasterizer.cpp index fdc1df199..862135614 100644 --- a/src/video_core/swrasterizer/rasterizer.cpp +++ b/src/video_core/swrasterizer/rasterizer.cpp @@ -437,8 +437,8 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve GetInterpolatedAttribute(v0.view.y, v1.view.y, v2.view.y).ToFloat32(), GetInterpolatedAttribute(v0.view.z, v1.view.z, v2.view.z).ToFloat32(), }; - std::tie(primary_fragment_color, secondary_fragment_color) = - ComputeFragmentsColors(g_state.regs.lighting, g_state.lighting, normquat, view); + std::tie(primary_fragment_color, secondary_fragment_color) = ComputeFragmentsColors( + g_state.regs.lighting, g_state.lighting, normquat, view, texture_color); } for (unsigned tev_stage_index = 0; tev_stage_index < tev_stages.size(); |