Browse Source

Fixed WebGL Wrappings.
Added WebGL Texture Filters.

Mr.doob 14 years ago
parent
commit
e7f5f3865a
5 changed files with 215 additions and 188 deletions
  1. 10 7
      build/Three.js
  2. 10 7
      build/ThreeDebug.js
  3. 10 7
      build/ThreeExtras.js
  4. 15 3
      src/materials/Texture.js
  5. 170 164
      src/renderers/WebGLRenderer.js

+ 10 - 7
build/Three.js

@@ -81,8 +81,10 @@ a.uniforms;if(a.shading!==undefined)this.shading=a.shading;if(a.blending!==undef
 this.blending+"<br/>wireframe: "+this.wireframe+"<br/>wireframe_linewidth: "+this.wireframe_linewidth+"<br/>wireframe_linecap: "+this.wireframe_linecap+"<br/>wireframe_linejoin: "+this.wireframe_linejoin+"<br/>)"}};THREE.MeshShaderMaterialCounter={value:0};
 THREE.ParticleBasicMaterial=function(a){this.color=new THREE.Color(16711680);this.map=null;this.opacity=1;this.blending=THREE.NormalBlending;this.offset=new THREE.Vector2;if(a){a.color!==undefined&&this.color.setHex(a.color);if(a.map!==undefined)this.map=a.map;if(a.opacity!==undefined)this.opacity=a.opacity;if(a.blending!==undefined)this.blending=a.blending}this.toString=function(){return"THREE.ParticleBasicMaterial (<br/>color: "+this.color+"<br/>map: "+this.map+"<br/>opacity: "+this.opacity+"<br/>blending: "+
 this.blending+"<br/>)"}};THREE.ParticleCircleMaterial=function(a){this.color=new THREE.Color(16711680);this.opacity=1;this.blending=THREE.NormalBlending;if(a){a.color!==undefined&&this.color.setHex(a.color);if(a.opacity!==undefined)this.opacity=a.opacity;if(a.blending!==undefined)this.blending=a.blending}this.toString=function(){return"THREE.ParticleCircleMaterial (<br/>color: "+this.color+"<br/>opacity: "+this.opacity+"<br/>blending: "+this.blending+"<br/>)"}};
-THREE.ParticleDOMMaterial=function(a){this.domElement=a;this.toString=function(){return"THREE.ParticleDOMMaterial ( domElement: "+this.domElement+" )"}};THREE.Texture=function(a,b,d,g){this.image=a;this.mapping=b!==undefined?b:new THREE.UVMapping;this.wrap_s=d!==undefined?d:THREE.ClampToEdge;this.wrap_t=g!==undefined?g:THREE.ClampToEdge;this.toString=function(){return"THREE.Texture (<br/>image: "+this.image+"<br/>wrap_s: "+this.wrap_s+"<br/>wrap_t: "+this.wrap_t+"<br/>)"}};
-THREE.MultiplyOperation=0;THREE.MixOperation=1;THREE.RepeatWrapping=0;THREE.ClampToEdgeWrapping=1;THREE.MirroredRepeatWrapping=2;THREE.CubeReflectionMapping=function(){};THREE.CubeRefractionMapping=function(){};THREE.LatitudeReflectionMapping=function(){};THREE.LatitudeRefractionMapping=function(){};THREE.SphericalReflectionMapping=function(){};THREE.SphericalRefractionMapping=function(){};THREE.UVMapping=function(){};
+THREE.ParticleDOMMaterial=function(a){this.domElement=a;this.toString=function(){return"THREE.ParticleDOMMaterial ( domElement: "+this.domElement+" )"}};
+THREE.Texture=function(a,b,d,g,j,n){this.image=a;this.mapping=b!==undefined?b:new THREE.UVMapping;this.wrap_s=d!==undefined?d:THREE.ClampToEdgeWrapping;this.wrap_t=g!==undefined?g:THREE.ClampToEdgeWrapping;this.mag_filter=j!==undefined?j:THREE.LinearFilter;this.min_filter=n!==undefined?n:THREE.LinearMipMapLinearFilter;this.toString=function(){return"THREE.Texture (<br/>image: "+this.image+"<br/>wrap_s: "+this.wrap_s+"<br/>wrap_t: "+this.wrap_t+"<br/>mag_filter: "+this.mag_filter+"<br/>min_filter: "+
+this.min_filter+"<br/>)"}};THREE.MultiplyOperation=0;THREE.MixOperation=1;THREE.RepeatWrapping=0;THREE.ClampToEdgeWrapping=1;THREE.MirroredRepeatWrapping=2;THREE.NearestFilter=3;THREE.NearestMipMapNearestFilter=4;THREE.NearestMipMapLinearFilter=5;THREE.LinearFilter=6;THREE.LinearMipMapNearestFilter=7;THREE.LinearMipMapLinearFilter=8;THREE.CubeReflectionMapping=function(){};THREE.CubeRefractionMapping=function(){};THREE.LatitudeReflectionMapping=function(){};THREE.LatitudeRefractionMapping=function(){};
+THREE.SphericalReflectionMapping=function(){};THREE.SphericalRefractionMapping=function(){};THREE.UVMapping=function(){};
 THREE.Scene=function(){this.objects=[];this.lights=[];this.addObject=function(a){this.objects.push(a)};this.removeObject=function(a){a=this.objects.indexOf(a);a!==-1&&this.objects.splice(a,1)};this.addLight=function(a){this.lights.push(a)};this.removeLight=function(a){a=this.lights.indexOf(a);a!==-1&&this.lights.splice(a,1)};this.toString=function(){return"THREE.Scene ( "+this.objects+" )"}};
 THREE.Projector=function(){function a(O,u){var f=0,k=1,e=O.z+O.w,p=u.z+u.w,h=-O.z+O.w,i=-u.z+u.w;if(e>=0&&p>=0&&h>=0&&i>=0)return true;else if(e<0&&p<0||h<0&&i<0)return false;else{if(e<0)f=Math.max(f,e/(e-p));else if(p<0)k=Math.min(k,e/(e-p));if(h<0)f=Math.max(f,h/(h-i));else if(i<0)k=Math.min(k,h/(h-i));if(k<f)return false;else{O.lerpSelf(u,f);u.lerpSelf(O,1-k);return true}}}var b=null,d,g,j,n=[],m,l,o=[],c,F,D=[],v=new THREE.Vector4,x=new THREE.Matrix4,H=new THREE.Matrix4,G=new THREE.Vector4,K=
 new THREE.Vector4,N;this.projectScene=function(O,u){var f,k,e,p,h,i,r,q,L,A,M,Q,t,R,y,z,E;b=[];j=l=F=0;u.autoUpdateMatrix&&u.updateMatrix();x.multiply(u.projectionMatrix,u.matrix);r=O.objects;f=0;for(k=r.length;f<k;f++){q=r[f];q.autoUpdateMatrix&&q.updateMatrix();L=q.matrix;A=q.rotationMatrix;M=q.material;Q=q.overdraw;if(q instanceof THREE.Mesh){t=q.geometry.vertices;e=0;for(p=t.length;e<p;e++){R=t[e];R.positionWorld.copy(R.position);L.multiplyVector3(R.positionWorld);y=R.positionScreen;y.copy(R.positionWorld);
@@ -130,12 +132,13 @@ THREE.MeshFaceMaterial){U=0;for(X=S.faceMaterial.length;U<X;)(P=S.faceMaterial[U
 THREE.WebGLRenderer=function(a){function b(f,k){var e=c.createProgram();c.attachShader(e,m("fragment","#ifdef GL_ES\nprecision highp float;\n#endif\n"+f));c.attachShader(e,m("vertex","uniform mat4 objectMatrix;\nuniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\nuniform vec3 cameraPosition;\nattribute vec3 position;\nattribute vec3 normal;\nattribute vec2 uv;\n"+k));c.linkProgram(e);c.getProgramParameter(e,c.LINK_STATUS)||alert("Could not initialise shaders\nVALIDATE_STATUS: "+c.getProgramParameter(e,
 c.VALIDATE_STATUS)+", gl error ["+c.getError()+"]");e.uniforms={};e.attributes={};return e}function d(f,k){if(f.image.length==6){if(!f.image.__webGLTextureCube&&!f.image.__cubeMapInitialized&&f.image.loadCount==6){f.image.__webGLTextureCube=c.createTexture();c.bindTexture(c.TEXTURE_CUBE_MAP,f.image.__webGLTextureCube);c.texParameteri(c.TEXTURE_CUBE_MAP,c.TEXTURE_WRAP_S,c.CLAMP_TO_EDGE);c.texParameteri(c.TEXTURE_CUBE_MAP,c.TEXTURE_WRAP_T,c.CLAMP_TO_EDGE);c.texParameteri(c.TEXTURE_CUBE_MAP,c.TEXTURE_MAG_FILTER,
 c.LINEAR);c.texParameteri(c.TEXTURE_CUBE_MAP,c.TEXTURE_MIN_FILTER,c.LINEAR_MIPMAP_LINEAR);for(var e=0;e<6;++e)c.texImage2D(c.TEXTURE_CUBE_MAP_POSITIVE_X+e,0,c.RGBA,c.RGBA,c.UNSIGNED_BYTE,f.image[e]);c.generateMipmap(c.TEXTURE_CUBE_MAP);c.bindTexture(c.TEXTURE_CUBE_MAP,null);f.image.__cubeMapInitialized=true}c.activeTexture(c.TEXTURE0+k);c.bindTexture(c.TEXTURE_CUBE_MAP,f.image.__webGLTextureCube)}}function g(f,k){if(!f.__webGLTexture&&f.image.loaded){f.__webGLTexture=c.createTexture();c.bindTexture(c.TEXTURE_2D,
-f.__webGLTexture);c.texImage2D(c.TEXTURE_2D,0,c.RGBA,c.RGBA,c.UNSIGNED_BYTE,f.image);c.texParameteri(c.TEXTURE_2D,c.TEXTURE_WRAP_S,l(f.wrap_s));c.texParameteri(c.TEXTURE_2D,c.TEXTURE_WRAP_T,l(f.wrap_t));c.texParameteri(c.TEXTURE_2D,c.TEXTURE_MAG_FILTER,c.LINEAR);c.texParameteri(c.TEXTURE_2D,c.TEXTURE_MIN_FILTER,c.LINEAR_MIPMAP_LINEAR);c.generateMipmap(c.TEXTURE_2D);c.bindTexture(c.TEXTURE_2D,null)}c.activeTexture(c.TEXTURE0+k);c.bindTexture(c.TEXTURE_2D,f.__webGLTexture)}function j(f,k){var e,p,h;
+f.__webGLTexture);c.texImage2D(c.TEXTURE_2D,0,c.RGBA,c.RGBA,c.UNSIGNED_BYTE,f.image);c.texParameteri(c.TEXTURE_2D,c.TEXTURE_WRAP_S,l(f.wrap_s));c.texParameteri(c.TEXTURE_2D,c.TEXTURE_WRAP_T,l(f.wrap_t));c.texParameteri(c.TEXTURE_2D,c.TEXTURE_MAG_FILTER,l(f.mag_filter));c.texParameteri(c.TEXTURE_2D,c.TEXTURE_MIN_FILTER,l(f.min_filter));c.generateMipmap(c.TEXTURE_2D);c.bindTexture(c.TEXTURE_2D,null)}c.activeTexture(c.TEXTURE0+k);c.bindTexture(c.TEXTURE_2D,f.__webGLTexture)}function j(f,k){var e,p,h;
 e=0;for(p=k.length;e<p;e++){h=k[e];f.uniforms[h]=c.getUniformLocation(f,h)}}function n(f,k){var e,p,h;e=0;for(p=k.length;e<p;e++){h=k[e];f.attributes[h]=c.getAttribLocation(f,h);f.attributes[h]>=0&&c.enableVertexAttribArray(f.attributes[h])}}function m(f,k){var e;if(f=="fragment")e=c.createShader(c.FRAGMENT_SHADER);else if(f=="vertex")e=c.createShader(c.VERTEX_SHADER);c.shaderSource(e,k);c.compileShader(e);if(!c.getShaderParameter(e,c.COMPILE_STATUS)){alert(c.getShaderInfoLog(e));return null}return e}
-function l(f){switch(f){case THREE.Repeat:return c.REPEAT;case THREE.ClampToEdge:return c.CLAMP_TO_EDGE;case THREE.MirroredRepeat:return c.MIRRORED_REPEAT}return 0}var o=document.createElement("canvas"),c,F,D,v=new THREE.Matrix4,x,H=new Float32Array(16),G=new Float32Array(16),K=new Float32Array(16),N=new Float32Array(9),O=new Float32Array(16);a=function(f,k){if(f){var e,p,h,i=pointLights=maxDirLights=maxPointLights=0;e=0;for(p=f.lights.length;e<p;e++){h=f.lights[e];h instanceof THREE.DirectionalLight&&
-i++;h instanceof THREE.PointLight&&pointLights++}if(pointLights+i<=k){maxDirLights=i;maxPointLights=pointLights}else{maxDirLights=Math.ceil(k*i/(pointLights+i));maxPointLights=k-maxDirLights}return{directional:maxDirLights,point:maxPointLights}}return{directional:1,point:k-1}}(a,4);this.domElement=o;this.autoClear=true;try{c=o.getContext("experimental-webgl",{antialias:true})}catch(u){}if(!c){alert("WebGL not supported");throw"cannot create webgl context";}c.clearColor(0,0,0,1);c.clearDepth(1);c.enable(c.DEPTH_TEST);
-c.depthFunc(c.LEQUAL);c.frontFace(c.CCW);c.cullFace(c.BACK);c.enable(c.CULL_FACE);c.enable(c.BLEND);c.blendFunc(c.ONE,c.ONE_MINUS_SRC_ALPHA);c.clearColor(0,0,0,0);F=D=function(f,k){var e=[f?"#define MAX_DIR_LIGHTS "+f:"",k?"#define MAX_POINT_LIGHTS "+k:"","uniform bool enableLighting;\nuniform bool useRefract;\nuniform int pointLightNumber;\nuniform int directionalLightNumber;\nuniform vec3 ambientLightColor;",f?"uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];":"",f?"uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];":
-"",k?"uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];":"",k?"uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];":"","uniform mat4 viewMatrix;\nuniform mat3 normalMatrix;\nvarying vec3 vNormal;\nvarying vec2 vUv;\nvarying vec3 vLightWeighting;",k?"varying vec3 vPointLightVector[ MAX_POINT_LIGHTS ];":"","varying vec3 vViewPosition;\nvarying vec3 vReflect;\nuniform float mRefractionRatio;\nvoid main(void) {\nvec4 mPosition = objectMatrix * vec4( position, 1.0 );\nvViewPosition = cameraPosition - mPosition.xyz;\nvec3 nWorld = mat3( objectMatrix[0].xyz, objectMatrix[1].xyz, objectMatrix[2].xyz ) * normal;\nvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\nvec3 transformedNormal = normalize( normalMatrix * normal );\nif ( !enableLighting ) {\nvLightWeighting = vec3( 1.0, 1.0, 1.0 );\n} else {\nvLightWeighting = ambientLightColor;",
+function l(f){switch(f){case THREE.RepeatWrapping:return c.REPEAT;case THREE.ClampToEdgeWrapping:return c.CLAMP_TO_EDGE;case THREE.MirroredRepeatWrapping:return c.MIRRORED_REPEAT;case THREE.NearestFilter:return c.NEAREST;case THREE.NearestMipMapNearestFilter:return c.NEAREST_MIPMAP_NEAREST;case THREE.NearestMipMapLinearFilter:return c.NEAREST_MIPMAP_LINEAR;case THREE.LinearFilter:return c.LINEAR;case THREE.LinearMipMapNearestFilter:return c.LINEAR_MIPMAP_NEAREST;case THREE.LinearMipMapLinearFilter:return c.LINEAR_MIPMAP_LINEAR}return 0}
+var o=document.createElement("canvas"),c,F,D,v=new THREE.Matrix4,x,H=new Float32Array(16),G=new Float32Array(16),K=new Float32Array(16),N=new Float32Array(9),O=new Float32Array(16);a=function(f,k){if(f){var e,p,h,i=pointLights=maxDirLights=maxPointLights=0;e=0;for(p=f.lights.length;e<p;e++){h=f.lights[e];h instanceof THREE.DirectionalLight&&i++;h instanceof THREE.PointLight&&pointLights++}if(pointLights+i<=k){maxDirLights=i;maxPointLights=pointLights}else{maxDirLights=Math.ceil(k*i/(pointLights+i));
+maxPointLights=k-maxDirLights}return{directional:maxDirLights,point:maxPointLights}}return{directional:1,point:k-1}}(a,4);this.domElement=o;this.autoClear=true;try{c=o.getContext("experimental-webgl",{antialias:true})}catch(u){}if(!c){alert("WebGL not supported");throw"cannot create webgl context";}c.clearColor(0,0,0,1);c.clearDepth(1);c.enable(c.DEPTH_TEST);c.depthFunc(c.LEQUAL);c.frontFace(c.CCW);c.cullFace(c.BACK);c.enable(c.CULL_FACE);c.enable(c.BLEND);c.blendFunc(c.ONE,c.ONE_MINUS_SRC_ALPHA);
+c.clearColor(0,0,0,0);F=D=function(f,k){var e=[f?"#define MAX_DIR_LIGHTS "+f:"",k?"#define MAX_POINT_LIGHTS "+k:"","uniform bool enableLighting;\nuniform bool useRefract;\nuniform int pointLightNumber;\nuniform int directionalLightNumber;\nuniform vec3 ambientLightColor;",f?"uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];":"",f?"uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];":"",k?"uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];":"",k?"uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];":
+"","uniform mat4 viewMatrix;\nuniform mat3 normalMatrix;\nvarying vec3 vNormal;\nvarying vec2 vUv;\nvarying vec3 vLightWeighting;",k?"varying vec3 vPointLightVector[ MAX_POINT_LIGHTS ];":"","varying vec3 vViewPosition;\nvarying vec3 vReflect;\nuniform float mRefractionRatio;\nvoid main(void) {\nvec4 mPosition = objectMatrix * vec4( position, 1.0 );\nvViewPosition = cameraPosition - mPosition.xyz;\nvec3 nWorld = mat3( objectMatrix[0].xyz, objectMatrix[1].xyz, objectMatrix[2].xyz ) * normal;\nvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\nvec3 transformedNormal = normalize( normalMatrix * normal );\nif ( !enableLighting ) {\nvLightWeighting = vec3( 1.0, 1.0, 1.0 );\n} else {\nvLightWeighting = ambientLightColor;",
 f?"for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {":"",f?"vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );":"",f?"float directionalLightWeighting = max( dot( transformedNormal, normalize(lDirection.xyz ) ), 0.0 );":"",f?"vLightWeighting += directionalLightColor[ i ] * directionalLightWeighting;":"",f?"}":"",k?"for( int i = 0; i < MAX_POINT_LIGHTS; i++ ) {":"",k?"vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );":"",k?"vPointLightVector[ i ] = normalize( lPosition.xyz - mvPosition.xyz );":
 "",k?"float pointLightWeighting = max( dot( transformedNormal, vPointLightVector[ i ] ), 0.0 );":"",k?"vLightWeighting += pointLightColor[ i ] * pointLightWeighting;":"",k?"}":"","}\nvNormal = transformedNormal;\nvUv = uv;\nif ( useRefract ) {\nvReflect = refract( normalize(mPosition.xyz - cameraPosition), normalize(nWorld.xyz), mRefractionRatio );\n} else {\nvReflect = reflect( normalize(mPosition.xyz - cameraPosition), normalize(nWorld.xyz) );\n}\ngl_Position = projectionMatrix * mvPosition;\n}"].join("\n"),
 p=[f?"#define MAX_DIR_LIGHTS "+f:"",k?"#define MAX_POINT_LIGHTS "+k:"","uniform int material;\nuniform bool enableMap;\nuniform bool enableCubeMap;\nuniform bool mixEnvMap;\nuniform samplerCube tCube;\nuniform float mReflectivity;\nuniform sampler2D tMap;\nuniform vec4 mColor;\nuniform float mOpacity;\nuniform vec4 mAmbient;\nuniform vec4 mSpecular;\nuniform float mShininess;\nuniform float m2Near;\nuniform float mFarPlusNear;\nuniform float mFarMinusNear;\nuniform int pointLightNumber;\nuniform int directionalLightNumber;",

+ 10 - 7
build/ThreeDebug.js

@@ -81,8 +81,10 @@ a.uniforms;if(a.shading!==undefined)this.shading=a.shading;if(a.blending!==undef
 this.blending+"<br/>wireframe: "+this.wireframe+"<br/>wireframe_linewidth: "+this.wireframe_linewidth+"<br/>wireframe_linecap: "+this.wireframe_linecap+"<br/>wireframe_linejoin: "+this.wireframe_linejoin+"<br/>)"}};THREE.MeshShaderMaterialCounter={value:0};
 THREE.ParticleBasicMaterial=function(a){this.color=new THREE.Color(16711680);this.map=null;this.opacity=1;this.blending=THREE.NormalBlending;this.offset=new THREE.Vector2;if(a){a.color!==undefined&&this.color.setHex(a.color);if(a.map!==undefined)this.map=a.map;if(a.opacity!==undefined)this.opacity=a.opacity;if(a.blending!==undefined)this.blending=a.blending}this.toString=function(){return"THREE.ParticleBasicMaterial (<br/>color: "+this.color+"<br/>map: "+this.map+"<br/>opacity: "+this.opacity+"<br/>blending: "+
 this.blending+"<br/>)"}};THREE.ParticleCircleMaterial=function(a){this.color=new THREE.Color(16711680);this.opacity=1;this.blending=THREE.NormalBlending;if(a){a.color!==undefined&&this.color.setHex(a.color);if(a.opacity!==undefined)this.opacity=a.opacity;if(a.blending!==undefined)this.blending=a.blending}this.toString=function(){return"THREE.ParticleCircleMaterial (<br/>color: "+this.color+"<br/>opacity: "+this.opacity+"<br/>blending: "+this.blending+"<br/>)"}};
-THREE.ParticleDOMMaterial=function(a){this.domElement=a;this.toString=function(){return"THREE.ParticleDOMMaterial ( domElement: "+this.domElement+" )"}};THREE.Texture=function(a,b,d,g){this.image=a;this.mapping=b!==undefined?b:new THREE.UVMapping;this.wrap_s=d!==undefined?d:THREE.ClampToEdge;this.wrap_t=g!==undefined?g:THREE.ClampToEdge;this.toString=function(){return"THREE.Texture (<br/>image: "+this.image+"<br/>wrap_s: "+this.wrap_s+"<br/>wrap_t: "+this.wrap_t+"<br/>)"}};
-THREE.MultiplyOperation=0;THREE.MixOperation=1;THREE.RepeatWrapping=0;THREE.ClampToEdgeWrapping=1;THREE.MirroredRepeatWrapping=2;THREE.CubeReflectionMapping=function(){};THREE.CubeRefractionMapping=function(){};THREE.LatitudeReflectionMapping=function(){};THREE.LatitudeRefractionMapping=function(){};THREE.SphericalReflectionMapping=function(){};THREE.SphericalRefractionMapping=function(){};THREE.UVMapping=function(){};
+THREE.ParticleDOMMaterial=function(a){this.domElement=a;this.toString=function(){return"THREE.ParticleDOMMaterial ( domElement: "+this.domElement+" )"}};
+THREE.Texture=function(a,b,d,g,j,n){this.image=a;this.mapping=b!==undefined?b:new THREE.UVMapping;this.wrap_s=d!==undefined?d:THREE.ClampToEdgeWrapping;this.wrap_t=g!==undefined?g:THREE.ClampToEdgeWrapping;this.mag_filter=j!==undefined?j:THREE.LinearFilter;this.min_filter=n!==undefined?n:THREE.LinearMipMapLinearFilter;this.toString=function(){return"THREE.Texture (<br/>image: "+this.image+"<br/>wrap_s: "+this.wrap_s+"<br/>wrap_t: "+this.wrap_t+"<br/>mag_filter: "+this.mag_filter+"<br/>min_filter: "+
+this.min_filter+"<br/>)"}};THREE.MultiplyOperation=0;THREE.MixOperation=1;THREE.RepeatWrapping=0;THREE.ClampToEdgeWrapping=1;THREE.MirroredRepeatWrapping=2;THREE.NearestFilter=3;THREE.NearestMipMapNearestFilter=4;THREE.NearestMipMapLinearFilter=5;THREE.LinearFilter=6;THREE.LinearMipMapNearestFilter=7;THREE.LinearMipMapLinearFilter=8;THREE.CubeReflectionMapping=function(){};THREE.CubeRefractionMapping=function(){};THREE.LatitudeReflectionMapping=function(){};THREE.LatitudeRefractionMapping=function(){};
+THREE.SphericalReflectionMapping=function(){};THREE.SphericalRefractionMapping=function(){};THREE.UVMapping=function(){};
 THREE.Scene=function(){this.objects=[];this.lights=[];this.addObject=function(a){this.objects.push(a)};this.removeObject=function(a){a=this.objects.indexOf(a);a!==-1&&this.objects.splice(a,1)};this.addLight=function(a){this.lights.push(a)};this.removeLight=function(a){a=this.lights.indexOf(a);a!==-1&&this.lights.splice(a,1)};this.toString=function(){return"THREE.Scene ( "+this.objects+" )"}};
 THREE.Projector=function(){function a(O,v){var f=0,l=1,e=O.z+O.w,p=v.z+v.w,h=-O.z+O.w,i=-v.z+v.w;if(e>=0&&p>=0&&h>=0&&i>=0)return true;else if(e<0&&p<0||h<0&&i<0)return false;else{if(e<0)f=Math.max(f,e/(e-p));else if(p<0)l=Math.min(l,e/(e-p));if(h<0)f=Math.max(f,h/(h-i));else if(i<0)l=Math.min(l,h/(h-i));if(l<f)return false;else{O.lerpSelf(v,f);v.lerpSelf(O,1-l);return true}}}var b=null,d,g,j,n=[],m,k,o=[],c,F,D=[],w=new THREE.Vector4,x=new THREE.Matrix4,H=new THREE.Matrix4,G=new THREE.Vector4,K=
 new THREE.Vector4,N;this.projectScene=function(O,v){var f,l,e,p,h,i,r,q,L,B,M,Q,t,R,y,A,E;b=[];j=k=F=0;v.autoUpdateMatrix&&v.updateMatrix();x.multiply(v.projectionMatrix,v.matrix);r=O.objects;f=0;for(l=r.length;f<l;f++){q=r[f];q.autoUpdateMatrix&&q.updateMatrix();L=q.matrix;B=q.rotationMatrix;M=q.material;Q=q.overdraw;if(q instanceof THREE.Mesh){t=q.geometry.vertices;e=0;for(p=t.length;e<p;e++){R=t[e];R.positionWorld.copy(R.position);L.multiplyVector3(R.positionWorld);y=R.positionScreen;y.copy(R.positionWorld);
@@ -131,12 +133,13 @@ THREE.MeshFaceMaterial){S=0;for(X=T.faceMaterial.length;S<X;)(P=T.faceMaterial[S
 THREE.WebGLRenderer=function(a){function b(f,l){var e=c.createProgram();c.attachShader(e,m("fragment","#ifdef GL_ES\nprecision highp float;\n#endif\n"+f));c.attachShader(e,m("vertex","uniform mat4 objectMatrix;\nuniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\nuniform vec3 cameraPosition;\nattribute vec3 position;\nattribute vec3 normal;\nattribute vec2 uv;\n"+l));c.linkProgram(e);c.getProgramParameter(e,c.LINK_STATUS)||alert("Could not initialise shaders\nVALIDATE_STATUS: "+c.getProgramParameter(e,
 c.VALIDATE_STATUS)+", gl error ["+c.getError()+"]");e.uniforms={};e.attributes={};return e}function d(f,l){if(f.image.length==6){if(!f.image.__webGLTextureCube&&!f.image.__cubeMapInitialized&&f.image.loadCount==6){f.image.__webGLTextureCube=c.createTexture();c.bindTexture(c.TEXTURE_CUBE_MAP,f.image.__webGLTextureCube);c.texParameteri(c.TEXTURE_CUBE_MAP,c.TEXTURE_WRAP_S,c.CLAMP_TO_EDGE);c.texParameteri(c.TEXTURE_CUBE_MAP,c.TEXTURE_WRAP_T,c.CLAMP_TO_EDGE);c.texParameteri(c.TEXTURE_CUBE_MAP,c.TEXTURE_MAG_FILTER,
 c.LINEAR);c.texParameteri(c.TEXTURE_CUBE_MAP,c.TEXTURE_MIN_FILTER,c.LINEAR_MIPMAP_LINEAR);for(var e=0;e<6;++e)c.texImage2D(c.TEXTURE_CUBE_MAP_POSITIVE_X+e,0,c.RGBA,c.RGBA,c.UNSIGNED_BYTE,f.image[e]);c.generateMipmap(c.TEXTURE_CUBE_MAP);c.bindTexture(c.TEXTURE_CUBE_MAP,null);f.image.__cubeMapInitialized=true}c.activeTexture(c.TEXTURE0+l);c.bindTexture(c.TEXTURE_CUBE_MAP,f.image.__webGLTextureCube)}}function g(f,l){if(!f.__webGLTexture&&f.image.loaded){f.__webGLTexture=c.createTexture();c.bindTexture(c.TEXTURE_2D,
-f.__webGLTexture);c.texImage2D(c.TEXTURE_2D,0,c.RGBA,c.RGBA,c.UNSIGNED_BYTE,f.image);c.texParameteri(c.TEXTURE_2D,c.TEXTURE_WRAP_S,k(f.wrap_s));c.texParameteri(c.TEXTURE_2D,c.TEXTURE_WRAP_T,k(f.wrap_t));c.texParameteri(c.TEXTURE_2D,c.TEXTURE_MAG_FILTER,c.LINEAR);c.texParameteri(c.TEXTURE_2D,c.TEXTURE_MIN_FILTER,c.LINEAR_MIPMAP_LINEAR);c.generateMipmap(c.TEXTURE_2D);c.bindTexture(c.TEXTURE_2D,null)}c.activeTexture(c.TEXTURE0+l);c.bindTexture(c.TEXTURE_2D,f.__webGLTexture)}function j(f,l){var e,p,h;
+f.__webGLTexture);c.texImage2D(c.TEXTURE_2D,0,c.RGBA,c.RGBA,c.UNSIGNED_BYTE,f.image);c.texParameteri(c.TEXTURE_2D,c.TEXTURE_WRAP_S,k(f.wrap_s));c.texParameteri(c.TEXTURE_2D,c.TEXTURE_WRAP_T,k(f.wrap_t));c.texParameteri(c.TEXTURE_2D,c.TEXTURE_MAG_FILTER,k(f.mag_filter));c.texParameteri(c.TEXTURE_2D,c.TEXTURE_MIN_FILTER,k(f.min_filter));c.generateMipmap(c.TEXTURE_2D);c.bindTexture(c.TEXTURE_2D,null)}c.activeTexture(c.TEXTURE0+l);c.bindTexture(c.TEXTURE_2D,f.__webGLTexture)}function j(f,l){var e,p,h;
 e=0;for(p=l.length;e<p;e++){h=l[e];f.uniforms[h]=c.getUniformLocation(f,h)}}function n(f,l){var e,p,h;e=0;for(p=l.length;e<p;e++){h=l[e];f.attributes[h]=c.getAttribLocation(f,h);f.attributes[h]>=0&&c.enableVertexAttribArray(f.attributes[h])}}function m(f,l){var e;if(f=="fragment")e=c.createShader(c.FRAGMENT_SHADER);else if(f=="vertex")e=c.createShader(c.VERTEX_SHADER);c.shaderSource(e,l);c.compileShader(e);if(!c.getShaderParameter(e,c.COMPILE_STATUS)){alert(c.getShaderInfoLog(e));return null}return e}
-function k(f){switch(f){case THREE.Repeat:return c.REPEAT;case THREE.ClampToEdge:return c.CLAMP_TO_EDGE;case THREE.MirroredRepeat:return c.MIRRORED_REPEAT}return 0}var o=document.createElement("canvas"),c,F,D,w=new THREE.Matrix4,x,H=new Float32Array(16),G=new Float32Array(16),K=new Float32Array(16),N=new Float32Array(9),O=new Float32Array(16);a=function(f,l){if(f){var e,p,h,i=pointLights=maxDirLights=maxPointLights=0;e=0;for(p=f.lights.length;e<p;e++){h=f.lights[e];h instanceof THREE.DirectionalLight&&
-i++;h instanceof THREE.PointLight&&pointLights++}if(pointLights+i<=l){maxDirLights=i;maxPointLights=pointLights}else{maxDirLights=Math.ceil(l*i/(pointLights+i));maxPointLights=l-maxDirLights}return{directional:maxDirLights,point:maxPointLights}}return{directional:1,point:l-1}}(a,4);this.domElement=o;this.autoClear=true;try{c=o.getContext("experimental-webgl",{antialias:true})}catch(v){}if(!c){alert("WebGL not supported");throw"cannot create webgl context";}c.clearColor(0,0,0,1);c.clearDepth(1);c.enable(c.DEPTH_TEST);
-c.depthFunc(c.LEQUAL);c.frontFace(c.CCW);c.cullFace(c.BACK);c.enable(c.CULL_FACE);c.enable(c.BLEND);c.blendFunc(c.ONE,c.ONE_MINUS_SRC_ALPHA);c.clearColor(0,0,0,0);F=D=function(f,l){var e=[f?"#define MAX_DIR_LIGHTS "+f:"",l?"#define MAX_POINT_LIGHTS "+l:"","uniform bool enableLighting;\nuniform bool useRefract;\nuniform int pointLightNumber;\nuniform int directionalLightNumber;\nuniform vec3 ambientLightColor;",f?"uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];":"",f?"uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];":
-"",l?"uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];":"",l?"uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];":"","uniform mat4 viewMatrix;\nuniform mat3 normalMatrix;\nvarying vec3 vNormal;\nvarying vec2 vUv;\nvarying vec3 vLightWeighting;",l?"varying vec3 vPointLightVector[ MAX_POINT_LIGHTS ];":"","varying vec3 vViewPosition;\nvarying vec3 vReflect;\nuniform float mRefractionRatio;\nvoid main(void) {\nvec4 mPosition = objectMatrix * vec4( position, 1.0 );\nvViewPosition = cameraPosition - mPosition.xyz;\nvec3 nWorld = mat3( objectMatrix[0].xyz, objectMatrix[1].xyz, objectMatrix[2].xyz ) * normal;\nvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\nvec3 transformedNormal = normalize( normalMatrix * normal );\nif ( !enableLighting ) {\nvLightWeighting = vec3( 1.0, 1.0, 1.0 );\n} else {\nvLightWeighting = ambientLightColor;",
+function k(f){switch(f){case THREE.RepeatWrapping:return c.REPEAT;case THREE.ClampToEdgeWrapping:return c.CLAMP_TO_EDGE;case THREE.MirroredRepeatWrapping:return c.MIRRORED_REPEAT;case THREE.NearestFilter:return c.NEAREST;case THREE.NearestMipMapNearestFilter:return c.NEAREST_MIPMAP_NEAREST;case THREE.NearestMipMapLinearFilter:return c.NEAREST_MIPMAP_LINEAR;case THREE.LinearFilter:return c.LINEAR;case THREE.LinearMipMapNearestFilter:return c.LINEAR_MIPMAP_NEAREST;case THREE.LinearMipMapLinearFilter:return c.LINEAR_MIPMAP_LINEAR}return 0}
+var o=document.createElement("canvas"),c,F,D,w=new THREE.Matrix4,x,H=new Float32Array(16),G=new Float32Array(16),K=new Float32Array(16),N=new Float32Array(9),O=new Float32Array(16);a=function(f,l){if(f){var e,p,h,i=pointLights=maxDirLights=maxPointLights=0;e=0;for(p=f.lights.length;e<p;e++){h=f.lights[e];h instanceof THREE.DirectionalLight&&i++;h instanceof THREE.PointLight&&pointLights++}if(pointLights+i<=l){maxDirLights=i;maxPointLights=pointLights}else{maxDirLights=Math.ceil(l*i/(pointLights+i));
+maxPointLights=l-maxDirLights}return{directional:maxDirLights,point:maxPointLights}}return{directional:1,point:l-1}}(a,4);this.domElement=o;this.autoClear=true;try{c=o.getContext("experimental-webgl",{antialias:true})}catch(v){}if(!c){alert("WebGL not supported");throw"cannot create webgl context";}c.clearColor(0,0,0,1);c.clearDepth(1);c.enable(c.DEPTH_TEST);c.depthFunc(c.LEQUAL);c.frontFace(c.CCW);c.cullFace(c.BACK);c.enable(c.CULL_FACE);c.enable(c.BLEND);c.blendFunc(c.ONE,c.ONE_MINUS_SRC_ALPHA);
+c.clearColor(0,0,0,0);F=D=function(f,l){var e=[f?"#define MAX_DIR_LIGHTS "+f:"",l?"#define MAX_POINT_LIGHTS "+l:"","uniform bool enableLighting;\nuniform bool useRefract;\nuniform int pointLightNumber;\nuniform int directionalLightNumber;\nuniform vec3 ambientLightColor;",f?"uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];":"",f?"uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];":"",l?"uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];":"",l?"uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];":
+"","uniform mat4 viewMatrix;\nuniform mat3 normalMatrix;\nvarying vec3 vNormal;\nvarying vec2 vUv;\nvarying vec3 vLightWeighting;",l?"varying vec3 vPointLightVector[ MAX_POINT_LIGHTS ];":"","varying vec3 vViewPosition;\nvarying vec3 vReflect;\nuniform float mRefractionRatio;\nvoid main(void) {\nvec4 mPosition = objectMatrix * vec4( position, 1.0 );\nvViewPosition = cameraPosition - mPosition.xyz;\nvec3 nWorld = mat3( objectMatrix[0].xyz, objectMatrix[1].xyz, objectMatrix[2].xyz ) * normal;\nvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\nvec3 transformedNormal = normalize( normalMatrix * normal );\nif ( !enableLighting ) {\nvLightWeighting = vec3( 1.0, 1.0, 1.0 );\n} else {\nvLightWeighting = ambientLightColor;",
 f?"for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {":"",f?"vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );":"",f?"float directionalLightWeighting = max( dot( transformedNormal, normalize(lDirection.xyz ) ), 0.0 );":"",f?"vLightWeighting += directionalLightColor[ i ] * directionalLightWeighting;":"",f?"}":"",l?"for( int i = 0; i < MAX_POINT_LIGHTS; i++ ) {":"",l?"vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );":"",l?"vPointLightVector[ i ] = normalize( lPosition.xyz - mvPosition.xyz );":
 "",l?"float pointLightWeighting = max( dot( transformedNormal, vPointLightVector[ i ] ), 0.0 );":"",l?"vLightWeighting += pointLightColor[ i ] * pointLightWeighting;":"",l?"}":"","}\nvNormal = transformedNormal;\nvUv = uv;\nif ( useRefract ) {\nvReflect = refract( normalize(mPosition.xyz - cameraPosition), normalize(nWorld.xyz), mRefractionRatio );\n} else {\nvReflect = reflect( normalize(mPosition.xyz - cameraPosition), normalize(nWorld.xyz) );\n}\ngl_Position = projectionMatrix * mvPosition;\n}"].join("\n"),
 p=[f?"#define MAX_DIR_LIGHTS "+f:"",l?"#define MAX_POINT_LIGHTS "+l:"","uniform int material;\nuniform bool enableMap;\nuniform bool enableCubeMap;\nuniform bool mixEnvMap;\nuniform samplerCube tCube;\nuniform float mReflectivity;\nuniform sampler2D tMap;\nuniform vec4 mColor;\nuniform float mOpacity;\nuniform vec4 mAmbient;\nuniform vec4 mSpecular;\nuniform float mShininess;\nuniform float m2Near;\nuniform float mFarPlusNear;\nuniform float mFarMinusNear;\nuniform int pointLightNumber;\nuniform int directionalLightNumber;",

+ 10 - 7
build/ThreeExtras.js

@@ -81,8 +81,10 @@ a.uniforms;if(a.shading!==undefined)this.shading=a.shading;if(a.blending!==undef
 this.blending+"<br/>wireframe: "+this.wireframe+"<br/>wireframe_linewidth: "+this.wireframe_linewidth+"<br/>wireframe_linecap: "+this.wireframe_linecap+"<br/>wireframe_linejoin: "+this.wireframe_linejoin+"<br/>)"}};THREE.MeshShaderMaterialCounter={value:0};
 THREE.ParticleBasicMaterial=function(a){this.color=new THREE.Color(16711680);this.map=null;this.opacity=1;this.blending=THREE.NormalBlending;this.offset=new THREE.Vector2;if(a){a.color!==undefined&&this.color.setHex(a.color);if(a.map!==undefined)this.map=a.map;if(a.opacity!==undefined)this.opacity=a.opacity;if(a.blending!==undefined)this.blending=a.blending}this.toString=function(){return"THREE.ParticleBasicMaterial (<br/>color: "+this.color+"<br/>map: "+this.map+"<br/>opacity: "+this.opacity+"<br/>blending: "+
 this.blending+"<br/>)"}};THREE.ParticleCircleMaterial=function(a){this.color=new THREE.Color(16711680);this.opacity=1;this.blending=THREE.NormalBlending;if(a){a.color!==undefined&&this.color.setHex(a.color);if(a.opacity!==undefined)this.opacity=a.opacity;if(a.blending!==undefined)this.blending=a.blending}this.toString=function(){return"THREE.ParticleCircleMaterial (<br/>color: "+this.color+"<br/>opacity: "+this.opacity+"<br/>blending: "+this.blending+"<br/>)"}};
-THREE.ParticleDOMMaterial=function(a){this.domElement=a;this.toString=function(){return"THREE.ParticleDOMMaterial ( domElement: "+this.domElement+" )"}};THREE.Texture=function(a,b,d,e){this.image=a;this.mapping=b!==undefined?b:new THREE.UVMapping;this.wrap_s=d!==undefined?d:THREE.ClampToEdge;this.wrap_t=e!==undefined?e:THREE.ClampToEdge;this.toString=function(){return"THREE.Texture (<br/>image: "+this.image+"<br/>wrap_s: "+this.wrap_s+"<br/>wrap_t: "+this.wrap_t+"<br/>)"}};
-THREE.MultiplyOperation=0;THREE.MixOperation=1;THREE.RepeatWrapping=0;THREE.ClampToEdgeWrapping=1;THREE.MirroredRepeatWrapping=2;THREE.CubeReflectionMapping=function(){};THREE.CubeRefractionMapping=function(){};THREE.LatitudeReflectionMapping=function(){};THREE.LatitudeRefractionMapping=function(){};THREE.SphericalReflectionMapping=function(){};THREE.SphericalRefractionMapping=function(){};THREE.UVMapping=function(){};
+THREE.ParticleDOMMaterial=function(a){this.domElement=a;this.toString=function(){return"THREE.ParticleDOMMaterial ( domElement: "+this.domElement+" )"}};
+THREE.Texture=function(a,b,d,e,g,j){this.image=a;this.mapping=b!==undefined?b:new THREE.UVMapping;this.wrap_s=d!==undefined?d:THREE.ClampToEdgeWrapping;this.wrap_t=e!==undefined?e:THREE.ClampToEdgeWrapping;this.mag_filter=g!==undefined?g:THREE.LinearFilter;this.min_filter=j!==undefined?j:THREE.LinearMipMapLinearFilter;this.toString=function(){return"THREE.Texture (<br/>image: "+this.image+"<br/>wrap_s: "+this.wrap_s+"<br/>wrap_t: "+this.wrap_t+"<br/>mag_filter: "+this.mag_filter+"<br/>min_filter: "+
+this.min_filter+"<br/>)"}};THREE.MultiplyOperation=0;THREE.MixOperation=1;THREE.RepeatWrapping=0;THREE.ClampToEdgeWrapping=1;THREE.MirroredRepeatWrapping=2;THREE.NearestFilter=3;THREE.NearestMipMapNearestFilter=4;THREE.NearestMipMapLinearFilter=5;THREE.LinearFilter=6;THREE.LinearMipMapNearestFilter=7;THREE.LinearMipMapLinearFilter=8;THREE.CubeReflectionMapping=function(){};THREE.CubeRefractionMapping=function(){};THREE.LatitudeReflectionMapping=function(){};THREE.LatitudeRefractionMapping=function(){};
+THREE.SphericalReflectionMapping=function(){};THREE.SphericalRefractionMapping=function(){};THREE.UVMapping=function(){};
 THREE.Scene=function(){this.objects=[];this.lights=[];this.addObject=function(a){this.objects.push(a)};this.removeObject=function(a){a=this.objects.indexOf(a);a!==-1&&this.objects.splice(a,1)};this.addLight=function(a){this.lights.push(a)};this.removeLight=function(a){a=this.lights.indexOf(a);a!==-1&&this.lights.splice(a,1)};this.toString=function(){return"THREE.Scene ( "+this.objects+" )"}};
 THREE.Projector=function(){function a(y,n){var i=0,m=1,h=y.z+y.w,z=n.z+n.w,l=-y.z+y.w,o=-n.z+n.w;if(h>=0&&z>=0&&l>=0&&o>=0)return true;else if(h<0&&z<0||l<0&&o<0)return false;else{if(h<0)i=Math.max(i,h/(h-z));else if(z<0)m=Math.min(m,h/(h-z));if(l<0)i=Math.max(i,l/(l-o));else if(o<0)m=Math.min(m,l/(l-o));if(m<i)return false;else{y.lerpSelf(n,i);n.lerpSelf(y,1-m);return true}}}var b=null,d,e,g,j=[],k,f,p=[],c,v,C=[],r=new THREE.Vector4,t=new THREE.Matrix4,u=new THREE.Matrix4,w=new THREE.Vector4,I=
 new THREE.Vector4,E;this.projectScene=function(y,n){var i,m,h,z,l,o,B,A,Q,K,R,T,D,V,J,L,N;b=[];g=f=v=0;n.autoUpdateMatrix&&n.updateMatrix();t.multiply(n.projectionMatrix,n.matrix);B=y.objects;i=0;for(m=B.length;i<m;i++){A=B[i];A.autoUpdateMatrix&&A.updateMatrix();Q=A.matrix;K=A.rotationMatrix;R=A.material;T=A.overdraw;if(A instanceof THREE.Mesh){D=A.geometry.vertices;h=0;for(z=D.length;h<z;h++){V=D[h];V.positionWorld.copy(V.position);Q.multiplyVector3(V.positionWorld);J=V.positionScreen;J.copy(V.positionWorld);
@@ -130,12 +132,13 @@ THREE.MeshFaceMaterial){W=0;for(q=s.faceMaterial.length;W<q;)(x=s.faceMaterial[W
 THREE.WebGLRenderer=function(a){function b(i,m){var h=c.createProgram();c.attachShader(h,k("fragment","#ifdef GL_ES\nprecision highp float;\n#endif\n"+i));c.attachShader(h,k("vertex","uniform mat4 objectMatrix;\nuniform mat4 modelViewMatrix;\nuniform mat4 projectionMatrix;\nuniform vec3 cameraPosition;\nattribute vec3 position;\nattribute vec3 normal;\nattribute vec2 uv;\n"+m));c.linkProgram(h);c.getProgramParameter(h,c.LINK_STATUS)||alert("Could not initialise shaders\nVALIDATE_STATUS: "+c.getProgramParameter(h,
 c.VALIDATE_STATUS)+", gl error ["+c.getError()+"]");h.uniforms={};h.attributes={};return h}function d(i,m){if(i.image.length==6){if(!i.image.__webGLTextureCube&&!i.image.__cubeMapInitialized&&i.image.loadCount==6){i.image.__webGLTextureCube=c.createTexture();c.bindTexture(c.TEXTURE_CUBE_MAP,i.image.__webGLTextureCube);c.texParameteri(c.TEXTURE_CUBE_MAP,c.TEXTURE_WRAP_S,c.CLAMP_TO_EDGE);c.texParameteri(c.TEXTURE_CUBE_MAP,c.TEXTURE_WRAP_T,c.CLAMP_TO_EDGE);c.texParameteri(c.TEXTURE_CUBE_MAP,c.TEXTURE_MAG_FILTER,
 c.LINEAR);c.texParameteri(c.TEXTURE_CUBE_MAP,c.TEXTURE_MIN_FILTER,c.LINEAR_MIPMAP_LINEAR);for(var h=0;h<6;++h)c.texImage2D(c.TEXTURE_CUBE_MAP_POSITIVE_X+h,0,c.RGBA,c.RGBA,c.UNSIGNED_BYTE,i.image[h]);c.generateMipmap(c.TEXTURE_CUBE_MAP);c.bindTexture(c.TEXTURE_CUBE_MAP,null);i.image.__cubeMapInitialized=true}c.activeTexture(c.TEXTURE0+m);c.bindTexture(c.TEXTURE_CUBE_MAP,i.image.__webGLTextureCube)}}function e(i,m){if(!i.__webGLTexture&&i.image.loaded){i.__webGLTexture=c.createTexture();c.bindTexture(c.TEXTURE_2D,
-i.__webGLTexture);c.texImage2D(c.TEXTURE_2D,0,c.RGBA,c.RGBA,c.UNSIGNED_BYTE,i.image);c.texParameteri(c.TEXTURE_2D,c.TEXTURE_WRAP_S,f(i.wrap_s));c.texParameteri(c.TEXTURE_2D,c.TEXTURE_WRAP_T,f(i.wrap_t));c.texParameteri(c.TEXTURE_2D,c.TEXTURE_MAG_FILTER,c.LINEAR);c.texParameteri(c.TEXTURE_2D,c.TEXTURE_MIN_FILTER,c.LINEAR_MIPMAP_LINEAR);c.generateMipmap(c.TEXTURE_2D);c.bindTexture(c.TEXTURE_2D,null)}c.activeTexture(c.TEXTURE0+m);c.bindTexture(c.TEXTURE_2D,i.__webGLTexture)}function g(i,m){var h,z,l;
+i.__webGLTexture);c.texImage2D(c.TEXTURE_2D,0,c.RGBA,c.RGBA,c.UNSIGNED_BYTE,i.image);c.texParameteri(c.TEXTURE_2D,c.TEXTURE_WRAP_S,f(i.wrap_s));c.texParameteri(c.TEXTURE_2D,c.TEXTURE_WRAP_T,f(i.wrap_t));c.texParameteri(c.TEXTURE_2D,c.TEXTURE_MAG_FILTER,f(i.mag_filter));c.texParameteri(c.TEXTURE_2D,c.TEXTURE_MIN_FILTER,f(i.min_filter));c.generateMipmap(c.TEXTURE_2D);c.bindTexture(c.TEXTURE_2D,null)}c.activeTexture(c.TEXTURE0+m);c.bindTexture(c.TEXTURE_2D,i.__webGLTexture)}function g(i,m){var h,z,l;
 h=0;for(z=m.length;h<z;h++){l=m[h];i.uniforms[l]=c.getUniformLocation(i,l)}}function j(i,m){var h,z,l;h=0;for(z=m.length;h<z;h++){l=m[h];i.attributes[l]=c.getAttribLocation(i,l);i.attributes[l]>=0&&c.enableVertexAttribArray(i.attributes[l])}}function k(i,m){var h;if(i=="fragment")h=c.createShader(c.FRAGMENT_SHADER);else if(i=="vertex")h=c.createShader(c.VERTEX_SHADER);c.shaderSource(h,m);c.compileShader(h);if(!c.getShaderParameter(h,c.COMPILE_STATUS)){alert(c.getShaderInfoLog(h));return null}return h}
-function f(i){switch(i){case THREE.Repeat:return c.REPEAT;case THREE.ClampToEdge:return c.CLAMP_TO_EDGE;case THREE.MirroredRepeat:return c.MIRRORED_REPEAT}return 0}var p=document.createElement("canvas"),c,v,C,r=new THREE.Matrix4,t,u=new Float32Array(16),w=new Float32Array(16),I=new Float32Array(16),E=new Float32Array(9),y=new Float32Array(16);a=function(i,m){if(i){var h,z,l,o=pointLights=maxDirLights=maxPointLights=0;h=0;for(z=i.lights.length;h<z;h++){l=i.lights[h];l instanceof THREE.DirectionalLight&&
-o++;l instanceof THREE.PointLight&&pointLights++}if(pointLights+o<=m){maxDirLights=o;maxPointLights=pointLights}else{maxDirLights=Math.ceil(m*o/(pointLights+o));maxPointLights=m-maxDirLights}return{directional:maxDirLights,point:maxPointLights}}return{directional:1,point:m-1}}(a,4);this.domElement=p;this.autoClear=true;try{c=p.getContext("experimental-webgl",{antialias:true})}catch(n){}if(!c){alert("WebGL not supported");throw"cannot create webgl context";}c.clearColor(0,0,0,1);c.clearDepth(1);c.enable(c.DEPTH_TEST);
-c.depthFunc(c.LEQUAL);c.frontFace(c.CCW);c.cullFace(c.BACK);c.enable(c.CULL_FACE);c.enable(c.BLEND);c.blendFunc(c.ONE,c.ONE_MINUS_SRC_ALPHA);c.clearColor(0,0,0,0);v=C=function(i,m){var h=[i?"#define MAX_DIR_LIGHTS "+i:"",m?"#define MAX_POINT_LIGHTS "+m:"","uniform bool enableLighting;\nuniform bool useRefract;\nuniform int pointLightNumber;\nuniform int directionalLightNumber;\nuniform vec3 ambientLightColor;",i?"uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];":"",i?"uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];":
-"",m?"uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];":"",m?"uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];":"","uniform mat4 viewMatrix;\nuniform mat3 normalMatrix;\nvarying vec3 vNormal;\nvarying vec2 vUv;\nvarying vec3 vLightWeighting;",m?"varying vec3 vPointLightVector[ MAX_POINT_LIGHTS ];":"","varying vec3 vViewPosition;\nvarying vec3 vReflect;\nuniform float mRefractionRatio;\nvoid main(void) {\nvec4 mPosition = objectMatrix * vec4( position, 1.0 );\nvViewPosition = cameraPosition - mPosition.xyz;\nvec3 nWorld = mat3( objectMatrix[0].xyz, objectMatrix[1].xyz, objectMatrix[2].xyz ) * normal;\nvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\nvec3 transformedNormal = normalize( normalMatrix * normal );\nif ( !enableLighting ) {\nvLightWeighting = vec3( 1.0, 1.0, 1.0 );\n} else {\nvLightWeighting = ambientLightColor;",
+function f(i){switch(i){case THREE.RepeatWrapping:return c.REPEAT;case THREE.ClampToEdgeWrapping:return c.CLAMP_TO_EDGE;case THREE.MirroredRepeatWrapping:return c.MIRRORED_REPEAT;case THREE.NearestFilter:return c.NEAREST;case THREE.NearestMipMapNearestFilter:return c.NEAREST_MIPMAP_NEAREST;case THREE.NearestMipMapLinearFilter:return c.NEAREST_MIPMAP_LINEAR;case THREE.LinearFilter:return c.LINEAR;case THREE.LinearMipMapNearestFilter:return c.LINEAR_MIPMAP_NEAREST;case THREE.LinearMipMapLinearFilter:return c.LINEAR_MIPMAP_LINEAR}return 0}
+var p=document.createElement("canvas"),c,v,C,r=new THREE.Matrix4,t,u=new Float32Array(16),w=new Float32Array(16),I=new Float32Array(16),E=new Float32Array(9),y=new Float32Array(16);a=function(i,m){if(i){var h,z,l,o=pointLights=maxDirLights=maxPointLights=0;h=0;for(z=i.lights.length;h<z;h++){l=i.lights[h];l instanceof THREE.DirectionalLight&&o++;l instanceof THREE.PointLight&&pointLights++}if(pointLights+o<=m){maxDirLights=o;maxPointLights=pointLights}else{maxDirLights=Math.ceil(m*o/(pointLights+o));
+maxPointLights=m-maxDirLights}return{directional:maxDirLights,point:maxPointLights}}return{directional:1,point:m-1}}(a,4);this.domElement=p;this.autoClear=true;try{c=p.getContext("experimental-webgl",{antialias:true})}catch(n){}if(!c){alert("WebGL not supported");throw"cannot create webgl context";}c.clearColor(0,0,0,1);c.clearDepth(1);c.enable(c.DEPTH_TEST);c.depthFunc(c.LEQUAL);c.frontFace(c.CCW);c.cullFace(c.BACK);c.enable(c.CULL_FACE);c.enable(c.BLEND);c.blendFunc(c.ONE,c.ONE_MINUS_SRC_ALPHA);
+c.clearColor(0,0,0,0);v=C=function(i,m){var h=[i?"#define MAX_DIR_LIGHTS "+i:"",m?"#define MAX_POINT_LIGHTS "+m:"","uniform bool enableLighting;\nuniform bool useRefract;\nuniform int pointLightNumber;\nuniform int directionalLightNumber;\nuniform vec3 ambientLightColor;",i?"uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];":"",i?"uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];":"",m?"uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];":"",m?"uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];":
+"","uniform mat4 viewMatrix;\nuniform mat3 normalMatrix;\nvarying vec3 vNormal;\nvarying vec2 vUv;\nvarying vec3 vLightWeighting;",m?"varying vec3 vPointLightVector[ MAX_POINT_LIGHTS ];":"","varying vec3 vViewPosition;\nvarying vec3 vReflect;\nuniform float mRefractionRatio;\nvoid main(void) {\nvec4 mPosition = objectMatrix * vec4( position, 1.0 );\nvViewPosition = cameraPosition - mPosition.xyz;\nvec3 nWorld = mat3( objectMatrix[0].xyz, objectMatrix[1].xyz, objectMatrix[2].xyz ) * normal;\nvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\nvec3 transformedNormal = normalize( normalMatrix * normal );\nif ( !enableLighting ) {\nvLightWeighting = vec3( 1.0, 1.0, 1.0 );\n} else {\nvLightWeighting = ambientLightColor;",
 i?"for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {":"",i?"vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );":"",i?"float directionalLightWeighting = max( dot( transformedNormal, normalize(lDirection.xyz ) ), 0.0 );":"",i?"vLightWeighting += directionalLightColor[ i ] * directionalLightWeighting;":"",i?"}":"",m?"for( int i = 0; i < MAX_POINT_LIGHTS; i++ ) {":"",m?"vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );":"",m?"vPointLightVector[ i ] = normalize( lPosition.xyz - mvPosition.xyz );":
 "",m?"float pointLightWeighting = max( dot( transformedNormal, vPointLightVector[ i ] ), 0.0 );":"",m?"vLightWeighting += pointLightColor[ i ] * pointLightWeighting;":"",m?"}":"","}\nvNormal = transformedNormal;\nvUv = uv;\nif ( useRefract ) {\nvReflect = refract( normalize(mPosition.xyz - cameraPosition), normalize(nWorld.xyz), mRefractionRatio );\n} else {\nvReflect = reflect( normalize(mPosition.xyz - cameraPosition), normalize(nWorld.xyz) );\n}\ngl_Position = projectionMatrix * mvPosition;\n}"].join("\n"),
 z=[i?"#define MAX_DIR_LIGHTS "+i:"",m?"#define MAX_POINT_LIGHTS "+m:"","uniform int material;\nuniform bool enableMap;\nuniform bool enableCubeMap;\nuniform bool mixEnvMap;\nuniform samplerCube tCube;\nuniform float mReflectivity;\nuniform sampler2D tMap;\nuniform vec4 mColor;\nuniform float mOpacity;\nuniform vec4 mAmbient;\nuniform vec4 mSpecular;\nuniform float mShininess;\nuniform float m2Near;\nuniform float mFarPlusNear;\nuniform float mFarMinusNear;\nuniform int pointLightNumber;\nuniform int directionalLightNumber;",

+ 15 - 3
src/materials/Texture.js

@@ -3,14 +3,17 @@
  * @author alteredq / http://alteredqualia.com/
  */
 
-THREE.Texture = function ( image, mapping, wrap_s, wrap_t ) {
+THREE.Texture = function ( image, mapping, wrap_s, wrap_t, mag_filter, min_filter ) {
 
 	this.image = image;
 
 	this.mapping = mapping !== undefined ? mapping : new THREE.UVMapping();
 
-	this.wrap_s = wrap_s !== undefined ? wrap_s : THREE.ClampToEdge;
-	this.wrap_t = wrap_t !== undefined ? wrap_t : THREE.ClampToEdge;
+	this.wrap_s = wrap_s !== undefined ? wrap_s : THREE.ClampToEdgeWrapping;
+	this.wrap_t = wrap_t !== undefined ? wrap_t : THREE.ClampToEdgeWrapping;
+
+	this.mag_filter = mag_filter !== undefined ? mag_filter : THREE.LinearFilter;
+	this.min_filter = min_filter !== undefined ? min_filter : THREE.LinearMipMapLinearFilter;
 
 	this.toString = function () {
 
@@ -18,6 +21,8 @@ THREE.Texture = function ( image, mapping, wrap_s, wrap_t ) {
 			'image: ' + this.image + '<br/>' +
 			'wrap_s: ' + this.wrap_s + '<br/>' +
 			'wrap_t: ' + this.wrap_t + '<br/>' +
+			'mag_filter: ' + this.mag_filter + '<br/>' +
+			'min_filter: ' + this.min_filter + '<br/>' +
 			')';
 
 	};
@@ -30,3 +35,10 @@ THREE.MixOperation = 1;
 THREE.RepeatWrapping = 0;
 THREE.ClampToEdgeWrapping = 1;
 THREE.MirroredRepeatWrapping = 2;
+
+THREE.NearestFilter = 3;
+THREE.NearestMipMapNearestFilter = 4;
+THREE.NearestMipMapLinearFilter = 5;
+THREE.LinearFilter = 6;
+THREE.LinearMipMapNearestFilter = 7;
+THREE.LinearMipMapLinearFilter = 8;

+ 170 - 164
src/renderers/WebGLRenderer.js

@@ -13,25 +13,25 @@ THREE.WebGLRenderer = function ( scene ) {
 
 	// This is not GPU limitation as the same shader works ok in Firefox
 	// and Chrome with "--use-gl=desktop" flag.
-	
+
 	// Difference comes from Chrome on Windows using by default ANGLE,
 	// thus going DirectX9 route (while FF uses OpenGL).
-	
+
 	// See http://code.google.com/p/chromium/issues/detail?id=63491
 
-	var _canvas = document.createElement( 'canvas' ), _gl, 
+	var _canvas = document.createElement( 'canvas' ), _gl,
 	_oldProgram, _uberProgram,
 	_modelViewMatrix = new THREE.Matrix4(), _normalMatrix,
-	
-	_viewMatrixArray = new Float32Array(16), 
-	_modelViewMatrixArray = new Float32Array(16), 
-	_projectionMatrixArray = new Float32Array(16), 
+
+	_viewMatrixArray = new Float32Array(16),
+	_modelViewMatrixArray = new Float32Array(16),
+	_projectionMatrixArray = new Float32Array(16),
 	_normalMatrixArray = new Float32Array(9),
 	_objectMatrixArray = new Float32Array(16),
 
 	// ubershader material constants
-	
-	BASIC = 0, LAMBERT = 1, PHONG = 2, DEPTH = 3, NORMAL = 4, CUBE = 5, 
+
+	BASIC = 0, LAMBERT = 1, PHONG = 2, DEPTH = 3, NORMAL = 4, CUBE = 5,
 
 	// heuristics to create shader parameters according to lights in the scene
 	// (not to blow over maxLights budget)
@@ -42,7 +42,7 @@ THREE.WebGLRenderer = function ( scene ) {
 	this.autoClear = true;
 
 	initGL();
-	
+
 	_uberProgram = initUbershader( maxLightCount.directional, maxLightCount.point );
 	_oldProgram = _uberProgram;
 
@@ -156,7 +156,7 @@ THREE.WebGLRenderer = function ( scene ) {
 		}
 
 	};
-	
+
 	this.createBuffers = function ( object, g ) {
 
 		var f, fl, fi, face, vertexNormals, normal, uv, v1, v2, v3, v4, m, ml, i,
@@ -216,7 +216,7 @@ THREE.WebGLRenderer = function ( scene ) {
 					for ( i = 0; i < 3; i ++ ) {
 
 						uvArray.push( uv[ i ].u, uv[ i ].v );
-						
+
 					}
 
 				}
@@ -266,7 +266,7 @@ THREE.WebGLRenderer = function ( scene ) {
 					for ( i = 0; i < 4; i ++ ) {
 
 						uvArray.push( uv[ i ].u, uv[ i ].v );
-						
+
 					}
 
 				}
@@ -285,7 +285,7 @@ THREE.WebGLRenderer = function ( scene ) {
 				vertexIndex += 4;
 
 			}
-			
+
 		}
 
 		if ( !vertexArray.length ) {
@@ -303,13 +303,13 @@ THREE.WebGLRenderer = function ( scene ) {
 		_gl.bufferData( _gl.ARRAY_BUFFER, new Float32Array( normalArray ), _gl.STATIC_DRAW );
 
 		if ( uvArray.length > 0 ) {
-			
+
 			geometryChunk.__webGLUVBuffer = _gl.createBuffer();
 			_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLUVBuffer );
 			_gl.bufferData( _gl.ARRAY_BUFFER, new Float32Array( uvArray ), _gl.STATIC_DRAW );
-			
+
 		}
-		
+
 		geometryChunk.__webGLFaceBuffer = _gl.createBuffer();
 		_gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, geometryChunk.__webGLFaceBuffer );
 		_gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, new Uint16Array( faceArray ), _gl.STATIC_DRAW );
@@ -331,59 +331,59 @@ THREE.WebGLRenderer = function ( scene ) {
 			mMap, envMap, mixEnvMap,
 			mRefractionRatio, useRefract,
 			program, u, identifiers, attributes;
-		
+
 
 		if ( material instanceof THREE.MeshShaderMaterial ) {
-			
+
 			if ( !material.program ) {
-				
+
 				material.program = buildProgram( material.fragment_shader, material.vertex_shader );
-				
+
 				identifiers = [ 'viewMatrix', 'modelViewMatrix', 'projectionMatrix', 'normalMatrix', 'objectMatrix', 'cameraPosition' ];
 				for( u in material.uniforms ) {
-					
+
 					identifiers.push(u);
-					
+
 				}
 				cacheUniformLocations( material.program, identifiers );
 				cacheAttributeLocations( material.program, [ "position", "normal", "uv" ] );
-				
+
 			}
-			
+
 			program = material.program;
-			
+
 		} else {
-			
+
 			program = _uberProgram;
-			
+
 		}
-		
+
 		if( program != _oldProgram ) {
-			
+
 			_gl.useProgram( program );
 			_oldProgram = program;
-			
+
 		}
-		
+
 		if ( program == _uberProgram ) {
 
 			this.setupLights( program, lights );
-			
+
 		}
-		
+
 		this.loadCamera( program, camera );
 		this.loadMatrices( program );
-		
-		
+
+
 		if ( material instanceof THREE.MeshShaderMaterial ) {
-			
+
 			mWireframe = material.wireframe;
 			mLineWidth = material.wireframe_linewidth;
-			
+
 			setUniforms( program, material.uniforms );
-			
-		} 
-		
+
+		}
+
 		if ( material instanceof THREE.MeshPhongMaterial ||
 			 material instanceof THREE.MeshLambertMaterial ||
 			 material instanceof THREE.MeshBasicMaterial ) {
@@ -466,11 +466,11 @@ THREE.WebGLRenderer = function ( scene ) {
 			envMap = material.env_map;
 
 		}
-		
+
 		if ( mMap ) {
 
 			setTexture( mMap, 0 );
-			
+
 			_gl.uniform1i( program.uniforms.tMap,  0 );
 			_gl.uniform1i( program.uniforms.enableMap, 1 );
 
@@ -483,7 +483,7 @@ THREE.WebGLRenderer = function ( scene ) {
 		if ( envMap ) {
 
 			setCubeTexture( envMap, 1 );
-			
+
 			_gl.uniform1i( program.uniforms.tCube, 1 );
 			_gl.uniform1i( program.uniforms.enableCubeMap, 1 );
 
@@ -494,7 +494,7 @@ THREE.WebGLRenderer = function ( scene ) {
 		}
 
 		attributes = program.attributes;
-		
+
 		// vertices
 
 		_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLVertexBuffer );
@@ -507,8 +507,8 @@ THREE.WebGLRenderer = function ( scene ) {
 
 		// uvs
 
-		if ( attributes.uv >= 0 ) { 
-			
+		if ( attributes.uv >= 0 ) {
+
 			if ( geometryChunk.__webGLUVBuffer ) {
 
 				_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryChunk.__webGLUVBuffer );
@@ -519,7 +519,7 @@ THREE.WebGLRenderer = function ( scene ) {
 			} else {
 
 				_gl.disableVertexAttribArray( attributes.uv );
-				
+
 			}
 
 		}
@@ -572,7 +572,7 @@ THREE.WebGLRenderer = function ( scene ) {
 
 					this.setBlending( material.blending );
 					this.renderBuffer( camera, lights, material, geometryChunk );
-					
+
 				}
 
 			}
@@ -580,10 +580,10 @@ THREE.WebGLRenderer = function ( scene ) {
 		}
 
 	};
-	
+
 	this.render = function( scene, camera ) {
 
-		var o, ol, webGLObject, object, buffer, 
+		var o, ol, webGLObject, object, buffer,
 			lights = scene.lights;
 
 		this.initWebGLObjects( scene );
@@ -595,21 +595,21 @@ THREE.WebGLRenderer = function ( scene ) {
 		}
 
 		camera.autoUpdateMatrix && camera.updateMatrix();
-		
+
 		// opaque pass
 
 		for ( o = 0, ol = scene.__webGLObjects.length; o < ol; o++ ) {
 
 			webGLObject = scene.__webGLObjects[ o ];
-			
+
 			object = webGLObject.object;
 			buffer = webGLObject.buffer;
-			
+
 			if ( object.visible ) {
 
 				this.setupMatrices( object, camera );
 				this.renderPass( camera, lights, object, buffer, THREE.NormalBlending, false );
-				
+
 			}
 
 		}
@@ -622,25 +622,25 @@ THREE.WebGLRenderer = function ( scene ) {
 
 			object = webGLObject.object;
 			buffer = webGLObject.buffer;
-			
+
 			if ( object.visible ) {
-				
+
 				this.setupMatrices( object, camera );
 
 				// opaque blended materials
-				
+
 				this.renderPass( camera, lights, object, buffer, THREE.AdditiveBlending, false );
 				this.renderPass( camera, lights, object, buffer, THREE.SubtractiveBlending, false );
-				
+
 				// transparent blended materials
-				
+
 				this.renderPass( camera, lights, object, buffer, THREE.AdditiveBlending, true );
 				this.renderPass( camera, lights, object, buffer, THREE.SubtractiveBlending, true );
 
 				// transparent normal materials
-				
+
 				this.renderPass( camera, lights, object, buffer, THREE.NormalBlending, true );
-				
+
 			}
 
 		}
@@ -663,13 +663,13 @@ THREE.WebGLRenderer = function ( scene ) {
 			object = scene.objects[ o ];
 
 			if ( scene.__webGLObjectsMap[ object.id ] == undefined ) {
-				
+
 				scene.__webGLObjectsMap[ object.id ] = {};
-				
+
 			}
-			
+
 			objmap = scene.__webGLObjectsMap[ object.id ];
-			
+
 			if ( object instanceof THREE.Mesh ) {
 
 				// create separate VBOs per geometry chunk
@@ -685,16 +685,16 @@ THREE.WebGLRenderer = function ( scene ) {
 						this.createBuffers( object, g );
 
 					}
-					
+
 					// create separate wrapper per each use of VBO
-					
+
 					if ( objmap[ g ] == undefined ) {
-					
+
 						globject = { buffer: geometryChunk, object: object };
 						scene.__webGLObjects.push( globject );
-					
+
 						objmap[ g ] = 1;
-						
+
 					}
 
 				}
@@ -712,19 +712,19 @@ THREE.WebGLRenderer = function ( scene ) {
 	this.removeObject = function ( scene, object ) {
 
 		var o, ol, zobject;
-		
+
 		for ( o = scene.__webGLObjects.length - 1; o >= 0; o-- ) {
-			
+
 			zobject = scene.__webGLObjects[ o ].object;
-			
+
 			if ( object == zobject ) {
 
 				scene.__webGLObjects.splice( o, 1 );
 
 			}
-			
+
 		}
-		
+
 	};
 
 	this.setupMatrices = function ( object, camera ) {
@@ -741,23 +741,23 @@ THREE.WebGLRenderer = function ( scene ) {
 		_normalMatrixArray.set( _normalMatrix.m );
 
 		_objectMatrixArray.set( object.matrix.flatten() );
-	
+
 	};
-	
+
 	this.loadMatrices = function ( program ) {
-		
+
 		_gl.uniformMatrix4fv( program.uniforms.viewMatrix, false, _viewMatrixArray );
 		_gl.uniformMatrix4fv( program.uniforms.modelViewMatrix, false, _modelViewMatrixArray );
 		_gl.uniformMatrix4fv( program.uniforms.projectionMatrix, false, _projectionMatrixArray );
 		_gl.uniformMatrix3fv( program.uniforms.normalMatrix, false, _normalMatrixArray );
 		_gl.uniformMatrix4fv( program.uniforms.objectMatrix, false, _objectMatrixArray );
-		
+
 	};
 
 	this.loadCamera = function( program, camera ) {
-		
+
 		_gl.uniform3f( program.uniforms.cameraPosition, camera.position.x, camera.position.y, camera.position.z );
-		
+
 	};
 
 	this.setBlending = function( blending ) {
@@ -799,7 +799,7 @@ THREE.WebGLRenderer = function ( scene ) {
 			} else {
 
 				_gl.frontFace( _gl.CW );
-				
+
 			}
 
 			if( cullFace == "back" ) {
@@ -813,7 +813,7 @@ THREE.WebGLRenderer = function ( scene ) {
 			} else {
 
 				_gl.cullFace( _gl.FRONT_AND_BACK );
-				
+
 			}
 
 			_gl.enable( _gl.CULL_FACE );
@@ -821,7 +821,7 @@ THREE.WebGLRenderer = function ( scene ) {
 		} else {
 
 			_gl.disable( _gl.CULL_FACE );
-		
+
 		}
 
 	};
@@ -852,8 +852,6 @@ THREE.WebGLRenderer = function ( scene ) {
 		_gl.enable( _gl.CULL_FACE );
 
 		_gl.enable( _gl.BLEND );
-		//_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE_MINUS_SRC_ALPHA );
-		//_gl.blendFunc( _gl.SRC_ALPHA, _gl.ONE ); // cool!
 		_gl.blendFunc( _gl.ONE, _gl.ONE_MINUS_SRC_ALPHA );
 		_gl.clearColor( 0, 0, 0, 0 );
 
@@ -1176,9 +1174,9 @@ THREE.WebGLRenderer = function ( scene ) {
 	};
 
 	function buildProgram( fragment_shader, vertex_shader ) {
-		
+
 		var program = _gl.createProgram(),
-		
+
 		prefix_fragment = [
 			"#ifdef GL_ES",
 			"precision highp float;",
@@ -1196,70 +1194,70 @@ THREE.WebGLRenderer = function ( scene ) {
 			"attribute vec2 uv;",
 			""
 		].join("\n");
-		
+
 		_gl.attachShader( program, getShader( "fragment", prefix_fragment + fragment_shader ) );
 		_gl.attachShader( program, getShader( "vertex", prefix_vertex + vertex_shader ) );
-		
+
 		_gl.linkProgram( program );
 
 		if ( !_gl.getProgramParameter( program, _gl.LINK_STATUS ) ) {
 
 			alert( "Could not initialise shaders\n"+
 					"VALIDATE_STATUS: " + _gl.getProgramParameter( program, _gl.VALIDATE_STATUS ) + ", gl error [" + _gl.getError() + "]" );
-			
+
 		}
-		
+
 		program.uniforms = {};
 		program.attributes = {};
-		
+
 		return program;
-		
+
 	};
-	
+
 	function setUniforms( program, uniforms ) {
-		
+
 		var u, value, type, location, texture;
-		
+
 		for( u in uniforms ) {
-			
+
 			type = uniforms[u].type;
 			value = uniforms[u].value;
 			location = program.uniforms[u];
-			
+
 			if( type == "i" ) {
-				
+
 				_gl.uniform1i( location, value );
-				
+
 			} else if( type == "f" ) {
-				
+
 				_gl.uniform1f( location, value );
-				
+
 			} else if( type == "t" ) {
-			
+
 				_gl.uniform1i( location, value );
-				
+
 				texture = uniforms[u].texture;
-				
+
 				if ( !texture ) continue;
-				
+
 				if ( texture.image instanceof Array && texture.image.length == 6 ) {
-					
+
 					setCubeTexture( texture, value );
-					
+
 				} else {
-					
+
 					setTexture( texture, value );
-					
+
 				}
-			
+
 			}
-			
+
 		}
-		
+
 	};
 
 	function setCubeTexture( texture, slot ) {
-		
+
 		if ( texture.image.length == 6 ) {
 
 			if ( !texture.image.__webGLTextureCube &&
@@ -1291,24 +1289,24 @@ THREE.WebGLRenderer = function ( scene ) {
 
 			_gl.activeTexture( _gl.TEXTURE0 + slot );
 			_gl.bindTexture( _gl.TEXTURE_CUBE_MAP, texture.image.__webGLTextureCube );
-		
+
 		}
-		
+
 	};
-	
+
 	function setTexture( texture, slot ) {
-		
+
 		if ( !texture.__webGLTexture && texture.image.loaded ) {
 
 			texture.__webGLTexture = _gl.createTexture();
 			_gl.bindTexture( _gl.TEXTURE_2D, texture.__webGLTexture );
 			_gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, _gl.RGBA, _gl.UNSIGNED_BYTE, texture.image );
-			
+
 			_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrap_s ) );
 			_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrap_t ) );
-			
-			_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MAG_FILTER, _gl.LINEAR );
-			_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, _gl.LINEAR_MIPMAP_LINEAR );
+
+			_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.mag_filter ) );
+			_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.min_filter ) );
 			_gl.generateMipmap( _gl.TEXTURE_2D );
 			_gl.bindTexture( _gl.TEXTURE_2D, null );
 
@@ -1316,41 +1314,41 @@ THREE.WebGLRenderer = function ( scene ) {
 
 		_gl.activeTexture( _gl.TEXTURE0 + slot );
 		_gl.bindTexture( _gl.TEXTURE_2D, texture.__webGLTexture );
-		
+
 	};
-	
+
 	function cacheUniformLocations( program, identifiers ) {
-		
+
 		var i, l, id;
-		
+
 		for( i = 0, l = identifiers.length; i < l; i++ ) {
-			
+
 			id = identifiers[ i ];
 			program.uniforms[ id ] = _gl.getUniformLocation( program, id );
-			
+
 		}
-		
+
 	};
 
 	function cacheAttributeLocations( program, identifiers ) {
 
 		var i, l, id;
-		
+
 		for( i = 0, l = identifiers.length; i < l; i++ ) {
-			
+
 			id = identifiers[ i ];
 			program.attributes[ id ] = _gl.getAttribLocation( program, id );
-			
+
 			if ( program.attributes[ id ] >= 0 ) {
-			
+
 				_gl.enableVertexAttribArray( program.attributes[ id ] );
-				
+
 			}
-		
+
 		}
-		
+
 	};
-	
+
 	function initUbershader( maxDirLights, maxPointLights ) {
 
 		var vertex_shader = generateVertexShader( maxDirLights, maxPointLights ),
@@ -1359,9 +1357,9 @@ THREE.WebGLRenderer = function ( scene ) {
 
 		//log ( vertex_shader );
 		//log ( fragment_shader );
-		
+
 		program = buildProgram( fragment_shader, vertex_shader );
-		
+
 		_gl.useProgram( program );
 
 		// matrices
@@ -1376,23 +1374,23 @@ THREE.WebGLRenderer = function ( scene ) {
 										   'enableCubeMap', 'tCube', 'mixEnvMap', 'mReflectivity',
 										   'mRefractionRatio', 'useRefract',
 										   'm2Near', 'mFarPlusNear', 'mFarMinusNear'
-		] );		
+		] );
 
 
 		if ( maxDirLights ) {
-			
-			cacheUniformLocations( program, [ 'directionalLightNumber', 'directionalLightColor', 'directionalLightDirection' ] );			
+
+			cacheUniformLocations( program, [ 'directionalLightNumber', 'directionalLightColor', 'directionalLightDirection' ] );
 
 		}
 
 		if ( maxPointLights ) {
 
-			cacheUniformLocations( program, [ 'pointLightNumber', 'pointLightColor', 'pointLightPosition' ] );			
+			cacheUniformLocations( program, [ 'pointLightNumber', 'pointLightColor', 'pointLightPosition' ] );
 
 		}
 
 		// texture (diffuse map)
-		
+
 		_gl.uniform1i( program.uniforms.enableMap, 0 );
 		_gl.uniform1i( program.uniforms.tMap, 0 );
 
@@ -1403,13 +1401,13 @@ THREE.WebGLRenderer = function ( scene ) {
 		_gl.uniform1i( program.uniforms.mixEnvMap, 0 );
 
 		// refraction
-		
+
 		_gl.uniform1i( program.uniforms.useRefract, 0 );
-		
+
 		// attribute arrays
 
 		cacheAttributeLocations( program, [ "position", "normal", "uv" ] );
-		
+
 		return program;
 
 	};
@@ -1443,17 +1441,25 @@ THREE.WebGLRenderer = function ( scene ) {
 	};
 
 	function paramThreeToGL( p ) {
-	
+
 		switch ( p ) {
-		
-		case THREE.Repeat: 	  	   return _gl.REPEAT; break;
-		case THREE.ClampToEdge:    return _gl.CLAMP_TO_EDGE; break;
-		case THREE.MirroredRepeat: return _gl.MIRRORED_REPEAT; break;
-		
+
+			case THREE.RepeatWrapping: return _gl.REPEAT; break;
+			case THREE.ClampToEdgeWrapping: return _gl.CLAMP_TO_EDGE; break;
+			case THREE.MirroredRepeatWrapping: return _gl.MIRRORED_REPEAT; break;
+
+			case THREE.NearestFilter: return _gl.NEAREST; break;
+			case THREE.NearestMipMapNearestFilter: return _gl.NEAREST_MIPMAP_NEAREST; break;
+			case THREE.NearestMipMapLinearFilter: return _gl.NEAREST_MIPMAP_LINEAR; break;
+
+			case THREE.LinearFilter: return _gl.LINEAR; break;
+			case THREE.LinearMipMapNearestFilter: return _gl.LINEAR_MIPMAP_NEAREST; break;
+			case THREE.LinearMipMapLinearFilter: return _gl.LINEAR_MIPMAP_LINEAR; break;
+
 		}
-		
+
 		return 0;
-		
+
 	};
 
 	function materialNeedsSmoothNormals( material ) {
@@ -1461,11 +1467,11 @@ THREE.WebGLRenderer = function ( scene ) {
 		return material && material.shading != undefined && material.shading == THREE.SmoothShading;
 
 	};
-	
+
 	function bufferNeedsSmoothNormals( geometryChunk, object ) {
-		
+
 		var m, ml, i, l, needsSmoothNormals = false;
-		
+
 		for ( m = 0, ml = object.material.length; m < ml; m++ ) {
 
 			meshMaterial = object.material[ m ];
@@ -1497,11 +1503,11 @@ THREE.WebGLRenderer = function ( scene ) {
 			if ( needsSmoothNormals ) break;
 
 		}
-		
+
 		return needsSmoothNormals;
-		
+
 	};
-	
+
 	function allocateLights( scene, maxLights ) {
 
 		if ( scene ) {
@@ -1536,7 +1542,7 @@ THREE.WebGLRenderer = function ( scene ) {
 		return { 'directional' : 1, 'point' : maxLights - 1 };
 
 	};
-	
+
 	/* DEBUG
 	function getGLParams() {