summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Subv2017-06-09 17:33:25 -0500
committerGravatar wwylele2017-07-11 19:39:15 +0300
commitf2d4d5c2191275bd91f2f42b880f3edf3bccfd63 (patch)
tree50e8bfcd9f9873ee6d8ba5174e9f45e942c30173 /src
parentSwRasterizer: Fixed the lighting lut lookup function. (diff)
downloadyuzu-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.h5
-rw-r--r--src/video_core/swrasterizer/rasterizer.cpp76
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
35template <typename T> 40template <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 118float LookupLightingLut(size_t lut_index, u8 index, float delta) {
119float 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
134std::tuple<Math::Vec4<u8>, Math::Vec4<u8>> ComputeFragmentsColors(const Math::Quaternion<float>& normquat, const Math::Vec3<float>& view) { 128std::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 ||