mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
softgpu: Handle infnan fog coefficients better.
If we ended up with a dot product that had opposing inf signs, the add would result in NAN and cause problems.
This commit is contained in:
1 parent
c5844c4174
commit
38de2f11af
1 file changed
+21
-8
@@ -295,17 +295,30 @@ void ComputeTransformState(TransformState *state, const VertexReader &vreader) {
|
||||
if (state->enableFog) {
|
||||
float fogEnd = getFloat24(gstate.fog1);
|
||||
float fogSlope = getFloat24(gstate.fog2);
|
||||
// Same fixup as in ShaderManagerGLES.cpp
|
||||
if (my_isnanorinf(fogEnd)) {
|
||||
fogEnd = std::signbit(fogEnd) ? -INFINITY : INFINITY;
|
||||
}
|
||||
if (my_isnanorinf(fogSlope)) {
|
||||
fogSlope = std::signbit(fogSlope) ? -INFINITY : INFINITY;
|
||||
}
|
||||
|
||||
// We bake fog end and slope into the dot product.
|
||||
state->posToFog = Vec4f(worldview[2], worldview[6], worldview[10], worldview[14] + fogEnd);
|
||||
state->posToFog *= fogSlope;
|
||||
|
||||
// If either are NAN/INF, we simplify so there's no inf + -inf muddying things.
|
||||
// This is required for Outrun to render proper skies, for example.
|
||||
// The PSP treats these exponents as if they were valid.
|
||||
if (my_isnanorinf(fogEnd)) {
|
||||
bool sign = std::signbit(fogEnd);
|
||||
// The multiply would reverse it.
|
||||
if (my_isnanorinf(fogSlope) && std::signbit(fogSlope))
|
||||
sign = !sign;
|
||||
|
||||
// Since this is constant for the entire draw, we don't even use infinity.
|
||||
float forced = sign ? 0.0f : 1.0f;
|
||||
state->posToFog = Vec4f(0.0f, 0.0f, 0.0f, forced);
|
||||
} else if (my_isnanorinf(fogSlope)) {
|
||||
// We can't have signs differ with infinities, so we use a large value.
|
||||
// Anything outside [0, 1] will clamp, so this essentially forces extremes.
|
||||
fogSlope = std::signbit(fogSlope) ? -262144.0f : 262144.0f;
|
||||
state->posToFog *= fogSlope;
|
||||
} else {
|
||||
state->posToFog *= fogSlope;
|
||||
}
|
||||
}
|
||||
|
||||
state->screenScale = Vec3f(gstate.getViewportXScale(), gstate.getViewportYScale(), gstate.getViewportZScale());
|
||||
|
||||
Reference in new issue
Block a user