Browse Source

Merge pull request #8232 from bhouston/output_encoding

Output encoding
Mr.doob 9 years ago
parent
commit
5062677017

+ 21 - 32
build/three.js

@@ -29464,38 +29464,6 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) {
 
 
 	}
 	}
 
 
-	function getTextureEncodingFromMap( map ) {
-
-		if ( ! map ) return false;
-
-		var encoding;
-
-		if ( map instanceof THREE.Texture ) {
-
-			encoding = map.encoding;
-
-		} else if ( map instanceof THREE.WebGLRenderTarget ) {
-
-			encoding = map.texture.encoding;
-
-		} else {
-
-			throw new Error( "can not determine texture encoding from map: " + map );
-
-		}
-
-		// add backwards compatibility for WebGLRenderer.gammaInput parameter, should probably be removed at some point.
-
-		if ( encoding === THREE.LinearEncoding && renderer.gammaInput ) {
-
-			encoding = THREE.GammaEncoding;
-
-		}
-
-		return encoding;
-
-	}
-
 	this.getParameters = function ( material, lights, fog, object ) {
 	this.getParameters = function ( material, lights, fog, object ) {
 
 
 		var shaderID = shaderIDs[ material.type ];
 		var shaderID = shaderIDs[ material.type ];
@@ -29517,6 +29485,27 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) {
 
 
 		}
 		}
 
 
+		var getTextureEncodingFromMap = function( map ) {
+			if( ! map ) { // no texture
+				return false;
+			}
+			var encoding;
+			if( map.encoding !== undefined ) { // standard texture
+				encoding = map.encoding;
+			}
+			else if( map.texture !== undefined ) {  // render target pretending to be a texture, get the texture inside it.
+				encoding = map.texture.encoding;
+			}
+			else {
+				throw new Error( "can not determine texture encoding from map: " + map );
+			}
+			// add backwards compatibility for WebGLRenderer.gammaInput parameter, should probably be removed at some point. 
+			if( encoding === THREE.LinearEncoding && renderer.gammaInput ) {
+				encoding = THREE.GammaEncoding;
+			}
+			return encoding;
+		}
+
 		var parameters = {
 		var parameters = {
 
 
 			shaderID: shaderID,
 			shaderID: shaderID,

+ 26 - 26
build/three.min.js

@@ -489,7 +489,7 @@ THREE.Mesh=function(a,b){THREE.Object3D.call(this);this.type="Mesh";this.geometr
 THREE.Mesh.prototype.updateMorphTargets=function(){if(void 0!==this.geometry.morphTargets&&0<this.geometry.morphTargets.length){this.morphTargetBase=-1;this.morphTargetInfluences=[];this.morphTargetDictionary={};for(var a=0,b=this.geometry.morphTargets.length;a<b;a++)this.morphTargetInfluences.push(0),this.morphTargetDictionary[this.geometry.morphTargets[a].name]=a}};
 THREE.Mesh.prototype.updateMorphTargets=function(){if(void 0!==this.geometry.morphTargets&&0<this.geometry.morphTargets.length){this.morphTargetBase=-1;this.morphTargetInfluences=[];this.morphTargetDictionary={};for(var a=0,b=this.geometry.morphTargets.length;a<b;a++)this.morphTargetInfluences.push(0),this.morphTargetDictionary[this.geometry.morphTargets[a].name]=a}};
 THREE.Mesh.prototype.getMorphTargetIndexByName=function(a){if(void 0!==this.morphTargetDictionary[a])return this.morphTargetDictionary[a];console.warn("THREE.Mesh.getMorphTargetIndexByName: morph target "+a+" does not exist. Returning 0.");return 0};
 THREE.Mesh.prototype.getMorphTargetIndexByName=function(a){if(void 0!==this.morphTargetDictionary[a])return this.morphTargetDictionary[a];console.warn("THREE.Mesh.getMorphTargetIndexByName: morph target "+a+" does not exist. Returning 0.");return 0};
 THREE.Mesh.prototype.raycast=function(){function a(a,b,c,d,e,g,f){THREE.Triangle.barycoordFromPoint(a,b,c,d,t);e.multiplyScalar(t.x);g.multiplyScalar(t.y);f.multiplyScalar(t.z);e.add(g).add(f);return e.clone()}function b(a,b,c,d,e,g,f){var h=a.material;if(null===(h.side===THREE.BackSide?c.intersectTriangle(g,e,d,!0,f):c.intersectTriangle(d,e,g,h.side!==THREE.DoubleSide,f)))return null;x.copy(f);x.applyMatrix4(a.matrixWorld);c=b.ray.origin.distanceTo(x);return c<b.near||c>b.far?null:{distance:c,point:x.clone(),
 THREE.Mesh.prototype.raycast=function(){function a(a,b,c,d,e,g,f){THREE.Triangle.barycoordFromPoint(a,b,c,d,t);e.multiplyScalar(t.x);g.multiplyScalar(t.y);f.multiplyScalar(t.z);e.add(g).add(f);return e.clone()}function b(a,b,c,d,e,g,f){var h=a.material;if(null===(h.side===THREE.BackSide?c.intersectTriangle(g,e,d,!0,f):c.intersectTriangle(d,e,g,h.side!==THREE.DoubleSide,f)))return null;x.copy(f);x.applyMatrix4(a.matrixWorld);c=b.ray.origin.distanceTo(x);return c<b.near||c>b.far?null:{distance:c,point:x.clone(),
-object:a}}function c(c,d,e,f,l,p,n,t){g.fromArray(f,3*p);h.fromArray(f,3*n);k.fromArray(f,3*t);if(c=b(c,d,e,g,h,k,u))l&&(m.fromArray(l,2*p),q.fromArray(l,2*n),r.fromArray(l,2*t),c.uv=a(u,g,h,k,m,q,r)),c.face=new THREE.Face3(p,n,t,THREE.Triangle.normal(g,h,k)),c.faceIndex=p;return c}var d=new THREE.Matrix4,e=new THREE.Ray,f=new THREE.Sphere,g=new THREE.Vector3,h=new THREE.Vector3,k=new THREE.Vector3,l=new THREE.Vector3,n=new THREE.Vector3,p=new THREE.Vector3,m=new THREE.Vector2,q=new THREE.Vector2,
+object:a}}function c(c,d,e,f,l,n,p,t){g.fromArray(f,3*n);h.fromArray(f,3*p);k.fromArray(f,3*t);if(c=b(c,d,e,g,h,k,u))l&&(m.fromArray(l,2*n),q.fromArray(l,2*p),r.fromArray(l,2*t),c.uv=a(u,g,h,k,m,q,r)),c.face=new THREE.Face3(n,p,t,THREE.Triangle.normal(g,h,k)),c.faceIndex=n;return c}var d=new THREE.Matrix4,e=new THREE.Ray,f=new THREE.Sphere,g=new THREE.Vector3,h=new THREE.Vector3,k=new THREE.Vector3,l=new THREE.Vector3,n=new THREE.Vector3,p=new THREE.Vector3,m=new THREE.Vector2,q=new THREE.Vector2,
 r=new THREE.Vector2,t=new THREE.Vector3,u=new THREE.Vector3,x=new THREE.Vector3;return function(t,x){var w=this.geometry,D=this.material,A=this.matrixWorld;if(void 0!==D&&(null===w.boundingSphere&&w.computeBoundingSphere(),f.copy(w.boundingSphere),f.applyMatrix4(A),!1!==t.ray.intersectsSphere(f)&&(d.getInverse(A),e.copy(t.ray).applyMatrix4(d),null===w.boundingBox||!1!==e.intersectsBox(w.boundingBox)))){var y,B;if(w instanceof THREE.BufferGeometry){var G,E,D=w.index,A=w.attributes,w=A.position.array;
 r=new THREE.Vector2,t=new THREE.Vector3,u=new THREE.Vector3,x=new THREE.Vector3;return function(t,x){var w=this.geometry,D=this.material,A=this.matrixWorld;if(void 0!==D&&(null===w.boundingSphere&&w.computeBoundingSphere(),f.copy(w.boundingSphere),f.applyMatrix4(A),!1!==t.ray.intersectsSphere(f)&&(d.getInverse(A),e.copy(t.ray).applyMatrix4(d),null===w.boundingBox||!1!==e.intersectsBox(w.boundingBox)))){var y,B;if(w instanceof THREE.BufferGeometry){var G,E,D=w.index,A=w.attributes,w=A.position.array;
 void 0!==A.uv&&(y=A.uv.array);if(null!==D)for(var A=D.array,z=0,K=A.length;z<K;z+=3){if(D=A[z],G=A[z+1],E=A[z+2],B=c(this,t,e,w,y,D,G,E))B.faceIndex=Math.floor(z/3),x.push(B)}else for(z=0,K=w.length;z<K;z+=9)if(D=z/3,G=D+1,E=D+2,B=c(this,t,e,w,y,D,G,E))B.index=D,x.push(B)}else if(w instanceof THREE.Geometry){var P,N,A=D instanceof THREE.MultiMaterial,z=!0===A?D.materials:null,K=w.vertices;G=w.faces;E=w.faceVertexUvs[0];0<E.length&&(y=E);for(var L=0,H=G.length;L<H;L++){var M=G[L];B=!0===A?z[M.materialIndex]:
 void 0!==A.uv&&(y=A.uv.array);if(null!==D)for(var A=D.array,z=0,K=A.length;z<K;z+=3){if(D=A[z],G=A[z+1],E=A[z+2],B=c(this,t,e,w,y,D,G,E))B.faceIndex=Math.floor(z/3),x.push(B)}else for(z=0,K=w.length;z<K;z+=9)if(D=z/3,G=D+1,E=D+2,B=c(this,t,e,w,y,D,G,E))B.index=D,x.push(B)}else if(w instanceof THREE.Geometry){var P,N,A=D instanceof THREE.MultiMaterial,z=!0===A?D.materials:null,K=w.vertices;G=w.faces;E=w.faceVertexUvs[0];0<E.length&&(y=E);for(var L=0,H=G.length;L<H;L++){var M=G[L];B=!0===A?z[M.materialIndex]:
 D;if(void 0!==B){E=K[M.a];P=K[M.b];N=K[M.c];if(!0===B.morphTargets){B=w.morphTargets;var Q=this.morphTargetInfluences;g.set(0,0,0);h.set(0,0,0);k.set(0,0,0);for(var O=0,R=B.length;O<R;O++){var I=Q[O];if(0!==I){var F=B[O].vertices;g.addScaledVector(l.subVectors(F[M.a],E),I);h.addScaledVector(n.subVectors(F[M.b],P),I);k.addScaledVector(p.subVectors(F[M.c],N),I)}}g.add(E);h.add(P);k.add(N);E=g;P=h;N=k}if(B=b(this,t,e,E,P,N,u))y&&(Q=y[L],m.copy(Q[0]),q.copy(Q[1]),r.copy(Q[2]),B.uv=a(u,E,P,N,m,q,r)),B.face=
 D;if(void 0!==B){E=K[M.a];P=K[M.b];N=K[M.c];if(!0===B.morphTargets){B=w.morphTargets;var Q=this.morphTargetInfluences;g.set(0,0,0);h.set(0,0,0);k.set(0,0,0);for(var O=0,R=B.length;O<R;O++){var I=Q[O];if(0!==I){var F=B[O].vertices;g.addScaledVector(l.subVectors(F[M.a],E),I);h.addScaledVector(n.subVectors(F[M.b],P),I);k.addScaledVector(p.subVectors(F[M.c],N),I)}}g.add(E);h.add(P);k.add(N);E=g;P=h;N=k}if(B=b(this,t,e,E,P,N,u))y&&(Q=y[L],m.copy(Q[0]),q.copy(Q[1]),r.copy(Q[2]),B.uv=a(u,E,P,N,m,q,r)),B.face=
@@ -587,21 +587,21 @@ a.object.renderOrder-b.object.renderOrder:a.z!==b.z?b.z-a.z:a.id-b.id}function m
 THREE.LensFlare)ha.push(a);else if(a instanceof THREE.ImmediateRenderObject)!0===Y.sortObjects&&(X.setFromMatrixPosition(a.matrixWorld),X.applyProjection(sa)),m(a,null,a.material,X.z,null);else if(a instanceof THREE.Mesh||a instanceof THREE.Line||a instanceof THREE.Points)if(a instanceof THREE.SkinnedMesh&&a.skeleton.update(),!1===a.frustumCulled||!0===ya.intersectsObject(a)){var c=a.material;if(!0===c.visible){!0===Y.sortObjects&&(X.setFromMatrixPosition(a.matrixWorld),X.applyProjection(sa));var d=
 THREE.LensFlare)ha.push(a);else if(a instanceof THREE.ImmediateRenderObject)!0===Y.sortObjects&&(X.setFromMatrixPosition(a.matrixWorld),X.applyProjection(sa)),m(a,null,a.material,X.z,null);else if(a instanceof THREE.Mesh||a instanceof THREE.Line||a instanceof THREE.Points)if(a instanceof THREE.SkinnedMesh&&a.skeleton.update(),!1===a.frustumCulled||!0===ya.intersectsObject(a)){var c=a.material;if(!0===c.visible){!0===Y.sortObjects&&(X.setFromMatrixPosition(a.matrixWorld),X.applyProjection(sa));var d=
 pa.update(a);if(c instanceof THREE.MultiMaterial)for(var e=d.groups,g=c.materials,c=0,f=e.length;c<f;c++){var h=e[c],k=g[h.materialIndex];!0===k.visible&&m(a,d,k,X.z,h)}else m(a,d,c,X.z,null)}}d=a.children;c=0;for(f=d.length;c<f;c++)q(d[c],b)}}function r(a,b,c,d){for(var e=0,g=a.length;e<g;e++){var f=a[e],h=f.object,k=f.geometry,l=void 0===d?f.material:d,f=f.group;h.modelViewMatrix.multiplyMatrices(b.matrixWorldInverse,h.matrixWorld);h.normalMatrix.getNormalMatrix(h.modelViewMatrix);if(h instanceof
 pa.update(a);if(c instanceof THREE.MultiMaterial)for(var e=d.groups,g=c.materials,c=0,f=e.length;c<f;c++){var h=e[c],k=g[h.materialIndex];!0===k.visible&&m(a,d,k,X.z,h)}else m(a,d,c,X.z,null)}}d=a.children;c=0;for(f=d.length;c<f;c++)q(d[c],b)}}function r(a,b,c,d){for(var e=0,g=a.length;e<g;e++){var f=a[e],h=f.object,k=f.geometry,l=void 0===d?f.material:d,f=f.group;h.modelViewMatrix.multiplyMatrices(b.matrixWorldInverse,h.matrixWorld);h.normalMatrix.getNormalMatrix(h.modelViewMatrix);if(h instanceof
 THREE.ImmediateRenderObject){t(l);var m=u(b,c,l,h);na="";h.render(function(a){Y.renderBufferImmediate(a,m,l)})}else Y.renderBufferDirect(b,c,k,l,h,f)}}function t(a){a.side!==THREE.DoubleSide?J.enable(s.CULL_FACE):J.disable(s.CULL_FACE);J.setFlipSided(a.side===THREE.BackSide);!0===a.transparent?J.setBlending(a.blending,a.blendEquation,a.blendSrc,a.blendDst,a.blendEquationAlpha,a.blendSrcAlpha,a.blendDstAlpha):J.setBlending(THREE.NoBlending);J.setDepthFunc(a.depthFunc);J.setDepthTest(a.depthTest);J.setDepthWrite(a.depthWrite);
 THREE.ImmediateRenderObject){t(l);var m=u(b,c,l,h);na="";h.render(function(a){Y.renderBufferImmediate(a,m,l)})}else Y.renderBufferDirect(b,c,k,l,h,f)}}function t(a){a.side!==THREE.DoubleSide?J.enable(s.CULL_FACE):J.disable(s.CULL_FACE);J.setFlipSided(a.side===THREE.BackSide);!0===a.transparent?J.setBlending(a.blending,a.blendEquation,a.blendSrc,a.blendDst,a.blendEquationAlpha,a.blendSrcAlpha,a.blendDstAlpha):J.setBlending(THREE.NoBlending);J.setDepthFunc(a.depthFunc);J.setDepthTest(a.depthTest);J.setDepthWrite(a.depthWrite);
-J.setColorWrite(a.colorWrite);J.setPolygonOffset(a.polygonOffset,a.polygonOffsetFactor,a.polygonOffsetUnits)}function u(a,b,c,d){ta=0;var e=T.get(c);void 0===e.program&&(c.needsUpdate=!0);void 0!==e.lightsHash&&e.lightsHash!==S.hash&&(c.needsUpdate=!0);if(c.needsUpdate){a:{var g=T.get(c),f=oa.getParameters(c,S,b,d),l=oa.getProgramCode(c,f),m=g.program,p=!0;if(void 0===m)c.addEventListener("dispose",h);else if(m.code!==l)k(c);else if(void 0!==f.shaderID)break a;else p=!1;p&&(f.shaderID?(m=THREE.ShaderLib[f.shaderID],
+J.setColorWrite(a.colorWrite);J.setPolygonOffset(a.polygonOffset,a.polygonOffsetFactor,a.polygonOffsetUnits)}function u(a,b,c,d){ta=0;var e=T.get(c);void 0===e.program&&(c.needsUpdate=!0);void 0!==e.lightsHash&&e.lightsHash!==S.hash&&(c.needsUpdate=!0);if(c.needsUpdate){a:{var g=T.get(c),f=oa.getParameters(c,S,b,d),l=oa.getProgramCode(c,f),m=g.program,q=!0;if(void 0===m)c.addEventListener("dispose",h);else if(m.code!==l)k(c);else if(void 0!==f.shaderID)break a;else q=!1;q&&(f.shaderID?(m=THREE.ShaderLib[f.shaderID],
 g.__webglShader={name:c.type,uniforms:THREE.UniformsUtils.clone(m.uniforms),vertexShader:m.vertexShader,fragmentShader:m.fragmentShader}):g.__webglShader={name:c.type,uniforms:c.uniforms,vertexShader:c.vertexShader,fragmentShader:c.fragmentShader},c.__webglShader=g.__webglShader,m=oa.acquireProgram(c,f,l),g.program=m,c.program=m);f=m.getAttributes();if(c.morphTargets)for(l=c.numSupportedMorphTargets=0;l<Y.maxMorphTargets;l++)0<=f["morphTarget"+l]&&c.numSupportedMorphTargets++;if(c.morphNormals)for(l=
 g.__webglShader={name:c.type,uniforms:THREE.UniformsUtils.clone(m.uniforms),vertexShader:m.vertexShader,fragmentShader:m.fragmentShader}):g.__webglShader={name:c.type,uniforms:c.uniforms,vertexShader:c.vertexShader,fragmentShader:c.fragmentShader},c.__webglShader=g.__webglShader,m=oa.acquireProgram(c,f,l),g.program=m,c.program=m);f=m.getAttributes();if(c.morphTargets)for(l=c.numSupportedMorphTargets=0;l<Y.maxMorphTargets;l++)0<=f["morphTarget"+l]&&c.numSupportedMorphTargets++;if(c.morphNormals)for(l=
-c.numSupportedMorphNormals=0;l<Y.maxMorphNormals;l++)0<=f["morphNormal"+l]&&c.numSupportedMorphNormals++;g.uniformsList=[];var f=g.__webglShader.uniforms,l=g.program.getUniforms(),q;for(q in f)(m=l[q])&&g.uniformsList.push([g.__webglShader.uniforms[q],m]);if(c instanceof THREE.MeshPhongMaterial||c instanceof THREE.MeshLambertMaterial||c instanceof THREE.MeshStandardMaterial||c.lights)g.lightsHash=S.hash,f.ambientLightColor.value=S.ambient,f.directionalLights.value=S.directional,f.spotLights.value=
-S.spot,f.pointLights.value=S.point,f.hemisphereLights.value=S.hemi,f.directionalShadowMap.value=S.directionalShadowMap,f.directionalShadowMatrix.value=S.directionalShadowMatrix,f.spotShadowMap.value=S.spotShadowMap,f.spotShadowMatrix.value=S.spotShadowMatrix,f.pointShadowMap.value=S.pointShadowMap,f.pointShadowMatrix.value=S.pointShadowMatrix;g.hasDynamicUniforms=!1;q=0;for(f=g.uniformsList.length;q<f;q++)if(!0===g.uniformsList[q][0].dynamic){g.hasDynamicUniforms=!0;break}}c.needsUpdate=!1}m=l=p=
-!1;g=e.program;q=g.getUniforms();f=e.__webglShader.uniforms;g.id!==ma&&(s.useProgram(g.program),ma=g.id,m=l=p=!0);c.id!==ra&&(ra=c.id,l=!0);if(p||a!==la)s.uniformMatrix4fv(q.projectionMatrix,!1,a.projectionMatrix.elements),da.logarithmicDepthBuffer&&s.uniform1f(q.logDepthBufFC,2/(Math.log(a.far+1)/Math.LN2)),a!==la&&(la=a,m=l=!0),(c instanceof THREE.ShaderMaterial||c instanceof THREE.MeshPhongMaterial||c instanceof THREE.MeshStandardMaterial||c.envMap)&&void 0!==q.cameraPosition&&(X.setFromMatrixPosition(a.matrixWorld),
-s.uniform3f(q.cameraPosition,X.x,X.y,X.z)),(c instanceof THREE.MeshPhongMaterial||c instanceof THREE.MeshLambertMaterial||c instanceof THREE.MeshBasicMaterial||c instanceof THREE.MeshStandardMaterial||c instanceof THREE.ShaderMaterial||c.skinning)&&void 0!==q.viewMatrix&&s.uniformMatrix4fv(q.viewMatrix,!1,a.matrixWorldInverse.elements);c.skinning&&(d.bindMatrix&&void 0!==q.bindMatrix&&s.uniformMatrix4fv(q.bindMatrix,!1,d.bindMatrix.elements),d.bindMatrixInverse&&void 0!==q.bindMatrixInverse&&s.uniformMatrix4fv(q.bindMatrixInverse,
-!1,d.bindMatrixInverse.elements),da.floatVertexTextures&&d.skeleton&&d.skeleton.useVertexTexture?(void 0!==q.boneTexture&&(p=x(),s.uniform1i(q.boneTexture,p),Y.setTexture(d.skeleton.boneTexture,p)),void 0!==q.boneTextureWidth&&s.uniform1i(q.boneTextureWidth,d.skeleton.boneTextureWidth),void 0!==q.boneTextureHeight&&s.uniform1i(q.boneTextureHeight,d.skeleton.boneTextureHeight)):d.skeleton&&d.skeleton.boneMatrices&&void 0!==q.boneGlobalMatrices&&s.uniformMatrix4fv(q.boneGlobalMatrices,!1,d.skeleton.boneMatrices));
+c.numSupportedMorphNormals=0;l<Y.maxMorphNormals;l++)0<=f["morphNormal"+l]&&c.numSupportedMorphNormals++;g.uniformsList=[];var f=g.__webglShader.uniforms,l=g.program.getUniforms(),n;for(n in f)(m=l[n])&&g.uniformsList.push([g.__webglShader.uniforms[n],m]);if(c instanceof THREE.MeshPhongMaterial||c instanceof THREE.MeshLambertMaterial||c instanceof THREE.MeshStandardMaterial||c.lights)g.lightsHash=S.hash,f.ambientLightColor.value=S.ambient,f.directionalLights.value=S.directional,f.spotLights.value=
+S.spot,f.pointLights.value=S.point,f.hemisphereLights.value=S.hemi,f.directionalShadowMap.value=S.directionalShadowMap,f.directionalShadowMatrix.value=S.directionalShadowMatrix,f.spotShadowMap.value=S.spotShadowMap,f.spotShadowMatrix.value=S.spotShadowMatrix,f.pointShadowMap.value=S.pointShadowMap,f.pointShadowMatrix.value=S.pointShadowMatrix;g.hasDynamicUniforms=!1;n=0;for(f=g.uniformsList.length;n<f;n++)if(!0===g.uniformsList[n][0].dynamic){g.hasDynamicUniforms=!0;break}}c.needsUpdate=!1}m=l=q=
+!1;g=e.program;n=g.getUniforms();f=e.__webglShader.uniforms;g.id!==ma&&(s.useProgram(g.program),ma=g.id,m=l=q=!0);c.id!==ra&&(ra=c.id,l=!0);if(q||a!==la)s.uniformMatrix4fv(n.projectionMatrix,!1,a.projectionMatrix.elements),da.logarithmicDepthBuffer&&s.uniform1f(n.logDepthBufFC,2/(Math.log(a.far+1)/Math.LN2)),a!==la&&(la=a,m=l=!0),(c instanceof THREE.ShaderMaterial||c instanceof THREE.MeshPhongMaterial||c instanceof THREE.MeshStandardMaterial||c.envMap)&&void 0!==n.cameraPosition&&(X.setFromMatrixPosition(a.matrixWorld),
+s.uniform3f(n.cameraPosition,X.x,X.y,X.z)),(c instanceof THREE.MeshPhongMaterial||c instanceof THREE.MeshLambertMaterial||c instanceof THREE.MeshBasicMaterial||c instanceof THREE.MeshStandardMaterial||c instanceof THREE.ShaderMaterial||c.skinning)&&void 0!==n.viewMatrix&&s.uniformMatrix4fv(n.viewMatrix,!1,a.matrixWorldInverse.elements);c.skinning&&(d.bindMatrix&&void 0!==n.bindMatrix&&s.uniformMatrix4fv(n.bindMatrix,!1,d.bindMatrix.elements),d.bindMatrixInverse&&void 0!==n.bindMatrixInverse&&s.uniformMatrix4fv(n.bindMatrixInverse,
+!1,d.bindMatrixInverse.elements),da.floatVertexTextures&&d.skeleton&&d.skeleton.useVertexTexture?(void 0!==n.boneTexture&&(q=x(),s.uniform1i(n.boneTexture,q),Y.setTexture(d.skeleton.boneTexture,q)),void 0!==n.boneTextureWidth&&s.uniform1i(n.boneTextureWidth,d.skeleton.boneTextureWidth),void 0!==n.boneTextureHeight&&s.uniform1i(n.boneTextureHeight,d.skeleton.boneTextureHeight)):d.skeleton&&d.skeleton.boneMatrices&&void 0!==n.boneGlobalMatrices&&s.uniformMatrix4fv(n.boneGlobalMatrices,!1,d.skeleton.boneMatrices));
 if(l){if(c instanceof THREE.MeshPhongMaterial||c instanceof THREE.MeshLambertMaterial||c instanceof THREE.MeshStandardMaterial||c.lights)l=m,f.ambientLightColor.needsUpdate=l,f.directionalLights.needsUpdate=l,f.pointLights.needsUpdate=l,f.spotLights.needsUpdate=l,f.hemisphereLights.needsUpdate=l;b&&c.fog&&(f.fogColor.value=b.color,b instanceof THREE.Fog?(f.fogNear.value=b.near,f.fogFar.value=b.far):b instanceof THREE.FogExp2&&(f.fogDensity.value=b.density));if(c instanceof THREE.MeshBasicMaterial||
 if(l){if(c instanceof THREE.MeshPhongMaterial||c instanceof THREE.MeshLambertMaterial||c instanceof THREE.MeshStandardMaterial||c.lights)l=m,f.ambientLightColor.needsUpdate=l,f.directionalLights.needsUpdate=l,f.pointLights.needsUpdate=l,f.spotLights.needsUpdate=l,f.hemisphereLights.needsUpdate=l;b&&c.fog&&(f.fogColor.value=b.color,b instanceof THREE.Fog?(f.fogNear.value=b.near,f.fogFar.value=b.far):b instanceof THREE.FogExp2&&(f.fogDensity.value=b.density));if(c instanceof THREE.MeshBasicMaterial||
-c instanceof THREE.MeshLambertMaterial||c instanceof THREE.MeshPhongMaterial||c instanceof THREE.MeshStandardMaterial){f.opacity.value=c.opacity;f.diffuse.value=c.color;c.emissive&&f.emissive.value.copy(c.emissive).multiplyScalar(c.emissiveIntensity);f.map.value=c.map;f.specularMap.value=c.specularMap;f.alphaMap.value=c.alphaMap;c.aoMap&&(f.aoMap.value=c.aoMap,f.aoMapIntensity.value=c.aoMapIntensity);var n;c.map?n=c.map:c.specularMap?n=c.specularMap:c.displacementMap?n=c.displacementMap:c.normalMap?
-n=c.normalMap:c.bumpMap?n=c.bumpMap:c.roughnessMap?n=c.roughnessMap:c.metalnessMap?n=c.metalnessMap:c.alphaMap?n=c.alphaMap:c.emissiveMap&&(n=c.emissiveMap);void 0!==n&&(n instanceof THREE.WebGLRenderTarget&&(n=n.texture),b=n.offset,n=n.repeat,f.offsetRepeat.value.set(b.x,b.y,n.x,n.y));f.envMap.value=c.envMap;f.flipEnvMap.value=c.envMap instanceof THREE.WebGLRenderTargetCube?1:-1;f.reflectivity.value=c.reflectivity;f.refractionRatio.value=c.refractionRatio}c instanceof THREE.LineBasicMaterial?(f.diffuse.value=
-c.color,f.opacity.value=c.opacity):c instanceof THREE.LineDashedMaterial?(f.diffuse.value=c.color,f.opacity.value=c.opacity,f.dashSize.value=c.dashSize,f.totalSize.value=c.dashSize+c.gapSize,f.scale.value=c.scale):c instanceof THREE.PointsMaterial?(f.diffuse.value=c.color,f.opacity.value=c.opacity,f.size.value=c.size*$,f.scale.value=K.clientHeight/2,f.map.value=c.map,null!==c.map&&(n=c.map.offset,c=c.map.repeat,f.offsetRepeat.value.set(n.x,n.y,c.x,c.y))):c instanceof THREE.MeshLambertMaterial?(c.lightMap&&
+c instanceof THREE.MeshLambertMaterial||c instanceof THREE.MeshPhongMaterial||c instanceof THREE.MeshStandardMaterial){f.opacity.value=c.opacity;f.diffuse.value=c.color;c.emissive&&f.emissive.value.copy(c.emissive).multiplyScalar(c.emissiveIntensity);f.map.value=c.map;f.specularMap.value=c.specularMap;f.alphaMap.value=c.alphaMap;c.aoMap&&(f.aoMap.value=c.aoMap,f.aoMapIntensity.value=c.aoMapIntensity);var p;c.map?p=c.map:c.specularMap?p=c.specularMap:c.displacementMap?p=c.displacementMap:c.normalMap?
+p=c.normalMap:c.bumpMap?p=c.bumpMap:c.roughnessMap?p=c.roughnessMap:c.metalnessMap?p=c.metalnessMap:c.alphaMap?p=c.alphaMap:c.emissiveMap&&(p=c.emissiveMap);void 0!==p&&(p instanceof THREE.WebGLRenderTarget&&(p=p.texture),b=p.offset,p=p.repeat,f.offsetRepeat.value.set(b.x,b.y,p.x,p.y));f.envMap.value=c.envMap;f.flipEnvMap.value=c.envMap instanceof THREE.WebGLRenderTargetCube?1:-1;f.reflectivity.value=c.reflectivity;f.refractionRatio.value=c.refractionRatio}c instanceof THREE.LineBasicMaterial?(f.diffuse.value=
+c.color,f.opacity.value=c.opacity):c instanceof THREE.LineDashedMaterial?(f.diffuse.value=c.color,f.opacity.value=c.opacity,f.dashSize.value=c.dashSize,f.totalSize.value=c.dashSize+c.gapSize,f.scale.value=c.scale):c instanceof THREE.PointsMaterial?(f.diffuse.value=c.color,f.opacity.value=c.opacity,f.size.value=c.size*$,f.scale.value=K.clientHeight/2,f.map.value=c.map,null!==c.map&&(p=c.map.offset,c=c.map.repeat,f.offsetRepeat.value.set(p.x,p.y,c.x,c.y))):c instanceof THREE.MeshLambertMaterial?(c.lightMap&&
 (f.lightMap.value=c.lightMap,f.lightMapIntensity.value=c.lightMapIntensity),c.emissiveMap&&(f.emissiveMap.value=c.emissiveMap)):c instanceof THREE.MeshPhongMaterial?(f.specular.value=c.specular,f.shininess.value=Math.max(c.shininess,1E-4),c.lightMap&&(f.lightMap.value=c.lightMap,f.lightMapIntensity.value=c.lightMapIntensity),c.emissiveMap&&(f.emissiveMap.value=c.emissiveMap),c.bumpMap&&(f.bumpMap.value=c.bumpMap,f.bumpScale.value=c.bumpScale),c.normalMap&&(f.normalMap.value=c.normalMap,f.normalScale.value.copy(c.normalScale)),
 (f.lightMap.value=c.lightMap,f.lightMapIntensity.value=c.lightMapIntensity),c.emissiveMap&&(f.emissiveMap.value=c.emissiveMap)):c instanceof THREE.MeshPhongMaterial?(f.specular.value=c.specular,f.shininess.value=Math.max(c.shininess,1E-4),c.lightMap&&(f.lightMap.value=c.lightMap,f.lightMapIntensity.value=c.lightMapIntensity),c.emissiveMap&&(f.emissiveMap.value=c.emissiveMap),c.bumpMap&&(f.bumpMap.value=c.bumpMap,f.bumpScale.value=c.bumpScale),c.normalMap&&(f.normalMap.value=c.normalMap,f.normalScale.value.copy(c.normalScale)),
 c.displacementMap&&(f.displacementMap.value=c.displacementMap,f.displacementScale.value=c.displacementScale,f.displacementBias.value=c.displacementBias)):c instanceof THREE.MeshStandardMaterial?(f.roughness.value=c.roughness,f.metalness.value=c.metalness,c.roughnessMap&&(f.roughnessMap.value=c.roughnessMap),c.metalnessMap&&(f.metalnessMap.value=c.metalnessMap),c.lightMap&&(f.lightMap.value=c.lightMap,f.lightMapIntensity.value=c.lightMapIntensity),c.emissiveMap&&(f.emissiveMap.value=c.emissiveMap),
 c.displacementMap&&(f.displacementMap.value=c.displacementMap,f.displacementScale.value=c.displacementScale,f.displacementBias.value=c.displacementBias)):c instanceof THREE.MeshStandardMaterial?(f.roughness.value=c.roughness,f.metalness.value=c.metalness,c.roughnessMap&&(f.roughnessMap.value=c.roughnessMap),c.metalnessMap&&(f.metalnessMap.value=c.metalnessMap),c.lightMap&&(f.lightMap.value=c.lightMap,f.lightMapIntensity.value=c.lightMapIntensity),c.emissiveMap&&(f.emissiveMap.value=c.emissiveMap),
 c.bumpMap&&(f.bumpMap.value=c.bumpMap,f.bumpScale.value=c.bumpScale),c.normalMap&&(f.normalMap.value=c.normalMap,f.normalScale.value.copy(c.normalScale)),c.displacementMap&&(f.displacementMap.value=c.displacementMap,f.displacementScale.value=c.displacementScale,f.displacementBias.value=c.displacementBias),c.envMap&&(f.envMapIntensity.value=c.envMapIntensity)):c instanceof THREE.MeshDepthMaterial?(f.mNear.value=a.near,f.mFar.value=a.far,f.opacity.value=c.opacity):c instanceof THREE.MeshNormalMaterial&&
 c.bumpMap&&(f.bumpMap.value=c.bumpMap,f.bumpScale.value=c.bumpScale),c.normalMap&&(f.normalMap.value=c.normalMap,f.normalScale.value.copy(c.normalScale)),c.displacementMap&&(f.displacementMap.value=c.displacementMap,f.displacementScale.value=c.displacementScale,f.displacementBias.value=c.displacementBias),c.envMap&&(f.envMapIntensity.value=c.envMapIntensity)):c instanceof THREE.MeshDepthMaterial?(f.mNear.value=a.near,f.mFar.value=a.far,f.opacity.value=c.opacity):c instanceof THREE.MeshNormalMaterial&&
-(f.opacity.value=c.opacity);v(e.uniformsList)}s.uniformMatrix4fv(q.modelViewMatrix,!1,d.modelViewMatrix.elements);q.normalMatrix&&s.uniformMatrix3fv(q.normalMatrix,!1,d.normalMatrix.elements);void 0!==q.modelMatrix&&s.uniformMatrix4fv(q.modelMatrix,!1,d.matrixWorld.elements);if(!0===e.hasDynamicUniforms){e=e.uniformsList;c=[];n=0;for(b=e.length;n<b;n++)q=e[n][0],f=q.onUpdateCallback,void 0!==f&&(f.bind(q)(d,a),c.push(e[n]));v(c)}return g}function x(){var a=ta;a>=da.maxTextures&&console.warn("WebGLRenderer: trying to use "+
+(f.opacity.value=c.opacity);v(e.uniformsList)}s.uniformMatrix4fv(n.modelViewMatrix,!1,d.modelViewMatrix.elements);n.normalMatrix&&s.uniformMatrix3fv(n.normalMatrix,!1,d.normalMatrix.elements);void 0!==n.modelMatrix&&s.uniformMatrix4fv(n.modelMatrix,!1,d.matrixWorld.elements);if(!0===e.hasDynamicUniforms){e=e.uniformsList;c=[];p=0;for(b=e.length;p<b;p++)n=e[p][0],f=n.onUpdateCallback,void 0!==f&&(f.bind(n)(d,a),c.push(e[p]));v(c)}return g}function x(){var a=ta;a>=da.maxTextures&&console.warn("WebGLRenderer: trying to use "+
 a+" texture units while this GPU supports only "+da.maxTextures);ta+=1;return a}function v(a){for(var b,c,d=0,e=a.length;d<e;d++){var f=a[d][0];if(!1!==f.needsUpdate){var g=f.type;b=f.value;var h=a[d][1];switch(g){case "1i":s.uniform1i(h,b);break;case "1f":s.uniform1f(h,b);break;case "2f":s.uniform2f(h,b[0],b[1]);break;case "3f":s.uniform3f(h,b[0],b[1],b[2]);break;case "4f":s.uniform4f(h,b[0],b[1],b[2],b[3]);break;case "1iv":s.uniform1iv(h,b);break;case "3iv":s.uniform3iv(h,b);break;case "1fv":s.uniform1fv(h,
 a+" texture units while this GPU supports only "+da.maxTextures);ta+=1;return a}function v(a){for(var b,c,d=0,e=a.length;d<e;d++){var f=a[d][0];if(!1!==f.needsUpdate){var g=f.type;b=f.value;var h=a[d][1];switch(g){case "1i":s.uniform1i(h,b);break;case "1f":s.uniform1f(h,b);break;case "2f":s.uniform2f(h,b[0],b[1]);break;case "3f":s.uniform3f(h,b[0],b[1],b[2]);break;case "4f":s.uniform4f(h,b[0],b[1],b[2],b[3]);break;case "1iv":s.uniform1iv(h,b);break;case "3iv":s.uniform3iv(h,b);break;case "1fv":s.uniform1fv(h,
 b);break;case "2fv":s.uniform2fv(h,b);break;case "3fv":s.uniform3fv(h,b);break;case "4fv":s.uniform4fv(h,b);break;case "Matrix2fv":s.uniformMatrix2fv(h,!1,b);break;case "Matrix3fv":s.uniformMatrix3fv(h,!1,b);break;case "Matrix4fv":s.uniformMatrix4fv(h,!1,b);break;case "i":s.uniform1i(h,b);break;case "f":s.uniform1f(h,b);break;case "v2":s.uniform2f(h,b.x,b.y);break;case "v3":s.uniform3f(h,b.x,b.y,b.z);break;case "v4":s.uniform4f(h,b.x,b.y,b.z,b.w);break;case "c":s.uniform3f(h,b.r,b.g,b.b);break;case "sa":for(g=
 b);break;case "2fv":s.uniform2fv(h,b);break;case "3fv":s.uniform3fv(h,b);break;case "4fv":s.uniform4fv(h,b);break;case "Matrix2fv":s.uniformMatrix2fv(h,!1,b);break;case "Matrix3fv":s.uniformMatrix3fv(h,!1,b);break;case "Matrix4fv":s.uniformMatrix4fv(h,!1,b);break;case "i":s.uniform1i(h,b);break;case "f":s.uniform1f(h,b);break;case "v2":s.uniform2f(h,b.x,b.y);break;case "v3":s.uniform3f(h,b.x,b.y,b.z);break;case "v4":s.uniform4f(h,b.x,b.y,b.z,b.w);break;case "c":s.uniform3f(h,b.r,b.g,b.b);break;case "sa":for(g=
 0;g<b.length;g++)for(var k in f.properties){var l=h[g][k];c=b[g][k];switch(f.properties[k].type){case "i":s.uniform1i(l,c);break;case "f":s.uniform1f(l,c);break;case "v2":s.uniform2f(l,c.x,c.y);break;case "v3":s.uniform3f(l,c.x,c.y,c.z);break;case "v4":s.uniform4f(l,c.x,c.y,c.z,c.w);break;case "c":s.uniform3f(l,c.r,c.g,c.b);break;case "m4":s.uniformMatrix4fv(l,!1,c.elements)}}break;case "iv1":s.uniform1iv(h,b);break;case "iv":s.uniform3iv(h,b);break;case "fv1":s.uniform1fv(h,b);break;case "fv":s.uniform3fv(h,
 0;g<b.length;g++)for(var k in f.properties){var l=h[g][k];c=b[g][k];switch(f.properties[k].type){case "i":s.uniform1i(l,c);break;case "f":s.uniform1f(l,c);break;case "v2":s.uniform2f(l,c.x,c.y);break;case "v3":s.uniform3f(l,c.x,c.y,c.z);break;case "v4":s.uniform4f(l,c.x,c.y,c.z,c.w);break;case "c":s.uniform3f(l,c.r,c.g,c.b);break;case "m4":s.uniformMatrix4fv(l,!1,c.elements)}}break;case "iv1":s.uniform1iv(h,b);break;case "iv":s.uniform3iv(h,b);break;case "fv1":s.uniform1fv(h,b);break;case "fv":s.uniform3fv(h,
@@ -613,8 +613,8 @@ z(b.magFilter)),s.texParameteri(a,s.TEXTURE_MIN_FILTER,z(b.minFilter))):(s.texPa
 b.minFilter!==THREE.NearestFilter&&b.minFilter!==THREE.LinearFilter&&console.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.",b));!(c=V.get("EXT_texture_filter_anisotropic"))||b.type===THREE.FloatType&&null===V.get("OES_texture_float_linear")||b.type===THREE.HalfFloatType&&null===V.get("OES_texture_half_float_linear")||!(1<b.anisotropy||T.get(b).__currentAnisotropy)||(s.texParameterf(a,c.TEXTURE_MAX_ANISOTROPY_EXT,
 b.minFilter!==THREE.NearestFilter&&b.minFilter!==THREE.LinearFilter&&console.warn("THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.",b));!(c=V.get("EXT_texture_filter_anisotropic"))||b.type===THREE.FloatType&&null===V.get("OES_texture_float_linear")||b.type===THREE.HalfFloatType&&null===V.get("OES_texture_half_float_linear")||!(1<b.anisotropy||T.get(b).__currentAnisotropy)||(s.texParameterf(a,c.TEXTURE_MAX_ANISOTROPY_EXT,
 Math.min(b.anisotropy,Y.getMaxAnisotropy())),T.get(b).__currentAnisotropy=b.anisotropy)}function w(a,b){if(a.width>b||a.height>b){var c=b/Math.max(a.width,a.height),d=document.createElement("canvas");d.width=Math.floor(a.width*c);d.height=Math.floor(a.height*c);d.getContext("2d").drawImage(a,0,0,a.width,a.height,0,0,d.width,d.height);console.warn("THREE.WebGLRenderer: image is too big ("+a.width+"x"+a.height+"). Resized to "+d.width+"x"+d.height,a);return d}return a}function D(a){return THREE.Math.isPowerOfTwo(a.width)&&
 Math.min(b.anisotropy,Y.getMaxAnisotropy())),T.get(b).__currentAnisotropy=b.anisotropy)}function w(a,b){if(a.width>b||a.height>b){var c=b/Math.max(a.width,a.height),d=document.createElement("canvas");d.width=Math.floor(a.width*c);d.height=Math.floor(a.height*c);d.getContext("2d").drawImage(a,0,0,a.width,a.height,0,0,d.width,d.height);console.warn("THREE.WebGLRenderer: image is too big ("+a.width+"x"+a.height+"). Resized to "+d.width+"x"+d.height,a);return d}return a}function D(a){return THREE.Math.isPowerOfTwo(a.width)&&
 THREE.Math.isPowerOfTwo(a.height)}function A(a,b){var c=T.get(a);if(6===a.image.length)if(0<a.version&&c.__version!==a.version){c.__image__webglTextureCube||(a.addEventListener("dispose",f),c.__image__webglTextureCube=s.createTexture(),ga.textures++);J.activeTexture(s.TEXTURE0+b);J.bindTexture(s.TEXTURE_CUBE_MAP,c.__image__webglTextureCube);s.pixelStorei(s.UNPACK_FLIP_Y_WEBGL,a.flipY);for(var d=a instanceof THREE.CompressedTexture,e=a.image[0]instanceof THREE.DataTexture,g=[],h=0;6>h;h++)g[h]=!Y.autoScaleCubemaps||
 THREE.Math.isPowerOfTwo(a.height)}function A(a,b){var c=T.get(a);if(6===a.image.length)if(0<a.version&&c.__version!==a.version){c.__image__webglTextureCube||(a.addEventListener("dispose",f),c.__image__webglTextureCube=s.createTexture(),ga.textures++);J.activeTexture(s.TEXTURE0+b);J.bindTexture(s.TEXTURE_CUBE_MAP,c.__image__webglTextureCube);s.pixelStorei(s.UNPACK_FLIP_Y_WEBGL,a.flipY);for(var d=a instanceof THREE.CompressedTexture,e=a.image[0]instanceof THREE.DataTexture,g=[],h=0;6>h;h++)g[h]=!Y.autoScaleCubemaps||
-d||e?e?a.image[h].image:a.image[h]:w(a.image[h],da.maxCubemapSize);var k=D(g[0]),l=z(a.format),m=z(a.type);C(s.TEXTURE_CUBE_MAP,a,k);for(h=0;6>h;h++)if(d)for(var q,n=g[h].mipmaps,p=0,r=n.length;p<r;p++)q=n[p],a.format!==THREE.RGBAFormat&&a.format!==THREE.RGBFormat?-1<J.getCompressedTextureFormats().indexOf(l)?J.compressedTexImage2D(s.TEXTURE_CUBE_MAP_POSITIVE_X+h,p,l,q.width,q.height,0,q.data):console.warn("THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setCubeTexture()"):
-J.texImage2D(s.TEXTURE_CUBE_MAP_POSITIVE_X+h,p,l,q.width,q.height,0,l,m,q.data);else e?J.texImage2D(s.TEXTURE_CUBE_MAP_POSITIVE_X+h,0,l,g[h].width,g[h].height,0,l,m,g[h].data):J.texImage2D(s.TEXTURE_CUBE_MAP_POSITIVE_X+h,0,l,l,m,g[h]);a.generateMipmaps&&k&&s.generateMipmap(s.TEXTURE_CUBE_MAP);c.__version=a.version;if(a.onUpdate)a.onUpdate(a)}else J.activeTexture(s.TEXTURE0+b),J.bindTexture(s.TEXTURE_CUBE_MAP,c.__image__webglTextureCube)}function y(a,b){J.activeTexture(s.TEXTURE0+b);J.bindTexture(s.TEXTURE_CUBE_MAP,
+d||e?e?a.image[h].image:a.image[h]:w(a.image[h],da.maxCubemapSize);var k=D(g[0]),l=z(a.format),m=z(a.type);C(s.TEXTURE_CUBE_MAP,a,k);for(h=0;6>h;h++)if(d)for(var n,p=g[h].mipmaps,q=0,r=p.length;q<r;q++)n=p[q],a.format!==THREE.RGBAFormat&&a.format!==THREE.RGBFormat?-1<J.getCompressedTextureFormats().indexOf(l)?J.compressedTexImage2D(s.TEXTURE_CUBE_MAP_POSITIVE_X+h,q,l,n.width,n.height,0,n.data):console.warn("THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setCubeTexture()"):
+J.texImage2D(s.TEXTURE_CUBE_MAP_POSITIVE_X+h,q,l,n.width,n.height,0,l,m,n.data);else e?J.texImage2D(s.TEXTURE_CUBE_MAP_POSITIVE_X+h,0,l,g[h].width,g[h].height,0,l,m,g[h].data):J.texImage2D(s.TEXTURE_CUBE_MAP_POSITIVE_X+h,0,l,l,m,g[h]);a.generateMipmaps&&k&&s.generateMipmap(s.TEXTURE_CUBE_MAP);c.__version=a.version;if(a.onUpdate)a.onUpdate(a)}else J.activeTexture(s.TEXTURE0+b),J.bindTexture(s.TEXTURE_CUBE_MAP,c.__image__webglTextureCube)}function y(a,b){J.activeTexture(s.TEXTURE0+b);J.bindTexture(s.TEXTURE_CUBE_MAP,
 T.get(a).__webglTexture)}function B(a,b,c,d){var e=z(b.texture.format),f=z(b.texture.type);J.texImage2D(d,0,e,b.width,b.height,0,e,f,null);s.bindFramebuffer(s.FRAMEBUFFER,a);s.framebufferTexture2D(s.FRAMEBUFFER,c,d,T.get(b.texture).__webglTexture,0);s.bindFramebuffer(s.FRAMEBUFFER,null)}function G(a,b){s.bindRenderbuffer(s.RENDERBUFFER,a);b.depthBuffer&&!b.stencilBuffer?(s.renderbufferStorage(s.RENDERBUFFER,s.DEPTH_COMPONENT16,b.width,b.height),s.framebufferRenderbuffer(s.FRAMEBUFFER,s.DEPTH_ATTACHMENT,
 T.get(a).__webglTexture)}function B(a,b,c,d){var e=z(b.texture.format),f=z(b.texture.type);J.texImage2D(d,0,e,b.width,b.height,0,e,f,null);s.bindFramebuffer(s.FRAMEBUFFER,a);s.framebufferTexture2D(s.FRAMEBUFFER,c,d,T.get(b.texture).__webglTexture,0);s.bindFramebuffer(s.FRAMEBUFFER,null)}function G(a,b){s.bindRenderbuffer(s.RENDERBUFFER,a);b.depthBuffer&&!b.stencilBuffer?(s.renderbufferStorage(s.RENDERBUFFER,s.DEPTH_COMPONENT16,b.width,b.height),s.framebufferRenderbuffer(s.FRAMEBUFFER,s.DEPTH_ATTACHMENT,
 s.RENDERBUFFER,a)):b.depthBuffer&&b.stencilBuffer?(s.renderbufferStorage(s.RENDERBUFFER,s.DEPTH_STENCIL,b.width,b.height),s.framebufferRenderbuffer(s.FRAMEBUFFER,s.DEPTH_STENCIL_ATTACHMENT,s.RENDERBUFFER,a)):s.renderbufferStorage(s.RENDERBUFFER,s.RGBA4,b.width,b.height);s.bindRenderbuffer(s.RENDERBUFFER,null)}function E(a){return a===THREE.NearestFilter||a===THREE.NearestMipMapNearestFilter||a===THREE.NearestMipMapLinearFilter?s.NEAREST:s.LINEAR}function z(a){var b;if(a===THREE.RepeatWrapping)return s.REPEAT;
 s.RENDERBUFFER,a)):b.depthBuffer&&b.stencilBuffer?(s.renderbufferStorage(s.RENDERBUFFER,s.DEPTH_STENCIL,b.width,b.height),s.framebufferRenderbuffer(s.FRAMEBUFFER,s.DEPTH_STENCIL_ATTACHMENT,s.RENDERBUFFER,a)):s.renderbufferStorage(s.RENDERBUFFER,s.RGBA4,b.width,b.height);s.bindRenderbuffer(s.RENDERBUFFER,null)}function E(a){return a===THREE.NearestFilter||a===THREE.NearestMipMapNearestFilter||a===THREE.NearestMipMapLinearFilter?s.NEAREST:s.LINEAR}function z(a){var b;if(a===THREE.RepeatWrapping)return s.REPEAT;
 if(a===THREE.ClampToEdgeWrapping)return s.CLAMP_TO_EDGE;if(a===THREE.MirroredRepeatWrapping)return s.MIRRORED_REPEAT;if(a===THREE.NearestFilter)return s.NEAREST;if(a===THREE.NearestMipMapNearestFilter)return s.NEAREST_MIPMAP_NEAREST;if(a===THREE.NearestMipMapLinearFilter)return s.NEAREST_MIPMAP_LINEAR;if(a===THREE.LinearFilter)return s.LINEAR;if(a===THREE.LinearMipMapNearestFilter)return s.LINEAR_MIPMAP_NEAREST;if(a===THREE.LinearMipMapLinearFilter)return s.LINEAR_MIPMAP_LINEAR;if(a===THREE.UnsignedByteType)return s.UNSIGNED_BYTE;
 if(a===THREE.ClampToEdgeWrapping)return s.CLAMP_TO_EDGE;if(a===THREE.MirroredRepeatWrapping)return s.MIRRORED_REPEAT;if(a===THREE.NearestFilter)return s.NEAREST;if(a===THREE.NearestMipMapNearestFilter)return s.NEAREST_MIPMAP_NEAREST;if(a===THREE.NearestMipMapLinearFilter)return s.NEAREST_MIPMAP_LINEAR;if(a===THREE.LinearFilter)return s.LINEAR;if(a===THREE.LinearMipMapNearestFilter)return s.LINEAR_MIPMAP_NEAREST;if(a===THREE.LinearMipMapLinearFilter)return s.LINEAR_MIPMAP_LINEAR;if(a===THREE.UnsignedByteType)return s.UNSIGNED_BYTE;
@@ -634,13 +634,13 @@ this.setClearAlpha=function(a){fa=a;b(aa.r,aa.g,aa.b,fa)};this.clear=function(a,
 e,!1)};this.renderBufferImmediate=function(a,b,c){J.initAttributes();var d=T.get(a);a.hasPositions&&!d.position&&(d.position=s.createBuffer());a.hasNormals&&!d.normal&&(d.normal=s.createBuffer());a.hasUvs&&!d.uv&&(d.uv=s.createBuffer());a.hasColors&&!d.color&&(d.color=s.createBuffer());b=b.getAttributes();a.hasPositions&&(s.bindBuffer(s.ARRAY_BUFFER,d.position),s.bufferData(s.ARRAY_BUFFER,a.positionArray,s.DYNAMIC_DRAW),J.enableAttribute(b.position),s.vertexAttribPointer(b.position,3,s.FLOAT,!1,0,
 e,!1)};this.renderBufferImmediate=function(a,b,c){J.initAttributes();var d=T.get(a);a.hasPositions&&!d.position&&(d.position=s.createBuffer());a.hasNormals&&!d.normal&&(d.normal=s.createBuffer());a.hasUvs&&!d.uv&&(d.uv=s.createBuffer());a.hasColors&&!d.color&&(d.color=s.createBuffer());b=b.getAttributes();a.hasPositions&&(s.bindBuffer(s.ARRAY_BUFFER,d.position),s.bufferData(s.ARRAY_BUFFER,a.positionArray,s.DYNAMIC_DRAW),J.enableAttribute(b.position),s.vertexAttribPointer(b.position,3,s.FLOAT,!1,0,
 0));if(a.hasNormals){s.bindBuffer(s.ARRAY_BUFFER,d.normal);if("MeshPhongMaterial"!==c.type&&"MeshStandardMaterial"!==c.type&&c.shading===THREE.FlatShading)for(var e=0,f=3*a.count;e<f;e+=9){var g=a.normalArray,h=(g[e+0]+g[e+3]+g[e+6])/3,k=(g[e+1]+g[e+4]+g[e+7])/3,l=(g[e+2]+g[e+5]+g[e+8])/3;g[e+0]=h;g[e+1]=k;g[e+2]=l;g[e+3]=h;g[e+4]=k;g[e+5]=l;g[e+6]=h;g[e+7]=k;g[e+8]=l}s.bufferData(s.ARRAY_BUFFER,a.normalArray,s.DYNAMIC_DRAW);J.enableAttribute(b.normal);s.vertexAttribPointer(b.normal,3,s.FLOAT,!1,
 0));if(a.hasNormals){s.bindBuffer(s.ARRAY_BUFFER,d.normal);if("MeshPhongMaterial"!==c.type&&"MeshStandardMaterial"!==c.type&&c.shading===THREE.FlatShading)for(var e=0,f=3*a.count;e<f;e+=9){var g=a.normalArray,h=(g[e+0]+g[e+3]+g[e+6])/3,k=(g[e+1]+g[e+4]+g[e+7])/3,l=(g[e+2]+g[e+5]+g[e+8])/3;g[e+0]=h;g[e+1]=k;g[e+2]=l;g[e+3]=h;g[e+4]=k;g[e+5]=l;g[e+6]=h;g[e+7]=k;g[e+8]=l}s.bufferData(s.ARRAY_BUFFER,a.normalArray,s.DYNAMIC_DRAW);J.enableAttribute(b.normal);s.vertexAttribPointer(b.normal,3,s.FLOAT,!1,
 0,0)}a.hasUvs&&c.map&&(s.bindBuffer(s.ARRAY_BUFFER,d.uv),s.bufferData(s.ARRAY_BUFFER,a.uvArray,s.DYNAMIC_DRAW),J.enableAttribute(b.uv),s.vertexAttribPointer(b.uv,2,s.FLOAT,!1,0,0));a.hasColors&&c.vertexColors!==THREE.NoColors&&(s.bindBuffer(s.ARRAY_BUFFER,d.color),s.bufferData(s.ARRAY_BUFFER,a.colorArray,s.DYNAMIC_DRAW),J.enableAttribute(b.color),s.vertexAttribPointer(b.color,3,s.FLOAT,!1,0,0));J.disableUnusedAttributes();s.drawArrays(s.TRIANGLES,0,a.count);a.count=0};this.renderBufferDirect=function(a,
 0,0)}a.hasUvs&&c.map&&(s.bindBuffer(s.ARRAY_BUFFER,d.uv),s.bufferData(s.ARRAY_BUFFER,a.uvArray,s.DYNAMIC_DRAW),J.enableAttribute(b.uv),s.vertexAttribPointer(b.uv,2,s.FLOAT,!1,0,0));a.hasColors&&c.vertexColors!==THREE.NoColors&&(s.bindBuffer(s.ARRAY_BUFFER,d.color),s.bufferData(s.ARRAY_BUFFER,a.colorArray,s.DYNAMIC_DRAW),J.enableAttribute(b.color),s.vertexAttribPointer(b.color,3,s.FLOAT,!1,0,0));J.disableUnusedAttributes();s.drawArrays(s.TRIANGLES,0,a.count);a.count=0};this.renderBufferDirect=function(a,
-b,c,d,e,f){t(d);var g=u(a,b,d,e),h=!1;a=c.id+"_"+g.id+"_"+d.wireframe;a!==na&&(na=a,h=!0);b=e.morphTargetInfluences;if(void 0!==b){a=[];for(var k=0,h=b.length;k<h;k++){var m=b[k];a.push([m,k])}a.sort(l);8<a.length&&(a.length=8);for(var q=c.morphAttributes,k=0,h=a.length;k<h;k++)m=a[k],Z[k]=m[0],0!==m[0]?(b=m[1],!0===d.morphTargets&&q.position&&c.addAttribute("morphTarget"+k,q.position[b]),!0===d.morphNormals&&q.normal&&c.addAttribute("morphNormal"+k,q.normal[b])):(!0===d.morphTargets&&c.removeAttribute("morphTarget"+
-k),!0===d.morphNormals&&c.removeAttribute("morphNormal"+k));a=g.getUniforms();null!==a.morphTargetInfluences&&s.uniform1fv(a.morphTargetInfluences,Z);h=!0}b=c.index;k=c.attributes.position;!0===d.wireframe&&(b=pa.getWireframeAttribute(c));null!==b?(a=Ea,a.setIndex(b)):a=Da;if(h){a:{var h=void 0,n;if(c instanceof THREE.InstancedBufferGeometry&&(n=V.get("ANGLE_instanced_arrays"),null===n)){console.error("THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.");
-break a}void 0===h&&(h=0);J.initAttributes();var m=c.attributes,g=g.getAttributes(),q=d.defaultAttributeValues,p;for(p in g){var r=g[p];if(0<=r){var v=m[p];if(void 0!==v){var x=v.itemSize,w=pa.getAttributeBuffer(v);if(v instanceof THREE.InterleavedBufferAttribute){var C=v.data,y=C.stride,v=v.offset;C instanceof THREE.InstancedInterleavedBuffer?(J.enableAttributeAndDivisor(r,C.meshPerAttribute,n),void 0===c.maxInstancedCount&&(c.maxInstancedCount=C.meshPerAttribute*C.count)):J.enableAttribute(r);s.bindBuffer(s.ARRAY_BUFFER,
-w);s.vertexAttribPointer(r,x,s.FLOAT,!1,y*C.array.BYTES_PER_ELEMENT,(h*y+v)*C.array.BYTES_PER_ELEMENT)}else v instanceof THREE.InstancedBufferAttribute?(J.enableAttributeAndDivisor(r,v.meshPerAttribute,n),void 0===c.maxInstancedCount&&(c.maxInstancedCount=v.meshPerAttribute*v.count)):J.enableAttribute(r),s.bindBuffer(s.ARRAY_BUFFER,w),s.vertexAttribPointer(r,x,s.FLOAT,!1,0,h*x*4)}else if(void 0!==q&&(x=q[p],void 0!==x))switch(x.length){case 2:s.vertexAttrib2fv(r,x);break;case 3:s.vertexAttrib3fv(r,
-x);break;case 4:s.vertexAttrib4fv(r,x);break;default:s.vertexAttrib1fv(r,x)}}}J.disableUnusedAttributes()}null!==b&&s.bindBuffer(s.ELEMENT_ARRAY_BUFFER,pa.getAttributeBuffer(b))}n=Infinity;null!==b?n=b.count:void 0!==k&&(n=k.count);p=c.drawRange.start;b=c.drawRange.count;k=null!==f?f.start:0;h=null!==f?f.count:Infinity;f=Math.max(0,p,k);n=Math.min(0+n,p+b,k+h)-1;n=Math.max(0,n-f+1);if(e instanceof THREE.Mesh)if(!0===d.wireframe)J.setLineWidth(d.wireframeLinewidth*(null===ia?$:1)),a.setMode(s.LINES);
+b,c,d,e,f){t(d);var g=u(a,b,d,e),h=!1;a=c.id+"_"+g.id+"_"+d.wireframe;a!==na&&(na=a,h=!0);b=e.morphTargetInfluences;if(void 0!==b){a=[];for(var k=0,h=b.length;k<h;k++){var m=b[k];a.push([m,k])}a.sort(l);8<a.length&&(a.length=8);for(var n=c.morphAttributes,k=0,h=a.length;k<h;k++)m=a[k],Z[k]=m[0],0!==m[0]?(b=m[1],!0===d.morphTargets&&n.position&&c.addAttribute("morphTarget"+k,n.position[b]),!0===d.morphNormals&&n.normal&&c.addAttribute("morphNormal"+k,n.normal[b])):(!0===d.morphTargets&&c.removeAttribute("morphTarget"+
+k),!0===d.morphNormals&&c.removeAttribute("morphNormal"+k));a=g.getUniforms();null!==a.morphTargetInfluences&&s.uniform1fv(a.morphTargetInfluences,Z);h=!0}b=c.index;k=c.attributes.position;!0===d.wireframe&&(b=pa.getWireframeAttribute(c));null!==b?(a=Ea,a.setIndex(b)):a=Da;if(h){a:{var h=void 0,p;if(c instanceof THREE.InstancedBufferGeometry&&(p=V.get("ANGLE_instanced_arrays"),null===p)){console.error("THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.");
+break a}void 0===h&&(h=0);J.initAttributes();var m=c.attributes,g=g.getAttributes(),n=d.defaultAttributeValues,q;for(q in g){var r=g[q];if(0<=r){var v=m[q];if(void 0!==v){var x=v.itemSize,w=pa.getAttributeBuffer(v);if(v instanceof THREE.InterleavedBufferAttribute){var C=v.data,y=C.stride,v=v.offset;C instanceof THREE.InstancedInterleavedBuffer?(J.enableAttributeAndDivisor(r,C.meshPerAttribute,p),void 0===c.maxInstancedCount&&(c.maxInstancedCount=C.meshPerAttribute*C.count)):J.enableAttribute(r);s.bindBuffer(s.ARRAY_BUFFER,
+w);s.vertexAttribPointer(r,x,s.FLOAT,!1,y*C.array.BYTES_PER_ELEMENT,(h*y+v)*C.array.BYTES_PER_ELEMENT)}else v instanceof THREE.InstancedBufferAttribute?(J.enableAttributeAndDivisor(r,v.meshPerAttribute,p),void 0===c.maxInstancedCount&&(c.maxInstancedCount=v.meshPerAttribute*v.count)):J.enableAttribute(r),s.bindBuffer(s.ARRAY_BUFFER,w),s.vertexAttribPointer(r,x,s.FLOAT,!1,0,h*x*4)}else if(void 0!==n&&(x=n[q],void 0!==x))switch(x.length){case 2:s.vertexAttrib2fv(r,x);break;case 3:s.vertexAttrib3fv(r,
+x);break;case 4:s.vertexAttrib4fv(r,x);break;default:s.vertexAttrib1fv(r,x)}}}J.disableUnusedAttributes()}null!==b&&s.bindBuffer(s.ELEMENT_ARRAY_BUFFER,pa.getAttributeBuffer(b))}p=Infinity;null!==b?p=b.count:void 0!==k&&(p=k.count);q=c.drawRange.start;b=c.drawRange.count;k=null!==f?f.start:0;h=null!==f?f.count:Infinity;f=Math.max(0,q,k);p=Math.min(0+p,q+b,k+h)-1;p=Math.max(0,p-f+1);if(e instanceof THREE.Mesh)if(!0===d.wireframe)J.setLineWidth(d.wireframeLinewidth*(null===ia?$:1)),a.setMode(s.LINES);
 else switch(e.drawMode){case THREE.TrianglesDrawMode:a.setMode(s.TRIANGLES);break;case THREE.TriangleStripDrawMode:a.setMode(s.TRIANGLE_STRIP);break;case THREE.TriangleFanDrawMode:a.setMode(s.TRIANGLE_FAN)}else e instanceof THREE.Line?(d=d.linewidth,void 0===d&&(d=1),J.setLineWidth(d*(null===ia?$:1)),e instanceof THREE.LineSegments?a.setMode(s.LINES):a.setMode(s.LINE_STRIP)):e instanceof THREE.Points&&a.setMode(s.POINTS);c instanceof THREE.InstancedBufferGeometry&&0<c.maxInstancedCount?a.renderInstances(c,
 else switch(e.drawMode){case THREE.TrianglesDrawMode:a.setMode(s.TRIANGLES);break;case THREE.TriangleStripDrawMode:a.setMode(s.TRIANGLE_STRIP);break;case THREE.TriangleFanDrawMode:a.setMode(s.TRIANGLE_FAN)}else e instanceof THREE.Line?(d=d.linewidth,void 0===d&&(d=1),J.setLineWidth(d*(null===ia?$:1)),e instanceof THREE.LineSegments?a.setMode(s.LINES):a.setMode(s.LINE_STRIP)):e instanceof THREE.Points&&a.setMode(s.POINTS);c instanceof THREE.InstancedBufferGeometry&&0<c.maxInstancedCount?a.renderInstances(c,
-f,n):a.render(f,n)};this.render=function(a,b,c,d){if(!1===b instanceof THREE.Camera)console.error("THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.");else{var e=a.fog;na="";ra=-1;la=null;!0===a.autoUpdate&&a.updateMatrixWorld();null===b.parent&&b.updateMatrixWorld();b.matrixWorldInverse.getInverse(b.matrixWorld);sa.multiplyMatrices(b.projectionMatrix,b.matrixWorldInverse);ya.setFromMatrix(sa);R.length=0;W=F=-1;ca.length=0;ha.length=0;q(a,b);I.length=F+1;U.length=W+1;!0===Y.sortObjects&&
+f,p):a.render(f,p)};this.render=function(a,b,c,d){if(!1===b instanceof THREE.Camera)console.error("THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.");else{var e=a.fog;na="";ra=-1;la=null;!0===a.autoUpdate&&a.updateMatrixWorld();null===b.parent&&b.updateMatrixWorld();b.matrixWorldInverse.getInverse(b.matrixWorld);sa.multiplyMatrices(b.projectionMatrix,b.matrixWorldInverse);ya.setFromMatrix(sa);R.length=0;W=F=-1;ca.length=0;ha.length=0;q(a,b);I.length=F+1;U.length=W+1;!0===Y.sortObjects&&
 (I.sort(n),U.sort(p));var f=R,g,h,k,l=0,m=0,t=0,v,u,x,w=b.matrixWorldInverse,C=0,y=0,Z=0,A=0,B=0;g=S.shadowsPointLight=0;for(h=f.length;g<h;g++)if(k=f[g],v=k.color,u=k.intensity,x=k.distance,k instanceof THREE.AmbientLight)l+=v.r*u,m+=v.g*u,t+=v.b*u;else if(k instanceof THREE.DirectionalLight){var z=wa.get(k);z.color.copy(k.color).multiplyScalar(k.intensity);z.direction.setFromMatrixPosition(k.matrixWorld);X.setFromMatrixPosition(k.target.matrixWorld);z.direction.sub(X);z.direction.transformDirection(w);
 (I.sort(n),U.sort(p));var f=R,g,h,k,l=0,m=0,t=0,v,u,x,w=b.matrixWorldInverse,C=0,y=0,Z=0,A=0,B=0;g=S.shadowsPointLight=0;for(h=f.length;g<h;g++)if(k=f[g],v=k.color,u=k.intensity,x=k.distance,k instanceof THREE.AmbientLight)l+=v.r*u,m+=v.g*u,t+=v.b*u;else if(k instanceof THREE.DirectionalLight){var z=wa.get(k);z.color.copy(k.color).multiplyScalar(k.intensity);z.direction.setFromMatrixPosition(k.matrixWorld);X.setFromMatrixPosition(k.target.matrixWorld);z.direction.sub(X);z.direction.transformDirection(w);
 if(z.shadow=k.castShadow)z.shadowBias=k.shadow.bias,z.shadowRadius=k.shadow.radius,z.shadowMapSize=k.shadow.mapSize,S.shadows[B++]=k;S.directionalShadowMap[C]=k.shadow.map;S.directionalShadowMatrix[C]=k.shadow.matrix;S.directional[C++]=z}else if(k instanceof THREE.SpotLight){z=wa.get(k);z.position.setFromMatrixPosition(k.matrixWorld);z.position.applyMatrix4(w);z.color.copy(v).multiplyScalar(u);z.distance=x;z.direction.setFromMatrixPosition(k.matrixWorld);X.setFromMatrixPosition(k.target.matrixWorld);
 if(z.shadow=k.castShadow)z.shadowBias=k.shadow.bias,z.shadowRadius=k.shadow.radius,z.shadowMapSize=k.shadow.mapSize,S.shadows[B++]=k;S.directionalShadowMap[C]=k.shadow.map;S.directionalShadowMatrix[C]=k.shadow.matrix;S.directional[C++]=z}else if(k instanceof THREE.SpotLight){z=wa.get(k);z.position.setFromMatrixPosition(k.matrixWorld);z.position.applyMatrix4(w);z.color.copy(v).multiplyScalar(u);z.distance=x;z.direction.setFromMatrixPosition(k.matrixWorld);X.setFromMatrixPosition(k.target.matrixWorld);
 z.direction.sub(X);z.direction.transformDirection(w);z.coneCos=Math.cos(k.angle);z.penumbraCos=Math.cos(k.angle*(1-k.penumbra));z.decay=0===k.distance?0:k.decay;if(z.shadow=k.castShadow)z.shadowBias=k.shadow.bias,z.shadowRadius=k.shadow.radius,z.shadowMapSize=k.shadow.mapSize,S.shadows[B++]=k;S.spotShadowMap[Z]=k.shadow.map;S.spotShadowMatrix[Z]=k.shadow.matrix;S.spot[Z++]=z}else if(k instanceof THREE.PointLight){z=wa.get(k);z.position.setFromMatrixPosition(k.matrixWorld);z.position.applyMatrix4(w);
 z.direction.sub(X);z.direction.transformDirection(w);z.coneCos=Math.cos(k.angle);z.penumbraCos=Math.cos(k.angle*(1-k.penumbra));z.decay=0===k.distance?0:k.decay;if(z.shadow=k.castShadow)z.shadowBias=k.shadow.bias,z.shadowRadius=k.shadow.radius,z.shadowMapSize=k.shadow.mapSize,S.shadows[B++]=k;S.spotShadowMap[Z]=k.shadow.map;S.spotShadowMatrix[Z]=k.shadow.matrix;S.spot[Z++]=z}else if(k instanceof THREE.PointLight){z=wa.get(k);z.position.setFromMatrixPosition(k.matrixWorld);z.position.applyMatrix4(w);
@@ -696,13 +696,13 @@ x+v);C=THREE.WebGLShader(t,t.FRAGMENT_SHADER,C);t.attachShader(E,v);t.attachShad
 "gl.getProgramInfoLog",r,w,D);else if(""!==r)console.warn("THREE.WebGLProgram: gl.getProgramInfoLog()",r);else if(""===w||""===D)y=!1;y&&(this.diagnostics={runnable:A,material:q,programLog:r,vertexShader:{log:w,prefix:x},fragmentShader:{log:D,prefix:p}});t.deleteShader(v);t.deleteShader(C);var z;this.getUniforms=function(){if(void 0===z){for(var a={},b=t.getProgramParameter(E,t.ACTIVE_UNIFORMS),c=0;c<b;c++){var d=t.getActiveUniform(E,c).name,e=t.getUniformLocation(E,d),f=k.exec(d);if(f){var d=f[1],
 "gl.getProgramInfoLog",r,w,D);else if(""!==r)console.warn("THREE.WebGLProgram: gl.getProgramInfoLog()",r);else if(""===w||""===D)y=!1;y&&(this.diagnostics={runnable:A,material:q,programLog:r,vertexShader:{log:w,prefix:x},fragmentShader:{log:D,prefix:p}});t.deleteShader(v);t.deleteShader(C);var z;this.getUniforms=function(){if(void 0===z){for(var a={},b=t.getProgramParameter(E,t.ACTIVE_UNIFORMS),c=0;c<b;c++){var d=t.getActiveUniform(E,c).name,e=t.getUniformLocation(E,d),f=k.exec(d);if(f){var d=f[1],
 f=f[2],g=a[d];g||(g=a[d]={});g[f]=e}else if(f=l.exec(d)){var g=f[1],d=f[2],f=f[3],h=a[g];h||(h=a[g]=[]);(g=h[d])||(g=h[d]={});g[f]=e}else(f=n.exec(d))?(g=f[1],a[g]=e):a[d]=e}z=a}return z};var K;this.getAttributes=function(){if(void 0===K){for(var a={},b=t.getProgramParameter(E,t.ACTIVE_ATTRIBUTES),c=0;c<b;c++){var d=t.getActiveAttrib(E,c).name;a[d]=t.getAttribLocation(E,d)}K=a}return K};this.destroy=function(){t.deleteProgram(E);this.program=void 0};Object.defineProperties(this,{uniforms:{get:function(){console.warn("THREE.WebGLProgram: .uniforms is now .getUniforms().");
 f=f[2],g=a[d];g||(g=a[d]={});g[f]=e}else if(f=l.exec(d)){var g=f[1],d=f[2],f=f[3],h=a[g];h||(h=a[g]=[]);(g=h[d])||(g=h[d]={});g[f]=e}else(f=n.exec(d))?(g=f[1],a[g]=e):a[d]=e}z=a}return z};var K;this.getAttributes=function(){if(void 0===K){for(var a={},b=t.getProgramParameter(E,t.ACTIVE_ATTRIBUTES),c=0;c<b;c++){var d=t.getActiveAttrib(E,c).name;a[d]=t.getAttribLocation(E,d)}K=a}return K};this.destroy=function(){t.deleteProgram(E);this.program=void 0};Object.defineProperties(this,{uniforms:{get:function(){console.warn("THREE.WebGLProgram: .uniforms is now .getUniforms().");
 return this.getUniforms()}},attributes:{get:function(){console.warn("THREE.WebGLProgram: .attributes is now .getAttributes().");return this.getAttributes()}}});this.id=h++;this.code=m;this.usedTimes=1;this.program=E;this.vertexShader=v;this.fragmentShader=C;return this}}();
 return this.getUniforms()}},attributes:{get:function(){console.warn("THREE.WebGLProgram: .attributes is now .getAttributes().");return this.getAttributes()}}});this.id=h++;this.code=m;this.usedTimes=1;this.program=E;this.vertexShader=v;this.fragmentShader=C;return this}}();
-THREE.WebGLPrograms=function(a,b){function c(b){if(!b)return!1;if(b instanceof THREE.Texture)b=b.encoding;else if(b instanceof THREE.WebGLRenderTarget)b=b.texture.encoding;else throw Error("can not determine texture encoding from map: "+b);b===THREE.LinearEncoding&&a.gammaInput&&(b=THREE.GammaEncoding);return b}var d=[],e={MeshDepthMaterial:"depth",MeshNormalMaterial:"normal",MeshBasicMaterial:"basic",MeshLambertMaterial:"lambert",MeshPhongMaterial:"phong",MeshStandardMaterial:"standard",LineBasicMaterial:"basic",
-LineDashedMaterial:"dashed",PointsMaterial:"points"},f="precision supportsVertexTextures map mapEncoding envMap envMapMode envMapEncoding lightMap aoMap emissiveMap emissiveMapEncoding bumpMap normalMap displacementMap specularMap roughnessMap metalnessMap alphaMap combine vertexColors fog useFog fogExp flatShading sizeAttenuation logarithmicDepthBuffer skinning maxBones useVertexTexture morphTargets morphNormals maxMorphTargets maxMorphNormals numDirLights numPointLights numSpotLights numHemiLights shadowMapEnabled pointLightShadows shadowMapType alphaTest doubleSided flipSided".split(" ");
-this.getParameters=function(d,f,k,l){var n=e[d.type],p;b.floatVertexTextures&&l&&l.skeleton&&l.skeleton.useVertexTexture?p=1024:(p=Math.floor((b.maxVertexUniforms-20)/4),void 0!==l&&l instanceof THREE.SkinnedMesh&&(p=Math.min(l.skeleton.bones.length,p),p<l.skeleton.bones.length&&console.warn("WebGLRenderer: too many bones - "+l.skeleton.bones.length+", this GPU supports just "+p+" (try OpenGL instead of ANGLE)")));var m=a.getPrecision();null!==d.precision&&(m=b.getMaxPrecision(d.precision),m!==d.precision&&
-console.warn("THREE.WebGLProgram.getParameters:",d.precision,"not supported, using",m,"instead."));return{shaderID:n,precision:m,supportsVertexTextures:b.vertexTextures,map:!!d.map,mapEncoding:c(d.map),envMap:!!d.envMap,envMapMode:d.envMap&&d.envMap.mapping,envMapEncoding:c(d.envMap),lightMap:!!d.lightMap,aoMap:!!d.aoMap,emissiveMap:!!d.emissiveMap,emissiveMapEncoding:c(d.emissiveMap),bumpMap:!!d.bumpMap,normalMap:!!d.normalMap,displacementMap:!!d.displacementMap,roughnessMap:!!d.roughnessMap,metalnessMap:!!d.metalnessMap,
-specularMap:!!d.specularMap,alphaMap:!!d.alphaMap,combine:d.combine,vertexColors:d.vertexColors,fog:k,useFog:d.fog,fogExp:k instanceof THREE.FogExp2,flatShading:d.shading===THREE.FlatShading,sizeAttenuation:d.sizeAttenuation,logarithmicDepthBuffer:b.logarithmicDepthBuffer,skinning:d.skinning,maxBones:p,useVertexTexture:b.floatVertexTextures&&l&&l.skeleton&&l.skeleton.useVertexTexture,morphTargets:d.morphTargets,morphNormals:d.morphNormals,maxMorphTargets:a.maxMorphTargets,maxMorphNormals:a.maxMorphNormals,
-numDirLights:f.directional.length,numPointLights:f.point.length,numSpotLights:f.spot.length,numHemiLights:f.hemi.length,pointLightShadows:f.shadowsPointLight,shadowMapEnabled:a.shadowMap.enabled&&l.receiveShadow&&0<f.shadows.length,shadowMapType:a.shadowMap.type,alphaTest:d.alphaTest,doubleSided:d.side===THREE.DoubleSide,flipSided:d.side===THREE.BackSide}};this.getProgramCode=function(a,b){var c=[];b.shaderID?c.push(b.shaderID):(c.push(a.fragmentShader),c.push(a.vertexShader));if(void 0!==a.defines)for(var d in a.defines)c.push(d),
-c.push(a.defines[d]);for(d=0;d<f.length;d++){var e=f[d];c.push(e);c.push(b[e])}return c.join()};this.acquireProgram=function(b,c,e){for(var f,n=0,p=d.length;n<p;n++){var m=d[n];if(m.code===e){f=m;++f.usedTimes;break}}void 0===f&&(f=new THREE.WebGLProgram(a,e,b,c),d.push(f));return f};this.releaseProgram=function(a){if(0===--a.usedTimes){var b=d.indexOf(a);d[b]=d[d.length-1];d.pop();a.destroy()}};this.programs=d};
+THREE.WebGLPrograms=function(a,b){function c(a){if(b.floatVertexTextures&&a&&a.skeleton&&a.skeleton.useVertexTexture)return 1024;var c=Math.floor((b.maxVertexUniforms-20)/4);void 0!==a&&a instanceof THREE.SkinnedMesh&&(c=Math.min(a.skeleton.bones.length,c),c<a.skeleton.bones.length&&console.warn("WebGLRenderer: too many bones - "+a.skeleton.bones.length+", this GPU supports just "+c+" (try OpenGL instead of ANGLE)"));return c}var d=[],e={MeshDepthMaterial:"depth",MeshNormalMaterial:"normal",MeshBasicMaterial:"basic",
+MeshLambertMaterial:"lambert",MeshPhongMaterial:"phong",MeshStandardMaterial:"standard",LineBasicMaterial:"basic",LineDashedMaterial:"dashed",PointsMaterial:"points"},f="precision supportsVertexTextures map mapEncoding envMap envMapMode envMapEncoding lightMap aoMap emissiveMap emissiveMapEncoding bumpMap normalMap displacementMap specularMap roughnessMap metalnessMap alphaMap combine vertexColors fog useFog fogExp flatShading sizeAttenuation logarithmicDepthBuffer skinning maxBones useVertexTexture morphTargets morphNormals maxMorphTargets maxMorphNormals numDirLights numPointLights numSpotLights numHemiLights shadowMapEnabled pointLightShadows shadowMapType alphaTest doubleSided flipSided".split(" ");
+this.getParameters=function(d,f,k,l){var n=e[d.type],p=c(l),m=a.getPrecision();null!==d.precision&&(m=b.getMaxPrecision(d.precision),m!==d.precision&&console.warn("THREE.WebGLProgram.getParameters:",d.precision,"not supported, using",m,"instead."));var q=function(b){if(!b)return!1;if(void 0!==b.encoding)b=b.encoding;else if(void 0!==b.texture)b=b.texture.encoding;else throw Error("can not determine texture encoding from map: "+b);b===THREE.LinearEncoding&&a.gammaInput&&(b=THREE.GammaEncoding);return b};
+return{shaderID:n,precision:m,supportsVertexTextures:b.vertexTextures,map:!!d.map,mapEncoding:q(d.map),envMap:!!d.envMap,envMapMode:d.envMap&&d.envMap.mapping,envMapEncoding:q(d.envMap),lightMap:!!d.lightMap,aoMap:!!d.aoMap,emissiveMap:!!d.emissiveMap,emissiveMapEncoding:q(d.emissiveMap),bumpMap:!!d.bumpMap,normalMap:!!d.normalMap,displacementMap:!!d.displacementMap,roughnessMap:!!d.roughnessMap,metalnessMap:!!d.metalnessMap,specularMap:!!d.specularMap,alphaMap:!!d.alphaMap,combine:d.combine,vertexColors:d.vertexColors,
+fog:k,useFog:d.fog,fogExp:k instanceof THREE.FogExp2,flatShading:d.shading===THREE.FlatShading,sizeAttenuation:d.sizeAttenuation,logarithmicDepthBuffer:b.logarithmicDepthBuffer,skinning:d.skinning,maxBones:p,useVertexTexture:b.floatVertexTextures&&l&&l.skeleton&&l.skeleton.useVertexTexture,morphTargets:d.morphTargets,morphNormals:d.morphNormals,maxMorphTargets:a.maxMorphTargets,maxMorphNormals:a.maxMorphNormals,numDirLights:f.directional.length,numPointLights:f.point.length,numSpotLights:f.spot.length,
+numHemiLights:f.hemi.length,pointLightShadows:f.shadowsPointLight,shadowMapEnabled:a.shadowMap.enabled&&l.receiveShadow&&0<f.shadows.length,shadowMapType:a.shadowMap.type,alphaTest:d.alphaTest,doubleSided:d.side===THREE.DoubleSide,flipSided:d.side===THREE.BackSide}};this.getProgramCode=function(a,b){var c=[];b.shaderID?c.push(b.shaderID):(c.push(a.fragmentShader),c.push(a.vertexShader));if(void 0!==a.defines)for(var d in a.defines)c.push(d),c.push(a.defines[d]);for(d=0;d<f.length;d++){var e=f[d];
+c.push(e);c.push(b[e])}return c.join()};this.acquireProgram=function(b,c,e){for(var f,n=0,p=d.length;n<p;n++){var m=d[n];if(m.code===e){f=m;++f.usedTimes;break}}void 0===f&&(f=new THREE.WebGLProgram(a,e,b,c),d.push(f));return f};this.releaseProgram=function(a){if(0===--a.usedTimes){var b=d.indexOf(a);d[b]=d[d.length-1];d.pop();a.destroy()}};this.programs=d};
 THREE.WebGLProperties=function(){var a={};this.get=function(b){b=b.uuid;var c=a[b];void 0===c&&(c={},a[b]=c);return c};this.delete=function(b){delete a[b.uuid]};this.clear=function(){a={}}};
 THREE.WebGLProperties=function(){var a={};this.get=function(b){b=b.uuid;var c=a[b];void 0===c&&(c={},a[b]=c);return c};this.delete=function(b){delete a[b.uuid]};this.clear=function(){a={}}};
 THREE.WebGLShader=function(){function a(a){a=a.split("\n");for(var c=0;c<a.length;c++)a[c]=c+1+": "+a[c];return a.join("\n")}return function(b,c,d){var e=b.createShader(c);b.shaderSource(e,d);b.compileShader(e);!1===b.getShaderParameter(e,b.COMPILE_STATUS)&&console.error("THREE.WebGLShader: Shader couldn't compile.");""!==b.getShaderInfoLog(e)&&console.warn("THREE.WebGLShader: gl.getShaderInfoLog()",c===b.VERTEX_SHADER?"vertex":"fragment",b.getShaderInfoLog(e),a(d));return e}}();
 THREE.WebGLShader=function(){function a(a){a=a.split("\n");for(var c=0;c<a.length;c++)a[c]=c+1+": "+a[c];return a.join("\n")}return function(b,c,d){var e=b.createShader(c);b.shaderSource(e,d);b.compileShader(e);!1===b.getShaderParameter(e,b.COMPILE_STATUS)&&console.error("THREE.WebGLShader: Shader couldn't compile.");""!==b.getShaderInfoLog(e)&&console.warn("THREE.WebGLShader: gl.getShaderInfoLog()",c===b.VERTEX_SHADER?"vertex":"fragment",b.getShaderInfoLog(e),a(d));return e}}();
 THREE.WebGLShadowMap=function(a,b,c){function d(a,b,c,d){var e=a.geometry,f=null,f=q,g=a.customDepthMaterial;c&&(f=r,g=a.customDistanceMaterial);g?f=g:(a=a instanceof THREE.SkinnedMesh&&b.skinning,g=0,void 0!==e.morphTargets&&0<e.morphTargets.length&&b.morphTargets&&(g|=1),a&&(g|=2),f=f[g]);f.visible=b.visible;f.wireframe=b.wireframe;f.wireframeLinewidth=b.wireframeLinewidth;c&&void 0!==f.uniforms.lightPos&&f.uniforms.lightPos.value.copy(d);return f}function e(a,b,c){if(!1!==a.visible){a.layers.test(b.layers)&&
 THREE.WebGLShadowMap=function(a,b,c){function d(a,b,c,d){var e=a.geometry,f=null,f=q,g=a.customDepthMaterial;c&&(f=r,g=a.customDistanceMaterial);g?f=g:(a=a instanceof THREE.SkinnedMesh&&b.skinning,g=0,void 0!==e.morphTargets&&0<e.morphTargets.length&&b.morphTargets&&(g|=1),a&&(g|=2),f=f[g]);f.visible=b.visible;f.wireframe=b.wireframe;f.wireframeLinewidth=b.wireframeLinewidth;c&&void 0!==f.uniforms.lightPos&&f.uniforms.lightPos.value.copy(d);return f}function e(a,b,c){if(!1!==a.visible){a.layers.test(b.layers)&&

+ 4 - 6
examples/js/ShaderSkin.js

@@ -247,11 +247,9 @@ THREE.ShaderSkin = {
 
 
 				"outgoingLight += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor * diffuse ) + totalSpecularLight;",
 				"outgoingLight += diffuseColor.xyz * ( totalDiffuseLight + ambientLightColor * diffuse ) + totalSpecularLight;",
 
 
-				THREE.ShaderChunk[ "linear_to_gamma_fragment" ],
-				THREE.ShaderChunk[ "fog_fragment" ],
-
-				"gl_FragColor = vec4( outgoingLight, diffuseColor.a );",	// TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects
+				"gl_FragColor = linearToOutputTexel( vec4( outgoingLight, diffuseColor.a ) );",	// TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects
 
 
+				THREE.ShaderChunk[ "fog_fragment" ],
 
 
 			"}"
 			"}"
 
 
@@ -550,10 +548,10 @@ THREE.ShaderSkin = {
 
 
 				"}",
 				"}",
 
 
-				THREE.ShaderChunk[ "fog_fragment" ],
-
 				"gl_FragColor = vec4( outgoingLight, diffuseColor.a );",	// TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects
 				"gl_FragColor = vec4( outgoingLight, diffuseColor.a );",	// TODO, this should be pre-multiplied to allow for bright highlights on very transparent objects
 
 
+				THREE.ShaderChunk[ "fog_fragment" ],
+
 			"}"
 			"}"
 
 
 		].join( "\n" ),
 		].join( "\n" ),

+ 6 - 3
src/Three.js

@@ -310,9 +310,12 @@ THREE.TriangleFanDrawMode = 2;
 
 
 THREE.LinearEncoding = 3000; // No encoding at all.
 THREE.LinearEncoding = 3000; // No encoding at all.
 THREE.sRGBEncoding = 3001;
 THREE.sRGBEncoding = 3001;
-THREE.RGBEEncoding = 3002; // AKA Radiance
+THREE.GammaEncoding = 3007; // uses GAMMA_FACTOR, for backwards compatibility with WebGLRenderer.gammaInput/gammaOutput
+
+// The following Texture Encodings are for RGB-only (no alpha) HDR light emission sources.
+// These encodings should not specified as output encodings except in rare situations.
+THREE.RGBEEncoding = 3002; // AKA Radiance.
 THREE.LogLuvEncoding = 3003;
 THREE.LogLuvEncoding = 3003;
 THREE.RGBM7Encoding = 3004;
 THREE.RGBM7Encoding = 3004;
 THREE.RGBM16Encoding = 3005;
 THREE.RGBM16Encoding = 3005;
-THREE.RGBDEncoding = 3006; // MaxRange is 256
-THREE.GammaEncoding = 3007; // uses GAMMA_FACTOR
+THREE.RGBDEncoding = 3006; // MaxRange is 256.

+ 6 - 0
src/renderers/WebGLRenderer.js

@@ -3365,6 +3365,12 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 	}
 	}
 
 
+	this.getCurrentRenderTarget = function() {
+
+		return _currentRenderTarget;
+
+	}
+
 	this.setRenderTarget = function ( renderTarget ) {
 	this.setRenderTarget = function ( renderTarget ) {
 
 
 		_currentRenderTarget = renderTarget;
 		_currentRenderTarget = renderTarget;

+ 0 - 28
src/renderers/shaders/ShaderChunk/common.glsl

@@ -64,31 +64,3 @@ vec3 linePlaneIntersect( in vec3 pointOnLine, in vec3 lineDirection, in vec3 poi
 	return lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;
 	return lineDirection * ( dot( planeNormal, pointOnPlane - pointOnLine ) / dot( planeNormal, lineDirection ) ) + pointOnLine;
 
 
 }
 }
-
-vec3 inputToLinear( in vec3 a ) {
-
-	#ifdef GAMMA_INPUT
-
-		return pow( a, vec3( float( GAMMA_FACTOR ) ) );
-
-	#else
-
-		return a;
-
-	#endif
-
-}
-
-vec3 linearToOutput( in vec3 a ) {
-
-	#ifdef GAMMA_OUTPUT
-
-		return pow( a, vec3( 1.0 / float( GAMMA_FACTOR ) ) );
-
-	#else
-
-		return a;
-
-	#endif
-
-}

+ 1 - 1
src/renderers/shaders/ShaderChunk/encodings.glsl

@@ -7,7 +7,7 @@ vec4 LinearToLinear( in vec4 value ) {
 vec4 GammaToLinear( in vec4 value, in float gammaFactor ) {
 vec4 GammaToLinear( in vec4 value, in float gammaFactor ) {
   return vec4( pow( value.xyz, vec3( gammaFactor ) ), value.w );
   return vec4( pow( value.xyz, vec3( gammaFactor ) ), value.w );
 }
 }
-vec4 LinearTosGamma( in vec4 value, in float gammaFactor ) {
+vec4 LinearToGamma( in vec4 value, in float gammaFactor ) {
   return vec4( pow( value.xyz, vec3( 1.0 / gammaFactor ) ), value.w );
   return vec4( pow( value.xyz, vec3( 1.0 / gammaFactor ) ), value.w );
 }
 }
 
 

+ 3 - 3
src/renderers/shaders/ShaderChunk/fog_fragment.glsl

@@ -19,7 +19,7 @@
 		float fogFactor = smoothstep( fogNear, fogFar, depth );
 		float fogFactor = smoothstep( fogNear, fogFar, depth );
 
 
 	#endif
 	#endif
-	
-	outgoingLight = mix( outgoingLight, fogColor, fogFactor );
 
 
-#endif
+	gl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );
+
+#endif

+ 0 - 2
src/renderers/shaders/ShaderChunk/linear_to_gamma_fragment.glsl

@@ -1,2 +0,0 @@
-
-	outgoingLight = linearToOutput( outgoingLight );

+ 2 - 2
src/renderers/shaders/ShaderLib/linedashed_frag.glsl

@@ -27,8 +27,8 @@ void main() {
 
 
 	outgoingLight = diffuseColor.rgb; // simple shader
 	outgoingLight = diffuseColor.rgb; // simple shader
 
 
-	#include <fog_fragment>
+	gl_FragColor = linearToOutputTexel( vec4( outgoingLight, diffuseColor.a ) );
 
 
-	gl_FragColor = vec4( outgoingLight, diffuseColor.a );
+	#include <fog_fragment>
 
 
 }
 }

+ 3 - 3
src/renderers/shaders/ShaderLib/meshbasic_frag.glsl

@@ -41,9 +41,9 @@ void main() {
 	vec3 outgoingLight = reflectedLight.indirectDiffuse;
 	vec3 outgoingLight = reflectedLight.indirectDiffuse;
 
 
 	#include <envmap_fragment>
 	#include <envmap_fragment>
-	#include <linear_to_gamma_fragment>
-	#include <fog_fragment>
 
 
-	gl_FragColor = vec4( outgoingLight, diffuseColor.a );
+	gl_FragColor = linearToOutputTexel( vec4( outgoingLight, diffuseColor.a ) );
+
+	#include <fog_fragment>
 
 
 }
 }

+ 3 - 3
src/renderers/shaders/ShaderLib/meshlambert_frag.glsl

@@ -68,9 +68,9 @@ void main() {
 	vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveLight;
 	vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveLight;
 
 
 	#include <envmap_fragment>
 	#include <envmap_fragment>
-	#include <linear_to_gamma_fragment>
-	#include <fog_fragment>
 
 
-	gl_FragColor = vec4( outgoingLight, diffuseColor.a );
+	gl_FragColor = linearToOutputTexel( vec4( outgoingLight, diffuseColor.a ) );
+
+	#include <fog_fragment>
 
 
 }
 }

+ 2 - 3
src/renderers/shaders/ShaderLib/meshphong_frag.glsl

@@ -52,10 +52,9 @@ void main() {
 	vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveLight;
 	vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveLight;
 
 
 	#include <envmap_fragment>
 	#include <envmap_fragment>
-	#include <linear_to_gamma_fragment>
 
 
-	#include <fog_fragment>
+	gl_FragColor = linearToOutputTexel( vec4( outgoingLight, diffuseColor.a ) );
 
 
-	gl_FragColor = vec4( outgoingLight, diffuseColor.a );
+	#include <fog_fragment>
 
 
 }
 }

+ 1 - 3
src/renderers/shaders/ShaderLib/meshstandard_frag.glsl

@@ -64,10 +64,8 @@ void main() {
 
 
 	vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveLight;
 	vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveLight;
 
 
-	#include <linear_to_gamma_fragment>
+	gl_FragColor = linearToOutputTexel( vec4( outgoingLight, diffuseColor.a ) );
 
 
 	#include <fog_fragment>
 	#include <fog_fragment>
 
 
-	gl_FragColor = vec4( outgoingLight, diffuseColor.a );
-
 }
 }

+ 2 - 2
src/renderers/shaders/ShaderLib/points_frag.glsl

@@ -20,8 +20,8 @@ void main() {
 
 
 	outgoingLight = diffuseColor.rgb;
 	outgoingLight = diffuseColor.rgb;
 
 
-	#include <fog_fragment>
+	gl_FragColor = linearToOutputTexel( vec4( outgoingLight, diffuseColor.a ) );
 
 
-	gl_FragColor = vec4( outgoingLight, diffuseColor.a );
+	#include <fog_fragment>
 
 
 }
 }

+ 23 - 20
src/renderers/webgl/WebGLProgram.js

@@ -7,40 +7,42 @@ THREE.WebGLProgram = ( function () {
 	var arrayStructRe = /^([\w\d_]+)\[(\d+)\]\.([\w\d_]+)$/;
 	var arrayStructRe = /^([\w\d_]+)\[(\d+)\]\.([\w\d_]+)$/;
 	var arrayRe = /^([\w\d_]+)\[0\]$/;
 	var arrayRe = /^([\w\d_]+)\[0\]$/;
 
 
-	function getTexelDecodingFunction( functionName, encoding ) {
-
-		var code = "vec4 " + functionName + "( vec4 value ) { return ";
+	function getEncodingComponents( encoding ) {
 
 
 		switch ( encoding ) {
 		switch ( encoding ) {
 
 
 			case THREE.LinearEncoding:
 			case THREE.LinearEncoding:
-				code += "value";
-				break;
+				return ['Linear','( value )'];
 			case THREE.sRGBEncoding:
 			case THREE.sRGBEncoding:
-				code += "sRGBToLinear( value )";
-				break;
+				return ['sRGB','( value )'];
 			case THREE.RGBEEncoding:
 			case THREE.RGBEEncoding:
-				code += "RGBEToLinear( value )";
-				break;
+				return ['RGBE','( value )'];
 			case THREE.RGBM7Encoding:
 			case THREE.RGBM7Encoding:
-				code += "RGBMToLinear( value, 7.0 )";
-				break;
+				return ['RGBM','( value, 7.0 )'];
 			case THREE.RGBM16Encoding:
 			case THREE.RGBM16Encoding:
-				code += "RGBMToLinear( value, 16.0 )";
-				break;
+				return ['RGBM','( value, 16.0 )'];
 			case THREE.RGBDEncoding:
 			case THREE.RGBDEncoding:
-				code += "RGBDToLinear( value, 256.0 )";
-				break;
+				return ['RGBD','( value, 256.0 )'];
 			case THREE.GammaEncoding:
 			case THREE.GammaEncoding:
-				code += "GammaToLinear( value, float( GAMMA_FACTOR ) )";
-				break;
+				return ['Gamma','( value, float( GAMMA_FACTOR ) )'];
 			default:
 			default:
 				throw new Error( 'unsupported encoding: ' + encoding );
 				throw new Error( 'unsupported encoding: ' + encoding );
 
 
 		}
 		}
 
 
-		code += "; }";
-		return code;
+	}
+
+	function getTexelDecodingFunction( functionName, encoding ) {
+
+		var components = getEncodingComponents( encoding );
+		return "vec4 " + functionName + "( vec4 value ) { return " + components[0] + "ToLinear" + components[1] + "; }";
+
+	}
+
+	function getTexelEncodingFunction( functionName, encoding ) {
+
+		var components = getEncodingComponents( encoding );
+		return "vec4 " + functionName + "( vec4 value ) { return LinearTo" + components[0] + components[1] + "; }";
 
 
 	}
 	}
 
 
@@ -496,11 +498,12 @@ THREE.WebGLProgram = ( function () {
 				'uniform mat4 viewMatrix;',
 				'uniform mat4 viewMatrix;',
 				'uniform vec3 cameraPosition;',
 				'uniform vec3 cameraPosition;',
 
 
-				( parameters.mapEncoding || parameters.envMapEncoding || parameters.emissiveMapEncoding ) ? THREE.ShaderChunk[ 'encodings' ] : '',
+				( parameters.outputEncoding || parameters.mapEncoding || parameters.envMapEncoding || parameters.emissiveMapEncoding ) ? THREE.ShaderChunk[ 'encodings' ] : '',
 
 
 				parameters.mapEncoding ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '',
 				parameters.mapEncoding ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '',
 				parameters.envMapEncoding ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '',
 				parameters.envMapEncoding ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '',
 				parameters.emissiveMapEncoding ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '',
 				parameters.emissiveMapEncoding ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '',
+				parameters.outputEncoding ? getTexelEncodingFunction( "linearToOutputTexel", parameters.outputEncoding ) : '',
 
 
 				'\n'
 				'\n'
 
 

+ 15 - 18
src/renderers/webgl/WebGLPrograms.js

@@ -67,29 +67,28 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) {
 
 
 	}
 	}
 
 
-	function getTextureEncodingFromMap( map ) {
-
-		if ( ! map ) return false;
+	function getTextureEncodingFromMap( map, gammaOverrideLinear ) {
 
 
 		var encoding;
 		var encoding;
 
 
-		if ( map instanceof THREE.Texture ) {
+		if( ! map ) {
 
 
-			encoding = map.encoding;
+			encoding = THREE.LinearEncoding;
 
 
-		} else if ( map instanceof THREE.WebGLRenderTarget ) {
+		}
+		else if( map instanceof THREE.Texture ) {
 
 
-			encoding = map.texture.encoding;
+			encoding = map.encoding;
 
 
-		} else {
+		}
+		else if( map instanceof THREE.WebGLRenderTarget ) {
 
 
-			throw new Error( "can not determine texture encoding from map: " + map );
+			encoding = map.texture.encoding;
 
 
 		}
 		}
 
 
-		// add backwards compatibility for WebGLRenderer.gammaInput parameter, should probably be removed at some point.
-
-		if ( encoding === THREE.LinearEncoding && renderer.gammaInput ) {
+		// add backwards compatibility for WebGLRenderer.gammaInput/gammaOutput parameter, should probably be removed at some point.
+		if( encoding === THREE.LinearEncoding && gammaOverrideLinear ) {
 
 
 			encoding = THREE.GammaEncoding;
 			encoding = THREE.GammaEncoding;
 
 
@@ -100,7 +99,6 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) {
 	}
 	}
 
 
 	this.getParameters = function ( material, lights, fog, object ) {
 	this.getParameters = function ( material, lights, fog, object ) {
-
 		var shaderID = shaderIDs[ material.type ];
 		var shaderID = shaderIDs[ material.type ];
 		// heuristics to create shader parameters according to lights in the scene
 		// heuristics to create shader parameters according to lights in the scene
 		// (not to blow over maxLights budget)
 		// (not to blow over maxLights budget)
@@ -119,23 +117,22 @@ THREE.WebGLPrograms = function ( renderer, capabilities ) {
 			}
 			}
 
 
 		}
 		}
-
 		var parameters = {
 		var parameters = {
 
 
 			shaderID: shaderID,
 			shaderID: shaderID,
 
 
 			precision: precision,
 			precision: precision,
 			supportsVertexTextures: capabilities.vertexTextures,
 			supportsVertexTextures: capabilities.vertexTextures,
-
+			outputEncoding: getTextureEncodingFromMap( renderer.getCurrentRenderTarget(), renderer.gammaOutput ),
 			map: !! material.map,
 			map: !! material.map,
-			mapEncoding: getTextureEncodingFromMap( material.map ),
+			mapEncoding: getTextureEncodingFromMap( material.map, renderer.gammaInput ),
 			envMap: !! material.envMap,
 			envMap: !! material.envMap,
 			envMapMode: material.envMap && material.envMap.mapping,
 			envMapMode: material.envMap && material.envMap.mapping,
-			envMapEncoding: getTextureEncodingFromMap( material.envMap ),
+			envMapEncoding: getTextureEncodingFromMap( material.envMap, renderer.gammaInput ),
 			lightMap: !! material.lightMap,
 			lightMap: !! material.lightMap,
 			aoMap: !! material.aoMap,
 			aoMap: !! material.aoMap,
 			emissiveMap: !! material.emissiveMap,
 			emissiveMap: !! material.emissiveMap,
-			emissiveMapEncoding: getTextureEncodingFromMap( material.emissiveMap ),
+			emissiveMapEncoding: getTextureEncodingFromMap( material.emissiveMap, renderer.gammaInput ),
 			bumpMap: !! material.bumpMap,
 			bumpMap: !! material.bumpMap,
 			normalMap: !! material.normalMap,
 			normalMap: !! material.normalMap,
 			displacementMap: !! material.displacementMap,
 			displacementMap: !! material.displacementMap,

+ 0 - 1
utils/build/includes/common.json

@@ -155,7 +155,6 @@
 	"src/renderers/shaders/ShaderChunk/lights_standard_fragment.glsl",
 	"src/renderers/shaders/ShaderChunk/lights_standard_fragment.glsl",
 	"src/renderers/shaders/ShaderChunk/lights_standard_pars_fragment.glsl",
 	"src/renderers/shaders/ShaderChunk/lights_standard_pars_fragment.glsl",
 	"src/renderers/shaders/ShaderChunk/lights_template.glsl",
 	"src/renderers/shaders/ShaderChunk/lights_template.glsl",
-	"src/renderers/shaders/ShaderChunk/linear_to_gamma_fragment.glsl",
 	"src/renderers/shaders/ShaderChunk/logdepthbuf_fragment.glsl",
 	"src/renderers/shaders/ShaderChunk/logdepthbuf_fragment.glsl",
 	"src/renderers/shaders/ShaderChunk/logdepthbuf_pars_fragment.glsl",
 	"src/renderers/shaders/ShaderChunk/logdepthbuf_pars_fragment.glsl",
 	"src/renderers/shaders/ShaderChunk/logdepthbuf_pars_vertex.glsl",
 	"src/renderers/shaders/ShaderChunk/logdepthbuf_pars_vertex.glsl",