Repository: godot
Issue: AgX has low dynamic range output with Mobile renderer
Labels: discussion,topic:rendering,topic:3d

### Tested versions

All Godot versions with the AgX tonemapper ( 084e84be7813e55acd3d3e909bd66229834bedb1 onward)

### System information

Windows 10 (build 19045) - Multi-window, 1 monitor - Vulkan (Forward+) - dedicated NVIDIA GeForce GTX 980 Ti (NVIDIA; 31.0.15.4665) - Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz (8 threads)

### Issue description

When using the AgX tonemapper with the Mobile renderer, it is not possible to output the full SDR dynamic range without either adjusting the exposure to be very high (and making your scene look very overexposed) or using adjustments such as `Brightness`. In some situations, it appears that the `Glow` effect can also be used to brighten the final output.

This is inconsistent with the existing tonemappers, which use the `White` parameter to enable full SDR dynamic range output, even with the Mobile renderer. For example, Reinhard suffers from the same issue when `White` is set to 16.0, but can be resolved by simply setting `White` to a lower value.

This problem stems from white being hardcoded to around 16 in the AgX tonemapper and the Mobile renderer only providing values up to 2.0 to the tonemapping function.

Forward+ provides values of most any range to the tonemapper, and thus does not exhibit this problem.

Mobile:
![Image](https://github.com/user-attachments/assets/e29f0093-c0d7-4caa-a799-9faf3859ab35)

Forward+:
![Image](https://github.com/user-attachments/assets/926c7788-1873-4e99-aab5-9c16d6457d97)

The best way to circumvent this issue that I have come up with is to set the `Brightness` adjustment in Godot to  `1.17` for Mobile to get full [0.0, 1.0] dynamic range output. This feels wrong to me because it is inconsistent with the typical solution of adjusting the white parameter of the tonemapper.

It also feels wrong because the hardcoded white value of 16 prevents the full and intended behaviour of the AgX tonemapper to be used on the Mobile renderer; colours do not correctly desaturate as they become brighter and the top part of the "S" contrast curve is entirely discarded. (Said differently: AgX behaves incorrectly on the Mobile renderer and adjustments can only mask the problem.)

![Image](https://github.com/user-attachments/assets/d80fcb7a-eb96-48c8-9fb8-0f77772a3535)

It appears that the original AgX PR actually had an adjustable `White` parameter, but [it was removed](https://github.com/godotengine/godot/pull/87260#issuecomment-2388786615).

### Compatibility Renderer

I have also had a scenario sometimes occur where the compatibility renderer will also output a reduced dynamic range due to only passing values in the range [0.0, 1.0] to the tonemapping function. Unfortunately, I haven't been able to reproduce this consistently.

Compatibility (only sometimes??):
![Image](https://github.com/user-attachments/assets/32089496-f782-4a92-b887-b6960d3f3a00)

### Steps to reproduce

1. Create a project with the Mobile renderer
2. Create a 3D scene with a WorldEnvironment node and set its tonemapper to be AgX
3. Add a very high energy DirectionalLight3D (16.0 energy, for example)
4. Add a MeshInstance3D with a Sphere mesh
5. Add a StandardMaterial3D to the mesh with a white Albedo color
6. Note that no matter how bright the light, the scene will only render up to a value of #dbdbdb (219/255)
7. Switch to Forward+ and note that it is possible to output #ffffff (255/255) with a bright light

This can also be tested using the "Gradients" scene of the [tone mapping and color correction demo from Calinou](https://github.com/Calinou/godot-demo-projects/tree/add-color-correction-demo).

### Minimal reproduction project (MRP)

[agx-low-out-range.zip](https://github.com/user-attachments/files/18427018/agx-low-out-range.zip)