提交 83e9745b 编写于 作者: M Mr.doob

WebGLRenderer: Moved renderList logic to WebGLRenderList. Implemented mult-RenderList. See #9545.

上级 b559342a
......@@ -17,6 +17,7 @@ import { MeshBasicMaterial } from '../materials/MeshBasicMaterial';
import { PerspectiveCamera } from '../cameras/PerspectiveCamera';
import { OrthographicCamera } from '../cameras/OrthographicCamera';
import { WebGLAttributes } from './webgl/WebGLAttributes';
import { WebGLRenderLists } from './webgl/WebGLRenderLists';
import { WebGLIndexedBufferRenderer } from './webgl/WebGLIndexedBufferRenderer';
import { WebGLBufferRenderer } from './webgl/WebGLBufferRenderer';
import { WebGLGeometries } from './webgl/WebGLGeometries';
......@@ -62,10 +63,7 @@ function WebGLRenderer( parameters ) {
var lights = [];
var opaqueObjects = [];
var opaqueObjectsLastIndex = - 1;
var transparentObjects = [];
var transparentObjectsLastIndex = - 1;
var currentRenderList = null;
var morphInfluences = new Float32Array( 8 );
......@@ -296,6 +294,7 @@ function WebGLRenderer( parameters ) {
var objects = new WebGLObjects( _gl, geometries, _infoRender );
var programCache = new WebGLPrograms( this, capabilities );
var lightCache = new WebGLLights();
var renderLists = new WebGLRenderLists();
this.info.programs = programCache.programs;
......@@ -527,13 +526,10 @@ function WebGLRenderer( parameters ) {
this.dispose = function () {
transparentObjects = [];
transparentObjectsLastIndex = - 1;
opaqueObjects = [];
opaqueObjectsLastIndex = - 1;
_canvas.removeEventListener( 'webglcontextlost', onContextLost, false );
renderLists.dispose();
};
// Events
......@@ -1041,50 +1037,6 @@ function WebGLRenderer( parameters ) {
}
function painterSortStable( a, b ) {
if ( a.object.renderOrder !== b.object.renderOrder ) {
return a.object.renderOrder - b.object.renderOrder;
} else if ( a.material.program && b.material.program && a.material.program !== b.material.program ) {
return a.material.program.id - b.material.program.id;
} else if ( a.material.id !== b.material.id ) {
return a.material.id - b.material.id;
} else if ( a.z !== b.z ) {
return a.z - b.z;
} else {
return a.id - b.id;
}
}
function reversePainterSortStable( a, b ) {
if ( a.object.renderOrder !== b.object.renderOrder ) {
return a.object.renderOrder - b.object.renderOrder;
} if ( a.z !== b.z ) {
return b.z - a.z;
} else {
return a.id - b.id;
}
}
// Rendering
this.render = function ( scene, camera, renderTarget, forceClear ) {
......@@ -1116,25 +1068,22 @@ function WebGLRenderer( parameters ) {
_frustum.setFromMatrix( _projScreenMatrix );
lights.length = 0;
opaqueObjectsLastIndex = - 1;
transparentObjectsLastIndex = - 1;
sprites.length = 0;
lensFlares.length = 0;
_localClippingEnabled = this.localClippingEnabled;
_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );
currentRenderList = renderLists.get( scene, camera );
currentRenderList.init();
projectObject( scene, camera, _this.sortObjects );
opaqueObjects.length = opaqueObjectsLastIndex + 1;
transparentObjects.length = transparentObjectsLastIndex + 1;
currentRenderList.finish();
if ( _this.sortObjects === true ) {
opaqueObjects.sort( painterSortStable );
transparentObjects.sort( reversePainterSortStable );
currentRenderList.sort();
}
......@@ -1244,6 +1193,9 @@ function WebGLRenderer( parameters ) {
//
var opaqueObjects = currentRenderList.opaque;
var transparentObjects = currentRenderList.transparent;
if ( scene.overrideMaterial ) {
var overrideMaterial = scene.overrideMaterial;
......@@ -1287,55 +1239,6 @@ function WebGLRenderer( parameters ) {
};
function pushRenderItem( object, geometry, material, z, group ) {
var array, index;
// allocate the next position in the appropriate array
if ( material.transparent ) {
array = transparentObjects;
index = ++ transparentObjectsLastIndex;
} else {
array = opaqueObjects;
index = ++ opaqueObjectsLastIndex;
}
// recycle existing render item or grow the array
var renderItem = array[ index ];
if ( renderItem ) {
renderItem.id = object.id;
renderItem.object = object;
renderItem.geometry = geometry;
renderItem.material = material;
renderItem.z = _vector3.z;
renderItem.group = group;
} else {
renderItem = {
id: object.id,
object: object,
geometry: geometry,
material: material,
z: _vector3.z,
group: group
};
// assert( index === array.length );
array.push( renderItem );
}
}
/*
// TODO Duplicated code (Frustum)
......@@ -1424,7 +1327,7 @@ function WebGLRenderer( parameters ) {
}
pushRenderItem( object, null, object.material, _vector3.z, null );
currentRenderList.push( object, null, object.material, _vector3.z, null );
} else if ( object.isMesh || object.isLine || object.isPoints ) {
......@@ -1457,7 +1360,7 @@ function WebGLRenderer( parameters ) {
if ( groupMaterial && groupMaterial.visible ) {
pushRenderItem( object, geometry, groupMaterial, _vector3.z, group );
currentRenderList.push( object, geometry, groupMaterial, _vector3.z, group );
}
......@@ -1465,7 +1368,7 @@ function WebGLRenderer( parameters ) {
} else if ( material.visible ) {
pushRenderItem( object, geometry, material, _vector3.z, null );
currentRenderList.push( object, geometry, material, _vector3.z, null );
}
......
/**
* @author mrdoob / http://mrdoob.com/
*/
function painterSortStable( a, b ) {
if ( a.object.renderOrder !== b.object.renderOrder ) {
return a.object.renderOrder - b.object.renderOrder;
} else if ( a.material.program && b.material.program && a.material.program !== b.material.program ) {
return a.material.program.id - b.material.program.id;
} else if ( a.material.id !== b.material.id ) {
return a.material.id - b.material.id;
} else if ( a.z !== b.z ) {
return a.z - b.z;
} else {
return a.id - b.id;
}
}
function reversePainterSortStable( a, b ) {
if ( a.object.renderOrder !== b.object.renderOrder ) {
return a.object.renderOrder - b.object.renderOrder;
} if ( a.z !== b.z ) {
return b.z - a.z;
} else {
return a.id - b.id;
}
}
function WebGLRenderList() {
var opaque = [];
var opaqueLastIndex = - 1;
var transparent = [];
var transparentLastIndex = - 1;
function init() {
opaqueLastIndex = - 1;
transparentLastIndex = - 1;
}
function push( object, geometry, material, z, group ) {
var array, index;
// allocate the next position in the appropriate array
if ( material.transparent ) {
array = transparent;
index = ++ transparentLastIndex;
} else {
array = opaque;
index = ++ opaqueLastIndex;
}
// recycle existing render item or grow the array
var renderItem = array[ index ];
if ( renderItem ) {
renderItem.id = object.id;
renderItem.object = object;
renderItem.geometry = geometry;
renderItem.material = material;
renderItem.z = z;
renderItem.group = group;
} else {
renderItem = {
id: object.id,
object: object,
geometry: geometry,
material: material,
z: z,
group: group
};
// assert( index === array.length );
array.push( renderItem );
}
}
function finish() {
opaque.length = opaqueLastIndex + 1;
transparent.length = transparentLastIndex + 1;
}
function sort() {
opaque.sort( painterSortStable );
transparent.sort( reversePainterSortStable );
}
return {
opaque: opaque,
transparent: transparent,
init: init,
push: push,
finish: finish,
sort: sort
};
}
function WebGLRenderLists() {
var lists = {};
function get( scene, camera ) {
var hash = scene.id + ',' + camera.id;
var list = lists[ hash ];
if ( list === undefined ) {
list = new WebGLRenderList();
lists[ hash ] = list;
}
return list;
}
function dispose() {
lists = {};
}
return {
get: get,
dispose: dispose
};
}
export { WebGLRenderLists };
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册