Search Unity

Pure white background impossible?

Discussion in 'High Definition Render Pipeline' started by MatijsK, Jul 30, 2020.

  1. MatijsK

    MatijsK

    Joined:
    Nov 16, 2016
    Posts:
    6
    Hi all,

    We are using unity3d 2019.3 hdrp.

    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?

    HDRP is very hard to understand for me

    Thx a lot
     
  2. francescoc_unity

    francescoc_unity

    Unity Technologies

    Joined:
    Sep 19, 2018
    Posts:
    193
    Do you have auto-exposure in one of your volume profiles? (Or if you don't, is it on on the default volume https://docs.unity3d.com/Packages/c...ition@9.0/manual/Default-Settings-Window.html ? )

    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.
     
  3. MatijsK

    MatijsK

    Joined:
    Nov 16, 2016
    Posts:
    6
    No, both exposures is already on fixed. I dont know where to look now
     
  4. pierred_unity

    pierred_unity

    Unity Technologies

    Joined:
    May 25, 2018
    Posts:
    433
    Hey,

    See if using an unlit hdrp shader for this background mesh can help (and increase the emissive intensity to reach pure white).

    Another user already asked a related question (reaching pure white), and based on my test, it's totally doable.
     
  5. francescoc_unity

    francescoc_unity

    Unity Technologies

    Joined:
    Sep 19, 2018
    Posts:
    193
    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 https://en.wikipedia.org/wiki/Film_speed ); 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.
     
  6. MatijsK

    MatijsK

    Joined:
    Nov 16, 2016
    Posts:
    6
    Thanx guys, We dont use any backgroundmesh ... just a all white backgroundcolor in the Cams.
     
  7. MatijsK

    MatijsK

    Joined:
    Nov 16, 2016
    Posts:
    6
    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 ??
     
  8. pierred_unity

    pierred_unity

    Unity Technologies

    Joined:
    May 25, 2018
    Posts:
    433
    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.
     
  9. MatijsK

    MatijsK

    Joined:
    Nov 16, 2016
    Posts:
    6
    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.
     
  10. SebLagarde

    SebLagarde

    Unity Technologies

    Joined:
    Dec 30, 2015
    Posts:
    934
    Hey,

    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 http://en.wikipedia.org/wiki/Film_speed).


    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

    // maxLum = 78 / ( S * q ) * N^2 / t

    // = 78 / ( S * q ) * 2^ EV_100

    // = 78 / (100 * s_LensAttenuation) * 2^ EV_100

    // = 1.2 * 2^ EV // For s_LensAttenuation of 0.65

    // Reference: http://en.wikipedia.org/wiki/Film_speed

    float maxLuminance = 1.2 * pow(2.0, EV100);

    return 1.0 / maxLuminance;

    }


    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 https://en.wikipedia.org/wiki/Exposure_value) which depends on a calibration constant.

    For HDRP we use a calibration constant of 12.5 as highlighted in the wikipedia article.


    /// <summary>

    /// 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.

    /// </summary>

    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)

    {

    const float k = s_LightMeterCalibrationConstant ;

    return (float)Math.Log((luminance * 100f) / k, 2);

    }


    Note that a value of EV100 of 0 means 0.125 nits.


    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




    And it also handle Color as sRGB color space.

    Generate code is :

    float3 _EmissionNode_f6f4d90ac90f4578a36d8de8e453e458_Output_0 = Unity_HDRP_GetEmissionHDRColor_float(IsGammaSpace() ? float3(0.19, 0.19, 0.19) : SRGBToLinear(float3(0.19, 0.19, 0.19)).xyz, 1, 1, inverseExposureMultiplier);


    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.


    In HDRP use Burley’s Diffuse term (view dependent, influenced by roughness - https://disney-animation.s3.amazonaws.com/library/s2012_pbs_disney_brdf_notes_v2.pdf) as diffuse term. It is possible to switch to Lambert in the shader code. File lit.hlsl, at the beginning of the file, enable the define


    #define USE_DIFFUSE_LAMBERT_BRDF


    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.
     
  11. MatijsK

    MatijsK

    Joined:
    Nov 16, 2016
    Posts:
    6
    WOW @SebLagarde Thanks a lot for your extensive reply! We will dive into it
     
  12. andyz

    andyz

    Joined:
    Jan 5, 2010
    Posts:
    2,269
    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'!
     
  13. francescoc_unity

    francescoc_unity

    Unity Technologies

    Joined:
    Sep 19, 2018
    Posts:
    193
    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.
     
    andyz likes this.