Giter Club home page Giter Club logo

opengl_sky's Introduction

OpenGL Sky

This is a 100% procedural sky + clouds renderer. It calculates everything inside a shader.

I can run it without glitches in a cheap 2011 Macbook Air.

Hello stargazers interested in atmosphere rendering, here's two nice projects you could like: benanders/Hosek-Wilkie and wwwtyro/glsl-atmosphere

What does it look like?

Here's a sample with default settings:

screenshot

Here's one with the "softer" settings.

softer screenshot

What is it

There are two things here.

Blue sky

This thing uses a Mie + Rayleigh scattering function for the sky. Well, almost, it is too heavy so I fitted it to a makeshift math function until it was fast enough.

The theory

What is Mie + Rayleigh scattering, do you ask? Well, for our purposes, it's a complex formula used to calculate the color of the sky.

Here's some references:

The implementation

Here's the mu:

float mu = dot(normalize(pos), normalize(fsun));

And here's Rayleigh:

vec3 rayleigh = 3.0 / (8.0 * 3.14) * (1.0 + mu * mu)

And Mie:

vec3 mie = (Kr + Km * (1.0 - g * g) / (2.0 + g * g) / pow(1.0 + g * g - 2.0 * g * mu, 1.5)) / (Br + Bm)

The extinction is the hard part. I did that on an old Macbook, so I didn't have a lot of processing power. The traditional way of calculating that is using integration. Some imeplementations use 16, 32 or even more steps, and that's VERY HARD for an integrated graphics card.

What I did was plotting the graph and then coming up with a formula that was faster than all the iterations, but was still in the ballpark.

Basic curve fitting. I used a mix of empirical observation and a some Matlab.

vec3 day_extinction = exp(-exp(-((pos.y + fsun.y * 4.0) * (exp(-pos.y * 16.0) + 0.1) / 80.0) / Br) * (exp(-pos.y * 16.0) + 0.1) * Kr / Br) * exp(-pos.y * exp(-pos.y * 8.0 ) * 4.0) * exp(-pos.y * 2.0) * 4.0;

Another thing I wanted was a blue-ish extinction value for nights. This is not in the original formula.

vec3 night_extinction = vec3(1.0 - exp(fsun.y)) * 0.2;
vec3 extinction = mix(day_extinction, night_extinction, -fsun.y * 0.2 + 0.5);

That's it. Multiply Mie and Rayleigh with the extinction and you have your sky.

color.rgb = rayleigh * mie * extinction;

Clouds

The clouds use multi-layer brownian noise.

I have a main cloud layer that simulates Cumulus (fluffy) clouds, but it doesn't look that great. You need at least 10 layers of noise for it to look a bit fluffy. I'm using 4, I think. The more you use, the slower it is.

Cumulus: https://upload.wikimedia.org/wikipedia/commons/thumb/3/3c/GoldenMedows.jpg/1200px-GoldenMedows.jpg

There's also a less dense, cloud layer that simulates Cirrus (icy) clouds. This one looks OK and requires a single layer.

Cirrus: https://upload.wikimedia.org/wikipedia/commons/9/94/Cirrus_clouds_mar08.jpg

Compiling

  • Install glfw3 (brew install glfw3 if you're on a Mac).
  • Edit Makefile and change the path to glfw/includes and glfw/lib/libglfw3.a (you can use -lglfw or -lglfw3 here if you only have a libglfw3.dylib instead of a libglfw3.a).
  • Run make. It should work.

Where are the settings?

They're scattered around the code.

Cirrus Fluffiness ☁️

The 3 below is the amount of cirrus layers you'll render. The more you use, the slower it is 😞

for (int i = 0; i < 3; i++)

Amount of clouds 🌥

The bigger the number the more there are. From zero to one, although you can go higher. Play around with it.

uniform float cirrus = 0.9;
uniform float cumulus = 0.2;

Speed ⚡️

The 0.2f below is the speed ratio. Crank it to 5.0f if you're in a hurry to see the full cycle!

float time = (float)glfwGetTime() * 0.2f - 0.0f;

Nitrogen Color 🏞

That's not exactly the color of nitrogen, but it is actually related to that.

const vec3 nitrogen = vec3(0.650, 0.570, 0.475);

Scattering Coefficients 🤓

Play around with those. I got them emphirically, so I can't really explain why they are that amount 🤨

const float Br = 0.0025; // Rayleigh coefficient
const float Bm = 0.0003; // Mie coefficient
const float g =  0.9800; // Mie scattering direction. Should be ALMOST 1.0f

Another favourite setting of mine. I think it looks better.

const float Br = 0.0020;
const float Bm = 0.0009;
const float g =  0.9200;

And another favorite. It is a softer setting.

const float Br = 0.0005;
const float Bm = 0.0003;
const float g =  0.9200;

opengl_sky's People

Contributors

shferreira avatar shff avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

opengl_sky's Issues

Rotation

Hi,
i'm using your cloud implementation in a personal FragmentShader ... But i don't find any way to create the clouds in a hemispheral skydome and rotate the generate cloud when the camera rotate in different position.

Any idea how to change your code to do this ?

Best Regards,

MSVC: compile error

1>------ Build started: Project: ncnc, Configuration: Debug Win32 ------
1>main.c
1>C:\Users\a\source\repos\opengl_sky\main.c(183,40): error C2054: expected '(' to follow 'packed'
1>C:\Users\a\source\repos\opengl_sky\main.c(242,24): error C2057: expected constant expression
1>C:\Users\a\source\repos\opengl_sky\main.c(242,24): error C2466: cannot allocate an array of constant size 0
1>C:\Users\a\source\repos\opengl_sky\main.c(242,25): error C2133: 'error_log': unknown size
...

image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.