Unity3D : Advance Skybox Blending for Day Night Cycle

Day Night Skybox Blending

Last time I already create day night cycle with smooth light and fog transition. now I will perfected last day night cycle  in this article by adding Skybox transition from day and night just like the demo bellow. For this functionality we need a custom skybox shader that contain 2 type of skybox and blend factor with range [0-1] type to get combination of 2 skybox texture.

This custom shader is created by Aras Pranckevicius from his article on Unify Community (Unity wiki). I use it and applying it with my DayNightController script in my previous article. Here is the demo scene for complete Day Night Cycle created by unity3D 4 Trial Pro edition.


First create new shader and name it SkyboxBlend, copy code bellow to our shader.

Shader "RenderFX/Skybox Blended" {
Properties {
	_Tint ("Tint Color", Color) = (.5, .5, .5, .5)
	_Blend ("Blend", Range(0.0,1.0)) = 0.5
	_FrontTex ("Front (+Z)", 2D) = "white" {}
	_BackTex ("Back (-Z)", 2D) = "white" {}
	_LeftTex ("Left (+X)", 2D) = "white" {}
	_RightTex ("Right (-X)", 2D) = "white" {}
	_UpTex ("Up (+Y)", 2D) = "white" {}
	_DownTex ("Down (-Y)", 2D) = "white" {}
	_FrontTex2("2 Front (+Z)", 2D) = "white" {}
	_BackTex2("2 Back (-Z)", 2D) = "white" {}
	_LeftTex2("2 Left (+X)", 2D) = "white" {}
	_RightTex2("2 Right (-X)", 2D) = "white" {}
	_UpTex2("2 Up (+Y)", 2D) = "white" {}
	_DownTex2("2 Down (-Y)", 2D) = "white" {}
}

SubShader {
	Tags { "Queue" = "Background" }
	Cull Off
	Fog { Mode Off }
	Lighting Off
	Color [_Tint]
	Pass {
		SetTexture [_FrontTex] { combine texture }
		SetTexture [_FrontTex2] { constantColor (0,0,0,[_Blend]) combine texture lerp(constant) previous }
		SetTexture [_FrontTex2] { combine previous +- primary, previous * primary }
	}
	Pass {
		SetTexture [_BackTex] { combine texture }
		SetTexture [_BackTex2] { constantColor (0,0,0,[_Blend]) combine texture lerp(constant) previous }
		SetTexture [_BackTex2] { combine previous +- primary, previous * primary }
	}
	Pass {
		SetTexture [_LeftTex] { combine texture }
		SetTexture [_LeftTex2] { constantColor (0,0,0,[_Blend]) combine texture lerp(constant) previous }
		SetTexture [_LeftTex2] { combine previous +- primary, previous * primary }
	}
	Pass {
		SetTexture [_RightTex] { combine texture }
		SetTexture [_RightTex2] { constantColor (0,0,0,[_Blend]) combine texture lerp(constant) previous }
		SetTexture [_RightTex2] { combine previous +- primary, previous * primary }
	}
	Pass {
		SetTexture [_UpTex] { combine texture }
		SetTexture [_UpTex2] { constantColor (0,0,0,[_Blend]) combine texture lerp(constant) previous }
		SetTexture [_UpTex2] { combine previous +- primary, previous * primary }
	}
	Pass {
		SetTexture [_DownTex] { combine texture }
		SetTexture [_DownTex2] { constantColor (0,0,0,[_Blend]) combine texture lerp(constant) previous }
		SetTexture [_DownTex2] { combine previous +- primary, previous * primary }
	}
}

Fallback "RenderFX/Skybox", 1
}

Now we have our new custom shader, next we have to create new Skybox material and use shader RenderFX > Skybox Blended, now set blend slider to 0 and apply skybox texture to our material according to this rule

  • Put Day Skybox (front) texture to “Front”
  • Put Night Skybox (front) texture to  ”2 Front”
  • Put Day Skybox (up) texture to “Up”
  • Put Night Skybox (up) texture to “2 Up”
  • and also put left, right, back, down texture according to it’s variable

We have our custom Skybox material, assign render Setting > Skybox material with our custom material above. and we add this code bellow to our DayNightController from previous tutorial

first we add new variable SkyboxBlendFactor to our script

// blend value of skybox using SkyBoxBlend Shader in render settings range 0-1
private float SkyboxBlendFactor= 0.0f;

and we create new void UpdateSkyboxBlendFactor() to our script

private void UpdateSkyboxBlendFactor(){
	if (currentPhase == DayPhase.Dawn)
	{
		float relativeTime = currentCycleTime - dawnTime;
		SkyboxBlendFactor = 1 - (relativeTime / halfquarterDay);
	}
	else if (currentPhase == DayPhase.Day)
	{
		SkyboxBlendFactor = 0.0f;
	}
	else if (currentPhase == DayPhase.Dusk)
	{
		float relativeTime = currentCycleTime - duskTime;
		SkyboxBlendFactor = relativeTime / halfquarterDay;
	}
	else if (currentPhase == DayPhase.Night)
	{
		SkyboxBlendFactor = 1.0f;
	}

	RenderSettings.skybox.SetFloat("_Blend", SkyboxBlendFactor);
}

Next we call UpdateSkyboxBlendFactor() to our Update() function after we update ambient light of Game world.

11 Opinion to this post

  1. Twisttid says:

    Is there anyway you can make this same sort of thing, but instead of gradually changing depending on time, instead it depends on position. For an example if you are in some sort of wilderness the sky may be blue but you might walk into a dark graveyard and the skybox will gradually fade to a darker, saturated sky.

  2. Twisttid says:

    I was wondering, is there anyway to do this type of thing but the Skybox changes depending on where you are?

    For an example, if you have played Oblivion, when your on the bottom of the mountain where the gate is open it’s just a normal blue sky but as you walk up the mountain it gradually gets redder and if you walk down it goes back to blue.

  3. [...] technique to smoothly transition from day skybox to night (stars & moon) skybox that can be read here. It’s a little modification from Day Night Controller on [...]

  4. David Flynn says:

    I like you little clock you set up how would I go about making this and using a real time?

  5. Terry Morgan says:

    I have the sun traveling across the sky, but I’m using sunny3 skybox for a base, I don’t
    get where are the nighttime textures? Could you post a unitypackage please?

  6. Marti Belegu says:

    I am having a problem with the script. Can you give me the full script that you could accomplish after this tutorial? If you don’t understand what I mean, I mean can you give me the script even after you add the both short scripts. I hope you understand! Please reply :D

  7. Nelson Salles says:

    Hi, thanks a lot for the free tutorials, they helped me a lot. There’s still a problem, thought: in Unity Free, it’s not possible to assign a render to the scene, so I can’t make the skybox blending work unless I have Unity Pro. Is there a workaround?

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Comment moderation is enabled. Your comment may take some time to appear.