softgpu: Stop storing normal/worldnormal/worldpos.

This is only needed for lighting, which is applied right away.

This improves perf just simply from less data being copied.
This commit is contained in:
Unknown W. Brackets 2022-01-14 20:26:05 -08:00
parent 5a35525fd4
commit d6a8cb2a0e
4 changed files with 28 additions and 34 deletions

View File

@ -44,23 +44,23 @@ static inline float pspLightPow(float v, float e) {
return v;
}
static inline float GenerateLightCoord(VertexData &vertex, int light) {
static inline float GenerateLightCoord(VertexData &vertex, const WorldCoords &worldnormal, int light) {
// TODO: Should specular lighting should affect this, too? Doesn't in GLES.
Vec3<float> L = GetLightVec(gstate.lpos, light);
// In other words, L.Length2() == 0.0f means Dot({0, 0, 1}, worldnormal).
float diffuse_factor = Dot(L.NormalizedOr001(cpu_info.bSSE4_1), vertex.worldnormal);
float diffuse_factor = Dot(L.NormalizedOr001(cpu_info.bSSE4_1), worldnormal);
return (diffuse_factor + 1.0f) / 2.0f;
}
void GenerateLightST(VertexData &vertex) {
void GenerateLightST(VertexData &vertex, const WorldCoords &worldnormal) {
// Always calculate texture coords from lighting results if environment mapping is active
// This should be done even if lighting is disabled altogether.
vertex.texturecoords.s() = GenerateLightCoord(vertex, gstate.getUVLS0());
vertex.texturecoords.t() = GenerateLightCoord(vertex, gstate.getUVLS1());
vertex.texturecoords.s() = GenerateLightCoord(vertex, worldnormal, gstate.getUVLS0());
vertex.texturecoords.t() = GenerateLightCoord(vertex, worldnormal, gstate.getUVLS1());
}
void Process(VertexData& vertex, bool hasColor) {
void Process(VertexData& vertex, const WorldCoords &worldpos, const WorldCoords &worldnormal, bool hasColor) {
const int materialupdate = gstate.materialupdate & (hasColor ? 7 : 0);
Vec4<int> mec = Vec4<int>::FromRGBA(gstate.getMaterialEmissive());
@ -82,7 +82,7 @@ void Process(VertexData& vertex, bool hasColor) {
// TODO: Should transfer the light positions to world/view space for these calculations?
Vec3<float> L = GetLightVec(gstate.lpos, light);
if (!gstate.isDirectionalLight(light)) {
L -= vertex.worldpos;
L -= worldpos;
}
// TODO: Should this normalize (0, 0, 0) to (0, 0, 1)?
float d = L.NormalizeOr001();
@ -124,7 +124,7 @@ void Process(VertexData& vertex, bool hasColor) {
final_color += lambient;
// diffuse lighting
float diffuse_factor = Dot(L, vertex.worldnormal);
float diffuse_factor = Dot(L, worldnormal);
if (gstate.isUsingPoweredDiffuseLight(light)) {
float k = gstate.getMaterialSpecularCoef();
diffuse_factor = pspLightPow(diffuse_factor, k);
@ -143,7 +143,7 @@ void Process(VertexData& vertex, bool hasColor) {
if (gstate.isUsingSpecularLight(light) && diffuse_factor >= 0.0f) {
Vec3<float> H = L + Vec3<float>(0.f, 0.f, 1.f);
float specular_factor = Dot(H.NormalizedOr001(cpu_info.bSSE4_1), vertex.worldnormal);
float specular_factor = Dot(H.NormalizedOr001(cpu_info.bSSE4_1), worldnormal);
float k = gstate.getMaterialSpecularCoef();
specular_factor = pspLightPow(specular_factor, k);

View File

@ -21,7 +21,7 @@
namespace Lighting {
void GenerateLightST(VertexData &vertex);
void Process(VertexData& vertex, bool hasColor);
void GenerateLightST(VertexData &vertex, const WorldCoords &worldnormal);
void Process(VertexData &vertex, const WorldCoords &worldpos, const WorldCoords &worldnormal, bool hasColor);
}

View File

@ -164,11 +164,12 @@ VertexData TransformUnit::ReadVertex(VertexReader &vreader, bool &outside_range_
vreader.ReadUV(vertex.texturecoords.AsArray());
}
Vec3<float> normal;
if (vreader.hasNormal()) {
vreader.ReadNrm(vertex.normal.AsArray());
vreader.ReadNrm(normal.AsArray());
if (gstate.areNormalsReversed())
vertex.normal = -vertex.normal;
normal = -normal;
}
if (vertTypeIsSkinningEnabled(gstate.vertType) && !gstate.isModeThrough()) {
@ -182,14 +183,14 @@ VertexData TransformUnit::ReadVertex(VertexReader &vreader, bool &outside_range_
Vec3<float> step = Vec3ByMatrix43(pos, gstate.boneMatrix + i * 12);
tmppos += step * W[i];
if (vreader.hasNormal()) {
step = Norm3ByMatrix43(vertex.normal, gstate.boneMatrix + i * 12);
step = Norm3ByMatrix43(normal, gstate.boneMatrix + i * 12);
tmpnrm += step * W[i];
}
}
pos = tmppos;
if (vreader.hasNormal())
vertex.normal = tmpnrm;
normal = tmpnrm;
}
if (vreader.hasColor0()) {
@ -210,8 +211,8 @@ VertexData TransformUnit::ReadVertex(VertexReader &vreader, bool &outside_range_
if (!gstate.isModeThrough()) {
vertex.modelpos = pos;
vertex.worldpos = WorldCoords(TransformUnit::ModelToWorld(vertex.modelpos));
ModelCoords viewpos = TransformUnit::WorldToView(vertex.worldpos);
WorldCoords worldpos = WorldCoords(TransformUnit::ModelToWorld(vertex.modelpos));
ModelCoords viewpos = TransformUnit::WorldToView(worldpos);
vertex.clippos = ClipCoords(TransformUnit::ViewToClip(viewpos));
if (gstate.isFogEnabled()) {
float fog_end = getFloat24(gstate.fog1);
@ -230,11 +231,12 @@ VertexData TransformUnit::ReadVertex(VertexReader &vreader, bool &outside_range_
}
vertex.screenpos = ClipToScreenInternal(vertex.clippos, &outside_range_flag);
Vec3<float> worldnormal;
if (vreader.hasNormal()) {
vertex.worldnormal = TransformUnit::ModelToWorldNormal(vertex.normal);
vertex.worldnormal.NormalizeOr001();
worldnormal = TransformUnit::ModelToWorldNormal(normal);
worldnormal.NormalizeOr001();
} else {
vertex.worldnormal = Vec3<float>(0.0f, 0.0f, 1.0f);
worldnormal = Vec3<float>(0.0f, 0.0f, 1.0f);
}
// Time to generate some texture coords. Lighting will handle shade mapping.
@ -250,11 +252,11 @@ VertexData TransformUnit::ReadVertex(VertexReader &vreader, bool &outside_range_
break;
case GE_PROJMAP_NORMALIZED_NORMAL:
source = vertex.normal.NormalizedOr001(cpu_info.bSSE4_1);
source = normal.NormalizedOr001(cpu_info.bSSE4_1);
break;
case GE_PROJMAP_NORMAL:
source = vertex.normal;
source = normal;
break;
default:
@ -268,12 +270,12 @@ VertexData TransformUnit::ReadVertex(VertexReader &vreader, bool &outside_range_
float z_recip = 1.0f / stq.z;
vertex.texturecoords = Vec2f(stq.x * z_recip, stq.y * z_recip);
} else if (gstate.getUVGenMode() == GE_TEXMAP_ENVIRONMENT_MAP) {
Lighting::GenerateLightST(vertex);
Lighting::GenerateLightST(vertex, worldnormal);
}
PROFILE_THIS_SCOPE("light");
if (gstate.isLightingEnabled())
Lighting::Process(vertex, vreader.hasColor0());
Lighting::Process(vertex, worldpos, worldnormal, vreader.hasColor0());
} else {
vertex.screenpos.x = (int)(pos[0] * 16) + gstate.getOffsetX16();
vertex.screenpos.y = (int)(pos[1] * 16) + gstate.getOffsetY16();

View File

@ -82,17 +82,12 @@ struct DrawingCoords
}
};
struct VertexData
{
void Lerp(float t, const VertexData& a, const VertexData& b)
{
// World coords only needed for lighting, so we don't Lerp those
struct VertexData {
void Lerp(float t, const VertexData &a, const VertexData &b) {
modelpos = ::Lerp(a.modelpos, b.modelpos, t);
clippos = ::Lerp(a.clippos, b.clippos, t);
screenpos = ::Lerp(a.screenpos, b.screenpos, t); // TODO: Should use a LerpInt (?)
texturecoords = ::Lerp(a.texturecoords, b.texturecoords, t);
normal = ::Lerp(a.normal, b.normal, t);
fogdepth = ::Lerp(a.fogdepth, b.fogdepth, t);
u16 t_int = (u16)(t*256);
@ -101,12 +96,9 @@ struct VertexData
}
ModelCoords modelpos;
WorldCoords worldpos; // TODO: Storing this is dumb, should transform the light to clip space instead
ClipCoords clippos;
ScreenCoords screenpos; // TODO: Shouldn't store this ?
Vec2<float> texturecoords;
Vec3<float> normal;
WorldCoords worldnormal;
Vec4<int> color0;
Vec3<int> color1;
float fogdepth;