DaemonEngine / Daemon

The Dæmon game engine. With some bits of ioq3 and XreaL.
https://unvanquished.net
BSD 3-Clause "New" or "Revised" License
293 stars 60 forks source link

fail to detect alpha channel heightmap in png normal map (seems to be the same with webp) #233

Closed illwieckz closed 4 years ago

illwieckz commented 4 years ago

Some time ago I added some code to be able to autodetect an heightmap in a normalmap, this is very useful when loading third-party asset from games that relies on such mechanism (Xonotic maps are good example of maps that push our engine forward):

https://github.com/DaemonEngine/Daemon/blob/e63aa213b6593da0021a759f3b9d4cf30705bcde/src/engine/renderer/tr_image.cpp#L1364-L1383

I discovered that code is not able to autodetect the heightmap in png, and if I'm right, webp too. It would be useful to test against tga too.

I verified it works against crn and dds by the way (haven't experimented with ktx at all) which are some kind of “native” GPU formats.

I plan to implement an explicit normalHeightMap keyword (as others idtech3 derivated engines did) but it would be good to know why the above code fails on non-GPU textures formats.

illwieckz commented 4 years ago

It looks like I fixed it in one of my work-in-progress branch.

The problem is that XreaL was bad designed and expected loose heightmap to be heightmap and embedded heightmap in normalmap to be depthmap, so if normalmap had no alpha channel, loading the alpha channel would result in a weird displacement, so the code disabled normalmap alpha channel if the shader did not asked for it explicitly, making alphachannel hence heightmap detection not possible at all.

After fixing the design by using an heightmap instead of a depthmap like all the industry around, we can keep normalmap alphachannel even if does not exist: it will result in a flat heightmap with no side effect.

It even does not break the capcom z reconstruction trick (see https://github.com/DaemonEngine/Daemon/issues/183#issuecomment-473691252) which expects alphachannel to be fully opaque to do it's computation when dxt format does not abuse the alpha channel.

And we can still then use the detection for fully opaque alpha channel to even make the engine aware of the heightmap being embedded, even if if not knowing it would not break the render when dxt texture does not abuse alpha channel for normal z reconstruction and capcom z reconstruction trick.

Knowing the heightmap is not embedded can be used to use the capcom z reconstruction trick for normalmap abusing alpha channel for z reconstruction.