softgpu: Correct accuracy of fog calculation.

This matches values from a PSP exactly, with the help of immediate mode
vertex values (since this directly allows specifying the fog factor
without any floating point math.)
This commit is contained in:
Unknown W. Brackets 2022-09-11 08:24:40 -07:00
parent 2e3b73abaa
commit b90fc7137f
3 changed files with 11 additions and 9 deletions

View file

@ -228,11 +228,11 @@ public:
Vec3() {}
Vec3(const T a[3]) : x(a[0]), y(a[1]), z(a[2]) {}
Vec3(const T& _x, const T& _y, const T& _z) : x(_x), y(_y), z(_z) {}
constexpr Vec3(const T& _x, const T& _y, const T& _z) : x(_x), y(_y), z(_z) {}
Vec3(const Vec2<T>& _xy, const T& _z) : x(_xy.x), y(_xy.y), z(_z) {}
#if defined(_M_SSE)
Vec3(const __m128 &_vec) : vec(_vec) {}
Vec3(const __m128i &_ivec) : ivec(_ivec) {}
constexpr Vec3(const __m128 &_vec) : vec(_vec) {}
constexpr Vec3(const __m128i &_ivec) : ivec(_ivec) {}
Vec3(const Vec3Packed<T> &_xyz) {
vec = _mm_loadu_ps(_xyz.AsArray());
}
@ -249,7 +249,7 @@ public:
#endif
template<typename T2>
Vec3<T2> Cast() const
constexpr Vec3<T2> Cast() const
{
return Vec3<T2>((T2)x, (T2)y, (T2)z);
}
@ -258,7 +258,7 @@ public:
static Vec3 FromRGB(unsigned int rgb);
unsigned int ToRGB() const; // alpha bits set to zero
static Vec3 AssignToAll(const T& f)
static constexpr Vec3 AssignToAll(const T& f)
{
return Vec3<T>(f, f, f);
}

View file

@ -415,7 +415,9 @@ void SOFTRAST_CALL DrawSinglePixel(int x, int y, int z, int fog, Vec4IntArg colo
// Fog is applied prior to color test.
if (pixelID.applyFog && !clearMode) {
Vec3<int> fogColor = Vec3<int>::FromRGB(pixelID.cached.fogColor);
fogColor = (prim_color.rgb() * fog + fogColor * (255 - fog)) / 255;
// This is very similar to the BLEND texfunc, and simply always rounds up.
static constexpr Vec3<int> roundup = Vec3<int>::AssignToAll(255);
fogColor = (prim_color.rgb() * fog + fogColor * (255 - fog) + roundup) / 256;
prim_color.r() = fogColor.r();
prim_color.g() = fogColor.g();
prim_color.b() = fogColor.b();

View file

@ -348,7 +348,7 @@ Vec3<int> AlphaBlendingResult(const PixelFuncID &pixelID, const Vec4<int> &sourc
return Vec3<int>(_mm_unpacklo_epi16(_mm_adds_epi16(s, d), _mm_setzero_si128()));
#else
Vec3<int> half = Vec3<int>::AssignToAll(1);
static constexpr Vec3<int> half = Vec3<int>::AssignToAll(1);
Vec3<int> lhs = ((source.rgb() * 2 + half) * (srcfactor * 2 + half)) / 1024;
Vec3<int> rhs = ((dst.rgb() * 2 + half) * (dstfactor * 2 + half)) / 1024;
return lhs + rhs;
@ -370,7 +370,7 @@ Vec3<int> AlphaBlendingResult(const PixelFuncID &pixelID, const Vec4<int> &sourc
return Vec3<int>(_mm_unpacklo_epi16(_mm_max_epi16(_mm_subs_epi16(s, d), _mm_setzero_si128()), _mm_setzero_si128()));
#else
Vec3<int> half = Vec3<int>::AssignToAll(1);
static constexpr Vec3<int> half = Vec3<int>::AssignToAll(1);
Vec3<int> lhs = ((source.rgb() * 2 + half) * (srcfactor * 2 + half)) / 1024;
Vec3<int> rhs = ((dst.rgb() * 2 + half) * (dstfactor * 2 + half)) / 1024;
return lhs - rhs;
@ -392,7 +392,7 @@ Vec3<int> AlphaBlendingResult(const PixelFuncID &pixelID, const Vec4<int> &sourc
return Vec3<int>(_mm_unpacklo_epi16(_mm_max_epi16(_mm_subs_epi16(d, s), _mm_setzero_si128()), _mm_setzero_si128()));
#else
Vec3<int> half = Vec3<int>::AssignToAll(1);
static constexpr Vec3<int> half = Vec3<int>::AssignToAll(1);
Vec3<int> lhs = ((source.rgb() * 2 + half) * (srcfactor * 2 + half)) / 1024;
Vec3<int> rhs = ((dst.rgb() * 2 + half) * (dstfactor * 2 + half)) / 1024;
return rhs - lhs;