Skybox blending and transitioning in real time

Hello peoples,

I would need some help on my current project. I’m trying to blend three different skyboxes (One for day, one for dusk / dawn, one for night) and make them transitioning smoothly according to the system time. But can’t manage to get through this. I’ve spent two fulls days on that. So if any of you could help me please !

Here’s what i have :

SkyboxCycle.cs

Here i’ll manage the cycles according to real time. The script is obviously not finished.

using System;
using UnityEngine;

public class SkyboxCycle : MonoBehaviour
{

    public Material skybox;
    public float ActualTime;

    public enum Dayphase
    {
        Dawn,
        Day,
        Dusk,
        Night
    }

    private void Update()
    {
        ActualTime = DateTime.Now.Hour;

        skybox.SetFloat("_Blend", Mathf.Lerp(skybox.GetFloat("_Blend"), ActualTime * 0.1f, Time.deltaTime));


    }
}

SjyboxBlend.Shader

Here’s my Shader managing the blending of the severals skyboxes.

Shader "RenderFX/Skybox Blended" {
    Properties {
        _Tint ("Tint Color", Color) = (1, 1, 1, 1)
        _Tint1 ("Tint Color one", Color) = (1, 1, 1, 1)
        _Tint2 ("Tint Color two", Color) = (1, 1, 1, 1)
        _Blend ("Blend", Range(0,1)) = 0.5
        _Skybox1 ("Skybox one", Cube) = ""
        _Skybox2 ("Skybox two", Cube) = ""
        _Skybox3 ("Skybox three", Cube) = ""
    }
    SubShader {
        Tags { "Queue" = "Background" }
        Cull Off
        Fog { Mode Off }
        Lighting On      
        Color [_Tint]
        Pass {
            SetTexture [_Skybox1] { combine texture }
            SetTexture [_Skybox2] { constantColor (0,0,0,[_Blend]) combine texture lerp(constant) previous }
            SetTexture [_Skybox2] { combine previous +- primary, previous * primary }
            SetTexture [_Skybox2] { combine texture }
            SetTexture [_Skybox3] { constantColor (0,0,0,[_Blend]) combine texture lerp(constant) previous }
            SetTexture [_Skybox3] { combine previous +- primary, previous * primary }
        }
    }
    Fallback "RenderFX/Skybox", 1
}

What is the problem ?

My Skyboxes are blending. But they are blending way too fast to each others. And i don’t get how to increase the Blend slider. I increased the value of the slider from 0 to 24, that’s not difficult, just needed to change the “Range” property, but it doesn’t increase the blending gap (the skyboxes will still be blending between 0 and 1, and after 1 the skybox is becoming darker and weirder until the max 24).

Also, how will i make the slider increase related to time ?

Thanks everyone.

First, don’t write code like this:

If you have more than one or two dots (.) in a single statement, you’re just being mean to yourself.

Putting it all one one line DOES NOT make it faster. That’s not how compiled code works.

How to break down hairy lines of code:

http://plbm.com/?p=248

Break it up, practice social distancing in your code, one thing per line please.

“Programming is hard enough without making it harder for ourselves.” - angrypenguin on Unity3D forums

“Combining a bunch of stuff into one line always feels satisfying, but it’s always a PITA to debug.” - StarManta on the Unity3D forums

I’m presuming the blend accepts values from 0.0 to 1.0

Provide it with such. Change it slower and the change should happen slower.

But before you go too much further, verify the shader itself works right when hand-fed numbers from 0 to 1

It will all be ratios. The System.DateTime class can give you real time.

Alternately, Time.deltaTime can help you advance a reliably-scaled amount of time per frame.

Thank you for your time.

I’ll break down more often my code. I know it’s not making compilation faster. I just prefer having on one line things that acts to do one action together.

Yes the blend accepts values from 0.0 to 1.0. That’s what i’m currently thinking. But is there a way to make it go from 0.0 to 24.0. Because it would ease the next steps ?
Anyway, the problem with the slider (when it is 0 min and 1 max) is that my first skyboxes in blending into the second one at 0.132 value, the second skybox is blending fast too on the third one, so in consequence you have the third skybox from 0.5 to 1. That’s not balanced. But can’t see where in the code it dispatch "Skybox one should blend to 0.132, then skybox 2 should blend with the third at 0.5, etc…). I’ll try to record and put it here.

Sorry for my bad explanations, english is not my native language.

Okay i manage to find a shader that does well the job. Just needed two skyboxes in fact not a third one.

Still blocked for the time feature.

Here is what i got now :

using System;
using UnityEngine;

public class SkyboxCycle : MonoBehaviour
{

    public Material skybox;
    public float ActualTime;



    private void Update()
    {
        ActualTime = DateTime.Now.Hour;
        float normalizedTime = Mathf.InverseLerp(0, 24, ActualTime);
        float ValueIncreaseTime = Mathf.Lerp(skybox.GetFloat("_CubemapTransition"), normalizedTime, Time.deltaTime);
        skybox.SetFloat("_CubemapTransition", ValueIncreaseTime);



    }


}

My internet is bad so can’t upload a video unfortunately. But can upload pictures.

So, about the new problem. I got the Cubemap transition slider from 0 to 1, i got a Cubemap exposure slider that can help me make the skybox more dayish or nightish, and i would like to play with this two related to real time. But it’s hard because days aren’t divide equally. Dusk is only 1-2 hours, Dawn same, Day and night last a long more. But the cubemap transition slider don’t know that, he is just blending the skyboxes and making transition on the blend. So from 0 to 0.2 i got day skybox, 0.2 to 0.8 i got dusk / dawn, 0.8 to 1 i got night.

Is there a way to slow the calculation between 0 to 0.2 so it takes more times, then accelerate the calculations between 0.2 to 0.8, and then make it back slower for night. And it should automatically do it related to System time.
In fact, when i think about it, it’s like the opposite of how it works in real life.

I’m confused…

You can use something like an AnimationCurve to change rates across a continuum like that.

You could also just treat day and night separately, iterating from 0 to 1 for day, then 0 to 1 for night, doing each one at its own speed, then blending them (fractionally) into a final output from 0 to 1.