提交 31225559 编写于 作者: M Mugen87

WebGLRenderer: Introduce WebGLRenderContext

上级 846d03ad
...@@ -8,9 +8,6 @@ THREE.LensFlare = function () { ...@@ -8,9 +8,6 @@ THREE.LensFlare = function () {
THREE.Mesh.call( this ); THREE.Mesh.call( this );
this.type = 'LensFlare'; this.type = 'LensFlare';
this.renderOrder = Infinity; // see #12883
this.material.transparent = true;
this.frustumCulled = false; this.frustumCulled = false;
// //
......
...@@ -7,7 +7,6 @@ THREE.Reflector = function ( geometry, options ) { ...@@ -7,7 +7,6 @@ THREE.Reflector = function ( geometry, options ) {
THREE.Mesh.call( this, geometry ); THREE.Mesh.call( this, geometry );
this.type = 'Reflector'; this.type = 'Reflector';
this.renderOrder = Infinity; // see #12883
var scope = this; var scope = this;
......
...@@ -15,7 +15,6 @@ import { WebGLMorphtargets } from './webgl/WebGLMorphtargets.js'; ...@@ -15,7 +15,6 @@ import { WebGLMorphtargets } from './webgl/WebGLMorphtargets.js';
import { WebGLIndexedBufferRenderer } from './webgl/WebGLIndexedBufferRenderer.js'; import { WebGLIndexedBufferRenderer } from './webgl/WebGLIndexedBufferRenderer.js';
import { WebGLBufferRenderer } from './webgl/WebGLBufferRenderer.js'; import { WebGLBufferRenderer } from './webgl/WebGLBufferRenderer.js';
import { WebGLGeometries } from './webgl/WebGLGeometries.js'; import { WebGLGeometries } from './webgl/WebGLGeometries.js';
import { WebGLLights } from './webgl/WebGLLights.js';
import { WebGLObjects } from './webgl/WebGLObjects.js'; import { WebGLObjects } from './webgl/WebGLObjects.js';
import { WebGLPrograms } from './webgl/WebGLPrograms.js'; import { WebGLPrograms } from './webgl/WebGLPrograms.js';
import { WebGLTextures } from './webgl/WebGLTextures.js'; import { WebGLTextures } from './webgl/WebGLTextures.js';
...@@ -29,6 +28,7 @@ import { WebGLClipping } from './webgl/WebGLClipping.js'; ...@@ -29,6 +28,7 @@ import { WebGLClipping } from './webgl/WebGLClipping.js';
import { Frustum } from '../math/Frustum.js'; import { Frustum } from '../math/Frustum.js';
import { Vector4 } from '../math/Vector4.js'; import { Vector4 } from '../math/Vector4.js';
import { WebGLUtils } from './webgl/WebGLUtils.js'; import { WebGLUtils } from './webgl/WebGLUtils.js';
import { WebGLRenderContexts } from './webgl/WebGLRenderContexts.js';
/** /**
* @author supereggbert / http://www.paulbrunt.co.uk/ * @author supereggbert / http://www.paulbrunt.co.uk/
...@@ -55,12 +55,8 @@ function WebGLRenderer( parameters ) { ...@@ -55,12 +55,8 @@ function WebGLRenderer( parameters ) {
_preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false, _preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false,
_powerPreference = parameters.powerPreference !== undefined ? parameters.powerPreference : 'default'; _powerPreference = parameters.powerPreference !== undefined ? parameters.powerPreference : 'default';
var lightsArray = [];
var shadowsArray = [];
var currentRenderList = null; var currentRenderList = null;
var currentRenderContext = null;
var spritesArray = [];
// public properties // public properties
...@@ -254,8 +250,8 @@ function WebGLRenderer( parameters ) { ...@@ -254,8 +250,8 @@ function WebGLRenderer( parameters ) {
} }
var extensions, capabilities, state; var extensions, capabilities, state;
var properties, textures, attributes, geometries, objects, lights; var properties, textures, attributes, geometries, objects;
var programCache, renderLists; var programCache, renderLists, renderContexts;
var background, morphtargets, bufferRenderer, indexedBufferRenderer; var background, morphtargets, bufferRenderer, indexedBufferRenderer;
var spriteRenderer; var spriteRenderer;
...@@ -289,8 +285,8 @@ function WebGLRenderer( parameters ) { ...@@ -289,8 +285,8 @@ function WebGLRenderer( parameters ) {
objects = new WebGLObjects( geometries, _infoRender ); objects = new WebGLObjects( geometries, _infoRender );
morphtargets = new WebGLMorphtargets( _gl ); morphtargets = new WebGLMorphtargets( _gl );
programCache = new WebGLPrograms( _this, extensions, capabilities ); programCache = new WebGLPrograms( _this, extensions, capabilities );
lights = new WebGLLights();
renderLists = new WebGLRenderLists(); renderLists = new WebGLRenderLists();
renderContexts = new WebGLRenderContexts();
background = new WebGLBackground( _this, state, geometries, _premultipliedAlpha ); background = new WebGLBackground( _this, state, geometries, _premultipliedAlpha );
...@@ -525,6 +521,7 @@ function WebGLRenderer( parameters ) { ...@@ -525,6 +521,7 @@ function WebGLRenderer( parameters ) {
_canvas.removeEventListener( 'webglcontextrestored', onContextRestore, false ); _canvas.removeEventListener( 'webglcontextrestored', onContextRestore, false );
renderLists.dispose(); renderLists.dispose();
renderContexts.dispose();
properties.dispose(); properties.dispose();
objects.dispose(); objects.dispose();
...@@ -994,18 +991,17 @@ function WebGLRenderer( parameters ) { ...@@ -994,18 +991,17 @@ function WebGLRenderer( parameters ) {
this.compile = function ( scene, camera ) { this.compile = function ( scene, camera ) {
lightsArray.length = 0; currentRenderContext.init();
shadowsArray.length = 0;
scene.traverse( function ( object ) { scene.traverse( function ( object ) {
if ( object.isLight ) { if ( object.isLight ) {
lightsArray.push( object ); currentRenderContext.pushLight( object );
if ( object.castShadow ) { if ( object.castShadow ) {
shadowsArray.push( object ); currentRenderContext.pushShadow( object );
} }
...@@ -1013,7 +1009,7 @@ function WebGLRenderer( parameters ) { ...@@ -1013,7 +1009,7 @@ function WebGLRenderer( parameters ) {
} ); } );
lights.setup( lightsArray, shadowsArray, camera ); currentRenderContext.setupLights( camera );
scene.traverse( function ( object ) { scene.traverse( function ( object ) {
...@@ -1122,16 +1118,16 @@ function WebGLRenderer( parameters ) { ...@@ -1122,16 +1118,16 @@ function WebGLRenderer( parameters ) {
} }
//
currentRenderContext = renderContexts.get( scene, camera );
currentRenderContext.init();
scene.onBeforeRender( _this, scene, camera, renderTarget ); scene.onBeforeRender( _this, scene, camera, renderTarget );
_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse ); _projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
_frustum.setFromMatrix( _projScreenMatrix ); _frustum.setFromMatrix( _projScreenMatrix );
lightsArray.length = 0;
shadowsArray.length = 0;
spritesArray.length = 0;
_localClippingEnabled = this.localClippingEnabled; _localClippingEnabled = this.localClippingEnabled;
_clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera ); _clippingEnabled = _clipping.init( this.clippingPlanes, _localClippingEnabled, camera );
...@@ -1150,9 +1146,11 @@ function WebGLRenderer( parameters ) { ...@@ -1150,9 +1146,11 @@ function WebGLRenderer( parameters ) {
if ( _clippingEnabled ) _clipping.beginShadows(); if ( _clippingEnabled ) _clipping.beginShadows();
var shadowsArray = currentRenderContext.state.shadowsArray;
shadowMap.render( shadowsArray, scene, camera ); shadowMap.render( shadowsArray, scene, camera );
lights.setup( lightsArray, shadowsArray, camera ); currentRenderContext.setupLights( camera );
if ( _clippingEnabled ) _clipping.endShadows(); if ( _clippingEnabled ) _clipping.endShadows();
...@@ -1198,6 +1196,8 @@ function WebGLRenderer( parameters ) { ...@@ -1198,6 +1196,8 @@ function WebGLRenderer( parameters ) {
// custom renderers // custom renderers
var spritesArray = currentRenderContext.state.spritesArray;
spriteRenderer.render( spritesArray, scene, camera ); spriteRenderer.render( spritesArray, scene, camera );
// Generate mipmap if we're using any kind of mipmap filtering // Generate mipmap if we're using any kind of mipmap filtering
...@@ -1293,11 +1293,11 @@ function WebGLRenderer( parameters ) { ...@@ -1293,11 +1293,11 @@ function WebGLRenderer( parameters ) {
if ( object.isLight ) { if ( object.isLight ) {
lightsArray.push( object ); currentRenderContext.pushLight( object );
if ( object.castShadow ) { if ( object.castShadow ) {
shadowsArray.push( object ); currentRenderContext.pushShadow( object );
} }
...@@ -1305,7 +1305,7 @@ function WebGLRenderer( parameters ) { ...@@ -1305,7 +1305,7 @@ function WebGLRenderer( parameters ) {
if ( ! object.frustumCulled || _frustum.intersectsSprite( object ) ) { if ( ! object.frustumCulled || _frustum.intersectsSprite( object ) ) {
spritesArray.push( object ); currentRenderContext.pushSprite( object );
} }
...@@ -1432,6 +1432,7 @@ function WebGLRenderer( parameters ) { ...@@ -1432,6 +1432,7 @@ function WebGLRenderer( parameters ) {
function renderObject( object, scene, camera, geometry, material, group ) { function renderObject( object, scene, camera, geometry, material, group ) {
object.onBeforeRender( _this, scene, camera, geometry, material, group ); object.onBeforeRender( _this, scene, camera, geometry, material, group );
restoreRenderContext( scene, _currentArrayCamera || camera );
object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld ); object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
object.normalMatrix.getNormalMatrix( object.modelViewMatrix ); object.normalMatrix.getNormalMatrix( object.modelViewMatrix );
...@@ -1455,6 +1456,7 @@ function WebGLRenderer( parameters ) { ...@@ -1455,6 +1456,7 @@ function WebGLRenderer( parameters ) {
} }
object.onAfterRender( _this, scene, camera, geometry, material, group ); object.onAfterRender( _this, scene, camera, geometry, material, group );
restoreRenderContext( scene, _currentArrayCamera || camera );
} }
...@@ -1462,6 +1464,9 @@ function WebGLRenderer( parameters ) { ...@@ -1462,6 +1464,9 @@ function WebGLRenderer( parameters ) {
var materialProperties = properties.get( material ); var materialProperties = properties.get( material );
var lights = currentRenderContext.state.lights;
var shadowsArray = currentRenderContext.state.shadowsArray;
var parameters = programCache.getParameters( var parameters = programCache.getParameters(
material, lights.state, shadowsArray, fog, _clipping.numPlanes, _clipping.numIntersection, object ); material, lights.state, shadowsArray, fog, _clipping.numPlanes, _clipping.numIntersection, object );
...@@ -1480,6 +1485,11 @@ function WebGLRenderer( parameters ) { ...@@ -1480,6 +1485,11 @@ function WebGLRenderer( parameters ) {
// changed glsl or parameters // changed glsl or parameters
releaseMaterialProgramReference( material ); releaseMaterialProgramReference( material );
} else if ( materialProperties.lightsHash !== lights.state.hash ) {
properties.update( material, 'lightsHash', lights.state.hash );
programChange = false;
} else if ( parameters.shaderID !== undefined ) { } else if ( parameters.shaderID !== undefined ) {
// same glsl and uniform list // same glsl and uniform list
...@@ -1611,6 +1621,7 @@ function WebGLRenderer( parameters ) { ...@@ -1611,6 +1621,7 @@ function WebGLRenderer( parameters ) {
_usedTextureUnits = 0; _usedTextureUnits = 0;
var materialProperties = properties.get( material ); var materialProperties = properties.get( material );
var lights = currentRenderContext.state.lights;
if ( _clippingEnabled ) { if ( _clippingEnabled ) {
...@@ -2308,6 +2319,14 @@ function WebGLRenderer( parameters ) { ...@@ -2308,6 +2319,14 @@ function WebGLRenderer( parameters ) {
} }
//
function restoreRenderContext( scene, camera ) {
currentRenderContext = renderContexts.get( scene, camera );
}
// GL state setting // GL state setting
this.setFaceCulling = function ( cullFace, frontFaceDirection ) { this.setFaceCulling = function ( cullFace, frontFaceDirection ) {
......
...@@ -100,7 +100,7 @@ function UniformsCache() { ...@@ -100,7 +100,7 @@ function UniformsCache() {
} }
function WebGLLights() { function WebGLLights( contextId ) {
var cache = new UniformsCache(); var cache = new UniformsCache();
...@@ -313,7 +313,7 @@ function WebGLLights() { ...@@ -313,7 +313,7 @@ function WebGLLights() {
state.hemi.length = hemiLength; state.hemi.length = hemiLength;
// TODO (sam-g-steel) why aren't we using join // TODO (sam-g-steel) why aren't we using join
state.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + rectAreaLength + ',' + hemiLength + ',' + shadows.length; state.hash = directionalLength + ',' + pointLength + ',' + spotLength + ',' + rectAreaLength + ',' + hemiLength + ',' + shadows.length + ',' + contextId;
} }
......
...@@ -28,6 +28,15 @@ function WebGLProperties() { ...@@ -28,6 +28,15 @@ function WebGLProperties() {
} }
function update( object, key, value ) {
var uuid = object.uuid;
var map = properties[ uuid ];
map[ key ] = value;
}
function dispose() { function dispose() {
properties = {}; properties = {};
...@@ -37,6 +46,7 @@ function WebGLProperties() { ...@@ -37,6 +46,7 @@ function WebGLProperties() {
return { return {
get: get, get: get,
remove: remove, remove: remove,
update: update,
dispose: dispose dispose: dispose
}; };
......
/**
* @author Mugen87 / https://github.com/Mugen87
*/
import { WebGLLights } from './WebGLLights.js';
var count = 0;
function WebGLRenderContext() {
var id = count ++;
var lights = new WebGLLights( id );
var lightsArray = [];
var shadowsArray = [];
var spritesArray = [];
function init() {
lightsArray.length = 0;
shadowsArray.length = 0;
spritesArray.length = 0;
}
function pushLight( light ) {
lightsArray.push( light );
}
function pushShadow( shadowLight ) {
shadowsArray.push( shadowLight );
}
function pushSprite( shadowLight ) {
spritesArray.push( shadowLight );
}
function setupLights( camera ) {
lights.setup( lightsArray, shadowsArray, camera );
}
var state = {
lightsArray: lightsArray,
shadowsArray: shadowsArray,
spritesArray: spritesArray,
lights: lights
};
return {
init: init,
state: state,
setupLights: setupLights,
pushLight: pushLight,
pushShadow: pushShadow,
pushSprite: pushSprite
};
}
function WebGLRenderContexts() {
var renderContexts = {};
function get( scene, camera ) {
var hash = scene.id + ',' + camera.id;
var renderContext = renderContexts[ hash ];
if ( renderContext === undefined ) {
renderContext = new WebGLRenderContext();
renderContexts[ hash ] = renderContext;
}
return renderContext;
}
function dispose() {
renderContexts = {};
}
return {
get: get,
dispose: dispose
};
}
export { WebGLRenderContexts };
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册