提交 6419bd37 编写于 作者: M Mr.doob

Got CanvasRenderer and SVGRenderer using the new Scene Graph.

* The new system allow us to add lights and cameras as children of any object without hacks.
* The Camera needs to be added to a Scene. If the Camera has no parent it's added to the Scene being renderer automatically.
* I'll work on implementing this into the WebGLRenderrer tomorrow (gonna be a looong day... ).
上级 1e5fc985
...@@ -14,9 +14,12 @@ THREE.Camera = function () { ...@@ -14,9 +14,12 @@ THREE.Camera = function () {
THREE.Object3D.call( this ); THREE.Object3D.call( this );
this.projectionMatrix = new THREE.Matrix4();
this.matrixWorldInverse = new THREE.Matrix4(); this.matrixWorldInverse = new THREE.Matrix4();
this.projectionMatrix = new THREE.Matrix4();
this.projectionMatrixInverse = new THREE.Matrix4();
}; };
THREE.Camera.prototype = new THREE.Object3D(); THREE.Camera.prototype = new THREE.Object3D();
......
...@@ -446,7 +446,7 @@ THREE.Matrix4.prototype = { ...@@ -446,7 +446,7 @@ THREE.Matrix4.prototype = {
}, },
setPosition: function( v ) { setPosition: function ( v ) {
this.n14 = v.x; this.n14 = v.x;
this.n24 = v.y; this.n24 = v.y;
...@@ -456,58 +456,56 @@ THREE.Matrix4.prototype = { ...@@ -456,58 +456,56 @@ THREE.Matrix4.prototype = {
}, },
getPosition: function() { getPosition: function () {
if ( ! this.position ) { return THREE.Matrix4.__v1.set( this.n14, this.n24, this.n34 );
this.position = new THREE.Vector3();
}
this.position.set( this.n14, this.n24, this.n34 );
return this.position;
}, },
getColumnX: function() { getColumnX: function () {
if ( ! this.columnX ) {
this.columnX = new THREE.Vector3();
}
this.columnX.set( this.n11, this.n21, this.n31 ); return THREE.Matrix4.__v1.set( this.n11, this.n21, this.n31 );
return this.columnX;
}, },
getColumnY: function() { getColumnY: function () {
if ( ! this.columnY ) { return THREE.Matrix4.__v1.set( this.n12, this.n22, this.n32 );
this.columnY = new THREE.Vector3();
}
this.columnY.set( this.n12, this.n22, this.n32 );
return this.columnY;
}, },
getColumnZ: function() { getColumnZ: function() {
if ( ! this.columnZ ) { return THREE.Matrix4.__v1.set( this.n13, this.n23, this.n33 );
this.columnZ = new THREE.Vector3(); },
} getInverse: function ( m ) {
this.columnZ.set( this.n13, this.n23, this.n33 ); var n11 = m.n11, n12 = m.n12, n13 = m.n13, n14 = m.n14,
n21 = m.n21, n22 = m.n22, n23 = m.n23, n24 = m.n24,
n31 = m.n31, n32 = m.n32, n33 = m.n33, n34 = m.n34,
n41 = m.n41, n42 = m.n42, n43 = m.n43, n44 = m.n44;
return this.columnZ; this.n11 = n23*n34*n42 - n24*n33*n42 + n24*n32*n43 - n22*n34*n43 - n23*n32*n44 + n22*n33*n44;
this.n12 = n14*n33*n42 - n13*n34*n42 - n14*n32*n43 + n12*n34*n43 + n13*n32*n44 - n12*n33*n44;
this.n13 = n13*n24*n42 - n14*n23*n42 + n14*n22*n43 - n12*n24*n43 - n13*n22*n44 + n12*n23*n44;
this.n14 = n14*n23*n32 - n13*n24*n32 - n14*n22*n33 + n12*n24*n33 + n13*n22*n34 - n12*n23*n34;
this.n21 = n24*n33*n41 - n23*n34*n41 - n24*n31*n43 + n21*n34*n43 + n23*n31*n44 - n21*n33*n44;
this.n22 = n13*n34*n41 - n14*n33*n41 + n14*n31*n43 - n11*n34*n43 - n13*n31*n44 + n11*n33*n44;
this.n23 = n14*n23*n41 - n13*n24*n41 - n14*n21*n43 + n11*n24*n43 + n13*n21*n44 - n11*n23*n44;
this.n24 = n13*n24*n31 - n14*n23*n31 + n14*n21*n33 - n11*n24*n33 - n13*n21*n34 + n11*n23*n34;
this.n31 = n22*n34*n41 - n24*n32*n41 + n24*n31*n42 - n21*n34*n42 - n22*n31*n44 + n21*n32*n44;
this.n32 = n14*n32*n41 - n12*n34*n41 - n14*n31*n42 + n11*n34*n42 + n12*n31*n44 - n11*n32*n44;
this.n33 = n13*n24*n41 - n14*n22*n41 + n14*n21*n42 - n11*n24*n42 - n12*n21*n44 + n11*n22*n44;
this.n34 = n14*n22*n31 - n12*n24*n31 - n14*n21*n32 + n11*n24*n32 + n12*n21*n34 - n11*n22*n34;
this.n41 = n23*n32*n41 - n22*n33*n41 - n23*n31*n42 + n21*n33*n42 + n22*n31*n43 - n21*n32*n43;
this.n42 = n12*n33*n41 - n13*n32*n41 + n13*n31*n42 - n11*n33*n42 - n12*n31*n43 + n11*n32*n43;
this.n43 = n13*n22*n41 - n12*n23*n41 - n13*n21*n42 + n11*n23*n42 + n12*n21*n43 - n11*n22*n43;
this.n44 = n12*n23*n31 - n13*n22*n31 + n13*n21*n32 - n11*n23*n32 - n12*n21*n33 + n11*n22*n33;
this.multiplyScalar( 1 / m.determinant() );
return this;
}, },
...@@ -770,6 +768,7 @@ THREE.Matrix4.prototype = { ...@@ -770,6 +768,7 @@ THREE.Matrix4.prototype = {
}; };
/*
THREE.Matrix4.makeInvert = function ( m1, m2 ) { THREE.Matrix4.makeInvert = function ( m1, m2 ) {
// based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm // based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm
...@@ -802,6 +801,7 @@ THREE.Matrix4.makeInvert = function ( m1, m2 ) { ...@@ -802,6 +801,7 @@ THREE.Matrix4.makeInvert = function ( m1, m2 ) {
return m2; return m2;
}; };
*/
THREE.Matrix4.makeInvert3x3 = function ( m1 ) { THREE.Matrix4.makeInvert3x3 = function ( m1 ) {
......
...@@ -12,7 +12,7 @@ THREE.Projector = function() { ...@@ -12,7 +12,7 @@ THREE.Projector = function() {
_line, _lineCount, _linePool = [], _line, _lineCount, _linePool = [],
_particle, _particleCount, _particlePool = [], _particle, _particleCount, _particlePool = [],
_objectList = [], _renderList = [], _renderData = { objects: [], lights: [], elements: [] },
_vector3 = new THREE.Vector3(), _vector3 = new THREE.Vector3(),
_vector4 = new THREE.Vector4(), _vector4 = new THREE.Vector4(),
...@@ -37,7 +37,7 @@ THREE.Projector = function() { ...@@ -37,7 +37,7 @@ THREE.Projector = function() {
this.projectVector = function ( vector, camera ) { this.projectVector = function ( vector, camera ) {
THREE.Matrix4.makeInvert( camera.matrixWorld, camera.matrixWorldInverse ); camera.matrixWorldInverse.getInverse( camera.matrixWorld );
_projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse ); _projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
_projScreenMatrix.multiplyVector3( vector ); _projScreenMatrix.multiplyVector3( vector );
...@@ -48,7 +48,9 @@ THREE.Projector = function() { ...@@ -48,7 +48,9 @@ THREE.Projector = function() {
this.unprojectVector = function ( vector, camera ) { this.unprojectVector = function ( vector, camera ) {
_projScreenMatrix.multiply( camera.matrixWorld, THREE.Matrix4.makeInvert( camera.projectionMatrix ) ); camera.projectionMatrixInverse.getInverse( camera.projectionMatrix );
_projScreenMatrix.multiply( camera.matrixWorld, camera.projectionMatrixInverse );
_projScreenMatrix.multiplyVector3( vector ); _projScreenMatrix.multiplyVector3( vector );
return vector; return vector;
...@@ -79,10 +81,10 @@ THREE.Projector = function() { ...@@ -79,10 +81,10 @@ THREE.Projector = function() {
}; };
this.projectObjects = function ( object, sort ) { this.projectGraph = function ( object ) {
_objectList.length = 0; _renderData.objects.length = 0;
_objectCount = 0; _renderData.lights.length = 0;
var projectObject = function ( object ) { var projectObject = function ( object ) {
...@@ -91,15 +93,11 @@ THREE.Projector = function() { ...@@ -91,15 +93,11 @@ THREE.Projector = function() {
if ( object instanceof THREE.Particle || object instanceof THREE.Line || if ( object instanceof THREE.Particle || object instanceof THREE.Line ||
( object instanceof THREE.Mesh && ( !object.frustumCulled || isInFrustum( object ) ) ) ) { ( object instanceof THREE.Mesh && ( !object.frustumCulled || isInFrustum( object ) ) ) ) {
_object = getNextObjectInPool(); _renderData.objects.push( object );
_vector3.copy( object.position );
_projScreenMatrix.multiplyVector3( _vector3 );
_object.object = object; } else if ( object instanceof THREE.Light ) {
_object.z = _vector3.z;
_objectList.push( _object ); _renderData.lights.push( object );
} }
...@@ -111,30 +109,28 @@ THREE.Projector = function() { ...@@ -111,30 +109,28 @@ THREE.Projector = function() {
}; };
projectObject( scene ); projectObject( object );
sort && _objectList.sort( painterSort );
return _objectList; return _renderData;
}; };
this.projectScene = function ( scene, camera, sort ) { this.projectScene = function ( scene, camera, sort ) {
var near = camera.near, far = camera.far, var near = camera.near, far = camera.far,
o, ol, v, vl, f, fl, n, nl, c, cl, u, ul, objects, object, o, ol, v, vl, f, fl, n, nl, c, cl, u, ul, object,
objectMatrix, objectMatrixRotation, objectMaterials, objectOverdraw, objectMatrix, objectMatrixRotation, objectMaterials, objectOverdraw,
geometry, vertices, vertex, vertexPositionScreen, geometry, vertices, vertex, vertexPositionScreen,
faces, face, faceVertexNormals, normal, faceVertexUvs, uvs, faces, face, faceVertexNormals, normal, faceVertexUvs, uvs,
v1, v2, v3, v4; v1, v2, v3, v4;
_renderList.length = 0;
_face3Count = 0; _face3Count = 0;
_face4Count = 0; _face4Count = 0;
_lineCount = 0; _lineCount = 0;
_particleCount = 0; _particleCount = 0;
_renderData.elements.length = 0;
if ( camera.parent == null ) { if ( camera.parent == null ) {
console.warn( "Camera is not on the Scene. Adding it..." ); console.warn( "Camera is not on the Scene. Adding it..." );
...@@ -144,19 +140,17 @@ THREE.Projector = function() { ...@@ -144,19 +140,17 @@ THREE.Projector = function() {
scene.updateMatrixWorld(); scene.updateMatrixWorld();
THREE.Matrix4.makeInvert( camera.matrixWorld, camera.matrixWorldInverse ); camera.matrixWorldInverse.getInverse( camera.matrixWorld );
_projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse ); _projScreenMatrix.multiply( camera.projectionMatrix, camera.matrixWorldInverse );
computeFrustum( _projScreenMatrix ); computeFrustum( _projScreenMatrix );
objects = this.projectObjects( scene, true ); _renderData = this.projectGraph( scene );
for ( o = 0, ol = objects.length; o < ol; o++ ) {
object = objects[ o ].object; for ( o = 0, ol = _renderData.objects.length; o < ol; o++ ) {
if ( !object.visible ) continue; object = _renderData.objects[ o ];
objectMatrix = object.matrixWorld; objectMatrix = object.matrixWorld;
...@@ -286,7 +280,7 @@ THREE.Projector = function() { ...@@ -286,7 +280,7 @@ THREE.Projector = function() {
_face.z = _face.centroidScreen.z; _face.z = _face.centroidScreen.z;
_renderList.push( _face ); _renderData.elements.push( _face );
} }
...@@ -325,7 +319,7 @@ THREE.Projector = function() { ...@@ -325,7 +319,7 @@ THREE.Projector = function() {
_line.materials = object.materials; _line.materials = object.materials;
_renderList.push( _line ); _renderData.elements.push( _line );
} }
} }
...@@ -351,7 +345,7 @@ THREE.Projector = function() { ...@@ -351,7 +345,7 @@ THREE.Projector = function() {
_particle.materials = object.materials; _particle.materials = object.materials;
_renderList.push( _particle ); _renderData.elements.push( _particle );
} }
...@@ -359,9 +353,9 @@ THREE.Projector = function() { ...@@ -359,9 +353,9 @@ THREE.Projector = function() {
} }
sort && _renderList.sort( painterSort ); sort && _renderData.elements.sort( painterSort );
return _renderList; return _renderData;
}; };
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
THREE.CanvasRenderer = function ( parameters ) { THREE.CanvasRenderer = function ( parameters ) {
var _this = this, var _this = this,
_renderList = null, _renderData, _elements, _lights,
_projector = new THREE.Projector(), _projector = new THREE.Projector(),
parameters = parameters || {}, parameters = parameters || {},
...@@ -33,11 +33,11 @@ THREE.CanvasRenderer = function ( parameters ) { ...@@ -33,11 +33,11 @@ THREE.CanvasRenderer = function ( parameters ) {
_v1x, _v1y, _v2x, _v2y, _v3x, _v3y, _v1x, _v1y, _v2x, _v2y, _v3x, _v3y,
_v4x, _v4y, _v5x, _v5y, _v6x, _v6y, _v4x, _v4y, _v5x, _v5y, _v6x, _v6y,
_color = new THREE.Color( 0x000000 ), _color = new THREE.Color(),
_color1 = new THREE.Color( 0x000000 ), _color1 = new THREE.Color(),
_color2 = new THREE.Color( 0x000000 ), _color2 = new THREE.Color(),
_color3 = new THREE.Color( 0x000000 ), _color3 = new THREE.Color(),
_color4 = new THREE.Color( 0x000000 ), _color4 = new THREE.Color(),
_patterns = [], _patterns = [],
...@@ -51,7 +51,6 @@ THREE.CanvasRenderer = function ( parameters ) { ...@@ -51,7 +51,6 @@ THREE.CanvasRenderer = function ( parameters ) {
_bboxRect = new THREE.Rectangle(), _bboxRect = new THREE.Rectangle(),
_enableLighting = false, _enableLighting = false,
_light = new THREE.Color(),
_ambientLight = new THREE.Color(), _ambientLight = new THREE.Color(),
_directionalLights = new THREE.Color(), _directionalLights = new THREE.Color(),
_pointLights = new THREE.Color(), _pointLights = new THREE.Color(),
...@@ -181,24 +180,26 @@ THREE.CanvasRenderer = function ( parameters ) { ...@@ -181,24 +180,26 @@ THREE.CanvasRenderer = function ( parameters ) {
_this.info.render.vertices = 0; _this.info.render.vertices = 0;
_this.info.render.faces = 0; _this.info.render.faces = 0;
_renderList = _projector.projectScene( scene, camera, this.sortElements ); _renderData = _projector.projectScene( scene, camera, this.sortElements );
_elements = _renderData.elements;
_lights = _renderData.lights;
/* DEBUG /* DEBUG
_context.fillStyle = 'rgba( 0, 255, 255, 0.5 )'; _context.fillStyle = 'rgba( 0, 255, 255, 0.5 )';
_context.fillRect( _clipRect.getX(), _clipRect.getY(), _clipRect.getWidth(), _clipRect.getHeight() ); _context.fillRect( _clipRect.getX(), _clipRect.getY(), _clipRect.getWidth(), _clipRect.getHeight() );
*/ */
// _enableLighting = scene.lights.length > 0; _enableLighting = _lights.length > 0;
if ( _enableLighting ) { if ( _enableLighting ) {
calculateLights( scene ); calculateLights( _lights );
} }
for ( e = 0, el = _renderList.length; e < el; e++ ) { for ( e = 0, el = _elements.length; e < el; e++ ) {
element = _renderList[ e ]; element = _elements[ e ];
_bboxRect.empty(); _bboxRect.empty();
...@@ -369,10 +370,9 @@ THREE.CanvasRenderer = function ( parameters ) { ...@@ -369,10 +370,9 @@ THREE.CanvasRenderer = function ( parameters ) {
// //
function calculateLights( scene ) { function calculateLights( lights ) {
var l, ll, light, lightColor, var l, ll, light, lightColor;
lights = scene.lights;
_ambientLight.setRGB( 0, 0, 0 ); _ambientLight.setRGB( 0, 0, 0 );
_directionalLights.setRGB( 0, 0, 0 ); _directionalLights.setRGB( 0, 0, 0 );
...@@ -411,10 +411,9 @@ THREE.CanvasRenderer = function ( parameters ) { ...@@ -411,10 +411,9 @@ THREE.CanvasRenderer = function ( parameters ) {
} }
function calculateLight( scene, position, normal, color ) { function calculateLight( lights, position, normal, color ) {
var l, ll, light, lightColor, var l, ll, light, lightColor, lightPosition, amount;
amount, lights = scene.lights;
for ( l = 0, ll = lights.length; l < ll; l ++ ) { for ( l = 0, ll = lights.length; l < ll; l ++ ) {
...@@ -423,7 +422,9 @@ THREE.CanvasRenderer = function ( parameters ) { ...@@ -423,7 +422,9 @@ THREE.CanvasRenderer = function ( parameters ) {
if ( light instanceof THREE.DirectionalLight ) { if ( light instanceof THREE.DirectionalLight ) {
amount = normal.dot( light.position ); lightPosition = light.matrixWorld.getPosition();
amount = normal.dot( lightPosition );
if ( amount <= 0 ) continue; if ( amount <= 0 ) continue;
...@@ -435,11 +436,13 @@ THREE.CanvasRenderer = function ( parameters ) { ...@@ -435,11 +436,13 @@ THREE.CanvasRenderer = function ( parameters ) {
} else if ( light instanceof THREE.PointLight ) { } else if ( light instanceof THREE.PointLight ) {
amount = normal.dot( _vector3.sub( light.position, position ).normalize() ); lightPosition = light.matrixWorld.getPosition();
amount = normal.dot( _vector3.sub( lightPosition, position ).normalize() );
if ( amount <= 0 ) continue; if ( amount <= 0 ) continue;
amount *= light.distance == 0 ? 1 : 1 - Math.min( position.distanceTo( light.position ) / light.distance, 1 ); amount *= light.distance == 0 ? 1 : 1 - Math.min( position.distanceTo( lightPosition ) / light.distance, 1 );
if ( amount == 0 ) continue; if ( amount == 0 ) continue;
...@@ -645,9 +648,9 @@ THREE.CanvasRenderer = function ( parameters ) { ...@@ -645,9 +648,9 @@ THREE.CanvasRenderer = function ( parameters ) {
_color1.g = _color2.g = _color3.g = _ambientLight.g; _color1.g = _color2.g = _color3.g = _ambientLight.g;
_color1.b = _color2.b = _color3.b = _ambientLight.b; _color1.b = _color2.b = _color3.b = _ambientLight.b;
calculateLight( scene, element.v1.positionWorld, element.vertexNormalsWorld[ 0 ], _color1 ); calculateLight( _lights, element.v1.positionWorld, element.vertexNormalsWorld[ 0 ], _color1 );
calculateLight( scene, element.v2.positionWorld, element.vertexNormalsWorld[ 1 ], _color2 ); calculateLight( _lights, element.v2.positionWorld, element.vertexNormalsWorld[ 1 ], _color2 );
calculateLight( scene, element.v3.positionWorld, element.vertexNormalsWorld[ 2 ], _color3 ); calculateLight( _lights, element.v3.positionWorld, element.vertexNormalsWorld[ 2 ], _color3 );
_color1.r = Math.max( 0, Math.min( material.color.r * _color1.r, 1 ) ); _color1.r = Math.max( 0, Math.min( material.color.r * _color1.r, 1 ) );
_color1.g = Math.max( 0, Math.min( material.color.g * _color1.g, 1 ) ); _color1.g = Math.max( 0, Math.min( material.color.g * _color1.g, 1 ) );
...@@ -671,15 +674,15 @@ THREE.CanvasRenderer = function ( parameters ) { ...@@ -671,15 +674,15 @@ THREE.CanvasRenderer = function ( parameters ) {
} else { } else {
_light.r = _ambientLight.r; _color.r = _ambientLight.r;
_light.g = _ambientLight.g; _color.g = _ambientLight.g;
_light.b = _ambientLight.b; _color.b = _ambientLight.b;
calculateLight( scene, element.centroidWorld, element.normalWorld, _light ); calculateLight( _lights, element.centroidWorld, element.normalWorld, _color );
_color.r = Math.max( 0, Math.min( material.color.r * _light.r, 1 ) ); _color.r = Math.max( 0, Math.min( material.color.r * _color.r, 1 ) );
_color.g = Math.max( 0, Math.min( material.color.g * _light.g, 1 ) ); _color.g = Math.max( 0, Math.min( material.color.g * _color.g, 1 ) );
_color.b = Math.max( 0, Math.min( material.color.b * _light.b, 1 ) ); _color.b = Math.max( 0, Math.min( material.color.b * _color.b, 1 ) );
material.wireframe ? strokePath( _color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin ) : fillPath( _color ); material.wireframe ? strokePath( _color, material.wireframeLinewidth, material.wireframeLinecap, material.wireframeLinejoin ) : fillPath( _color );
...@@ -762,10 +765,10 @@ THREE.CanvasRenderer = function ( parameters ) { ...@@ -762,10 +765,10 @@ THREE.CanvasRenderer = function ( parameters ) {
_color1.g = _color2.g = _color3.g = _color4.g = _ambientLight.g; _color1.g = _color2.g = _color3.g = _color4.g = _ambientLight.g;
_color1.b = _color2.b = _color3.b = _color4.b = _ambientLight.b; _color1.b = _color2.b = _color3.b = _color4.b = _ambientLight.b;
calculateLight( scene, element.v1.positionWorld, element.vertexNormalsWorld[ 0 ], _color1 ); calculateLight( _lights, element.v1.positionWorld, element.vertexNormalsWorld[ 0 ], _color1 );
calculateLight( scene, element.v2.positionWorld, element.vertexNormalsWorld[ 1 ], _color2 ); calculateLight( _lights, element.v2.positionWorld, element.vertexNormalsWorld[ 1 ], _color2 );
calculateLight( scene, element.v4.positionWorld, element.vertexNormalsWorld[ 3 ], _color3 ); calculateLight( _lights, element.v4.positionWorld, element.vertexNormalsWorld[ 3 ], _color3 );
calculateLight( scene, element.v3.positionWorld, element.vertexNormalsWorld[ 2 ], _color4 ); calculateLight( _lights, element.v3.positionWorld, element.vertexNormalsWorld[ 2 ], _color4 );
_color1.r = Math.max( 0, Math.min( material.color.r * _color1.r, 1 ) ); _color1.r = Math.max( 0, Math.min( material.color.r * _color1.r, 1 ) );
_color1.g = Math.max( 0, Math.min( material.color.g * _color1.g, 1 ) ); _color1.g = Math.max( 0, Math.min( material.color.g * _color1.g, 1 ) );
...@@ -795,15 +798,15 @@ THREE.CanvasRenderer = function ( parameters ) { ...@@ -795,15 +798,15 @@ THREE.CanvasRenderer = function ( parameters ) {
} else { } else {
_light.r = _ambientLight.r; _color.r = _ambientLight.r;
_light.g = _ambientLight.g; _color.g = _ambientLight.g;
_light.b = _ambientLight.b; _color.b = _ambientLight.b;
calculateLight( scene, element.centroidWorld, element.normalWorld, _light ); calculateLight( _lights, element.centroidWorld, element.normalWorld, _color );
_color.r = Math.max( 0, Math.min( material.color.r * _light.r, 1 ) ); _color.r = Math.max( 0, Math.min( material.color.r * _color.r, 1 ) );
_color.g = Math.max( 0, Math.min( material.color.g * _light.g, 1 ) ); _color.g = Math.max( 0, Math.min( material.color.g * _color.g, 1 ) );
_color.b = Math.max( 0, Math.min( material.color.b * _light.b, 1 ) ); _color.b = Math.max( 0, Math.min( material.color.b * _color.b, 1 ) );
drawQuad( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, _v4x, _v4y ); drawQuad( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, _v4x, _v4y );
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
THREE.SVGRenderer = function () { THREE.SVGRenderer = function () {
var _this = this, var _this = this,
_renderList = null, _renderData, _elements, _lights,
_projector = new THREE.Projector(), _projector = new THREE.Projector(),
_svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'), _svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'),
_svgWidth, _svgHeight, _svgWidthHalf, _svgHeightHalf, _svgWidth, _svgHeight, _svgWidthHalf, _svgHeightHalf,
...@@ -16,11 +16,10 @@ THREE.SVGRenderer = function () { ...@@ -16,11 +16,10 @@ THREE.SVGRenderer = function () {
_bboxRect = new THREE.Rectangle(), _bboxRect = new THREE.Rectangle(),
_enableLighting = false, _enableLighting = false,
_color = new THREE.Color( 0xffffff ), _color = new THREE.Color(),
_light = new THREE.Color( 0xffffff ), _ambientLight = new THREE.Color(),
_ambientLight = new THREE.Color( 0x000000 ), _directionalLights = new THREE.Color(),
_directionalLights = new THREE.Color( 0x000000 ), _pointLights = new THREE.Color(),
_pointLights = new THREE.Color( 0x000000 ),
_w, // z-buffer to w-buffer _w, // z-buffer to w-buffer
_vector3 = new THREE.Vector3(), // Needed for PointLight _vector3 = new THREE.Vector3(), // Needed for PointLight
...@@ -80,7 +79,7 @@ THREE.SVGRenderer = function () { ...@@ -80,7 +79,7 @@ THREE.SVGRenderer = function () {
}; };
this.render = function( scene, camera ) { this.render = function ( scene, camera ) {
var e, el, m, ml, fm, fml, element, material; var e, el, m, ml, fm, fml, element, material;
...@@ -89,21 +88,23 @@ THREE.SVGRenderer = function () { ...@@ -89,21 +88,23 @@ THREE.SVGRenderer = function () {
_this.info.render.vertices = 0; _this.info.render.vertices = 0;
_this.info.render.faces = 0; _this.info.render.faces = 0;
_renderList = _projector.projectScene( scene, camera, this.sortElements ); _renderData = _projector.projectScene( scene, camera, this.sortElements );
_elements = _renderData.elements;
_lights = _renderData.lights;
_pathCount = 0; _circleCount = 0; _lineCount = 0; _pathCount = 0; _circleCount = 0; _lineCount = 0;
_enableLighting = scene.lights.length > 0; _enableLighting = _lights.length > 0;
if ( _enableLighting ) { if ( _enableLighting ) {
calculateLights( scene ); calculateLights( _lights );
} }
for ( e = 0, el = _renderList.length; e < el; e ++ ) { for ( e = 0, el = _elements.length; e < el; e ++ ) {
element = _renderList[ e ]; element = _elements[ e ];
_bboxRect.empty(); _bboxRect.empty();
...@@ -240,10 +241,9 @@ THREE.SVGRenderer = function () { ...@@ -240,10 +241,9 @@ THREE.SVGRenderer = function () {
}; };
function calculateLights( scene ) { function calculateLights( lights ) {
var l, ll, light, lightColor, var l, ll, light, lightColor;
lights = scene.lights;
_ambientLight.setRGB( 0, 0, 0 ); _ambientLight.setRGB( 0, 0, 0 );
_directionalLights.setRGB( 0, 0, 0 ); _directionalLights.setRGB( 0, 0, 0 );
...@@ -278,40 +278,46 @@ THREE.SVGRenderer = function () { ...@@ -278,40 +278,46 @@ THREE.SVGRenderer = function () {
} }
function calculateFaceLight( scene, element, color ) { function calculateLight( lights, position, normal, color ) {
var l, ll, light, amount; var l, ll, light, lightColor, lightPosition, amount;
for ( l = 0, ll = scene.lights.length; l < ll; l++ ) { for ( l = 0, ll = lights.length; l < ll; l ++ ) {
light = scene.lights[ l ]; light = lights[ l ];
lightColor = light.color;
if ( light instanceof THREE.DirectionalLight ) { if ( light instanceof THREE.DirectionalLight ) {
amount = element.normalWorld.dot( light.position ) * light.intensity; lightPosition = light.matrixWorld.getPosition();
if ( amount > 0 ) { amount = normal.dot( lightPosition );
color.r += light.color.r * amount; if ( amount <= 0 ) continue;
color.g += light.color.g * amount;
color.b += light.color.b * amount;
} amount *= light.intensity;
color.r += lightColor.r * amount;
color.g += lightColor.g * amount;
color.b += lightColor.b * amount;
} else if ( light instanceof THREE.PointLight ) { } else if ( light instanceof THREE.PointLight ) {
_vector3.sub( light.position, element.centroidWorld ); lightPosition = light.matrixWorld.getPosition();
_vector3.normalize();
amount = element.normalWorld.dot( _vector3 ) * light.intensity; amount = normal.dot( _vector3.sub( lightPosition, position ).normalize() );
if ( amount > 0 ) { if ( amount <= 0 ) continue;
color.r += light.color.r * amount; amount *= light.distance == 0 ? 1 : 1 - Math.min( position.distanceTo( lightPosition ) / light.distance, 1 );
color.g += light.color.g * amount;
color.b += light.color.b * amount;
} if ( amount == 0 ) continue;
amount *= light.intensity;
color.r += lightColor.r * amount;
color.g += lightColor.g * amount;
color.b += lightColor.b * amount;
} }
...@@ -331,13 +337,13 @@ THREE.SVGRenderer = function () { ...@@ -331,13 +337,13 @@ THREE.SVGRenderer = function () {
if ( _enableLighting ) { if ( _enableLighting ) {
_light.r = _ambientLight.r + _directionalLights.r + _pointLights.r; _color.r = _ambientLight.r + _directionalLights.r + _pointLights.r;
_light.g = _ambientLight.g + _directionalLights.g + _pointLights.g; _color.g = _ambientLight.g + _directionalLights.g + _pointLights.g;
_light.b = _ambientLight.b + _directionalLights.b + _pointLights.b; _color.b = _ambientLight.b + _directionalLights.b + _pointLights.b;
_color.r = material.color.r * _light.r; _color.r = material.color.r * _color.r;
_color.g = material.color.g * _light.g; _color.g = material.color.g * _color.g;
_color.b = material.color.b * _light.b; _color.b = material.color.b * _color.b;
_color.updateStyleString(); _color.updateStyleString();
...@@ -391,15 +397,15 @@ THREE.SVGRenderer = function () { ...@@ -391,15 +397,15 @@ THREE.SVGRenderer = function () {
if ( _enableLighting ) { if ( _enableLighting ) {
_light.r = _ambientLight.r; _color.r = _ambientLight.r;
_light.g = _ambientLight.g; _color.g = _ambientLight.g;
_light.b = _ambientLight.b; _color.b = _ambientLight.b;
calculateFaceLight( scene, element, _light ); calculateLight( _lights, element.centroidWorld, element.normalWorld, _color );
_color.r = Math.max( 0, Math.min( material.color.r * _light.r, 1 ) ); _color.r = Math.max( 0, Math.min( material.color.r * _color.r, 1 ) );
_color.g = Math.max( 0, Math.min( material.color.g * _light.g, 1 ) ); _color.g = Math.max( 0, Math.min( material.color.g * _color.g, 1 ) );
_color.b = Math.max( 0, Math.min( material.color.b * _light.b, 1 ) ); _color.b = Math.max( 0, Math.min( material.color.b * _color.b, 1 ) );
} else { } else {
...@@ -448,15 +454,15 @@ THREE.SVGRenderer = function () { ...@@ -448,15 +454,15 @@ THREE.SVGRenderer = function () {
if ( _enableLighting ) { if ( _enableLighting ) {
_light.r = _ambientLight.r; _color.r = _ambientLight.r;
_light.g = _ambientLight.g; _color.g = _ambientLight.g;
_light.b = _ambientLight.b; _color.b = _ambientLight.b;
calculateFaceLight( scene, element, _light ); calculateLight( _lights, element.centroidWorld, element.normalWorld, _color );
_color.r = Math.max( 0, Math.min( material.color.r * _light.r, 1 ) ); _color.r = Math.max( 0, Math.min( material.color.r * _color.r, 1 ) );
_color.g = Math.max( 0, Math.min( material.color.g * _light.g, 1 ) ); _color.g = Math.max( 0, Math.min( material.color.g * _color.g, 1 ) );
_color.b = Math.max( 0, Math.min( material.color.b * _light.b, 1 ) ); _color.b = Math.max( 0, Math.min( material.color.b * _color.b, 1 ) );
} else { } else {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册