michael-fadely / sadx-d3d11

MIT License
9 stars 3 forks source link

Fog and some SA_ONE or DA_DST models not blending correctly #5

Open PiKeyAr opened 6 years ago

PiKeyAr commented 6 years ago

In SA1, the object Rlight uses a material that has NJD_SA_SRC and NJD_DA_DST. This makes the light more opaque when you're far away from it, and more transparent when you get closer. With OIT it blends incorrectly: image image Without OIT it looks like this, which is correct apart from self-blending artifacts: image image Here's a DLL that has SA_SRC and DA_DST enabled for this model: https://dcmods.unreliable.network/owncloud/data/PiKeyAr/files/Various/lwselfblend.7z

michael-fadely commented 6 years ago

Comparing the second and fourth screenshots, the distant light shaft looks correct, just with correct self-blending. I'm really not sure why the nearer one changes at all in vanilla, to be honest. It shouldn't do that with NJD_DA_DST, but it's an inaccuracy nonetheless.

PiKeyAr commented 6 years ago

Maybe it's something like the QueuedModelFlagsB_EnableZWrite queued model flag? As in, the NJD_DA_DST is working correctly with OIT but it blends all faces of the model as opposed to just those facing the camera. Like backface culling but for transparent stuff?

michael-fadely commented 6 years ago

OIT does indeed blend all of the model's faces, front and back (which isn't to say a single face gets blended with itself; that would be weird). Since SADX loads all of its vertex data incorrectly, enabling culling isn't an option unless all the vertex loading functions are rewritten.

Writing to the depth buffer would solve this issue in vanilla, but even in those screenshots above it's not working correctly if that's what they're supposed to be doing. The last two screenshots shows the back faces rendering... for the most part. OIT just fills in the missing gaps there.

It still doesn't explain why the closer ones are so much more transparent in vanilla, though.

PiKeyAr commented 6 years ago

Here are a couple screens from the DC version just in case image image It almost looks like an intentional effect done in code - the light is completely invisible when its position is close to the camera, and it reacts to changes in camera position. It does something very similar when NJD_DA_DST is used in the PC port, which is why I assumed it was only the OIT that was needed to make it display properly. It does become more transparent with OIT, just not transparent enough.

I noticed one thing though, it looks like the "front" side (which covers the area in the center) is rendered with the correct opacity, but the remaining three sides are too bright. There's also some weird stuff going on with the "front" side changing suddenly depending on camera position: https://dcmods.unreliable.network/owncloud/data/PiKeyAr/files/Various/rlight.mp4 This thing happens with and without OIT, and I think in the Dreamcast version too. Interestingly the "front" side doesn't seem to react much when you enable or disable OIT, while the other sides become brighter with OIT on. Also, if I remember correctly, these lights looked fine with depth peeling.

PiKeyAr commented 6 years ago

Here's a screenshot of this area in redream, which doesn't have fog implemented: image So maybe this has something to do with fog blending?

michael-fadely commented 6 years ago

That would make sense, now that I think about it. Transparent fragments for OIT are stored after fog is applied. In this case, it causes to surfaces influenced by fog to blend together, causing the overly bright result.

PiKeyAr commented 6 years ago

This "side effect" would be nice to have for stuff with SA_ONE blending, which apparently applies fog before blending the color. E.g. Sonic's spindash trail, electric shield.

PiKeyAr commented 5 years ago

After fixing these lights in vanilla DX (by using queued model flags 0 instead of EnableZWrite) I found out that they now look correct with this mod, too. image

PiKeyAr commented 5 years ago

The issue is back with the latest generic build, and it seems that SA_ONE/DA_ONE is also affected.