|
@@ -92,6 +92,40 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
this.autoClear = true;
|
|
|
this.sortObjects = true;
|
|
|
|
|
|
+ // shadow map
|
|
|
+
|
|
|
+ this.shadowMapBias = 0.0039;
|
|
|
+ this.shadowMapDarkness = 0.5;
|
|
|
+ this.shadowMapWidth = 512;
|
|
|
+ this.shadowMapHeight = 512;
|
|
|
+
|
|
|
+ this.shadowCameraNear = 1;
|
|
|
+ this.shadowCameraFar = 5000;
|
|
|
+ this.shadowCameraFov = 50;
|
|
|
+
|
|
|
+ this.shadowMap = [];
|
|
|
+ this.shadowMapEnabled = false;
|
|
|
+ this.shadowMapSoft = true;
|
|
|
+
|
|
|
+ var _cameraLight,
|
|
|
+ _shadowMatrix = [];
|
|
|
+
|
|
|
+ var depthShader = THREE.ShaderLib[ "depthRGBA" ];
|
|
|
+ var depthUniforms = THREE.UniformsUtils.clone( depthShader.uniforms );
|
|
|
+
|
|
|
+ var _depthMaterial = new THREE.MeshShaderMaterial( { fragmentShader: depthShader.fragmentShader,
|
|
|
+ vertexShader: depthShader.vertexShader,
|
|
|
+ uniforms: depthUniforms } );
|
|
|
+
|
|
|
+ var _depthMaterialMorph = new THREE.MeshShaderMaterial( { fragmentShader: depthShader.fragmentShader,
|
|
|
+ vertexShader: depthShader.vertexShader,
|
|
|
+ uniforms: depthUniforms,
|
|
|
+ morphTargets: true
|
|
|
+ } );
|
|
|
+
|
|
|
+ _depthMaterial._shadowPass = true;
|
|
|
+ _depthMaterialMorph._shadowPass = true;
|
|
|
+
|
|
|
// Init GL
|
|
|
|
|
|
try {
|
|
@@ -401,18 +435,19 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
this.setStencilShadowDarkness = function( value ) {
|
|
|
|
|
|
_stencilShadow.darkness = value;
|
|
|
+
|
|
|
};
|
|
|
|
|
|
this.getContext = function() {
|
|
|
|
|
|
return _gl;
|
|
|
|
|
|
- }
|
|
|
-
|
|
|
+ };
|
|
|
|
|
|
function setupLights ( program, lights ) {
|
|
|
|
|
|
- var l, ll, light, r = 0, g = 0, b = 0,
|
|
|
+ var l, ll, light, n,
|
|
|
+ r = 0, g = 0, b = 0,
|
|
|
color, position, intensity, distance,
|
|
|
|
|
|
zlights = _lights,
|
|
@@ -449,25 +484,41 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
doffset = dlength * 3;
|
|
|
|
|
|
- dcolors[ doffset ] = color.r * intensity;
|
|
|
+ dcolors[ doffset ] = color.r * intensity;
|
|
|
dcolors[ doffset + 1 ] = color.g * intensity;
|
|
|
dcolors[ doffset + 2 ] = color.b * intensity;
|
|
|
|
|
|
- dpositions[ doffset ] = position.x;
|
|
|
+ dpositions[ doffset ] = position.x;
|
|
|
dpositions[ doffset + 1 ] = position.y;
|
|
|
dpositions[ doffset + 2 ] = position.z;
|
|
|
|
|
|
dlength += 1;
|
|
|
|
|
|
+ } else if ( light instanceof THREE.SpotLight ) { // hack, not a proper spotlight
|
|
|
+
|
|
|
+ doffset = dlength * 3;
|
|
|
+
|
|
|
+ dcolors[ doffset ] = color.r * intensity;
|
|
|
+ dcolors[ doffset + 1 ] = color.g * intensity;
|
|
|
+ dcolors[ doffset + 2 ] = color.b * intensity;
|
|
|
+
|
|
|
+ n = 1 / position.length();
|
|
|
+
|
|
|
+ dpositions[ doffset ] = position.x * n;
|
|
|
+ dpositions[ doffset + 1 ] = position.y * n;
|
|
|
+ dpositions[ doffset + 2 ] = position.z * n;
|
|
|
+
|
|
|
+ dlength += 1;
|
|
|
+
|
|
|
} else if( light instanceof THREE.PointLight ) {
|
|
|
|
|
|
poffset = plength * 3;
|
|
|
|
|
|
- pcolors[ poffset ] = color.r * intensity;
|
|
|
+ pcolors[ poffset ] = color.r * intensity;
|
|
|
pcolors[ poffset + 1 ] = color.g * intensity;
|
|
|
pcolors[ poffset + 2 ] = color.b * intensity;
|
|
|
|
|
|
- ppositions[ poffset ] = position.x;
|
|
|
+ ppositions[ poffset ] = position.x;
|
|
|
ppositions[ poffset + 1 ] = position.y;
|
|
|
ppositions[ poffset + 2 ] = position.z;
|
|
|
|
|
@@ -923,6 +974,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
obj_skinVerticesB = geometry.skinVerticesB,
|
|
|
obj_skinIndices = geometry.skinIndices,
|
|
|
obj_skinWeights = geometry.skinWeights,
|
|
|
+
|
|
|
obj_edgeFaces = object instanceof THREE.ShadowVolume ? geometry.edgeFaces : undefined,
|
|
|
|
|
|
morphTargets = geometry.morphTargets;
|
|
@@ -1944,6 +1996,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
_gl.bufferData( _gl.ARRAY_BUFFER, morphTargetsArrays[ vk ], hint );
|
|
|
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
|
|
|
if ( dirtyColors && offset_color > 0 ) {
|
|
@@ -2511,9 +2564,28 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
};
|
|
|
|
|
|
+ function refreshUniformsShadow( uniforms, material ) {
|
|
|
+
|
|
|
+ if ( uniforms.shadowMatrix ) {
|
|
|
+
|
|
|
+ for ( var i = 0; i < _shadowMatrix.length; i ++ ) {
|
|
|
+
|
|
|
+ uniforms.shadowMatrix.value[ i ] = _shadowMatrix[ i ];
|
|
|
+ uniforms.shadowMap.texture[ i ] = _this.shadowMap[ i ];
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ uniforms.shadowDarkness.value = _this.shadowMapDarkness;
|
|
|
+ uniforms.shadowBias.value = _this.shadowMapBias;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ };
|
|
|
+
|
|
|
this.initMaterial = function ( material, lights, fog, object ) {
|
|
|
|
|
|
- var u, a, identifiers, i, parameters, maxLightCount, maxBones, shaderID;
|
|
|
+ var u, a, identifiers, i, parameters, maxLightCount, maxBones, maxShadows, shaderID;
|
|
|
|
|
|
if ( material instanceof THREE.MeshDepthMaterial ) {
|
|
|
|
|
@@ -2560,9 +2632,12 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
maxLightCount = allocateLights( lights, 4 );
|
|
|
|
|
|
+ maxShadows = allocateShadows( lights );
|
|
|
+
|
|
|
maxBones = allocateBones( object );
|
|
|
|
|
|
parameters = {
|
|
|
+
|
|
|
map: !!material.map, envMap: !!material.envMap, lightMap: !!material.lightMap,
|
|
|
vertexColors: material.vertexColors,
|
|
|
fog: fog, sizeAttenuation: material.sizeAttenuation,
|
|
@@ -2570,7 +2645,13 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
morphTargets: material.morphTargets,
|
|
|
maxMorphTargets: this.maxMorphTargets,
|
|
|
maxDirLights: maxLightCount.directional, maxPointLights: maxLightCount.point,
|
|
|
- maxBones: maxBones
|
|
|
+ maxBones: maxBones,
|
|
|
+ shadowMapEnabled: this.shadowMapEnabled && object.receiveShadow,
|
|
|
+ shadowMapSoft: this.shadowMapSoft,
|
|
|
+ shadowMapWidth: this.shadowMapWidth,
|
|
|
+ shadowMapHeight: this.shadowMapHeight,
|
|
|
+ maxShadows: maxShadows
|
|
|
+
|
|
|
};
|
|
|
|
|
|
material.program = buildProgram( shaderID, material.fragmentShader, material.vertexShader, material.uniforms, material.attributes, parameters );
|
|
@@ -2607,7 +2688,6 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
material.numSupportedMorphTargets = 0;
|
|
|
|
|
|
-
|
|
|
if ( attributes.morphTarget0 >= 0 ) {
|
|
|
|
|
|
_gl.enableVertexAttribArray( attributes.morphTarget0 );
|
|
@@ -2664,14 +2744,6 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
}
|
|
|
|
|
|
- object.__webglMorphTargetInfluences = new Float32Array( this.maxMorphTargets );
|
|
|
-
|
|
|
- for ( var i = 0, il = this.maxMorphTargets; i < il; i ++ ) {
|
|
|
-
|
|
|
- object.__webglMorphTargetInfluences[ i ] = 0;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
}
|
|
|
|
|
|
};
|
|
@@ -2684,6 +2756,22 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ if ( material.morphTargets ) {
|
|
|
+
|
|
|
+ if ( ! object.__webglMorphTargetInfluences ) {
|
|
|
+
|
|
|
+ object.__webglMorphTargetInfluences = new Float32Array( _this.maxMorphTargets );
|
|
|
+
|
|
|
+ for ( var i = 0, il = this.maxMorphTargets; i < il; i ++ ) {
|
|
|
+
|
|
|
+ object.__webglMorphTargetInfluences[ i ] = 0;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
var program = material.program,
|
|
|
p_uniforms = program.uniforms,
|
|
|
m_uniforms = material.uniforms;
|
|
@@ -2752,6 +2840,13 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
} else if ( material instanceof THREE.MeshNormalMaterial ) {
|
|
|
|
|
|
m_uniforms.opacity.value = material.opacity;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( object.receiveShadow && ! material._shadowPass ) {
|
|
|
+
|
|
|
+ refreshUniformsShadow( m_uniforms, material );
|
|
|
+
|
|
|
}
|
|
|
|
|
|
// load common uniforms
|
|
@@ -2776,7 +2871,8 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
if ( material instanceof THREE.MeshShaderMaterial ||
|
|
|
material.envMap ||
|
|
|
- material.skinning ) {
|
|
|
+ material.skinning ||
|
|
|
+ object.receiveShadow ) {
|
|
|
|
|
|
if ( p_uniforms.objectMatrix !== null ) {
|
|
|
|
|
@@ -3098,6 +3194,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
candidateInfluence = influences[ candidate ];
|
|
|
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
|
|
|
_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ candidate ] );
|
|
@@ -3108,7 +3205,9 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
used[ candidate ] = 1;
|
|
|
candidateInfluence = -1;
|
|
|
m ++;
|
|
|
+
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
|
|
|
// load updated influences uniform
|
|
@@ -3377,13 +3476,184 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
};
|
|
|
|
|
|
-
|
|
|
function painterSort( a, b ) {
|
|
|
|
|
|
return b.z - a.z;
|
|
|
|
|
|
};
|
|
|
|
|
|
+ function renderShadowMap( scene, camera ) {
|
|
|
+
|
|
|
+ var i, il, light,
|
|
|
+ j = 0,
|
|
|
+ shadowMap, shadowMatrix,
|
|
|
+ oil,
|
|
|
+ material,
|
|
|
+ o, ol, webglObject, object,
|
|
|
+ lights = scene.lights,
|
|
|
+ fog = null;
|
|
|
+
|
|
|
+ if ( ! _cameraLight ) {
|
|
|
+
|
|
|
+ _cameraLight = new THREE.Camera( _this.shadowCameraFov, camera.aspect, _this.shadowCameraNear, _this.shadowCameraFar );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ for ( i = 0, il = lights.length; i < il; i ++ ) {
|
|
|
+
|
|
|
+ light = lights[ i ];
|
|
|
+
|
|
|
+ if ( light instanceof THREE.SpotLight && light.castShadow ) {
|
|
|
+
|
|
|
+ if ( ! _this.shadowMap[ j ] ) {
|
|
|
+
|
|
|
+ var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat };
|
|
|
+ _this.shadowMap[ j ] = new THREE.WebGLRenderTarget( _this.shadowMapWidth, _this.shadowMapHeight, pars );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( ! _shadowMatrix[ j ] ) {
|
|
|
+
|
|
|
+ _shadowMatrix[ j ] = new THREE.Matrix4();
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ shadowMap = _this.shadowMap[ j ];
|
|
|
+ shadowMatrix = _shadowMatrix[ j ];
|
|
|
+
|
|
|
+ _cameraLight.position.copy( light.position );
|
|
|
+ _cameraLight.target.position.copy( light.target.position );
|
|
|
+
|
|
|
+ _cameraLight.update( undefined, true );
|
|
|
+
|
|
|
+ scene.update( undefined, false, _cameraLight );
|
|
|
+
|
|
|
+ // compute shadow matrix
|
|
|
+
|
|
|
+ shadowMatrix.set( 0.5, 0.0, 0.0, 0.5,
|
|
|
+ 0.0, 0.5, 0.0, 0.5,
|
|
|
+ 0.0, 0.0, 0.5, 0.5,
|
|
|
+ 0.0, 0.0, 0.0, 1.0 );
|
|
|
+
|
|
|
+ shadowMatrix.multiplySelf( _cameraLight.projectionMatrix );
|
|
|
+ shadowMatrix.multiplySelf( _cameraLight.matrixWorldInverse );
|
|
|
+
|
|
|
+ // render shadow map
|
|
|
+
|
|
|
+ _cameraLight.matrixWorldInverse.flattenToArray( _viewMatrixArray );
|
|
|
+ _cameraLight.projectionMatrix.flattenToArray( _projectionMatrixArray );
|
|
|
+
|
|
|
+ _projScreenMatrix.multiply( _cameraLight.projectionMatrix, _cameraLight.matrixWorldInverse );
|
|
|
+ computeFrustum( _projScreenMatrix );
|
|
|
+
|
|
|
+ _this.initWebGLObjects( scene );
|
|
|
+
|
|
|
+ setRenderTarget( shadowMap );
|
|
|
+
|
|
|
+ // using arbitrary clear color in depth pass
|
|
|
+ // creates variance in shadows
|
|
|
+
|
|
|
+ _gl.clearColor( 1, 1, 1, 1 );
|
|
|
+ //_gl.clearColor( 0, 0, 0, 1 );
|
|
|
+
|
|
|
+ _this.clear();
|
|
|
+
|
|
|
+ _gl.clearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
|
|
|
+
|
|
|
+
|
|
|
+ // set matrices & frustum culling
|
|
|
+
|
|
|
+ ol = scene.__webglObjects.length;
|
|
|
+ oil = scene.__webglObjectsImmediate.length;
|
|
|
+
|
|
|
+ for ( o = 0; o < ol; o ++ ) {
|
|
|
+
|
|
|
+ webglObject = scene.__webglObjects[ o ];
|
|
|
+ object = webglObject.object;
|
|
|
+
|
|
|
+ if ( object.visible && object.castShadow ) {
|
|
|
+
|
|
|
+ if ( ! ( object instanceof THREE.Mesh ) || isInFrustum( object ) ) {
|
|
|
+
|
|
|
+ object.matrixWorld.flattenToArray( object._objectMatrixArray );
|
|
|
+
|
|
|
+ setupMatrices( object, _cameraLight, false );
|
|
|
+
|
|
|
+ webglObject.render = true;
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ webglObject.render = false;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ webglObject.render = false;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ setDepthTest( true );
|
|
|
+ setBlending( THREE.NormalBlending ); // maybe blending should be just disabled?
|
|
|
+
|
|
|
+ //_gl.cullFace( _gl.FRONT );
|
|
|
+
|
|
|
+ for ( o = 0; o < ol; o ++ ) {
|
|
|
+
|
|
|
+ webglObject = scene.__webglObjects[ o ];
|
|
|
+
|
|
|
+ if ( webglObject.render ) {
|
|
|
+
|
|
|
+ object = webglObject.object;
|
|
|
+ buffer = webglObject.buffer;
|
|
|
+
|
|
|
+ setObjectFaces( object );
|
|
|
+
|
|
|
+ material = object.geometry.morphTargets.length ? _depthMaterialMorph : _depthMaterial;
|
|
|
+
|
|
|
+ renderBuffer( _cameraLight, lights, fog, material, buffer, object );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ for ( o = 0; o < oil; o++ ) {
|
|
|
+
|
|
|
+ webglObject = scene.__webglObjectsImmediate[ o ];
|
|
|
+ object = webglObject.object;
|
|
|
+
|
|
|
+ if ( object.visible && object.castShadow ) {
|
|
|
+
|
|
|
+ if( object.matrixAutoUpdate ) {
|
|
|
+
|
|
|
+ object.matrixWorld.flattenToArray( object._objectMatrixArray );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ setupMatrices( object, _cameraLight, false );
|
|
|
+
|
|
|
+ setObjectFaces( object );
|
|
|
+
|
|
|
+ program = setProgram( _cameraLight, lights, fog, _depthMaterial, object );
|
|
|
+ object.render( function( object ) { renderBufferImmediate( object, program, _depthMaterial.shading ); } );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ //_gl.cullFace( _gl.BACK );
|
|
|
+
|
|
|
+ j ++;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ };
|
|
|
+
|
|
|
this.render = function( scene, camera, renderTarget, forceClear ) {
|
|
|
|
|
|
var i, program, opaque, transparent, material,
|
|
@@ -3391,6 +3661,8 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
lights = scene.lights,
|
|
|
fog = scene.fog;
|
|
|
|
|
|
+ if ( this.shadowMapEnabled ) renderShadowMap( scene, camera );
|
|
|
+
|
|
|
_this.data.vertices = 0;
|
|
|
_this.data.faces = 0;
|
|
|
_this.data.drawCalls = 0;
|
|
@@ -3430,7 +3702,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
object.matrixWorld.flattenToArray( object._objectMatrixArray );
|
|
|
|
|
|
- setupMatrices( object, camera );
|
|
|
+ setupMatrices( object, camera, true );
|
|
|
|
|
|
unrollBufferMaterials( webglObject );
|
|
|
|
|
@@ -3488,7 +3760,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
}
|
|
|
|
|
|
- setupMatrices( object, camera );
|
|
|
+ setupMatrices( object, camera, true );
|
|
|
|
|
|
unrollImmediateBufferMaterials( webglObject );
|
|
|
|
|
@@ -4183,10 +4455,15 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
};
|
|
|
|
|
|
|
|
|
- function setupMatrices( object, camera ) {
|
|
|
+ function setupMatrices( object, camera, computeNormalMatrix ) {
|
|
|
|
|
|
object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
|
|
|
- THREE.Matrix4.makeInvert3x3( object._modelViewMatrix ).transposeIntoArray( object._normalMatrixArray );
|
|
|
+
|
|
|
+ if ( computeNormalMatrix ) {
|
|
|
+
|
|
|
+ THREE.Matrix4.makeInvert3x3( object._modelViewMatrix ).transposeIntoArray( object._normalMatrixArray );
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
};
|
|
|
|
|
@@ -4787,6 +5064,8 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
|
|
|
"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
|
|
|
|
|
|
+ "#define MAX_SHADOWS " + parameters.maxShadows,
|
|
|
+
|
|
|
"#define MAX_BONES " + parameters.maxBones,
|
|
|
|
|
|
parameters.map ? "#define USE_MAP" : "",
|
|
@@ -4796,6 +5075,9 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
parameters.skinning ? "#define USE_SKINNING" : "",
|
|
|
parameters.morphTargets ? "#define USE_MORPHTARGETS" : "",
|
|
|
|
|
|
+ parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
|
|
|
+ parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
|
|
|
+
|
|
|
parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",
|
|
|
|
|
|
"uniform mat4 objectMatrix;",
|
|
@@ -4853,6 +5135,8 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
|
|
|
"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
|
|
|
|
|
|
+ "#define MAX_SHADOWS " + parameters.maxShadows,
|
|
|
+
|
|
|
parameters.fog ? "#define USE_FOG" : "",
|
|
|
parameters.fog instanceof THREE.FogExp2 ? "#define FOG_EXP2" : "",
|
|
|
|
|
@@ -4861,6 +5145,11 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
parameters.lightMap ? "#define USE_LIGHTMAP" : "",
|
|
|
parameters.vertexColors ? "#define USE_COLOR" : "",
|
|
|
|
|
|
+ parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
|
|
|
+ parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
|
|
|
+ parameters.shadowMapSoft ? "#define SHADOWMAP_WIDTH " + parameters.shadowMapWidth.toFixed( 1 ) : "",
|
|
|
+ parameters.shadowMapSoft ? "#define SHADOWMAP_HEIGHT " + parameters.shadowMapHeight.toFixed( 1 ) : "",
|
|
|
+
|
|
|
"uniform mat4 viewMatrix;",
|
|
|
"uniform vec3 cameraPosition;",
|
|
|
""
|
|
@@ -4949,14 +5238,14 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
function loadUniformsGeneric( program, uniforms ) {
|
|
|
|
|
|
- var u, uniform, value, type, location, texture;
|
|
|
+ var u, uniform, value, type, location, texture, i, il;
|
|
|
|
|
|
for( u in uniforms ) {
|
|
|
|
|
|
- location = program.uniforms[u];
|
|
|
+ location = program.uniforms[ u ];
|
|
|
if ( !location ) continue;
|
|
|
|
|
|
- uniform = uniforms[u];
|
|
|
+ uniform = uniforms[ u ];
|
|
|
|
|
|
type = uniform.type;
|
|
|
value = uniform.value;
|
|
@@ -5000,6 +5289,22 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
value.flattenToArray( uniform._array );
|
|
|
_gl.uniformMatrix4fv( location, false, uniform._array );
|
|
|
|
|
|
+ } else if( type == "m4v" ) {
|
|
|
+
|
|
|
+ if ( ! uniform._array ) {
|
|
|
+
|
|
|
+ uniform._array = new Float32Array( 16 * value.length );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ for ( i = 0, il = value.length; i < il; i ++ ) {
|
|
|
+
|
|
|
+ value[ i ].flattenToArrayOffset( uniform._array, i * 16 );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ _gl.uniformMatrix4fv( location, false, uniform._array );
|
|
|
+
|
|
|
} else if( type == "c" ) {
|
|
|
|
|
|
_gl.uniform3f( location, value.r, value.g, value.b );
|
|
@@ -5022,6 +5327,32 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ } else if( type == "tv" ) {
|
|
|
+
|
|
|
+ if ( ! uniform._array ) {
|
|
|
+
|
|
|
+ uniform._array = [];
|
|
|
+
|
|
|
+ for( i = 0, il = uniform.texture.length; i < il; i ++ ) {
|
|
|
+
|
|
|
+ uniform._array[ i ] = value + i;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ _gl.uniform1iv( location, uniform._array );
|
|
|
+
|
|
|
+ for( i = 0, il = uniform.texture.length; i < il; i ++ ) {
|
|
|
+
|
|
|
+ texture = uniform.texture[ i ];
|
|
|
+
|
|
|
+ if ( !texture ) continue;
|
|
|
+
|
|
|
+ setTexture( texture, uniform._array[ i ] );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
|
|
|
}
|
|
@@ -5608,8 +5939,9 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
light = lights[ l ];
|
|
|
|
|
|
- if ( light instanceof THREE.DirectionalLight ) dirLights++;
|
|
|
- if ( light instanceof THREE.PointLight ) pointLights++;
|
|
|
+ if ( light instanceof THREE.SpotLight ) dirLights ++; // hack, not a proper spotlight
|
|
|
+ if ( light instanceof THREE.DirectionalLight ) dirLights ++;
|
|
|
+ if ( light instanceof THREE.PointLight ) pointLights ++;
|
|
|
|
|
|
}
|
|
|
|
|
@@ -5629,6 +5961,24 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
};
|
|
|
|
|
|
+ function allocateShadows( lights ) {
|
|
|
+
|
|
|
+ var l, ll, light,
|
|
|
+ maxShadows = 0;
|
|
|
+
|
|
|
+ for ( l = 0, ll = lights.length; l < ll; l++ ) {
|
|
|
+
|
|
|
+ light = lights[ l ];
|
|
|
+
|
|
|
+ if ( light instanceof THREE.SpotLight && light.castShadow ) maxShadows ++;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ return maxShadows;
|
|
|
+
|
|
|
+ };
|
|
|
+
|
|
|
+
|
|
|
/* DEBUG
|
|
|
function getGLParams() {
|
|
|
|