mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-27 15:30:35 +00:00
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:
parent
5a35525fd4
commit
d6a8cb2a0e
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user