Skip to content

Commit efafcef

Browse files
committed
updates+basic preetham
1 parent dfb71b5 commit efafcef

File tree

5 files changed

+241
-20
lines changed

5 files changed

+241
-20
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ And on my desktop computer it runs ~0.5-2ms/frame (Nvidia GTX 1050)
1111
This project is far from finished, it will still undergo various optimizations and tweaks as well as added functionality
1212
The goal is to make this into something that can be used in other projects
1313

14-
### Screenshots!
14+
### Screenshots! (as of 07/12/17)
1515
![dec7-1](https://user-images.githubusercontent.com/16521339/33801879-362f844a-dd1e-11e7-87fb-5b13e2aefc24.png)
1616
![dec7-2](https://user-images.githubusercontent.com/16521339/33801880-38cf507c-dd1e-11e7-9d5c-ef3ca9967a9f.png)
1717
![dec7-3](https://user-images.githubusercontent.com/16521339/33801881-3a97b8b8-dd1e-11e7-9297-3b609dc0d42d.png)

assets/shaders/pree.frag

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
#version 330 core
2+
3+
in vec3 vSunDirection;
4+
in float vSunfade;
5+
in vec3 vBetaR;
6+
in vec3 vBetaM;
7+
in float vSunE;
8+
9+
out vec4 Color;
10+
11+
uniform float luminance;
12+
uniform float mieDirectionalG;
13+
uniform mat4 MVPM;
14+
15+
const vec3 cameraPos = vec3( 0.0, 0.0, 0.0 );
16+
17+
// constants for atmospheric scattering
18+
const float pi = 3.141592653589793238462643383279502884197169;
19+
20+
const float n = 1.0003; // refractive index of air
21+
const float N = 2.545E25; // number of molecules per unit volume for air at
22+
// 288.15K and 1013mb (sea level -45 celsius)
23+
24+
// optical length at zenith for molecules
25+
const float rayleighZenithLength = 8.4E3;
26+
const float mieZenithLength = 1.25E3;
27+
const vec3 up = vec3( 0.0, 1.0, 0.0 );
28+
// 66 arc seconds -> degrees, and the cosine of that
29+
const float sunAngularDiameterCos = 0.999956676946448443553574619906976478926848692873900859324;
30+
31+
// 3.0 / ( 16.0 * pi )
32+
const float THREE_OVER_SIXTEENPI = 0.05968310365946075;
33+
// 1.0 / ( 4.0 * pi )
34+
const float ONE_OVER_FOURPI = 0.07957747154594767;
35+
36+
float rayleighPhase( float cosTheta ) {
37+
return THREE_OVER_SIXTEENPI * ( 1.0 + pow( cosTheta, 2.0 ) );
38+
}
39+
40+
float hgPhase( float cosTheta, float g ) {
41+
float g2 = pow( g, 2.0 );
42+
float inv = 1.0 / pow( 1.0 - 2.0 * g * cosTheta + g2, 1.5 );
43+
return ONE_OVER_FOURPI * ( ( 1.0 - g2 ) * inv );
44+
}
45+
46+
// Filmic ToneMapping http://filmicgames.com/archives/75
47+
const float A = 0.15;
48+
const float B = 0.50;
49+
const float C = 0.10;
50+
const float D = 0.20;
51+
const float E = 0.02;
52+
const float F = 0.30;
53+
54+
const float whiteScale = 1.0748724675633854; // 1.0 / Uncharted2Tonemap(1000.0)
55+
56+
vec3 Uncharted2Tonemap( vec3 x ) {
57+
return ( ( x * ( A * x + C * B ) + D * E ) / ( x * ( A * x + B ) + D * F ) ) - E / F;
58+
}
59+
60+
61+
void main() {
62+
63+
vec2 puv = (gl_FragCoord.xy)/(512.0);
64+
puv = puv-vec2(0.5);
65+
puv *= 2.0;
66+
vec4 uvdir = (vec4(puv.xy, 1.0, 1.0));
67+
vec4 worldPos = (inverse((MVPM))*uvdir);
68+
vec3 dir = normalize(worldPos.xyz/worldPos.w);
69+
vec3 vWorldPosition = dir;
70+
71+
72+
73+
// optical length
74+
// cutoff angle at 90 to avoid singularity in next formula.
75+
float zenithAngle = acos( max( 0.0, dot( up, normalize( vWorldPosition - cameraPos ) ) ) );
76+
float inverse = 1.0 / ( cos( zenithAngle ) + 0.15 * pow( 93.885 - ( ( zenithAngle * 180.0 ) / pi ), -1.253 ) );
77+
float sR = rayleighZenithLength * inverse;
78+
float sM = mieZenithLength * inverse;
79+
80+
// combined extinction factor
81+
vec3 Fex = exp( -( vBetaR * sR + vBetaM * sM ) );
82+
83+
// in scattering
84+
float cosTheta = dot( normalize( vWorldPosition - cameraPos ), vSunDirection );
85+
86+
float rPhase = rayleighPhase( cosTheta * 0.5 + 0.5 );
87+
vec3 betaRTheta = vBetaR * rPhase;
88+
89+
float mPhase = hgPhase( cosTheta, mieDirectionalG );
90+
vec3 betaMTheta = vBetaM * mPhase;
91+
92+
vec3 Lin = pow( vSunE * ( ( betaRTheta + betaMTheta ) / ( vBetaR + vBetaM ) ) * ( 1.0 - Fex ), vec3( 1.5 ) );
93+
Lin *= mix( vec3( 1.0 ), pow( vSunE * ( ( betaRTheta + betaMTheta ) / ( vBetaR + vBetaM ) ) * Fex, vec3( 1.0 / 2.0 ) ), clamp( pow( 1.0 - dot( up, vSunDirection ), 5.0 ), 0.0, 1.0 ) );
94+
95+
// nightsky
96+
vec3 direction = normalize( vWorldPosition - cameraPos );
97+
float theta = acos( direction.y ); // elevation --> y-axis, [-pi/2, pi/2]
98+
float phi = atan( direction.z, direction.x ); // azimuth --> x-axis [-pi/2, pi/2]
99+
vec2 uv = vec2( phi, theta ) / vec2( 2.0 * pi, pi ) + vec2( 0.5, 0.0 );
100+
vec3 L0 = vec3( 0.1 ) * Fex;
101+
102+
// composition + solar disc
103+
float sundisk = smoothstep( sunAngularDiameterCos, sunAngularDiameterCos + 0.00002, cosTheta );
104+
L0 += ( vSunE * 19000.0 * Fex ) * sundisk;
105+
106+
vec3 texColor = ( Lin + L0 ) * 0.04 + vec3( 0.0, 0.0003, 0.00075 );
107+
108+
vec3 curr = Uncharted2Tonemap( ( log2( 2.0 / pow( luminance, 4.0 ) ) ) * texColor );
109+
vec3 color = curr * whiteScale;
110+
111+
vec3 retColor = pow( color, vec3( 1.0 / ( 1.2 + ( 1.2 * vSunfade ) ) ) );
112+
113+
Color = vec4( retColor, 1.0 );
114+
}

assets/shaders/pree.vert

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#version 330 core
2+
layout (location = 0) in vec2 position;
3+
4+
uniform vec3 sunPosition;
5+
uniform float rayleigh;
6+
uniform float turbidity;
7+
uniform float mieCoefficient;
8+
9+
out vec3 vWorldPosition;
10+
out vec3 vSunDirection;
11+
out float vSunfade;
12+
out vec3 vBetaR;
13+
out vec3 vBetaM;
14+
out float vSunE;
15+
16+
const vec3 up = vec3( 0.0, 1.0, 0.0 );
17+
18+
// constants for atmospheric scattering
19+
const float e = 2.71828182845904523536028747135266249775724709369995957;
20+
const float pi = 3.141592653589793238462643383279502884197169;
21+
22+
// wavelength of used primaries, according to preetham
23+
const vec3 lambda = vec3( 680E-9, 550E-9, 450E-9 );
24+
// this pre-calcuation replaces older TotalRayleigh(vec3 lambda) function:
25+
// (8.0 * pow(pi, 3.0) * pow(pow(n, 2.0) - 1.0, 2.0) * (6.0 + 3.0 * pn)) / (3.0 * N * pow(lambda, vec3(4.0)) * (6.0 - 7.0 * pn))
26+
const vec3 totalRayleigh = vec3( 5.804542996261093E-6, 1.3562911419845635E-5, 3.0265902468824876E-5 );
27+
28+
// mie stuff
29+
// K coefficient for the primaries
30+
const float v = 4.0;
31+
const vec3 K = vec3( 0.686, 0.678, 0.666 );
32+
// MieConst = pi * pow( ( 2.0 * pi ) / lambda, vec3( v - 2.0 ) ) * K
33+
const vec3 MieConst = vec3( 1.8399918514433978E14, 2.7798023919660528E14, 4.0790479543861094E14 );
34+
35+
// earth shadow hack
36+
// cutoffAngle = pi / 1.95;
37+
const float cutoffAngle = 1.6110731556870734;
38+
const float steepness = 1.5;
39+
const float EE = 1000.0;
40+
41+
float sunIntensity( float zenithAngleCos ) {
42+
zenithAngleCos = clamp( zenithAngleCos, -1.0, 1.0 );
43+
return EE * max( 0.0, 1.0 - pow( e, -( ( cutoffAngle - acos( zenithAngleCos ) ) / steepness ) ) );
44+
}
45+
46+
vec3 totalMie( float T ) {
47+
float c = ( 0.2 * T ) * 10E-18;
48+
return 0.434 * c * MieConst;
49+
}
50+
51+
void main() {
52+
53+
vec4 worldPosition = vec4( position, -1.0, 1.0 );
54+
vWorldPosition = worldPosition.xyz;
55+
56+
gl_Position = vec4( position, -1.0, 1.0 );
57+
58+
vSunDirection = normalize( sunPosition );
59+
60+
vSunE = sunIntensity( dot( vSunDirection, up ) );
61+
62+
vSunfade = 1.0 - clamp( 1.0 - exp( ( sunPosition.y / 450000.0 ) ), 0.0, 1.0 );
63+
64+
float rayleighCoefficient = rayleigh - ( 1.0 * ( 1.0 - vSunfade ) );
65+
66+
// extinction (absorbtion + out scattering)
67+
// rayleigh coefficients
68+
vBetaR = totalRayleigh * rayleighCoefficient;
69+
70+
// mie coefficients
71+
vBetaM = totalMie( turbidity ) * mieCoefficient;
72+
73+
}
74+

assets/shaders/sky.frag

+24-17
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ const float hM = 1200.0; // Mie
4747
const float earth_radius = 6360e3; // (m)
4848
const float atmosphere_radius = 6420e3; // (m)
4949

50-
vec3 sun_dir = vec3(0, 1, 0);
5150
const float sun_power = 30.0;
5251

5352
const int num_samples = 16;
@@ -66,6 +65,13 @@ mat3 rotate_around_x(const in float angle_degrees)
6665
return mat3(1, 0, 0, 0, _cos, -_sin, 0, _sin, _cos);
6766
}
6867

68+
vec3 getSunDirection() {
69+
const vec3 sun_dir = vec3(0.0, 1.0, 0.0);
70+
71+
mat3 rot = rotate_around_x(-abs(sin(time / 20.)) * 100.);
72+
return sun_dir*rot;
73+
}
74+
6975
bool isect_sphere(const in ray_t ray, inout float t0, inout float t1)
7076
{
7177
vec3 rc = vec3(0.0) - ray.origin;
@@ -134,6 +140,7 @@ vec3 get_incident_light(const in ray_t ray)
134140

135141
float march_step = t1 / float(num_samples);
136142

143+
vec3 sun_dir = getSunDirection();
137144
// cosine of angle between view and light directions
138145
float mu = dot(ray.direction, sun_dir);
139146

@@ -222,21 +229,21 @@ vec3 U2Tone(const vec3 x) {
222229
return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F;
223230
}
224231

225-
vec3 getSunDirection() {
226-
const vec3 sun_dir = vec3(0.0, 1.0, 0.0);
227-
228-
mat3 rot = rotate_around_x(-abs(sin(time / 20.)) * 90.);
229-
return sun_dir*rot;
230-
}
231-
232232
vec3 getSunColor() {
233-
vec3 dir = getSunDirection();
234-
return mix(vec3(1.0, 0.3, 0.0), vec3(0.99), smoothstep(0.05, 0.2, dir.y));
233+
vec3 sun_dir = getSunDirection();
234+
ray_t ray = ray_t(vec3(0.0, earth_radius+1.0, 0.0), normalize(sun_dir+vec3(0.01, 0.01, 0.0)));
235+
return get_incident_light(ray)*0.02;
235236
}
236237

237238
vec3 getSkyColor() {
238-
vec3 dir = getSunDirection();
239-
return mix(vec3(0.2, 0.3, 0.4), vec3(0.9, 0.9, 1.0), smoothstep(0.05, 0.2, dir.y));
239+
ray_t ray = ray_t(vec3(0.0, earth_radius+1.0, 0.0), normalize(vec3(0.2, 0.8, 0.3)));
240+
ray_t ray1 = ray_t(vec3(0.0, earth_radius+1.0, 0.0), normalize(vec3(0.0, -0.5, -0.5)));
241+
ray_t ray2 = ray_t(vec3(0.0, earth_radius+1.0, 0.0), normalize(vec3(0.0, 0.3, 0.4)));
242+
vec3 col = get_incident_light(ray);
243+
col += get_incident_light(ray1);
244+
col += get_incident_light(ray2);
245+
return col;
246+
//return mix(vec3(0.2, 0.3, 0.4), vec3(0.9, 0.9, 1.0), smoothstep(0.05, 0.2, dir.y));
240247
}
241248

242249
float hash(vec3 p) {
@@ -322,11 +329,11 @@ float density(vec3 p, vec3 weather,const bool hq,const float LOD) {
322329
base_cloud = remap(base_cloud*g, 1.0-cloud_coverage, 1.0, 0.0, 1.0);
323330
base_cloud *= cloud_coverage;
324331
if (hq) {
325-
vec2 whisp = texture(curl, p.xy*0.0003).xy*2.0-1.0;
326-
p.xy += whisp*200.0*(1.0-height_fraction);
332+
vec2 whisp = texture(curl, p.xy*0.0003).xy;
333+
p.xy += whisp*400.0*(1.0-height_fraction);
327334
vec3 hn = texture(worl, p*0.002, LOD-2.0).xyz;
328335
float hfbm = hn.r*0.625+hn.g*0.25+hn.b*0.125;
329-
hfbm = mix(hfbm, 1.0-hfbm, clamp(height_fraction*5.0, 0.0, 1.0));
336+
hfbm = mix(hfbm, 1.0-hfbm, clamp(height_fraction*3.0, 0.0, 1.0));
330337
base_cloud = remap(base_cloud, hfbm*0.2, 1.0, 0.0, 1.0);
331338
}
332339
return clamp(base_cloud, 0.0, 1.0);
@@ -340,7 +347,7 @@ vec4 march(const vec3 pos, const vec3 end, vec3 dir, const int depth) {
340347
const float t_dist = sky_t_radius-sky_b_radius;
341348
float lss = t_dist/float(depth);
342349
vec3 ldir = getSunDirection()*ss;
343-
vec3 L = vec3(0.0);//getSkyColor();
350+
vec3 L = vec3(0.0);
344351
dir += hash(p);//helps eliminate some weird spherical artifacts//should solve the root of the artifact rather than hack this, but oh well
345352
int count=0;
346353
float t = 1.0;
@@ -422,7 +429,6 @@ void main()
422429

423430
vec3 background = vec3(0.0);
424431
if (volume.a<0.99) {
425-
sun_dir = getSunDirection();
426432
ray_t ray = ray_t(vec3(0.0, earth_radius+1.0, 0.0), dir);
427433
background += get_incident_light(ray)*8.0;
428434
}
@@ -434,6 +440,7 @@ void main()
434440
if (volume.a>1.0) {col = vec4(1.0, 0.0, 0.0, 1.0);}
435441
} else {
436442
col = vec4(vec3(0.4), 1.0);
443+
col = texture(weather, uv*0.5).yyyw;
437444
}
438445
color = col;
439446
}

main.cpp

+28-2
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ int main()
7777
Shader ourShader("sky.vert", "sky.frag");
7878
Shader postShader("tex.vert", "tex.frag");
7979
Shader upscaleShader("upscale.vert", "upscale.frag");
80+
Shader preethamShader("pree.vert", "pree.frag");
8081

8182
GLfloat vertices[] = {
8283
-1.0f, -1.0f,
@@ -149,7 +150,7 @@ int main()
149150

150151
//stbi_set_flip_vertically_on_load(true);
151152
int x, y, n;
152-
unsigned char *curlNoiseArray = stbi_load("assets/curlnoise.bmp", &x, &y, &n, 0);
153+
unsigned char *curlNoiseArray = stbi_load("assets/curlnoise.png", &x, &y, &n, 0);
153154

154155
glGenTextures(1, &curltex);
155156
glBindTexture(GL_TEXTURE_2D, curltex);
@@ -220,6 +221,15 @@ int main()
220221
GLuint updownscale = glGetUniformLocation(upscaleShader.Program, "downscale");
221222
GLuint buffuniform = glGetUniformLocation(upscaleShader.Program, "buff");
222223
GLuint ponguniform = glGetUniformLocation(upscaleShader.Program, "pong");
224+
225+
preethamShader.Use();
226+
GLuint pMVPM = glGetUniformLocation(preethamShader.Program, "MVPM");
227+
GLuint pturbidity = glGetUniformLocation(preethamShader.Program, "turbidity");
228+
GLuint psunPosition = glGetUniformLocation(preethamShader.Program, "sunPosition");
229+
GLuint prayleigh = glGetUniformLocation(preethamShader.Program, "rayleigh");
230+
GLuint pmieCoefficient = glGetUniformLocation(preethamShader.Program, "mieCoefficient");
231+
GLuint pluminance = glGetUniformLocation(preethamShader.Program, "luminance");
232+
GLuint pmieDirectionalG = glGetUniformLocation(preethamShader.Program, "mieDirectionalG");
223233

224234
int check = 0;//used for checkerboarding in the upscale shader
225235
while (!glfwWindowShouldClose(window))
@@ -325,7 +335,23 @@ int main()
325335
//copy to the screen
326336
glBindFramebuffer(GL_FRAMEBUFFER, 0);
327337

328-
postShader.Use();
338+
//postShader.Use();
339+
float distance = 400000.0;
340+
const float PI = 3.141592653589793238462643383279502884197169;
341+
float theta = PI * (-0.01 );
342+
float phi = 2 * PI * (-0.25 );
343+
float sunposx = distance * cos( phi );
344+
float sunposy = distance * sin( phi ) * sin( theta );
345+
float sunposz = distance * sin( phi ) * cos( theta );
346+
347+
preethamShader.Use();
348+
glUniformMatrix4fv(pMVPM, 1, GL_FALSE, glm::value_ptr(MVPM));
349+
glUniform1f(pturbidity, GLfloat(10.0));
350+
glUniform1f(prayleigh, GLfloat(2.0));
351+
glUniform1f(pmieCoefficient, GLfloat(0.005));
352+
glUniform1f(pluminance, GLfloat(1.0));
353+
glUniform1f(pmieDirectionalG, GLfloat(0.8));
354+
glUniform3f(psunPosition, GLfloat(sunposx), GLfloat(sunposy), GLfloat(sunposz));
329355

330356
glActiveTexture(GL_TEXTURE0);
331357
glBindTexture(GL_TEXTURE_2D, fbotex);

0 commit comments

Comments
 (0)