niftools / nifskope

A git repository for nifskope.
http://www.niftools.org
Other
553 stars 235 forks source link

Morrowind decals #184

Open AnyOldName3 opened 4 years ago

AnyOldName3 commented 4 years ago

I've been investigating how decals are drawn in Morrowind with APITrace as we need to know for OpenMW. My understanding is that using APITrace and describing what I saw in plain English so you can implement it definitely 100% counts as clean-room reverse engineering, and I'm reasonably sure that it's equivalent to snooping on network traffic, so would also be fine if I ended up implementing it myself, so no licenses are being violated by me writing this. Yay! I've checked and an APITrace counts as output from a black box rather than peering inside it, so it definitely doesn't cause any licence issues if you do stuff based on this report.

Anyway, NifSkope's handling of Morrowind meshes with decals is currently inaccurate. The correct procedure is to do something equivalent to:

Obviously this can be achieved more cheaply with a shader and single draw call. I've not investigated what happens when other effects are in play at the same time, either, so there might be more fun things that could go wrong.

In vanilla Morrowind, the attached Nif looks like this: image whereas in NifSkope, you only get the base texture: image

This is achieved with an opaque base dirt texture and opaque decal grass texture, vertex colours with varying alpha, and no blending or testing on the mesh as a whole.

decal_blending.zip

hexabits commented 4 years ago

image

In Renderer::setupFixedFunction one can change

glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_TEXTURE );

to

glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_PRIMARY_COLOR );

... inside of the decal stages.

I have absolutely no idea if this is correct in the general case, or if it's conditional upon some NIF setting, and I would also have to extensively test NIFs from other games using NiTexturingProperty with decals to see if this is some Bethesda-specific change.

AnyOldName3 commented 4 years ago

Just so I can find it more easily, Renderer::setupFixedFunction hangs out here: https://github.com/niftools/nifskope/blob/3a85ac55e65cc60abc3434cc4aaca2a5cc712eef/src/gl/renderer.cpp#L1069-L1320

hexabits commented 4 years ago

Also, I'm not sure how you only got the base texture. Make sure you have the Bloodmoon BSA as a resource in your settings. Without the change, I only get the decal texture, not the base texture.

AnyOldName3 commented 4 years ago

I thought I had Bloodmoon in my archives list, but apparently not. It's huge due to a bazillion mods from several games being in there. Maybe a more obvious some referenced textures couldn't be found message would be reasonable to add, e.g. in the bottom bar of the window so it's not super obtrusive.

hexabits commented 4 years ago

It's huge due to a bazillion mods from several games being in there.

@AnyOldName3 Unrelated to this ticket, but if you use my Dev 8 release on my fork, it has a Game Manager that separates all the games. This was done so that Fallout 4 and Fallout 76 would stop conflicting resource-wise. It doesn't (and can't) currently help differentiate FO3/FNV. It's more than just organization; though helpful that it cuts down on conflicts, it massively speeds up finding of textures since it looks only at the archives for one game.

Regarding this ticket, if you could maybe find several more examples of this vertex color - decal thing, I would like a list of files. I don't need the files, just a list. I would also like a list of files where there are vertex colors + no decals, and vertex colors + decals, but the decals don't use the vertex colors (if that exists).

AnyOldName3 commented 4 years ago

I'm not 100% sure Morrowind actually used decals in any vanilla meshes. We might well be looking at something only mods did, so it's probably easier for both of us if we work with purpose-made test meshes.

Greatness7 commented 4 years ago

Bethesda did not use this in any vanilla assets. They did however use it for meshes generated in-game. Notably this technique is how terrain textures are blended in exteriors. We discovered this using the engine's native "SaveBinary" function (exposed by MWSE), which allows dumping the in-game scene graph directly to .NIF files.

As far as I know this behavior is Morrowind specific. I did not check other Bethesda titles, but I know it does not render properly in SceneImmerse.

As for how it works visually: It seems to be just a simple case of multiplying the vertex color alpha channel (or material alpha if no vertex colors are present) with the decal alpha channel(s).

AnyOldName3 commented 4 years ago

As for how it works visually: It seems to be just a simple case of multiplying the vertex color alpha channel (or material alpha if no vertex colors are present) with the decal alpha channel(s).

At least with the test mesh I posted here, that's what's happening. The vanilla engine is achieving that with multiple draw calls, though, but NifSkope is trying to bully texenv into doing that, which I don't think is possible. John Carmack only proved texenv is Turing-complete when multiple passes are allowed.