godot icon indicating copy to clipboard operation
godot copied to clipboard

Add AgX tonemapper option to Environment

Open Calinou opened this issue 1 year ago • 107 comments

Thanks to @begla for providing this code under MIT license and helping with the whitepoint configuration :slightly_smiling_face:

  • This closes https://github.com/godotengine/godot-proposals/discussions/7545.

Testing project: https://github.com/godotengine/godot-demo-projects/pull/857

TODO

  • [ ] Consider using specialization constants for each tonemapper in RenderingDevice shaders to improve performance a bit, as tonemapping methods are generally never switched during gameplay.

Preview

All images use whitepoint 6.0 unless otherwise mentioned.

Tonemap Forward+ Compatibility[^1]
Linear Screenshot_20240116_181348 webp Screenshot_20240116_181630 webp
Reinhard Screenshot_20240116_181352 webp Screenshot_20240116_181634 webp
Filmic Screenshot_20240116_181356 webp Screenshot_20240116_181637 webp
ACES Screenshot_20240116_181400 webp Screenshot_20240116_181641 webp
AgX AgX After AgX Compatibility
AgX (whitepoint = 16.0) AgX After 16.0 AgX Compatibility 16.0
AgX Punchy AgX Punchy After AgX Punchy Compatibility

[^1]: This demo is currently not designed with Compatibility in mind, so the surface colors are incorrect. Nonetheless, the tonemappers work.

Calinou avatar Jan 16 '24 17:01 Calinou

Maybe not related to this pr, but why does the red light for example, leak through?

Norrox avatar Feb 03 '24 19:02 Norrox

Maybe not related to this pr, but why does the red light for example, leak through?

That's just due to how the reflection probe is set up in the scene (one probe near the red box covers the entire scene). It's not related to this PR :slightly_smiling_face:

Calinou avatar Feb 03 '24 19:02 Calinou

Hi. What version of AgX is being implemented? Troy's / or Eary's branch (the one included in blender)

joelRVC avatar Feb 03 '24 23:02 joelRVC

Hi. What version of AgX is being implemented? Troy's / or Eary's branch (the one included in blender)

This relies upon the implementation found in this article, which I believe is closer to Troy's version (but not 100% identical).

Calinou avatar Feb 03 '24 23:02 Calinou

Thanks for the clarification. You are right, if you compare the example of the sweeps (from Troy) with the one on the website you shared, they are similar, only the red seems more saturated than in the original implementation, and since in the code the punchy version has an increase in saturation of 1.4 I think that can end up creating unwanted clipping, and it seems to be messing with the luminance values?.

joelRVC avatar Feb 04 '24 00:02 joelRVC

Not sure if it's helpful but you can also look at three.js's implementation as reference: https://github.com/mrdoob/three.js/pull/27366#issuecomment-1862040027

BTW the term "white point" has a very specific meaning in RGB color, it means the chromaticity of R=G=B, in a lot of colorspaces like Rec.709, sRGB, Rec.2020 etc. it's D65, for other spaces like DCI-P3, they have their own white points like the DCI "theatre" white point. So when the PR says something about white point being 16, it looks very confusing.

EaryChow avatar Feb 04 '24 06:02 EaryChow

BTW the term "white point" has a very specific meaning in RGB color, it means the chromaticity of R=G=B, in a lot of colorspaces like Rec.709, sRGB, Rec.2020 etc. it's D65, for other spaces like DCI-P3, they have their own white points like the DCI "theatre" white point. So when the PR says something about white point being 16, it looks very confusing.

Godot doesn't have color management, so it uses an arbitrary whitepoint unit. Higher values result in less blown out highlights, but will slightly darken the whole scene. There are diminishing effects to increasing the whitepoint value, so usually, a value like 10 will look pretty close to something like 20.

Calinou avatar Feb 06 '24 21:02 Calinou

There are diminishing effects to increasing the whitepoint value, so usually, a value like 10 will look pretty close to something like 20.

My point is, "white point" is a widely accepted language for chromaticity, I.E how warm, how cold should the white be, not brightness or intensity. A white point value is usually a CIE XYZ or CIE xyY coordinate (For example, D65's CIE XYZ is [0.95047, 1, 1.08883]), not a scalar value. If Godot uses a scalar value to refer to an intensity value and then call it "white point", the terminology is confusing.

As for the white clipping point, how steep the curve is also affects the rate of change in gradients. It's best to test against EXRs like Red Xmas etc. to make sure things are still smooth. Red Xmas EXR is available here The Matas Night club is also an important one Another important one is ARRI Alexa 35's Diver footage But note the diver footage above is in AWG4, I converted it to Linear Rec.709 below for convenience: Siren4_arri_alexa35_BT709.exr.txt (delete the .txt at the end, just a workaround of GitHub's upload file type limitation) If you took a look at the three.js page you should see that they have done these testings. These testings are important.

EaryChow avatar Feb 07 '24 08:02 EaryChow

@Calinou Greetings! Is the feature gonna be in 4.3? Would be nice to have alongside with the new Global Illumination to achieve overall proper lighting and coloring in complex scenes.

ArseniyMirniy avatar Feb 07 '24 20:02 ArseniyMirniy

@Calinou Greetings! Is the feature gonna be in 4.3? Would be nice to have alongside with the new Global Illumination to achieve overall proper lighting and coloring in complex scenes.

I can't give an ETA for merging this, as this PR still needs a review from other contributors before it can be merged.

Calinou avatar Feb 07 '24 21:02 Calinou

Google's Filament uses slightly different matrices. It says that the matrices are taken from Blender's AgX implementation. Below are the differences between the implementation in this PR and the Filament (Blender) implementation using a custom software renderer as an example. There is almost no difference, but the Filament (Blender) implementation gives a slightly darker image.

AgX Look This PR Filament (Blender)
Default image image
Punchy image image
Golden image image

PavielKraskouski avatar Feb 12 '24 23:02 PavielKraskouski

Thanks! I really enjoy how "natural" AgX looks, as I did not like how ACES compressed the dark colors. This is really noticeable when using global illumination. AgX seems a bit brighter than the others. AgX punchy is a bit too punchy for my use-case (I'm sure it looks better after tweaking the assets for a bit.)

Tone-mapper Photo
Filmic afbeelding
ACES afbeelding
AgX afbeelding
AgX Punchy afbeelding

(Car model CC-BY Link to Sketchfab )

WrobotGames avatar Feb 16 '24 21:02 WrobotGames

It would be really nice if you guys could prioritize this for 4.3

Tonemappers affect the whole asset production pipeline, so with this we could go ham on making the assets without worrying that they'll look different later when upgrading to the release build. ~~(sorry if I didn't make much sense e.e)~~

MathyFey avatar Feb 21 '24 10:02 MathyFey

Comparison on Tonemapping a HDRI:

Tonemapper Godot Blender
None GodotNone BlendenNone
Filmic GodotFilmic BlendenFilmic
AgX GodotAgX BlendenAgX
AgX Punchy GodotAgXP BlendenAgXP
ACES GodotACES X

(Used 6.0 for white in Godot) Notes:

  • To me, AgX in Godot seems a bit too bright. This is compared to AgX in Blender and Filmic in Godot. As far as I know, AgX was designed as a Filmic replacement, so the brightness shouldn't differ this much.
  • AgX punchy in Godot looks a lot more punchy than in Blender. In this scene, it looks really nice, but is this what AgX punchy is meant to look like? Or is my Blender install off?

WrobotGames avatar Feb 22 '24 12:02 WrobotGames

It would be really nice if you guys could prioritize this for 4.3

Tonemappers affect the whole asset production pipeline, so with this we could go ham on making the assets without worrying that they'll look different later when upgrading to the release build. ~(sorry if I didn't make much sense e.e)~

This feature is also important for any global illumination upgrades since it will help a lot to achieve properly exposed areas (with more accurate colors in both dark and lit areas). Currently it's nearly impossible to achieve with existing modes.

ArseniyMirniy avatar Feb 22 '24 13:02 ArseniyMirniy

In this scene, it looks really nice, but is this what AgX punchy is meant to look like? Or is my Blender install off?

Want to comment on this. Originally Troy's original Punchy included a boosting of "CDL Saturation", on top of the original AgX that DID NOT HAVE OUTSET MATRIX!.

And afterwards in later edition, we added the ouset matrix to the Base AgX, then in Troy's version, "Punchy" was then completely removed. (Note there we also designed a "rotation" included in the inset/outset matrix, reason will be stated later in this post.)

I choose to add back the Punchy look, but since the boosting of "CDL Saturation" has already been replaced by the outset matrix, it's not needed anymore. So in the version I submitted to Blender, the Punchy look is a simple darkening without the boosting of "CDL Saturation". The original Punchy was a simple 1.35 power curve after AgX Base formation (which darkens the image), but due to OCIO's constrain, OCIO Looks are required to be pre-AgX-Base-Formation, so I had to move it to AgX Log pre formation, I tried to use some different curves to achieve in the final image the approximately the same middle grey and roughly the same "black level" as the post formation 1.35 power curve, though of course not going to be completely identical.

If the doubling of outset + "CDL Saturation" is what you folks think looks better, then feel free, but I have to stress the importance of checking out those EXR files I linked up there, please make sure after your modifications that those gradients in those EXRs are still smooth as always! Too much post formation chroma boosting can lead to unsmoothness, as some boundary condition might be triggered.

Google's Filament uses slightly different matrices. It says that the matrices are taken from Blender's AgX implementation.

I advise either go make your own rotation matrix by testing against many different challenging EXRs, or use the same one right there, it's for some compensation for Abney Effect etc. (note it's not a fix, it's currently impossible to fix Abney Effect, but the rotated matrix was tested by myself to at least somewhat compensate for it.) (Also note that the matrix was supposed to be used in BT.2020 formation space. I have already mentioned this in the three.js PR page I linked here earlier.)

EaryChow avatar Feb 22 '24 13:02 EaryChow

Using the EXR EaryCrow provided, you can see something is off with Godots AgX. (Sorry for filling up this thread with screenshots ehhh.) No tonemapping: afbeelding Filmic: afbeelding AgX: afbeelding AgX Punchy: afbeelding ACES (Godot only): afbeelding

WrobotGames avatar Feb 22 '24 15:02 WrobotGames

Blender Cycles CPU viewport clips negatives. Better view it in compositor. Just click use nodes, drag and drop exr, and shift ctrl left click. Or at least use Cycles GPU viewport.

EaryChow avatar Feb 23 '24 05:02 EaryChow

Agree with @WrobotGames. In fact, in https://github.com/godotengine/godot/pull/87260#pullrequestreview-1882991287 the AgX looks washed off and worse than Linear or Reinhard tonemap (esp. Close up shots).

AgX Punchy is well implemented though 👍

Spacedesolate avatar Feb 23 '24 06:02 Spacedesolate

TODO: Consider using specialization constants for each tonemapper in RenderingDevice shaders to improve performance a bit, as tonemapping methods are generally never switched during gameplay.

How much of a gain are we projecting? I don't feel like this would be in line with how easily runtime-modifiable Godot has been. Do we already use specialization constants for our existing methods?

surfacedfox avatar Feb 29 '24 02:02 surfacedfox

How much of a gain are we projecting? I don't feel like this would be in line with how easily runtime-modifiable Godot has been. Do we already use specialization constants for our existing methods?

We use specialization constants in the decal and projector shader code already, as well as different shadow filter quality settings. This means stuttering already occurs when switching between shadow filter quality settings, unless the pipeline has been cached beforehand.

If you really need to avoid PSO stutter when switching tonemapping modes, you could ensure they're precompiled by switching to the tonemapping modes for one frame when the project starts.

Calinou avatar Feb 29 '24 18:02 Calinou

:o I see, thank you so much!

surfacedfox avatar Feb 29 '24 22:02 surfacedfox

@Calinou Can you specify what is wrong with it? Why it wasn't approved and merged?

ArseniyMirniy avatar Jun 09 '24 13:06 ArseniyMirniy

I guess this PR just slipped through the crack and was forgotten about, considering how there were no activity for months.

atirut-w avatar Jun 09 '24 16:06 atirut-w

At least to me and some others, the current implementation isn't satisfactory as it doesn't handle highlights properly and the exposure is off. (Compared to godot aces and blender.)

Comparison: https://github.com/godotengine/godot/pull/87260#issuecomment-1959700664

I think it's really important that the AgX looks the same as the default AgX in blender. (AgX Punchy doesn't need to match blender, because AgX punchy in blender is just AgX with lowered expose, and can be easily replicated in godot if the base AgX looks the same. )

WrobotGames avatar Jun 09 '24 17:06 WrobotGames

Is this PR still being worked on?

radiantgurl avatar Jun 19 '24 19:06 radiantgurl

@Calinou it seems a little odd that there are still no replies since February. Any news? Can issues mentioned by @WrobotGames be fixed? Who has to review the merge?

ArseniyMirniy avatar Jun 20 '24 06:06 ArseniyMirniy

As far as I know, contributors are currently working on the upcoming 4.3 release, which is in beta. New features (such as this one) will probably be worked on after 4.3 has been released and when 'master' accepts new features.

WrobotGames avatar Jun 20 '24 07:06 WrobotGames

@Calinou @WrobotGames There's a new solution by Khronos Group: Khronos PBR Neutral Tone Mapper!

https://www.youtube.com/watch?v=iQ3m0CfuSmg

ArseniyMirniy avatar Jul 21 '24 15:07 ArseniyMirniy

I replied to the top comment on that video when it was released. (The one asking for disadvantages.)

This is what I said: "There are a few downsides. 1. Khronos does only work with sRGB output in blender. 2. Khronos darkens some of the shadow areas, giving it more contrast, but it is less accurate. 3. Khronos doesn't work well with big high exposure areas, like a sunset hdri. (Try the built in venice sunset hdri and you can see it looks completely wrong.)

Khronos is really designed for virtual product photography, and that is where it excels at."

I do not think this is a good option for a game engine, but if someone wants to implement it, sure, go ahead.

WrobotGames avatar Jul 21 '24 15:07 WrobotGames