diff options
| author | 2017-06-09 17:33:25 -0500 | |
|---|---|---|
| committer | 2017-07-11 19:39:15 +0300 | |
| commit | f2d4d5c2191275bd91f2f42b880f3edf3bccfd63 (patch) | |
| tree | 50e8bfcd9f9873ee6d8ba5174e9f45e942c30173 /src | |
| parent | SwRasterizer: Fixed the lighting lut lookup function. (diff) | |
| download | yuzu-f2d4d5c2191275bd91f2f42b880f3edf3bccfd63.tar.gz yuzu-f2d4d5c2191275bd91f2f42b880f3edf3bccfd63.tar.xz yuzu-f2d4d5c2191275bd91f2f42b880f3edf3bccfd63.zip | |
SwRasterizer: Corrected the light LUT lookups.
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/quaternion.h | 5 | ||||
| -rw-r--r-- | src/video_core/swrasterizer/rasterizer.cpp | 76 |
2 files changed, 48 insertions, 33 deletions
diff --git a/src/common/quaternion.h b/src/common/quaternion.h index 84ac82ed3..77f626bcb 100644 --- a/src/common/quaternion.h +++ b/src/common/quaternion.h | |||
| @@ -30,6 +30,11 @@ public: | |||
| 30 | return {xyz * other.w + other.xyz * w + Cross(xyz, other.xyz), | 30 | return {xyz * other.w + other.xyz * w + Cross(xyz, other.xyz), |
| 31 | w * other.w - Dot(xyz, other.xyz)}; | 31 | w * other.w - Dot(xyz, other.xyz)}; |
| 32 | } | 32 | } |
| 33 | |||
| 34 | Quaternion<T> Normalized() const { | ||
| 35 | T length = std::sqrt(xyz.Length2() + w * w); | ||
| 36 | return {xyz / length, w / length}; | ||
| 37 | } | ||
| 33 | }; | 38 | }; |
| 34 | 39 | ||
| 35 | template <typename T> | 40 | template <typename T> |
diff --git a/src/video_core/swrasterizer/rasterizer.cpp b/src/video_core/swrasterizer/rasterizer.cpp index 2b85ac86c..a9098e1f0 100644 --- a/src/video_core/swrasterizer/rasterizer.cpp +++ b/src/video_core/swrasterizer/rasterizer.cpp | |||
| @@ -115,20 +115,14 @@ static std::tuple<float24, float24, PAddr> ConvertCubeCoord(float24 u, float24 v | |||
| 115 | return std::make_tuple(x / z * half + half, y / z * half + half, addr); | 115 | return std::make_tuple(x / z * half + half, y / z * half + half, addr); |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | 118 | float LookupLightingLut(size_t lut_index, u8 index, float delta) { | |
| 119 | float LookupLightingLut(size_t lut_index, float index) { | ||
| 120 | index *= 256; | ||
| 121 | |||
| 122 | unsigned index_i = static_cast<unsigned>(MathUtil::Clamp(floor(index), 0.0f, 255.0f)); | ||
| 123 | |||
| 124 | float index_f = index - index_i; | ||
| 125 | |||
| 126 | ASSERT_MSG(lut_index < g_state.lighting.luts.size(), "Out of range lut"); | 119 | ASSERT_MSG(lut_index < g_state.lighting.luts.size(), "Out of range lut"); |
| 120 | ASSERT_MSG(index < g_state.lighting.luts[0].size(), "Out of range index"); | ||
| 127 | 121 | ||
| 128 | float lut_value = g_state.lighting.luts[lut_index][index_i].ToFloat(); | 122 | float lut_value = g_state.lighting.luts[lut_index][index].ToFloat(); |
| 129 | float lut_diff = g_state.lighting.luts[lut_index][index_i].DiffToFloat(); | 123 | float lut_diff = g_state.lighting.luts[lut_index][index].DiffToFloat(); |
| 130 | 124 | ||
| 131 | return lut_value + lut_diff * index_f / 256.f; | 125 | return lut_value + lut_diff * delta; |
| 132 | } | 126 | } |
| 133 | 127 | ||
| 134 | std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(const Math::Quaternion<float>& normquat, const Math::Vec3<float>& view) { | 128 | std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(const Math::Quaternion<float>& normquat, const Math::Vec3<float>& view) { |
| @@ -145,8 +139,8 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(const Math::Qu | |||
| 145 | UNIMPLEMENTED(); | 139 | UNIMPLEMENTED(); |
| 146 | } | 140 | } |
| 147 | 141 | ||
| 148 | // TODO(Subv): Do we need to normalize the quaternion here? | 142 | // Use the normalized the quaternion when performing the rotation |
| 149 | auto normal = Math::QuaternionRotate(normquat, surface_normal); | 143 | auto normal = Math::QuaternionRotate(normquat.Normalized(), surface_normal); |
| 150 | 144 | ||
| 151 | Math::Vec3<float> light_vector = {}; | 145 | Math::Vec3<float> light_vector = {}; |
| 152 | Math::Vec4<float> diffuse_sum = {0.f, 0.f, 0.f, 1.f}; | 146 | Math::Vec4<float> diffuse_sum = {0.f, 0.f, 0.f, 1.f}; |
| @@ -182,7 +176,10 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(const Math::Qu | |||
| 182 | size_t lut = static_cast<size_t>(LightingRegs::LightingSampler::DistanceAttenuation) + num; | 176 | size_t lut = static_cast<size_t>(LightingRegs::LightingSampler::DistanceAttenuation) + num; |
| 183 | 177 | ||
| 184 | float sample_loc = scale * distance + bias; | 178 | float sample_loc = scale * distance + bias; |
| 185 | dist_atten = LookupLightingLut(lut, sample_loc); | 179 | |
| 180 | u8 lutindex = MathUtil::Clamp(floorf(sample_loc * 256.f), 0.0f, 255.0f); | ||
| 181 | float delta = sample_loc * 256 - lutindex; | ||
| 182 | dist_atten = LookupLightingLut(lut, lutindex, delta / 256.f); | ||
| 186 | } | 183 | } |
| 187 | 184 | ||
| 188 | float clamp_highlights = 1.0f; | 185 | float clamp_highlights = 1.0f; |
| @@ -195,7 +192,7 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(const Math::Qu | |||
| 195 | } | 192 | } |
| 196 | 193 | ||
| 197 | auto GetLutIndex = [&](unsigned num, LightingRegs::LightingLutInput input, | 194 | auto GetLutIndex = [&](unsigned num, LightingRegs::LightingLutInput input, |
| 198 | bool abs) -> float { | 195 | bool abs) -> std::tuple<u8, float> { |
| 199 | 196 | ||
| 200 | Math::Vec3<float> norm_view = view.Normalized(); | 197 | Math::Vec3<float> norm_view = view.Normalized(); |
| 201 | Math::Vec3<float> half_angle = (norm_view + light_vector).Normalized(); | 198 | Math::Vec3<float> half_angle = (norm_view + light_vector).Normalized(); |
| @@ -229,14 +226,15 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(const Math::Qu | |||
| 229 | result = std::abs(result); | 226 | result = std::abs(result); |
| 230 | else | 227 | else |
| 231 | result = std::max(result, 0.0f); | 228 | result = std::max(result, 0.0f); |
| 232 | } else { | ||
| 233 | if (result < 0.f) | ||
| 234 | result += 2.f; | ||
| 235 | 229 | ||
| 236 | result /= 2.f; | 230 | u8 lutindex = MathUtil::Clamp(floorf(result * 256.f), 0.0f, 255.0f); |
| 231 | float delta = result * 256 - lutindex; | ||
| 232 | return { lutindex, delta / 256.f }; | ||
| 233 | } else { | ||
| 234 | u8 tmpi = MathUtil::Clamp(floorf(result * 128.f), 0.0f, 127.0f); | ||
| 235 | float delta = result * 128.f - tmpi; | ||
| 236 | return { tmpi & 0xFF, delta / 128.f }; | ||
| 237 | } | 237 | } |
| 238 | |||
| 239 | return MathUtil::Clamp(result, 0.0f, 1.0f); | ||
| 240 | }; | 238 | }; |
| 241 | 239 | ||
| 242 | // Specular 0 component | 240 | // Specular 0 component |
| @@ -246,11 +244,13 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(const Math::Qu | |||
| 246 | lighting.config0.config, LightingRegs::LightingSampler::Distribution0)) { | 244 | lighting.config0.config, LightingRegs::LightingSampler::Distribution0)) { |
| 247 | 245 | ||
| 248 | // Lookup specular "distribution 0" LUT value | 246 | // Lookup specular "distribution 0" LUT value |
| 249 | float index = GetLutIndex(num, lighting.lut_input.d0.Value(), lighting.abs_lut_input.disable_d0 == 0); | 247 | u8 index; |
| 248 | float delta; | ||
| 249 | std::tie(index, delta) = GetLutIndex(num, lighting.lut_input.d0.Value(), lighting.abs_lut_input.disable_d0 == 0); | ||
| 250 | 250 | ||
| 251 | float scale = lighting.lut_scale.GetScale(lighting.lut_scale.d0); | 251 | float scale = lighting.lut_scale.GetScale(lighting.lut_scale.d0); |
| 252 | 252 | ||
| 253 | d0_lut_value = scale * LookupLightingLut(static_cast<size_t>(LightingRegs::LightingSampler::Distribution0), index); | 253 | d0_lut_value = scale * LookupLightingLut(static_cast<size_t>(LightingRegs::LightingSampler::Distribution0), index, delta); |
| 254 | } | 254 | } |
| 255 | 255 | ||
| 256 | Math::Vec3<float> specular_0 = d0_lut_value * light_config.specular_0.ToVec3f(); | 256 | Math::Vec3<float> specular_0 = d0_lut_value * light_config.specular_0.ToVec3f(); |
| @@ -260,11 +260,13 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(const Math::Qu | |||
| 260 | LightingRegs::IsLightingSamplerSupported(lighting.config0.config, | 260 | LightingRegs::IsLightingSamplerSupported(lighting.config0.config, |
| 261 | LightingRegs::LightingSampler::ReflectRed)) { | 261 | LightingRegs::LightingSampler::ReflectRed)) { |
| 262 | 262 | ||
| 263 | float index = GetLutIndex(num, lighting.lut_input.rr, lighting.abs_lut_input.disable_rr == 0); | 263 | u8 index; |
| 264 | float delta; | ||
| 265 | std::tie(index, delta) = GetLutIndex(num, lighting.lut_input.rr, lighting.abs_lut_input.disable_rr == 0); | ||
| 264 | 266 | ||
| 265 | float scale = lighting.lut_scale.GetScale(lighting.lut_scale.rr); | 267 | float scale = lighting.lut_scale.GetScale(lighting.lut_scale.rr); |
| 266 | 268 | ||
| 267 | refl_value.x = scale * LookupLightingLut(static_cast<size_t>(LightingRegs::LightingSampler::ReflectRed), index); | 269 | refl_value.x = scale * LookupLightingLut(static_cast<size_t>(LightingRegs::LightingSampler::ReflectRed), index, delta); |
| 268 | } else { | 270 | } else { |
| 269 | refl_value.x = 1.0f; | 271 | refl_value.x = 1.0f; |
| 270 | } | 272 | } |
| @@ -274,11 +276,13 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(const Math::Qu | |||
| 274 | LightingRegs::IsLightingSamplerSupported(lighting.config0.config, | 276 | LightingRegs::IsLightingSamplerSupported(lighting.config0.config, |
| 275 | LightingRegs::LightingSampler::ReflectGreen)) { | 277 | LightingRegs::LightingSampler::ReflectGreen)) { |
| 276 | 278 | ||
| 277 | float index = GetLutIndex(num, lighting.lut_input.rg, lighting.abs_lut_input.disable_rg == 0); | 279 | u8 index; |
| 280 | float delta; | ||
| 281 | std::tie(index, delta) = GetLutIndex(num, lighting.lut_input.rg, lighting.abs_lut_input.disable_rg == 0); | ||
| 278 | 282 | ||
| 279 | float scale = lighting.lut_scale.GetScale(lighting.lut_scale.rg); | 283 | float scale = lighting.lut_scale.GetScale(lighting.lut_scale.rg); |
| 280 | 284 | ||
| 281 | refl_value.y = scale * LookupLightingLut(static_cast<size_t>(LightingRegs::LightingSampler::ReflectGreen), index); | 285 | refl_value.y = scale * LookupLightingLut(static_cast<size_t>(LightingRegs::LightingSampler::ReflectGreen), index, delta); |
| 282 | } else { | 286 | } else { |
| 283 | refl_value.y = refl_value.x; | 287 | refl_value.y = refl_value.x; |
| 284 | } | 288 | } |
| @@ -288,11 +292,13 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(const Math::Qu | |||
| 288 | LightingRegs::IsLightingSamplerSupported(lighting.config0.config, | 292 | LightingRegs::IsLightingSamplerSupported(lighting.config0.config, |
| 289 | LightingRegs::LightingSampler::ReflectBlue)) { | 293 | LightingRegs::LightingSampler::ReflectBlue)) { |
| 290 | 294 | ||
| 291 | float index = GetLutIndex(num, lighting.lut_input.rb, lighting.abs_lut_input.disable_rb == 0); | 295 | u8 index; |
| 296 | float delta; | ||
| 297 | std::tie(index, delta) = GetLutIndex(num, lighting.lut_input.rb, lighting.abs_lut_input.disable_rb == 0); | ||
| 292 | 298 | ||
| 293 | float scale = lighting.lut_scale.GetScale(lighting.lut_scale.rb); | 299 | float scale = lighting.lut_scale.GetScale(lighting.lut_scale.rb); |
| 294 | 300 | ||
| 295 | refl_value.z = scale * LookupLightingLut(static_cast<size_t>(LightingRegs::LightingSampler::ReflectBlue), index); | 301 | refl_value.z = scale * LookupLightingLut(static_cast<size_t>(LightingRegs::LightingSampler::ReflectBlue), index, delta); |
| 296 | } else { | 302 | } else { |
| 297 | refl_value.z = refl_value.x; | 303 | refl_value.z = refl_value.x; |
| 298 | } | 304 | } |
| @@ -303,11 +309,13 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(const Math::Qu | |||
| 303 | lighting.config0.config, LightingRegs::LightingSampler::Distribution1)) { | 309 | lighting.config0.config, LightingRegs::LightingSampler::Distribution1)) { |
| 304 | 310 | ||
| 305 | // Lookup specular "distribution 1" LUT value | 311 | // Lookup specular "distribution 1" LUT value |
| 306 | float index = GetLutIndex(num, lighting.lut_input.d1.Value(), lighting.abs_lut_input.disable_d1 == 0); | 312 | u8 index; |
| 313 | float delta; | ||
| 314 | std::tie(index, delta) = GetLutIndex(num, lighting.lut_input.d1.Value(), lighting.abs_lut_input.disable_d1 == 0); | ||
| 307 | 315 | ||
| 308 | float scale = lighting.lut_scale.GetScale(lighting.lut_scale.d1); | 316 | float scale = lighting.lut_scale.GetScale(lighting.lut_scale.d1); |
| 309 | 317 | ||
| 310 | d1_lut_value = scale * LookupLightingLut(static_cast<size_t>(LightingRegs::LightingSampler::Distribution1), index); | 318 | d1_lut_value = scale * LookupLightingLut(static_cast<size_t>(LightingRegs::LightingSampler::Distribution1), index, delta); |
| 311 | } | 319 | } |
| 312 | 320 | ||
| 313 | Math::Vec3<float> specular_1 = d1_lut_value * refl_value * light_config.specular_1.ToVec3f(); | 321 | Math::Vec3<float> specular_1 = d1_lut_value * refl_value * light_config.specular_1.ToVec3f(); |
| @@ -317,11 +325,13 @@ std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(const Math::Qu | |||
| 317 | lighting.config0.config, LightingRegs::LightingSampler::Fresnel)) { | 325 | lighting.config0.config, LightingRegs::LightingSampler::Fresnel)) { |
| 318 | 326 | ||
| 319 | // Lookup fresnel LUT value | 327 | // Lookup fresnel LUT value |
| 320 | float index = GetLutIndex(num, lighting.lut_input.fr.Value(), lighting.abs_lut_input.disable_fr == 0); | 328 | u8 index; |
| 329 | float delta; | ||
| 330 | std::tie(index, delta) = GetLutIndex(num, lighting.lut_input.fr.Value(), lighting.abs_lut_input.disable_fr == 0); | ||
| 321 | 331 | ||
| 322 | float scale = lighting.lut_scale.GetScale(lighting.lut_scale.fr); | 332 | float scale = lighting.lut_scale.GetScale(lighting.lut_scale.fr); |
| 323 | 333 | ||
| 324 | float lut_value = scale * LookupLightingLut(static_cast<size_t>(LightingRegs::LightingSampler::Fresnel), index); | 334 | float lut_value = scale * LookupLightingLut(static_cast<size_t>(LightingRegs::LightingSampler::Fresnel), index, delta); |
| 325 | 335 | ||
| 326 | // Enabled for difffuse lighting alpha component | 336 | // Enabled for difffuse lighting alpha component |
| 327 | if (lighting.config0.fresnel_selector == LightingRegs::LightingFresnelSelector::PrimaryAlpha || | 337 | if (lighting.config0.fresnel_selector == LightingRegs::LightingFresnelSelector::PrimaryAlpha || |