Video backends: fix rounding in lighting computation.
For whatever reason, the hardware doesn't do a full divide by 255, but instead uses an approximation with shifting, similar to the way it is done in TEV.
This commit is contained in:
parent
36720e6822
commit
9e4eeb3b9b
|
@ -5,6 +5,8 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#include "Common/Common.h"
|
#include "Common/Common.h"
|
||||||
|
#include "Common/MathUtil.h"
|
||||||
|
|
||||||
#include "VideoBackends/Software/BPMemLoader.h"
|
#include "VideoBackends/Software/BPMemLoader.h"
|
||||||
#include "VideoBackends/Software/CPMemLoader.h"
|
#include "VideoBackends/Software/CPMemLoader.h"
|
||||||
#include "VideoBackends/Software/NativeVertexFormat.h"
|
#include "VideoBackends/Software/NativeVertexFormat.h"
|
||||||
|
@ -200,11 +202,6 @@ inline void AddScaledIntegerColor(const u8 *src, float scale, Vec3 &dst)
|
||||||
dst.z += src[3] * scale;
|
dst.z += src[3] * scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline float Clamp(float val, float a, float b)
|
|
||||||
{
|
|
||||||
return val<a?a:val>b?b:val;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline float SafeDivide(float n, float d)
|
inline float SafeDivide(float n, float d)
|
||||||
{
|
{
|
||||||
return (d==0) ? (n>0?1:0) : n/d;
|
return (d==0) ? (n>0?1:0) : n/d;
|
||||||
|
@ -414,10 +411,15 @@ void TransformColor(const InputVertexData *src, OutputVertexData *dst)
|
||||||
LightColor(dst->mvPosition, dst->normal[0], i, colorchan, lightCol);
|
LightColor(dst->mvPosition, dst->normal[0], i, colorchan, lightCol);
|
||||||
}
|
}
|
||||||
|
|
||||||
float inv = 1.0f / 255.0f;
|
int light_x = int(lightCol.x);
|
||||||
chancolor[1] = (u8)(matcolor[1] * Clamp(lightCol.x * inv, 0.0f, 1.0f));
|
int light_y = int(lightCol.y);
|
||||||
chancolor[2] = (u8)(matcolor[2] * Clamp(lightCol.y * inv, 0.0f, 1.0f));
|
int light_z = int(lightCol.z);
|
||||||
chancolor[3] = (u8)(matcolor[3] * Clamp(lightCol.z * inv, 0.0f, 1.0f));
|
MathUtil::Clamp(&light_x, 0, 255);
|
||||||
|
MathUtil::Clamp(&light_y, 0, 255);
|
||||||
|
MathUtil::Clamp(&light_z, 0, 255);
|
||||||
|
chancolor[1] = (matcolor[1] * (light_x + (light_x >> 7))) >> 8;
|
||||||
|
chancolor[2] = (matcolor[2] * (light_y + (light_y >> 7))) >> 8;
|
||||||
|
chancolor[3] = (matcolor[3] * (light_z + (light_z >> 7))) >> 8;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -446,7 +448,9 @@ void TransformColor(const InputVertexData *src, OutputVertexData *dst)
|
||||||
LightAlpha(dst->mvPosition, dst->normal[0], i, alphachan, lightCol);
|
LightAlpha(dst->mvPosition, dst->normal[0], i, alphachan, lightCol);
|
||||||
}
|
}
|
||||||
|
|
||||||
chancolor[0] = (u8)(matcolor[0] * Clamp(lightCol / 255.0f, 0.0f, 1.0f));
|
int light_a = int(lightCol);
|
||||||
|
MathUtil::Clamp(&light_a, 0, 255);
|
||||||
|
chancolor[0] = (matcolor[0] * (light_a + (light_a >> 7))) >> 8;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -255,7 +255,8 @@ static void GenerateLightingShader(T& object, LightingUidData& uid_data, int com
|
||||||
GenerateLightShader<T>(object, uid_data, i, lit_index, lightsColName, lightsName, coloralpha);
|
GenerateLightShader<T>(object, uid_data, i, lit_index, lightsColName, lightsName, coloralpha);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
object.Write("%s%d = float4(mat * clamp(lacc, 0, 255) / 255) / 255.0;\n", dest, j);
|
object.Write("lacc = clamp(lacc, 0, 255);");
|
||||||
|
object.Write("%s%d = float4((mat * (lacc + (lacc >> 7))) >> 8) / 255.0;\n", dest, j);
|
||||||
object.Write("}\n");
|
object.Write("}\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue