-
Notifications
You must be signed in to change notification settings - Fork 1
/
procsky.frag
124 lines (102 loc) · 4.18 KB
/
procsky.frag
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#version 450
// Based on https://www2.cs.duke.edu/courses/cps124/spring08/assign/07_papers/p91-preetham.pdf
layout(location = 0) out vec4 o_Target;
layout(location = 0) in vec3 vWorldPosition;
layout(set = 0, binding = 0) uniform Camera {
mat4 ViewProj;
mat4 CameraTransform;
};
layout(push_constant) uniform Sky {
vec3 primaries;
float luminance;
vec3 mieKCoefficient;
float mieCoefficient;
float mieDirectionalG;
float mieV;
float mieZenithLength;
float numMolecules;
float rayleigh;
float rayleighZenithLength;
float turbidity;
float refractiveIndex;
vec3 sunPosition;
float sunAngularDiameterDegrees;
float sunIntensityFactor;
float sunIntensityFalloffSteepness;
float tonemapWeighting;
float depolarizationFactor;
vec3 total_rayleigh_scattering_coefficients;
float _placeholder1;
vec3 total_mie_scattering_coefficients;
};
const float PI = 3.141592653589793238462643383279502884197169;
const vec3 UP = vec3(0.0, 1.0, 0.0);
vec3 totalMie(vec3 lambda, vec3 K, float T)
{
float c = 0.2 * T * 10e-18;
return 0.434 * c * PI * pow((2.0 * PI) / lambda, vec3(mieV - 2.0)) * K;
}
float rayleighPhase(float cosTheta)
{
return (3.0 / (16.0 * PI)) * (1.0 + pow(cosTheta, 2.0));
}
float henyeyGreensteinPhase(float cosTheta, float g)
{
return (1.0 / (4.0 * PI)) * ((1.0 - pow(g, 2.0)) / pow(1.0 - 2.0 * g * cosTheta + pow(g, 2.0), 1.5));
}
float sunIntensity(float zenithAngleCos)
{
float cutoffAngle = PI / 1.95; // Earth shadow hack
return sunIntensityFactor * max(0.0, 1.0 - exp(-((cutoffAngle - acos(zenithAngleCos)) / sunIntensityFalloffSteepness)));
}
// Whitescale tonemapping calculation, see http://filmicgames.com/archives/75
// Also see http://blenderartists.org/forum/showthread.php?321110-Shaders-and-Skybox-madness
const float A = 0.15; // Shoulder strength
const float B = 0.50; // Linear strength
const float C = 0.10; // Linear angle
const float D = 0.20; // Toe strength
const float E = 0.02; // Toe numerator
const float F = 0.30; // Toe denominator
vec3 Uncharted2Tonemap(vec3 W)
{
return ((W * (A * W + C * B) + D * E) / (W * (A * W + B) + D * F)) - E / F;
}
void main()
{
vec3 normalized_dir = normalize(vWorldPosition); // vWorldPos - cameraPos
// Rayleigh coefficient
float sunfade = clamp(1.0 - exp(sunPosition.y / 450000.0), 0.0, 1.0);
float rayleighCoefficient = rayleigh - (sunfade);
vec3 betaR = total_rayleigh_scattering_coefficients * rayleighCoefficient;
// Mie coefficient
vec3 betaM = total_mie_scattering_coefficients;
// Optical length, cutoff angle at 90 to avoid singularity
float zenithAngle = acos(max(0.0, dot(UP, normalized_dir)));
float denom = cos(zenithAngle) + 0.15 * pow(93.885 - ((zenithAngle * 180.0) / PI), -1.253);
float sR = rayleighZenithLength / denom;
float sM = mieZenithLength / denom;
// Combined extinction factor
vec3 Fex = exp(-(betaR * sR + betaM * sM));
// In-scattering
vec3 sunDirection = normalize(sunPosition);
float cosTheta = dot(normalized_dir, sunDirection);
vec3 betaRTheta = betaR * rayleighPhase(cosTheta * 0.5 + 0.5);
vec3 betaMTheta = betaM * henyeyGreensteinPhase(cosTheta, mieDirectionalG);
float sunE = sunIntensity(dot(sunDirection, UP));
vec3 Lin = pow(sunE * ((betaRTheta + betaMTheta) / (betaR + betaM)) * (1.0 - Fex), vec3(1.5));
Lin *= mix(vec3(1.0), pow(sunE * ((betaRTheta + betaMTheta) / (betaR + betaM)) * Fex, vec3(0.5)), clamp(pow(1.0 - dot(UP, sunDirection), 5.0), 0.0, 1.0));
// Composition + solar disc
float sunAngularDiameterCos = cos(sunAngularDiameterDegrees);
float sundisk = smoothstep(sunAngularDiameterCos, sunAngularDiameterCos + 0.00002, cosTheta);
vec3 L0 = vec3(0.1) * Fex;
L0 += sunE * 19000.0 * Fex * sundisk;
vec3 texColor = Lin + L0;
texColor *= 0.04;
texColor += vec3(0.0, 0.001, 0.0025) * 0.3;
// Tonemapping
vec3 whiteScale = 1.0 / Uncharted2Tonemap(vec3(tonemapWeighting));
vec3 curr = Uncharted2Tonemap((log2(2.0 / pow(luminance, 4.0))) * texColor);
vec3 color = curr * whiteScale;
vec3 retColor = pow(color, vec3(1.0 / (1.2 + (1.2 * (1 - sunfade)))));
o_Target = vec4(retColor, 1.0);
}