Created
August 13, 2015 15:21
-
-
Save chanibal/709d35766ce14e45080b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
THREE.WebGLRenderer 71 | |
three.js:34 THREE.WebGLRenderer: OES_texture_float_linear extension not supported. | |
three.js:31981 THREE.PlaneGeometry: Consider using THREE.PlaneBufferGeometry for lower memory footprint. | |
three.js:31981 THREE.PlaneGeometry: Consider using THREE.PlaneBufferGeometry for lower memory footprint. | |
three.js:31981 THREE.PlaneGeometry: Consider using THREE.PlaneBufferGeometry for lower memory footprint. | |
three.js:31981 THREE.PlaneGeometry: Consider using THREE.PlaneBufferGeometry for lower memory footprint. | |
three.js:31981 THREE.PlaneGeometry: Consider using THREE.PlaneBufferGeometry for lower memory footprint. | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( ) | |
three.js:34 THREE.WebGLShader: gl.getShaderInfoLog() WARNING: 0:3: ' | |
' : extension directive must occur before any non-preprocessor tokens | |
1: precision highp float; | |
2: precision highp int; | |
3: #extension GL_OES_standard_derivatives : enable | |
4: | |
5: #define MAX_DIR_LIGHTS 0 | |
6: #define MAX_POINT_LIGHTS 2 | |
7: #define MAX_SPOT_LIGHTS 0 | |
8: #define MAX_HEMI_LIGHTS 0 | |
9: #define MAX_SHADOWS 0 | |
10: | |
11: | |
12: | |
13: #define GAMMA_FACTOR 2 | |
14: | |
15: | |
16: #define USE_MAP | |
17: | |
18: | |
19: | |
20: | |
21: | |
22: | |
23: #define USE_NORMALMAP | |
24: | |
25: | |
26: | |
27: | |
28: | |
29: | |
30: | |
31: | |
32: | |
33: | |
34: | |
35: | |
36: | |
37: uniform mat4 viewMatrix; | |
38: uniform vec3 cameraPosition; | |
39: #define PHONG | |
40: uniform vec3 diffuse; | |
41: uniform vec3 emissive; | |
42: uniform vec3 specular; | |
43: uniform float shininess; | |
44: uniform float opacity; | |
45: #define PI 3.14159 | |
46: #define PI2 6.28318 | |
47: #define RECIPROCAL_PI2 0.15915494 | |
48: #define LOG2 1.442695 | |
49: #define EPSILON 1e-6 | |
50: | |
51: float square( in float a ) { return a*a; } | |
52: vec2 square( in vec2 a ) { return vec2( a.x*a.x, a.y*a.y ); } | |
53: vec3 square( in vec3 a ) { return vec3( a.x*a.x, a.y*a.y, a.z*a.z ); } | |
54: vec4 square( in vec4 a ) { return vec4( a.x*a.x, a.y*a.y, a.z*a.z, a.w*a.w ); } | |
55: float saturate( in float a ) { return clamp( a, 0.0, 1.0 ); } | |
56: vec2 saturate( in vec2 a ) { return clamp( a, 0.0, 1.0 ); } | |
57: vec3 saturate( in vec3 a ) { return clamp( a, 0.0, 1.0 ); } | |
58: vec4 saturate( in vec4 a ) { return clamp( a, 0.0, 1.0 ); } | |
59: float average( in float a ) { return a; } | |
60: float average( in vec2 a ) { return ( a.x + a.y) * 0.5; } | |
61: float average( in vec3 a ) { return ( a.x + a.y + a.z) / 3.0; } | |
62: float average( in vec4 a ) { return ( a.x + a.y + a.z + a.w) * 0.25; } | |
63: float whiteCompliment( in float a ) { return saturate( 1.0 - a ); } | |
64: vec2 whiteCompliment( in vec2 a ) { return saturate( vec2(1.0) - a ); } | |
65: vec3 whiteCompliment( in vec3 a ) { return saturate( vec3(1.0) - a ); } | |
66: vec4 whiteCompliment( in vec4 a ) { return saturate( vec4(1.0) - a ); } | |
67: vec3 transformDirection( in vec3 normal, in mat4 matrix ) { | |
68: return normalize( ( matrix * vec4( normal, 0.0 ) ).xyz ); | |
69: } | |
70: // http://en.wikibooks.org/wiki/GLSL_Programming/Applying_Matrix_Transformations | |
71: vec3 inverseTransformDirection( in vec3 normal, in mat4 matrix ) { | |
72: return normalize( ( vec4( normal, 0.0 ) * matrix ).xyz ); | |
73: } | |
74: vec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal) { | |
75: float distance = dot( planeNormal, point-pointOnPlane ); | |
76: return point - distance * planeNormal; | |
77: } | |
78: float sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) { | |
79: return sign( dot( point - pointOnPlane, planeNormal ) ); | |
80: } | |
81: vec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) { | |
82: return pointOnLine + lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ); | |
83: } | |
84: float calcLightAttenuation( float lightDistance, float cutoffDistance, float decayExponent ) { | |
85: if ( decayExponent > 0.0 ) { | |
86: return pow( saturate( 1.0 - lightDistance / cutoffDistance ), decayExponent ); | |
87: } | |
88: return 1.0; | |
89: } | |
90: | |
91: vec3 inputToLinear( in vec3 a ) { | |
92: #ifdef GAMMA_INPUT | |
93: return pow( a, vec3( float( GAMMA_FACTOR ) ) ); | |
94: #else | |
95: return a; | |
96: #endif | |
97: } | |
98: vec3 linearToOutput( in vec3 a ) { | |
99: #ifdef GAMMA_OUTPUT | |
100: return pow( a, vec3( 1.0 / float( GAMMA_FACTOR ) ) ); | |
101: #else | |
102: return a; | |
103: #endif | |
104: } | |
105: | |
106: #ifdef USE_COLOR | |
107: | |
108: varying vec3 vColor; | |
109: | |
110: #endif | |
111: | |
112: #if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) | |
113: | |
114: varying vec2 vUv; | |
115: | |
116: #endif | |
117: | |
118: #ifdef USE_MAP | |
119: | |
120: uniform sampler2D map; | |
121: | |
122: #endif | |
123: #ifdef USE_ALPHAMAP | |
124: | |
125: uniform sampler2D alphaMap; | |
126: | |
127: #endif | |
128: | |
129: #ifdef USE_LIGHTMAP | |
130: | |
131: varying vec2 vUv2; | |
132: uniform sampler2D lightMap; | |
133: | |
134: #endif | |
135: #ifdef USE_ENVMAP | |
136: | |
137: uniform float reflectivity; | |
138: #ifdef ENVMAP_TYPE_CUBE | |
139: uniform samplerCube envMap; | |
140: #else | |
141: uniform sampler2D envMap; | |
142: #endif | |
143: uniform float flipEnvMap; | |
144: | |
145: #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) | |
146: | |
147: uniform float refractionRatio; | |
148: | |
149: #else | |
150: | |
151: varying vec3 vReflect; | |
152: | |
153: #endif | |
154: | |
155: #endif | |
156: | |
157: #ifdef USE_FOG | |
158: | |
159: uniform vec3 fogColor; | |
160: | |
161: #ifdef FOG_EXP2 | |
162: | |
163: uniform float fogDensity; | |
164: | |
165: #else | |
166: | |
167: uniform float fogNear; | |
168: uniform float fogFar; | |
169: #endif | |
170: | |
171: #endif | |
172: uniform vec3 ambientLightColor; | |
173: | |
174: #if MAX_DIR_LIGHTS > 0 | |
175: | |
176: uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ]; | |
177: uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ]; | |
178: | |
179: #endif | |
180: | |
181: #if MAX_HEMI_LIGHTS > 0 | |
182: | |
183: uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ]; | |
184: uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ]; | |
185: uniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ]; | |
186: | |
187: #endif | |
188: | |
189: #if MAX_POINT_LIGHTS > 0 | |
190: | |
191: uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ]; | |
192: | |
193: uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ]; | |
194: uniform float pointLightDistance[ MAX_POINT_LIGHTS ]; | |
195: uniform float pointLightDecay[ MAX_POINT_LIGHTS ]; | |
196: | |
197: #endif | |
198: | |
199: #if MAX_SPOT_LIGHTS > 0 | |
200: | |
201: uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ]; | |
202: uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ]; | |
203: uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ]; | |
204: uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ]; | |
205: uniform float spotLightExponent[ MAX_SPOT_LIGHTS ]; | |
206: uniform float spotLightDistance[ MAX_SPOT_LIGHTS ]; | |
207: uniform float spotLightDecay[ MAX_SPOT_LIGHTS ]; | |
208: | |
209: #endif | |
210: | |
211: #if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP ) || defined( USE_ENVMAP ) | |
212: | |
213: varying vec3 vWorldPosition; | |
214: | |
215: #endif | |
216: | |
217: #ifdef WRAP_AROUND | |
218: | |
219: uniform vec3 wrapRGB; | |
220: | |
221: #endif | |
222: | |
223: varying vec3 vViewPosition; | |
224: | |
225: #ifndef FLAT_SHADED | |
226: | |
227: varying vec3 vNormal; | |
228: | |
229: #endif | |
230: | |
231: #ifdef USE_SHADOWMAP | |
232: | |
233: uniform sampler2D shadowMap[ MAX_SHADOWS ]; | |
234: uniform vec2 shadowMapSize[ MAX_SHADOWS ]; | |
235: | |
236: uniform float shadowDarkness[ MAX_SHADOWS ]; | |
237: uniform float shadowBias[ MAX_SHADOWS ]; | |
238: | |
239: varying vec4 vShadowCoord[ MAX_SHADOWS ]; | |
240: | |
241: float unpackDepth( const in vec4 rgba_depth ) { | |
242: | |
243: const vec4 bit_shift = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 ); | |
244: float depth = dot( rgba_depth, bit_shift ); | |
245: return depth; | |
246: | |
247: } | |
248: | |
249: #endif | |
250: #ifdef USE_BUMPMAP | |
251: | |
252: uniform sampler2D bumpMap; | |
253: uniform float bumpScale; | |
254: | |
255: // Derivative maps - bump mapping unparametrized surfaces by Morten Mikkelsen | |
256: // http://mmikkelsen3d.blogspot.sk/2011/07/derivative-maps.html | |
257: | |
258: // Evaluate the derivative of the height w.r.t. screen-space using forward differencing (listing 2) | |
259: | |
260: vec2 dHdxy_fwd() { | |
261: | |
262: vec2 dSTdx = dFdx( vUv ); | |
263: vec2 dSTdy = dFdy( vUv ); | |
264: | |
265: float Hll = bumpScale * texture2D( bumpMap, vUv ).x; | |
266: float dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll; | |
267: float dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll; | |
268: | |
269: return vec2( dBx, dBy ); | |
270: | |
271: } | |
272: | |
273: vec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) { | |
274: | |
275: vec3 vSigmaX = dFdx( surf_pos ); | |
276: vec3 vSigmaY = dFdy( surf_pos ); | |
277: vec3 vN = surf_norm; // normalized | |
278: | |
279: vec3 R1 = cross( vSigmaY, vN ); | |
280: vec3 R2 = cross( vN, vSigmaX ); | |
281: | |
282: float fDet = dot( vSigmaX, R1 ); | |
283: | |
284: vec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 ); | |
285: return normalize( abs( fDet ) * surf_norm - vGrad ); | |
286: | |
287: } | |
288: | |
289: #endif | |
290: | |
291: #ifdef USE_NORMALMAP | |
292: | |
293: uniform sampler2D normalMap; | |
294: uniform vec2 normalScale; | |
295: | |
296: // Per-Pixel Tangent Space Normal Mapping | |
297: // http://hacksoflife.blogspot.ch/2009/11/per-pixel-tangent-space-normal-mapping.html | |
298: | |
299: vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) { | |
300: | |
301: vec3 q0 = dFdx( eye_pos.xyz ); | |
302: vec3 q1 = dFdy( eye_pos.xyz ); | |
303: vec2 st0 = dFdx( vUv.st ); | |
304: vec2 st1 = dFdy( vUv.st ); | |
305: | |
306: vec3 S = normalize( q0 * st1.t - q1 * st0.t ); | |
307: vec3 T = normalize( -q0 * st1.s + q1 * st0.s ); | |
308: vec3 N = normalize( surf_norm ); | |
309: | |
310: vec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0; | |
311: mapN.xy = normalScale * mapN.xy; | |
312: mat3 tsn = mat3( S, T, N ); | |
313: return normalize( tsn * mapN ); | |
314: | |
315: } | |
316: | |
317: #endif | |
318: | |
319: #ifdef USE_SPECULARMAP | |
320: | |
321: uniform sampler2D specularMap; | |
322: | |
323: #endif | |
324: #ifdef USE_LOGDEPTHBUF | |
325: | |
326: uniform float logDepthBufFC; | |
327: | |
328: #ifdef USE_LOGDEPTHBUF_EXT | |
329: | |
330: #extension GL_EXT_frag_depth : enable | |
331: varying float vFragDepth; | |
332: | |
333: #endif | |
334: | |
335: #endif | |
336: void main() { | |
337: vec3 outgoingLight = vec3( 0.0 ); | |
338: vec4 diffuseColor = vec4( diffuse, opacity ); | |
339: #if defined(USE_LOGDEPTHBUF) && defined(USE_LOGDEPTHBUF_EXT) | |
340: | |
341: gl_FragDepthEXT = log2(vFragDepth) * logDepthBufFC * 0.5; | |
342: | |
343: #endif | |
344: #ifdef USE_MAP | |
345: | |
346: vec4 texelColor = texture2D( map, vUv ); | |
347: | |
348: texelColor.xyz = inputToLinear( texelColor.xyz ); | |
349: | |
350: diffuseColor *= texelColor; | |
351: | |
352: #endif | |
353: #ifdef USE_COLOR | |
354: | |
355: diffuseColor.rgb *= vColor; | |
356: | |
357: #endif | |
358: #ifdef USE_ALPHAMAP | |
359: | |
360: diffuseColor.a *= texture2D( alphaMap, vUv ).g; | |
361: | |
362: #endif | |
363: | |
364: #ifdef ALPHATEST | |
365: | |
366: if ( diffuseColor.a < ALPHATEST ) discard; | |
367: | |
368: #endif | |
369: | |
370: float specularStrength; | |
371: | |
372: #ifdef USE_SPECULARMAP | |
373: | |
374: vec4 texelSpecular = texture2D( specularMap, vUv ); | |
375: specularStrength = texelSpecular.r; | |
376: | |
377: #else | |
378: | |
379: specularStrength = 1.0; | |
380: | |
381: #endif | |
382: #ifndef FLAT_SHADED | |
383: | |
384: vec3 normal = normalize( vNormal ); | |
385: | |
386: #ifdef DOUBLE_SIDED | |
387: | |
388: normal = normal * ( -1.0 + 2.0 * float( gl_FrontFacing ) ); | |
389: | |
390: #endif | |
391: | |
392: #else | |
393: | |
394: vec3 fdx = dFdx( vViewPosition ); | |
395: vec3 fdy = dFdy( vViewPosition ); | |
396: vec3 normal = normalize( cross( fdx, fdy ) ); | |
397: | |
398: #endif | |
399: | |
400: vec3 viewPosition = normalize( vViewPosition ); | |
401: | |
402: #ifdef USE_NORMALMAP | |
403: | |
404: normal = perturbNormal2Arb( -vViewPosition, normal ); | |
405: | |
406: #elif defined( USE_BUMPMAP ) | |
407: | |
408: normal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() ); | |
409: | |
410: #endif | |
411: | |
412: vec3 totalDiffuseLight = vec3( 0.0 ); | |
413: vec3 totalSpecularLight = vec3( 0.0 ); | |
414: | |
415: #if MAX_POINT_LIGHTS > 0 | |
416: | |
417: for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) { | |
418: | |
419: vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 ); | |
420: vec3 lVector = lPosition.xyz + vViewPosition.xyz; | |
421: | |
422: float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] ); | |
423: | |
424: lVector = normalize( lVector ); | |
425: | |
426: // diffuse | |
427: | |
428: float dotProduct = dot( normal, lVector ); | |
429: | |
430: #ifdef WRAP_AROUND | |
431: | |
432: float pointDiffuseWeightFull = max( dotProduct, 0.0 ); | |
433: float pointDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 ); | |
434: | |
435: vec3 pointDiffuseWeight = mix( vec3( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), wrapRGB ); | |
436: | |
437: #else | |
438: | |
439: float pointDiffuseWeight = max( dotProduct, 0.0 ); | |
440: | |
441: #endif | |
442: | |
443: totalDiffuseLight += pointLightColor[ i ] * pointDiffuseWeight * attenuation; | |
444: | |
445: // specular | |
446: | |
447: vec3 pointHalfVector = normalize( lVector + viewPosition ); | |
448: float pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 ); | |
449: float pointSpecularWeight = specularStrength * max( pow( pointDotNormalHalf, shininess ), 0.0 ); | |
450: | |
451: float specularNormalization = ( shininess + 2.0 ) / 8.0; | |
452: | |
453: vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, pointHalfVector ), 0.0 ), 5.0 ); | |
454: totalSpecularLight += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * attenuation * specularNormalization; | |
455: | |
456: } | |
457: | |
458: #endif | |
459: | |
460: #if MAX_SPOT_LIGHTS > 0 | |
461: | |
462: for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) { | |
463: | |
464: vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 ); | |
465: vec3 lVector = lPosition.xyz + vViewPosition.xyz; | |
466: | |
467: float attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] ); | |
468: | |
469: lVector = normalize( lVector ); | |
470: | |
471: float spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - vWorldPosition ) ); | |
472: | |
473: if ( spotEffect > spotLightAngleCos[ i ] ) { | |
474: | |
475: spotEffect = max( pow( max( spotEffect, 0.0 ), spotLightExponent[ i ] ), 0.0 ); | |
476: | |
477: // diffuse | |
478: | |
479: float dotProduct = dot( normal, lVector ); | |
480: | |
481: #ifdef WRAP_AROUND | |
482: | |
483: float spotDiffuseWeightFull = max( dotProduct, 0.0 ); | |
484: float spotDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 ); | |
485: | |
486: vec3 spotDiffuseWeight = mix( vec3( spotDiffuseWeightFull ), vec3( spotDiffuseWeightHalf ), wrapRGB ); | |
487: | |
488: #else | |
489: | |
490: float spotDiffuseWeight = max( dotProduct, 0.0 ); | |
491: | |
492: #endif | |
493: | |
494: totalDiffuseLight += spotLightColor[ i ] * spotDiffuseWeight * attenuation * spotEffect; | |
495: | |
496: // specular | |
497: | |
498: vec3 spotHalfVector = normalize( lVector + viewPosition ); | |
499: float spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 ); | |
500: float spotSpecularWeight = specularStrength * max( pow( spotDotNormalHalf, shininess ), 0.0 ); | |
501: | |
502: float specularNormalization = ( shininess + 2.0 ) / 8.0; | |
503: | |
504: vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, spotHalfVector ), 0.0 ), 5.0 ); | |
505: totalSpecularLight += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * attenuation * specularNormalization * spotEffect; | |
506: | |
507: } | |
508: | |
509: } | |
510: | |
511: #endif | |
512: | |
513: #if MAX_DIR_LIGHTS > 0 | |
514: | |
515: for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) { | |
516: | |
517: vec3 dirVector = transformDirection( directionalLightDirection[ i ], viewMatrix ); | |
518: | |
519: // diffuse | |
520: | |
521: float dotProduct = dot( normal, dirVector ); | |
522: | |
523: #ifdef WRAP_AROUND | |
524: | |
525: float dirDiffuseWeightFull = max( dotProduct, 0.0 ); | |
526: float dirDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 ); | |
527: | |
528: vec3 dirDiffuseWeight = mix( vec3( dirDiffuseWeightFull ), vec3( dirDiffuseWeightHalf ), wrapRGB ); | |
529: | |
530: #else | |
531: | |
532: float dirDiffuseWeight = max( dotProduct, 0.0 ); | |
533: | |
534: #endif | |
535: | |
536: totalDiffuseLight += directionalLightColor[ i ] * dirDiffuseWeight; | |
537: | |
538: // specular | |
539: | |
540: vec3 dirHalfVector = normalize( dirVector + viewPosition ); | |
541: float dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 ); | |
542: float dirSpecularWeight = specularStrength * max( pow( dirDotNormalHalf, shininess ), 0.0 ); | |
543: | |
544: /* | |
545: // fresnel term from skin shader | |
546: const float F0 = 0.128; | |
547: | |
548: float base = 1.0 - dot( viewPosition, dirHalfVector ); | |
549: float exponential = pow( base, 5.0 ); | |
550: | |
551: float fresnel = exponential + F0 * ( 1.0 - exponential ); | |
552: */ | |
553: | |
554: /* | |
555: // fresnel term from fresnel shader | |
556: const float mFresnelBias = 0.08; | |
557: const float mFresnelScale = 0.3; | |
558: const float mFresnelPower = 5.0; | |
559: | |
560: float fresnel = mFresnelBias + mFresnelScale * pow( 1.0 + dot( normalize( -viewPosition ), normal ), mFresnelPower ); | |
561: */ | |
562: | |
563: float specularNormalization = ( shininess + 2.0 ) / 8.0; | |
564: | |
565: // dirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization * fresnel; | |
566: | |
567: vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( dirVector, dirHalfVector ), 0.0 ), 5.0 ); | |
568: totalSpecularLight += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization; | |
569: | |
570: | |
571: } | |
572: | |
573: #endif | |
574: | |
575: #if MAX_HEMI_LIGHTS > 0 | |
576: | |
577: for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) { | |
578: | |
579: vec3 lVector = transformDirection( hemisphereLightDirection[ i ], viewMatrix ); | |
580: | |
581: // diffuse | |
582: | |
583: float dotProduct = dot( normal, lVector ); | |
584: float hemiDiffuseWeight = 0.5 * dotProduct + 0.5; | |
585: | |
586: vec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight ); | |
587: | |
588: totalDiffuseLight += hemiColor; | |
589: | |
590: // specular (sky light) | |
591: | |
592: vec3 hemiHalfVectorSky = normalize( lVector + viewPosition ); | |
593: float hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5; | |
594: float hemiSpecularWeightSky = specularStrength * max( pow( max( hemiDotNormalHalfSky, 0.0 ), shininess ), 0.0 ); | |
595: | |
596: // specular (ground light) | |
597: | |
598: vec3 lVectorGround = -lVector; | |
599: | |
600: vec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition ); | |
601: float hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5; | |
602: float hemiSpecularWeightGround = specularStrength * max( pow( max( hemiDotNormalHalfGround, 0.0 ), shininess ), 0.0 ); | |
603: | |
604: float dotProductGround = dot( normal, lVectorGround ); | |
605: | |
606: float specularNormalization = ( shininess + 2.0 ) / 8.0; | |
607: | |
608: vec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, hemiHalfVectorSky ), 0.0 ), 5.0 ); | |
609: vec3 schlickGround = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 0.0 ), 5.0 ); | |
610: totalSpecularLight += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) ); | |
611: | |
612: } | |
613: | |
614: #endif | |
615: | |
616: #ifdef METAL | |
617: | |
618: outgoingLight += diffuseColor.rgb * ( totalDiffuseLight + ambientLightColor ) * specular + totalSpecularLight + emissive; | |
619: | |
620: #else | |
621: | |
622: outgoingLight += diffuseColor.rgb * ( totalDiffuseLight + ambientLightColor ) + totalSpecularLight + emissive; | |
623: | |
624: #endif | |
625: | |
626: #ifdef USE_LIGHTMAP | |
627: | |
628: outgoingLight *= diffuseColor.xyz * texture2D( lightMap, vUv2 ).xyz; | |
629: | |
630: #endif | |
631: #ifdef USE_ENVMAP | |
632: | |
633: #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) | |
634: | |
635: vec3 cameraToVertex = normalize( vWorldPosition - cameraPosition ); | |
636: | |
637: // Transforming Normal Vectors with the Inverse Transformation | |
638: vec3 worldNormal = inverseTransformDirection( normal, viewMatrix ); | |
639: | |
640: #ifdef ENVMAP_MODE_REFLECTION | |
641: | |
642: vec3 reflectVec = reflect( cameraToVertex, worldNormal ); | |
643: | |
644: #else | |
645: | |
646: vec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio ); | |
647: | |
648: #endif | |
649: | |
650: #else | |
651: | |
652: vec3 reflectVec = vReflect; | |
653: | |
654: #endif | |
655: | |
656: #ifdef DOUBLE_SIDED | |
657: float flipNormal = ( -1.0 + 2.0 * float( gl_FrontFacing ) ); | |
658: #else | |
659: float flipNormal = 1.0; | |
660: #endif | |
661: | |
662: #ifdef ENVMAP_TYPE_CUBE | |
663: vec4 envColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) ); | |
664: | |
665: #elif defined( ENVMAP_TYPE_EQUIREC ) | |
666: vec2 sampleUV; | |
667: sampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 ); | |
668: sampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5; | |
669: vec4 envColor = texture2D( envMap, sampleUV ); | |
670: | |
671: #elif defined( ENVMAP_TYPE_SPHERE ) | |
672: vec3 reflectView = flipNormal * normalize((viewMatrix * vec4( reflectVec, 0.0 )).xyz + vec3(0.0,0.0,1.0)); | |
673: vec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 ); | |
674: #endif | |
675: | |
676: envColor.xyz = inputToLinear( envColor.xyz ); | |
677: | |
678: #ifdef ENVMAP_BLENDING_MULTIPLY | |
679: | |
680: outgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity ); | |
681: | |
682: #elif defined( ENVMAP_BLENDING_MIX ) | |
683: | |
684: outgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity ); | |
685: | |
686: #elif defined( ENVMAP_BLENDING_ADD ) | |
687: | |
688: outgoingLight += envColor.xyz * specularStrength * reflectivity; | |
689: | |
690: #endif | |
691: | |
692: #endif | |
693: | |
694: #ifdef USE_SHADOWMAP | |
695: | |
696: #ifdef SHADOWMAP_DEBUG | |
697: | |
698: vec3 frustumColors[3]; | |
699: frustumColors[0] = vec3( 1.0, 0.5, 0.0 ); | |
700: frustumColors[1] = vec3( 0.0, 1.0, 0.8 ); | |
701: frustumColors[2] = vec3( 0.0, 0.5, 1.0 ); | |
702: | |
703: #endif | |
704: | |
705: #ifdef SHADOWMAP_CASCADE | |
706: | |
707: int inFrustumCount = 0; | |
708: | |
709: #endif | |
710: | |
711: float fDepth; | |
712: vec3 shadowColor = vec3( 1.0 ); | |
713: | |
714: for( int i = 0; i < MAX_SHADOWS; i ++ ) { | |
715: | |
716: vec3 shadowCoord = vShadowCoord[ i ].xyz / vShadowCoord[ i ].w; | |
717: | |
718: // if ( something && something ) breaks ATI OpenGL shader compiler | |
719: // if ( all( something, something ) ) using this instead | |
720: | |
721: bvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 ); | |
722: bool inFrustum = all( inFrustumVec ); | |
723: | |
724: // don't shadow pixels outside of light frustum | |
725: // use just first frustum (for cascades) | |
726: // don't shadow pixels behind far plane of light frustum | |
727: | |
728: #ifdef SHADOWMAP_CASCADE | |
729: | |
730: inFrustumCount += int( inFrustum ); | |
731: bvec3 frustumTestVec = bvec3( inFrustum, inFrustumCount == 1, shadowCoord.z <= 1.0 ); | |
732: | |
733: #else | |
734: | |
735: bvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 ); | |
736: | |
737: #endif | |
738: | |
739: bool frustumTest = all( frustumTestVec ); | |
740: | |
741: if ( frustumTest ) { | |
742: | |
743: shadowCoord.z += shadowBias[ i ]; | |
744: | |
745: #if defined( SHADOWMAP_TYPE_PCF ) | |
746: | |
747: // Percentage-close filtering | |
748: // (9 pixel kernel) | |
749: // http://fabiensanglard.net/shadowmappingPCF/ | |
750: | |
751: float shadow = 0.0; | |
752: | |
753: /* | |
754: // nested loops breaks shader compiler / validator on some ATI cards when using OpenGL | |
755: // must enroll loop manually | |
756: | |
757: for ( float y = -1.25; y <= 1.25; y += 1.25 ) | |
758: for ( float x = -1.25; x <= 1.25; x += 1.25 ) { | |
759: | |
760: vec4 rgbaDepth = texture2D( shadowMap[ i ], vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy ); | |
761: | |
762: // doesn't seem to produce any noticeable visual difference compared to simple texture2D lookup | |
763: //vec4 rgbaDepth = texture2DProj( shadowMap[ i ], vec4( vShadowCoord[ i ].w * ( vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy ), 0.05, vShadowCoord[ i ].w ) ); | |
764: | |
765: float fDepth = unpackDepth( rgbaDepth ); | |
766: | |
767: if ( fDepth < shadowCoord.z ) | |
768: shadow += 1.0; | |
769: | |
770: } | |
771: | |
772: shadow /= 9.0; | |
773: | |
774: */ | |
775: | |
776: const float shadowDelta = 1.0 / 9.0; | |
777: | |
778: float xPixelOffset = 1.0 / shadowMapSize[ i ].x; | |
779: float yPixelOffset = 1.0 / shadowMapSize[ i ].y; | |
780: | |
781: float dx0 = -1.25 * xPixelOffset; | |
782: float dy0 = -1.25 * yPixelOffset; | |
783: float dx1 = 1.25 * xPixelOffset; | |
784: float dy1 = 1.25 * yPixelOffset; | |
785: | |
786: fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) ); | |
787: if ( fDepth < shadowCoord.z ) shadow += shadowDelta; | |
788: | |
789: fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) ); | |
790: if ( fDepth < shadowCoord.z ) shadow += shadowDelta; | |
791: | |
792: fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) ); | |
793: if ( fDepth < shadowCoord.z ) shadow += shadowDelta; | |
794: | |
795: fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) ); | |
796: if ( fDepth < shadowCoord.z ) shadow += shadowDelta; | |
797: | |
798: fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) ); | |
799: if ( fDepth < shadowCoord.z ) shadow += shadowDelta; | |
800: | |
801: fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) ); | |
802: if ( fDepth < shadowCoord.z ) shadow += shadowDelta; | |
803: | |
804: fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) ); | |
805: if ( fDepth < shadowCoord.z ) shadow += shadowDelta; | |
806: | |
807: fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) ); | |
808: if ( fDepth < shadowCoord.z ) shadow += shadowDelta; | |
809: | |
810: fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) ); | |
811: if ( fDepth < shadowCoord.z ) shadow += shadowDelta; | |
812: | |
813: shadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness[ i ] * shadow ) ); | |
814: | |
815: #elif defined( SHADOWMAP_TYPE_PCF_SOFT ) | |
816: | |
817: // Percentage-close filtering | |
818: // (9 pixel kernel) | |
819: // http://fabiensanglard.net/shadowmappingPCF/ | |
820: | |
821: float shadow = 0.0; | |
822: | |
823: float xPixelOffset = 1.0 / shadowMapSize[ i ].x; | |
824: float yPixelOffset = 1.0 / shadowMapSize[ i ].y; | |
825: | |
826: float dx0 = -1.0 * xPixelOffset; | |
827: float dy0 = -1.0 * yPixelOffset; | |
828: float dx1 = 1.0 * xPixelOffset; | |
829: float dy1 = 1.0 * yPixelOffset; | |
830: | |
831: mat3 shadowKernel; | |
832: mat3 depthKernel; | |
833: | |
834: depthKernel[0][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) ); | |
835: depthKernel[0][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) ); | |
836: depthKernel[0][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) ); | |
837: depthKernel[1][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) ); | |
838: depthKernel[1][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) ); | |
839: depthKernel[1][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) ); | |
840: depthKernel[2][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) ); | |
841: depthKernel[2][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) ); | |
842: depthKernel[2][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) ); | |
843: | |
844: vec3 shadowZ = vec3( shadowCoord.z ); | |
845: shadowKernel[0] = vec3(lessThan(depthKernel[0], shadowZ )); | |
846: shadowKernel[0] *= vec3(0.25); | |
847: | |
848: shadowKernel[1] = vec3(lessThan(depthKernel[1], shadowZ )); | |
849: shadowKernel[1] *= vec3(0.25); | |
850: | |
851: shadowKernel[2] = vec3(lessThan(depthKernel[2], shadowZ )); | |
852: shadowKernel[2] *= vec3(0.25); | |
853: | |
854: vec2 fractionalCoord = 1.0 - fract( shadowCoord.xy * shadowMapSize[i].xy ); | |
855: | |
856: shadowKernel[0] = mix( shadowKernel[1], shadowKernel[0], fractionalCoord.x ); | |
857: shadowKernel[1] = mix( shadowKernel[2], shadowKernel[1], fractionalCoord.x ); | |
858: | |
859: vec4 shadowValues; | |
860: shadowValues.x = mix( shadowKernel[0][1], shadowKernel[0][0], fractionalCoord.y ); | |
861: shadowValues.y = mix( shadowKernel[0][2], shadowKernel[0][1], fractionalCoord.y ); | |
862: shadowValues.z = mix( shadowKernel[1][1], shadowKernel[1][0], fractionalCoord.y ); | |
863: shadowValues.w = mix( shadowKernel[1][2], shadowKernel[1][1], fractionalCoord.y ); | |
864: | |
865: shadow = dot( shadowValues, vec4( 1.0 ) ); | |
866: | |
867: shadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness[ i ] * shadow ) ); | |
868: | |
869: #else | |
870: | |
871: vec4 rgbaDepth = texture2D( shadowMap[ i ], shadowCoord.xy ); | |
872: float fDepth = unpackDepth( rgbaDepth ); | |
873: | |
874: if ( fDepth < shadowCoord.z ) | |
875: | |
876: // spot with multiple shadows is darker | |
877: | |
878: shadowColor = shadowColor * vec3( 1.0 - shadowDarkness[ i ] ); | |
879: | |
880: // spot with multiple shadows has the same color as single shadow spot | |
881: | |
882: // shadowColor = min( shadowColor, vec3( shadowDarkness[ i ] ) ); | |
883: | |
884: #endif | |
885: | |
886: } | |
887: | |
888: | |
889: #ifdef SHADOWMAP_DEBUG | |
890: | |
891: #ifdef SHADOWMAP_CASCADE | |
892: | |
893: if ( inFrustum && inFrustumCount == 1 ) outgoingLight *= frustumColors[ i ]; | |
894: | |
895: #else | |
896: | |
897: if ( inFrustum ) outgoingLight *= frustumColors[ i ]; | |
898: | |
899: #endif | |
900: | |
901: #endif | |
902: | |
903: } | |
904: | |
905: // NOTE: I am unsure if this is correct in linear space. -bhouston, Dec 29, 2014 | |
906: shadowColor = inputToLinear( shadowColor ); | |
907: | |
908: outgoingLight = outgoingLight * shadowColor; | |
909: | |
910: #endif | |
911: | |
912: | |
913: outgoingLight = linearToOutput( outgoingLight ); | |
914: | |
915: #ifdef USE_FOG | |
916: | |
917: #ifdef USE_LOGDEPTHBUF_EXT | |
918: | |
919: float depth = gl_FragDepthEXT / gl_FragCoord.w; | |
920: | |
921: #else | |
922: | |
923: float depth = gl_FragCoord.z / gl_FragCoord.w; | |
924: | |
925: #endif | |
926: | |
927: #ifdef FOG_EXP2 | |
928: | |
929: float fogFactor = exp2( - square( fogDensity ) * square( depth ) * LOG2 ); | |
930: fogFactor = whiteCompliment( fogFactor ); | |
931: | |
932: #else | |
933: | |
934: float fogFactor = smoothstep( fogNear, fogFar, depth ); | |
935: | |
936: #endif | |
937: | |
938: outgoingLight = mix( outgoingLight, fogColor, fogFactor ); | |
939: | |
940: #endif | |
941: gl_FragColor = vec4( outgoingLight, diffuseColor.a ); | |
942: } | |
three.js:34 THREE.WebGLShader: gl.getShaderInfoLog() WARNING: 0:3: ' | |
' : extension directive must occur before any non-preprocessor tokens | |
1: precision highp float; | |
2: precision highp int; | |
3: #extension GL_OES_standard_derivatives : enable | |
4: | |
5: #define MAX_DIR_LIGHTS 0 | |
6: #define MAX_POINT_LIGHTS 2 | |
7: #define MAX_SPOT_LIGHTS 0 | |
8: #define MAX_HEMI_LIGHTS 0 | |
9: #define MAX_SHADOWS 0 | |
10: | |
11: | |
12: | |
13: #define GAMMA_FACTOR 2 | |
14: | |
15: | |
16: | |
17: | |
18: | |
19: | |
20: | |
21: | |
22: | |
23: | |
24: | |
25: | |
26: | |
27: #define FLAT_SHADED | |
28: | |
29: | |
30: | |
31: | |
32: | |
33: | |
34: | |
35: | |
36: | |
37: uniform mat4 viewMatrix; | |
38: uniform vec3 cameraPosition; | |
39: #define PHONG | |
40: uniform vec3 diffuse; | |
41: uniform vec3 emissive; | |
42: uniform vec3 specular; | |
43: uniform float shininess; | |
44: uniform float opacity; | |
45: #define PI 3.14159 | |
46: #define PI2 6.28318 | |
47: #define RECIPROCAL_PI2 0.15915494 | |
48: #define LOG2 1.442695 | |
49: #define EPSILON 1e-6 | |
50: | |
51: float square( in float a ) { return a*a; } | |
52: vec2 square( in vec2 a ) { return vec2( a.x*a.x, a.y*a.y ); } | |
53: vec3 square( in vec3 a ) { return vec3( a.x*a.x, a.y*a.y, a.z*a.z ); } | |
54: vec4 square( in vec4 a ) { return vec4( a.x*a.x, a.y*a.y, a.z*a.z, a.w*a.w ); } | |
55: float saturate( in float a ) { return clamp( a, 0.0, 1.0 ); } | |
56: vec2 saturate( in vec2 a ) { return clamp( a, 0.0, 1.0 ); } | |
57: vec3 saturate( in vec3 a ) { return clamp( a, 0.0, 1.0 ); } | |
58: vec4 saturate( in vec4 a ) { return clamp( a, 0.0, 1.0 ); } | |
59: float average( in float a ) { return a; } | |
60: float average( in vec2 a ) { return ( a.x + a.y) * 0.5; } | |
61: float average( in vec3 a ) { return ( a.x + a.y + a.z) / 3.0; } | |
62: float average( in vec4 a ) { return ( a.x + a.y + a.z + a.w) * 0.25; } | |
63: float whiteCompliment( in float a ) { return saturate( 1.0 - a ); } | |
64: vec2 whiteCompliment( in vec2 a ) { return saturate( vec2(1.0) - a ); } | |
65: vec3 whiteCompliment( in vec3 a ) { return saturate( vec3(1.0) - a ); } | |
66: vec4 whiteCompliment( in vec4 a ) { return saturate( vec4(1.0) - a ); } | |
67: vec3 transformDirection( in vec3 normal, in mat4 matrix ) { | |
68: return normalize( ( matrix * vec4( normal, 0.0 ) ).xyz ); | |
69: } | |
70: // http://en.wikibooks.org/wiki/GLSL_Programming/Applying_Matrix_Transformations | |
71: vec3 inverseTransformDirection( in vec3 normal, in mat4 matrix ) { | |
72: return normalize( ( vec4( normal, 0.0 ) * matrix ).xyz ); | |
73: } | |
74: vec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal) { | |
75: float distance = dot( planeNormal, point-pointOnPlane ); | |
76: return point - distance * planeNormal; | |
77: } | |
78: float sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) { | |
79: return sign( dot( point - pointOnPlane, planeNormal ) ); | |
80: } | |
81: vec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) { | |
82: return pointOnLine + lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ); | |
83: } | |
84: float calcLightAttenuation( float lightDistance, float cutoffDistance, float decayExponent ) { | |
85: if ( decayExponent > 0.0 ) { | |
86: return pow( saturate( 1.0 - lightDistance / cutoffDistance ), decayExponent ); | |
87: } | |
88: return 1.0; | |
89: } | |
90: | |
91: vec3 inputToLinear( in vec3 a ) { | |
92: #ifdef GAMMA_INPUT | |
93: return pow( a, vec3( float( GAMMA_FACTOR ) ) ); | |
94: #else | |
95: return a; | |
96: #endif | |
97: } | |
98: vec3 linearToOutput( in vec3 a ) { | |
99: #ifdef GAMMA_OUTPUT | |
100: return pow( a, vec3( 1.0 / float( GAMMA_FACTOR ) ) ); | |
101: #else | |
102: return a; | |
103: #endif | |
104: } | |
105: | |
106: #ifdef USE_COLOR | |
107: | |
108: varying vec3 vColor; | |
109: | |
110: #endif | |
111: | |
112: #if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) | |
113: | |
114: varying vec2 vUv; | |
115: | |
116: #endif | |
117: | |
118: #ifdef USE_MAP | |
119: | |
120: uniform sampler2D map; | |
121: | |
122: #endif | |
123: #ifdef USE_ALPHAMAP | |
124: | |
125: uniform sampler2D alphaMap; | |
126: | |
127: #endif | |
128: | |
129: #ifdef USE_LIGHTMAP | |
130: | |
131: varying vec2 vUv2; | |
132: uniform sampler2D lightMap; | |
133: | |
134: #endif | |
135: #ifdef USE_ENVMAP | |
136: | |
137: uniform float reflectivity; | |
138: #ifdef ENVMAP_TYPE_CUBE | |
139: uniform samplerCube envMap; | |
140: #else | |
141: uniform sampler2D envMap; | |
142: #endif | |
143: uniform float flipEnvMap; | |
144: | |
145: #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) | |
146: | |
147: uniform float refractionRatio; | |
148: | |
149: #else | |
150: | |
151: varying vec3 vReflect; | |
152: | |
153: #endif | |
154: | |
155: #endif | |
156: | |
157: #ifdef USE_FOG | |
158: | |
159: uniform vec3 fogColor; | |
160: | |
161: #ifdef FOG_EXP2 | |
162: | |
163: uniform float fogDensity; | |
164: | |
165: #else | |
166: | |
167: uniform float fogNear; | |
168: uniform float fogFar; | |
169: #endif | |
170: | |
171: #endif | |
172: uniform vec3 ambientLightColor; | |
173: | |
174: #if MAX_DIR_LIGHTS > 0 | |
175: | |
176: uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ]; | |
177: uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ]; | |
178: | |
179: #endif | |
180: | |
181: #if MAX_HEMI_LIGHTS > 0 | |
182: | |
183: uniform vec3 hemisphereLightSkyColor[ MAX_HEMI_LIGHTS ]; | |
184: uniform vec3 hemisphereLightGroundColor[ MAX_HEMI_LIGHTS ]; | |
185: uniform vec3 hemisphereLightDirection[ MAX_HEMI_LIGHTS ]; | |
186: | |
187: #endif | |
188: | |
189: #if MAX_POINT_LIGHTS > 0 | |
190: | |
191: uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ]; | |
192: | |
193: uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ]; | |
194: uniform float pointLightDistance[ MAX_POINT_LIGHTS ]; | |
195: uniform float pointLightDecay[ MAX_POINT_LIGHTS ]; | |
196: | |
197: #endif | |
198: | |
199: #if MAX_SPOT_LIGHTS > 0 | |
200: | |
201: uniform vec3 spotLightColor[ MAX_SPOT_LIGHTS ]; | |
202: uniform vec3 spotLightPosition[ MAX_SPOT_LIGHTS ]; | |
203: uniform vec3 spotLightDirection[ MAX_SPOT_LIGHTS ]; | |
204: uniform float spotLightAngleCos[ MAX_SPOT_LIGHTS ]; | |
205: uniform float spotLightExponent[ MAX_SPOT_LIGHTS ]; | |
206: uniform float spotLightDistance[ MAX_SPOT_LIGHTS ]; | |
207: uniform float spotLightDecay[ MAX_SPOT_LIGHTS ]; | |
208: | |
209: #endif | |
210: | |
211: #if MAX_SPOT_LIGHTS > 0 || defined( USE_BUMPMAP ) || defined( USE_ENVMAP ) | |
212: | |
213: varying vec3 vWorldPosition; | |
214: | |
215: #endif | |
216: | |
217: #ifdef WRAP_AROUND | |
218: | |
219: uniform vec3 wrapRGB; | |
220: | |
221: #endif | |
222: | |
223: varying vec3 vViewPosition; | |
224: | |
225: #ifndef FLAT_SHADED | |
226: | |
227: varying vec3 vNormal; | |
228: | |
229: #endif | |
230: | |
231: #ifdef USE_SHADOWMAP | |
232: | |
233: uniform sampler2D shadowMap[ MAX_SHADOWS ]; | |
234: uniform vec2 shadowMapSize[ MAX_SHADOWS ]; | |
235: | |
236: uniform float shadowDarkness[ MAX_SHADOWS ]; | |
237: uniform float shadowBias[ MAX_SHADOWS ]; | |
238: | |
239: varying vec4 vShadowCoord[ MAX_SHADOWS ]; | |
240: | |
241: float unpackDepth( const in vec4 rgba_depth ) { | |
242: | |
243: const vec4 bit_shift = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 ); | |
244: float depth = dot( rgba_depth, bit_shift ); | |
245: return depth; | |
246: | |
247: } | |
248: | |
249: #endif | |
250: #ifdef USE_BUMPMAP | |
251: | |
252: uniform sampler2D bumpMap; | |
253: uniform float bumpScale; | |
254: | |
255: // Derivative maps - bump mapping unparametrized surfaces by Morten Mikkelsen | |
256: // http://mmikkelsen3d.blogspot.sk/2011/07/derivative-maps.html | |
257: | |
258: // Evaluate the derivative of the height w.r.t. screen-space using forward differencing (listing 2) | |
259: | |
260: vec2 dHdxy_fwd() { | |
261: | |
262: vec2 dSTdx = dFdx( vUv ); | |
263: vec2 dSTdy = dFdy( vUv ); | |
264: | |
265: float Hll = bumpScale * texture2D( bumpMap, vUv ).x; | |
266: float dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll; | |
267: float dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll; | |
268: | |
269: return vec2( dBx, dBy ); | |
270: | |
271: } | |
272: | |
273: vec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) { | |
274: | |
275: vec3 vSigmaX = dFdx( surf_pos ); | |
276: vec3 vSigmaY = dFdy( surf_pos ); | |
277: vec3 vN = surf_norm; // normalized | |
278: | |
279: vec3 R1 = cross( vSigmaY, vN ); | |
280: vec3 R2 = cross( vN, vSigmaX ); | |
281: | |
282: float fDet = dot( vSigmaX, R1 ); | |
283: | |
284: vec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 ); | |
285: return normalize( abs( fDet ) * surf_norm - vGrad ); | |
286: | |
287: } | |
288: | |
289: #endif | |
290: | |
291: #ifdef USE_NORMALMAP | |
292: | |
293: uniform sampler2D normalMap; | |
294: uniform vec2 normalScale; | |
295: | |
296: // Per-Pixel Tangent Space Normal Mapping | |
297: // http://hacksoflife.blogspot.ch/2009/11/per-pixel-tangent-space-normal-mapping.html | |
298: | |
299: vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) { | |
300: | |
301: vec3 q0 = dFdx( eye_pos.xyz ); | |
302: vec3 q1 = dFdy( eye_pos.xyz ); | |
303: vec2 st0 = dFdx( vUv.st ); | |
304: vec2 st1 = dFdy( vUv.st ); | |
305: | |
306: vec3 S = normalize( q0 * st1.t - q1 * st0.t ); | |
307: vec3 T = normalize( -q0 * st1.s + q1 * st0.s ); | |
308: vec3 N = normalize( surf_norm ); | |
309: | |
310: vec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0; | |
311: mapN.xy = normalScale * mapN.xy; | |
312: mat3 tsn = mat3( S, T, N ); | |
313: return normalize( tsn * mapN ); | |
314: | |
315: } | |
316: | |
317: #endif | |
318: | |
319: #ifdef USE_SPECULARMAP | |
320: | |
321: uniform sampler2D specularMap; | |
322: | |
323: #endif | |
324: #ifdef USE_LOGDEPTHBUF | |
325: | |
326: uniform float logDepthBufFC; | |
327: | |
328: #ifdef USE_LOGDEPTHBUF_EXT | |
329: | |
330: #extension GL_EXT_frag_depth : enable | |
331: varying float vFragDepth; | |
332: | |
333: #endif | |
334: | |
335: #endif | |
336: void main() { | |
337: vec3 outgoingLight = vec3( 0.0 ); | |
338: vec4 diffuseColor = vec4( diffuse, opacity ); | |
339: #if defined(USE_LOGDEPTHBUF) && defined(USE_LOGDEPTHBUF_EXT) | |
340: | |
341: gl_FragDepthEXT = log2(vFragDepth) * logDepthBufFC * 0.5; | |
342: | |
343: #endif | |
344: #ifdef USE_MAP | |
345: | |
346: vec4 texelColor = texture2D( map, vUv ); | |
347: | |
348: texelColor.xyz = inputToLinear( texelColor.xyz ); | |
349: | |
350: diffuseColor *= texelColor; | |
351: | |
352: #endif | |
353: #ifdef USE_COLOR | |
354: | |
355: diffuseColor.rgb *= vColor; | |
356: | |
357: #endif | |
358: #ifdef USE_ALPHAMAP | |
359: | |
360: diffuseColor.a *= texture2D( alphaMap, vUv ).g; | |
361: | |
362: #endif | |
363: | |
364: #ifdef ALPHATEST | |
365: | |
366: if ( diffuseColor.a < ALPHATEST ) discard; | |
367: | |
368: #endif | |
369: | |
370: float specularStrength; | |
371: | |
372: #ifdef USE_SPECULARMAP | |
373: | |
374: vec4 texelSpecular = texture2D( specularMap, vUv ); | |
375: specularStrength = texelSpecular.r; | |
376: | |
377: #else | |
378: | |
379: specularStrength = 1.0; | |
380: | |
381: #endif | |
382: #ifndef FLAT_SHADED | |
383: | |
384: vec3 normal = normalize( vNormal ); | |
385: | |
386: #ifdef DOUBLE_SIDED | |
387: | |
388: normal = normal * ( -1.0 + 2.0 * float( gl_FrontFacing ) ); | |
389: | |
390: #endif | |
391: | |
392: #else | |
393: | |
394: vec3 fdx = dFdx( vViewPosition ); | |
395: vec3 fdy = dFdy( vViewPosition ); | |
396: vec3 normal = normalize( cross( fdx, fdy ) ); | |
397: | |
398: #endif | |
399: | |
400: vec3 viewPosition = normalize( vViewPosition ); | |
401: | |
402: #ifdef USE_NORMALMAP | |
403: | |
404: normal = perturbNormal2Arb( -vViewPosition, normal ); | |
405: | |
406: #elif defined( USE_BUMPMAP ) | |
407: | |
408: normal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() ); | |
409: | |
410: #endif | |
411: | |
412: vec3 totalDiffuseLight = vec3( 0.0 ); | |
413: vec3 totalSpecularLight = vec3( 0.0 ); | |
414: | |
415: #if MAX_POINT_LIGHTS > 0 | |
416: | |
417: for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) { | |
418: | |
419: vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 ); | |
420: vec3 lVector = lPosition.xyz + vViewPosition.xyz; | |
421: | |
422: float attenuation = calcLightAttenuation( length( lVector ), pointLightDistance[ i ], pointLightDecay[ i ] ); | |
423: | |
424: lVector = normalize( lVector ); | |
425: | |
426: // diffuse | |
427: | |
428: float dotProduct = dot( normal, lVector ); | |
429: | |
430: #ifdef WRAP_AROUND | |
431: | |
432: float pointDiffuseWeightFull = max( dotProduct, 0.0 ); | |
433: float pointDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 ); | |
434: | |
435: vec3 pointDiffuseWeight = mix( vec3( pointDiffuseWeightFull ), vec3( pointDiffuseWeightHalf ), wrapRGB ); | |
436: | |
437: #else | |
438: | |
439: float pointDiffuseWeight = max( dotProduct, 0.0 ); | |
440: | |
441: #endif | |
442: | |
443: totalDiffuseLight += pointLightColor[ i ] * pointDiffuseWeight * attenuation; | |
444: | |
445: // specular | |
446: | |
447: vec3 pointHalfVector = normalize( lVector + viewPosition ); | |
448: float pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 ); | |
449: float pointSpecularWeight = specularStrength * max( pow( pointDotNormalHalf, shininess ), 0.0 ); | |
450: | |
451: float specularNormalization = ( shininess + 2.0 ) / 8.0; | |
452: | |
453: vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, pointHalfVector ), 0.0 ), 5.0 ); | |
454: totalSpecularLight += schlick * pointLightColor[ i ] * pointSpecularWeight * pointDiffuseWeight * attenuation * specularNormalization; | |
455: | |
456: } | |
457: | |
458: #endif | |
459: | |
460: #if MAX_SPOT_LIGHTS > 0 | |
461: | |
462: for ( int i = 0; i < MAX_SPOT_LIGHTS; i ++ ) { | |
463: | |
464: vec4 lPosition = viewMatrix * vec4( spotLightPosition[ i ], 1.0 ); | |
465: vec3 lVector = lPosition.xyz + vViewPosition.xyz; | |
466: | |
467: float attenuation = calcLightAttenuation( length( lVector ), spotLightDistance[ i ], spotLightDecay[ i ] ); | |
468: | |
469: lVector = normalize( lVector ); | |
470: | |
471: float spotEffect = dot( spotLightDirection[ i ], normalize( spotLightPosition[ i ] - vWorldPosition ) ); | |
472: | |
473: if ( spotEffect > spotLightAngleCos[ i ] ) { | |
474: | |
475: spotEffect = max( pow( max( spotEffect, 0.0 ), spotLightExponent[ i ] ), 0.0 ); | |
476: | |
477: // diffuse | |
478: | |
479: float dotProduct = dot( normal, lVector ); | |
480: | |
481: #ifdef WRAP_AROUND | |
482: | |
483: float spotDiffuseWeightFull = max( dotProduct, 0.0 ); | |
484: float spotDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 ); | |
485: | |
486: vec3 spotDiffuseWeight = mix( vec3( spotDiffuseWeightFull ), vec3( spotDiffuseWeightHalf ), wrapRGB ); | |
487: | |
488: #else | |
489: | |
490: float spotDiffuseWeight = max( dotProduct, 0.0 ); | |
491: | |
492: #endif | |
493: | |
494: totalDiffuseLight += spotLightColor[ i ] * spotDiffuseWeight * attenuation * spotEffect; | |
495: | |
496: // specular | |
497: | |
498: vec3 spotHalfVector = normalize( lVector + viewPosition ); | |
499: float spotDotNormalHalf = max( dot( normal, spotHalfVector ), 0.0 ); | |
500: float spotSpecularWeight = specularStrength * max( pow( spotDotNormalHalf, shininess ), 0.0 ); | |
501: | |
502: float specularNormalization = ( shininess + 2.0 ) / 8.0; | |
503: | |
504: vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, spotHalfVector ), 0.0 ), 5.0 ); | |
505: totalSpecularLight += schlick * spotLightColor[ i ] * spotSpecularWeight * spotDiffuseWeight * attenuation * specularNormalization * spotEffect; | |
506: | |
507: } | |
508: | |
509: } | |
510: | |
511: #endif | |
512: | |
513: #if MAX_DIR_LIGHTS > 0 | |
514: | |
515: for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) { | |
516: | |
517: vec3 dirVector = transformDirection( directionalLightDirection[ i ], viewMatrix ); | |
518: | |
519: // diffuse | |
520: | |
521: float dotProduct = dot( normal, dirVector ); | |
522: | |
523: #ifdef WRAP_AROUND | |
524: | |
525: float dirDiffuseWeightFull = max( dotProduct, 0.0 ); | |
526: float dirDiffuseWeightHalf = max( 0.5 * dotProduct + 0.5, 0.0 ); | |
527: | |
528: vec3 dirDiffuseWeight = mix( vec3( dirDiffuseWeightFull ), vec3( dirDiffuseWeightHalf ), wrapRGB ); | |
529: | |
530: #else | |
531: | |
532: float dirDiffuseWeight = max( dotProduct, 0.0 ); | |
533: | |
534: #endif | |
535: | |
536: totalDiffuseLight += directionalLightColor[ i ] * dirDiffuseWeight; | |
537: | |
538: // specular | |
539: | |
540: vec3 dirHalfVector = normalize( dirVector + viewPosition ); | |
541: float dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 ); | |
542: float dirSpecularWeight = specularStrength * max( pow( dirDotNormalHalf, shininess ), 0.0 ); | |
543: | |
544: /* | |
545: // fresnel term from skin shader | |
546: const float F0 = 0.128; | |
547: | |
548: float base = 1.0 - dot( viewPosition, dirHalfVector ); | |
549: float exponential = pow( base, 5.0 ); | |
550: | |
551: float fresnel = exponential + F0 * ( 1.0 - exponential ); | |
552: */ | |
553: | |
554: /* | |
555: // fresnel term from fresnel shader | |
556: const float mFresnelBias = 0.08; | |
557: const float mFresnelScale = 0.3; | |
558: const float mFresnelPower = 5.0; | |
559: | |
560: float fresnel = mFresnelBias + mFresnelScale * pow( 1.0 + dot( normalize( -viewPosition ), normal ), mFresnelPower ); | |
561: */ | |
562: | |
563: float specularNormalization = ( shininess + 2.0 ) / 8.0; | |
564: | |
565: // dirSpecular += specular * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization * fresnel; | |
566: | |
567: vec3 schlick = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( dirVector, dirHalfVector ), 0.0 ), 5.0 ); | |
568: totalSpecularLight += schlick * directionalLightColor[ i ] * dirSpecularWeight * dirDiffuseWeight * specularNormalization; | |
569: | |
570: | |
571: } | |
572: | |
573: #endif | |
574: | |
575: #if MAX_HEMI_LIGHTS > 0 | |
576: | |
577: for( int i = 0; i < MAX_HEMI_LIGHTS; i ++ ) { | |
578: | |
579: vec3 lVector = transformDirection( hemisphereLightDirection[ i ], viewMatrix ); | |
580: | |
581: // diffuse | |
582: | |
583: float dotProduct = dot( normal, lVector ); | |
584: float hemiDiffuseWeight = 0.5 * dotProduct + 0.5; | |
585: | |
586: vec3 hemiColor = mix( hemisphereLightGroundColor[ i ], hemisphereLightSkyColor[ i ], hemiDiffuseWeight ); | |
587: | |
588: totalDiffuseLight += hemiColor; | |
589: | |
590: // specular (sky light) | |
591: | |
592: vec3 hemiHalfVectorSky = normalize( lVector + viewPosition ); | |
593: float hemiDotNormalHalfSky = 0.5 * dot( normal, hemiHalfVectorSky ) + 0.5; | |
594: float hemiSpecularWeightSky = specularStrength * max( pow( max( hemiDotNormalHalfSky, 0.0 ), shininess ), 0.0 ); | |
595: | |
596: // specular (ground light) | |
597: | |
598: vec3 lVectorGround = -lVector; | |
599: | |
600: vec3 hemiHalfVectorGround = normalize( lVectorGround + viewPosition ); | |
601: float hemiDotNormalHalfGround = 0.5 * dot( normal, hemiHalfVectorGround ) + 0.5; | |
602: float hemiSpecularWeightGround = specularStrength * max( pow( max( hemiDotNormalHalfGround, 0.0 ), shininess ), 0.0 ); | |
603: | |
604: float dotProductGround = dot( normal, lVectorGround ); | |
605: | |
606: float specularNormalization = ( shininess + 2.0 ) / 8.0; | |
607: | |
608: vec3 schlickSky = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVector, hemiHalfVectorSky ), 0.0 ), 5.0 ); | |
609: vec3 schlickGround = specular + vec3( 1.0 - specular ) * pow( max( 1.0 - dot( lVectorGround, hemiHalfVectorGround ), 0.0 ), 5.0 ); | |
610: totalSpecularLight += hemiColor * specularNormalization * ( schlickSky * hemiSpecularWeightSky * max( dotProduct, 0.0 ) + schlickGround * hemiSpecularWeightGround * max( dotProductGround, 0.0 ) ); | |
611: | |
612: } | |
613: | |
614: #endif | |
615: | |
616: #ifdef METAL | |
617: | |
618: outgoingLight += diffuseColor.rgb * ( totalDiffuseLight + ambientLightColor ) * specular + totalSpecularLight + emissive; | |
619: | |
620: #else | |
621: | |
622: outgoingLight += diffuseColor.rgb * ( totalDiffuseLight + ambientLightColor ) + totalSpecularLight + emissive; | |
623: | |
624: #endif | |
625: | |
626: #ifdef USE_LIGHTMAP | |
627: | |
628: outgoingLight *= diffuseColor.xyz * texture2D( lightMap, vUv2 ).xyz; | |
629: | |
630: #endif | |
631: #ifdef USE_ENVMAP | |
632: | |
633: #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) | |
634: | |
635: vec3 cameraToVertex = normalize( vWorldPosition - cameraPosition ); | |
636: | |
637: // Transforming Normal Vectors with the Inverse Transformation | |
638: vec3 worldNormal = inverseTransformDirection( normal, viewMatrix ); | |
639: | |
640: #ifdef ENVMAP_MODE_REFLECTION | |
641: | |
642: vec3 reflectVec = reflect( cameraToVertex, worldNormal ); | |
643: | |
644: #else | |
645: | |
646: vec3 reflectVec = refract( cameraToVertex, worldNormal, refractionRatio ); | |
647: | |
648: #endif | |
649: | |
650: #else | |
651: | |
652: vec3 reflectVec = vReflect; | |
653: | |
654: #endif | |
655: | |
656: #ifdef DOUBLE_SIDED | |
657: float flipNormal = ( -1.0 + 2.0 * float( gl_FrontFacing ) ); | |
658: #else | |
659: float flipNormal = 1.0; | |
660: #endif | |
661: | |
662: #ifdef ENVMAP_TYPE_CUBE | |
663: vec4 envColor = textureCube( envMap, flipNormal * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) ); | |
664: | |
665: #elif defined( ENVMAP_TYPE_EQUIREC ) | |
666: vec2 sampleUV; | |
667: sampleUV.y = saturate( flipNormal * reflectVec.y * 0.5 + 0.5 ); | |
668: sampleUV.x = atan( flipNormal * reflectVec.z, flipNormal * reflectVec.x ) * RECIPROCAL_PI2 + 0.5; | |
669: vec4 envColor = texture2D( envMap, sampleUV ); | |
670: | |
671: #elif defined( ENVMAP_TYPE_SPHERE ) | |
672: vec3 reflectView = flipNormal * normalize((viewMatrix * vec4( reflectVec, 0.0 )).xyz + vec3(0.0,0.0,1.0)); | |
673: vec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 ); | |
674: #endif | |
675: | |
676: envColor.xyz = inputToLinear( envColor.xyz ); | |
677: | |
678: #ifdef ENVMAP_BLENDING_MULTIPLY | |
679: | |
680: outgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity ); | |
681: | |
682: #elif defined( ENVMAP_BLENDING_MIX ) | |
683: | |
684: outgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity ); | |
685: | |
686: #elif defined( ENVMAP_BLENDING_ADD ) | |
687: | |
688: outgoingLight += envColor.xyz * specularStrength * reflectivity; | |
689: | |
690: #endif | |
691: | |
692: #endif | |
693: | |
694: #ifdef USE_SHADOWMAP | |
695: | |
696: #ifdef SHADOWMAP_DEBUG | |
697: | |
698: vec3 frustumColors[3]; | |
699: frustumColors[0] = vec3( 1.0, 0.5, 0.0 ); | |
700: frustumColors[1] = vec3( 0.0, 1.0, 0.8 ); | |
701: frustumColors[2] = vec3( 0.0, 0.5, 1.0 ); | |
702: | |
703: #endif | |
704: | |
705: #ifdef SHADOWMAP_CASCADE | |
706: | |
707: int inFrustumCount = 0; | |
708: | |
709: #endif | |
710: | |
711: float fDepth; | |
712: vec3 shadowColor = vec3( 1.0 ); | |
713: | |
714: for( int i = 0; i < MAX_SHADOWS; i ++ ) { | |
715: | |
716: vec3 shadowCoord = vShadowCoord[ i ].xyz / vShadowCoord[ i ].w; | |
717: | |
718: // if ( something && something ) breaks ATI OpenGL shader compiler | |
719: // if ( all( something, something ) ) using this instead | |
720: | |
721: bvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 ); | |
722: bool inFrustum = all( inFrustumVec ); | |
723: | |
724: // don't shadow pixels outside of light frustum | |
725: // use just first frustum (for cascades) | |
726: // don't shadow pixels behind far plane of light frustum | |
727: | |
728: #ifdef SHADOWMAP_CASCADE | |
729: | |
730: inFrustumCount += int( inFrustum ); | |
731: bvec3 frustumTestVec = bvec3( inFrustum, inFrustumCount == 1, shadowCoord.z <= 1.0 ); | |
732: | |
733: #else | |
734: | |
735: bvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 ); | |
736: | |
737: #endif | |
738: | |
739: bool frustumTest = all( frustumTestVec ); | |
740: | |
741: if ( frustumTest ) { | |
742: | |
743: shadowCoord.z += shadowBias[ i ]; | |
744: | |
745: #if defined( SHADOWMAP_TYPE_PCF ) | |
746: | |
747: // Percentage-close filtering | |
748: // (9 pixel kernel) | |
749: // http://fabiensanglard.net/shadowmappingPCF/ | |
750: | |
751: float shadow = 0.0; | |
752: | |
753: /* | |
754: // nested loops breaks shader compiler / validator on some ATI cards when using OpenGL | |
755: // must enroll loop manually | |
756: | |
757: for ( float y = -1.25; y <= 1.25; y += 1.25 ) | |
758: for ( float x = -1.25; x <= 1.25; x += 1.25 ) { | |
759: | |
760: vec4 rgbaDepth = texture2D( shadowMap[ i ], vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy ); | |
761: | |
762: // doesn't seem to produce any noticeable visual difference compared to simple texture2D lookup | |
763: //vec4 rgbaDepth = texture2DProj( shadowMap[ i ], vec4( vShadowCoord[ i ].w * ( vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy ), 0.05, vShadowCoord[ i ].w ) ); | |
764: | |
765: float fDepth = unpackDepth( rgbaDepth ); | |
766: | |
767: if ( fDepth < shadowCoord.z ) | |
768: shadow += 1.0; | |
769: | |
770: } | |
771: | |
772: shadow /= 9.0; | |
773: | |
774: */ | |
775: | |
776: const float shadowDelta = 1.0 / 9.0; | |
777: | |
778: float xPixelOffset = 1.0 / shadowMapSize[ i ].x; | |
779: float yPixelOffset = 1.0 / shadowMapSize[ i ].y; | |
780: | |
781: float dx0 = -1.25 * xPixelOffset; | |
782: float dy0 = -1.25 * yPixelOffset; | |
783: float dx1 = 1.25 * xPixelOffset; | |
784: float dy1 = 1.25 * yPixelOffset; | |
785: | |
786: fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) ); | |
787: if ( fDepth < shadowCoord.z ) shadow += shadowDelta; | |
788: | |
789: fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) ); | |
790: if ( fDepth < shadowCoord.z ) shadow += shadowDelta; | |
791: | |
792: fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) ); | |
793: if ( fDepth < shadowCoord.z ) shadow += shadowDelta; | |
794: | |
795: fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) ); | |
796: if ( fDepth < shadowCoord.z ) shadow += shadowDelta; | |
797: | |
798: fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) ); | |
799: if ( fDepth < shadowCoord.z ) shadow += shadowDelta; | |
800: | |
801: fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) ); | |
802: if ( fDepth < shadowCoord.z ) shadow += shadowDelta; | |
803: | |
804: fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) ); | |
805: if ( fDepth < shadowCoord.z ) shadow += shadowDelta; | |
806: | |
807: fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) ); | |
808: if ( fDepth < shadowCoord.z ) shadow += shadowDelta; | |
809: | |
810: fDepth = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) ); | |
811: if ( fDepth < shadowCoord.z ) shadow += shadowDelta; | |
812: | |
813: shadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness[ i ] * shadow ) ); | |
814: | |
815: #elif defined( SHADOWMAP_TYPE_PCF_SOFT ) | |
816: | |
817: // Percentage-close filtering | |
818: // (9 pixel kernel) | |
819: // http://fabiensanglard.net/shadowmappingPCF/ | |
820: | |
821: float shadow = 0.0; | |
822: | |
823: float xPixelOffset = 1.0 / shadowMapSize[ i ].x; | |
824: float yPixelOffset = 1.0 / shadowMapSize[ i ].y; | |
825: | |
826: float dx0 = -1.0 * xPixelOffset; | |
827: float dy0 = -1.0 * yPixelOffset; | |
828: float dx1 = 1.0 * xPixelOffset; | |
829: float dy1 = 1.0 * yPixelOffset; | |
830: | |
831: mat3 shadowKernel; | |
832: mat3 depthKernel; | |
833: | |
834: depthKernel[0][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy0 ) ) ); | |
835: depthKernel[0][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, 0.0 ) ) ); | |
836: depthKernel[0][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx0, dy1 ) ) ); | |
837: depthKernel[1][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy0 ) ) ); | |
838: depthKernel[1][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy ) ); | |
839: depthKernel[1][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( 0.0, dy1 ) ) ); | |
840: depthKernel[2][0] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy0 ) ) ); | |
841: depthKernel[2][1] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, 0.0 ) ) ); | |
842: depthKernel[2][2] = unpackDepth( texture2D( shadowMap[ i ], shadowCoord.xy + vec2( dx1, dy1 ) ) ); | |
843: | |
844: vec3 shadowZ = vec3( shadowCoord.z ); | |
845: shadowKernel[0] = vec3(lessThan(depthKernel[0], shadowZ )); | |
846: shadowKernel[0] *= vec3(0.25); | |
847: | |
848: shadowKernel[1] = vec3(lessThan(depthKernel[1], shadowZ )); | |
849: shadowKernel[1] *= vec3(0.25); | |
850: | |
851: shadowKernel[2] = vec3(lessThan(depthKernel[2], shadowZ )); | |
852: shadowKernel[2] *= vec3(0.25); | |
853: | |
854: vec2 fractionalCoord = 1.0 - fract( shadowCoord.xy * shadowMapSize[i].xy ); | |
855: | |
856: shadowKernel[0] = mix( shadowKernel[1], shadowKernel[0], fractionalCoord.x ); | |
857: shadowKernel[1] = mix( shadowKernel[2], shadowKernel[1], fractionalCoord.x ); | |
858: | |
859: vec4 shadowValues; | |
860: shadowValues.x = mix( shadowKernel[0][1], shadowKernel[0][0], fractionalCoord.y ); | |
861: shadowValues.y = mix( shadowKernel[0][2], shadowKernel[0][1], fractionalCoord.y ); | |
862: shadowValues.z = mix( shadowKernel[1][1], shadowKernel[1][0], fractionalCoord.y ); | |
863: shadowValues.w = mix( shadowKernel[1][2], shadowKernel[1][1], fractionalCoord.y ); | |
864: | |
865: shadow = dot( shadowValues, vec4( 1.0 ) ); | |
866: | |
867: shadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness[ i ] * shadow ) ); | |
868: | |
869: #else | |
870: | |
871: vec4 rgbaDepth = texture2D( shadowMap[ i ], shadowCoord.xy ); | |
872: float fDepth = unpackDepth( rgbaDepth ); | |
873: | |
874: if ( fDepth < shadowCoord.z ) | |
875: | |
876: // spot with multiple shadows is darker | |
877: | |
878: shadowColor = shadowColor * vec3( 1.0 - shadowDarkness[ i ] ); | |
879: | |
880: // spot with multiple shadows has the same color as single shadow spot | |
881: | |
882: // shadowColor = min( shadowColor, vec3( shadowDarkness[ i ] ) ); | |
883: | |
884: #endif | |
885: | |
886: } | |
887: | |
888: | |
889: #ifdef SHADOWMAP_DEBUG | |
890: | |
891: #ifdef SHADOWMAP_CASCADE | |
892: | |
893: if ( inFrustum && inFrustumCount == 1 ) outgoingLight *= frustumColors[ i ]; | |
894: | |
895: #else | |
896: | |
897: if ( inFrustum ) outgoingLight *= frustumColors[ i ]; | |
898: | |
899: #endif | |
900: | |
901: #endif | |
902: | |
903: } | |
904: | |
905: // NOTE: I am unsure if this is correct in linear space. -bhouston, Dec 29, 2014 | |
906: shadowColor = inputToLinear( shadowColor ); | |
907: | |
908: outgoingLight = outgoingLight * shadowColor; | |
909: | |
910: #endif | |
911: | |
912: | |
913: outgoingLight = linearToOutput( outgoingLight ); | |
914: | |
915: #ifdef USE_FOG | |
916: | |
917: #ifdef USE_LOGDEPTHBUF_EXT | |
918: | |
919: float depth = gl_FragDepthEXT / gl_FragCoord.w; | |
920: | |
921: #else | |
922: | |
923: float depth = gl_FragCoord.z / gl_FragCoord.w; | |
924: | |
925: #endif | |
926: | |
927: #ifdef FOG_EXP2 | |
928: | |
929: float fogFactor = exp2( - square( fogDensity ) * square( depth ) * LOG2 ); | |
930: fogFactor = whiteCompliment( fogFactor ); | |
931: | |
932: #else | |
933: | |
934: float fogFactor = smoothstep( fogNear, fogFar, depth ); | |
935: | |
936: #endif | |
937: | |
938: outgoingLight = mix( outgoingLight, fogColor, fogFactor ); | |
939: | |
940: #endif | |
941: gl_FragColor = vec4( outgoingLight, diffuseColor.a ); | |
942: } | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( ) | |
6three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( ) | |
2three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/reflection.png ) | |
2three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( ) | |
5three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/links-particles.png ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/horizontal_lights.png ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/about.png ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/twitter.png ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/github.png ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/online-open-circle.png ) | |
2three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/online-closed-circle.png ) | |
3three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/online-open-circle.png ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/online-closed-circle.png ) | |
2three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/online-open-circle.png ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/online-closed-circle.png ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/online-open-circle.png ) | |
2three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/online-closed-circle.png ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/online-open-circle.png ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/online-closed-circle.png ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/online-open-circle.png ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/online-home.png ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/online-github.png ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/online-closed-circle.png ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/online-twitter.png ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/online-open-circle.png ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/online-linkedin.png ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/online-flickr.png ) | |
4three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/online-open-circle.png ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/links-text-linkedin.png ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/links-text-twitter.png ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/links-text-github.png ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/links-text-flickr.png ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/links-text-home.png ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/links-legend.png ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/links-header.png ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/links-select-background.png ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/links-text-cover.png ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/links-text-select.png ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/online-open-circle.png ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/projects-background.png ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/projects-pointer.png ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/projects-boardroom.png ) | |
2three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/projects-globe.png ) | |
2three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/projects-wargames.png ) | |
2three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( images/projects-rotate.png ) | |
three.js:34 THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( ) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment