• Stars
    star
    180
  • Rank 212,430 (Top 5 %)
  • Language Objective-C++
  • License
    MIT License
  • Created over 7 years ago
  • Updated over 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Pure-shader sky and cloud rendering in OpenGL

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;

More Repositories

1

parcel-plugin-inliner

Parcel plugin to inline CSS and JS code in your HTML file.
JavaScript
71
star
2

my-react-hooks

React/Preact/Orby.js Hooks I used in personal projects, all in public domain form. Copy and paste or do as you wish.
JavaScript
16
star
3

postcss-remove-unused-css

Whitelists your CSS selectors based on your other files.
JavaScript
13
star
4

parcel-plugin-purifycss

Runs PurifyCSS on all CSS assets
JavaScript
9
star
5

parcel-svelte-template

HTML
3
star
6

sinatra-can

CanCan reimplemented as a Sinatra plugin
Ruby
2
star
7

buchla-synthesizer-cad-files

AGS Script
2
star
8

GK3-extractor

An asset extractor for Jane Jensen's game Gabriel Knight 3. Extracts content from BRN files and converts to common formats like WAV, BMP, OBJ when appropriate.
C
2
star
9

dotfiles

Shell
1
star
10

preactz

Preact + DomZ in a convenient package
JavaScript
1
star
11

parcel-sass-postcss-remove-unused-css

Example of an app using Parcel + SASS + postcss-remove-unused-css (https://github.com/shff/postcss-remove-unused-css)
HTML
1
star
12

gk3tools

Fork/mirror of https://sourceforge.net/projects/gk3tools/
C++
1
star
13

transformer

Transforms XML and JSON payloads using "reverse templates"
Go
1
star
14

csharp-hindley-milner

Implementation of the Hindley-Damas-Miner inference algorithm in C#. Based on Rob Smallshire's Python implementation.
C#
1
star
15

csharp-magic-proxy

An experiment in C# that transforms classes on the fly using reflection and Emit, all that in order to avoid implementing and calling INotifyPropertyChanged. This is an experiment that should not be used in production.
C#
1
star
16

spacedesigner-patchmaker

Tool to aid me at creating SpaceDesigner (Apple Logic's convolution reverb plugin) patches in bulk.
Ruby
1
star
17

parcel-inferno-template

Degit template for Inferno.js + Parcel. Run `npx degit shff/parcel-inferno-template` to use it.
HTML
1
star
18

parcel-vue-template

Degit template for Vue.js + Parcel. Run `npx degit shff/parcel-vue` to use it.
JavaScript
1
star
19

hosts

HOSTS file for ad blocking
Shell
1
star
20

webpack-vue-template

No-frills Vue.js + Webpack template. Run `npx degit shff/webpack-vue-template` to use it.
JavaScript
1
star
21

best_go_packages

Semi-curated list of Golang packages
1
star
22

combinators

Rust
1
star
23

paq

Minimalist Javascript bundler with code that's easy to understand
Rust
1
star
24

vdom

Minimal V-Dom framework similar to React
JavaScript
1
star
25

miniqueue

Minimalist generic queue in Rust for "fan-out" operations
Rust
1
star
26

parcel-mithril-template

Degit template for Mithril + Parcel. Run `npx degit shff/parcel-mithril` to use it.
JavaScript
1
star
27

b

Homebrew, except fast. And totally unsafe.
Shell
1
star