diff options
| author | wwylele <wwylele@gmail.com> | 2017-08-18 15:04:56 +0300 | 
|---|---|---|
| committer | wwylele <wwylele@gmail.com> | 2017-08-22 09:34:44 +0300 | 
| commit | 3e478ca13110639a67ad95880aae5d7d13e096b7 (patch) | |
| tree | 6d6c4bbada2738e20ff7ba3d895443214fecffca /src/video_core | |
| parent | 46d1ca768d9ee2856b663ee68c8d7fdd7b160a7e (diff) | |
SwRasterizer/Lighting: implement bump mapping
Diffstat (limited to 'src/video_core')
| -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(); | 
