Open Askaniy opened 4 years ago
First two rows of renders by Björn Johnson (at the bottom of this site) compare the current photometric model fairly accurately to what I suggest:
Quite an improvement, in my subjective opinion. Celestia requires a tricky balance between accuracy and aesthetics, but I would call this an improvement for both sides.
Modern hardware supports hardware gamma correction, so we can enable it easily. For older ones we can use fallback code in shaders. Or more likely we can use correction in glsl code in all cases as it allows control over gamma value. In glsl usually a simpler formula is used: pow(x, 1/gamma)
, where gamma
is 2.2 usually, because it easier to compute and gives very close result usually.
That's what we have: Hardware sRGB enabled globally:
GLSL-based correction:
Nice!
@Askaniy aren't bodies to bright?
@375gnu hmm. It looks like the gamma correction was applied to the final body render, not just the shading model. In what I suggested, the textures shouldn't change (see figure).
@Askaniy, what about this one? Here the diffuse texture is converted from sRGB to linear and then final pixels are converted back to sRGB.
Looks like the result is fine, but wouldn't it be more efficient to add gamma correction directly to the shading model? It should be a formula that calculates the brightness of each pixel. Also, there will be data loss in your method.
This will be quite a nonstandard approach. Usual approach is (as I can tell from GL tutorials): 1) load textures in sRGB format and convert them to linear colospace, in modern desktop GL can be performed with HW support 2) work in linear colorspace 3) convert the final image to sRGB.
And why do you think we have data loss? GL colors are float
so we can easily manipulate them.
You are right, then there is no data loss.
Although the method is not optimal for this task, it's easier to add features to it. For example, we can implement two new boolean flags for textures in SSC: GammaCorrection
and BlendAlbedo
. The first parameter allows users to specify the format of loaded textures (by default True
), the second will be considered later.
downside of shader based gamma correction - incorrect blending. it should be performed in linear space for proper results. with hw assisted sRGB pixels read from a framebuffer are converted to linear space and back to sRGB after blending.
Strange artifacts on quad borders with enabled sRGB correction.
@375gnu was the atmosphere turned on on Saturn?
If an atmosphere is not the problem, then the render engine is not providing enough quality of shadow transition for gamma correction. It makes previously invisible artifacts visible.
Not sure what to do. Maybe increase the polygon factor (polygons are sometimes visible on HiDPI displays too). I suppose my suggestion to dig into the shading model code could lead to a similar problem.
It doesn't matter whether atmosphere is on or off.
These artifacts are caused by the fact the Celestia uses per-primitive shading instead of per-pixel one. This decision was made because per-pixel calculations will slowdown rendering and without gamma correction results are almost indistinguishable.
Here is an example of a shader in q&d way updated to provide per-pixel shader: vs original:
cel://Follow/Sol:Saturn/2023-01-22T14:07:19.83472Z?x=II3d4kc9D/7//////////w&y=IDbhNRzU/QE&z=QK9zqxlz0gI&ow=-0.8751254&ox=-0.17094435&oy=-0.33854935&oz=-0.30052933&select=Sol:Saturn&fov=45.535126&ts=1.0<d=0&p=0&rf=134218242&nrf=64&lm=0&tsrc=0&ver=3
So we should: 1) make gamma correction optional (especially as it's harder to implement it with GL ES). 2) when gamma correction is disabled use per-primitive shading. 3) investigate if precomputed scattering is applicable.
But linear->sRGB conversion makes the border between lit and unlit parts too sharp. Such image is then converted into the 1st one in the previous comment.
I see. Is the linear part of gamma correction taken into account? Referring to the formula in the first post
Also, apparently, the texture is first converted to linear space. What if we add an option to the SSC to indicate that the texture is already in linear space? Often, add-on creators forget about gamma correction for textures, and this option will allow to quickly fix it.
it doesn't matter whether we use a simple formula or a more complicate one. And the image you posted in the very beginning of the issue looks the same.
It really looks like some textures should be treated as they are in linear space despite the presence of sRGB metadata.
it doesn't matter whether we use a simple formula or a more complicate one. And the image you posted in the very beginning of the issue looks the same.
It should matter. To create the image, I used Photoshop, in which I used a simple formula. It seems that the complication of the formula is done specifically to make the border not so sharp.
There is a progress moving stuff to fragment shaders.
Celestia uses the Lunar-Lambert photometric model, and (except for compatibility issues with specular maps) it works right for linear sensitivity to light (brightness is distributed in proportion to received photons). However, in a nutshell, human vision isn't linear and greatly increases the brightness of dark areas compared to bright ones. Evolutionarily, it probably matters. This is called gamma correction and the conversion from linear brightness (0 to 1), in the simplest cases, defined by this power-law expression:
Visible = Linear^(1/2.2)
. More applied use in Python looks like this:So, I suggest a small change in the shading model that will be a really huge step in realism! Also, if it seems necessary, gamma correction control can be added to the settings.
To show roughly what it will look like, I took a gamma-corrected texture (on the left) and texture with linear brightness (on the right), then I added a gamma correction to the right side: Processing by Gordan Ugarkovic for comparison.
Notes:
SSC
, but this is a separate issue;