i.far?null:{distance:x,point:gf.clone(),object:e}}function yf(e,t,i,l,c,h,f,r,v,x,w,b){tl.fromBufferAttribute(c,x),nl.fromBufferAttribute(c,w),il.fromBufferAttribute(c,b);var A=e.morphTargetInfluences;if(t.morphTargets&&h&&A){pf.set(0,0,0),ff.set(0,0,0),mf.set(0,0,0);for(var L=0,P=h.length;L0)for(var x=0;x0&&(this.normalsNeedUpdate=!0)},computeFlatVertexNormals:function(){var e,t,i;for(this.computeFaceNormals(),e=0,t=this.faces.length;e0&&(this.normalsNeedUpdate=!0)},computeMorphNormals:function(){var e,t,i,l,c;for(i=0,l=this.faces.length;i=0;r--){var R=L[r];for(this.faces.splice(R,1),b=0,A=this.faceVertexUvs.length;b0,j=L.vertexNormals.length>0,J=L.color.r!==1||L.color.g!==1||L.color.b!==1,ne=L.vertexColors.length>0,H=0;if(H=le(H,0,0),H=le(H,1,P),H=le(H,2,R),H=le(H,3,F),H=le(H,4,V),H=le(H,5,j),H=le(H,6,J),H=le(H,7,ne),f.push(H),f.push(L.a,L.b,L.c),f.push(L.materialIndex),F){var Q=this.faceVertexUvs[0][c];f.push(he(Q[0]),he(Q[1]),he(Q[2]))}if(V&&f.push(fe(L.normal)),j){var ae=L.vertexNormals;f.push(fe(ae[0]),fe(ae[1]),fe(ae[2]))}if(J&&f.push(me(L.color)),ne){var ie=L.vertexColors;f.push(me(ie[0]),me(ie[1]),me(ie[2]))}}function le(Oe,Ve,He){return He?Oe|1<0&&(e.data.colors=x),b.length>0&&(e.data.uvs=[b]),e.data.faces=f,e},clone:function(){return new Bn().copy(this)},copy:function(e){var t,i,l,c,h,f;this.vertices=[],this.colors=[],this.faces=[],this.faceVertexUvs=[[]],this.morphTargets=[],this.morphNormals=[],this.skinWeights=[],this.skinIndices=[],this.lineDistances=[],this.boundingBox=null,this.boundingSphere=null,this.name=e.name;var r=e.vertices;for(t=0,i=r.length;t0?1:-1,w.push(Nt.x,Nt.y,Nt.z),b.push(Dt/ae),b.push(1-It/ie),At+=1}}for(It=0;It0&&(t.defines=this.defines),t.vertexShader=this.vertexShader,t.fragmentShader=this.fragmentShader;var h={};for(var f in this.extensions)this.extensions[f]===!0&&(h[f]=!0);return Object.keys(h).length>0&&(t.extensions=h),t};function Ia(){on.call(this),this.type="Camera",this.matrixWorldInverse=new Hn,this.projectionMatrix=new Hn,this.projectionMatrixInverse=new Hn}Ia.prototype=Object.assign(Object.create(on.prototype),{constructor:Ia,isCamera:!0,copy:function(e,t){return on.prototype.copy.call(this,e,t),this.matrixWorldInverse.copy(e.matrixWorldInverse),this.projectionMatrix.copy(e.projectionMatrix),this.projectionMatrixInverse.copy(e.projectionMatrixInverse),this},getWorldDirection:function(e){e===void 0&&(console.warn("THREE.Camera: .getWorldDirection() target is now required"),e=new Pe),this.updateMatrixWorld(!0);var t=this.matrixWorld.elements;return e.set(-t[8],-t[9],-t[10]).normalize()},updateMatrixWorld:function(e){on.prototype.updateMatrixWorld.call(this,e),this.matrixWorldInverse.getInverse(this.matrixWorld)},updateWorldMatrix:function(e,t){on.prototype.updateWorldMatrix.call(this,e,t),this.matrixWorldInverse.getInverse(this.matrixWorld)},clone:function(){return new this.constructor().copy(this)}});function Xi(e,t,i,l){Ia.call(this),this.type="PerspectiveCamera",this.fov=e!==void 0?e:50,this.zoom=1,this.near=i!==void 0?i:.1,this.far=l!==void 0?l:2e3,this.focus=10,this.aspect=t!==void 0?t:1,this.view=null,this.filmGauge=35,this.filmOffset=0,this.updateProjectionMatrix()}Xi.prototype=Object.assign(Object.create(Ia.prototype),{constructor:Xi,isPerspectiveCamera:!0,copy:function(e,t){return Ia.prototype.copy.call(this,e,t),this.fov=e.fov,this.zoom=e.zoom,this.near=e.near,this.far=e.far,this.focus=e.focus,this.aspect=e.aspect,this.view=e.view===null?null:Object.assign({},e.view),this.filmGauge=e.filmGauge,this.filmOffset=e.filmOffset,this},setFocalLength:function(e){var t=.5*this.getFilmHeight()/e;this.fov=jn.RAD2DEG*2*Math.atan(t),this.updateProjectionMatrix()},getFocalLength:function(){var e=Math.tan(jn.DEG2RAD*.5*this.fov);return .5*this.getFilmHeight()/e},getEffectiveFOV:function(){return jn.RAD2DEG*2*Math.atan(Math.tan(jn.DEG2RAD*.5*this.fov)/this.zoom)},getFilmWidth:function(){return this.filmGauge*Math.min(this.aspect,1)},getFilmHeight:function(){return this.filmGauge/Math.max(this.aspect,1)},setViewOffset:function(e,t,i,l,c,h){this.aspect=e/t,this.view===null&&(this.view={enabled:!0,fullWidth:1,fullHeight:1,offsetX:0,offsetY:0,width:1,height:1}),this.view.enabled=!0,this.view.fullWidth=e,this.view.fullHeight=t,this.view.offsetX=i,this.view.offsetY=l,this.view.width=c,this.view.height=h,this.updateProjectionMatrix()},clearViewOffset:function(){this.view!==null&&(this.view.enabled=!1),this.updateProjectionMatrix()},updateProjectionMatrix:function(){var e=this.near,t=e*Math.tan(jn.DEG2RAD*.5*this.fov)/this.zoom,i=2*t,l=this.aspect*i,c=-.5*l,h=this.view;if(this.view!==null&&this.view.enabled){var f=h.fullWidth,r=h.fullHeight;c+=h.offsetX*l/f,t-=h.offsetY*i/r,l*=h.width/f,i*=h.height/r}var v=this.filmOffset;v!==0&&(c+=e*v/this.getFilmWidth()),this.projectionMatrix.makePerspective(c,c+l,t,t-i,e,this.far),this.projectionMatrixInverse.getInverse(this.projectionMatrix)},toJSON:function(e){var t=on.prototype.toJSON.call(this,e);return t.object.fov=this.fov,t.object.zoom=this.zoom,t.object.near=this.near,t.object.far=this.far,t.object.focus=this.focus,t.object.aspect=this.aspect,this.view!==null&&(t.object.view=Object.assign({},this.view)),t.object.filmGauge=this.filmGauge,t.object.filmOffset=this.filmOffset,t}});var Ec=90,Cc=1;function Dh(e,t,i,l){on.call(this),this.type="CubeCamera";var c=new Xi(Ec,Cc,e,t);c.up.set(0,-1,0),c.lookAt(new Pe(1,0,0)),this.add(c);var h=new Xi(Ec,Cc,e,t);h.up.set(0,-1,0),h.lookAt(new Pe(-1,0,0)),this.add(h);var f=new Xi(Ec,Cc,e,t);f.up.set(0,0,1),f.lookAt(new Pe(0,1,0)),this.add(f);var r=new Xi(Ec,Cc,e,t);r.up.set(0,0,-1),r.lookAt(new Pe(0,-1,0)),this.add(r);var v=new Xi(Ec,Cc,e,t);v.up.set(0,-1,0),v.lookAt(new Pe(0,0,1)),this.add(v);var x=new Xi(Ec,Cc,e,t);x.up.set(0,-1,0),x.lookAt(new Pe(0,0,-1)),this.add(x),l=l||{format:Ma,magFilter:$i,minFilter:$i},this.renderTarget=new Ac(i,l),this.renderTarget.texture.name="CubeCamera",this.update=function(w,b){this.parent===null&&this.updateMatrixWorld();var A=w.getRenderTarget(),L=this.renderTarget,P=L.texture.generateMipmaps;L.texture.generateMipmaps=!1,w.setRenderTarget(L,0),w.render(b,c),w.setRenderTarget(L,1),w.render(b,h),w.setRenderTarget(L,2),w.render(b,f),w.setRenderTarget(L,3),w.render(b,r),w.setRenderTarget(L,4),w.render(b,v),L.texture.generateMipmaps=P,w.setRenderTarget(L,5),w.render(b,x),w.setRenderTarget(A)},this.clear=function(w,b,A,L){for(var P=w.getRenderTarget(),R=this.renderTarget,F=0;F<6;F++)w.setRenderTarget(R,F),w.clear(b,A,L);w.setRenderTarget(P)}}Dh.prototype=Object.create(on.prototype),Dh.prototype.constructor=Dh;function Ac(e,t,i){Number.isInteger(t)&&(console.warn("THREE.WebGLCubeRenderTarget: constructor signature is now WebGLCubeRenderTarget( size, options )"),t=i),Tr.call(this,e,e,t)}Ac.prototype=Object.create(Tr.prototype),Ac.prototype.constructor=Ac,Ac.prototype.isWebGLCubeRenderTarget=!0,Ac.prototype.fromEquirectangularTexture=function(e,t){this.texture.type=t.type,this.texture.format=t.format,this.texture.encoding=t.encoding;var i=new Ca,l={uniforms:{tEquirect:{value:null}},vertexShader:["varying vec3 vWorldDirection;","vec3 transformDirection( in vec3 dir, in mat4 matrix ) {"," return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );","}","void main() {"," vWorldDirection = transformDirection( position, modelMatrix );"," #include "," #include ","}"].join(`
`),fragmentShader:["uniform sampler2D tEquirect;","varying vec3 vWorldDirection;","#define RECIPROCAL_PI 0.31830988618","#define RECIPROCAL_PI2 0.15915494","void main() {"," vec3 direction = normalize( vWorldDirection );"," vec2 sampleUV;"," sampleUV.y = asin( clamp( direction.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;"," sampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;"," gl_FragColor = texture2D( tEquirect, sampleUV );","}"].join(`
`)},c=new Ur({type:"CubemapFromEquirect",uniforms:Tc(l.uniforms),vertexShader:l.vertexShader,fragmentShader:l.fragmentShader,side:tr,blending:es});c.uniforms.tEquirect.value=t;var h=new Ai(new vf(5,5,5),c);i.add(h);var f=new Dh(1,10,1);return f.renderTarget=this,f.renderTarget.texture.name="CubeCameraTexture",f.update(e,i),h.geometry.dispose(),h.material.dispose(),this};function Dc(e,t,i,l,c,h,f,r,v,x,w,b){mi.call(this,null,h,f,r,v,x,l,c,w,b),this.image={data:e||null,width:t||1,height:i||1},this.magFilter=v!==void 0?v:Ui,this.minFilter=x!==void 0?x:Ui,this.generateMipmaps=!1,this.flipY=!1,this.unpackAlignment=1,this.needsUpdate=!0}Dc.prototype=Object.create(mi.prototype),Dc.prototype.constructor=Dc,Dc.prototype.isDataTexture=!0;var Pc=new Da,xf=new Pe;function Ph(e,t,i,l,c,h){this.planes=[e!==void 0?e:new $o,t!==void 0?t:new $o,i!==void 0?i:new $o,l!==void 0?l:new $o,c!==void 0?c:new $o,h!==void 0?h:new $o]}Object.assign(Ph.prototype,{set:function(e,t,i,l,c,h){var f=this.planes;return f[0].copy(e),f[1].copy(t),f[2].copy(i),f[3].copy(l),f[4].copy(c),f[5].copy(h),this},clone:function(){return new this.constructor().copy(this)},copy:function(e){for(var t=this.planes,i=0;i<6;i++)t[i].copy(e.planes[i]);return this},setFromProjectionMatrix:function(e){var t=this.planes,i=e.elements,l=i[0],c=i[1],h=i[2],f=i[3],r=i[4],v=i[5],x=i[6],w=i[7],b=i[8],A=i[9],L=i[10],P=i[11],R=i[12],F=i[13],V=i[14],j=i[15];return t[0].setComponents(f-l,w-r,P-b,j-R).normalize(),t[1].setComponents(f+l,w+r,P+b,j+R).normalize(),t[2].setComponents(f+c,w+v,P+A,j+F).normalize(),t[3].setComponents(f-c,w-v,P-A,j-F).normalize(),t[4].setComponents(f-h,w-x,P-L,j-V).normalize(),t[5].setComponents(f+h,w+x,P+L,j+V).normalize(),this},intersectsObject:function(e){var t=e.geometry;return t.boundingSphere===null&&t.computeBoundingSphere(),Pc.copy(t.boundingSphere).applyMatrix4(e.matrixWorld),this.intersectsSphere(Pc)},intersectsSprite:function(e){return Pc.center.set(0,0,0),Pc.radius=.7071067811865476,Pc.applyMatrix4(e.matrixWorld),this.intersectsSphere(Pc)},intersectsSphere:function(e){for(var t=this.planes,i=e.center,l=-e.radius,c=0;c<6;c++){var h=t[c].distanceToPoint(i);if(h0?e.max.x:e.min.x,xf.y=l.normal.y>0?e.max.y:e.min.y,xf.z=l.normal.z>0?e.max.z:e.min.z,l.distanceToPoint(xf)<0)return!1}return!0},containsPoint:function(e){for(var t=this.planes,i=0;i<6;i++)if(t[i].distanceToPoint(e)<0)return!1;return!0}});var an={common:{diffuse:{value:new tn(15658734)},opacity:{value:1},map:{value:null},uvTransform:{value:new pr},uv2Transform:{value:new pr},alphaMap:{value:null}},specularmap:{specularMap:{value:null}},envmap:{envMap:{value:null},flipEnvMap:{value:-1},reflectivity:{value:1},refractionRatio:{value:.98},maxMipLevel:{value:0}},aomap:{aoMap:{value:null},aoMapIntensity:{value:1}},lightmap:{lightMap:{value:null},lightMapIntensity:{value:1}},emissivemap:{emissiveMap:{value:null}},bumpmap:{bumpMap:{value:null},bumpScale:{value:1}},normalmap:{normalMap:{value:null},normalScale:{value:new Lt(1,1)}},displacementmap:{displacementMap:{value:null},displacementScale:{value:1},displacementBias:{value:0}},roughnessmap:{roughnessMap:{value:null}},metalnessmap:{metalnessMap:{value:null}},gradientmap:{gradientMap:{value:null}},fog:{fogDensity:{value:25e-5},fogNear:{value:1},fogFar:{value:2e3},fogColor:{value:new tn(16777215)}},lights:{ambientLightColor:{value:[]},lightProbe:{value:[]},directionalLights:{value:[],properties:{direction:{},color:{},shadow:{},shadowBias:{},shadowRadius:{},shadowMapSize:{}}},directionalShadowMap:{value:[]},directionalShadowMatrix:{value:[]},spotLights:{value:[],properties:{color:{},position:{},direction:{},distance:{},coneCos:{},penumbraCos:{},decay:{},shadow:{},shadowBias:{},shadowRadius:{},shadowMapSize:{}}},spotShadowMap:{value:[]},spotShadowMatrix:{value:[]},pointLights:{value:[],properties:{color:{},position:{},decay:{},distance:{},shadow:{},shadowBias:{},shadowRadius:{},shadowMapSize:{},shadowCameraNear:{},shadowCameraFar:{}}},pointShadowMap:{value:[]},pointShadowMatrix:{value:[]},hemisphereLights:{value:[],properties:{direction:{},skyColor:{},groundColor:{}}},rectAreaLights:{value:[],properties:{color:{},position:{},width:{},height:{}}}},points:{diffuse:{value:new tn(15658734)},opacity:{value:1},size:{value:1},scale:{value:1},map:{value:null},alphaMap:{value:null},uvTransform:{value:new pr}},sprite:{diffuse:{value:new tn(15658734)},opacity:{value:1},center:{value:new Lt(.5,.5)},rotation:{value:0},map:{value:null},alphaMap:{value:null},uvTransform:{value:new pr}}};function o0(){var e=null,t=!1,i=null;function l(c,h){t!==!1&&(i(c,h),e.requestAnimationFrame(l))}return{start:function(){t!==!0&&i!==null&&(e.requestAnimationFrame(l),t=!0)},stop:function(){t=!1},setAnimationLoop:function(c){i=c},setContext:function(c){e=c}}}function QE(e,t){var i=t.isWebGL2,l=new WeakMap;function c(x,w){var b=x.array,A=x.usage,L=e.createBuffer();e.bindBuffer(w,L),e.bufferData(w,b,A),x.onUploadCallback();var P=5126;return b instanceof Float32Array?P=5126:b instanceof Float64Array?console.warn("THREE.WebGLAttributes: Unsupported data buffer format: Float64Array."):b instanceof Uint16Array?P=5123:b instanceof Int16Array?P=5122:b instanceof Uint32Array?P=5125:b instanceof Int32Array?P=5124:b instanceof Int8Array?P=5120:b instanceof Uint8Array&&(P=5121),{buffer:L,type:P,bytesPerElement:b.BYTES_PER_ELEMENT,version:x.version}}function h(x,w,b){var A=w.array,L=w.updateRange;e.bindBuffer(b,x),L.count===-1?e.bufferSubData(b,0,A):(i?e.bufferSubData(b,L.offset*A.BYTES_PER_ELEMENT,A,L.offset,L.count):e.bufferSubData(b,L.offset*A.BYTES_PER_ELEMENT,A.subarray(L.offset,L.offset+L.count)),L.count=-1)}function f(x){return x.isInterleavedBufferAttribute&&(x=x.data),l.get(x)}function r(x){x.isInterleavedBufferAttribute&&(x=x.data);var w=l.get(x);w&&(e.deleteBuffer(w.buffer),l.delete(x))}function v(x,w){x.isInterleavedBufferAttribute&&(x=x.data);var b=l.get(x);b===void 0?l.set(x,c(x,w)):b.version 0.0 ) {
distanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );
}
return distanceFalloff;
#else
if( cutoffDistance > 0.0 && decayExponent > 0.0 ) {
return pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );
}
return 1.0;
#endif
}
vec3 BRDF_Diffuse_Lambert( const in vec3 diffuseColor ) {
return RECIPROCAL_PI * diffuseColor;
}
vec3 F_Schlick( const in vec3 specularColor, const in float dotLH ) {
float fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );
return ( 1.0 - specularColor ) * fresnel + specularColor;
}
vec3 F_Schlick_RoughnessDependent( const in vec3 F0, const in float dotNV, const in float roughness ) {
float fresnel = exp2( ( -5.55473 * dotNV - 6.98316 ) * dotNV );
vec3 Fr = max( vec3( 1.0 - roughness ), F0 ) - F0;
return Fr * fresnel + F0;
}
float G_GGX_Smith( const in float alpha, const in float dotNL, const in float dotNV ) {
float a2 = pow2( alpha );
float gl = dotNL + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );
float gv = dotNV + sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );
return 1.0 / ( gl * gv );
}
float G_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {
float a2 = pow2( alpha );
float gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );
float gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );
return 0.5 / max( gv + gl, EPSILON );
}
float D_GGX( const in float alpha, const in float dotNH ) {
float a2 = pow2( alpha );
float denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;
return RECIPROCAL_PI * a2 / pow2( denom );
}
vec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) {
float alpha = pow2( roughness );
vec3 halfDir = normalize( incidentLight.direction + viewDir );
float dotNL = saturate( dot( normal, incidentLight.direction ) );
float dotNV = saturate( dot( normal, viewDir ) );
float dotNH = saturate( dot( normal, halfDir ) );
float dotLH = saturate( dot( incidentLight.direction, halfDir ) );
vec3 F = F_Schlick( specularColor, dotLH );
float G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );
float D = D_GGX( alpha, dotNH );
return F * ( G * D );
}
vec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {
const float LUT_SIZE = 64.0;
const float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;
const float LUT_BIAS = 0.5 / LUT_SIZE;
float dotNV = saturate( dot( N, V ) );
vec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );
uv = uv * LUT_SCALE + LUT_BIAS;
return uv;
}
float LTC_ClippedSphereFormFactor( const in vec3 f ) {
float l = length( f );
return max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );
}
vec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {
float x = dot( v1, v2 );
float y = abs( x );
float a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;
float b = 3.4175940 + ( 4.1616724 + y ) * y;
float v = a / b;
float theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;
return cross( v1, v2 ) * theta_sintheta;
}
vec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {
vec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];
vec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];
vec3 lightNormal = cross( v1, v2 );
if( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );
vec3 T1, T2;
T1 = normalize( V - N * dot( V, N ) );
T2 = - cross( N, T1 );
mat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );
vec3 coords[ 4 ];
coords[ 0 ] = mat * ( rectCoords[ 0 ] - P );
coords[ 1 ] = mat * ( rectCoords[ 1 ] - P );
coords[ 2 ] = mat * ( rectCoords[ 2 ] - P );
coords[ 3 ] = mat * ( rectCoords[ 3 ] - P );
coords[ 0 ] = normalize( coords[ 0 ] );
coords[ 1 ] = normalize( coords[ 1 ] );
coords[ 2 ] = normalize( coords[ 2 ] );
coords[ 3 ] = normalize( coords[ 3 ] );
vec3 vectorFormFactor = vec3( 0.0 );
vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );
vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );
vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );
vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );
float result = LTC_ClippedSphereFormFactor( vectorFormFactor );
return vec3( result );
}
vec3 BRDF_Specular_GGX_Environment( const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float roughness ) {
float dotNV = saturate( dot( normal, viewDir ) );
vec2 brdf = integrateSpecularBRDF( dotNV, roughness );
return specularColor * brdf.x + brdf.y;
}
void BRDF_Specular_Multiscattering_Environment( const in GeometricContext geometry, const in vec3 specularColor, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {
float dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );
vec3 F = F_Schlick_RoughnessDependent( specularColor, dotNV, roughness );
vec2 brdf = integrateSpecularBRDF( dotNV, roughness );
vec3 FssEss = F * brdf.x + brdf.y;
float Ess = brdf.x + brdf.y;
float Ems = 1.0 - Ess;
vec3 Favg = specularColor + ( 1.0 - specularColor ) * 0.047619; vec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );
singleScatter += FssEss;
multiScatter += Fms * Ems;
}
float G_BlinnPhong_Implicit( ) {
return 0.25;
}
float D_BlinnPhong( const in float shininess, const in float dotNH ) {
return RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );
}
vec3 BRDF_Specular_BlinnPhong( const in IncidentLight incidentLight, const in GeometricContext geometry, const in vec3 specularColor, const in float shininess ) {
vec3 halfDir = normalize( incidentLight.direction + geometry.viewDir );
float dotNH = saturate( dot( geometry.normal, halfDir ) );
float dotLH = saturate( dot( incidentLight.direction, halfDir ) );
vec3 F = F_Schlick( specularColor, dotLH );
float G = G_BlinnPhong_Implicit( );
float D = D_BlinnPhong( shininess, dotNH );
return F * ( G * D );
}
float GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {
return ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );
}
float BlinnExponentToGGXRoughness( const in float blinnExponent ) {
return sqrt( 2.0 / ( blinnExponent + 2.0 ) );
}
#if defined( USE_SHEEN )
float D_Charlie(float roughness, float NoH) {
float invAlpha = 1.0 / roughness;
float cos2h = NoH * NoH;
float sin2h = max(1.0 - cos2h, 0.0078125); return (2.0 + invAlpha) * pow(sin2h, invAlpha * 0.5) / (2.0 * PI);
}
float V_Neubelt(float NoV, float NoL) {
return saturate(1.0 / (4.0 * (NoL + NoV - NoL * NoV)));
}
vec3 BRDF_Specular_Sheen( const in float roughness, const in vec3 L, const in GeometricContext geometry, vec3 specularColor ) {
vec3 N = geometry.normal;
vec3 V = geometry.viewDir;
vec3 H = normalize( V + L );
float dotNH = saturate( dot( N, H ) );
return specularColor * D_Charlie( roughness, dotNH ) * V_Neubelt( dot(N, V), dot(N, L) );
}
#endif`,lC=`#ifdef USE_BUMPMAP
uniform sampler2D bumpMap;
uniform float bumpScale;
vec2 dHdxy_fwd() {
vec2 dSTdx = dFdx( vUv );
vec2 dSTdy = dFdy( vUv );
float Hll = bumpScale * texture2D( bumpMap, vUv ).x;
float dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;
float dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;
return vec2( dBx, dBy );
}
vec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy ) {
vec3 vSigmaX = vec3( dFdx( surf_pos.x ), dFdx( surf_pos.y ), dFdx( surf_pos.z ) );
vec3 vSigmaY = vec3( dFdy( surf_pos.x ), dFdy( surf_pos.y ), dFdy( surf_pos.z ) );
vec3 vN = surf_norm;
vec3 R1 = cross( vSigmaY, vN );
vec3 R2 = cross( vN, vSigmaX );
float fDet = dot( vSigmaX, R1 );
fDet *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );
vec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );
return normalize( abs( fDet ) * surf_norm - vGrad );
}
#endif`,cC=`#if NUM_CLIPPING_PLANES > 0
vec4 plane;
#pragma unroll_loop
for ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {
plane = clippingPlanes[ i ];
if ( dot( vViewPosition, plane.xyz ) > plane.w ) discard;
}
#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES
bool clipped = true;
#pragma unroll_loop
for ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {
plane = clippingPlanes[ i ];
clipped = ( dot( vViewPosition, plane.xyz ) > plane.w ) && clipped;
}
if ( clipped ) discard;
#endif
#endif`,uC=`#if NUM_CLIPPING_PLANES > 0
#if ! defined( STANDARD ) && ! defined( PHONG ) && ! defined( MATCAP )
varying vec3 vViewPosition;
#endif
uniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];
#endif`,hC=`#if NUM_CLIPPING_PLANES > 0 && ! defined( STANDARD ) && ! defined( PHONG ) && ! defined( MATCAP )
varying vec3 vViewPosition;
#endif`,dC=`#if NUM_CLIPPING_PLANES > 0 && ! defined( STANDARD ) && ! defined( PHONG ) && ! defined( MATCAP )
vViewPosition = - mvPosition.xyz;
#endif`,pC=`#ifdef USE_COLOR
diffuseColor.rgb *= vColor;
#endif`,fC=`#ifdef USE_COLOR
varying vec3 vColor;
#endif`,mC=`#ifdef USE_COLOR
varying vec3 vColor;
#endif`,gC=`#ifdef USE_COLOR
vColor.xyz = color.xyz;
#endif`,yC=`#define PI 3.14159265359
#define PI2 6.28318530718
#define PI_HALF 1.5707963267949
#define RECIPROCAL_PI 0.31830988618
#define RECIPROCAL_PI2 0.15915494
#define LOG2 1.442695
#define EPSILON 1e-6
#ifndef saturate
#define saturate(a) clamp( a, 0.0, 1.0 )
#endif
#define whiteComplement(a) ( 1.0 - saturate( a ) )
float pow2( const in float x ) { return x*x; }
float pow3( const in float x ) { return x*x*x; }
float pow4( const in float x ) { float x2 = x*x; return x2*x2; }
float average( const in vec3 color ) { return dot( color, vec3( 0.3333 ) ); }
highp float rand( const in vec2 uv ) {
const highp float a = 12.9898, b = 78.233, c = 43758.5453;
highp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );
return fract(sin(sn) * c);
}
#ifdef HIGH_PRECISION
float precisionSafeLength( vec3 v ) { return length( v ); }
#else
float max3( vec3 v ) { return max( max( v.x, v.y ), v.z ); }
float precisionSafeLength( vec3 v ) {
float maxComponent = max3( abs( v ) );
return length( v / maxComponent ) * maxComponent;
}
#endif
struct IncidentLight {
vec3 color;
vec3 direction;
bool visible;
};
struct ReflectedLight {
vec3 directDiffuse;
vec3 directSpecular;
vec3 indirectDiffuse;
vec3 indirectSpecular;
};
struct GeometricContext {
vec3 position;
vec3 normal;
vec3 viewDir;
#ifdef CLEARCOAT
vec3 clearcoatNormal;
#endif
};
vec3 transformDirection( in vec3 dir, in mat4 matrix ) {
return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );
}
vec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {
return normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );
}
vec3 projectOnPlane(in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {
float distance = dot( planeNormal, point - pointOnPlane );
return - distance * planeNormal + point;
}
float sideOfPlane( in vec3 point, in vec3 pointOnPlane, in vec3 planeNormal ) {
return sign( dot( point - pointOnPlane, planeNormal ) );
}
vec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 pointOnPlane, in vec3 planeNormal ) {
return lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;
}
mat3 transposeMat3( const in mat3 m ) {
mat3 tmp;
tmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );
tmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );
tmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );
return tmp;
}
float linearToRelativeLuminance( const in vec3 color ) {
vec3 weights = vec3( 0.2126, 0.7152, 0.0722 );
return dot( weights, color.rgb );
}
bool isPerspectiveMatrix( mat4 m ) {
return m[ 2 ][ 3 ] == - 1.0;
}`,_C=`#ifdef ENVMAP_TYPE_CUBE_UV
#define cubeUV_maxMipLevel 8.0
#define cubeUV_minMipLevel 4.0
#define cubeUV_maxTileSize 256.0
#define cubeUV_minTileSize 16.0
float getFace(vec3 direction) {
vec3 absDirection = abs(direction);
float face = -1.0;
if (absDirection.x > absDirection.z) {
if (absDirection.x > absDirection.y)
face = direction.x > 0.0 ? 0.0 : 3.0;
else
face = direction.y > 0.0 ? 1.0 : 4.0;
} else {
if (absDirection.z > absDirection.y)
face = direction.z > 0.0 ? 2.0 : 5.0;
else
face = direction.y > 0.0 ? 1.0 : 4.0;
}
return face;
}
vec2 getUV(vec3 direction, float face) {
vec2 uv;
if (face == 0.0) {
uv = vec2(-direction.z, direction.y) / abs(direction.x);
} else if (face == 1.0) {
uv = vec2(direction.x, -direction.z) / abs(direction.y);
} else if (face == 2.0) {
uv = direction.xy / abs(direction.z);
} else if (face == 3.0) {
uv = vec2(direction.z, direction.y) / abs(direction.x);
} else if (face == 4.0) {
uv = direction.xz / abs(direction.y);
} else {
uv = vec2(-direction.x, direction.y) / abs(direction.z);
}
return 0.5 * (uv + 1.0);
}
vec3 bilinearCubeUV(sampler2D envMap, vec3 direction, float mipInt) {
float face = getFace(direction);
float filterInt = max(cubeUV_minMipLevel - mipInt, 0.0);
mipInt = max(mipInt, cubeUV_minMipLevel);
float faceSize = exp2(mipInt);
float texelSize = 1.0 / (3.0 * cubeUV_maxTileSize);
vec2 uv = getUV(direction, face) * (faceSize - 1.0);
vec2 f = fract(uv);
uv += 0.5 - f;
if (face > 2.0) {
uv.y += faceSize;
face -= 3.0;
}
uv.x += face * faceSize;
if(mipInt < cubeUV_maxMipLevel){
uv.y += 2.0 * cubeUV_maxTileSize;
}
uv.y += filterInt * 2.0 * cubeUV_minTileSize;
uv.x += 3.0 * max(0.0, cubeUV_maxTileSize - 2.0 * faceSize);
uv *= texelSize;
vec3 tl = envMapTexelToLinear(texture2D(envMap, uv)).rgb;
uv.x += texelSize;
vec3 tr = envMapTexelToLinear(texture2D(envMap, uv)).rgb;
uv.y += texelSize;
vec3 br = envMapTexelToLinear(texture2D(envMap, uv)).rgb;
uv.x -= texelSize;
vec3 bl = envMapTexelToLinear(texture2D(envMap, uv)).rgb;
vec3 tm = mix(tl, tr, f.x);
vec3 bm = mix(bl, br, f.x);
return mix(tm, bm, f.y);
}
#define r0 1.0
#define v0 0.339
#define m0 -2.0
#define r1 0.8
#define v1 0.276
#define m1 -1.0
#define r4 0.4
#define v4 0.046
#define m4 2.0
#define r5 0.305
#define v5 0.016
#define m5 3.0
#define r6 0.21
#define v6 0.0038
#define m6 4.0
float roughnessToMip(float roughness) {
float mip = 0.0;
if (roughness >= r1) {
mip = (r0 - roughness) * (m1 - m0) / (r0 - r1) + m0;
} else if (roughness >= r4) {
mip = (r1 - roughness) * (m4 - m1) / (r1 - r4) + m1;
} else if (roughness >= r5) {
mip = (r4 - roughness) * (m5 - m4) / (r4 - r5) + m4;
} else if (roughness >= r6) {
mip = (r5 - roughness) * (m6 - m5) / (r5 - r6) + m5;
} else {
mip = -2.0 * log2(1.16 * roughness); }
return mip;
}
vec4 textureCubeUV(sampler2D envMap, vec3 sampleDir, float roughness) {
float mip = clamp(roughnessToMip(roughness), m0, cubeUV_maxMipLevel);
float mipF = fract(mip);
float mipInt = floor(mip);
vec3 color0 = bilinearCubeUV(envMap, sampleDir, mipInt);
if (mipF == 0.0) {
return vec4(color0, 1.0);
} else {
vec3 color1 = bilinearCubeUV(envMap, sampleDir, mipInt + 1.0);
return vec4(mix(color0, color1, mipF), 1.0);
}
}
#endif`,vC=`vec3 transformedNormal = objectNormal;
#ifdef USE_INSTANCING
transformedNormal = mat3( instanceMatrix ) * transformedNormal;
#endif
transformedNormal = normalMatrix * transformedNormal;
#ifdef FLIP_SIDED
transformedNormal = - transformedNormal;
#endif
#ifdef USE_TANGENT
vec3 transformedTangent = ( modelViewMatrix * vec4( objectTangent, 0.0 ) ).xyz;
#ifdef FLIP_SIDED
transformedTangent = - transformedTangent;
#endif
#endif`,xC=`#ifdef USE_DISPLACEMENTMAP
uniform sampler2D displacementMap;
uniform float displacementScale;
uniform float displacementBias;
#endif`,bC=`#ifdef USE_DISPLACEMENTMAP
transformed += normalize( objectNormal ) * ( texture2D( displacementMap, vUv ).x * displacementScale + displacementBias );
#endif`,wC=`#ifdef USE_EMISSIVEMAP
vec4 emissiveColor = texture2D( emissiveMap, vUv );
emissiveColor.rgb = emissiveMapTexelToLinear( emissiveColor ).rgb;
totalEmissiveRadiance *= emissiveColor.rgb;
#endif`,MC=`#ifdef USE_EMISSIVEMAP
uniform sampler2D emissiveMap;
#endif`,TC="gl_FragColor = linearToOutputTexel( gl_FragColor );",EC=`
vec4 LinearToLinear( in vec4 value ) {
return value;
}
vec4 GammaToLinear( in vec4 value, in float gammaFactor ) {
return vec4( pow( value.rgb, vec3( gammaFactor ) ), value.a );
}
vec4 LinearToGamma( in vec4 value, in float gammaFactor ) {
return vec4( pow( value.rgb, vec3( 1.0 / gammaFactor ) ), value.a );
}
vec4 sRGBToLinear( in vec4 value ) {
return vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.a );
}
vec4 LinearTosRGB( in vec4 value ) {
return vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );
}
vec4 RGBEToLinear( in vec4 value ) {
return vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );
}
vec4 LinearToRGBE( in vec4 value ) {
float maxComponent = max( max( value.r, value.g ), value.b );
float fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );
return vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );
}
vec4 RGBMToLinear( in vec4 value, in float maxRange ) {
return vec4( value.rgb * value.a * maxRange, 1.0 );
}
vec4 LinearToRGBM( in vec4 value, in float maxRange ) {
float maxRGB = max( value.r, max( value.g, value.b ) );
float M = clamp( maxRGB / maxRange, 0.0, 1.0 );
M = ceil( M * 255.0 ) / 255.0;
return vec4( value.rgb / ( M * maxRange ), M );
}
vec4 RGBDToLinear( in vec4 value, in float maxRange ) {
return vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );
}
vec4 LinearToRGBD( in vec4 value, in float maxRange ) {
float maxRGB = max( value.r, max( value.g, value.b ) );
float D = max( maxRange / maxRGB, 1.0 );
D = clamp( floor( D ) / 255.0, 0.0, 1.0 );
return vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );
}
const mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );
vec4 LinearToLogLuv( in vec4 value ) {
vec3 Xp_Y_XYZp = cLogLuvM * value.rgb;
Xp_Y_XYZp = max( Xp_Y_XYZp, vec3( 1e-6, 1e-6, 1e-6 ) );
vec4 vResult;
vResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;
float Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;
vResult.w = fract( Le );
vResult.z = ( Le - ( floor( vResult.w * 255.0 ) ) / 255.0 ) / 255.0;
return vResult;
}
const mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );
vec4 LogLuvToLinear( in vec4 value ) {
float Le = value.z * 255.0 + value.w;
vec3 Xp_Y_XYZp;
Xp_Y_XYZp.y = exp2( ( Le - 127.0 ) / 2.0 );
Xp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;
Xp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;
vec3 vRGB = cLogLuvInverseM * Xp_Y_XYZp.rgb;
return vec4( max( vRGB, 0.0 ), 1.0 );
}`,CC=`#ifdef USE_ENVMAP
#ifdef ENV_WORLDPOS
vec3 cameraToFrag;
if ( isOrthographic ) {
cameraToFrag = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );
} else {
cameraToFrag = normalize( vWorldPosition - cameraPosition );
}
vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );
#ifdef ENVMAP_MODE_REFLECTION
vec3 reflectVec = reflect( cameraToFrag, worldNormal );
#else
vec3 reflectVec = refract( cameraToFrag, worldNormal, refractionRatio );
#endif
#else
vec3 reflectVec = vReflect;
#endif
#ifdef ENVMAP_TYPE_CUBE
vec4 envColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );
#elif defined( ENVMAP_TYPE_CUBE_UV )
vec4 envColor = textureCubeUV( envMap, reflectVec, 0.0 );
#elif defined( ENVMAP_TYPE_EQUIREC )
vec2 sampleUV;
reflectVec = normalize( reflectVec );
sampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;
sampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;
vec4 envColor = texture2D( envMap, sampleUV );
#elif defined( ENVMAP_TYPE_SPHERE )
reflectVec = normalize( reflectVec );
vec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0, 0.0, 1.0 ) );
vec4 envColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5 );
#else
vec4 envColor = vec4( 0.0 );
#endif
#ifndef ENVMAP_TYPE_CUBE_UV
envColor = envMapTexelToLinear( envColor );
#endif
#ifdef ENVMAP_BLENDING_MULTIPLY
outgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );
#elif defined( ENVMAP_BLENDING_MIX )
outgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );
#elif defined( ENVMAP_BLENDING_ADD )
outgoingLight += envColor.xyz * specularStrength * reflectivity;
#endif
#endif`,AC=`#ifdef USE_ENVMAP
uniform float envMapIntensity;
uniform float flipEnvMap;
uniform int maxMipLevel;
#ifdef ENVMAP_TYPE_CUBE
uniform samplerCube envMap;
#else
uniform sampler2D envMap;
#endif
#endif`,DC=`#ifdef USE_ENVMAP
uniform float reflectivity;
#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )
#define ENV_WORLDPOS
#endif
#ifdef ENV_WORLDPOS
varying vec3 vWorldPosition;
uniform float refractionRatio;
#else
varying vec3 vReflect;
#endif
#endif`,PC=`#ifdef USE_ENVMAP
#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) ||defined( PHONG )
#define ENV_WORLDPOS
#endif
#ifdef ENV_WORLDPOS
varying vec3 vWorldPosition;
#else
varying vec3 vReflect;
uniform float refractionRatio;
#endif
#endif`,SC=`#ifdef USE_ENVMAP
#ifdef ENV_WORLDPOS
vWorldPosition = worldPosition.xyz;
#else
vec3 cameraToVertex;
if ( isOrthographic ) {
cameraToVertex = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );
} else {
cameraToVertex = normalize( worldPosition.xyz - cameraPosition );
}
vec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );
#ifdef ENVMAP_MODE_REFLECTION
vReflect = reflect( cameraToVertex, worldNormal );
#else
vReflect = refract( cameraToVertex, worldNormal, refractionRatio );
#endif
#endif
#endif`,LC=`#ifdef USE_FOG
fogDepth = -mvPosition.z;
#endif`,IC=`#ifdef USE_FOG
varying float fogDepth;
#endif`,RC=`#ifdef USE_FOG
#ifdef FOG_EXP2
float fogFactor = 1.0 - exp( - fogDensity * fogDensity * fogDepth * fogDepth );
#else
float fogFactor = smoothstep( fogNear, fogFar, fogDepth );
#endif
gl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );
#endif`,kC=`#ifdef USE_FOG
uniform vec3 fogColor;
varying float fogDepth;
#ifdef FOG_EXP2
uniform float fogDensity;
#else
uniform float fogNear;
uniform float fogFar;
#endif
#endif`,zC=`#ifdef USE_GRADIENTMAP
uniform sampler2D gradientMap;
#endif
vec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {
float dotNL = dot( normal, lightDirection );
vec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );
#ifdef USE_GRADIENTMAP
return texture2D( gradientMap, coord ).rgb;
#else
return ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );
#endif
}`,FC=`#ifdef USE_LIGHTMAP
vec4 lightMapTexel= texture2D( lightMap, vUv2 );
reflectedLight.indirectDiffuse += PI * lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity;
#endif`,BC=`#ifdef USE_LIGHTMAP
uniform sampler2D lightMap;
uniform float lightMapIntensity;
#endif`,OC=`vec3 diffuse = vec3( 1.0 );
GeometricContext geometry;
geometry.position = mvPosition.xyz;
geometry.normal = normalize( transformedNormal );
geometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( -mvPosition.xyz );
GeometricContext backGeometry;
backGeometry.position = geometry.position;
backGeometry.normal = -geometry.normal;
backGeometry.viewDir = geometry.viewDir;
vLightFront = vec3( 0.0 );
vIndirectFront = vec3( 0.0 );
#ifdef DOUBLE_SIDED
vLightBack = vec3( 0.0 );
vIndirectBack = vec3( 0.0 );
#endif
IncidentLight directLight;
float dotNL;
vec3 directLightColor_Diffuse;
#if NUM_POINT_LIGHTS > 0
#pragma unroll_loop
for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {
getPointDirectLightIrradiance( pointLights[ i ], geometry, directLight );
dotNL = dot( geometry.normal, directLight.direction );
directLightColor_Diffuse = PI * directLight.color;
vLightFront += saturate( dotNL ) * directLightColor_Diffuse;
#ifdef DOUBLE_SIDED
vLightBack += saturate( -dotNL ) * directLightColor_Diffuse;
#endif
}
#endif
#if NUM_SPOT_LIGHTS > 0
#pragma unroll_loop
for ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {
getSpotDirectLightIrradiance( spotLights[ i ], geometry, directLight );
dotNL = dot( geometry.normal, directLight.direction );
directLightColor_Diffuse = PI * directLight.color;
vLightFront += saturate( dotNL ) * directLightColor_Diffuse;
#ifdef DOUBLE_SIDED
vLightBack += saturate( -dotNL ) * directLightColor_Diffuse;
#endif
}
#endif
#if NUM_DIR_LIGHTS > 0
#pragma unroll_loop
for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {
getDirectionalDirectLightIrradiance( directionalLights[ i ], geometry, directLight );
dotNL = dot( geometry.normal, directLight.direction );
directLightColor_Diffuse = PI * directLight.color;
vLightFront += saturate( dotNL ) * directLightColor_Diffuse;
#ifdef DOUBLE_SIDED
vLightBack += saturate( -dotNL ) * directLightColor_Diffuse;
#endif
}
#endif
#if NUM_HEMI_LIGHTS > 0
#pragma unroll_loop
for ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {
vIndirectFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );
#ifdef DOUBLE_SIDED
vIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry );
#endif
}
#endif`,NC=`uniform bool receiveShadow;
uniform vec3 ambientLightColor;
uniform vec3 lightProbe[ 9 ];
vec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {
float x = normal.x, y = normal.y, z = normal.z;
vec3 result = shCoefficients[ 0 ] * 0.886227;
result += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;
result += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;
result += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;
result += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;
result += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;
result += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );
result += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;
result += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );
return result;
}
vec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in GeometricContext geometry ) {
vec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );
vec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );
return irradiance;
}
vec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {
vec3 irradiance = ambientLightColor;
#ifndef PHYSICALLY_CORRECT_LIGHTS
irradiance *= PI;
#endif
return irradiance;
}
#if NUM_DIR_LIGHTS > 0
struct DirectionalLight {
vec3 direction;
vec3 color;
int shadow;
float shadowBias;
float shadowRadius;
vec2 shadowMapSize;
};
uniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];
void getDirectionalDirectLightIrradiance( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight directLight ) {
directLight.color = directionalLight.color;
directLight.direction = directionalLight.direction;
directLight.visible = true;
}
#endif
#if NUM_POINT_LIGHTS > 0
struct PointLight {
vec3 position;
vec3 color;
float distance;
float decay;
int shadow;
float shadowBias;
float shadowRadius;
vec2 shadowMapSize;
float shadowCameraNear;
float shadowCameraFar;
};
uniform PointLight pointLights[ NUM_POINT_LIGHTS ];
void getPointDirectLightIrradiance( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight directLight ) {
vec3 lVector = pointLight.position - geometry.position;
directLight.direction = normalize( lVector );
float lightDistance = length( lVector );
directLight.color = pointLight.color;
directLight.color *= punctualLightIntensityToIrradianceFactor( lightDistance, pointLight.distance, pointLight.decay );
directLight.visible = ( directLight.color != vec3( 0.0 ) );
}
#endif
#if NUM_SPOT_LIGHTS > 0
struct SpotLight {
vec3 position;
vec3 direction;
vec3 color;
float distance;
float decay;
float coneCos;
float penumbraCos;
int shadow;
float shadowBias;
float shadowRadius;
vec2 shadowMapSize;
};
uniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];
void getSpotDirectLightIrradiance( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight directLight ) {
vec3 lVector = spotLight.position - geometry.position;
directLight.direction = normalize( lVector );
float lightDistance = length( lVector );
float angleCos = dot( directLight.direction, spotLight.direction );
if ( angleCos > spotLight.coneCos ) {
float spotEffect = smoothstep( spotLight.coneCos, spotLight.penumbraCos, angleCos );
directLight.color = spotLight.color;
directLight.color *= spotEffect * punctualLightIntensityToIrradianceFactor( lightDistance, spotLight.distance, spotLight.decay );
directLight.visible = true;
} else {
directLight.color = vec3( 0.0 );
directLight.visible = false;
}
}
#endif
#if NUM_RECT_AREA_LIGHTS > 0
struct RectAreaLight {
vec3 color;
vec3 position;
vec3 halfWidth;
vec3 halfHeight;
};
uniform sampler2D ltc_1; uniform sampler2D ltc_2;
uniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];
#endif
#if NUM_HEMI_LIGHTS > 0
struct HemisphereLight {
vec3 direction;
vec3 skyColor;
vec3 groundColor;
};
uniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];
vec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in GeometricContext geometry ) {
float dotNL = dot( geometry.normal, hemiLight.direction );
float hemiDiffuseWeight = 0.5 * dotNL + 0.5;
vec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );
#ifndef PHYSICALLY_CORRECT_LIGHTS
irradiance *= PI;
#endif
return irradiance;
}
#endif`,UC=`#if defined( USE_ENVMAP )
#ifdef ENVMAP_MODE_REFRACTION
uniform float refractionRatio;
#endif
vec3 getLightProbeIndirectIrradiance( const in GeometricContext geometry, const in int maxMIPLevel ) {
vec3 worldNormal = inverseTransformDirection( geometry.normal, viewMatrix );
#ifdef ENVMAP_TYPE_CUBE
vec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );
#ifdef TEXTURE_LOD_EXT
vec4 envMapColor = textureCubeLodEXT( envMap, queryVec, float( maxMIPLevel ) );
#else
vec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );
#endif
envMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;
#elif defined( ENVMAP_TYPE_CUBE_UV )
vec4 envMapColor = textureCubeUV( envMap, worldNormal, 1.0 );
#else
vec4 envMapColor = vec4( 0.0 );
#endif
return PI * envMapColor.rgb * envMapIntensity;
}
float getSpecularMIPLevel( const in float roughness, const in int maxMIPLevel ) {
float maxMIPLevelScalar = float( maxMIPLevel );
float sigma = PI * roughness * roughness / ( 1.0 + roughness );
float desiredMIPLevel = maxMIPLevelScalar + log2( sigma );
return clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );
}
vec3 getLightProbeIndirectRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness, const in int maxMIPLevel ) {
#ifdef ENVMAP_MODE_REFLECTION
vec3 reflectVec = reflect( -viewDir, normal );
reflectVec = normalize( mix( reflectVec, normal, roughness * roughness) );
#else
vec3 reflectVec = refract( -viewDir, normal, refractionRatio );
#endif
reflectVec = inverseTransformDirection( reflectVec, viewMatrix );
float specularMIPLevel = getSpecularMIPLevel( roughness, maxMIPLevel );
#ifdef ENVMAP_TYPE_CUBE
vec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );
#ifdef TEXTURE_LOD_EXT
vec4 envMapColor = textureCubeLodEXT( envMap, queryReflectVec, specularMIPLevel );
#else
vec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );
#endif
envMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;
#elif defined( ENVMAP_TYPE_CUBE_UV )
vec4 envMapColor = textureCubeUV( envMap, reflectVec, roughness );
#elif defined( ENVMAP_TYPE_EQUIREC )
vec2 sampleUV;
sampleUV.y = asin( clamp( reflectVec.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;
sampleUV.x = atan( reflectVec.z, reflectVec.x ) * RECIPROCAL_PI2 + 0.5;
#ifdef TEXTURE_LOD_EXT
vec4 envMapColor = texture2DLodEXT( envMap, sampleUV, specularMIPLevel );
#else
vec4 envMapColor = texture2D( envMap, sampleUV, specularMIPLevel );
#endif
envMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;
#elif defined( ENVMAP_TYPE_SPHERE )
vec3 reflectView = normalize( ( viewMatrix * vec4( reflectVec, 0.0 ) ).xyz + vec3( 0.0,0.0,1.0 ) );
#ifdef TEXTURE_LOD_EXT
vec4 envMapColor = texture2DLodEXT( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );
#else
vec4 envMapColor = texture2D( envMap, reflectView.xy * 0.5 + 0.5, specularMIPLevel );
#endif
envMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;
#endif
return envMapColor.rgb * envMapIntensity;
}
#endif`,VC=`ToonMaterial material;
material.diffuseColor = diffuseColor.rgb;
material.specularColor = specular;
material.specularShininess = shininess;
material.specularStrength = specularStrength;`,GC=`varying vec3 vViewPosition;
#ifndef FLAT_SHADED
varying vec3 vNormal;
#endif
struct ToonMaterial {
vec3 diffuseColor;
vec3 specularColor;
float specularShininess;
float specularStrength;
};
void RE_Direct_Toon( const in IncidentLight directLight, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {
vec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;
#ifndef PHYSICALLY_CORRECT_LIGHTS
irradiance *= PI;
#endif
reflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );
reflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;
}
void RE_IndirectDiffuse_Toon( const in vec3 irradiance, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {
reflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );
}
#define RE_Direct RE_Direct_Toon
#define RE_IndirectDiffuse RE_IndirectDiffuse_Toon
#define Material_LightProbeLOD( material ) (0)`,WC=`BlinnPhongMaterial material;
material.diffuseColor = diffuseColor.rgb;
material.specularColor = specular;
material.specularShininess = shininess;
material.specularStrength = specularStrength;`,jC=`varying vec3 vViewPosition;
#ifndef FLAT_SHADED
varying vec3 vNormal;
#endif
struct BlinnPhongMaterial {
vec3 diffuseColor;
vec3 specularColor;
float specularShininess;
float specularStrength;
};
void RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {
float dotNL = saturate( dot( geometry.normal, directLight.direction ) );
vec3 irradiance = dotNL * directLight.color;
#ifndef PHYSICALLY_CORRECT_LIGHTS
irradiance *= PI;
#endif
reflectedLight.directDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );
reflectedLight.directSpecular += irradiance * BRDF_Specular_BlinnPhong( directLight, geometry, material.specularColor, material.specularShininess ) * material.specularStrength;
}
void RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {
reflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );
}
#define RE_Direct RE_Direct_BlinnPhong
#define RE_IndirectDiffuse RE_IndirectDiffuse_BlinnPhong
#define Material_LightProbeLOD( material ) (0)`,HC=`PhysicalMaterial material;
material.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );
vec3 dxy = max( abs( dFdx( geometryNormal ) ), abs( dFdy( geometryNormal ) ) );
float geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );
material.specularRoughness = max( roughnessFactor, 0.0525 );material.specularRoughness += geometryRoughness;
material.specularRoughness = min( material.specularRoughness, 1.0 );
#ifdef REFLECTIVITY
material.specularColor = mix( vec3( MAXIMUM_SPECULAR_COEFFICIENT * pow2( reflectivity ) ), diffuseColor.rgb, metalnessFactor );
#else
material.specularColor = mix( vec3( DEFAULT_SPECULAR_COEFFICIENT ), diffuseColor.rgb, metalnessFactor );
#endif
#ifdef CLEARCOAT
material.clearcoat = saturate( clearcoat ); material.clearcoatRoughness = max( clearcoatRoughness, 0.0525 );
material.clearcoatRoughness += geometryRoughness;
material.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 );
#endif
#ifdef USE_SHEEN
material.sheenColor = sheen;
#endif`,$C=`struct PhysicalMaterial {
vec3 diffuseColor;
float specularRoughness;
vec3 specularColor;
#ifdef CLEARCOAT
float clearcoat;
float clearcoatRoughness;
#endif
#ifdef USE_SHEEN
vec3 sheenColor;
#endif
};
#define MAXIMUM_SPECULAR_COEFFICIENT 0.16
#define DEFAULT_SPECULAR_COEFFICIENT 0.04
float clearcoatDHRApprox( const in float roughness, const in float dotNL ) {
return DEFAULT_SPECULAR_COEFFICIENT + ( 1.0 - DEFAULT_SPECULAR_COEFFICIENT ) * ( pow( 1.0 - dotNL, 5.0 ) * pow( 1.0 - roughness, 2.0 ) );
}
#if NUM_RECT_AREA_LIGHTS > 0
void RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {
vec3 normal = geometry.normal;
vec3 viewDir = geometry.viewDir;
vec3 position = geometry.position;
vec3 lightPos = rectAreaLight.position;
vec3 halfWidth = rectAreaLight.halfWidth;
vec3 halfHeight = rectAreaLight.halfHeight;
vec3 lightColor = rectAreaLight.color;
float roughness = material.specularRoughness;
vec3 rectCoords[ 4 ];
rectCoords[ 0 ] = lightPos + halfWidth - halfHeight; rectCoords[ 1 ] = lightPos - halfWidth - halfHeight;
rectCoords[ 2 ] = lightPos - halfWidth + halfHeight;
rectCoords[ 3 ] = lightPos + halfWidth + halfHeight;
vec2 uv = LTC_Uv( normal, viewDir, roughness );
vec4 t1 = texture2D( ltc_1, uv );
vec4 t2 = texture2D( ltc_2, uv );
mat3 mInv = mat3(
vec3( t1.x, 0, t1.y ),
vec3( 0, 1, 0 ),
vec3( t1.z, 0, t1.w )
);
vec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );
reflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );
reflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );
}
#endif
void RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {
float dotNL = saturate( dot( geometry.normal, directLight.direction ) );
vec3 irradiance = dotNL * directLight.color;
#ifndef PHYSICALLY_CORRECT_LIGHTS
irradiance *= PI;
#endif
#ifdef CLEARCOAT
float ccDotNL = saturate( dot( geometry.clearcoatNormal, directLight.direction ) );
vec3 ccIrradiance = ccDotNL * directLight.color;
#ifndef PHYSICALLY_CORRECT_LIGHTS
ccIrradiance *= PI;
#endif
float clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL );
reflectedLight.directSpecular += ccIrradiance * material.clearcoat * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.clearcoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearcoatRoughness );
#else
float clearcoatDHR = 0.0;
#endif
#ifdef USE_SHEEN
reflectedLight.directSpecular += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Specular_Sheen(
material.specularRoughness,
directLight.direction,
geometry,
material.sheenColor
);
#else
reflectedLight.directSpecular += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Specular_GGX( directLight, geometry.viewDir, geometry.normal, material.specularColor, material.specularRoughness);
#endif
reflectedLight.directDiffuse += ( 1.0 - clearcoatDHR ) * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );
}
void RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {
reflectedLight.indirectDiffuse += irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );
}
void RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {
#ifdef CLEARCOAT
float ccDotNV = saturate( dot( geometry.clearcoatNormal, geometry.viewDir ) );
reflectedLight.indirectSpecular += clearcoatRadiance * material.clearcoat * BRDF_Specular_GGX_Environment( geometry.viewDir, geometry.clearcoatNormal, vec3( DEFAULT_SPECULAR_COEFFICIENT ), material.clearcoatRoughness );
float ccDotNL = ccDotNV;
float clearcoatDHR = material.clearcoat * clearcoatDHRApprox( material.clearcoatRoughness, ccDotNL );
#else
float clearcoatDHR = 0.0;
#endif
float clearcoatInv = 1.0 - clearcoatDHR;
vec3 singleScattering = vec3( 0.0 );
vec3 multiScattering = vec3( 0.0 );
vec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;
BRDF_Specular_Multiscattering_Environment( geometry, material.specularColor, material.specularRoughness, singleScattering, multiScattering );
vec3 diffuse = material.diffuseColor * ( 1.0 - ( singleScattering + multiScattering ) );
reflectedLight.indirectSpecular += clearcoatInv * radiance * singleScattering;
reflectedLight.indirectSpecular += multiScattering * cosineWeightedIrradiance;
reflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance;
}
#define RE_Direct RE_Direct_Physical
#define RE_Direct_RectArea RE_Direct_RectArea_Physical
#define RE_IndirectDiffuse RE_IndirectDiffuse_Physical
#define RE_IndirectSpecular RE_IndirectSpecular_Physical
float computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {
return saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );
}`,qC=`
GeometricContext geometry;
geometry.position = - vViewPosition;
geometry.normal = normal;
geometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );
#ifdef CLEARCOAT
geometry.clearcoatNormal = clearcoatNormal;
#endif
IncidentLight directLight;
#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )
PointLight pointLight;
#pragma unroll_loop
for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {
pointLight = pointLights[ i ];
getPointDirectLightIrradiance( pointLight, geometry, directLight );
#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )
directLight.color *= all( bvec3( pointLight.shadow, directLight.visible, receiveShadow ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;
#endif
RE_Direct( directLight, geometry, material, reflectedLight );
}
#endif
#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )
SpotLight spotLight;
#pragma unroll_loop
for ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {
spotLight = spotLights[ i ];
getSpotDirectLightIrradiance( spotLight, geometry, directLight );
#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )
directLight.color *= all( bvec3( spotLight.shadow, directLight.visible, receiveShadow ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;
#endif
RE_Direct( directLight, geometry, material, reflectedLight );
}
#endif
#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )
DirectionalLight directionalLight;
#pragma unroll_loop
for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {
directionalLight = directionalLights[ i ];
getDirectionalDirectLightIrradiance( directionalLight, geometry, directLight );
#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )
directLight.color *= all( bvec3( directionalLight.shadow, directLight.visible, receiveShadow ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;
#endif
RE_Direct( directLight, geometry, material, reflectedLight );
}
#endif
#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )
RectAreaLight rectAreaLight;
#pragma unroll_loop
for ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {
rectAreaLight = rectAreaLights[ i ];
RE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );
}
#endif
#if defined( RE_IndirectDiffuse )
vec3 iblIrradiance = vec3( 0.0 );
vec3 irradiance = getAmbientLightIrradiance( ambientLightColor );
irradiance += getLightProbeIrradiance( lightProbe, geometry );
#if ( NUM_HEMI_LIGHTS > 0 )
#pragma unroll_loop
for ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {
irradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );
}
#endif
#endif
#if defined( RE_IndirectSpecular )
vec3 radiance = vec3( 0.0 );
vec3 clearcoatRadiance = vec3( 0.0 );
#endif`,XC=`#if defined( RE_IndirectDiffuse )
#ifdef USE_LIGHTMAP
vec4 lightMapTexel= texture2D( lightMap, vUv2 );
vec3 lightMapIrradiance = lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity;
#ifndef PHYSICALLY_CORRECT_LIGHTS
lightMapIrradiance *= PI;
#endif
irradiance += lightMapIrradiance;
#endif
#if defined( USE_ENVMAP ) && defined( STANDARD ) && defined( ENVMAP_TYPE_CUBE_UV )
iblIrradiance += getLightProbeIndirectIrradiance( geometry, maxMipLevel );
#endif
#endif
#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )
radiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.normal, material.specularRoughness, maxMipLevel );
#ifdef CLEARCOAT
clearcoatRadiance += getLightProbeIndirectRadiance( geometry.viewDir, geometry.clearcoatNormal, material.clearcoatRoughness, maxMipLevel );
#endif
#endif`,ZC=`#if defined( RE_IndirectDiffuse )
RE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );
#endif
#if defined( RE_IndirectSpecular )
RE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometry, material, reflectedLight );
#endif`,YC=`#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )
gl_FragDepthEXT = vIsPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;
#endif`,KC=`#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )
uniform float logDepthBufFC;
varying float vFragDepth;
varying float vIsPerspective;
#endif`,JC=`#ifdef USE_LOGDEPTHBUF
#ifdef USE_LOGDEPTHBUF_EXT
varying float vFragDepth;
varying float vIsPerspective;
#else
uniform float logDepthBufFC;
#endif
#endif`,QC=`#ifdef USE_LOGDEPTHBUF
#ifdef USE_LOGDEPTHBUF_EXT
vFragDepth = 1.0 + gl_Position.w;
vIsPerspective = float( isPerspectiveMatrix( projectionMatrix ) );
#else
if ( isPerspectiveMatrix( projectionMatrix ) ) {
gl_Position.z = log2( max( EPSILON, gl_Position.w + 1.0 ) ) * logDepthBufFC - 1.0;
gl_Position.z *= gl_Position.w;
}
#endif
#endif`,eA=`#ifdef USE_MAP
vec4 texelColor = texture2D( map, vUv );
texelColor = mapTexelToLinear( texelColor );
diffuseColor *= texelColor;
#endif`,tA=`#ifdef USE_MAP
uniform sampler2D map;
#endif`,nA=`#if defined( USE_MAP ) || defined( USE_ALPHAMAP )
vec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;
#endif
#ifdef USE_MAP
vec4 mapTexel = texture2D( map, uv );
diffuseColor *= mapTexelToLinear( mapTexel );
#endif
#ifdef USE_ALPHAMAP
diffuseColor.a *= texture2D( alphaMap, uv ).g;
#endif`,iA=`#if defined( USE_MAP ) || defined( USE_ALPHAMAP )
uniform mat3 uvTransform;
#endif
#ifdef USE_MAP
uniform sampler2D map;
#endif
#ifdef USE_ALPHAMAP
uniform sampler2D alphaMap;
#endif`,rA=`float metalnessFactor = metalness;
#ifdef USE_METALNESSMAP
vec4 texelMetalness = texture2D( metalnessMap, vUv );
metalnessFactor *= texelMetalness.b;
#endif`,oA=`#ifdef USE_METALNESSMAP
uniform sampler2D metalnessMap;
#endif`,aA=`#ifdef USE_MORPHNORMALS
objectNormal *= morphTargetBaseInfluence;
objectNormal += morphNormal0 * morphTargetInfluences[ 0 ];
objectNormal += morphNormal1 * morphTargetInfluences[ 1 ];
objectNormal += morphNormal2 * morphTargetInfluences[ 2 ];
objectNormal += morphNormal3 * morphTargetInfluences[ 3 ];
#endif`,sA=`#ifdef USE_MORPHTARGETS
uniform float morphTargetBaseInfluence;
#ifndef USE_MORPHNORMALS
uniform float morphTargetInfluences[ 8 ];
#else
uniform float morphTargetInfluences[ 4 ];
#endif
#endif`,lA=`#ifdef USE_MORPHTARGETS
transformed *= morphTargetBaseInfluence;
transformed += morphTarget0 * morphTargetInfluences[ 0 ];
transformed += morphTarget1 * morphTargetInfluences[ 1 ];
transformed += morphTarget2 * morphTargetInfluences[ 2 ];
transformed += morphTarget3 * morphTargetInfluences[ 3 ];
#ifndef USE_MORPHNORMALS
transformed += morphTarget4 * morphTargetInfluences[ 4 ];
transformed += morphTarget5 * morphTargetInfluences[ 5 ];
transformed += morphTarget6 * morphTargetInfluences[ 6 ];
transformed += morphTarget7 * morphTargetInfluences[ 7 ];
#endif
#endif`,cA=`#ifdef FLAT_SHADED
vec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );
vec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );
vec3 normal = normalize( cross( fdx, fdy ) );
#else
vec3 normal = normalize( vNormal );
#ifdef DOUBLE_SIDED
normal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );
#endif
#ifdef USE_TANGENT
vec3 tangent = normalize( vTangent );
vec3 bitangent = normalize( vBitangent );
#ifdef DOUBLE_SIDED
tangent = tangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );
bitangent = bitangent * ( float( gl_FrontFacing ) * 2.0 - 1.0 );
#endif
#if defined( TANGENTSPACE_NORMALMAP ) || defined( USE_CLEARCOAT_NORMALMAP )
mat3 vTBN = mat3( tangent, bitangent, normal );
#endif
#endif
#endif
vec3 geometryNormal = normal;`,uA=`#ifdef OBJECTSPACE_NORMALMAP
normal = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;
#ifdef FLIP_SIDED
normal = - normal;
#endif
#ifdef DOUBLE_SIDED
normal = normal * ( float( gl_FrontFacing ) * 2.0 - 1.0 );
#endif
normal = normalize( normalMatrix * normal );
#elif defined( TANGENTSPACE_NORMALMAP )
vec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;
mapN.xy *= normalScale;
#ifdef USE_TANGENT
normal = normalize( vTBN * mapN );
#else
normal = perturbNormal2Arb( -vViewPosition, normal, mapN );
#endif
#elif defined( USE_BUMPMAP )
normal = perturbNormalArb( -vViewPosition, normal, dHdxy_fwd() );
#endif`,hA=`#ifdef USE_NORMALMAP
uniform sampler2D normalMap;
uniform vec2 normalScale;
#endif
#ifdef OBJECTSPACE_NORMALMAP
uniform mat3 normalMatrix;
#endif
#if ! defined ( USE_TANGENT ) && ( defined ( TANGENTSPACE_NORMALMAP ) || defined ( USE_CLEARCOAT_NORMALMAP ) )
vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec3 mapN ) {
vec3 q0 = vec3( dFdx( eye_pos.x ), dFdx( eye_pos.y ), dFdx( eye_pos.z ) );
vec3 q1 = vec3( dFdy( eye_pos.x ), dFdy( eye_pos.y ), dFdy( eye_pos.z ) );
vec2 st0 = dFdx( vUv.st );
vec2 st1 = dFdy( vUv.st );
float scale = sign( st1.t * st0.s - st0.t * st1.s );
vec3 S = normalize( ( q0 * st1.t - q1 * st0.t ) * scale );
vec3 T = normalize( ( - q0 * st1.s + q1 * st0.s ) * scale );
vec3 N = normalize( surf_norm );
mat3 tsn = mat3( S, T, N );
mapN.xy *= ( float( gl_FrontFacing ) * 2.0 - 1.0 );
return normalize( tsn * mapN );
}
#endif`,dA=`#ifdef CLEARCOAT
vec3 clearcoatNormal = geometryNormal;
#endif`,pA=`#ifdef USE_CLEARCOAT_NORMALMAP
vec3 clearcoatMapN = texture2D( clearcoatNormalMap, vUv ).xyz * 2.0 - 1.0;
clearcoatMapN.xy *= clearcoatNormalScale;
#ifdef USE_TANGENT
clearcoatNormal = normalize( vTBN * clearcoatMapN );
#else
clearcoatNormal = perturbNormal2Arb( - vViewPosition, clearcoatNormal, clearcoatMapN );
#endif
#endif`,fA=`#ifdef USE_CLEARCOAT_NORMALMAP
uniform sampler2D clearcoatNormalMap;
uniform vec2 clearcoatNormalScale;
#endif`,mA=`vec3 packNormalToRGB( const in vec3 normal ) {
return normalize( normal ) * 0.5 + 0.5;
}
vec3 unpackRGBToNormal( const in vec3 rgb ) {
return 2.0 * rgb.xyz - 1.0;
}
const float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;
const vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );
const vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );
const float ShiftRight8 = 1. / 256.;
vec4 packDepthToRGBA( const in float v ) {
vec4 r = vec4( fract( v * PackFactors ), v );
r.yzw -= r.xyz * ShiftRight8; return r * PackUpscale;
}
float unpackRGBAToDepth( const in vec4 v ) {
return dot( v, UnpackFactors );
}
vec4 pack2HalfToRGBA( vec2 v ) {
vec4 r = vec4( v.x, fract( v.x * 255.0 ), v.y, fract( v.y * 255.0 ));
return vec4( r.x - r.y / 255.0, r.y, r.z - r.w / 255.0, r.w);
}
vec2 unpackRGBATo2Half( vec4 v ) {
return vec2( v.x + ( v.y / 255.0 ), v.z + ( v.w / 255.0 ) );
}
float viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {
return ( viewZ + near ) / ( near - far );
}
float orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {
return linearClipZ * ( near - far ) - near;
}
float viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {
return (( near + viewZ ) * far ) / (( far - near ) * viewZ );
}
float perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {
return ( near * far ) / ( ( far - near ) * invClipZ - far );
}`,gA=`#ifdef PREMULTIPLIED_ALPHA
gl_FragColor.rgb *= gl_FragColor.a;
#endif`,yA=`vec4 mvPosition = vec4( transformed, 1.0 );
#ifdef USE_INSTANCING
mvPosition = instanceMatrix * mvPosition;
#endif
mvPosition = modelViewMatrix * mvPosition;
gl_Position = projectionMatrix * mvPosition;`,_A=`#ifdef DITHERING
gl_FragColor.rgb = dithering( gl_FragColor.rgb );
#endif`,vA=`#ifdef DITHERING
vec3 dithering( vec3 color ) {
float grid_position = rand( gl_FragCoord.xy );
vec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );
dither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );
return color + dither_shift_RGB;
}
#endif`,xA=`float roughnessFactor = roughness;
#ifdef USE_ROUGHNESSMAP
vec4 texelRoughness = texture2D( roughnessMap, vUv );
roughnessFactor *= texelRoughness.g;
#endif`,bA=`#ifdef USE_ROUGHNESSMAP
uniform sampler2D roughnessMap;
#endif`,wA=`#ifdef USE_SHADOWMAP
#if NUM_DIR_LIGHT_SHADOWS > 0
uniform sampler2D directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];
varying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];
#endif
#if NUM_SPOT_LIGHT_SHADOWS > 0
uniform sampler2D spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];
varying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];
#endif
#if NUM_POINT_LIGHT_SHADOWS > 0
uniform sampler2D pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];
varying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];
#endif
float texture2DCompare( sampler2D depths, vec2 uv, float compare ) {
return step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );
}
vec2 texture2DDistribution( sampler2D shadow, vec2 uv ) {
return unpackRGBATo2Half( texture2D( shadow, uv ) );
}
float VSMShadow (sampler2D shadow, vec2 uv, float compare ){
float occlusion = 1.0;
vec2 distribution = texture2DDistribution( shadow, uv );
float hard_shadow = step( compare , distribution.x );
if (hard_shadow != 1.0 ) {
float distance = compare - distribution.x ;
float variance = max( 0.00000, distribution.y * distribution.y );
float softness_probability = variance / (variance + distance * distance ); softness_probability = clamp( ( softness_probability - 0.3 ) / ( 0.95 - 0.3 ), 0.0, 1.0 ); occlusion = clamp( max( hard_shadow, softness_probability ), 0.0, 1.0 );
}
return occlusion;
}
float getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {
float shadow = 1.0;
shadowCoord.xyz /= shadowCoord.w;
shadowCoord.z += shadowBias;
bvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );
bool inFrustum = all( inFrustumVec );
bvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );
bool frustumTest = all( frustumTestVec );
if ( frustumTest ) {
#if defined( SHADOWMAP_TYPE_PCF )
vec2 texelSize = vec2( 1.0 ) / shadowMapSize;
float dx0 = - texelSize.x * shadowRadius;
float dy0 = - texelSize.y * shadowRadius;
float dx1 = + texelSize.x * shadowRadius;
float dy1 = + texelSize.y * shadowRadius;
float dx2 = dx0 / 2.0;
float dy2 = dy0 / 2.0;
float dx3 = dx1 / 2.0;
float dy3 = dy1 / 2.0;
shadow = (
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy2 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy2 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy2 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, 0.0 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, 0.0 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy3 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy3 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy3 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +
texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )
) * ( 1.0 / 17.0 );
#elif defined( SHADOWMAP_TYPE_PCF_SOFT )
vec2 texelSize = vec2( 1.0 ) / shadowMapSize;
float dx = texelSize.x;
float dy = texelSize.y;
vec2 uv = shadowCoord.xy;
vec2 f = fract( uv * shadowMapSize + 0.5 );
uv -= f * texelSize;
shadow = (
texture2DCompare( shadowMap, uv, shadowCoord.z ) +
texture2DCompare( shadowMap, uv + vec2( dx, 0.0 ), shadowCoord.z ) +
texture2DCompare( shadowMap, uv + vec2( 0.0, dy ), shadowCoord.z ) +
texture2DCompare( shadowMap, uv + texelSize, shadowCoord.z ) +
mix( texture2DCompare( shadowMap, uv + vec2( -dx, 0.0 ), shadowCoord.z ),
texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 0.0 ), shadowCoord.z ),
f.x ) +
mix( texture2DCompare( shadowMap, uv + vec2( -dx, dy ), shadowCoord.z ),
texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, dy ), shadowCoord.z ),
f.x ) +
mix( texture2DCompare( shadowMap, uv + vec2( 0.0, -dy ), shadowCoord.z ),
texture2DCompare( shadowMap, uv + vec2( 0.0, 2.0 * dy ), shadowCoord.z ),
f.y ) +
mix( texture2DCompare( shadowMap, uv + vec2( dx, -dy ), shadowCoord.z ),
texture2DCompare( shadowMap, uv + vec2( dx, 2.0 * dy ), shadowCoord.z ),
f.y ) +
mix( mix( texture2DCompare( shadowMap, uv + vec2( -dx, -dy ), shadowCoord.z ),
texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, -dy ), shadowCoord.z ),
f.x ),
mix( texture2DCompare( shadowMap, uv + vec2( -dx, 2.0 * dy ), shadowCoord.z ),
texture2DCompare( shadowMap, uv + + vec2( 2.0 * dx, 2.0 * dy ), shadowCoord.z ),
f.x ),
f.y )
) * ( 1.0 / 9.0 );
#elif defined( SHADOWMAP_TYPE_VSM )
shadow = VSMShadow( shadowMap, shadowCoord.xy, shadowCoord.z );
#else
shadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );
#endif
}
return shadow;
}
vec2 cubeToUV( vec3 v, float texelSizeY ) {
vec3 absV = abs( v );
float scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );
absV *= scaleToCube;
v *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );
vec2 planar = v.xy;
float almostATexel = 1.5 * texelSizeY;
float almostOne = 1.0 - almostATexel;
if ( absV.z >= almostOne ) {
if ( v.z > 0.0 )
planar.x = 4.0 - v.x;
} else if ( absV.x >= almostOne ) {
float signX = sign( v.x );
planar.x = v.z * signX + 2.0 * signX;
} else if ( absV.y >= almostOne ) {
float signY = sign( v.y );
planar.x = v.x + 2.0 * signY + 2.0;
planar.y = v.z * signY - 2.0;
}
return vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );
}
float getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {
vec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );
vec3 lightToPosition = shadowCoord.xyz;
float dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear ); dp += shadowBias;
vec3 bd3D = normalize( lightToPosition );
#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT ) || defined( SHADOWMAP_TYPE_VSM )
vec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;
return (
texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +
texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +
texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +
texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +
texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +
texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +
texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +
texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +
texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )
) * ( 1.0 / 9.0 );
#else
return texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );
#endif
}
#endif`,MA=`#ifdef USE_SHADOWMAP
#if NUM_DIR_LIGHT_SHADOWS > 0
uniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];
varying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];
#endif
#if NUM_SPOT_LIGHT_SHADOWS > 0
uniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHT_SHADOWS ];
varying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];
#endif
#if NUM_POINT_LIGHT_SHADOWS > 0
uniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];
varying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];
#endif
#endif`,TA=`#ifdef USE_SHADOWMAP
#if NUM_DIR_LIGHT_SHADOWS > 0
#pragma unroll_loop
for ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {
vDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * worldPosition;
}
#endif
#if NUM_SPOT_LIGHT_SHADOWS > 0
#pragma unroll_loop
for ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {
vSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * worldPosition;
}
#endif
#if NUM_POINT_LIGHT_SHADOWS > 0
#pragma unroll_loop
for ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {
vPointShadowCoord[ i ] = pointShadowMatrix[ i ] * worldPosition;
}
#endif
#endif`,EA=`float getShadowMask() {
float shadow = 1.0;
#ifdef USE_SHADOWMAP
#if NUM_DIR_LIGHT_SHADOWS > 0
DirectionalLight directionalLight;
#pragma unroll_loop
for ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {
directionalLight = directionalLights[ i ];
shadow *= all( bvec2( directionalLight.shadow, receiveShadow ) ) ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;
}
#endif
#if NUM_SPOT_LIGHT_SHADOWS > 0
SpotLight spotLight;
#pragma unroll_loop
for ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {
spotLight = spotLights[ i ];
shadow *= all( bvec2( spotLight.shadow, receiveShadow ) ) ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;
}
#endif
#if NUM_POINT_LIGHT_SHADOWS > 0
PointLight pointLight;
#pragma unroll_loop
for ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {
pointLight = pointLights[ i ];
shadow *= all( bvec2( pointLight.shadow, receiveShadow ) ) ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;
}
#endif
#endif
return shadow;
}`,CA=`#ifdef USE_SKINNING
mat4 boneMatX = getBoneMatrix( skinIndex.x );
mat4 boneMatY = getBoneMatrix( skinIndex.y );
mat4 boneMatZ = getBoneMatrix( skinIndex.z );
mat4 boneMatW = getBoneMatrix( skinIndex.w );
#endif`,AA=`#ifdef USE_SKINNING
uniform mat4 bindMatrix;
uniform mat4 bindMatrixInverse;
#ifdef BONE_TEXTURE
uniform highp sampler2D boneTexture;
uniform int boneTextureSize;
mat4 getBoneMatrix( const in float i ) {
float j = i * 4.0;
float x = mod( j, float( boneTextureSize ) );
float y = floor( j / float( boneTextureSize ) );
float dx = 1.0 / float( boneTextureSize );
float dy = 1.0 / float( boneTextureSize );
y = dy * ( y + 0.5 );
vec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );
vec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );
vec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );
vec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );
mat4 bone = mat4( v1, v2, v3, v4 );
return bone;
}
#else
uniform mat4 boneMatrices[ MAX_BONES ];
mat4 getBoneMatrix( const in float i ) {
mat4 bone = boneMatrices[ int(i) ];
return bone;
}
#endif
#endif`,DA=`#ifdef USE_SKINNING
vec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );
vec4 skinned = vec4( 0.0 );
skinned += boneMatX * skinVertex * skinWeight.x;
skinned += boneMatY * skinVertex * skinWeight.y;
skinned += boneMatZ * skinVertex * skinWeight.z;
skinned += boneMatW * skinVertex * skinWeight.w;
transformed = ( bindMatrixInverse * skinned ).xyz;
#endif`,PA=`#ifdef USE_SKINNING
mat4 skinMatrix = mat4( 0.0 );
skinMatrix += skinWeight.x * boneMatX;
skinMatrix += skinWeight.y * boneMatY;
skinMatrix += skinWeight.z * boneMatZ;
skinMatrix += skinWeight.w * boneMatW;
skinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;
objectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;
#ifdef USE_TANGENT
objectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz;
#endif
#endif`,SA=`float specularStrength;
#ifdef USE_SPECULARMAP
vec4 texelSpecular = texture2D( specularMap, vUv );
specularStrength = texelSpecular.r;
#else
specularStrength = 1.0;
#endif`,LA=`#ifdef USE_SPECULARMAP
uniform sampler2D specularMap;
#endif`,IA=`#if defined( TONE_MAPPING )
gl_FragColor.rgb = toneMapping( gl_FragColor.rgb );
#endif`,RA=`#ifndef saturate
#define saturate(a) clamp( a, 0.0, 1.0 )
#endif
uniform float toneMappingExposure;
uniform float toneMappingWhitePoint;
vec3 LinearToneMapping( vec3 color ) {
return toneMappingExposure * color;
}
vec3 ReinhardToneMapping( vec3 color ) {
color *= toneMappingExposure;
return saturate( color / ( vec3( 1.0 ) + color ) );
}
#define Uncharted2Helper( x ) max( ( ( x * ( 0.15 * x + 0.10 * 0.50 ) + 0.20 * 0.02 ) / ( x * ( 0.15 * x + 0.50 ) + 0.20 * 0.30 ) ) - 0.02 / 0.30, vec3( 0.0 ) )
vec3 Uncharted2ToneMapping( vec3 color ) {
color *= toneMappingExposure;
return saturate( Uncharted2Helper( color ) / Uncharted2Helper( vec3( toneMappingWhitePoint ) ) );
}
vec3 OptimizedCineonToneMapping( vec3 color ) {
color *= toneMappingExposure;
color = max( vec3( 0.0 ), color - 0.004 );
return pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );
}
vec3 ACESFilmicToneMapping( vec3 color ) {
color *= toneMappingExposure;
return saturate( ( color * ( 2.51 * color + 0.03 ) ) / ( color * ( 2.43 * color + 0.59 ) + 0.14 ) );
}`,kA=`#if ( defined( USE_UV ) && ! defined( UVS_VERTEX_ONLY ) )
varying vec2 vUv;
#endif`,zA=`#ifdef USE_UV
#ifdef UVS_VERTEX_ONLY
vec2 vUv;
#else
varying vec2 vUv;
#endif
uniform mat3 uvTransform;
#endif`,FA=`#ifdef USE_UV
vUv = ( uvTransform * vec3( uv, 1 ) ).xy;
#endif`,BA=`#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )
varying vec2 vUv2;
#endif`,OA=`#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )
attribute vec2 uv2;
varying vec2 vUv2;
uniform mat3 uv2Transform;
#endif`,NA=`#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )
vUv2 = ( uv2Transform * vec3( uv2, 1 ) ).xy;
#endif`,UA=`#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP )
vec4 worldPosition = vec4( transformed, 1.0 );
#ifdef USE_INSTANCING
worldPosition = instanceMatrix * worldPosition;
#endif
worldPosition = modelMatrix * worldPosition;
#endif`,VA=`uniform sampler2D t2D;
varying vec2 vUv;
void main() {
vec4 texColor = texture2D( t2D, vUv );
gl_FragColor = mapTexelToLinear( texColor );
#include
#include
}`,GA=`varying vec2 vUv;
uniform mat3 uvTransform;
void main() {
vUv = ( uvTransform * vec3( uv, 1 ) ).xy;
gl_Position = vec4( position.xy, 1.0, 1.0 );
}`,WA=`#include
uniform float opacity;
varying vec3 vWorldDirection;
#include
void main() {
vec3 vReflect = vWorldDirection;
#include
gl_FragColor = envColor;
gl_FragColor.a *= opacity;
#include
#include
}`,jA=`varying vec3 vWorldDirection;
#include
void main() {
vWorldDirection = transformDirection( position, modelMatrix );
#include
#include
gl_Position.z = gl_Position.w;
}`,HA=`#if DEPTH_PACKING == 3200
uniform float opacity;
#endif
#include
#include
#include
#include
#include
#include
#include
void main() {
#include
vec4 diffuseColor = vec4( 1.0 );
#if DEPTH_PACKING == 3200
diffuseColor.a = opacity;
#endif
#include
#include
#include
#include
#if DEPTH_PACKING == 3200
gl_FragColor = vec4( vec3( 1.0 - gl_FragCoord.z ), opacity );
#elif DEPTH_PACKING == 3201
gl_FragColor = packDepthToRGBA( gl_FragCoord.z );
#endif
}`,$A=`#include
#include
#include
#include
#include
#include
#include
void main() {
#include
#include
#ifdef USE_DISPLACEMENTMAP
#include
#include
#include
#endif
#include
#include
#include
#include
#include
#include
#include
}`,qA=`#define DISTANCE
uniform vec3 referencePosition;
uniform float nearDistance;
uniform float farDistance;
varying vec3 vWorldPosition;
#include
#include
#include
#include
#include
#include
void main () {
#include
vec4 diffuseColor = vec4( 1.0 );
#include
#include
#include
float dist = length( vWorldPosition - referencePosition );
dist = ( dist - nearDistance ) / ( farDistance - nearDistance );
dist = saturate( dist );
gl_FragColor = packDepthToRGBA( dist );
}`,XA=`#define DISTANCE
varying vec3 vWorldPosition;
#include
#include
#include
#include
#include
#include
void main() {
#include
#include
#ifdef USE_DISPLACEMENTMAP
#include
#include
#include
#endif
#include
#include
#include
#include
#include
#include
#include
vWorldPosition = worldPosition.xyz;
}`,ZA=`uniform sampler2D tEquirect;
varying vec3 vWorldDirection;
#include
void main() {
vec3 direction = normalize( vWorldDirection );
vec2 sampleUV;
sampleUV.y = asin( clamp( direction.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;
sampleUV.x = atan( direction.z, direction.x ) * RECIPROCAL_PI2 + 0.5;
vec4 texColor = texture2D( tEquirect, sampleUV );
gl_FragColor = mapTexelToLinear( texColor );
#include
#include
}`,YA=`varying vec3 vWorldDirection;
#include
void main() {
vWorldDirection = transformDirection( position, modelMatrix );
#include
#include
}`,KA=`uniform vec3 diffuse;
uniform float opacity;
uniform float dashSize;
uniform float totalSize;
varying float vLineDistance;
#include
#include
#include
#include
#include
void main() {
#include
if ( mod( vLineDistance, totalSize ) > dashSize ) {
discard;
}
vec3 outgoingLight = vec3( 0.0 );
vec4 diffuseColor = vec4( diffuse, opacity );
#include
#include
outgoingLight = diffuseColor.rgb;
gl_FragColor = vec4( outgoingLight, diffuseColor.a );
#include
#include
#include
#include
}`,JA=`uniform float scale;
attribute float lineDistance;
varying float vLineDistance;
#include
#include
#include
#include
#include
void main() {
#include
vLineDistance = scale * lineDistance;
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
gl_Position = projectionMatrix * mvPosition;
#include
#include
#include
}`,QA=`uniform vec3 diffuse;
uniform float opacity;
#ifndef FLAT_SHADED
varying vec3 vNormal;
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
void main() {
#include
vec4 diffuseColor = vec4( diffuse, opacity );
#include
#include
#include
#include
#include
#include
ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );
#ifdef USE_LIGHTMAP
vec4 lightMapTexel= texture2D( lightMap, vUv2 );
reflectedLight.indirectDiffuse += lightMapTexelToLinear( lightMapTexel ).rgb * lightMapIntensity;
#else
reflectedLight.indirectDiffuse += vec3( 1.0 );
#endif
#include
reflectedLight.indirectDiffuse *= diffuseColor.rgb;
vec3 outgoingLight = reflectedLight.indirectDiffuse;
#include
gl_FragColor = vec4( outgoingLight, diffuseColor.a );
#include
#include
#include
#include
}`,eD=`#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
void main() {
#include
#include
#include
#include
#ifdef USE_ENVMAP
#include
#include
#include
#include
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
}`,tD=`uniform vec3 diffuse;
uniform vec3 emissive;
uniform float opacity;
varying vec3 vLightFront;
varying vec3 vIndirectFront;
#ifdef DOUBLE_SIDED
varying vec3 vLightBack;
varying vec3 vIndirectBack;
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
void main() {
#include
vec4 diffuseColor = vec4( diffuse, opacity );
ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );
vec3 totalEmissiveRadiance = emissive;
#include
#include
#include
#include
#include
#include
#include
reflectedLight.indirectDiffuse = getAmbientLightIrradiance( ambientLightColor );
#ifdef DOUBLE_SIDED
reflectedLight.indirectDiffuse += ( gl_FrontFacing ) ? vIndirectFront : vIndirectBack;
#else
reflectedLight.indirectDiffuse += vIndirectFront;
#endif
#include
reflectedLight.indirectDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb );
#ifdef DOUBLE_SIDED
reflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;
#else
reflectedLight.directDiffuse = vLightFront;
#endif
reflectedLight.directDiffuse *= BRDF_Diffuse_Lambert( diffuseColor.rgb ) * getShadowMask();
#include
vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;
#include
gl_FragColor = vec4( outgoingLight, diffuseColor.a );
#include
#include
#include
#include
#include
}`,nD=`#define LAMBERT
varying vec3 vLightFront;
varying vec3 vIndirectFront;
#ifdef DOUBLE_SIDED
varying vec3 vLightBack;
varying vec3 vIndirectBack;
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
void main() {
#include
#include
#include
#include
#include
#include
#include