- Home /
Having a changing Skybox depending on location of player
I have a large world in my game, and I wanted to have different skyboxes for different areas. What I mean is, if for example, the character is on top of a mountain, I want perhaps a cloudy Skybox, and if he is on flat land is sunny. I have no experience with scripting (sorry), and all I can really do is replace specific things in order to match with my game. How could I go about doing this?
Thanks :)
Answer by aldonaletto · Dec 29, 2012 at 04:52 PM
Check this article in the Unify Community: there's a shader that can blend between two different skyboxes, and another one that does the same and also adds fog.
EDITED
HOW TO USE:
Save the first shader as "SkyboxBlended.shader" in your Assets folder (or in one of its subfolders), then select it in the Project view and click Create->Material to make a SkyboxBlended material. Select this material and assign the six faces of each skybox to the appropriate texture slots, then in the Render Settings select it in the Skybox field. In the script, control the blending like this:
RenderSettings.skybox.SetFloat("_Blend", blendFactor);
where blendFactor is a float between 0 and 1. Just to test this, attach this simple script to some object (the camera, for instance):
function Update(){
var blend: float = Mathf.PingPong(0.2*Time.time, 1.0);
RenderSettings.skybox.SetFloat("_Blend", blend);
}
I have not tested the other shader yet - it needs a fog mask, and I'm trying to create one that works.
EDITED2
After trying some masks, I decided to modify the regular Skybox shader to include blending and fog, but this time using the UV coordinates instead of a fog mask:
Shader "RenderFX/Skybox Blended With Fog" {
Properties {
_FogColor ("Fog Color", Color) = (.5, .5, .5, .5)
_Fog ("Fog Intensity", Range(0.0,1.0)) = 1.0
_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 ("Front (+Z)", 2D) = "white" {}
_BackTex2 ("Back (-Z)", 2D) = "white" {}
_LeftTex2 ("Left (+X)", 2D) = "white" {}
_RightTex2 ("Right (-X)", 2D) = "white" {}
_UpTex2 ("Up (+Y)", 2D) = "white" {}
_DownTex2 ("Down (-Y)", 2D) = "white" {}
}
SubShader {
Tags { "Queue"="Background" "RenderType"="Background" }
Cull Off ZWrite Off Fog { Mode Off }
CGINCLUDE
#include "UnityCG.cginc"
fixed4 _FogColor;
fixed _Blend;
fixed _Fog;
struct appdata_t {
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct v2f {
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
v2f vert (appdata_t v) {
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.texcoord = v.texcoord;
return o;
}
fixed4 skybox_frag (v2f i, sampler2D sky1, sampler2D sky2, half fogBase) {
// calculate fog value: 100% at horizon, 0% at the top face
half fog = _Fog * saturate(lerp(2, 0, i.texcoord.y));
// mix skyboxes 1 and 2 according to _Blend
fixed4 tex = lerp(tex2D(sky1, i.texcoord), tex2D(sky2, i.texcoord), _Blend);
// apply fog: fogBase forces 100% if >=1, 0% if <= -1
tex = lerp(tex, _FogColor, saturate(fog + fogBase));
return tex;
}
ENDCG
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
sampler2D _FrontTex;
sampler2D _FrontTex2;
fixed4 frag (v2f i) : COLOR { return skybox_frag(i, _FrontTex, _FrontTex2, 0); }
ENDCG
}
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
sampler2D _BackTex;
sampler2D _BackTex2;
fixed4 frag (v2f i) : COLOR { return skybox_frag(i, _BackTex, _BackTex2, 0); }
ENDCG
}
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
sampler2D _LeftTex;
sampler2D _LeftTex2;
fixed4 frag (v2f i) : COLOR { return skybox_frag(i, _LeftTex, _LeftTex2, 0); }
ENDCG
}
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
sampler2D _RightTex;
sampler2D _RightTex2;
fixed4 frag (v2f i) : COLOR { return skybox_frag(i, _RightTex, _RightTex2, 0); }
ENDCG
}
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
sampler2D _UpTex;
sampler2D _UpTex2;
fixed4 frag (v2f i) : COLOR { return skybox_frag(i, _UpTex, _UpTex2, -1); } // no fog at top
ENDCG
}
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
sampler2D _DownTex;
sampler2D _DownTex2;
fixed4 frag (v2f i) : COLOR { return skybox_frag(i, _DownTex, _DownTex2, 1); } // 100% fog at bottom
ENDCG
}
}
}
It can be used exactly like the SkyboxBlended shader, but allows global fog intensity via the parameter _Fog. For better results, the _FogColor parameter should match the fog color defined in the Render Settings, what can be done at Start with this simple code:
function Start () {
RenderSettings.skybox.SetColor("_FogColor", RenderSettings.fogColor);
}
Thanks! How would I apply this to my game? Like I said, I'm awful with scripting :L
Ok, that's a little tricky - I'll edit the answer to include a "How To Use" section.
Hey @aldonaletto where in the script do we add the blend controller " RenderSettings.skybox.SetFloat("_Blend", blendFactor);"? Can upload a completely finished script and create a tutorial on youtube possibly?
Also @aldonaletto, it doesnt fully transition btw the textures and it resets (not fading) when it finishes. Could u plz help?
Your answer
Follow this Question
Related Questions
How to write a script which will switch the scene after the character reached a location? 1 Answer
Changing tint color of skybox via script 2 Answers
Character Controller Script 3 Answers
Player or character select 2 Answers
I'd like to add frictionless movment to my character with key press. 1 Answer