mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 05:19:56 +00:00
GPU: Normalize 0 to 1 always in software lighting.
See #14167. This seems to be consistent.
This commit is contained in:
parent
5d4d8ab418
commit
2f63f9999d
@ -17,6 +17,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include "Common/CPUDetect.h"
|
||||
#include "Common/Math/math_util.h"
|
||||
#include "Common/GPU/OpenGL/GLFeatures.h"
|
||||
|
||||
@ -266,7 +267,7 @@ void SoftwareTransform::Decode(int prim, u32 vertType, const DecVtxFormat &decVt
|
||||
normal = -normal;
|
||||
}
|
||||
Norm3ByMatrix43(worldnormal.AsArray(), normal.AsArray(), gstate.worldMatrix);
|
||||
worldnormal = worldnormal.Normalized();
|
||||
worldnormal = worldnormal.NormalizedOr001(cpu_info.bSSE4_1);
|
||||
}
|
||||
} else {
|
||||
float weights[8];
|
||||
@ -298,7 +299,7 @@ void SoftwareTransform::Decode(int prim, u32 vertType, const DecVtxFormat &decVt
|
||||
normal = -normal;
|
||||
}
|
||||
Norm3ByMatrix43(worldnormal.AsArray(), normal.AsArray(), gstate.worldMatrix);
|
||||
worldnormal = worldnormal.Normalized();
|
||||
worldnormal = worldnormal.NormalizedOr001(cpu_info.bSSE4_1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -358,7 +359,7 @@ void SoftwareTransform::Decode(int prim, u32 vertType, const DecVtxFormat &decVt
|
||||
break;
|
||||
|
||||
case GE_PROJMAP_NORMALIZED_NORMAL: // Use normalized normal as source
|
||||
source = normal.Normalized();
|
||||
source = normal.NormalizedOr001(cpu_info.bSSE4_1);
|
||||
if (!reader.hasNormal()) {
|
||||
ERROR_LOG_REPORT(G3D, "Normal projection mapping without normal?");
|
||||
}
|
||||
@ -391,11 +392,7 @@ void SoftwareTransform::Decode(int prim, u32 vertType, const DecVtxFormat &decVt
|
||||
};
|
||||
auto calcShadingLPos = [&](int l) {
|
||||
Vec3f pos = getLPos(l);
|
||||
if (pos.Length2() == 0.0f) {
|
||||
return Vec3f(0.0f, 0.0f, 1.0f);
|
||||
} else {
|
||||
return pos.Normalized();
|
||||
}
|
||||
return pos.NormalizedOr001(cpu_info.bSSE4_1);
|
||||
};
|
||||
// Might not have lighting enabled, so don't use lighter.
|
||||
Vec3f lightpos0 = calcShadingLPos(gstate.getUVLS0());
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "Common/CPUDetect.h"
|
||||
#include "GPU/GPUState.h"
|
||||
#include "GPU/Common/TransformCommon.h"
|
||||
|
||||
@ -140,7 +141,7 @@ void Lighter::Light(float colorOut0[4], float colorOut1[4], const float colorIn[
|
||||
case GE_LIGHTTYPE_SPOT:
|
||||
case GE_LIGHTTYPE_UNKNOWN:
|
||||
lightDir = Vec3Packedf(&ldir[l * 3]);
|
||||
angle = Dot(toLight.Normalized(), lightDir.Normalized());
|
||||
angle = Dot(toLight.NormalizedOr001(cpu_info.bSSE4_1), lightDir.NormalizedOr001(cpu_info.bSSE4_1));
|
||||
if (angle >= lcutoff[l])
|
||||
lightScale = clamp(1.0f / (latt[l * 3] + latt[l * 3 + 1] * distanceToLight + latt[l * 3 + 2] * distanceToLight*distanceToLight), 0.0f, 1.0f) * powf(angle, lconv[l]);
|
||||
break;
|
||||
@ -155,11 +156,10 @@ void Lighter::Light(float colorOut0[4], float colorOut1[4], const float colorIn[
|
||||
// Real PSP specular
|
||||
Vec3f toViewer(0, 0, 1);
|
||||
// Better specular
|
||||
// Vec3f toViewer = (viewer - pos).Normalized();
|
||||
// Vec3f toViewer = (viewer - pos).NormalizedOr001(cpu_info.bSSE4_1);
|
||||
|
||||
if (doSpecular) {
|
||||
Vec3f halfVec = (toLight + toViewer);
|
||||
halfVec.Normalize();
|
||||
Vec3f halfVec = (toLight + toViewer).NormalizedOr001(cpu_info.bSSE4_1);
|
||||
|
||||
dot = Dot(halfVec, norm);
|
||||
if (dot > 0.0f) {
|
||||
|
@ -138,12 +138,31 @@ Vec3<float> Vec3<float>::Normalized(bool useSSE4) const
|
||||
const __m128 normalize = SSENormalizeMultiplier(useSSE4, vec);
|
||||
return _mm_mul_ps(normalize, vec);
|
||||
}
|
||||
|
||||
template<>
|
||||
Vec3<float> Vec3<float>::NormalizedOr001(bool useSSE4) const {
|
||||
const __m128 normalize = SSENormalizeMultiplier(useSSE4, vec);
|
||||
const __m128 result = _mm_mul_ps(normalize, vec);
|
||||
const __m128 mask = _mm_cmpunord_ps(result, vec);
|
||||
const __m128 replace = _mm_and_ps(_mm_set_ps(0.0f, 1.0f, 0.0f, 0.0f), mask);
|
||||
// Replace with the constant if the mask matched.
|
||||
return _mm_or_ps(_mm_andnot_ps(mask, result), replace);
|
||||
}
|
||||
#else
|
||||
template<>
|
||||
Vec3<float> Vec3<float>::Normalized(bool useSSE4) const
|
||||
{
|
||||
return (*this) / Length();
|
||||
}
|
||||
|
||||
template<>
|
||||
Vec3<float> Vec3<float>::NormalizedOr001(bool useSSE4) const {
|
||||
float len = Length();
|
||||
if (len == 0.0f) {
|
||||
return Vec3<float>(0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
return *this / len;
|
||||
}
|
||||
#endif
|
||||
|
||||
template<>
|
||||
@ -154,6 +173,17 @@ float Vec3<float>::Normalize()
|
||||
return len;
|
||||
}
|
||||
|
||||
template<>
|
||||
float Vec3<float>::NormalizeOr001() {
|
||||
float len = Length();
|
||||
if (len == 0.0f) {
|
||||
z = 1.0f;
|
||||
} else {
|
||||
*this /= len;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
template<>
|
||||
Vec3Packed<float> Vec3Packed<float>::FromRGB(unsigned int rgb)
|
||||
{
|
||||
|
@ -297,7 +297,9 @@ public:
|
||||
Vec3 WithLength(const float l) const;
|
||||
float Distance2To(Vec3 &other);
|
||||
Vec3 Normalized(bool useSSE4 = false) const;
|
||||
Vec3 NormalizedOr001(bool useSSE4 = false) const;
|
||||
float Normalize(); // returns the previous length, which is often useful
|
||||
float NormalizeOr001();
|
||||
|
||||
T& operator [] (int i) //allow vector[2] = 3 (vector.z=3)
|
||||
{
|
||||
|
@ -15,9 +15,9 @@
|
||||
// Official git repository and contact information can be found at
|
||||
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
|
||||
|
||||
#include "../GPUState.h"
|
||||
|
||||
#include "Lighting.h"
|
||||
#include "Common/CPUDetect.h"
|
||||
#include "GPU/GPUState.h"
|
||||
#include "GPU/Software/Lighting.h"
|
||||
|
||||
namespace Lighting {
|
||||
|
||||
@ -53,7 +53,7 @@ void Process(VertexData& vertex, bool hasColor) {
|
||||
if (gstate.getUVGenMode() == GE_TEXMAP_ENVIRONMENT_MAP) {
|
||||
Vec3<float> L = GetLightVec(gstate.lpos, light);
|
||||
// In other words, L.Length2() == 0.0f means Dot({0, 0, 1}, worldnormal).
|
||||
float diffuse_factor = L.Length2() == 0.0f ? vertex.worldnormal.z : Dot(L.Normalized(), vertex.worldnormal);
|
||||
float diffuse_factor = Dot(L.NormalizedOr001(cpu_info.bSSE4_1), vertex.worldnormal);
|
||||
|
||||
if (gstate.getUVLS0() == (int)light)
|
||||
vertex.texturecoords.s() = (diffuse_factor + 1.f) / 2.f;
|
||||
@ -77,7 +77,7 @@ void Process(VertexData& vertex, bool hasColor) {
|
||||
L -= vertex.worldpos;
|
||||
}
|
||||
// TODO: Should this normalize (0, 0, 0) to (0, 0, 1)?
|
||||
float d = L.Normalize();
|
||||
float d = L.NormalizeOr001();
|
||||
|
||||
float att = 1.f;
|
||||
if (!gstate.isDirectionalLight(light)) {
|
||||
@ -89,7 +89,7 @@ void Process(VertexData& vertex, bool hasColor) {
|
||||
float spot = 1.f;
|
||||
if (gstate.isSpotLight(light)) {
|
||||
Vec3<float> dir = GetLightVec(gstate.ldir, light);
|
||||
float rawSpot = dir.Length2() == 0.0f ? 0.0f : Dot(dir.Normalized(), L);
|
||||
float rawSpot = Dot(dir.NormalizedOr001(cpu_info.bSSE4_1), L);
|
||||
float cutoff = getFloat24(gstate.lcutoff[light]);
|
||||
if (rawSpot >= cutoff) {
|
||||
float conv = getFloat24(gstate.lconv[light]);
|
||||
@ -123,7 +123,7 @@ void Process(VertexData& vertex, bool hasColor) {
|
||||
Vec3<float> lsc = Vec3<float>::FromRGB(gstate.getSpecularColor(light));
|
||||
Vec3<float> msc = (materialupdate & 4) ? vcol0 : Vec3<float>::FromRGB(gstate.getMaterialSpecular());
|
||||
|
||||
float specular_factor = Dot(H.Normalized(), vertex.worldnormal);
|
||||
float specular_factor = Dot(H.NormalizedOr001(cpu_info.bSSE4_1), vertex.worldnormal);
|
||||
float k = gstate.getMaterialSpecularCoef();
|
||||
specular_factor = pspLightPow(specular_factor, k);
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
|
||||
#include "Common/CPUDetect.h"
|
||||
#include "Common/Math/math_util.h"
|
||||
#include "Common/MemoryUtil.h"
|
||||
#include "Core/Config.h"
|
||||
@ -256,7 +257,7 @@ VertexData TransformUnit::ReadVertex(VertexReader& vreader)
|
||||
break;
|
||||
|
||||
case GE_PROJMAP_NORMALIZED_NORMAL:
|
||||
source = vertex.normal.Normalized();
|
||||
source = vertex.normal.NormalizedOr001(cpu_info.bSSE4_1);
|
||||
break;
|
||||
|
||||
case GE_PROJMAP_NORMAL:
|
||||
|
Loading…
Reference in New Issue
Block a user