提交 04cae716 编写于 作者: A alteredq

Refactored render pass madness in WebGLRenderer to something a bit more sane.

Also fixed subtle bug in `materials_gl` example: face.material => face.materials (since renaming this example was just silently broken)
上级 373e6c29
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -66,20 +66,20 @@
generatedTexture.image.loaded = 1;
var materials = [];
materials.push( { material: new THREE.MeshLambertMaterial( { color: 0xdddddd, shading: THREE.FlatShading } ), overdraw: true, doubleSided: false } );
materials.push( { material: new THREE.MeshPhongMaterial( { ambient: 0x030303, color: 0xdddddd, specular: 0x009900, shininess: 30, shading: THREE.FlatShading } ), overdraw: true, doubleSided: false } );
materials.push( { material: new THREE.MeshNormalMaterial( ), overdraw: true, doubleSided: false } );
materials.push( { material: new THREE.MeshBasicMaterial( { color: 0x665500, blending: THREE.AdditiveBlending } ), overdraw: false, doubleSided: true } );
//materials.push( { material: new THREE.MeshBasicMaterial( { color: 0xff0000, blending: THREE.SubtractiveBlending } ), overdraw: false, doubleSided: true } );
materials.push( new THREE.MeshLambertMaterial( { color: 0xdddddd, shading: THREE.FlatShading } ) );
materials.push( new THREE.MeshPhongMaterial( { ambient: 0x030303, color: 0xdddddd, specular: 0x009900, shininess: 30, shading: THREE.FlatShading } ) );
materials.push( new THREE.MeshNormalMaterial( ) );
materials.push( new THREE.MeshBasicMaterial( { color: 0x665500, blending: THREE.AdditiveBlending } ) );
//materials.push( new THREE.MeshBasicMaterial( { color: 0xff0000, blending: THREE.SubtractiveBlending } ) );
materials.push( { material: new THREE.MeshLambertMaterial( { color: 0xdddddd, shading: THREE.SmoothShading } ), overdraw: true, doubleSided: false } );
materials.push( { material: new THREE.MeshPhongMaterial( { ambient: 0x030303, color: 0xdddddd, specular: 0x009900, shininess: 30, shading: THREE.SmoothShading } ), overdraw: true, doubleSided: false } );
materials.push( { material: new THREE.MeshNormalMaterial( { shading: THREE.SmoothShading } ), overdraw: true, doubleSided: false } );
materials.push( { material: new THREE.MeshBasicMaterial( { color: 0xffaa00, wireframe: true } ), overdraw: false, doubleSided: true } );
materials.push( new THREE.MeshLambertMaterial( { color: 0xdddddd, shading: THREE.SmoothShading } ) );
materials.push( new THREE.MeshPhongMaterial( { ambient: 0x030303, color: 0xdddddd, specular: 0x009900, shininess: 30, shading: THREE.SmoothShading } ) );
materials.push( new THREE.MeshNormalMaterial( { shading: THREE.SmoothShading } ) );
materials.push( new THREE.MeshBasicMaterial( { color: 0xffaa00, wireframe: true } ) );
materials.push( { material: new THREE.MeshDepthMaterial(), overdraw: true, doubleSided: false } );
materials.push( { material: new THREE.MeshBasicMaterial( { map: generatedTexture } ), overdraw: true, doubleSided: false } );
materials.push( { material: new THREE.MeshLambertMaterial( { map: generatedTexture } ), overdraw: true, doubleSided: false } );
materials.push( new THREE.MeshDepthMaterial() );
materials.push( new THREE.MeshBasicMaterial( { map: generatedTexture } ) );
materials.push( new THREE.MeshLambertMaterial( { map: generatedTexture } ) );
// Spheres geometry
......@@ -90,11 +90,13 @@
for ( var i = 0, l = geometry_pieces.faces.length; i < l; i ++ ) {
var face = geometry_pieces.faces[ i ];
if ( Math.random() > 0.7 ) face.material = [ materials[ Math.floor( Math.random() * materials.length ) ].material ];
if ( Math.random() > 0.7 ) face.materials = [ materials[ Math.floor( Math.random() * materials.length ) ] ];
}
materials.push( { material: new THREE.MeshFaceMaterial(), overdraw: false, doubleSided: true } );
geometry_pieces.sortFacesByMaterial();
materials.push( new THREE.MeshFaceMaterial() );
objects = [];
......@@ -102,15 +104,12 @@
for ( var i = 0, l = materials.length; i < l; i ++ ) {
material = materials[ i ].material;
material = materials[ i ];
geometry = material instanceof THREE.MeshFaceMaterial ? geometry_pieces :
( material.shading == THREE.FlatShading ? geometry_flat : geometry_smooth );
sphere = new THREE.Mesh( geometry, material );
sphere.overdraw = material.overdraw;
sphere.doubleSided = material.doubleSided;
sphere.position.x = ( i % 4 ) * 200 - 400;
sphere.position.z = Math.floor( i / 4 ) * 200 - 200;
......
......@@ -1297,72 +1297,6 @@ THREE.WebGLRenderer = function ( parameters ) {
};
this.renderPass = function ( camera, lights, fog, object, geometryChunk, blending, transparent ) {
var i, l, m, ml, material, meshMaterial;
for ( m = 0, ml = object.materials.length; m < ml; m++ ) {
meshMaterial = object.materials[ m ];
if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {
for ( i = 0, l = geometryChunk.materials.length; i < l; i++ ) {
material = geometryChunk.materials[ i ];
if ( material && material.blending == blending && ( material.opacity < 1.0 == transparent ) ) {
setBlending( material.blending );
this.setDepthTest( material.depth_test );
this.renderBuffer( camera, lights, fog, material, geometryChunk, object );
}
}
} else {
material = meshMaterial;
if ( material && material.blending == blending && ( material.opacity < 1.0 == transparent ) ) {
setBlending( material.blending );
this.setDepthTest( material.depth_test );
this.renderBuffer( camera, lights, fog, material, geometryChunk, object );
}
}
}
};
this.renderPassImmediate = function ( camera, lights, fog, object, blending, transparent ) {
var i, l, m, ml, material, program;
for ( m = 0, ml = object.materials.length; m < ml; m++ ) {
material = object.materials[ m ];
if ( material && material.blending == blending && ( material.opacity < 1.0 == transparent ) ) {
setBlending( material.blending );
this.setDepthTest( material.depth_test );
program = this.setProgram( camera, lights, fog, material, object );
object.render( function( object ) { renderBufferImmediate( object, program ); } );
}
}
};
function setObjectFaces( object ) {
if ( _oldDoubleSided != object.doubleSided ) {
......@@ -1434,10 +1368,88 @@ THREE.WebGLRenderer = function ( parameters ) {
return true;
};
function addToFixedArray( where, what ) {
where.list[ where.count ] = what;
where.count += 1;
};
function unrollImmediateBufferMaterials( globject ) {
var i, l, m, ml, material,
object = globject.object,
opaque = globject.opaque,
transparent = globject.transparent;
transparent.count = 0;
opaque.count = 0;
for ( m = 0, ml = object.materials.length; m < ml; m++ ) {
material = object.materials[ m ];
if ( ( material.opacity && material.opacity < 1.0 ) || material.blending != THREE.NormalBlending )
addToFixedArray( transparent, material );
else
addToFixedArray( opaque, material );
}
};
function unrollBufferMaterials( globject ) {
var i, l, m, ml, material, meshMaterial,
object = globject.object,
buffer = globject.buffer,
opaque = globject.opaque,
transparent = globject.transparent;
transparent.count = 0;
opaque.count = 0;
for ( m = 0, ml = object.materials.length; m < ml; m++ ) {
meshMaterial = object.materials[ m ];
if ( meshMaterial instanceof THREE.MeshFaceMaterial ) {
for ( i = 0, l = buffer.materials.length; i < l; i++ ) {
material = buffer.materials[ i ];
if ( material ) {
if ( ( material.opacity && material.opacity < 1.0 ) || material.blending != THREE.NormalBlending )
addToFixedArray( transparent, material );
else
addToFixedArray( opaque, material );
}
}
} else {
material = meshMaterial;
if ( ( material.opacity && material.opacity < 1.0 ) || material.blending != THREE.NormalBlending )
addToFixedArray( transparent, material );
else
addToFixedArray( opaque, material );
}
}
};
this.render = function( scene, camera, renderTarget, clear ) {
var o, ol, oil, webGLObject, object, buffer,
var i, program, opaque, transparent,
o, ol, oil, webGLObject, object, buffer,
lights = scene.lights,
fog = scene.fog,
ol;
......@@ -1480,7 +1492,10 @@ THREE.WebGLRenderer = function ( parameters ) {
this.setupMatrices( object, camera );
unrollBufferMaterials( webGLObject );
webGLObject.render = true;
} else {
......@@ -1494,7 +1509,8 @@ THREE.WebGLRenderer = function ( parameters ) {
for ( o = 0; o < oil; o++ ) {
object = scene.__webGLObjectsImmediate[ o ].object;
webGLObject = scene.__webGLObjectsImmediate[ o ];
object = webGLObject.object;
if ( object.visible ) {
......@@ -1506,6 +1522,8 @@ THREE.WebGLRenderer = function ( parameters ) {
}
this.setupMatrices( object, camera );
unrollImmediateBufferMaterials( webGLObject );
}
......@@ -1513,6 +1531,8 @@ THREE.WebGLRenderer = function ( parameters ) {
// opaque pass
setBlending( THREE.NormalBlending );
for ( o = 0; o < ol; o++ ) {
webGLObject = scene.__webGLObjects[ o ];
......@@ -1521,9 +1541,18 @@ THREE.WebGLRenderer = function ( parameters ) {
object = webGLObject.object;
buffer = webGLObject.buffer;
opaque = webGLObject.opaque;
setObjectFaces( object );
this.renderPass( camera, lights, fog, object, buffer, THREE.NormalBlending, false );
for( i = 0; i < opaque.count; i++ ) {
material = opaque.list[ i ];
this.setDepthTest( material.depth_test );
this.renderBuffer( camera, lights, fog, material, buffer, object );
}
}
......@@ -1533,12 +1562,24 @@ THREE.WebGLRenderer = function ( parameters ) {
for ( o = 0; o < oil; o++ ) {
object = scene.__webGLObjectsImmediate[ o ].object;
webGLObject = scene.__webGLObjectsImmediate[ o ];
object = webGLObject.object;
if ( object.visible ) {
opaque = webGLObject.opaque;
setObjectFaces( object );
this.renderPassImmediate( camera, lights, fog, object, THREE.NormalBlending, false );
for( i = 0; i < opaque.count; i++ ) {
material = opaque.list[ i ];
this.setDepthTest( material.depth_test );
program = this.setProgram( camera, lights, fog, material, object );
object.render( function( object ) { renderBufferImmediate( object, program ); } );
}
}
......@@ -1554,26 +1595,19 @@ THREE.WebGLRenderer = function ( parameters ) {
object = webGLObject.object;
buffer = webGLObject.buffer;
transparent = webGLObject.transparent;
setObjectFaces( object );
// opaque blended materials
this.renderPass( camera, lights, fog, object, buffer, THREE.AdditiveBlending, false );
this.renderPass( camera, lights, fog, object, buffer, THREE.SubtractiveBlending, false );
// transparent blended materials
this.renderPass( camera, lights, fog, object, buffer, THREE.AdditiveBlending, true );
this.renderPass( camera, lights, fog, object, buffer, THREE.SubtractiveBlending, true );
// transparent normal materials
this.renderPass( camera, lights, fog, object, buffer, THREE.NormalBlending, true );
// billboard materials
this.renderPass( camera, lights, fog, object, buffer, THREE.BillboardBlending, false );
for( i = 0; i < transparent.count; i++ ) {
material = transparent.list[ i ];
setBlending( material.blending );
this.setDepthTest( material.depth_test );
this.renderBuffer( camera, lights, fog, material, buffer, object );
}
}
......@@ -1583,12 +1617,25 @@ THREE.WebGLRenderer = function ( parameters ) {
for ( o = 0; o < oil; o++ ) {
object = scene.__webGLObjectsImmediate[ o ].object;
webGLObject = scene.__webGLObjectsImmediate[ o ];
object = webGLObject.object;
if ( object.visible ) {
transparent = webGLObject.transparent;
setObjectFaces( object );
this.renderPassImmediate( camera, lights, fog, object, THREE.NormalBlending, true );
for( i = 0; i < transparent.count; i++ ) {
material = transparent.list[ i ];
setBlending( material.blending );
this.setDepthTest( material.depth_test );
program = this.setProgram( camera, lights, fog, material, object );
object.render( function( object ) { renderBufferImmediate( object, program ); } );
}
}
......@@ -1610,7 +1657,10 @@ THREE.WebGLRenderer = function ( parameters ) {
if ( objmap[ id ] == undefined ) {
scene.__webGLObjects.push( { buffer: buffer, object: object } );
scene.__webGLObjects.push( { buffer: buffer, object: object,
opaque: { list: [], count: 0 },
transparent: { list: [], count: 0 }
} );
objmap[ id ] = 1;
}
......@@ -1621,7 +1671,10 @@ THREE.WebGLRenderer = function ( parameters ) {
if ( objmap[ id ] == undefined ) {
scene.__webGLObjectsImmediate.push( { object: object } );
scene.__webGLObjectsImmediate.push( { object: object,
opaque: { list: [], count: 0 },
transparent: { list: [], count: 0 }
} );
objmap[ id ] = 1;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册