For several clients we need a pure white background to match their websites.
Now all white backgrounds and white textures turned out grey-ish. Even with tonemapping disabled or in “none”.
Where can we find the magic button that disable all the postprocessing or tonemapping?
We need white, not grey!
Why is a pure white colour so hard to achieve?
Auto exposure maps the average scene luminance to a middle grey value (akin to what happens in real cameras), so if your scene is completely white it will map it to a grey value and it is expected.
If that’s the case, you can set the exposure to a fixed value that works best for you or apply an exposure compensation to your scene.
Also, important to keep in mind that in HDRP we use EV100 for camera exposure and sky intensity and we take into account lens imperfections (see Film speed - Wikipedia ); in HDRP 9+ we allow the user to change this imperfection factor (in debug settings for now only).
What this mean is that some of the light our virtual camera receives is dispersed due to lens transmission and vignetting.
Ahaaaa! that we didnt know … Not everyone wants to use fancy stuff We use scanned textures and need to be like real. We absolutely dont want to use any fx to lose colour accuracy…
so we have to wait for 9+ then ??
You could apply exposure compensation (in the “Exposure” volume component) to compensate for the imperfect lens transmission.
However, why not use a custom mesh with an unlit emissive shader to handle the background, as proposed above? it would let you have total control, without having to fiddle very much with the exposure. It could even be just a sphere with inverted normals, that you attach to the camera.
Absolutely right for this background, but that doesnt solve the grey-ish “white” textures issue which we are also fighting against. We make product configurators, so we are not your average game studio …
So we have more issues then just a background colour. But thanks for all the help for now! We have to wait for more control of default camera settings.
here is some information which should help you (sorry for the big post, but this was extract from an internal document)
In this document, we read the various value of the buffer with debug color picker of HDRP
And enable the Always refresh option:
The value read is affected by exposure but not by any postprocess. The value is linear RGB (i.e what you get when exporting with .exr in Recorder).
Unity HDRP EV100 as a multiplier for camera color buffer and sky
In Unity we use EV100 and not EV for all our camera exposure control and sky intensity multiplier. EV100 takes into account lens imperfections (See Film speed - Wikipedia).
We chose the value define in wikipedia of 0.65 for lens imperfection
/// Factor used for our lens system w.r.t. exposure calculation. Modifying this will lead to a change on how linear exposure
/// multipliers are computed from EV100 values (and vice versa). s_LensAttenuation models transmission attenuation and lens vignetting.
/// Note that according to the standard ISO 12232, a lens saturates at s_LensAttenuation = 0.78f (under ISO 100).
static public float s_LensAttenuation = 0.65f;
And the conversion function from EV100 to a multiplier is define like this:
float ConvertEV100ToExposure(float EV100)
{
// Compute the maximum luminance possible with H_sbs sensitivity
Note that a value of EV100 of 0 produces a final multiplier of 0.83333 and not 1.
To get 1 the value of EV100 should be log2(1 / 1.2) = -0.26303
The lens imperfection in HDRP 8.x can’t be configured and is fixed to 0.65.
In HDRP 9.x-preview and 10.x it can be configured for debug validation purposes. Change the value to 0.78 to have a EV100 matching a 1 multiplier in HDRP. [Caution: When changing the debug lens attenuation it is required to update the static lighting (sky ambient probe, light probe, lightmap) to have the sky value contribute correctly as the exposure rely on multiplier that take into account the lens attenuation]
Note: Using the same multipliers for exposure control and Sky allow us to easily match visuals. If the sky was in EV with luminance unity instead of multiplier it would be less obvious how to make them match.
Unity HDRP EV100 as a Unit for lighting
Unity HDRP also uses EV100 as a convenient way to setup Emissive or Light intensity (See Exposure value - Wikipedia) which depends on a calibration constant.
For HDRP we use a calibration constant of 12.5 as highlighted in the wikipedia article.
///
/// Calibration constant (K) used for our virtual reflected light meter. Modifying this will lead to a change on how average scene luminance
/// gets mapped to exposure.
///
static public float s_LightMeterCalibrationConstant = 12.5f;
Which results in the following conversion function.
// Convert from EV100 to nits
public static float ConvertEvToLuminance(float ev)
{
Mathf.Pow(2, ev - 3);
}
// Convert from nits to EV100
public static float ConvertLuminanceToEv(float luminance)
Validation with white sky background
Our lens is not perfect, when setting a white sky (Gradient sky of 1, exposure 0, no Fog, no tonemap) we get a value on a gradient sky of 0.6875
If setting the lens attenuation factor in the new debug menu option to a perfect lens (0.78 factor) we get a white background as white (1)
Unlit shader validation
Unlit shaders have two properties to display something on the screen. One is Color and the other is Emissive Color.
The Emissive Color is split in two different controls.
Emissive HDR color (with a HDR color picker) when not using the Use Emissive Intensity property. This property is in linear color space as it is HDR. HDR color texture (.exr) can be provided.
Emissive LDR color (with a LDR color picker) when using the Use Emissive Intensity property. This property is in sRGB color space and will be converted to linear before being sent to the shader. Color textures are expected to be imported with sRGB flags for this property. [CAUTION: Before Unity 10.x the constant property was incorrectly set as linear RGB instead of sRGB color space]
Note that Shader Graph Unlit shader have similar control with the Emission Node
Unity HDRP uses a pre-exposition concept. The lighting is pre-expose during the lighting pass instead of exposing the color buffer at the end of the pipeline to increase precision.
Color input of the Unlit shader isn’t pre-expose as it isn’t related to lighting and thus by-pass the exposure computation. Thus a value of 0.19 in Unlit will not change and give an output of 0.19 .
However the Emissive component is a lighting component and thus is pre-expose. And thus a value of 0.19 in Emissive Color HDR with our lens imperfection of 0.65 give 0.158
With a perfect lens (0.78), we get the correct 0.19 value.
With a value of 0.19 for Emissive Color LDR with our lens imperfection of 0.65 give 0.025
With a perfect lens (0.78), we get the correct 0.03 value (was converted to linear RGB) [Only in 10.x version otherwise it display 0.19 in previous version]
Lit shader in HDRP
Lit shader have a diffuse / Base Color property and Emission. Emission work exactly like for Unlit shader so it will not be repeat here.
We only use this define for validation purposes. Artists use Disney diffuse BRDF in practice.
The baseColor uses sRGB color space. Textures are expected to have sRGB flags enabled in import settings.
White furnace test. Setup a Gradient sky to 1. Check the lux meter mode. The receive lighting at the location of a cube should be PI (We get 3.125 below due to approximation).
Note: Lux meter is independent of Lit BaseColor. Be sure to have the static sky correctly updated in Lighting settings as Lux meter is ready the SH ambient probe. Integral of white sky (1) over the hemisphere is PI.
A lambertian surface of baseColor 0.19 lit by a white furnace must have a response of 0.03 (sRGB convert to linear). To setup such a test in HDRP, you need to use a perfect lens (0.78), and white gradient sky (1) - exposure 0 without any lights, be sure it is in static lighting and the SH ambient probe is up to date. No fog, no tonemap. Scene exposure at 0. Switch to debug mode DiffuseLighting only (to remove the specular contribution).
Have USE_DIFFUSE_LAMBERT_BRDF in lit.hlsl then you will correctly get 0.03.
Important: All those setup (Lambertian surface, perfect lens), are only used for validation of the pipeline. In practice they are not required for the artists as artists are dealing with physical light units for lights rig and tend to prefer Burley Diffuse BRDF. With a sun of 100K lux and a HDRI sky at 20K lux, what matters is the visual result, all the accurate numbers are only to validate that the render pipeline works as expected, thus why all those settings are “hidden”.
Decal shader in HDRP
The BaseColor and Emission follow the same rules as for the Lit shader.
This is a useful reply but [from a quick read] I can not understand why it is setup that a white gradient sky (by the way where is plain ambient color/sky?) is so far off appearing white.
Instead of exactly recreating cameras, allow users to have colours appear in the full range they provide, otherwise getting things to appear on screen as intended means calculating how to undo ‘degradation’!
In upcoming 10.1.0 package you will be able to set the lens attenuation factor in the default settings; specifically you can set to perfect lens hence avoiding the loss of energy if you desire so.