Daemon icon indicating copy to clipboard operation
Daemon copied to clipboard

WIP: tr_shader: linearize fog colors and fog image

Open illwieckz opened this issue 7 months ago • 8 comments

Linearize fog colors.

Something I overlooked when writing #1687:

  • https://github.com/DaemonEngine/Daemon/pull/1687

This is not enough to make fog looks good in the linear pipeline.

A fog relying on some kind of blend (I guess), we may need to recalibrate/reimplement it for the linear pipeline.

But at least with that patch the colors become right.

illwieckz avatar Aug 06 '25 00:08 illwieckz

In fact I found how to get the fog working in the linear pipeline, by using a linearized image!

So basically I create two fog images, one for the naive pipeline, one for the linear pipeline, and use them accordingly.

For unknown reasons that doesn't work when I ask to upload the second image with an sRGB format, it's like this metadata is ignored. But it works if I convert the image beforehand. I would prefer to flag the image and not convert it beforehand to not lose precision when storing as bytes, so if someone knows why the flag doesn't work, please help! Otherwise it's ready to use.

illwieckz avatar Aug 06 '25 01:08 illwieckz

Well, I guess know why the sRGB flag doesn't change anything: only the alpha channel seems to be used and the sRGB conversion doesn't apply on the alpha channel that is always linear (of course!).

illwieckz avatar Aug 06 '25 05:08 illwieckz

So I stored the alpha channel in the red channel and then we can flag the texture as sRGB to get it implicitly converted.

It works.

illwieckz avatar Aug 06 '25 05:08 illwieckz

I added code to store the fog naive color as a GL_RED, and the fog linear color GL_SR8_EXT when supported.

illwieckz avatar Aug 06 '25 06:08 illwieckz

Well, I guess know why the sRGB flag doesn't change anything: only the alpha channel seems to be used and the sRGB conversion doesn't apply on the alpha channel that is always linear (of course!).

The thing is, it actually is used as an alpha. The fog works as if alpha-blending a solid-color image with color fogColor, and an alpha value depending on the fog depth which is sourced from fogImage. So it probably doesn't make sense to sRGB-convert the fog image.

Now if we leave the fog image alone and just convert the color, the result is expected to be brighter than with the naive pipeline, since naive alpha blending produces results that are darker than they should be. Probably the fog shaders just need to be adjusted on a per-map basis, like other translucent shaders.

slipher avatar Aug 09 '25 03:08 slipher

Yes it's actually an alpha channel, but we need a different alpha channel for when working in linear space, and it happens that applying this transformation is the cheapest way to produce an approximation that works.

I'm not against us adding a different image generator with a different specially-shaped curve for that alpha channel when blending in linear space, but I have no idea how such curve should be generated. I can add an HACK comment explaining that.

In a similar topic, I've heard that actually multiplying sRGB texture with sRGB lightmap without linearizing them before and delinearizing the result after is interestingly close to doing the things properl. That's why my testing server doesn't look that bad when not using a colorspace-aware engine, and that it still looks better than maps rendered the legacy way.

I wonder if we can also approximate some other blending compatibility by converting the alpha too.

I guess that blending an sRGB texture with a linear alpha channel produces a somewhat sRGB image, so maybe blending a linear texture with an sRGB alpha channel somewhat produces that sRGB image, at least close enough. Or something like that. It's totally hacky but things may produce interesting results this way.

illwieckz avatar Aug 09 '25 04:08 illwieckz

I added a comment saying the current fog image implementation in linear pipeline is a hack.

But now I thought about something. The fog image generator for the naive pipeline unaware of colorspaces is doing some complex algorithm, picking values from tables and using custom factors… I actually wonder what would happen if we would just use some linear values instead, when running the linear pipeline. Maybe all that fog factor and fog table thing is yet another workaround for the broken naive pipeline?

illwieckz avatar Aug 11 '25 14:08 illwieckz

This is what the contents of the fogImage look like as it currently is, with the alpha-channel used for rgb: image

VReaperV avatar Aug 13 '25 10:08 VReaperV