Amend ambient fog logic

Should stop the sky flashing in lemans24, and the background totally disappearing in sega rally after a game. The logic here is still not totally understood but works well enough for the games.
This commit is contained in:
Ian Curtis 2023-12-27 12:42:32 +00:00
parent c039d08c03
commit 0e07f29f80

View file

@ -227,27 +227,46 @@ void CNew3D::DrawAmbientFog()
// If fogAmbient = 1.0 it's a no-op. Lower values darken the image
// Does this work with scroll fog? Well technically scroll fog already takes into account the fog ambient as it darkens the fog colour
// Let's pick the lowest fog ambient value
// lemans24 every viewport will set ambient fog, scroll attentuation is sometimes set (for every viewport) for explosion effects from car exhaust. So has no effect on ambient fog
// otherwise we'll make the ambient fog flash
// sega rally will set ambient fog to zero for every viewport in priority layers 1-3 with a fog density set. Disabled viewports with priority zero have ambient fog disabled (1.0). Don't think srally uses ambient fog
// vf3 almost all viewports in all priority layers have ambient fog set (<1.0)
// lost world is setting an ambient fog value every every viewport but has no density or fog start value set. Don't think lost world is using ambient fog
// Let's pick the lowest fog ambient value from only the first priority layer
// Check for fog density or a fog start value, otherwise the effect seems to be disabled (lost world)
float fogAmbient = 1.0f;
Node* nodePtr = nullptr;
for (int i = 0; i < 4; i++) {
bool hasPriority = false;
for (auto& n : m_nodes) {
auto& vp = n.viewport;
if (vp.priority == i) {
hasPriority = true;
// check to see if we have a fog density or fog start
if (n.viewport.fogParams[3] <= 0.0f && n.viewport.fogParams[4] <= 0.0f) {
if (vp.fogParams[3] <= 0.0f && vp.fogParams[4] <= 0.0f) {
continue;
}
if (n.viewport.scrollAtt > 0.0f) {
continue; // scroll attenuation indicates scroll fog layer
if (vp.fogParams[6] < fogAmbient) {
nodePtr = &n;
fogAmbient = vp.fogParams[6];
}
}
}
if (n.viewport.fogParams[6] < fogAmbient) {
nodePtr = &n;
fogAmbient = n.viewport.fogParams[6];
if (nodePtr || hasPriority) {
break;
}
}
if (nodePtr) {
@ -982,8 +1001,9 @@ void CNew3D::RenderViewport(UINT32 addr)
return;
}
if (!(vpnode[0] & 0x20)) { // only if viewport enabled
bool vpDisabled = vpnode[0] & 0x20; // only if viewport enabled
{
// create node object
m_nodes.emplace_back(Node());
m_nodes.back().models.reserve(2048); // create space for models
@ -1105,11 +1125,13 @@ void CNew3D::RenderViewport(UINT32 addr)
InitMatrixStack(matrixBase, m_modelMat);
// Descend down the node link. Need to start with a culling node because that defines our culling radius.
if (!vpDisabled) {
auto childptr = vpnode[0x02];
if (((childptr >> 24) & 0x5) == 0) {
DescendNodePtr(vpnode[0x02]);
}
}
}
// render next viewport
if (vpnode[0x01] != 0x01000000) {