|
@@ -32,14 +32,9 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
var lights = [];
|
|
var lights = [];
|
|
|
|
|
|
var opaqueObjects = [];
|
|
var opaqueObjects = [];
|
|
- var opaqueObjectsLastIndex = -1;
|
|
|
|
|
|
+ var opaqueObjectsLastIndex = - 1;
|
|
var transparentObjects = [];
|
|
var transparentObjects = [];
|
|
- var transparentObjectsLastIndex = -1;
|
|
|
|
-
|
|
|
|
- var opaqueImmediateObjects = [];
|
|
|
|
- var opaqueImmediateObjectsLastIndex = -1;
|
|
|
|
- var transparentImmediateObjects = [];
|
|
|
|
- var transparentImmediateObjectsLastIndex = -1;
|
|
|
|
|
|
+ var transparentObjectsLastIndex = - 1;
|
|
|
|
|
|
var morphInfluences = new Float32Array( 8 );
|
|
var morphInfluences = new Float32Array( 8 );
|
|
|
|
|
|
@@ -379,6 +374,16 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+ this.getViewport = function ( dimensions ) {
|
|
|
|
+
|
|
|
|
+ dimensions.x = _viewportX / pixelRatio;
|
|
|
|
+ dimensions.y = _viewportY / pixelRatio;
|
|
|
|
+
|
|
|
|
+ dimensions.z = _viewportWidth / pixelRatio;
|
|
|
|
+ dimensions.w = _viewportHeight / pixelRatio;
|
|
|
|
+
|
|
|
|
+ };
|
|
|
|
+
|
|
this.setScissor = function ( x, y, width, height ) {
|
|
this.setScissor = function ( x, y, width, height ) {
|
|
|
|
|
|
_gl.scissor(
|
|
_gl.scissor(
|
|
@@ -553,10 +558,11 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
function deallocateRenderTarget( renderTarget ) {
|
|
function deallocateRenderTarget( renderTarget ) {
|
|
|
|
|
|
var renderTargetProperties = properties.get( renderTarget );
|
|
var renderTargetProperties = properties.get( renderTarget );
|
|
|
|
+ var textureProperties = properties.get( renderTarget.texture );
|
|
|
|
|
|
- if ( ! renderTarget || renderTargetProperties.__webglTexture === undefined ) return;
|
|
|
|
|
|
+ if ( ! renderTarget || textureProperties.__webglTexture === undefined ) return;
|
|
|
|
|
|
- _gl.deleteTexture( renderTargetProperties.__webglTexture );
|
|
|
|
|
|
+ _gl.deleteTexture( textureProperties.__webglTexture );
|
|
|
|
|
|
if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) {
|
|
if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) {
|
|
|
|
|
|
@@ -574,6 +580,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ properties.delete( renderTarget.texture );
|
|
properties.delete( renderTarget );
|
|
properties.delete( renderTarget );
|
|
|
|
|
|
}
|
|
}
|
|
@@ -596,6 +603,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
if ( programInfo !== undefined ) {
|
|
if ( programInfo !== undefined ) {
|
|
|
|
|
|
programCache.releaseProgram( programInfo );
|
|
programCache.releaseProgram( programInfo );
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
@@ -803,28 +811,33 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- if ( group === undefined ) {
|
|
|
|
|
|
+ //
|
|
|
|
|
|
- var count;
|
|
|
|
|
|
+ var dataStart = 0;
|
|
|
|
+ var dataCount = Infinity;
|
|
|
|
|
|
- if ( index !== null ) {
|
|
|
|
|
|
+ if ( index !== null ) {
|
|
|
|
|
|
- count = index.array.length;
|
|
|
|
|
|
+ dataCount = index.count
|
|
|
|
|
|
- } else {
|
|
|
|
|
|
+ } else if ( position !== undefined ) {
|
|
|
|
|
|
- count = position.count;
|
|
|
|
|
|
+ dataCount = position.count;
|
|
|
|
|
|
- }
|
|
|
|
|
|
+ }
|
|
|
|
|
|
- var drawRange = geometry.drawRange;
|
|
|
|
|
|
+ var rangeStart = geometry.drawRange.start;
|
|
|
|
+ var rangeCount = geometry.drawRange.count;
|
|
|
|
|
|
- group = {
|
|
|
|
- start: drawRange.start,
|
|
|
|
- count: Math.min( drawRange.count, count )
|
|
|
|
- };
|
|
|
|
|
|
+ var groupStart = group !== null ? group.start : 0;
|
|
|
|
+ var groupCount = group !== null ? group.count : Infinity;
|
|
|
|
|
|
- }
|
|
|
|
|
|
+ var drawStart = Math.max( dataStart, rangeStart, groupStart );
|
|
|
|
+ var drawEnd = Math.min( dataStart + dataCount, rangeStart + rangeCount, groupStart + groupCount ) - 1;
|
|
|
|
+
|
|
|
|
+ var drawCount = Math.max( 0, drawEnd - drawStart + 1 );
|
|
|
|
+
|
|
|
|
+ //
|
|
|
|
|
|
if ( object instanceof THREE.Mesh ) {
|
|
if ( object instanceof THREE.Mesh ) {
|
|
|
|
|
|
@@ -845,7 +858,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
} else {
|
|
} else {
|
|
|
|
|
|
- renderer.render( group.start, group.count );
|
|
|
|
|
|
+ renderer.render( drawStart, drawCount );
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
@@ -867,12 +880,12 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- renderer.render( group.start, group.count );
|
|
|
|
|
|
+ renderer.render( drawStart, drawCount );
|
|
|
|
|
|
} else if ( object instanceof THREE.Points ) {
|
|
} else if ( object instanceof THREE.Points ) {
|
|
|
|
|
|
renderer.setMode( _gl.POINTS );
|
|
renderer.setMode( _gl.POINTS );
|
|
- renderer.render( group.start, group.count );
|
|
|
|
|
|
+ renderer.render( drawStart, drawCount );
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
@@ -915,8 +928,6 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
if ( geometryAttribute !== undefined ) {
|
|
if ( geometryAttribute !== undefined ) {
|
|
|
|
|
|
- state.enableAttribute( programAttribute );
|
|
|
|
-
|
|
|
|
var size = geometryAttribute.itemSize;
|
|
var size = geometryAttribute.itemSize;
|
|
var buffer = objects.getAttributeBuffer( geometryAttribute );
|
|
var buffer = objects.getAttributeBuffer( geometryAttribute );
|
|
|
|
|
|
@@ -926,19 +937,9 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
var stride = data.stride;
|
|
var stride = data.stride;
|
|
var offset = geometryAttribute.offset;
|
|
var offset = geometryAttribute.offset;
|
|
|
|
|
|
- _gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
|
|
|
|
- _gl.vertexAttribPointer( programAttribute, size, _gl.FLOAT, false, stride * data.array.BYTES_PER_ELEMENT, ( startIndex * stride + offset ) * data.array.BYTES_PER_ELEMENT );
|
|
|
|
-
|
|
|
|
if ( data instanceof THREE.InstancedInterleavedBuffer ) {
|
|
if ( data instanceof THREE.InstancedInterleavedBuffer ) {
|
|
|
|
|
|
- if ( extension === null ) {
|
|
|
|
-
|
|
|
|
- console.error( 'THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferAttribute but hardware does not support extension ANGLE_instanced_arrays.' );
|
|
|
|
- return;
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- extension.vertexAttribDivisorANGLE( programAttribute, data.meshPerAttribute );
|
|
|
|
|
|
+ state.enableAttributeAndDivisor( programAttribute, data.meshPerAttribute, extension );
|
|
|
|
|
|
if ( geometry.maxInstancedCount === undefined ) {
|
|
if ( geometry.maxInstancedCount === undefined ) {
|
|
|
|
|
|
@@ -946,23 +947,20 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- } else {
|
|
|
|
|
|
+ } else {
|
|
|
|
|
|
- _gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
|
|
|
|
- _gl.vertexAttribPointer( programAttribute, size, _gl.FLOAT, false, 0, startIndex * size * 4 ); // 4 bytes per Float32
|
|
|
|
|
|
+ state.enableAttribute( programAttribute );
|
|
|
|
|
|
- if ( geometryAttribute instanceof THREE.InstancedBufferAttribute ) {
|
|
|
|
|
|
+ }
|
|
|
|
|
|
- if ( extension === null ) {
|
|
|
|
|
|
+ _gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
|
|
|
|
+ _gl.vertexAttribPointer( programAttribute, size, _gl.FLOAT, false, stride * data.array.BYTES_PER_ELEMENT, ( startIndex * stride + offset ) * data.array.BYTES_PER_ELEMENT );
|
|
|
|
|
|
- console.error( 'THREE.WebGLRenderer.setupVertexAttributes: using THREE.InstancedBufferAttribute but hardware does not support extension ANGLE_instanced_arrays.' );
|
|
|
|
- return;
|
|
|
|
|
|
+ } else {
|
|
|
|
|
|
- }
|
|
|
|
|
|
+ if ( geometryAttribute instanceof THREE.InstancedBufferAttribute ) {
|
|
|
|
|
|
- extension.vertexAttribDivisorANGLE( programAttribute, geometryAttribute.meshPerAttribute );
|
|
|
|
|
|
+ state.enableAttributeAndDivisor( programAttribute, geometryAttribute.meshPerAttribute, extension );
|
|
|
|
|
|
if ( geometry.maxInstancedCount === undefined ) {
|
|
if ( geometry.maxInstancedCount === undefined ) {
|
|
|
|
|
|
@@ -970,8 +968,15 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ } else {
|
|
|
|
+
|
|
|
|
+ state.enableAttribute( programAttribute );
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ _gl.bindBuffer( _gl.ARRAY_BUFFER, buffer );
|
|
|
|
+ _gl.vertexAttribPointer( programAttribute, size, _gl.FLOAT, false, 0, startIndex * size * 4 ); // 4 bytes per Float32
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
} else if ( materialDefaultAttributeValues !== undefined ) {
|
|
} else if ( materialDefaultAttributeValues !== undefined ) {
|
|
@@ -1094,11 +1099,8 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
lights.length = 0;
|
|
lights.length = 0;
|
|
|
|
|
|
- opaqueObjectsLastIndex = -1;
|
|
|
|
- transparentObjectsLastIndex = -1;
|
|
|
|
-
|
|
|
|
- opaqueImmediateObjectsLastIndex = -1;
|
|
|
|
- transparentImmediateObjectsLastIndex = -1;
|
|
|
|
|
|
+ opaqueObjectsLastIndex = - 1;
|
|
|
|
+ transparentObjectsLastIndex = - 1;
|
|
|
|
|
|
sprites.length = 0;
|
|
sprites.length = 0;
|
|
lensFlares.length = 0;
|
|
lensFlares.length = 0;
|
|
@@ -1108,9 +1110,6 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
opaqueObjects.length = opaqueObjectsLastIndex + 1;
|
|
opaqueObjects.length = opaqueObjectsLastIndex + 1;
|
|
transparentObjects.length = transparentObjectsLastIndex + 1;
|
|
transparentObjects.length = transparentObjectsLastIndex + 1;
|
|
|
|
|
|
- opaqueImmediateObjects.length = opaqueImmediateObjectsLastIndex + 1;
|
|
|
|
- transparentImmediateObjects.length = transparentImmediateObjectsLastIndex + 1;
|
|
|
|
-
|
|
|
|
if ( _this.sortObjects === true ) {
|
|
if ( _this.sortObjects === true ) {
|
|
|
|
|
|
opaqueObjects.sort( painterSortStable );
|
|
opaqueObjects.sort( painterSortStable );
|
|
@@ -1120,7 +1119,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
//
|
|
//
|
|
|
|
|
|
- shadowMap.render( scene, camera );
|
|
|
|
|
|
+ shadowMap.render( scene );
|
|
|
|
|
|
//
|
|
//
|
|
|
|
|
|
@@ -1146,22 +1145,16 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
renderObjects( opaqueObjects, camera, lights, fog, overrideMaterial );
|
|
renderObjects( opaqueObjects, camera, lights, fog, overrideMaterial );
|
|
renderObjects( transparentObjects, camera, lights, fog, overrideMaterial );
|
|
renderObjects( transparentObjects, camera, lights, fog, overrideMaterial );
|
|
|
|
|
|
- renderObjectsImmediate( opaqueImmediateObjects, camera, lights, fog, overrideMaterial );
|
|
|
|
- renderObjectsImmediate( transparentImmediateObjects, camera, lights, fog, overrideMaterial );
|
|
|
|
-
|
|
|
|
} else {
|
|
} else {
|
|
|
|
|
|
// opaque pass (front-to-back order)
|
|
// opaque pass (front-to-back order)
|
|
|
|
|
|
state.setBlending( THREE.NoBlending );
|
|
state.setBlending( THREE.NoBlending );
|
|
-
|
|
|
|
renderObjects( opaqueObjects, camera, lights, fog );
|
|
renderObjects( opaqueObjects, camera, lights, fog );
|
|
- renderObjectsImmediate( opaqueImmediateObjects, camera, lights, fog );
|
|
|
|
|
|
|
|
// transparent pass (back-to-front order)
|
|
// transparent pass (back-to-front order)
|
|
|
|
|
|
renderObjects( transparentObjects, camera, lights, fog );
|
|
renderObjects( transparentObjects, camera, lights, fog );
|
|
- renderObjectsImmediate( transparentImmediateObjects, camera, lights, fog );
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1172,9 +1165,15 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
// Generate mipmap if we're using any kind of mipmap filtering
|
|
// Generate mipmap if we're using any kind of mipmap filtering
|
|
|
|
|
|
- if ( renderTarget && renderTarget.generateMipmaps && renderTarget.minFilter !== THREE.NearestFilter && renderTarget.minFilter !== THREE.LinearFilter ) {
|
|
|
|
|
|
+ if ( renderTarget ) {
|
|
|
|
+
|
|
|
|
+ var texture = renderTarget.texture;
|
|
|
|
+ var isTargetPowerOfTwo = isPowerOfTwo( renderTarget );
|
|
|
|
+ if ( texture.generateMipmaps && isTargetPowerOfTwo && texture.minFilter !== THREE.NearestFilter && texture.minFilter !== THREE.LinearFilter ) {
|
|
|
|
|
|
- updateRenderTargetMipmap( renderTarget );
|
|
|
|
|
|
+ updateRenderTargetMipmap( renderTarget );
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1188,40 +1187,6 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
};
|
|
};
|
|
|
|
|
|
- function pushImmediateRenderItem( object ) {
|
|
|
|
-
|
|
|
|
- var array, index;
|
|
|
|
-
|
|
|
|
- // allocate the next position in the appropriate array
|
|
|
|
-
|
|
|
|
- if ( object.material.transparent ) {
|
|
|
|
-
|
|
|
|
- array = transparentImmediateObjects;
|
|
|
|
- index = ++ transparentImmediateObjectsLastIndex;
|
|
|
|
-
|
|
|
|
- } else {
|
|
|
|
-
|
|
|
|
- array = opaqueImmediateObjects;
|
|
|
|
- index = ++ opaqueImmediateObjectsLastIndex;
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // recycle existing position or grow the array
|
|
|
|
-
|
|
|
|
- if ( index < array.length ) {
|
|
|
|
-
|
|
|
|
- array[ index ] = object;
|
|
|
|
-
|
|
|
|
- } else {
|
|
|
|
-
|
|
|
|
- // assert( index === array.length );
|
|
|
|
- array.push( object );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
function pushRenderItem( object, geometry, material, z, group ) {
|
|
function pushRenderItem( object, geometry, material, z, group ) {
|
|
|
|
|
|
var array, index;
|
|
var array, index;
|
|
@@ -1289,7 +1254,14 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
} else if ( object instanceof THREE.ImmediateRenderObject ) {
|
|
} else if ( object instanceof THREE.ImmediateRenderObject ) {
|
|
|
|
|
|
- pushImmediateRenderItem( object );
|
|
|
|
|
|
+ if ( _this.sortObjects === true ) {
|
|
|
|
+
|
|
|
|
+ _vector3.setFromMatrixPosition( object.matrixWorld );
|
|
|
|
+ _vector3.applyProjection( _projScreenMatrix );
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pushRenderItem( object, null, object.material, _vector3.z, null );
|
|
|
|
|
|
} else if ( object instanceof THREE.Mesh || object instanceof THREE.Line || object instanceof THREE.Points ) {
|
|
} else if ( object instanceof THREE.Mesh || object instanceof THREE.Line || object instanceof THREE.Points ) {
|
|
|
|
|
|
@@ -1334,7 +1306,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
} else {
|
|
} else {
|
|
|
|
|
|
- pushRenderItem( object, geometry, material, _vector3.z );
|
|
|
|
|
|
+ pushRenderItem( object, geometry, material, _vector3.z, null );
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1368,36 +1340,25 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
|
|
object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
|
|
object.normalMatrix.getNormalMatrix( object.modelViewMatrix );
|
|
object.normalMatrix.getNormalMatrix( object.modelViewMatrix );
|
|
|
|
|
|
- _this.renderBufferDirect( camera, lights, fog, geometry, material, object, group );
|
|
|
|
|
|
+ if ( object instanceof THREE.ImmediateRenderObject ) {
|
|
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
|
|
+ setMaterial( material );
|
|
|
|
|
|
- function renderObjectsImmediate( renderList, camera, lights, fog, overrideMaterial ) {
|
|
|
|
|
|
+ var program = setProgram( camera, lights, fog, material, object );
|
|
|
|
|
|
- var material = overrideMaterial;
|
|
|
|
|
|
+ _currentGeometryProgram = '';
|
|
|
|
|
|
- for ( var i = 0, l = renderList.length; i < l; i ++ ) {
|
|
|
|
-
|
|
|
|
- var object = renderList[ i ];
|
|
|
|
-
|
|
|
|
- object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
|
|
|
|
- object.normalMatrix.getNormalMatrix( object.modelViewMatrix );
|
|
|
|
|
|
+ object.render( function ( object ) {
|
|
|
|
|
|
- if ( overrideMaterial === undefined ) material = object.material;
|
|
|
|
|
|
+ _this.renderBufferImmediate( object, program, material );
|
|
|
|
|
|
- setMaterial( material );
|
|
|
|
|
|
+ } );
|
|
|
|
|
|
- var program = setProgram( camera, lights, fog, material, object );
|
|
|
|
-
|
|
|
|
- _currentGeometryProgram = '';
|
|
|
|
-
|
|
|
|
- object.render( function ( object ) {
|
|
|
|
|
|
+ } else {
|
|
|
|
|
|
- _this.renderBufferImmediate( object, program, material );
|
|
|
|
|
|
+ _this.renderBufferDirect( camera, lights, fog, geometry, material, object, group );
|
|
|
|
|
|
- } );
|
|
|
|
|
|
+ }
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1764,7 +1725,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
if ( object.receiveShadow && ! material._shadowPass ) {
|
|
if ( object.receiveShadow && ! material._shadowPass ) {
|
|
|
|
|
|
- refreshUniformsShadow( m_uniforms, lights );
|
|
|
|
|
|
+ refreshUniformsShadow( m_uniforms, lights, camera );
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1853,6 +1814,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
if ( uvScaleMap !== undefined ) {
|
|
if ( uvScaleMap !== undefined ) {
|
|
|
|
|
|
|
|
+ if ( uvScaleMap instanceof THREE.WebGLRenderTarget ) uvScaleMap = uvScaleMap.texture;
|
|
var offset = uvScaleMap.offset;
|
|
var offset = uvScaleMap.offset;
|
|
var repeat = uvScaleMap.repeat;
|
|
var repeat = uvScaleMap.repeat;
|
|
|
|
|
|
@@ -1923,7 +1885,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
function refreshUniformsPhong ( uniforms, material ) {
|
|
function refreshUniformsPhong ( uniforms, material ) {
|
|
|
|
|
|
uniforms.specular.value = material.specular;
|
|
uniforms.specular.value = material.specular;
|
|
- uniforms.shininess.value = material.shininess;
|
|
|
|
|
|
+ uniforms.shininess.value = Math.max( material.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 )
|
|
|
|
|
|
if ( material.lightMap ) {
|
|
if ( material.lightMap ) {
|
|
|
|
|
|
@@ -2016,7 +1978,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- function refreshUniformsShadow ( uniforms, lights ) {
|
|
|
|
|
|
+ function refreshUniformsShadow ( uniforms, lights, camera ) {
|
|
|
|
|
|
if ( uniforms.shadowMatrix ) {
|
|
if ( uniforms.shadowMatrix ) {
|
|
|
|
|
|
@@ -2026,19 +1988,36 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
var light = lights[ i ];
|
|
var light = lights[ i ];
|
|
|
|
|
|
- if ( ! light.castShadow ) continue;
|
|
|
|
|
|
+ if ( light.castShadow === true ) {
|
|
|
|
+
|
|
|
|
+ if ( light instanceof THREE.PointLight || light instanceof THREE.SpotLight || light instanceof THREE.DirectionalLight ) {
|
|
|
|
+
|
|
|
|
+ var shadow = light.shadow;
|
|
|
|
+
|
|
|
|
+ if ( light instanceof THREE.PointLight ) {
|
|
|
|
+
|
|
|
|
+ // for point lights we set the shadow matrix to be a translation-only matrix
|
|
|
|
+ // equal to inverse of the light's position
|
|
|
|
+ _vector3.setFromMatrixPosition( light.matrixWorld ).negate();
|
|
|
|
+ shadow.matrix.identity().setPosition( _vector3 );
|
|
|
|
+
|
|
|
|
+ // for point lights we set the sign of the shadowDarkness uniform to be negative
|
|
|
|
+ uniforms.shadowDarkness.value[ j ] = - shadow.darkness;
|
|
|
|
+
|
|
|
|
+ } else {
|
|
|
|
|
|
- if ( light instanceof THREE.SpotLight || ( light instanceof THREE.DirectionalLight ) ) {
|
|
|
|
|
|
+ uniforms.shadowDarkness.value[ j ] = shadow.darkness;
|
|
|
|
|
|
- uniforms.shadowMap.value[ j ] = light.shadowMap;
|
|
|
|
- uniforms.shadowMapSize.value[ j ] = light.shadowMapSize;
|
|
|
|
|
|
+ }
|
|
|
|
|
|
- uniforms.shadowMatrix.value[ j ] = light.shadowMatrix;
|
|
|
|
|
|
+ uniforms.shadowMatrix.value[ j ] = shadow.matrix;
|
|
|
|
+ uniforms.shadowMap.value[ j ] = shadow.map;
|
|
|
|
+ uniforms.shadowMapSize.value[ j ] = shadow.mapSize;
|
|
|
|
+ uniforms.shadowBias.value[ j ] = shadow.bias;
|
|
|
|
|
|
- uniforms.shadowDarkness.value[ j ] = light.shadowDarkness;
|
|
|
|
- uniforms.shadowBias.value[ j ] = light.shadowBias;
|
|
|
|
|
|
+ j ++;
|
|
|
|
|
|
- j ++;
|
|
|
|
|
|
+ }
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2359,7 +2338,11 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
} else if ( texture instanceof THREE.WebGLRenderTargetCube ) {
|
|
} else if ( texture instanceof THREE.WebGLRenderTargetCube ) {
|
|
|
|
|
|
- setCubeTextureDynamic( texture, textureUnit );
|
|
|
|
|
|
+ setCubeTextureDynamic( texture.texture, textureUnit );
|
|
|
|
+
|
|
|
|
+ } else if ( texture instanceof THREE.WebGLRenderTarget ) {
|
|
|
|
+
|
|
|
|
+ _this.setTexture( texture.texture, textureUnit );
|
|
|
|
|
|
} else {
|
|
} else {
|
|
|
|
|
|
@@ -2371,7 +2354,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
case 'tv':
|
|
case 'tv':
|
|
|
|
|
|
- // array of THREE.Texture (2d)
|
|
|
|
|
|
+ // array of THREE.Texture (2d or cube)
|
|
|
|
|
|
if ( uniform._array === undefined ) {
|
|
if ( uniform._array === undefined ) {
|
|
|
|
|
|
@@ -2394,7 +2377,26 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
if ( ! texture ) continue;
|
|
if ( ! texture ) continue;
|
|
|
|
|
|
- _this.setTexture( texture, textureUnit );
|
|
|
|
|
|
+ if ( texture instanceof THREE.CubeTexture ||
|
|
|
|
+ ( texture.image instanceof Array && texture.image.length === 6 ) ) {
|
|
|
|
+
|
|
|
|
+ // CompressedTexture can have Array in image :/
|
|
|
|
+
|
|
|
|
+ setCubeTexture( texture, textureUnit );
|
|
|
|
+
|
|
|
|
+ } else if ( texture instanceof THREE.WebGLRenderTarget ) {
|
|
|
|
+
|
|
|
|
+ _this.setTexture( texture.texture, textureUnit );
|
|
|
|
+
|
|
|
|
+ } else if ( texture instanceof THREE.WebGLRenderTargetCube ) {
|
|
|
|
+
|
|
|
|
+ setCubeTextureDynamic( texture.texture, textureUnit );
|
|
|
|
+
|
|
|
|
+ } else {
|
|
|
|
+
|
|
|
|
+ _this.setTexture( texture, textureUnit );
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2469,8 +2471,6 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
light = lights[ l ];
|
|
light = lights[ l ];
|
|
|
|
|
|
- if ( light.onlyShadow ) continue;
|
|
|
|
-
|
|
|
|
color = light.color;
|
|
color = light.color;
|
|
intensity = light.intensity;
|
|
intensity = light.intensity;
|
|
distance = light.distance;
|
|
distance = light.distance;
|
|
@@ -2668,7 +2668,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
if ( texture.wrapS !== THREE.ClampToEdgeWrapping || texture.wrapT !== THREE.ClampToEdgeWrapping ) {
|
|
if ( texture.wrapS !== THREE.ClampToEdgeWrapping || texture.wrapT !== THREE.ClampToEdgeWrapping ) {
|
|
|
|
|
|
- console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping. ( ' + texture.sourceFile + ' )' );
|
|
|
|
|
|
+ console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.', texture );
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2677,7 +2677,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
if ( texture.minFilter !== THREE.NearestFilter && texture.minFilter !== THREE.LinearFilter ) {
|
|
if ( texture.minFilter !== THREE.NearestFilter && texture.minFilter !== THREE.LinearFilter ) {
|
|
|
|
|
|
- console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter. ( ' + texture.sourceFile + ' )' );
|
|
|
|
|
|
+ console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.', texture );
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2707,8 +2707,6 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
textureProperties.__webglInit = true;
|
|
textureProperties.__webglInit = true;
|
|
|
|
|
|
- texture.__webglInit = true;
|
|
|
|
-
|
|
|
|
texture.addEventListener( 'dispose', onTextureDispose );
|
|
texture.addEventListener( 'dispose', onTextureDispose );
|
|
|
|
|
|
textureProperties.__webglTexture = _gl.createTexture();
|
|
textureProperties.__webglTexture = _gl.createTexture();
|
|
@@ -2726,8 +2724,14 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
texture.image = clampToMaxSize( texture.image, capabilities.maxTextureSize );
|
|
texture.image = clampToMaxSize( texture.image, capabilities.maxTextureSize );
|
|
|
|
|
|
|
|
+ if ( textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( texture.image ) === false ) {
|
|
|
|
+
|
|
|
|
+ texture.image = makePowerOfTwo( texture.image );
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
var image = texture.image,
|
|
var image = texture.image,
|
|
- isImagePowerOfTwo = THREE.Math.isPowerOfTwo( image.width ) && THREE.Math.isPowerOfTwo( image.height ),
|
|
|
|
|
|
+ isImagePowerOfTwo = isPowerOfTwo( image ),
|
|
glFormat = paramThreeToGL( texture.format ),
|
|
glFormat = paramThreeToGL( texture.format ),
|
|
glType = paramThreeToGL( texture.type );
|
|
glType = paramThreeToGL( texture.type );
|
|
|
|
|
|
@@ -2842,6 +2846,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
}
|
|
}
|
|
|
|
|
|
uploadTexture( textureProperties, texture, slot );
|
|
uploadTexture( textureProperties, texture, slot );
|
|
|
|
+
|
|
return;
|
|
return;
|
|
|
|
|
|
}
|
|
}
|
|
@@ -2877,6 +2882,42 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ function isPowerOfTwo( image ) {
|
|
|
|
+
|
|
|
|
+ return THREE.Math.isPowerOfTwo( image.width ) && THREE.Math.isPowerOfTwo( image.height );
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ function textureNeedsPowerOfTwo( texture ) {
|
|
|
|
+
|
|
|
|
+ if ( texture.wrapS !== THREE.ClampToEdgeWrapping || texture.wrapT !== THREE.ClampToEdgeWrapping ) return true;
|
|
|
|
+ if ( texture.minFilter !== THREE.NearestFilter && texture.minFilter !== THREE.LinearFilter ) return true;
|
|
|
|
+
|
|
|
|
+ return false;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ function makePowerOfTwo( image ) {
|
|
|
|
+
|
|
|
|
+ if ( image instanceof HTMLImageElement || image instanceof HTMLCanvasElement ) {
|
|
|
|
+
|
|
|
|
+ var canvas = document.createElement( 'canvas' );
|
|
|
|
+ canvas.width = THREE.Math.nearestPowerOfTwo( image.width );
|
|
|
|
+ canvas.height = THREE.Math.nearestPowerOfTwo( image.height );
|
|
|
|
+
|
|
|
|
+ var context = canvas.getContext( '2d' );
|
|
|
|
+ context.drawImage( image, 0, 0, canvas.width, canvas.height );
|
|
|
|
+
|
|
|
|
+ console.warn( 'THREE.WebGLRenderer: image is not power of two (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );
|
|
|
|
+
|
|
|
|
+ return canvas;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return image;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
function setCubeTexture ( texture, slot ) {
|
|
function setCubeTexture ( texture, slot ) {
|
|
|
|
|
|
var textureProperties = properties.get( texture );
|
|
var textureProperties = properties.get( texture );
|
|
@@ -2920,7 +2961,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
}
|
|
}
|
|
|
|
|
|
var image = cubeImage[ 0 ],
|
|
var image = cubeImage[ 0 ],
|
|
- isImagePowerOfTwo = THREE.Math.isPowerOfTwo( image.width ) && THREE.Math.isPowerOfTwo( image.height ),
|
|
|
|
|
|
+ isImagePowerOfTwo = isPowerOfTwo( image ),
|
|
glFormat = paramThreeToGL( texture.format ),
|
|
glFormat = paramThreeToGL( texture.format ),
|
|
glType = paramThreeToGL( texture.type );
|
|
glType = paramThreeToGL( texture.type );
|
|
|
|
|
|
@@ -3005,7 +3046,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
function setupFrameBuffer ( framebuffer, renderTarget, textureTarget ) {
|
|
function setupFrameBuffer ( framebuffer, renderTarget, textureTarget ) {
|
|
|
|
|
|
_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
|
|
_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
|
|
- _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureTarget, properties.get( renderTarget ).__webglTexture, 0 );
|
|
|
|
|
|
+ _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 );
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
@@ -3045,36 +3086,36 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
if ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) {
|
|
if ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) {
|
|
|
|
|
|
var renderTargetProperties = properties.get( renderTarget );
|
|
var renderTargetProperties = properties.get( renderTarget );
|
|
|
|
+ var textureProperties = properties.get( renderTarget.texture );
|
|
|
|
|
|
if ( renderTarget.depthBuffer === undefined ) renderTarget.depthBuffer = true;
|
|
if ( renderTarget.depthBuffer === undefined ) renderTarget.depthBuffer = true;
|
|
if ( renderTarget.stencilBuffer === undefined ) renderTarget.stencilBuffer = true;
|
|
if ( renderTarget.stencilBuffer === undefined ) renderTarget.stencilBuffer = true;
|
|
|
|
|
|
renderTarget.addEventListener( 'dispose', onRenderTargetDispose );
|
|
renderTarget.addEventListener( 'dispose', onRenderTargetDispose );
|
|
|
|
|
|
- renderTargetProperties.__webglTexture = _gl.createTexture();
|
|
|
|
|
|
+ textureProperties.__webglTexture = _gl.createTexture();
|
|
|
|
|
|
_infoMemory.textures ++;
|
|
_infoMemory.textures ++;
|
|
|
|
|
|
// Setup texture, create render and frame buffers
|
|
// Setup texture, create render and frame buffers
|
|
|
|
|
|
- var isTargetPowerOfTwo = THREE.Math.isPowerOfTwo( renderTarget.width ) && THREE.Math.isPowerOfTwo( renderTarget.height ),
|
|
|
|
- glFormat = paramThreeToGL( renderTarget.format ),
|
|
|
|
- glType = paramThreeToGL( renderTarget.type );
|
|
|
|
|
|
+ var isTargetPowerOfTwo = isPowerOfTwo( renderTarget ),
|
|
|
|
+ glFormat = paramThreeToGL( renderTarget.texture.format ),
|
|
|
|
+ glType = paramThreeToGL( renderTarget.texture.type );
|
|
|
|
|
|
if ( isCube ) {
|
|
if ( isCube ) {
|
|
|
|
|
|
renderTargetProperties.__webglFramebuffer = [];
|
|
renderTargetProperties.__webglFramebuffer = [];
|
|
renderTargetProperties.__webglRenderbuffer = [];
|
|
renderTargetProperties.__webglRenderbuffer = [];
|
|
|
|
|
|
- state.bindTexture( _gl.TEXTURE_CUBE_MAP, renderTargetProperties.__webglTexture );
|
|
|
|
|
|
+ state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture );
|
|
|
|
|
|
- setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget, isTargetPowerOfTwo );
|
|
|
|
|
|
+ setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo );
|
|
|
|
|
|
for ( var i = 0; i < 6; i ++ ) {
|
|
for ( var i = 0; i < 6; i ++ ) {
|
|
|
|
|
|
renderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer();
|
|
renderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer();
|
|
renderTargetProperties.__webglRenderbuffer[ i ] = _gl.createRenderbuffer();
|
|
renderTargetProperties.__webglRenderbuffer[ i ] = _gl.createRenderbuffer();
|
|
-
|
|
|
|
state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
|
|
state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
|
|
|
|
|
|
setupFrameBuffer( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
|
|
setupFrameBuffer( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
|
|
@@ -3082,7 +3123,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- if ( renderTarget.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
|
|
|
|
|
|
+ if ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
|
|
|
|
|
|
} else {
|
|
} else {
|
|
|
|
|
|
@@ -3098,8 +3139,8 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- state.bindTexture( _gl.TEXTURE_2D, renderTargetProperties.__webglTexture );
|
|
|
|
- setTextureParameters( _gl.TEXTURE_2D, renderTarget, isTargetPowerOfTwo );
|
|
|
|
|
|
+ state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );
|
|
|
|
+ setTextureParameters( _gl.TEXTURE_2D, renderTarget.texture, isTargetPowerOfTwo );
|
|
|
|
|
|
state.texImage2D( _gl.TEXTURE_2D, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
|
|
state.texImage2D( _gl.TEXTURE_2D, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
|
|
|
|
|
|
@@ -3123,7 +3164,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- if ( renderTarget.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
|
|
|
|
|
|
+ if ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
@@ -3187,75 +3228,96 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if ( isCube ) {
|
|
|
|
+
|
|
|
|
+ var textureProperties = properties.get( renderTarget.texture );
|
|
|
|
+ _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + renderTarget.activeCubeFace, textureProperties.__webglTexture, 0 );
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
_currentWidth = width;
|
|
_currentWidth = width;
|
|
_currentHeight = height;
|
|
_currentHeight = height;
|
|
|
|
|
|
};
|
|
};
|
|
|
|
|
|
- this.readRenderTargetPixels = function( renderTarget, x, y, width, height, buffer ) {
|
|
|
|
|
|
+ this.readRenderTargetPixels = function ( renderTarget, x, y, width, height, buffer ) {
|
|
|
|
|
|
- if ( ! ( renderTarget instanceof THREE.WebGLRenderTarget ) ) {
|
|
|
|
|
|
+ if ( renderTarget instanceof THREE.WebGLRenderTarget === false ) {
|
|
|
|
|
|
console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
|
|
console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.' );
|
|
return;
|
|
return;
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- if ( properties.get( renderTarget ).__webglFramebuffer ) {
|
|
|
|
-
|
|
|
|
- if ( renderTarget.format !== THREE.RGBAFormat ) {
|
|
|
|
-
|
|
|
|
- console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA format. readPixels can read only RGBA format.' );
|
|
|
|
- return;
|
|
|
|
|
|
+ var framebuffer = properties.get( renderTarget ).__webglFramebuffer;
|
|
|
|
|
|
- }
|
|
|
|
|
|
+ if ( framebuffer ) {
|
|
|
|
|
|
var restore = false;
|
|
var restore = false;
|
|
|
|
|
|
- if ( properties.get( renderTarget ).__webglFramebuffer !== _currentFramebuffer ) {
|
|
|
|
|
|
+ if ( framebuffer !== _currentFramebuffer ) {
|
|
|
|
|
|
- _gl.bindFramebuffer( _gl.FRAMEBUFFER, properties.get( renderTarget ).__webglFramebuffer );
|
|
|
|
|
|
+ _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
|
|
|
|
|
|
restore = true;
|
|
restore = true;
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- if ( _gl.checkFramebufferStatus( _gl.FRAMEBUFFER ) === _gl.FRAMEBUFFER_COMPLETE ) {
|
|
|
|
|
|
+ try {
|
|
|
|
|
|
- _gl.readPixels( x, y, width, height, _gl.RGBA, _gl.UNSIGNED_BYTE, buffer );
|
|
|
|
|
|
+ var texture = renderTarget.texture;
|
|
|
|
|
|
- } else {
|
|
|
|
|
|
+ if ( texture.format !== THREE.RGBAFormat
|
|
|
|
+ && paramThreeToGL( texture.format ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {
|
|
|
|
|
|
- console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' );
|
|
|
|
|
|
+ console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.' );
|
|
|
|
+ return;
|
|
|
|
|
|
- }
|
|
|
|
|
|
+ }
|
|
|
|
|
|
- if ( restore ) {
|
|
|
|
|
|
+ if ( texture.type !== THREE.UnsignedByteType
|
|
|
|
+ && paramThreeToGL( texture.type ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE )
|
|
|
|
+ && ! ( texture.type === THREE.FloatType && extensions.get( 'WEBGL_color_buffer_float' ) )
|
|
|
|
+ && ! ( texture.type === THREE.HalfFloatType && extensions.get( 'EXT_color_buffer_half_float' ) ) ) {
|
|
|
|
|
|
- _gl.bindFramebuffer( _gl.FRAMEBUFFER, _currentFramebuffer );
|
|
|
|
|
|
+ console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' );
|
|
|
|
+ return;
|
|
|
|
|
|
- }
|
|
|
|
|
|
+ }
|
|
|
|
|
|
- }
|
|
|
|
|
|
+ if ( _gl.checkFramebufferStatus( _gl.FRAMEBUFFER ) === _gl.FRAMEBUFFER_COMPLETE ) {
|
|
|
|
|
|
- };
|
|
|
|
|
|
+ _gl.readPixels( x, y, width, height, paramThreeToGL( texture.format ), paramThreeToGL( texture.type ), buffer );
|
|
|
|
|
|
- function updateRenderTargetMipmap ( renderTarget ) {
|
|
|
|
|
|
+ } else {
|
|
|
|
|
|
- if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) {
|
|
|
|
|
|
+ console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.' );
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
|
|
- state.bindTexture( _gl.TEXTURE_CUBE_MAP, properties.get( renderTarget ).__webglTexture );
|
|
|
|
- _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
|
|
|
|
- state.bindTexture( _gl.TEXTURE_CUBE_MAP, null );
|
|
|
|
|
|
+ } finally {
|
|
|
|
|
|
- } else {
|
|
|
|
|
|
+ if ( restore ) {
|
|
|
|
+
|
|
|
|
+ _gl.bindFramebuffer( _gl.FRAMEBUFFER, _currentFramebuffer );
|
|
|
|
|
|
- state.bindTexture( _gl.TEXTURE_2D, properties.get( renderTarget ).__webglTexture );
|
|
|
|
- _gl.generateMipmap( _gl.TEXTURE_2D );
|
|
|
|
- state.bindTexture( _gl.TEXTURE_2D, null );
|
|
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ function updateRenderTargetMipmap( renderTarget ) {
|
|
|
|
+
|
|
|
|
+ var target = renderTarget instanceof THREE.WebGLRenderTargetCube ? _gl.TEXTURE_CUBE_MAP : _gl.TEXTURE_2D;
|
|
|
|
+ var texture = properties.get( renderTarget.texture ).__webglTexture;
|
|
|
|
+
|
|
|
|
+ state.bindTexture( target, texture );
|
|
|
|
+ _gl.generateMipmap( target );
|
|
|
|
+ state.bindTexture( target, null );
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
// Fallback filters for non-power-of-2 textures
|
|
// Fallback filters for non-power-of-2 textures
|