Atmospheric Rendering with OSL


My latest experiment into OSL shading is focused on implementing a sky shading model similar to cycles’ existing sky textures. Whilst Blender’s existing options work pretty well, they only allow you to render the sky as it appears at sea level. I wanted a shader that could simulate the sky at any altitude, even from outside the Earth’s atmosphere. After some research I was able to track down an article on rendering atmospheric scattering at, which does a great job of explaining a model for rendering Earths atmosphere based on a 1993 technical paper by Tomoyuki Nishita.

I wont bother explaining the maths in too much detail here, as frankly I don’t 100% understand it anyway, and the ScratchAPixel article does a far better job than I could. But I wanted to share the results and my osl shader code for anyone who might be interested.

The shader works by sampling the path out from the camera, through the atmosphere out into space (or until we hit the earth) and adding together all of the sunlight scattered by the atmosphere (only single scattering is taken into account). Two kinds of scattering of light by the atmosphere are considered. Rayleigh scattering is the scattering of light by small molecules; those smaller than the wavelengths of visible light. Rayleigh scattering affects short wavelengths of light more than long ones and so blue light is scattered more strongly . Mie scattering is the scattering of light by larger particles called aerosols, and is largely independent of wavelength. Rayleigh scattering is what gives the sky its blue colour and sunsets their red colour. Skies are normally blue because you’re seeing predominantly the blue light scattered by Rayleigh scattering. A sunset looks red because you’re looking towards the sun, and the sunlight at the horizon has to travel further through the atmosphere to reach you, so the blue light has already been scattered out by the time the remaining light reaches you.

As you move higher in the Earth’s atmosphere it becomes less dense, and so Nishita’s model accounts for this by applying an exponential falloff to the amount of scattering as we progress higher in the atmosphere. This means as we go higher, the sky begins to look darker as we see less scattered light, and more of the darkness of space beyond.

Anyway, here’s my OSL shader code and some renders.

Nishita Atmosphere Shader on GitHub

Some different altitudes (at midday):


And here’s a sunset gif:

A test with Suzanne:


Some desktop wallpaper res shots.




Rendering Planets

Following on from getting the sky shader working, I wondered if it would be any good for rendering planets – it could already render an atmosphere of a planet, and it part of the code for the shader already found where on the planet the camera rays hit. From this I could also generate coordinates for rendering a texture on the planet, and with a bit of extra code and some nodes in blender I had a set up that I could render Earth (and other planets) with. It’s still very experimental, and it doesn’t do anything advanced like rendering clouds, but it’s been pretty fun to mess around with.

Here’s some images. You can find the code for the OSL portion of the shader on github. They’re pretty rough, but the neat thing about them I think is that there’s no geometry in the scene! Just a shader on the background.

Some Earth renders (looks a little weird without clouds):



Mars with some water:


And some procedural/grunge texture based planets!






16 responses to “Atmospheric Rendering with OSL

      • yes i’ve tried already..but the effect to me appears behind the planet..not the same as your screenshots! should i add another layer? and also how to make it coincide with planet position and sun direction? thank you!

      • So for my scene i also rendered the planet’s surface as a background shader. No geometry in the scene. I can send you an example file later if you’re interested.

  1. Could you post or send me a screenshot of your node setup or an example file for one of your planet renderings?

    Many thanks!

  2. I’m wondering if there are any tips for making the horizon look convincing with this. Should I do a large sphere for the ground or just hide the horizon with hills?

    • Like I say, the scene has *zero* geometry. It’s all a world shader including the planet.

  3. Hi Ben,

    When I put external file to script node and click reload i get:
    error: No shader function defined in console.
    I use Blender 2.75a. What can be wrong?

    Best regards.

    • Ok!. It seems to work great when text pasted.
      Is it possible to somehow “convert” it to bitmap to speed it up with static shots? It’s now really slow compared to internal blender sky.

      • You could put an equine angular camera in the scene and render out a HDR. Then use that as your environment map.

      • Hey Alex, would you mind describing how you got it to work? I tried connecting Sky to World Output: Surface but I don’t see anything.


  4. Hi Ben,

    For newbies like me, would you mind tell me how to use the OSL script in blender? I have it pasted as an internal script under World > Surface. It shows three outputs, but how do they connect to World Output in the node editor?


  5. Thank you very much!! The sky looks amazing!
    I searched hours but really couldn’t find anything about how to set up this node like that sunset gif…I’ll be very appreciate it if you can post a node screenshot:D

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s