- Home /
how to rotate a skybox on the z or x axes?
hey there! we are currently working on a endlessrunner for android devices and our question is, is it possible to rotate the skybox on the x or z axis via javascript? afaik, there is a possibility to rotate the skybox on the y-axis but not on the other ones. i hope you can help me :)
thanks in advance PhobosPhosphor
Answer by FortisVenaliter · May 12, 2015 at 04:18 PM
I don't think so, but you could make a separate camera for the skybox only and rotate it instead of the actual skybox. Then just render your regular game over that.
Like this:
You create a second camera and name it SkyBoxCam.
You set the cameras culling mask of the SkyBoxCam to None
You set the clear flags of the SkyBoxCam to SkyBox
You set the clear flags of the $$anonymous$$ain camera to None or Depth Only
$$anonymous$$ake sure your SkyBoxCam has a lower depth than the main camera. By default the main camera has a depth of "-1", so setting the SkyBoxCam depth to "-2" should work
The SkyBoxCam should be placed directly in the scene.
Now just rotate the SkyBoxCam the way you want
Answer by sergiobd · Nov 10, 2018 at 05:50 PM
You can also edit the shader. This is a 6 - sided shader with an arbitary rotation axis: (Edited from Unity built-in shaders, copied rotation matrix from here)
// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
Shader "Skybox/6 Sided - Arbitrary Rotation" {
Properties {
_Tint ("Tint Color", Color) = (.5, .5, .5, .5)
[Gamma] _Exposure ("Exposure", Range(0, 8)) = 1.0
_Rotation ("Rotation", Range(0, 360)) = 0
_RotationAxis("Rotation axis", Vector) = (0, 1, 0)
[NoScaleOffset] _FrontTex ("Front [+Z] (HDR)", 2D) = "grey" {}
[NoScaleOffset] _BackTex ("Back [-Z] (HDR)", 2D) = "grey" {}
[NoScaleOffset] _LeftTex ("Left [+X] (HDR)", 2D) = "grey" {}
[NoScaleOffset] _RightTex ("Right [-X] (HDR)", 2D) = "grey" {}
[NoScaleOffset] _UpTex ("Up [+Y] (HDR)", 2D) = "grey" {}
[NoScaleOffset] _DownTex ("Down [-Y] (HDR)", 2D) = "grey" {}
}
SubShader {
Tags { "Queue"="Background" "RenderType"="Background" "PreviewType"="Skybox" }
Cull Off ZWrite Off
CGINCLUDE
#include "UnityCG.cginc"
half4 _Tint;
half _Exposure;
float _Rotation;
float3 _RotationAxis;
float3 RotateAroundYInDegrees (float3 vertex, float degrees)
{
float alpha = degrees * UNITY_PI / 180.0;
float sina, cosa;
sincos(alpha, sina, cosa);
float2x2 m = float2x2(cosa, -sina, sina, cosa);
return float3(mul(m, vertex.xz), vertex.y).xzy;
}
float4x4 rotationMatrix(float3 axis, float angle)
{
axis = normalize(axis);
float s = sin(angle);
float c = cos(angle);
float oc = 1.0 - c;
return float4x4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0,
oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0,
oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0,
0.0, 0.0, 0.0, 1.0);
}
struct appdata_t {
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f {
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_OUTPUT_STEREO
};
v2f vert (appdata_t v)
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
//float3 rotated = RotateAroundYInDegrees(v.vertex, _Rotation);
float3 rotated = mul( rotationMatrix( normalize(_RotationAxis.xyz), _Rotation * UNITY_PI / 180.0), v.vertex).xyz;
o.vertex = UnityObjectToClipPos(rotated);
o.texcoord = v.texcoord;
return o;
}
half4 skybox_frag (v2f i, sampler2D smp, half4 smpDecode)
{
half4 tex = tex2D (smp, i.texcoord);
half3 c = DecodeHDR (tex, smpDecode);
c = c * _Tint.rgb * unity_ColorSpaceDouble.rgb;
c *= _Exposure;
return half4(c, 1);
}
ENDCG
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
sampler2D _FrontTex;
half4 _FrontTex_HDR;
half4 frag (v2f i) : SV_Target { return skybox_frag(i,_FrontTex, _FrontTex_HDR); }
ENDCG
}
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
sampler2D _BackTex;
half4 _BackTex_HDR;
half4 frag (v2f i) : SV_Target { return skybox_frag(i,_BackTex, _BackTex_HDR); }
ENDCG
}
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
sampler2D _LeftTex;
half4 _LeftTex_HDR;
half4 frag (v2f i) : SV_Target { return skybox_frag(i,_LeftTex, _LeftTex_HDR); }
ENDCG
}
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
sampler2D _RightTex;
half4 _RightTex_HDR;
half4 frag (v2f i) : SV_Target { return skybox_frag(i,_RightTex, _RightTex_HDR); }
ENDCG
}
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
sampler2D _UpTex;
half4 _UpTex_HDR;
half4 frag (v2f i) : SV_Target { return skybox_frag(i,_UpTex, _UpTex_HDR); }
ENDCG
}
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
sampler2D _DownTex;
half4 _DownTex_HDR;
half4 frag (v2f i) : SV_Target { return skybox_frag(i,_DownTex, _DownTex_HDR); }
ENDCG
}
}
}
If you are using another Unity skybox shader, should be as easy to edit: 1. Download built-in shaders from Unity downloads 2. Search for the one you need and place it in your assets 3. Change its name 4. Add axis variables 5. Comment "RotateAroundYInDegrees(v.vertex, _Rotation);" 6. Copy rotation matrix function from the code above, and add line for rotation.
That should make it.
This solution works well. Question from a shader noob: Would it be a good idea to have the angle and/or axis as a property and change it every frame at runtime? I think slowly rotating my outer space-skybox as the player's spaceship moves, viewed from a top-down camera, as a good way to mimic a parallax-scroll, but I don't know if doing so would be a massive hit on the performance.
with this shader I can only change one axis at a time, is there a way to rotate the three axis separately?
Answer by tuyenduy · May 26, 2020 at 04:00 AM
This may help, put it in any of your camera controller script: C#
float skyboxStartAngle = 30f;
void Start()
{
RenderSettings.skybox.SetFloat("_Rotation", skyboxStartAngle );
}
Answer by Duster_2015 · May 16, 2021 at 08:26 PM
Took some time, but if anyone is looking to rotate the skybox vertically, I combined Bunny83's steps with some code and now You can rotate the skybox vertically.
Create a second camera and name it SkyBoxCam.
Set the cameras culling mask of the SkyBoxCam to None
Set the clear flags of the SkyBoxCam to SkyBox
Set the clear flags of the Main camera to None or Depth Only (newer Unity's)
Now make sure your SkyBoxCam has a lower depth than the main camera. By default the main camera has a depth of "-1", so setting the SkyBoxCam depth to "-2" or less will work fine.
Place your SkyBoxCam directly in the scene, Example: (0, 0, 1).
Now, create a C# script as follows:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SkyBoxCamRotate : MonoBehaviour
{
public static class AxisInput
{
public const string Horizontal = "Horizontal";
public const string Vertical = "Vertical";
}
// Update is called once per frame
void Update()
{
float speed = Input.GetAxisRaw(AxisInput.Horizontal) * 5.0f;
transform.Rotate(-0.02f, 0, 0);
}
}
Now Your done!