I was wondering if it's possible to use an empty to control the sun position on a Nishita sky node. I'd like this so I can animate it properly and do easy testing in-world without having to edit the world material each time: Nishita gives you two values for Sun Elevation and Sun Rotation, those can't be easily animated to simulate the sun rising and setting at a logical angle, while also not allowing inputs to be plugged into their values which seems like an oversight in the node definition.

I'd like to avoid a whole script if possible, would rather do it manually if it's that complicated. I'm assuming my only option then are drivers, but how do I define them for the rotation and elevation fields so the sun moves at the location pointed to by an arrow empty?


You can do this easily by using drivers.

Final Result:

enter image description here

Note :

Use empty object's local rotation


  1. Add empty or use any pre existing object that you want to use for sun.(from here referred to as empty)
  2. Select empty and press N > item > rotation > z > right click > copy as new driver enter image description here
  3. Select you Nishita sky node. > Right click on Sun Rotation > Paste Driver enter image description here
  4. Select empty and press N > item > rotation > x > right click > copy as new driver [No image needed, similar to step 2]
  5. Select you Nishita sky node. > Right click on Sun Elevation > Paste Driver [No image needed, similar to step 2]
  • $\begingroup$ Thank you for the help, I didn't realize it was this simple! X rotation to Sun Elevation, -Z rotation to Sun Rotation. There is just one problem remaining: Due to how the Nishita sky node is programmed, the elevation does not warp around accordingly. You’re only allowed to use a value between -90 and 90: This means the elevation caps once the empty points upward (noon) unless you manually change the Z axis from 0 to 180. Is there a formula for the driver expressions to automatically warp the angle? $\endgroup$ Sep 11 '21 at 16:45
  • 1
    $\begingroup$ There might be solution to this using self in drivers or custom function in driver namespace. I'll take a look at it. $\endgroup$ Sep 11 '21 at 18:06

Managed to figure it out! Partly thanks to the answer provided by Pavan Bhadaja, followed by playing with the drivers and rotations in more depth.

The issue I was running into is that Nishita sky is programmed so the sun elevation angle doesn't warp around: Only values between -90* and 90* are valid, meaning an empty spinning all the way around won't work as values like 270 cap the sun. I was looking at complex driver formulas to warp / reverse the angles, yet it seems that wasn't needed: The sun always rises and sets at an angle, thus you can define a virtual 180* cone for the sun to work in which can itself be pointed in any direction on the Z axis.

For my daytime cycle I parented the sun's empty to a clock empty: The clock spins in one direction, you can animate the cycle by infinitely increasing its Y rotation over time, and you can give it any Z rotation to point the sun cycle at your desired location. The sun empty has a fixed rotation in the X axis to specify the sun's height at midday (max 90*), the higher this angle the further from the horizon and higher into the sky the sun travels each cycle.

In the image below the circle is the clock and the large cone is the sun. A smaller cone represents the moon, it will use a second Nishita sky blended on top at lower intensity, which will work the same way just parented at an opposing angle from the sun on the clock.

enter image description here

The drivers are a bit tricky. First you simply use the X rotation of the sun empty as the Sun Elevation value, the -Z rotation as the Sun Rotation value (Z must be negative or the sun goes the other way around). You need to use world rotation for this to work, local or pose space ignore the empty when it's being rotated by its parent. Also very importantly, you must set the mode to "Swing and Y Twist" from the default "Auto Euler", "XYZ Euler" and other transform modes won't work this way! Do so on both drivers and that should be it: You should have a day / night cycle you can animate from the scene via one rotation value.

enter image description here enter image description here

  • $\begingroup$ Correction: The clock will unfortunately not work at all Z rotations. Anything between -90* and +90* on the Z axis is fine, but the math does break and freeze the sun if I use 180*. If you're doing both sun and moon this way, safest bet is to set it at 90* which should guarantee both travel across the sky accordingly in opposite cones. Please let me know if anyone can improve complete my setup and find a way around this. $\endgroup$ Sep 12 '21 at 13:27
  • $\begingroup$ I figured out how to solve the wrapping issue with the following driver expressions: Sun Elevation: pi/2-abs(var) Sun Rotation: pi-var You'll have to use "XYZ Euler" for this approach. X will ping-pong the sun if you animate it outside the -90* / +90* range so avoid doing that if possible, the Z axis can be freely animated though. Both X and Z need to be animated together to produce a cycle, rotating with an attachment won't work any more. $\endgroup$ Sep 12 '21 at 16:26

Alternative approach: In the end I went with just scripting the whole thing using two world properties for the sun (with another two for the moon): I liked the empty but just couldn’t get it to wrap right so it felt broken and incomplete. It seems easier to just use sin / cos on #frame to make the sun move automatically. Simply use the following driver expressions, with a sun_direction around 0.5 and sun_time around 1000 for a good test… note that negative values are allowed to flip the side of sky or direction, whereas the moon is automatically reversed from the sun:

  • Sun Elevation: sin(pi*frame/sun_time)*abs(pi/2*sun_distance)
  • Sun Rotation: cos(pi*frame/sun_time)*(sun_distance*pi)-(sun_distance*pi)
  • Moon Elevation: cos(pi*frame/moon_time)*abs(pi/2*moon_distance)
  • Moon Rotation: sin(pi*frame/moon_time)*(moon_distance*pi)-(moon_distance*pi)+pi

The bottom nodes are the sun and moon Nishita skies, you can see the properties their drivers use at the right. The voronoi at the top is how I do the stars… muted them here since they look very noisy in the preview, only do this with a denoiser as stars are bright and sharp and a recipe for noisy speckles. For the moon just use the same drivers as the sun in reverse direction, then use a MixRGB to Add / Screen / Lighten the moon’s Nishita sky on top of the sun’s at a low intensity (I’m using 0.01).

enter image description here


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.