Search Unity

  1. The 2022.1 beta is now available for testing. To find out what's new, have a look at our 2022.1 beta blog post.
    Dismiss Notice

Rotate a Skybox?

Discussion in 'Editor & General Support' started by maxwood, Apr 3, 2012.

  1. maxwood

    maxwood

    Joined:
    Mar 28, 2012
    Posts:
    30
    Hi everyone,

    Does anyone know how I can rotate a skybox so it matches the position of my directional light?

    I don't want to animate it just rotate it into the correct position. It's important that it matches the directional light rather than the other way around.

    I'm using the included "DawnDusk Skybox"

    Thanks in advance,

    Max
     
  2. PolyMad

    PolyMad

    Joined:
    Mar 19, 2009
    Posts:
    2,282
    +1

    This is something that I wonder since long time why no engine allows a parameter of skybox rotation.
    It should be so easy to do, I think, and so useful!
    I place the light with the right direction only to find then that I have to rerender the skybox or make another one entirely because I can't adjust the original one.
    I found myself again recently in the same condition. Luckily I have my solution to create skyboxes in Max very easily so it wasn't a problem but I guess not everybody has the knowledge or time to do this so an option to rotate the skybox would be definitely useful.
     
  3. Johnny-Photon

    Johnny-Photon

    Joined:
    Sep 4, 2011
    Posts:
    84
    Maybe I'm missing something but since the skybox is composed of separate images right left etc. why don't you just copy the images into the orientation you want and rotate the overhead one?
     
  4. PolyMad

    PolyMad

    Joined:
    Mar 19, 2009
    Posts:
    2,282
    Probably because he (like me) needs finer tuning than 90 degrees :D

    After all, the skybox, for what I know, is really a geometry box so why not allow to draw it rotated respect to the cam?
     
  5. maxwood

    maxwood

    Joined:
    Mar 28, 2012
    Posts:
    30
    You can swap out each front/back/etc but it's not giving the position I want.
     
  6. Screenhog

    Screenhog

    Joined:
    Jul 2, 2009
    Posts:
    496
    Why not fake a skybox instead?

    - Create an empty GameObject.
    - Add 6 Unity plane objects. Form them into a cube with the normals pointing inward. Parent planes to GameObject (preferably with GameObject in the center of the cube).
    - Make six Unlit materials, one for each face of the cube. Make materials for the six textures that make up the skybox.
    - Apply the materials to the skybox in such a way that, when looking at it from the inside, it looks like a skybox.
    - Make a new layer called "Skybox". Add your fake skybox to that layer.
    - Make a new camera. Set it to only render the Skybox layer. Set its depth below the depth of your main camera.
    - Make sure your main Camera does not render the Skybox layer.
    - Position the new camera in the center of your fake skybox.
    - Write a script to make the new camera copy the rotation of your main camera.

    You should now have a fake Skybox. If you want to rotate the skybox by itself, you can just rotate the GameObject.
     
    saltysquid likes this.
  7. PolyMad

    PolyMad

    Joined:
    Mar 19, 2009
    Posts:
    2,282
    Yeah that's the first solution I thought of, Screenhog, thank you anyway, but the best solution, seeing that we already have a skybox built-in Unity, would be from them to add this option, right? :D
     
    KUFgoddess likes this.
  8. DESIMA

    DESIMA

    Joined:
    Aug 19, 2013
    Posts:
    1
    This was my solution to the problem.

    I make my skybox Unity way.

    then make an GameObject to put all my components in the scene in including my cam.
    Now I can rotate that object and the skybox background changes but the game setup is still the same.
    you may have to change the scrips to handle this rotation.
     
    KUFgoddess likes this.
  9. scottm361

    scottm361

    Joined:
    Sep 22, 2013
    Posts:
    2
    Hang on, there is a much simpler solution than this. It's always best to use the built in stuff if you can, and in this case it's not too hard.

    Heres what you can do:
    1. Add a second camera named "SkyboxCamera" to whatever game object your "main camera" is attached to.
    2. Set the clear flags of your Main camera to "don't clear" in the inspector
    3. Set the clear flags of "SkyboxCamera" to be "skybox", and set the depth of "SkyboxCamera" to be 1 less than the depth of "MainCamera in the inspector, and the culling mask of "SkyboxCamera" to be "nothing"
    4. add a script like below (or your own customized version) to your game object
    5. set the MainCamera and SkyCamera variables of the script in the inspector
    6. create your Unity Skybox and attach it to the "SkyboxCamera" in the inspector
    7. set the rotation of the script in the inspector if you need to rotate your skybox only intially, otherwise you set it in an update function if you want the skybox to rotate while running

    Good luck!

    Code (csharp):
    1. public class SkyboxCamera : MonoBehaviour {
    2.  
    3.    
    4.     // set the main camera in the inspector
    5.     public Camera MainCamera;
    6.    
    7.     // set the sky box camera in the inspector
    8.     public Camera SkyCamera;
    9.    
    10.     // the additional rotation to add to the skybox
    11.     // can be set during game play or in the inspector
    12.     public Vector3 SkyBoxRotation;
    13.  
    14.     // Use this for initialization
    15.     void Start()
    16.     {
    17.         if (SkyCamera.depth >= MainCamera.depth)
    18.         {
    19.             Debug.Log("Set skybox camera depth lower "+
    20.                 " than main camera depth in inspector");
    21.         }
    22.         if (MainCamera.clearFlags != CameraClearFlags.Nothing)
    23.         {
    24.             Debug.Log("Main camera needs to be set to dont clear" +
    25.                 "in the inspector");
    26.         }
    27.     }
    28.    
    29.     // if you need to rotate the skybox during gameplay
    30.     // rotate the skybox independently of the main camera
    31.     public void SetSkyBoxRotation(Vector3 rotation)
    32.     {
    33.         this.SkyBoxRotation = rotation;
    34.     }
    35.  
    36.     // Update is called once per frame
    37.     void Update()
    38.     {
    39.        
    40.         SkyCamera.transform.position = MainCamera.transform.position;
    41.         SkyCamera.transform.rotation = MainCamera.transform.rotation;
    42.         SkyCamera.transform.Rotate(SkyBoxRotation);
    43.     }
    44. }
     
  10. Serdnad

    Serdnad

    Joined:
    Jan 9, 2013
    Posts:
    14
    With some modifications to his script, scottm361's solution worked for me, thanks to the detailed guide. Thanks.
     
    KUFgoddess likes this.
  11. tarahugger

    tarahugger

    Joined:
    Jul 18, 2014
    Posts:
    129
    scottm361's solution worked for me after commenting a few lines.

    Code (CSharp):
    1.     // Update is called once per frame
    2.     void Update ()
    3.     {      
    4.         SkyCamera.transform.Rotate (SkyBoxRotation);
    5.     }
     
    KUFgoddess and Eddierocksuk like this.
  12. Bluestrike

    Bluestrike

    Joined:
    Sep 26, 2009
    Posts:
    256
    I had to make a update function like this to make it work (Space.World)

    Code (JavaScript):
    1. public function LateUpdate() : void
    2. {
    3.     transform.position     = parentTransform.position;
    4.     transform.rotation     = parentTransform.rotation;
    5.     transform.Rotate ( 0.00, skyRotation, 0.00, Space.World);
    6. }
    also some tips;
    I replaced transform with rTransform and added in awake rTransform = transform;
    I renamed lateupdate() and call it from my actual camera script that provides the position and rotation to the function.
     
  13. Bluestrike

    Bluestrike

    Joined:
    Sep 26, 2009
    Posts:
    256
    When using Deferred lighting, this does not seem to work,
    the skybox won't render, and if i change the camera witch has the depth only from deferred to forward it works.
    Bug?

    Also the skybox only cam can be set to vertex lit for performance or does this not matter?
     
  14. leogetz

    leogetz

    Joined:
    Oct 5, 2015
    Posts:
    1
    Create & Rotate Skybox tutorial

    by: SpeedTutor
     
  15. lactus

    lactus

    Joined:
    Oct 20, 2013
    Posts:
    6
    You could create a skybox shader for this purpose


    Skybox.shader
    Code (CSharp):
    1. Shader "World/Skybox"
    2. {
    3.  
    4.     Properties
    5.     {
    6.         _Brightness("Brightness", Range(0,1)) = .5
    7.         _MainTex("Stars", Cube) = "white" {}
    8.     }
    9.  
    10.     SubShader
    11.     {
    12.         Tags { "Queue" = "Background"  }
    13.  
    14.         Pass
    15.         {
    16.             ZWrite Off
    17.             Cull Off
    18.  
    19.             CGPROGRAM
    20.             #pragma vertex vert
    21.             #pragma fragment frag
    22.  
    23.             float _Brightness;
    24.             float4x4 _SkyboxRotation;
    25.          
    26.             #include "UnityCG.cginc"
    27.  
    28.             struct vertexInput
    29.             {
    30.                 float4 vertex : POSITION;
    31.                 float3 texcoord : TEXCOORD0;
    32.             };
    33.  
    34.             struct vertexOutput
    35.             {
    36.                 float4 vertex : SV_POSITION;
    37.                 float4 vertexWorld : POSITION1;
    38.                 float3 texcoord : TEXCOORD0;
    39.             };
    40.  
    41.             vertexOutput vert(vertexInput _input)
    42.             {
    43.                 vertexOutput output;
    44.                 output.vertex = mul(UNITY_MATRIX_MVP, mul(_SkyboxRotation,-_input.vertex));
    45.                 output.texcoord = -_input.texcoord;
    46.                 output.vertexWorld = mul(_Object2World, -_input.vertex);
    47.                 return output;
    48.             }
    49.  
    50.             fixed4 frag(vertexOutput _input) : COLOR
    51.             {
    52.                 return texCUBE(_StarsText, _input.texcoord);
    53.             }
    54.  
    55.             ENDCG
    56.         }
    57.     }
    58. }
     
    Panoramus likes this.
  16. presenciavr

    presenciavr

    Joined:
    May 24, 2015
    Posts:
    1
    This code rotate an skybox, but only from Y axis:

    void Update () {
    RenderSettings.skybox.SetFloat("_Rotation", Time.time * adjustment);
    }
     
    Gvrv, SimRuJ, ecv80 and 6 others like this.
  17. NicRule

    NicRule

    Joined:
    Jan 24, 2014
    Posts:
    3
    This shader will let you rotate a skybox in any direction. It will rotate with Light0.

    Code (CSharp):
    1. Shader "Custom/MovingSkyboxUpload" {
    2.     Properties {
    3.         _CubeMap ("Skybox Cube Map", Cube) = "" {}
    4.     }
    5.     SubShader {
    6.         Pass{
    7.         CGPROGRAM
    8.         #pragma vertex vert
    9.         #pragma fragment frag
    10.      
    11.         uniform samplerCUBE _CubeMap;
    12.      
    13.         struct vertexInput{
    14.             float4 vertex: POSITION;
    15.         };
    16.         struct vertexOutput{
    17.             float4 pos : SV_POSITION;
    18.             float4 posWorld : TEXCOORD1;
    19.             fixed3x3 R : TEXCOORD4;
    20.         };
    21.      
    22.         vertexOutput vert(vertexInput v){
    23.             vertexOutput o;
    24.             o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
    25.             o.posWorld = mul(_Object2World, v.vertex);
    26.  
    27.             fixed3 new_up = normalize(_WorldSpaceLightPos0.xyz);
    28. //        folowing code from http://stackoverflow.com/questions/32257338/vertex-position-relative-to-normal
    29.             float3 up = float3(0,1,0);
    30.  
    31.             float3 w = cross(up, new_up);
    32.             float s = length(w);  // Sine of the angle
    33.             float c = dot(up, new_up); // Cosine of the angle
    34.             float3x3 VX = float3x3 (
    35.                 0, -1 * w.z, w.y,
    36.                 w.z, 0, -1 * w.x,
    37.                 -1 * w.y, w.x, 0
    38.             ); // This is the skew-symmetric cross-product matrix of v
    39.             float3x3 I = float3x3 (
    40.                 1, 0, 0,
    41.                 0, 1, 0,
    42.                 0, 0, 1
    43.             ); // The identity matrix
    44.          
    45.             o.R = I + VX + mul(VX , VX) * (1 - c)/(s*s); // The rotation matrix! YAY!
    46. //        previous code from http://stackoverflow.com/questions/32257338/vertex-position-relative-to-normal
    47.             return o;
    48.         }
    49.      
    50.         float4 frag(vertexOutput i) : COLOR{
    51.             float3 viewDirection = normalize( _WorldSpaceCameraPos.xyz - i.posWorld.xyz );
    52.             viewDirection = mul (viewDirection , i.R);          
    53.             return texCUBE(_CubeMap, viewDirection);
    54.         }
    55.         ENDCG
    56.     }
    57. }
    58. }
    Built in Unity5.2.1
     
    corpsinheretoo and Michaelbgdrs like this.
  18. Nith666

    Nith666

    Joined:
    Aug 1, 2012
    Posts:
    33
    Thanks Demol, that was exactly what I needed
     
  19. Lazarus-Overman

    Lazarus-Overman

    Joined:
    Aug 18, 2016
    Posts:
    2
    I know this thread's been running for a while, but here's a real simple way to do it:
    Do the double camera set-up as scottm 361 explained above, but then put this simple script on the SkyboxCam :
    void FixedUpdate (){
    transform.Rotate (0, rotation speed, 0);
    }
    Works great and hardly any typing at all.
     
    KUFgoddess likes this.
  20. dradb

    dradb

    Joined:
    Jan 10, 2015
    Posts:
    81
    Nic,
    Your shader works well but it only seems to rotate the skybox about 2 axes. "Z" has no effect.
    Strangely, the main camera y and z rotation have exactly the same effect.
    Help please.
     
  21. MaxSilva

    MaxSilva

    Joined:
    Jul 25, 2012
    Posts:
    8
    Hey all. I stumbled upon this recently, and came up with a modified version of the Unity 5 Skybox (6-sided) shader that allows rotation in the 3 axes. I'm not good at shaders so I don't know how efficient this is. Just move the sliders on the material and it will rotate.

    Cheers.
     

    Attached Files:

  22. Michaelbgdrs

    Michaelbgdrs

    Joined:
    May 1, 2014
    Posts:
    27
    @NicRule In Unity 5.4 it compiles but shows the HDRI wrong.

    Can you kindly have a look and repost the shader code?

    Thank you very much.
     
  23. catfink

    catfink

    Joined:
    May 23, 2015
    Posts:
    168
    gregroberts and Michaelbgdrs like this.
  24. Michaelbgdrs

    Michaelbgdrs

    Joined:
    May 1, 2014
    Posts:
    27
    Yes true i am aware of this.
    Unfortunately you need to brake the HDRI to 6 pieces.
    Will see if i can find a soft that can do this easily.
    Thank you for the support @catfink
     
  25. catfink

    catfink

    Joined:
    May 23, 2015
    Posts:
    168
    I use this tool http://ggnome.com/pano2vr for converting panoramas into 6 face cube output.

    I think the trial version will let you experiment. Basically input the panorama image and then specify transformation as what you want to do and select cube map type output.
     
  26. Liinnkk

    Liinnkk

    Joined:
    Mar 19, 2016
    Posts:
    8
    Great work! It worked pretty well for me. While profiling, I couldn't see any impact on the performance at all.
     
  27. immaginartifilm

    immaginartifilm

    Joined:
    Sep 30, 2019
    Posts:
    1

    Absolutely the best solution work like a charm.
     
  28. GeorgeDubuque

    GeorgeDubuque

    Joined:
    Feb 8, 2018
    Posts:
    1
    You can't add multiple cameras to one gameobject.
     
  29. sirleto

    sirleto

    Joined:
    Sep 9, 2019
    Posts:
    17

    Thanks, works nicely with default unity skybox (atleast 2019)! this is the simplest and best solution in this thread.
    what you can do with it is:

    1. rotate your sky dynamically while the game is running (careful: if your skybox contains a sun, then this can complicate things)

    2. you can also use a value "public float myrotation" in a monobehaviour script, attach that to your camera or wherever you want, and then you can in editor rotate your skybox.


    public float Skybox_Rotation_Y = 0.0f;

    // OnValidate is called when value is changed in editor AND on "game startup"
    private void OnValidate()
    {
    RenderSettings.skybox.SetFloat("_Rotation", Skybox_Rotation_Y);
    }
     
    honor0102, Tangly and kmitl_iaai like this.
  30. sellverful

    sellverful

    Joined:
    Dec 4, 2018
    Posts:
    3
    If you still are still looking and just want to rotate skybox once go to your skybox material settings and there is a Rotation slider. Please, don't create unnecessary scripts for that.
     
  31. unity_A252D283E9C389815798

    unity_A252D283E9C389815798

    Joined:
    Jun 15, 2021
    Posts:
    1
    Here easy method. 1 stroke of code. 2 min of life

     
    Laniemme and longbottom71712 like this.
  32. longbottom71712

    longbottom71712

    Joined:
    May 15, 2018
    Posts:
    9
    Thank you so much.
     
  33. Hoglet

    Hoglet

    Joined:
    Oct 17, 2016
    Posts:
    2
    Optimized version of code with reseting rotation on disable

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class SkyBoxRotation : MonoBehaviour {
    4.  
    5.     public float speed = 0.2f;
    6.  
    7.     private int RotationProperty;
    8.     private float initRot;
    9.     private Material skyMat;
    10.  
    11.     private void OnDisable () => skyMat.SetFloat (RotationProperty, initRot);  
    12.  
    13.     void Start() {
    14.         RotationProperty = Shader.PropertyToID ("_Rotation");
    15.         skyMat = RenderSettings.skybox;
    16.         initRot = skyMat.GetFloat (RotationProperty);
    17.     }
    18.  
    19.     void Update () => skyMat.SetFloat (RotationProperty, Time.time * speed);
    20.  
    21. }
    22.  
     
unityunity