1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
[require]
GLSL >= 1.20
[vertex shader]
#version 120
#extension GL_ARB_texture_rectangle : enable
#define flat
#define texture2DRectOffset(sampler, coords, offset) texture2DRect(sampler, coords + vec2(offset))
#define shadow2DRectOffset(sampler, coords, offset) shadow2DRect(sampler, coords + vec2(offset))
attribute vec4 vvertex;
uniform mat4 sunmatrix;
varying vec3 camvec;
void main(void)
{
gl_Position = vvertex;
vec4 p = sunmatrix * vvertex;
camvec = p.xyz / p.w;
}
[fragment shader]
#version 120
#extension GL_ARB_texture_rectangle : enable
#define flat
#define texture2DRectOffset(sampler, coords, offset) texture2DRect(sampler, coords + vec2(offset))
#define shadow2DRectOffset(sampler, coords, offset) shadow2DRect(sampler, coords + vec2(offset))
#define fragdata(loc, name, type)
#define fragcolor gl_FragData[0]
uniform vec3 sunlight;
uniform vec3 sundir;
uniform vec3 sundiskparams;
uniform vec3 atmoradius;
uniform float gm;
uniform vec3 betar, betam, betarm;
uniform vec2 hdrgamma;
uniform float atmoalpha;
varying vec3 camvec;
fragdata(0, fragcolor, vec4)
vec3 calcextinction(float dist)
{
return exp2(-dist * betarm);
}
vec3 calcscatter(float costheta)
{
float rphase = 1.0 + costheta*costheta;
float mphase = pow(1.0 + gm*(gm - 2.0*costheta), -1.5);
return betar*rphase + betam*mphase;
}
float baseopticaldepth(vec3 ray)
{
float a = atmoradius.x * max(ray.z, min(sundir.z, 0.0));
return sqrt(a*a + atmoradius.z) - a;
}
float opticaldepth(vec3 pos, vec3 ray)
{
pos.z = max(pos.z, 0.0) + atmoradius.x;
float a = dot(pos, ray);
return sqrt(a*a + atmoradius.y - dot(pos, pos)) - a;
}
void main(void)
{
vec3 camdir = normalize(camvec);
float costheta = dot(camdir, sundir);
float raydist = baseopticaldepth(camdir);
vec3 extinction = calcextinction(raydist);
float lightraydist = opticaldepth(camdir * (raydist * max(0.15 + 0.75 * sundir.z, 0.0)), sundir);
vec3 incominglight = calcextinction(lightraydist);
vec3 scattering = calcscatter(costheta) * (1.0 - extinction);
vec3 inscatter = incominglight * scattering;
vec3 sundisk = sundiskparams.z * extinction * pow(clamp(costheta*sundiskparams.x + sundiskparams.y, 0.0, 1.0), 8.0);
inscatter += sundisk;
inscatter = sqrt(inscatter);
fragcolor = vec4(sunlight * inscatter, atmoalpha);
}
|