Search Unity

Baked Lights with Realtime Ambient?

Discussion in 'Global Illumination' started by CDF, Jul 20, 2017.

  1. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    1,311
    Hi, first off I'm making a Mobile game, so my realtime lighting options are limited.

    I'm trying to achieve an effect where I can go between night/day lighting. I only wish to change the intensity/color of light, the direction of the sun won't change, just the effect of the world getting darker.

    Problem is, in order to make it feel dark I need to bake the ambient at a dark value so that when I adjust the light intensity to something like 0.1, the realtime light matches with the baked light. This presents a problem when it's day time, the ambient is so dark on the baked objects making the scene look very unnatural. Changing the ambient color has no effect on baked objects.

    The solution is to use realtime GI with realtime ambient. But that is burning up my poor tiny little iPhone 5s.

    I'm pretty new to lighting, usually someone else does this stuff, but unfortunately it's up to me now. Wondering if there are any solutions to this problem for Mobile?

    I've tired making a white cubemap and setting that to my "Environment Relfections" source. While that does boost the blacks, everything kinda looks washed out.

    Should I look at the post processing stack for this? Seeing as the sun won't move, maybe I can just color grade the scene?
     
  2. Khazmadu

    Khazmadu

    Joined:
    Jun 24, 2017
    Posts:
    92
    You could bake all Lights and multiply the Lightmap with a color on runtime.
    I can't tell you how to do that exactly but with this approche there is absolutly no light that needs to be calculated in realtime.
     
  3. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    1,311
    yeah I think something like that is my only option here. Modifying all shaders used on static objects so their lightmaps are multiplied by a color. Seems odd to me this doesn't exist already and that ambient light cannot be changed for static objects unless realtime GI is used. Probably because it contributes to indirect light, so without recalculating that the change in ambient wouldn't be correct. But... I've already got indirect light baked and the difference (I think) of just tinting something black vs recalculating ambient is minimal.

    Guess I'll head over to shader land and override the surface shader GI function
     
  4. Khazmadu

    Khazmadu

    Joined:
    Jun 24, 2017
    Posts:
    92
    Another way would be postprocessing. You can render your Camera in HDR and use the grading tools to animate brightness and Tint.
    But I have no idea if this is fast enought for mobile.
     
  5. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    It's not, it would lead to a fairly large perf degradation and not even work on older mobiles (HDR) as it depends on support.

    But stuff like using lightprobes and blending between lightmaps works a treat still. Also you don't really need HDR for grading I thought?
     
  6. Khazmadu

    Khazmadu

    Joined:
    Jun 24, 2017
    Posts:
    92
    You will need HDR if you want to change day to night or you will get extrem bandings.
     
  7. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    11,791
    1. Blending 2 baked lightmaps is the way to go I think, especially if you are performance conscious. I did it with a lerp within my own shader, but there could potentially be easier ways.

    2. Blending between two sets of light probes was a bit problematic though (or at least, I couldn't figure it out at the time).

    3. Faking it with post processing color correction is also perfectly doable. You don't need HDR. You just might be a bit more prone to banding if you push things too far.
     
  8. AcidArrow

    AcidArrow

    Joined:
    May 20, 2010
    Posts:
    11,791
    If he starts with day and darkens everything (and maybe a blue tint), he shouldn't get too much banding. Usually banding appears when you're stretching the dynamic range, not when you're compressing it further.
     
  9. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    1,311
    Ah ok, so I'll still need to override the GI calculation to perform the lightmap blending correct?

    I've come across a lightmap switcher, but I guess that's just hard cuts between different lighting scenarios
     
  10. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    1,311
    Anyone know what I'm doing wrong here?

    I pretty much copied the syntax of the "custom GI" example here: https://docs.unity3d.com/Manual/SL-SurfaceShaderLightingExamples.html

    but I just get:
    Code (CSharp):
    1. Shader error in 'Mobile/Diffuse Static': Fragment program 'frag_surf': Unrecognized sampler 'samplerunity_lightmap' - does not match any texture and is not a recognized inline name (should contain filter and wrap modes).
    2. (on d3d11)
    3.  
    4. Compiling Fragment program with DIRECTIONAL SHADOWS_SCREEN LIGHTMAP_ON LIGHTMAP_SHADOW_MIXING SHADOWS_SHADOWMASK
    5. Platform defines: UNITY_NO_DXT5nm UNITY_ENABLE_REFLECTION_BUFFERS UNITY_NO_CUBEMAP_ARRAY UNITY_NO_SCREENSPACE_SHADOWS UNITY_PBS_USE_BRDF2 SHADER_API_DESKTOP UNITY_HARDWARE_TIER3 UNITY_COLORSPACE_GAMMA
    6.  
    If I comment out "gi = UnityGlobalIllumination(data, 1.0, s.Normal);" then no error, but no GI calculation.
    If I comment out "gi.indirect.diffuse = half3(0, 1, 0);" then no error, but no custom GI.

    So...

    The example uses the inbuilt functions. Is this some limitation of SurfaceOutput not being the same as SurfaceOutputStandard

    :(

    Code (CSharp):
    1. Shader "Mobile/Diffuse Static" {
    2.  
    3.     Properties {
    4.         _MainTex ("Base (RGB)", 2D) = "white" {}
    5.     }
    6.  
    7.     SubShader {
    8.      
    9.         Tags { "RenderType"="Opaque" }
    10.         LOD 150
    11.  
    12.         CGPROGRAM
    13.         #pragma surface surf StaticGI noforwardadd
    14.  
    15.         sampler2D _MainTex;
    16.  
    17.         struct Input {
    18.             float2 uv_MainTex;
    19.         };
    20.  
    21.         inline fixed4 LightingStaticGI(SurfaceOutput s, UnityGI gi) {
    22.          
    23.             return LightingLambert(s, gi);
    24.         }
    25.  
    26.         inline void LightingStaticGI_GI(SurfaceOutput s, UnityGIInput data, inout UnityGI gi) {
    27.  
    28.             gi = UnityGlobalIllumination(data, 1.0, s.Normal);
    29.  
    30.             //test
    31.             gi.indirect.diffuse = half3(0, 1, 0);
    32.         }
    33.  
    34.         void surf(Input IN, inout SurfaceOutput o) {
    35.          
    36.             fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
    37.             o.Albedo = c.rgb;
    38.             o.Alpha = c.a;
    39.         }
    40.      
    41.         ENDCG
    42.     }
    43.  
    44.     Fallback "Mobile/VertexLit"
    45. }
    46.  
     
  11. CDF

    CDF

    Joined:
    Sep 14, 2013
    Posts:
    1,311
    why is this happening??

    gi.indirect.diffuse *= half3(0, 1, 0); //Works
    gi.indirect.diffuse = half3(0, 1, 0); //Error