@@ -20,7 +20,7 @@ THREE.ShaderLib[ 'sky' ] = {
2020
2121 luminance : { value : 1 } ,
2222 turbidity : { value : 2 } ,
23- reileigh : { value : 1 } ,
23+ rayleigh : { value : 1 } ,
2424 mieCoefficient : { value : 0.005 } ,
2525 mieDirectionalG : { value : 0.8 } ,
2626 sunPosition : { value : new THREE . Vector3 ( ) }
@@ -29,7 +29,51 @@ THREE.ShaderLib[ 'sky' ] = {
2929
3030 vertexShader : [
3131
32+ "uniform vec3 sunPosition;" ,
33+ "uniform float rayleigh;" ,
34+ "uniform float turbidity;" ,
35+ "uniform float mieCoefficient;" ,
36+
3237 "varying vec3 vWorldPosition;" ,
38+ "varying vec3 vSunDirection;" ,
39+ "varying float vSunfade;" ,
40+ "varying vec3 vBetaR;" ,
41+ "varying vec3 vBetaM;" ,
42+ "varying float vSunE;" ,
43+
44+ "const vec3 up = vec3(0.0, 1.0, 0.0);" ,
45+
46+ // constants for atmospheric scattering
47+ "const float e = 2.71828182845904523536028747135266249775724709369995957;" ,
48+ "const float pi = 3.141592653589793238462643383279502884197169;" ,
49+
50+ // mie stuff
51+ // K coefficient for the primaries
52+ "const float v = 4.0;" ,
53+ "const vec3 K = vec3(0.686, 0.678, 0.666);" ,
54+
55+ // see http://blenderartists.org/forum/showthread.php?321110-Shaders-and-Skybox-madness
56+ // A simplied version of the total Reayleigh scattering to works on browsers that use ANGLE
57+ "const vec3 simplifiedRayleigh = 0.0005 / vec3(94, 40, 18);" ,
58+
59+ // wavelength of used primaries, according to preetham
60+ "const vec3 lambda = vec3(680E-9, 550E-9, 450E-9);" ,
61+
62+ // earth shadow hack
63+ "const float cutoffAngle = pi/1.95;" ,
64+ "const float steepness = 1.5;" ,
65+ "const float EE = 1000.0;" ,
66+
67+ "float sunIntensity(float zenithAngleCos)" ,
68+ "{" ,
69+ "return EE * max(0.0, 1.0 - pow(e, -((cutoffAngle - acos(zenithAngleCos))/steepness)));" ,
70+ "}" ,
71+
72+ "vec3 totalMie(vec3 lambda, float T)" ,
73+ "{" ,
74+ "float c = (0.2 * T ) * 10E-18;" ,
75+ "return 0.434 * c * pi * pow((2.0 * pi) / lambda, vec3(v - 2.0)) * K;" ,
76+ "}" ,
3377
3478 "void main() {" ,
3579
@@ -38,113 +82,73 @@ THREE.ShaderLib[ 'sky' ] = {
3882
3983 "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );" ,
4084
85+ "vSunDirection = normalize(sunPosition);" ,
86+
87+ "vSunE = sunIntensity(dot(vSunDirection, up));" ,
88+
89+ "vSunfade = 1.0-clamp(1.0-exp((sunPosition.y/450000.0)),0.0,1.0);" ,
90+
91+ "float rayleighCoefficient = rayleigh - (1.0 * (1.0-vSunfade));" ,
92+
93+ // extinction (absorbtion + out scattering)
94+ // rayleigh coefficients
95+ "vBetaR = simplifiedRayleigh * rayleighCoefficient;" ,
96+
97+ // mie coefficients
98+ "vBetaM = totalMie(lambda, turbidity) * mieCoefficient;" ,
99+
41100 "}" ,
42101
43102 ] . join ( "\n" ) ,
44103
45104 fragmentShader : [
46105
47- "uniform sampler2D skySampler;" ,
48- "uniform vec3 sunPosition;" ,
49106 "varying vec3 vWorldPosition;" ,
50-
51- "vec3 cameraPos = vec3(0., 0., 0.);" ,
52- "// uniform sampler2D sDiffuse;" ,
53- "// const float turbidity = 10.0; //" ,
54- "// const float reileigh = 2.; //" ,
55- "// const float luminance = 1.0; //" ,
56- "// const float mieCoefficient = 0.005;" ,
57- "// const float mieDirectionalG = 0.8;" ,
107+ "varying vec3 vSunDirection;" ,
108+ "varying float vSunfade;" ,
109+ "varying vec3 vBetaR;" ,
110+ "varying vec3 vBetaM;" ,
111+ "varying float vSunE;" ,
58112
59113 "uniform float luminance;" ,
60- "uniform float turbidity;" ,
61- "uniform float reileigh;" ,
62- "uniform float mieCoefficient;" ,
63114 "uniform float mieDirectionalG;" ,
64115
65- "// constants for atmospheric scattering" ,
66- "const float e = 2.71828182845904523536028747135266249775724709369995957;" ,
67- "const float pi = 3.141592653589793238462643383279502884197169;" ,
116+ "const vec3 cameraPos = vec3(0., 0., 0.);" ,
68117
69- "const float n = 1.0003; // refractive index of air" ,
70- "const float N = 2.545E25; // number of molecules per unit volume for air at" ,
71- "// 288.15K and 1013mb (sea level -45 celsius)" ,
72- "const float pn = 0.035; // depolatization factor for standard air" ,
73-
74- "// wavelength of used primaries, according to preetham" ,
75- "const vec3 lambda = vec3(680E-9, 550E-9, 450E-9);" ,
118+ // constants for atmospheric scattering
119+ "const float pi = 3.141592653589793238462643383279502884197169;" ,
76120
77- "// mie stuff" ,
78- "// K coefficient for the primaries" ,
79- "const vec3 K = vec3(0.686, 0.678, 0.666);" ,
80- "const float v = 4.0;" ,
121+ "const float n = 1.0003;" , // refractive index of air
122+ "const float N = 2.545E25;" , // number of molecules per unit volume for air at
123+ // 288.15K and 1013mb (sea level -45 celsius)
81124
82- " // optical length at zenith for molecules" ,
125+ // optical length at zenith for molecules
83126 "const float rayleighZenithLength = 8.4E3;" ,
84127 "const float mieZenithLength = 1.25E3;" ,
85128 "const vec3 up = vec3(0.0, 1.0, 0.0);" ,
86129
87- "const float EE = 1000.0;" ,
88130 "const float sunAngularDiameterCos = 0.999956676946448443553574619906976478926848692873900859324;" ,
89- "// 66 arc seconds -> degrees, and the cosine of that" ,
90-
91- "// earth shadow hack" ,
92- "const float cutoffAngle = pi/1.95;" ,
93- "const float steepness = 1.5;" ,
94-
95-
96- "vec3 totalRayleigh(vec3 lambda)" ,
97- "{" ,
98- "return (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));" ,
99- "}" ,
100-
101- // see http://blenderartists.org/forum/showthread.php?321110-Shaders-and-Skybox-madness
102- "// A simplied version of the total Reayleigh scattering to works on browsers that use ANGLE" ,
103- "vec3 simplifiedRayleigh()" ,
104- "{" ,
105- "return 0.0005 / vec3(94, 40, 18);" ,
106- // return 0.00054532832366 / (3.0 * 2.545E25 * pow(vec3(680E-9, 550E-9, 450E-9), vec3(4.0)) * 6.245);
107- "}" ,
131+ // 66 arc seconds -> degrees, and the cosine of that
108132
109133 "float rayleighPhase(float cosTheta)" ,
110- "{ " ,
111- "return (3.0 / (16.0*pi)) * (1.0 + pow(cosTheta, 2.0));" ,
112- "// return (1.0 / (3.0*pi)) * (1.0 + pow(cosTheta, 2.0));" ,
113- "// return (3.0 / 4.0) * (1.0 + pow(cosTheta, 2.0));" ,
114- "}" ,
115-
116- "vec3 totalMie(vec3 lambda, vec3 K, float T)" ,
117134 "{" ,
118- "float c = (0.2 * T ) * 10E-18;" ,
119- "return 0.434 * c * pi * pow((2.0 * pi) / lambda, vec3(v - 2.0)) * K;" ,
135+ "return (3.0 / (16.0*pi)) * (1.0 + pow(cosTheta, 2.0));" ,
120136 "}" ,
121137
122138 "float hgPhase(float cosTheta, float g)" ,
123139 "{" ,
124140 "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));" ,
125141 "}" ,
126142
127- "float sunIntensity(float zenithAngleCos)" ,
128- "{" ,
129- // This function originally used `exp(n)`, but it returns an incorrect value
130- // on Samsung S6 phones. So it has been replaced with the equivalent `pow(e, n)`.
131- // See https://github.com/mrdoob/three.js/issues/8382
132- "return EE * max(0.0, 1.0 - pow(e, -((cutoffAngle - acos(zenithAngleCos))/steepness)));" ,
133- "}" ,
134-
135- "// float logLuminance(vec3 c)" ,
136- "// {" ,
137- "// return log(c.r * 0.2126 + c.g * 0.7152 + c.b * 0.0722);" ,
138- "// }" ,
143+ // Filmic ToneMapping http://filmicgames.com/archives/75
144+ "const float A = 0.15;" ,
145+ "const float B = 0.50;" ,
146+ "const float C = 0.10;" ,
147+ "const float D = 0.20;" ,
148+ "const float E = 0.02;" ,
149+ "const float F = 0.30;" ,
139150
140- "// Filmic ToneMapping http://filmicgames.com/archives/75" ,
141- "float A = 0.15;" ,
142- "float B = 0.50;" ,
143- "float C = 0.10;" ,
144- "float D = 0.20;" ,
145- "float E = 0.02;" ,
146- "float F = 0.30;" ,
147- "float W = 1000.0;" ,
151+ "const float whiteScale = 1.0748724675633854;" , // 1.0 / Uncharted2Tonemap(1000.0)
148152
149153 "vec3 Uncharted2Tonemap(vec3 x)" ,
150154 "{" ,
@@ -154,83 +158,44 @@ THREE.ShaderLib[ 'sky' ] = {
154158
155159 "void main() " ,
156160 "{" ,
157- "float sunfade = 1.0-clamp(1.0-exp((sunPosition.y/450000.0)),0.0,1.0);" ,
158-
159- "// luminance = 1.0 ;// vWorldPosition.y / 450000. + 0.5; //sunPosition.y / 450000. * 1. + 0.5;" ,
160-
161- "// gl_FragColor = vec4(sunfade, sunfade, sunfade, 1.0);" ,
162-
163- "float reileighCoefficient = reileigh - (1.0* (1.0-sunfade));" ,
164-
165- "vec3 sunDirection = normalize(sunPosition);" ,
166-
167- "float sunE = sunIntensity(dot(sunDirection, up));" ,
168-
169- "// extinction (absorbtion + out scattering) " ,
170- "// rayleigh coefficients" ,
171-
172- // "vec3 betaR = totalRayleigh(lambda) * reileighCoefficient;",
173- "vec3 betaR = simplifiedRayleigh() * reileighCoefficient;" ,
174-
175- "// mie coefficients" ,
176- "vec3 betaM = totalMie(lambda, K, turbidity) * mieCoefficient;" ,
177-
178- "// optical length" ,
179- "// cutoff angle at 90 to avoid singularity in next formula." ,
161+ // optical length
162+ // cutoff angle at 90 to avoid singularity in next formula.
180163 "float zenithAngle = acos(max(0.0, dot(up, normalize(vWorldPosition - cameraPos))));" ,
181164 "float sR = rayleighZenithLength / (cos(zenithAngle) + 0.15 * pow(93.885 - ((zenithAngle * 180.0) / pi), -1.253));" ,
182165 "float sM = mieZenithLength / (cos(zenithAngle) + 0.15 * pow(93.885 - ((zenithAngle * 180.0) / pi), -1.253));" ,
183166
167+ // combined extinction factor
168+ "vec3 Fex = exp(-(vBetaR * sR + vBetaM * sM));" ,
184169
185-
186- "// combined extinction factor " ,
187- "vec3 Fex = exp(-(betaR * sR + betaM * sM));" ,
188-
189- "// in scattering" ,
190- "float cosTheta = dot(normalize(vWorldPosition - cameraPos), sunDirection);" ,
170+ // in scattering
171+ "float cosTheta = dot(normalize(vWorldPosition - cameraPos), vSunDirection);" ,
191172
192173 "float rPhase = rayleighPhase(cosTheta*0.5+0.5);" ,
193- "vec3 betaRTheta = betaR * rPhase;" ,
174+ "vec3 betaRTheta = vBetaR * rPhase;" ,
194175
195176 "float mPhase = hgPhase(cosTheta, mieDirectionalG);" ,
196- "vec3 betaMTheta = betaM * mPhase;" ,
197-
177+ "vec3 betaMTheta = vBetaM * mPhase;" ,
198178
199- "vec3 Lin = pow(sunE * ((betaRTheta + betaMTheta) / (betaR + betaM )) * (1.0 - Fex),vec3(1.5));" ,
200- "Lin *= mix(vec3(1.0),pow(sunE * ((betaRTheta + betaMTheta) / (betaR + betaM )) * Fex,vec3(1.0/2.0)),clamp(pow(1.0-dot(up, sunDirection ),5.0),0.0,1.0));" ,
179+ "vec3 Lin = pow(vSunE * ((betaRTheta + betaMTheta) / (vBetaR + vBetaM )) * (1.0 - Fex),vec3(1.5));" ,
180+ "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));" ,
201181
202- " //nightsky" ,
182+ //nightsky
203183 "vec3 direction = normalize(vWorldPosition - cameraPos);" ,
204184 "float theta = acos(direction.y); // elevation --> y-axis, [-pi/2, pi/2]" ,
205185 "float phi = atan(direction.z, direction.x); // azimuth --> x-axis [-pi/2, pi/2]" ,
206186 "vec2 uv = vec2(phi, theta) / vec2(2.0*pi, pi) + vec2(0.5, 0.0);" ,
207- "// vec3 L0 = texture2D(skySampler, uv).rgb+0.1 * Fex;" ,
208187 "vec3 L0 = vec3(0.1) * Fex;" ,
209188
210- "// composition + solar disc" ,
211- "//if (cosTheta > sunAngularDiameterCos)" ,
189+ // composition + solar disc
212190 "float sundisk = smoothstep(sunAngularDiameterCos,sunAngularDiameterCos+0.00002,cosTheta);" ,
213- "// if (normalize(vWorldPosition - cameraPos).y>0.0)" ,
214- "L0 += (sunE * 19000.0 * Fex)*sundisk;" ,
215-
191+ "L0 += (vSunE * 19000.0 * Fex)*sundisk;" ,
216192
217- "vec3 whiteScale = 1.0/Uncharted2Tonemap(vec3(W));" ,
218-
219- "vec3 texColor = (Lin+L0); " ,
220- "texColor *= 0.04 ;" ,
221- "texColor += vec3(0.0,0.001,0.0025)*0.3;" ,
222-
223- "float g_fMaxLuminance = 1.0;" ,
224- "float fLumScaled = 0.1 / luminance; " ,
225- "float fLumCompressed = (fLumScaled * (1.0 + (fLumScaled / (g_fMaxLuminance * g_fMaxLuminance)))) / (1.0 + fLumScaled); " ,
226-
227- "float ExposureBias = fLumCompressed;" ,
193+ "vec3 texColor = (Lin+L0) * 0.04 + vec3(0.0, 0.0003, 0.00075);" ,
228194
229195 "vec3 curr = Uncharted2Tonemap((log2(2.0/pow(luminance,4.0)))*texColor);" ,
230196 "vec3 color = curr*whiteScale;" ,
231197
232- "vec3 retColor = pow(color,vec3(1.0/(1.2+(1.2*sunfade))));" ,
233-
198+ "vec3 retColor = pow(color,vec3(1.0/(1.2+(1.2*vSunfade))));" ,
234199
235200 "gl_FragColor.rgb = retColor;" ,
236201
@@ -256,7 +221,6 @@ THREE.Sky = function () {
256221 var skyGeo = new THREE . SphereBufferGeometry ( 450000 , 32 , 15 ) ;
257222 var skyMesh = new THREE . Mesh ( skyGeo , skyMat ) ;
258223
259-
260224 // Expose variables
261225 this . mesh = skyMesh ;
262226 this . uniforms = skyUniforms ;
0 commit comments