Vom Anderen PC aus hoch gespielt
This commit is contained in:
58
node_modules/three/examples/jsm/renderers/common/Animation.js
generated
vendored
Normal file
58
node_modules/three/examples/jsm/renderers/common/Animation.js
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
class Animation {
|
||||
|
||||
constructor() {
|
||||
|
||||
this.nodes = null;
|
||||
|
||||
this.animationLoop = null;
|
||||
this.requestId = null;
|
||||
|
||||
this.isAnimating = false;
|
||||
|
||||
this.context = self;
|
||||
|
||||
}
|
||||
|
||||
start() {
|
||||
|
||||
if ( this.isAnimating === true || this.animationLoop === null || this.nodes === null ) return;
|
||||
|
||||
this.isAnimating = true;
|
||||
|
||||
const update = ( time, frame ) => {
|
||||
|
||||
this.requestId = self.requestAnimationFrame( update );
|
||||
|
||||
this.nodes.nodeFrame.update();
|
||||
|
||||
this.animationLoop( time, frame );
|
||||
|
||||
};
|
||||
|
||||
this.requestId = self.requestAnimationFrame( update );
|
||||
|
||||
}
|
||||
|
||||
stop() {
|
||||
|
||||
self.cancelAnimationFrame( this.requestId );
|
||||
|
||||
this.isAnimating = false;
|
||||
|
||||
}
|
||||
|
||||
setAnimationLoop( callback ) {
|
||||
|
||||
this.animationLoop = callback;
|
||||
|
||||
}
|
||||
|
||||
setNodes( nodes ) {
|
||||
|
||||
this.nodes = nodes;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Animation;
|
||||
75
node_modules/three/examples/jsm/renderers/common/Attributes.js
generated
vendored
Normal file
75
node_modules/three/examples/jsm/renderers/common/Attributes.js
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
import DataMap from './DataMap.js';
|
||||
import { AttributeType } from './Constants.js';
|
||||
import { DynamicDrawUsage } from 'three';
|
||||
|
||||
class Attributes extends DataMap {
|
||||
|
||||
constructor( backend ) {
|
||||
|
||||
super();
|
||||
|
||||
this.backend = backend;
|
||||
|
||||
}
|
||||
|
||||
delete( attribute ) {
|
||||
|
||||
const attributeData = super.delete( attribute );
|
||||
|
||||
if ( attributeData !== undefined ) {
|
||||
|
||||
this.backend.destroyAttribute( attribute );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
update( attribute, type ) {
|
||||
|
||||
const data = this.get( attribute );
|
||||
|
||||
if ( data.version === undefined ) {
|
||||
|
||||
if ( type === AttributeType.VERTEX ) {
|
||||
|
||||
this.backend.createAttribute( attribute );
|
||||
|
||||
} else if ( type === AttributeType.INDEX ) {
|
||||
|
||||
this.backend.createIndexAttribute( attribute );
|
||||
|
||||
} else if ( type === AttributeType.STORAGE ) {
|
||||
|
||||
this.backend.createStorageAttribute( attribute );
|
||||
|
||||
}
|
||||
|
||||
data.version = this._getBufferAttribute( attribute ).version;
|
||||
|
||||
} else {
|
||||
|
||||
const bufferAttribute = this._getBufferAttribute( attribute );
|
||||
|
||||
if ( data.version < bufferAttribute.version || bufferAttribute.usage === DynamicDrawUsage ) {
|
||||
|
||||
this.backend.updateAttribute( attribute );
|
||||
|
||||
data.version = bufferAttribute.version;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_getBufferAttribute( attribute ) {
|
||||
|
||||
if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data;
|
||||
|
||||
return attribute;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Attributes;
|
||||
165
node_modules/three/examples/jsm/renderers/common/Backend.js
generated
vendored
Normal file
165
node_modules/three/examples/jsm/renderers/common/Backend.js
generated
vendored
Normal file
@@ -0,0 +1,165 @@
|
||||
let vector2 = null;
|
||||
let vector4 = null;
|
||||
|
||||
import { Vector2, Vector4, REVISION, createCanvasElement } from 'three';
|
||||
|
||||
class Backend {
|
||||
|
||||
constructor( parameters = {} ) {
|
||||
|
||||
this.parameters = Object.assign( {}, parameters );
|
||||
this.data = new WeakMap();
|
||||
this.renderer = null;
|
||||
this.domElement = null;
|
||||
|
||||
}
|
||||
|
||||
async init( renderer ) {
|
||||
|
||||
this.renderer = renderer;
|
||||
|
||||
}
|
||||
|
||||
// render context
|
||||
|
||||
begin( renderContext ) { }
|
||||
|
||||
finish( renderContext ) { }
|
||||
|
||||
// render object
|
||||
|
||||
draw( renderObject, info ) { }
|
||||
|
||||
// program
|
||||
|
||||
createProgram( program ) { }
|
||||
|
||||
destroyProgram( program ) { }
|
||||
|
||||
// bindings
|
||||
|
||||
createBindings( renderObject ) { }
|
||||
|
||||
updateBindings( renderObject ) { }
|
||||
|
||||
// pipeline
|
||||
|
||||
createRenderPipeline( renderObject ) { }
|
||||
|
||||
createComputePipeline( computeNode, pipeline ) { }
|
||||
|
||||
destroyPipeline( pipeline ) { }
|
||||
|
||||
// cache key
|
||||
|
||||
needsUpdate( renderObject ) { } // return Boolean ( fast test )
|
||||
|
||||
getCacheKey( renderObject ) { } // return String
|
||||
|
||||
// node builder
|
||||
|
||||
createNodeBuilder( renderObject ) { } // return NodeBuilder (ADD IT)
|
||||
|
||||
// textures
|
||||
|
||||
createSampler( texture ) { }
|
||||
|
||||
createDefaultTexture( texture ) { }
|
||||
|
||||
createTexture( texture ) { }
|
||||
|
||||
copyTextureToBuffer( texture, x, y, width, height ) {}
|
||||
|
||||
// attributes
|
||||
|
||||
createAttribute( attribute ) { }
|
||||
|
||||
createIndexAttribute( attribute ) { }
|
||||
|
||||
updateAttribute( attribute ) { }
|
||||
|
||||
destroyAttribute( attribute ) { }
|
||||
|
||||
// canvas
|
||||
|
||||
updateSize() { }
|
||||
|
||||
// utils
|
||||
|
||||
hasFeature( name ) { } // return Boolean
|
||||
|
||||
getInstanceCount( renderObject ) {
|
||||
|
||||
const { object, geometry } = renderObject;
|
||||
|
||||
return geometry.isInstancedBufferGeometry ? geometry.instanceCount : ( object.isInstancedMesh ? object.count : 1 );
|
||||
|
||||
}
|
||||
|
||||
getDrawingBufferSize() {
|
||||
|
||||
vector2 = vector2 || new Vector2();
|
||||
|
||||
return this.renderer.getDrawingBufferSize( vector2 );
|
||||
|
||||
}
|
||||
|
||||
getScissor() {
|
||||
|
||||
vector4 = vector4 || new Vector4();
|
||||
|
||||
return this.renderer.getScissor( vector4 );
|
||||
|
||||
}
|
||||
|
||||
getDomElement() {
|
||||
|
||||
let domElement = this.domElement;
|
||||
|
||||
if ( domElement === null ) {
|
||||
|
||||
domElement = ( this.parameters.canvas !== undefined ) ? this.parameters.canvas : createCanvasElement();
|
||||
|
||||
// OffscreenCanvas does not have setAttribute, see #22811
|
||||
if ( 'setAttribute' in domElement ) domElement.setAttribute( 'data-engine', `three.js r${REVISION}` );
|
||||
|
||||
this.domElement = domElement;
|
||||
|
||||
}
|
||||
|
||||
return domElement;
|
||||
|
||||
}
|
||||
|
||||
// resource properties
|
||||
|
||||
set( object, value ) {
|
||||
|
||||
this.data.set( object, value );
|
||||
|
||||
}
|
||||
|
||||
get( object ) {
|
||||
|
||||
let map = this.data.get( object );
|
||||
|
||||
if ( map === undefined ) {
|
||||
|
||||
map = {};
|
||||
this.data.set( object, map );
|
||||
|
||||
}
|
||||
|
||||
return map;
|
||||
|
||||
}
|
||||
|
||||
delete( object ) {
|
||||
|
||||
this.data.delete( object );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Backend;
|
||||
136
node_modules/three/examples/jsm/renderers/common/Background.js
generated
vendored
Normal file
136
node_modules/three/examples/jsm/renderers/common/Background.js
generated
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
import DataMap from './DataMap.js';
|
||||
import { Color, Mesh, SphereGeometry, BackSide } from 'three';
|
||||
import { context, normalWorld, backgroundBlurriness, backgroundIntensity, NodeMaterial, modelViewProjection } from '../../nodes/Nodes.js';
|
||||
|
||||
let _clearAlpha;
|
||||
const _clearColor = new Color();
|
||||
|
||||
class Background extends DataMap {
|
||||
|
||||
constructor( renderer, nodes ) {
|
||||
|
||||
super();
|
||||
|
||||
this.renderer = renderer;
|
||||
this.nodes = nodes;
|
||||
|
||||
this.backgroundMesh = null;
|
||||
this.backgroundMeshNode = null;
|
||||
|
||||
}
|
||||
|
||||
update( scene, renderList, renderContext ) {
|
||||
|
||||
const renderer = this.renderer;
|
||||
const background = this.nodes.getBackgroundNode( scene ) || scene.background;
|
||||
|
||||
let forceClear = false;
|
||||
|
||||
if ( background === null ) {
|
||||
|
||||
// no background settings, use clear color configuration from the renderer
|
||||
|
||||
_clearColor.copyLinearToSRGB( renderer._clearColor );
|
||||
_clearAlpha = renderer._clearAlpha;
|
||||
|
||||
} else if ( background.isColor === true ) {
|
||||
|
||||
// background is an opaque color
|
||||
|
||||
_clearColor.copyLinearToSRGB( background );
|
||||
_clearAlpha = 1;
|
||||
forceClear = true;
|
||||
|
||||
} else if ( background.isNode === true ) {
|
||||
|
||||
const sceneData = this.get( scene );
|
||||
const backgroundNode = background;
|
||||
|
||||
_clearColor.copy( renderer._clearColor );
|
||||
_clearAlpha = renderer._clearAlpha;
|
||||
|
||||
let backgroundMesh = this.backgroundMesh;
|
||||
|
||||
if ( backgroundMesh === null ) {
|
||||
|
||||
this.backgroundMeshNode = context( backgroundNode, {
|
||||
// @TODO: Add Texture2D support using node context
|
||||
getUVNode: () => normalWorld,
|
||||
getSamplerLevelNode: () => backgroundBlurriness
|
||||
} ).mul( backgroundIntensity );
|
||||
|
||||
let viewProj = modelViewProjection();
|
||||
viewProj = viewProj.setZ( viewProj.w );
|
||||
|
||||
const nodeMaterial = new NodeMaterial();
|
||||
nodeMaterial.outputNode = this.backgroundMeshNode;
|
||||
nodeMaterial.side = BackSide;
|
||||
nodeMaterial.depthTest = false;
|
||||
nodeMaterial.depthWrite = false;
|
||||
nodeMaterial.fog = false;
|
||||
nodeMaterial.vertexNode = viewProj;
|
||||
|
||||
this.backgroundMesh = backgroundMesh = new Mesh( new SphereGeometry( 1, 32, 32 ), nodeMaterial );
|
||||
backgroundMesh.frustumCulled = false;
|
||||
|
||||
backgroundMesh.onBeforeRender = function ( renderer, scene, camera ) {
|
||||
|
||||
this.matrixWorld.copyPosition( camera.matrixWorld );
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
const backgroundCacheKey = backgroundNode.getCacheKey();
|
||||
|
||||
if ( sceneData.backgroundCacheKey !== backgroundCacheKey ) {
|
||||
|
||||
this.backgroundMeshNode.node = backgroundNode;
|
||||
|
||||
backgroundMesh.material.needsUpdate = true;
|
||||
|
||||
sceneData.backgroundCacheKey = backgroundCacheKey;
|
||||
|
||||
}
|
||||
|
||||
renderList.unshift( backgroundMesh, backgroundMesh.geometry, backgroundMesh.material, 0, 0, null );
|
||||
|
||||
} else {
|
||||
|
||||
console.error( 'THREE.Renderer: Unsupported background configuration.', background );
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
if ( renderer.autoClear === true || forceClear === true ) {
|
||||
|
||||
_clearColor.multiplyScalar( _clearAlpha );
|
||||
|
||||
const clearColorValue = renderContext.clearColorValue;
|
||||
|
||||
clearColorValue.r = _clearColor.r;
|
||||
clearColorValue.g = _clearColor.g;
|
||||
clearColorValue.b = _clearColor.b;
|
||||
clearColorValue.a = _clearAlpha;
|
||||
|
||||
renderContext.depthClearValue = renderer._clearDepth;
|
||||
renderContext.stencilClearValue = renderer._clearStencil;
|
||||
|
||||
renderContext.clearColor = renderer.autoClearColor === true;
|
||||
renderContext.clearDepth = renderer.autoClearDepth === true;
|
||||
renderContext.clearStencil = renderer.autoClearStencil === true;
|
||||
|
||||
} else {
|
||||
|
||||
renderContext.clearColor = false;
|
||||
renderContext.clearDepth = false;
|
||||
renderContext.clearStencil = false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Background;
|
||||
25
node_modules/three/examples/jsm/renderers/common/Binding.js
generated
vendored
Normal file
25
node_modules/three/examples/jsm/renderers/common/Binding.js
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
class Binding {
|
||||
|
||||
constructor( name = '' ) {
|
||||
|
||||
this.name = name;
|
||||
|
||||
this.visibility = 0;
|
||||
|
||||
}
|
||||
|
||||
setVisibility( visibility ) {
|
||||
|
||||
this.visibility |= visibility;
|
||||
|
||||
}
|
||||
|
||||
clone() {
|
||||
|
||||
return Object.assign( new this.constructor(), this );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Binding;
|
||||
164
node_modules/three/examples/jsm/renderers/common/Bindings.js
generated
vendored
Normal file
164
node_modules/three/examples/jsm/renderers/common/Bindings.js
generated
vendored
Normal file
@@ -0,0 +1,164 @@
|
||||
import DataMap from './DataMap.js';
|
||||
import { AttributeType } from './Constants.js';
|
||||
|
||||
class Bindings extends DataMap {
|
||||
|
||||
constructor( backend, nodes, textures, attributes, pipelines, info ) {
|
||||
|
||||
super();
|
||||
|
||||
this.backend = backend;
|
||||
this.textures = textures;
|
||||
this.pipelines = pipelines;
|
||||
this.attributes = attributes;
|
||||
this.nodes = nodes;
|
||||
this.info = info;
|
||||
|
||||
this.pipelines.bindings = this; // assign bindings to pipelines
|
||||
|
||||
this.updateMap = new WeakMap();
|
||||
|
||||
}
|
||||
|
||||
getForRender( renderObject ) {
|
||||
|
||||
const bindings = renderObject.getBindings();
|
||||
|
||||
const data = this.get( renderObject );
|
||||
|
||||
if ( data.bindings !== bindings ) {
|
||||
|
||||
// each object defines an array of bindings (ubos, textures, samplers etc.)
|
||||
|
||||
data.bindings = bindings;
|
||||
|
||||
this._init( bindings );
|
||||
|
||||
this.backend.createBindings( bindings );
|
||||
|
||||
}
|
||||
|
||||
return data.bindings;
|
||||
|
||||
}
|
||||
|
||||
getForCompute( computeNode ) {
|
||||
|
||||
const data = this.get( computeNode );
|
||||
|
||||
if ( data.bindings === undefined ) {
|
||||
|
||||
const nodeBuilderState = this.nodes.getForCompute( computeNode );
|
||||
|
||||
const bindings = nodeBuilderState.bindings.compute;
|
||||
|
||||
data.bindings = bindings;
|
||||
|
||||
this._init( bindings );
|
||||
|
||||
this.backend.createBindings( bindings );
|
||||
|
||||
}
|
||||
|
||||
return data.bindings;
|
||||
|
||||
}
|
||||
|
||||
updateForCompute( computeNode ) {
|
||||
|
||||
this._update( computeNode, this.getForCompute( computeNode ) );
|
||||
|
||||
}
|
||||
|
||||
updateForRender( renderObject ) {
|
||||
|
||||
this._update( renderObject, this.getForRender( renderObject ) );
|
||||
|
||||
}
|
||||
|
||||
_init( bindings ) {
|
||||
|
||||
for ( const binding of bindings ) {
|
||||
|
||||
if ( binding.isSampledTexture ) {
|
||||
|
||||
this.textures.updateTexture( binding.texture );
|
||||
|
||||
} else if ( binding.isStorageBuffer ) {
|
||||
|
||||
const attribute = binding.attribute;
|
||||
|
||||
this.attributes.update( attribute, AttributeType.STORAGE );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_update( object, bindings ) {
|
||||
|
||||
const { backend } = this;
|
||||
|
||||
const updateMap = this.updateMap;
|
||||
const frame = this.info.render.frame;
|
||||
|
||||
let needsBindingsUpdate = false;
|
||||
|
||||
// iterate over all bindings and check if buffer updates or a new binding group is required
|
||||
|
||||
for ( const binding of bindings ) {
|
||||
|
||||
const isUpdated = updateMap.get( binding ) === frame;
|
||||
|
||||
if ( isUpdated ) continue;
|
||||
|
||||
if ( binding.isUniformBuffer ) {
|
||||
|
||||
const needsUpdate = binding.update();
|
||||
|
||||
if ( needsUpdate ) {
|
||||
|
||||
backend.updateBinding( binding );
|
||||
|
||||
}
|
||||
|
||||
} else if ( binding.isSampledTexture ) {
|
||||
|
||||
if ( binding.needsBindingsUpdate ) needsBindingsUpdate = true;
|
||||
|
||||
const needsUpdate = binding.update();
|
||||
|
||||
if ( needsUpdate ) {
|
||||
|
||||
this.textures.updateTexture( binding.texture );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
updateMap.set( binding, frame );
|
||||
|
||||
}
|
||||
|
||||
if ( needsBindingsUpdate === true ) {
|
||||
|
||||
const pipeline = this.pipelines.getForRender( object );
|
||||
|
||||
this.backend.updateBindings( bindings, pipeline );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
super.dispose();
|
||||
|
||||
this.updateMap = new WeakMap();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Bindings;
|
||||
38
node_modules/three/examples/jsm/renderers/common/Buffer.js
generated
vendored
Normal file
38
node_modules/three/examples/jsm/renderers/common/Buffer.js
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
import Binding from './Binding.js';
|
||||
import { getFloatLength } from './BufferUtils.js';
|
||||
|
||||
class Buffer extends Binding {
|
||||
|
||||
constructor( name, buffer = null ) {
|
||||
|
||||
super( name );
|
||||
|
||||
this.isBuffer = true;
|
||||
|
||||
this.bytesPerElement = Float32Array.BYTES_PER_ELEMENT;
|
||||
|
||||
this._buffer = buffer;
|
||||
|
||||
}
|
||||
|
||||
get byteLength() {
|
||||
|
||||
return getFloatLength( this._buffer.byteLength );
|
||||
|
||||
}
|
||||
|
||||
get buffer() {
|
||||
|
||||
return this._buffer;
|
||||
|
||||
}
|
||||
|
||||
update() {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Buffer;
|
||||
33
node_modules/three/examples/jsm/renderers/common/BufferUtils.js
generated
vendored
Normal file
33
node_modules/three/examples/jsm/renderers/common/BufferUtils.js
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
import { GPU_CHUNK_BYTES } from './Constants.js';
|
||||
|
||||
function getFloatLength( floatLength ) {
|
||||
|
||||
// ensure chunk size alignment (STD140 layout)
|
||||
|
||||
return floatLength + ( ( GPU_CHUNK_BYTES - ( floatLength % GPU_CHUNK_BYTES ) ) % GPU_CHUNK_BYTES );
|
||||
|
||||
}
|
||||
|
||||
function getVectorLength( count, vectorLength = 4 ) {
|
||||
|
||||
const strideLength = getStrideLength( vectorLength );
|
||||
|
||||
const floatLength = strideLength * count;
|
||||
|
||||
return getFloatLength( floatLength );
|
||||
|
||||
}
|
||||
|
||||
function getStrideLength( vectorLength ) {
|
||||
|
||||
const strideLength = 4;
|
||||
|
||||
return vectorLength + ( ( strideLength - ( vectorLength % strideLength ) ) % strideLength );
|
||||
|
||||
}
|
||||
|
||||
export {
|
||||
getFloatLength,
|
||||
getVectorLength,
|
||||
getStrideLength
|
||||
};
|
||||
89
node_modules/three/examples/jsm/renderers/common/ChainMap.js
generated
vendored
Normal file
89
node_modules/three/examples/jsm/renderers/common/ChainMap.js
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
export default class ChainMap {
|
||||
|
||||
constructor() {
|
||||
|
||||
this.weakMap = new WeakMap();
|
||||
|
||||
}
|
||||
|
||||
get( keys ) {
|
||||
|
||||
if ( Array.isArray( keys ) ) {
|
||||
|
||||
let map = this.weakMap;
|
||||
|
||||
for ( let i = 0; i < keys.length - 1; i ++ ) {
|
||||
|
||||
map = map.get( keys[ i ] );
|
||||
|
||||
if ( map === undefined ) return undefined;
|
||||
|
||||
}
|
||||
|
||||
return map.get( keys[ keys.length - 1 ] );
|
||||
|
||||
} else {
|
||||
|
||||
return super.get( keys );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
set( keys, value ) {
|
||||
|
||||
if ( Array.isArray( keys ) ) {
|
||||
|
||||
let map = this.weakMap;
|
||||
|
||||
for ( let i = 0; i < keys.length - 1; i ++ ) {
|
||||
|
||||
const key = keys[ i ];
|
||||
|
||||
if ( map.has( key ) === false ) map.set( key, new WeakMap() );
|
||||
|
||||
map = map.get( key );
|
||||
|
||||
}
|
||||
|
||||
return map.set( keys[ keys.length - 1 ], value );
|
||||
|
||||
} else {
|
||||
|
||||
return super.set( keys, value );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
delete( keys ) {
|
||||
|
||||
if ( Array.isArray( keys ) ) {
|
||||
|
||||
let map = this.weakMap;
|
||||
|
||||
for ( let i = 0; i < keys.length - 1; i ++ ) {
|
||||
|
||||
map = map.get( keys[ i ] );
|
||||
|
||||
if ( map === undefined ) return false;
|
||||
|
||||
}
|
||||
|
||||
return map.delete( keys[ keys.length - 1 ] );
|
||||
|
||||
} else {
|
||||
|
||||
return super.delete( keys );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this.weakMap.clear();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
17
node_modules/three/examples/jsm/renderers/common/ComputePipeline.js
generated
vendored
Normal file
17
node_modules/three/examples/jsm/renderers/common/ComputePipeline.js
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
import Pipeline from './Pipeline.js';
|
||||
|
||||
class ComputePipeline extends Pipeline {
|
||||
|
||||
constructor( cacheKey, computeProgram ) {
|
||||
|
||||
super( cacheKey );
|
||||
|
||||
this.computeProgram = computeProgram;
|
||||
|
||||
this.isComputePipeline = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ComputePipeline;
|
||||
14
node_modules/three/examples/jsm/renderers/common/Constants.js
generated
vendored
Normal file
14
node_modules/three/examples/jsm/renderers/common/Constants.js
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
export const AttributeType = {
|
||||
VERTEX: 1,
|
||||
INDEX: 2,
|
||||
STORAGE: 4
|
||||
};
|
||||
|
||||
// size of a chunk in bytes (STD140 layout)
|
||||
|
||||
export const GPU_CHUNK_BYTES = 16;
|
||||
|
||||
// @TODO: Move to src/constants.js
|
||||
|
||||
export const BlendColorFactor = 211;
|
||||
export const OneMinusBlendColorFactor = 212;
|
||||
65
node_modules/three/examples/jsm/renderers/common/CubeRenderTarget.js
generated
vendored
Normal file
65
node_modules/three/examples/jsm/renderers/common/CubeRenderTarget.js
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
import { WebGLCubeRenderTarget, Scene, CubeCamera, BoxGeometry, Mesh, BackSide, NoBlending, LinearFilter, LinearMipmapLinearFilter } from 'three';
|
||||
import { equirectUV } from '../../nodes/utils/EquirectUVNode.js';
|
||||
import { texture as TSL_Texture } from '../../nodes/accessors/TextureNode.js';
|
||||
import { positionWorldDirection } from '../../nodes/accessors/PositionNode.js';
|
||||
import { createNodeMaterialFromType } from '../../nodes/materials/NodeMaterial.js';
|
||||
|
||||
// @TODO: Consider rename WebGLCubeRenderTarget to just CubeRenderTarget
|
||||
|
||||
class CubeRenderTarget extends WebGLCubeRenderTarget {
|
||||
|
||||
constructor( size = 1, options = {} ) {
|
||||
|
||||
super( size, options );
|
||||
|
||||
this.isCubeRenderTarget = true;
|
||||
|
||||
}
|
||||
|
||||
fromEquirectangularTexture( renderer, texture ) {
|
||||
|
||||
const currentMinFilter = texture.minFilter;
|
||||
const currentGenerateMipmaps = texture.generateMipmaps;
|
||||
|
||||
texture.generateMipmaps = true;
|
||||
|
||||
this.texture.type = texture.type;
|
||||
this.texture.colorSpace = texture.colorSpace;
|
||||
|
||||
this.texture.generateMipmaps = texture.generateMipmaps;
|
||||
this.texture.minFilter = texture.minFilter;
|
||||
this.texture.magFilter = texture.magFilter;
|
||||
|
||||
const geometry = new BoxGeometry( 5, 5, 5 );
|
||||
|
||||
const uvNode = equirectUV( positionWorldDirection );
|
||||
|
||||
const material = createNodeMaterialFromType( 'MeshBasicNodeMaterial' );
|
||||
material.colorNode = TSL_Texture( texture, uvNode, 0 );
|
||||
material.side = BackSide;
|
||||
material.blending = NoBlending;
|
||||
|
||||
const mesh = new Mesh( geometry, material );
|
||||
|
||||
const scene = new Scene();
|
||||
scene.add( mesh );
|
||||
|
||||
// Avoid blurred poles
|
||||
if ( texture.minFilter === LinearMipmapLinearFilter ) texture.minFilter = LinearFilter;
|
||||
|
||||
const camera = new CubeCamera( 1, 10, this );
|
||||
camera.update( renderer, scene );
|
||||
|
||||
texture.minFilter = currentMinFilter;
|
||||
texture.currentGenerateMipmaps = currentGenerateMipmaps;
|
||||
|
||||
mesh.geometry.dispose();
|
||||
mesh.material.dispose();
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default CubeRenderTarget;
|
||||
54
node_modules/three/examples/jsm/renderers/common/DataMap.js
generated
vendored
Normal file
54
node_modules/three/examples/jsm/renderers/common/DataMap.js
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
class DataMap {
|
||||
|
||||
constructor() {
|
||||
|
||||
this.data = new WeakMap();
|
||||
|
||||
}
|
||||
|
||||
get( object ) {
|
||||
|
||||
let map = this.data.get( object );
|
||||
|
||||
if ( map === undefined ) {
|
||||
|
||||
map = {};
|
||||
this.data.set( object, map );
|
||||
|
||||
}
|
||||
|
||||
return map;
|
||||
|
||||
}
|
||||
|
||||
delete( object ) {
|
||||
|
||||
let map;
|
||||
|
||||
if ( this.data.has( object ) ) {
|
||||
|
||||
map = this.data.get( object );
|
||||
|
||||
this.data.delete( object );
|
||||
|
||||
}
|
||||
|
||||
return map;
|
||||
|
||||
}
|
||||
|
||||
has( object ) {
|
||||
|
||||
return this.data.has( object );
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this.data.clear();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default DataMap;
|
||||
215
node_modules/three/examples/jsm/renderers/common/Geometries.js
generated
vendored
Normal file
215
node_modules/three/examples/jsm/renderers/common/Geometries.js
generated
vendored
Normal file
@@ -0,0 +1,215 @@
|
||||
import DataMap from './DataMap.js';
|
||||
import { AttributeType } from './Constants.js';
|
||||
import { Uint32BufferAttribute, Uint16BufferAttribute } from 'three';
|
||||
|
||||
function arrayNeedsUint32( array ) {
|
||||
|
||||
// assumes larger values usually on last
|
||||
|
||||
for ( let i = array.length - 1; i >= 0; -- i ) {
|
||||
|
||||
if ( array[ i ] >= 65535 ) return true; // account for PRIMITIVE_RESTART_FIXED_INDEX, #24565
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
function getWireframeVersion( geometry ) {
|
||||
|
||||
return ( geometry.index !== null ) ? geometry.index.version : geometry.attributes.position.version;
|
||||
|
||||
}
|
||||
|
||||
function getWireframeIndex( geometry ) {
|
||||
|
||||
const indices = [];
|
||||
|
||||
const geometryIndex = geometry.index;
|
||||
const geometryPosition = geometry.attributes.position;
|
||||
|
||||
if ( geometryIndex !== null ) {
|
||||
|
||||
const array = geometryIndex.array;
|
||||
|
||||
for ( let i = 0, l = array.length; i < l; i += 3 ) {
|
||||
|
||||
const a = array[ i + 0 ];
|
||||
const b = array[ i + 1 ];
|
||||
const c = array[ i + 2 ];
|
||||
|
||||
indices.push( a, b, b, c, c, a );
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
const array = geometryPosition.array;
|
||||
|
||||
for ( let i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) {
|
||||
|
||||
const a = i + 0;
|
||||
const b = i + 1;
|
||||
const c = i + 2;
|
||||
|
||||
indices.push( a, b, b, c, c, a );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const attribute = new ( arrayNeedsUint32( indices ) ? Uint32BufferAttribute : Uint16BufferAttribute )( indices, 1 );
|
||||
attribute.version = getWireframeVersion( geometry );
|
||||
|
||||
return attribute;
|
||||
|
||||
}
|
||||
|
||||
class Geometries extends DataMap {
|
||||
|
||||
constructor( attributes, info ) {
|
||||
|
||||
super();
|
||||
|
||||
this.attributes = attributes;
|
||||
this.info = info;
|
||||
|
||||
this.wireframes = new WeakMap();
|
||||
this.attributeFrame = new WeakMap();
|
||||
|
||||
}
|
||||
|
||||
has( renderObject ) {
|
||||
|
||||
const geometry = renderObject.geometry;
|
||||
|
||||
return super.has( geometry ) && this.get( geometry ).initialized === true;
|
||||
|
||||
}
|
||||
|
||||
updateForRender( renderObject ) {
|
||||
|
||||
if ( this.has( renderObject ) === false ) this.initGeometry( renderObject );
|
||||
|
||||
this.updateAttributes( renderObject );
|
||||
|
||||
}
|
||||
|
||||
initGeometry( renderObject ) {
|
||||
|
||||
const geometry = renderObject.geometry;
|
||||
const geometryData = this.get( geometry );
|
||||
|
||||
geometryData.initialized = true;
|
||||
|
||||
this.info.memory.geometries ++;
|
||||
|
||||
const onDispose = () => {
|
||||
|
||||
this.info.memory.geometries --;
|
||||
|
||||
const index = geometry.index;
|
||||
const geometryAttributes = renderObject.getAttributes();
|
||||
|
||||
if ( index !== null ) {
|
||||
|
||||
this.attributes.delete( index );
|
||||
|
||||
}
|
||||
|
||||
for ( const geometryAttribute of geometryAttributes ) {
|
||||
|
||||
this.attributes.delete( geometryAttribute );
|
||||
|
||||
}
|
||||
|
||||
const wireframeAttribute = this.wireframes.get( geometry );
|
||||
|
||||
if ( wireframeAttribute !== undefined ) {
|
||||
|
||||
this.attributes.delete( wireframeAttribute );
|
||||
|
||||
}
|
||||
|
||||
geometry.removeEventListener( 'dispose', onDispose );
|
||||
|
||||
};
|
||||
|
||||
geometry.addEventListener( 'dispose', onDispose );
|
||||
|
||||
}
|
||||
|
||||
updateAttributes( renderObject ) {
|
||||
|
||||
const attributes = renderObject.getAttributes();
|
||||
|
||||
for ( const attribute of attributes ) {
|
||||
|
||||
this.updateAttribute( attribute, AttributeType.VERTEX );
|
||||
|
||||
}
|
||||
|
||||
const index = this.getIndex( renderObject );
|
||||
|
||||
if ( index !== null ) {
|
||||
|
||||
this.updateAttribute( index, AttributeType.INDEX );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
updateAttribute( attribute, type ) {
|
||||
|
||||
const frame = this.info.render.frame;
|
||||
|
||||
if ( this.attributeFrame.get( attribute ) !== frame ) {
|
||||
|
||||
this.attributes.update( attribute, type );
|
||||
|
||||
this.attributeFrame.set( attribute, frame );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getIndex( renderObject ) {
|
||||
|
||||
const { geometry, material } = renderObject;
|
||||
|
||||
let index = geometry.index;
|
||||
|
||||
if ( material.wireframe === true ) {
|
||||
|
||||
const wireframes = this.wireframes;
|
||||
|
||||
let wireframeAttribute = wireframes.get( geometry );
|
||||
|
||||
if ( wireframeAttribute === undefined ) {
|
||||
|
||||
wireframeAttribute = getWireframeIndex( geometry );
|
||||
|
||||
wireframes.set( geometry, wireframeAttribute );
|
||||
|
||||
} else if ( wireframeAttribute.version !== getWireframeVersion( geometry ) ) {
|
||||
|
||||
this.attributes.delete( wireframeAttribute );
|
||||
|
||||
wireframeAttribute = getWireframeIndex( geometry );
|
||||
|
||||
wireframes.set( geometry, wireframeAttribute );
|
||||
|
||||
}
|
||||
|
||||
index = wireframeAttribute;
|
||||
|
||||
}
|
||||
|
||||
return index;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Geometries;
|
||||
73
node_modules/three/examples/jsm/renderers/common/Info.js
generated
vendored
Normal file
73
node_modules/three/examples/jsm/renderers/common/Info.js
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
class Info {
|
||||
|
||||
constructor() {
|
||||
|
||||
this.autoReset = true;
|
||||
|
||||
this.render = {
|
||||
frame: 0,
|
||||
drawCalls: 0,
|
||||
triangles: 0,
|
||||
points: 0,
|
||||
lines: 0
|
||||
};
|
||||
|
||||
this.memory = {
|
||||
geometries: 0,
|
||||
textures: 0
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
update( object, count, instanceCount ) {
|
||||
|
||||
this.render.drawCalls ++;
|
||||
|
||||
if ( object.isMesh || object.isSprite ) {
|
||||
|
||||
this.render.triangles += instanceCount * ( count / 3 );
|
||||
|
||||
} else if ( object.isPoints ) {
|
||||
|
||||
this.render.points += instanceCount * count;
|
||||
|
||||
} else if ( object.isLineSegments ) {
|
||||
|
||||
this.render.lines += instanceCount * ( count / 2 );
|
||||
|
||||
} else if ( object.isLine ) {
|
||||
|
||||
this.render.lines += instanceCount * ( count - 1 );
|
||||
|
||||
} else {
|
||||
|
||||
console.error( 'THREE.WebGPUInfo: Unknown object type.' );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
reset() {
|
||||
|
||||
this.render.drawCalls = 0;
|
||||
this.render.triangles = 0;
|
||||
this.render.points = 0;
|
||||
this.render.lines = 0;
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this.reset();
|
||||
|
||||
this.render.frame = 0;
|
||||
|
||||
this.memory.geometries = 0;
|
||||
this.memory.textures = 0;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export default Info;
|
||||
13
node_modules/three/examples/jsm/renderers/common/Pipeline.js
generated
vendored
Normal file
13
node_modules/three/examples/jsm/renderers/common/Pipeline.js
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
class Pipeline {
|
||||
|
||||
constructor( cacheKey ) {
|
||||
|
||||
this.cacheKey = cacheKey;
|
||||
|
||||
this.usedTimes = 0;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Pipeline;
|
||||
370
node_modules/three/examples/jsm/renderers/common/Pipelines.js
generated
vendored
Normal file
370
node_modules/three/examples/jsm/renderers/common/Pipelines.js
generated
vendored
Normal file
@@ -0,0 +1,370 @@
|
||||
import DataMap from './DataMap.js';
|
||||
import RenderPipeline from './RenderPipeline.js';
|
||||
import ComputePipeline from './ComputePipeline.js';
|
||||
import ProgrammableStage from './ProgrammableStage.js';
|
||||
|
||||
class Pipelines extends DataMap {
|
||||
|
||||
constructor( backend, nodes ) {
|
||||
|
||||
super();
|
||||
|
||||
this.backend = backend;
|
||||
this.nodes = nodes;
|
||||
|
||||
this.bindings = null; // set by the bindings
|
||||
|
||||
this.caches = new Map();
|
||||
this.programs = {
|
||||
vertex: new Map(),
|
||||
fragment: new Map(),
|
||||
compute: new Map()
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
getForCompute( computeNode, bindings ) {
|
||||
|
||||
const { backend } = this;
|
||||
|
||||
const data = this.get( computeNode );
|
||||
|
||||
if ( this._needsComputeUpdate( computeNode ) ) {
|
||||
|
||||
const previousPipeline = data.pipeline;
|
||||
|
||||
if ( previousPipeline ) {
|
||||
|
||||
previousPipeline.usedTimes --;
|
||||
previousPipeline.computeProgram.usedTimes --;
|
||||
|
||||
}
|
||||
|
||||
// get shader
|
||||
|
||||
const nodeBuilder = this.nodes.getForCompute( computeNode );
|
||||
|
||||
// programmable stage
|
||||
|
||||
let stageCompute = this.programs.compute.get( nodeBuilder.computeShader );
|
||||
|
||||
if ( stageCompute === undefined ) {
|
||||
|
||||
if ( previousPipeline && previousPipeline.computeProgram.usedTimes === 0 ) this._releaseProgram( previousPipeline.computeProgram );
|
||||
|
||||
stageCompute = new ProgrammableStage( nodeBuilder.computeShader, 'compute' );
|
||||
this.programs.compute.set( nodeBuilder.computeShader, stageCompute );
|
||||
|
||||
backend.createProgram( stageCompute );
|
||||
|
||||
}
|
||||
|
||||
// determine compute pipeline
|
||||
|
||||
const cacheKey = this._getComputeCacheKey( computeNode, stageCompute );
|
||||
|
||||
let pipeline = this.caches.get( cacheKey );
|
||||
|
||||
if ( pipeline === undefined ) {
|
||||
|
||||
if ( previousPipeline && previousPipeline.usedTimes === 0 ) this._releasePipeline( computeNode );
|
||||
|
||||
pipeline = this._getComputePipeline( computeNode, stageCompute, cacheKey, bindings );
|
||||
|
||||
}
|
||||
|
||||
// keep track of all used times
|
||||
|
||||
pipeline.usedTimes ++;
|
||||
stageCompute.usedTimes ++;
|
||||
|
||||
//
|
||||
|
||||
data.version = computeNode.version;
|
||||
data.pipeline = pipeline;
|
||||
|
||||
}
|
||||
|
||||
return data.pipeline;
|
||||
|
||||
}
|
||||
|
||||
getForRender( renderObject ) {
|
||||
|
||||
const { backend } = this;
|
||||
|
||||
const data = this.get( renderObject );
|
||||
|
||||
if ( this._needsRenderUpdate( renderObject ) ) {
|
||||
|
||||
const previousPipeline = data.pipeline;
|
||||
|
||||
if ( previousPipeline ) {
|
||||
|
||||
previousPipeline.usedTimes --;
|
||||
previousPipeline.vertexProgram.usedTimes --;
|
||||
previousPipeline.fragmentProgram.usedTimes --;
|
||||
|
||||
}
|
||||
|
||||
// get shader
|
||||
|
||||
const nodeBuilderState = renderObject.getNodeBuilderState();
|
||||
|
||||
// programmable stages
|
||||
|
||||
let stageVertex = this.programs.vertex.get( nodeBuilderState.vertexShader );
|
||||
|
||||
if ( stageVertex === undefined ) {
|
||||
|
||||
if ( previousPipeline && previousPipeline.vertexProgram.usedTimes === 0 ) this._releaseProgram( previousPipeline.vertexProgram );
|
||||
|
||||
stageVertex = new ProgrammableStage( nodeBuilderState.vertexShader, 'vertex' );
|
||||
this.programs.vertex.set( nodeBuilderState.vertexShader, stageVertex );
|
||||
|
||||
backend.createProgram( stageVertex );
|
||||
|
||||
}
|
||||
|
||||
let stageFragment = this.programs.fragment.get( nodeBuilderState.fragmentShader );
|
||||
|
||||
if ( stageFragment === undefined ) {
|
||||
|
||||
if ( previousPipeline && previousPipeline.fragmentProgram.usedTimes === 0 ) this._releaseProgram( previousPipeline.fragmentProgram );
|
||||
|
||||
stageFragment = new ProgrammableStage( nodeBuilderState.fragmentShader, 'fragment' );
|
||||
this.programs.fragment.set( nodeBuilderState.fragmentShader, stageFragment );
|
||||
|
||||
backend.createProgram( stageFragment );
|
||||
|
||||
}
|
||||
|
||||
// determine render pipeline
|
||||
|
||||
const cacheKey = this._getRenderCacheKey( renderObject, stageVertex, stageFragment );
|
||||
|
||||
let pipeline = this.caches.get( cacheKey );
|
||||
|
||||
if ( pipeline === undefined ) {
|
||||
|
||||
if ( previousPipeline && previousPipeline.usedTimes === 0 ) this._releasePipeline( previousPipeline );
|
||||
|
||||
pipeline = this._getRenderPipeline( renderObject, stageVertex, stageFragment, cacheKey );
|
||||
|
||||
} else {
|
||||
|
||||
renderObject.pipeline = pipeline;
|
||||
|
||||
}
|
||||
|
||||
// keep track of all used times
|
||||
|
||||
pipeline.usedTimes ++;
|
||||
stageVertex.usedTimes ++;
|
||||
stageFragment.usedTimes ++;
|
||||
|
||||
//
|
||||
|
||||
data.pipeline = pipeline;
|
||||
|
||||
}
|
||||
|
||||
return data.pipeline;
|
||||
|
||||
}
|
||||
|
||||
delete( object ) {
|
||||
|
||||
const pipeline = this.get( object ).pipeline;
|
||||
|
||||
if ( pipeline ) {
|
||||
|
||||
// pipeline
|
||||
|
||||
pipeline.usedTimes --;
|
||||
|
||||
if ( pipeline.usedTimes === 0 ) this._releasePipeline( pipeline );
|
||||
|
||||
// programs
|
||||
|
||||
if ( pipeline.isComputePipeline ) {
|
||||
|
||||
pipeline.computeProgram.usedTimes --;
|
||||
|
||||
if ( pipeline.computeProgram.usedTimes === 0 ) this._releaseProgram( pipeline.computeProgram );
|
||||
|
||||
} else {
|
||||
|
||||
pipeline.fragmentProgram.usedTimes --;
|
||||
pipeline.vertexProgram.usedTimes --;
|
||||
|
||||
if ( pipeline.vertexProgram.usedTimes === 0 ) this._releaseProgram( pipeline.vertexProgram );
|
||||
if ( pipeline.fragmentProgram.usedTimes === 0 ) this._releaseProgram( pipeline.fragmentProgram );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
super.delete( object );
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
super.dispose();
|
||||
|
||||
this.caches = new Map();
|
||||
this.programs = {
|
||||
vertex: new Map(),
|
||||
fragment: new Map(),
|
||||
compute: new Map()
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
updateForRender( renderObject ) {
|
||||
|
||||
this.getForRender( renderObject );
|
||||
|
||||
}
|
||||
|
||||
_getComputePipeline( computeNode, stageCompute, cacheKey, bindings ) {
|
||||
|
||||
// check for existing pipeline
|
||||
|
||||
cacheKey = cacheKey || this._getComputeCacheKey( computeNode, stageCompute );
|
||||
|
||||
let pipeline = this.caches.get( cacheKey );
|
||||
|
||||
if ( pipeline === undefined ) {
|
||||
|
||||
pipeline = new ComputePipeline( cacheKey, stageCompute );
|
||||
|
||||
this.caches.set( cacheKey, pipeline );
|
||||
|
||||
this.backend.createComputePipeline( pipeline, bindings );
|
||||
|
||||
}
|
||||
|
||||
return pipeline;
|
||||
|
||||
}
|
||||
|
||||
_getRenderPipeline( renderObject, stageVertex, stageFragment, cacheKey ) {
|
||||
|
||||
// check for existing pipeline
|
||||
|
||||
cacheKey = cacheKey || this._getRenderCacheKey( renderObject, stageVertex, stageFragment );
|
||||
|
||||
let pipeline = this.caches.get( cacheKey );
|
||||
|
||||
if ( pipeline === undefined ) {
|
||||
|
||||
pipeline = new RenderPipeline( cacheKey, stageVertex, stageFragment );
|
||||
|
||||
this.caches.set( cacheKey, pipeline );
|
||||
|
||||
renderObject.pipeline = pipeline;
|
||||
|
||||
this.backend.createRenderPipeline( renderObject );
|
||||
|
||||
}
|
||||
|
||||
return pipeline;
|
||||
|
||||
}
|
||||
|
||||
_getComputeCacheKey( computeNode, stageCompute ) {
|
||||
|
||||
return 'compute' + computeNode.id + stageCompute.id;
|
||||
|
||||
}
|
||||
|
||||
_getRenderCacheKey( renderObject, stageVertex, stageFragment ) {
|
||||
|
||||
const { material } = renderObject;
|
||||
|
||||
const parameters = [
|
||||
stageVertex.id, stageFragment.id,
|
||||
material.transparent, material.blending, material.premultipliedAlpha,
|
||||
material.blendSrc, material.blendDst, material.blendEquation,
|
||||
material.blendSrcAlpha, material.blendDstAlpha, material.blendEquationAlpha,
|
||||
material.colorWrite,
|
||||
material.depthWrite, material.depthTest, material.depthFunc,
|
||||
material.stencilWrite, material.stencilFunc,
|
||||
material.stencilFail, material.stencilZFail, material.stencilZPass,
|
||||
material.stencilFuncMask, material.stencilWriteMask,
|
||||
material.side,
|
||||
this.backend.getCacheKey( renderObject )
|
||||
];
|
||||
|
||||
return parameters.join();
|
||||
|
||||
}
|
||||
|
||||
_releasePipeline( pipeline ) {
|
||||
|
||||
this.caches.delete( pipeline.cacheKey );
|
||||
|
||||
}
|
||||
|
||||
_releaseProgram( program ) {
|
||||
|
||||
const code = program.code;
|
||||
const stage = program.stage;
|
||||
|
||||
this.programs[ stage ].delete( code );
|
||||
|
||||
}
|
||||
|
||||
_needsComputeUpdate( computeNode ) {
|
||||
|
||||
const data = this.get( computeNode );
|
||||
|
||||
return data.pipeline === undefined || data.version !== computeNode.version;
|
||||
|
||||
}
|
||||
|
||||
_needsRenderUpdate( renderObject ) {
|
||||
|
||||
const data = this.get( renderObject );
|
||||
const material = renderObject.material;
|
||||
|
||||
let needsUpdate = this.backend.needsUpdate( renderObject );
|
||||
|
||||
// check material state
|
||||
|
||||
if ( data.material !== material || data.materialVersion !== material.version ||
|
||||
data.transparent !== material.transparent || data.blending !== material.blending || data.premultipliedAlpha !== material.premultipliedAlpha ||
|
||||
data.blendSrc !== material.blendSrc || data.blendDst !== material.blendDst || data.blendEquation !== material.blendEquation ||
|
||||
data.blendSrcAlpha !== material.blendSrcAlpha || data.blendDstAlpha !== material.blendDstAlpha || data.blendEquationAlpha !== material.blendEquationAlpha ||
|
||||
data.colorWrite !== material.colorWrite ||
|
||||
data.depthWrite !== material.depthWrite || data.depthTest !== material.depthTest || data.depthFunc !== material.depthFunc ||
|
||||
data.stencilWrite !== material.stencilWrite || data.stencilFunc !== material.stencilFunc ||
|
||||
data.stencilFail !== material.stencilFail || data.stencilZFail !== material.stencilZFail || data.stencilZPass !== material.stencilZPass ||
|
||||
data.stencilFuncMask !== material.stencilFuncMask || data.stencilWriteMask !== material.stencilWriteMask ||
|
||||
data.side !== material.side || data.alphaToCoverage !== material.alphaToCoverage
|
||||
) {
|
||||
|
||||
data.material = material; data.materialVersion = material.version;
|
||||
data.transparent = material.transparent; data.blending = material.blending; data.premultipliedAlpha = material.premultipliedAlpha;
|
||||
data.blendSrc = material.blendSrc; data.blendDst = material.blendDst; data.blendEquation = material.blendEquation;
|
||||
data.blendSrcAlpha = material.blendSrcAlpha; data.blendDstAlpha = material.blendDstAlpha; data.blendEquationAlpha = material.blendEquationAlpha;
|
||||
data.colorWrite = material.colorWrite;
|
||||
data.depthWrite = material.depthWrite; data.depthTest = material.depthTest; data.depthFunc = material.depthFunc;
|
||||
data.stencilWrite = material.stencilWrite; data.stencilFunc = material.stencilFunc;
|
||||
data.stencilFail = material.stencilFail; data.stencilZFail = material.stencilZFail; data.stencilZPass = material.stencilZPass;
|
||||
data.stencilFuncMask = material.stencilFuncMask; data.stencilWriteMask = material.stencilWriteMask;
|
||||
data.side = material.side; data.alphaToCoverage = material.alphaToCoverage;
|
||||
|
||||
needsUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
return needsUpdate || data.pipeline === undefined;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Pipelines;
|
||||
18
node_modules/three/examples/jsm/renderers/common/ProgrammableStage.js
generated
vendored
Normal file
18
node_modules/three/examples/jsm/renderers/common/ProgrammableStage.js
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
let _id = 0;
|
||||
|
||||
class ProgrammableStage {
|
||||
|
||||
constructor( code, type ) {
|
||||
|
||||
this.id = _id ++;
|
||||
|
||||
this.code = code;
|
||||
this.stage = type;
|
||||
|
||||
this.usedTimes = 0;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ProgrammableStage;
|
||||
41
node_modules/three/examples/jsm/renderers/common/RenderContext.js
generated
vendored
Normal file
41
node_modules/three/examples/jsm/renderers/common/RenderContext.js
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
import { Vector4 } from 'three';
|
||||
|
||||
let id = 0;
|
||||
|
||||
class RenderContext {
|
||||
|
||||
constructor() {
|
||||
|
||||
this.id = id ++;
|
||||
|
||||
this.color = true;
|
||||
this.clearColor = true;
|
||||
this.clearColorValue = { r: 0, g: 0, b: 0, a: 1 };
|
||||
|
||||
this.depth = true;
|
||||
this.clearDepth = true;
|
||||
this.clearDepthValue = 1;
|
||||
|
||||
this.stencil = true;
|
||||
this.clearStencil = true;
|
||||
this.clearStencilValue = 1;
|
||||
|
||||
this.viewport = false;
|
||||
this.viewportValue = new Vector4();
|
||||
|
||||
this.scissor = false;
|
||||
this.scissorValue = new Vector4();
|
||||
|
||||
this.texture = null;
|
||||
this.depthTexture = null;
|
||||
this.activeCubeFace = 0;
|
||||
this.sampleCount = 1;
|
||||
|
||||
this.width = 0;
|
||||
this.height = 0;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default RenderContext;
|
||||
74
node_modules/three/examples/jsm/renderers/common/RenderContexts.js
generated
vendored
Normal file
74
node_modules/three/examples/jsm/renderers/common/RenderContexts.js
generated
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
import ChainMap from './ChainMap.js';
|
||||
import RenderContext from './RenderContext.js';
|
||||
|
||||
class RenderContexts {
|
||||
|
||||
constructor() {
|
||||
|
||||
this.chainMaps = {};
|
||||
|
||||
}
|
||||
|
||||
get( scene, camera, renderTarget = null ) {
|
||||
|
||||
const chainKey = [ scene, camera ];
|
||||
|
||||
let attachmentState;
|
||||
|
||||
if ( renderTarget === null ) {
|
||||
|
||||
attachmentState = 'default';
|
||||
|
||||
} else {
|
||||
|
||||
let format, count;
|
||||
|
||||
if ( renderTarget.isWebGLMultipleRenderTargets ) {
|
||||
|
||||
format = renderTarget.texture[ 0 ].format;
|
||||
count = renderTarget.texture.length;
|
||||
|
||||
} else {
|
||||
|
||||
format = renderTarget.texture.format;
|
||||
count = 1;
|
||||
|
||||
}
|
||||
|
||||
attachmentState = `${count}:${format}:${renderTarget.samples}:${renderTarget.depthBuffer}:${renderTarget.stencilBuffer}`;
|
||||
|
||||
}
|
||||
|
||||
const chainMap = this.getChainMap( attachmentState );
|
||||
|
||||
let renderState = chainMap.get( chainKey );
|
||||
|
||||
if ( renderState === undefined ) {
|
||||
|
||||
renderState = new RenderContext();
|
||||
|
||||
chainMap.set( chainKey, renderState );
|
||||
|
||||
}
|
||||
|
||||
if ( renderTarget !== null ) renderState.sampleCount = renderTarget.samples === 0 ? 1 : renderTarget.samples;
|
||||
|
||||
return renderState;
|
||||
|
||||
}
|
||||
|
||||
getChainMap( attachmentState ) {
|
||||
|
||||
return this.chainMaps[ attachmentState ] || ( this.chainMaps[ attachmentState ] = new ChainMap() );
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this.chainMaps = {};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default RenderContexts;
|
||||
186
node_modules/three/examples/jsm/renderers/common/RenderList.js
generated
vendored
Normal file
186
node_modules/three/examples/jsm/renderers/common/RenderList.js
generated
vendored
Normal file
@@ -0,0 +1,186 @@
|
||||
import { LightsNode } from '../../nodes/Nodes.js';
|
||||
|
||||
function painterSortStable( a, b ) {
|
||||
|
||||
if ( a.groupOrder !== b.groupOrder ) {
|
||||
|
||||
return a.groupOrder - b.groupOrder;
|
||||
|
||||
} else if ( a.renderOrder !== b.renderOrder ) {
|
||||
|
||||
return a.renderOrder - b.renderOrder;
|
||||
|
||||
} 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.groupOrder !== b.groupOrder ) {
|
||||
|
||||
return a.groupOrder - b.groupOrder;
|
||||
|
||||
} else if ( a.renderOrder !== b.renderOrder ) {
|
||||
|
||||
return a.renderOrder - b.renderOrder;
|
||||
|
||||
} else if ( a.z !== b.z ) {
|
||||
|
||||
return b.z - a.z;
|
||||
|
||||
} else {
|
||||
|
||||
return a.id - b.id;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class RenderList {
|
||||
|
||||
constructor() {
|
||||
|
||||
this.renderItems = [];
|
||||
this.renderItemsIndex = 0;
|
||||
|
||||
this.opaque = [];
|
||||
this.transparent = [];
|
||||
|
||||
this.lightsNode = new LightsNode( [] );
|
||||
this.lightsArray = [];
|
||||
|
||||
this.occlusionQueryCount = 0;
|
||||
|
||||
}
|
||||
|
||||
begin() {
|
||||
|
||||
this.renderItemsIndex = 0;
|
||||
|
||||
this.opaque.length = 0;
|
||||
this.transparent.length = 0;
|
||||
this.lightsArray.length = 0;
|
||||
|
||||
this.occlusionQueryCount = 0;
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
getNextRenderItem( object, geometry, material, groupOrder, z, group ) {
|
||||
|
||||
let renderItem = this.renderItems[ this.renderItemsIndex ];
|
||||
|
||||
if ( renderItem === undefined ) {
|
||||
|
||||
renderItem = {
|
||||
id: object.id,
|
||||
object: object,
|
||||
geometry: geometry,
|
||||
material: material,
|
||||
groupOrder: groupOrder,
|
||||
renderOrder: object.renderOrder,
|
||||
z: z,
|
||||
group: group
|
||||
};
|
||||
|
||||
this.renderItems[ this.renderItemsIndex ] = renderItem;
|
||||
|
||||
} else {
|
||||
|
||||
renderItem.id = object.id;
|
||||
renderItem.object = object;
|
||||
renderItem.geometry = geometry;
|
||||
renderItem.material = material;
|
||||
renderItem.groupOrder = groupOrder;
|
||||
renderItem.renderOrder = object.renderOrder;
|
||||
renderItem.z = z;
|
||||
renderItem.group = group;
|
||||
|
||||
}
|
||||
|
||||
this.renderItemsIndex ++;
|
||||
|
||||
return renderItem;
|
||||
|
||||
}
|
||||
|
||||
push( object, geometry, material, groupOrder, z, group ) {
|
||||
|
||||
const renderItem = this.getNextRenderItem( object, geometry, material, groupOrder, z, group );
|
||||
|
||||
if ( object.occlusionTest === true ) this.occlusionQueryCount ++;
|
||||
|
||||
( material.transparent === true ? this.transparent : this.opaque ).push( renderItem );
|
||||
|
||||
}
|
||||
|
||||
unshift( object, geometry, material, groupOrder, z, group ) {
|
||||
|
||||
const renderItem = this.getNextRenderItem( object, geometry, material, groupOrder, z, group );
|
||||
|
||||
( material.transparent === true ? this.transparent : this.opaque ).unshift( renderItem );
|
||||
|
||||
}
|
||||
|
||||
pushLight( light ) {
|
||||
|
||||
this.lightsArray.push( light );
|
||||
|
||||
}
|
||||
|
||||
getLightsNode() {
|
||||
|
||||
return this.lightsNode.fromLights( this.lightsArray );
|
||||
|
||||
}
|
||||
|
||||
sort( customOpaqueSort, customTransparentSort ) {
|
||||
|
||||
if ( this.opaque.length > 1 ) this.opaque.sort( customOpaqueSort || painterSortStable );
|
||||
if ( this.transparent.length > 1 ) this.transparent.sort( customTransparentSort || reversePainterSortStable );
|
||||
|
||||
}
|
||||
|
||||
finish() {
|
||||
|
||||
// update lights
|
||||
|
||||
this.lightsNode.fromLights( this.lightsArray );
|
||||
|
||||
// Clear references from inactive renderItems in the list
|
||||
|
||||
for ( let i = this.renderItemsIndex, il = this.renderItems.length; i < il; i ++ ) {
|
||||
|
||||
const renderItem = this.renderItems[ i ];
|
||||
|
||||
if ( renderItem.id === null ) break;
|
||||
|
||||
renderItem.id = null;
|
||||
renderItem.object = null;
|
||||
renderItem.geometry = null;
|
||||
renderItem.material = null;
|
||||
renderItem.groupOrder = null;
|
||||
renderItem.renderOrder = null;
|
||||
renderItem.z = null;
|
||||
renderItem.group = null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default RenderList;
|
||||
38
node_modules/three/examples/jsm/renderers/common/RenderLists.js
generated
vendored
Normal file
38
node_modules/three/examples/jsm/renderers/common/RenderLists.js
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
import ChainMap from './ChainMap.js';
|
||||
import RenderList from './RenderList.js';
|
||||
|
||||
class RenderLists {
|
||||
|
||||
constructor() {
|
||||
|
||||
this.lists = new ChainMap();
|
||||
|
||||
}
|
||||
|
||||
get( scene, camera ) {
|
||||
|
||||
const lists = this.lists;
|
||||
const keys = [ scene, camera ];
|
||||
|
||||
let list = lists.get( keys );
|
||||
|
||||
if ( list === undefined ) {
|
||||
|
||||
list = new RenderList();
|
||||
lists.set( keys, list );
|
||||
|
||||
}
|
||||
|
||||
return list;
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this.lists = new ChainMap();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default RenderLists;
|
||||
164
node_modules/three/examples/jsm/renderers/common/RenderObject.js
generated
vendored
Normal file
164
node_modules/three/examples/jsm/renderers/common/RenderObject.js
generated
vendored
Normal file
@@ -0,0 +1,164 @@
|
||||
let id = 0;
|
||||
|
||||
export default class RenderObject {
|
||||
|
||||
constructor( nodes, geometries, renderer, object, material, scene, camera, lightsNode, renderContext ) {
|
||||
|
||||
this._nodes = nodes;
|
||||
this._geometries = geometries;
|
||||
|
||||
this.id = id ++;
|
||||
|
||||
this.renderer = renderer;
|
||||
this.object = object;
|
||||
this.material = material;
|
||||
this.scene = scene;
|
||||
this.camera = camera;
|
||||
this.lightsNode = lightsNode;
|
||||
this.context = renderContext;
|
||||
|
||||
this.geometry = object.geometry;
|
||||
this.version = material.version;
|
||||
|
||||
this.attributes = null;
|
||||
this.pipeline = null;
|
||||
this.vertexBuffers = null;
|
||||
|
||||
this.initialNodesCacheKey = this.getNodesCacheKey();
|
||||
this.initialCacheKey = this.getCacheKey();
|
||||
|
||||
this._nodeBuilderState = null;
|
||||
this._bindings = null;
|
||||
|
||||
this.onDispose = null;
|
||||
|
||||
this.isRenderObject = true;
|
||||
|
||||
this.onMaterialDispose = () => {
|
||||
|
||||
this.dispose();
|
||||
|
||||
};
|
||||
|
||||
this.material.addEventListener( 'dispose', this.onMaterialDispose );
|
||||
|
||||
}
|
||||
|
||||
getNodeBuilderState() {
|
||||
|
||||
return this._nodeBuilderState || ( this._nodeBuilderState = this._nodes.getForRender( this ) );
|
||||
|
||||
}
|
||||
|
||||
getBindings() {
|
||||
|
||||
return this._bindings || ( this._bindings = this.getNodeBuilderState().createBindings() );
|
||||
|
||||
}
|
||||
|
||||
getIndex() {
|
||||
|
||||
return this._geometries.getIndex( this );
|
||||
|
||||
}
|
||||
|
||||
getChainArray() {
|
||||
|
||||
return [ this.object, this.material, this.context, this.lightsNode ];
|
||||
|
||||
}
|
||||
|
||||
getAttributes() {
|
||||
|
||||
if ( this.attributes !== null ) return this.attributes;
|
||||
|
||||
const nodeAttributes = this.getNodeBuilderState().nodeAttributes;
|
||||
const geometry = this.geometry;
|
||||
|
||||
const attributes = [];
|
||||
const vertexBuffers = new Set();
|
||||
|
||||
for ( const nodeAttribute of nodeAttributes ) {
|
||||
|
||||
const attribute = nodeAttribute.node && nodeAttribute.node.attribute ? nodeAttribute.node.attribute : geometry.getAttribute( nodeAttribute.name );
|
||||
|
||||
attributes.push( attribute );
|
||||
|
||||
const bufferAttribute = attribute.isInterleavedBufferAttribute ? attribute.data : attribute;
|
||||
vertexBuffers.add( bufferAttribute );
|
||||
|
||||
}
|
||||
|
||||
this.attributes = attributes;
|
||||
this.vertexBuffers = Array.from( vertexBuffers.values() );
|
||||
|
||||
return attributes;
|
||||
|
||||
}
|
||||
|
||||
getVertexBuffers() {
|
||||
|
||||
if ( this.vertexBuffers === null ) this.getAttributes();
|
||||
|
||||
return this.vertexBuffers;
|
||||
|
||||
}
|
||||
|
||||
getMaterialCacheKey() {
|
||||
|
||||
const material = this.material;
|
||||
|
||||
let cacheKey = material.customProgramCacheKey();
|
||||
|
||||
for ( const property in material ) {
|
||||
|
||||
if ( /^(is[A-Z])|^(visible|version|uuid|name|opacity|userData)$/.test( property ) ) continue;
|
||||
|
||||
let value = material[ property ];
|
||||
|
||||
if ( value !== null ) {
|
||||
|
||||
const type = typeof value;
|
||||
|
||||
if ( type === 'number' ) value = value !== 0 ? '1' : '0'; // Convert to on/off, important for clearcoat, transmission, etc
|
||||
else if ( type === 'object' ) value = '{}';
|
||||
|
||||
}
|
||||
|
||||
cacheKey += /*property + ':' +*/ value + ',';
|
||||
|
||||
}
|
||||
|
||||
return cacheKey;
|
||||
|
||||
}
|
||||
|
||||
get needsUpdate() {
|
||||
|
||||
return this.initialNodesCacheKey !== this.getNodesCacheKey();
|
||||
|
||||
}
|
||||
|
||||
getNodesCacheKey() {
|
||||
|
||||
// Environment Nodes Cache Key
|
||||
|
||||
return this._nodes.getCacheKey( this.scene, this.lightsNode );
|
||||
|
||||
}
|
||||
|
||||
getCacheKey() {
|
||||
|
||||
return this.getMaterialCacheKey() + ',' + this.getNodesCacheKey();
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this.material.removeEventListener( 'dispose', this.onMaterialDispose );
|
||||
|
||||
this.onDispose();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
89
node_modules/three/examples/jsm/renderers/common/RenderObjects.js
generated
vendored
Normal file
89
node_modules/three/examples/jsm/renderers/common/RenderObjects.js
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
import ChainMap from './ChainMap.js';
|
||||
import RenderObject from './RenderObject.js';
|
||||
|
||||
class RenderObjects {
|
||||
|
||||
constructor( renderer, nodes, geometries, pipelines, bindings, info ) {
|
||||
|
||||
this.renderer = renderer;
|
||||
this.nodes = nodes;
|
||||
this.geometries = geometries;
|
||||
this.pipelines = pipelines;
|
||||
this.bindings = bindings;
|
||||
this.info = info;
|
||||
|
||||
this.chainMaps = {};
|
||||
|
||||
}
|
||||
|
||||
get( object, material, scene, camera, lightsNode, renderContext, passId ) {
|
||||
|
||||
const chainMap = this.getChainMap( passId );
|
||||
const chainArray = [ object, material, renderContext, lightsNode ];
|
||||
|
||||
let renderObject = chainMap.get( chainArray );
|
||||
|
||||
if ( renderObject === undefined ) {
|
||||
|
||||
renderObject = this.createRenderObject( this.nodes, this.geometries, this.renderer, object, material, scene, camera, lightsNode, renderContext, passId );
|
||||
|
||||
chainMap.set( chainArray, renderObject );
|
||||
|
||||
} else {
|
||||
|
||||
if ( renderObject.version !== material.version || renderObject.needsUpdate ) {
|
||||
|
||||
renderObject.version = material.version;
|
||||
|
||||
if ( renderObject.initialCacheKey !== renderObject.getCacheKey() ) {
|
||||
|
||||
renderObject.dispose();
|
||||
|
||||
renderObject = this.get( object, material, scene, camera, lightsNode, renderContext, passId );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return renderObject;
|
||||
|
||||
}
|
||||
|
||||
getChainMap( passId = 'default' ) {
|
||||
|
||||
return this.chainMaps[ passId ] || ( this.chainMaps[ passId ] = new ChainMap() );
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this.chainMaps = {};
|
||||
|
||||
}
|
||||
|
||||
createRenderObject( nodes, geometries, renderer, object, material, scene, camera, lightsNode, renderContext, passId ) {
|
||||
|
||||
const chainMap = this.getChainMap( passId );
|
||||
|
||||
const renderObject = new RenderObject( nodes, geometries, renderer, object, material, scene, camera, lightsNode, renderContext );
|
||||
|
||||
renderObject.onDispose = () => {
|
||||
|
||||
this.pipelines.delete( renderObject );
|
||||
this.bindings.delete( renderObject );
|
||||
this.nodes.delete( renderObject );
|
||||
|
||||
chainMap.delete( renderObject.getChainArray() );
|
||||
|
||||
};
|
||||
|
||||
return renderObject;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
export default RenderObjects;
|
||||
16
node_modules/three/examples/jsm/renderers/common/RenderPipeline.js
generated
vendored
Normal file
16
node_modules/three/examples/jsm/renderers/common/RenderPipeline.js
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
import Pipeline from './Pipeline.js';
|
||||
|
||||
class RenderPipeline extends Pipeline {
|
||||
|
||||
constructor( cacheKey, vertexProgram, fragmentProgram ) {
|
||||
|
||||
super( cacheKey );
|
||||
|
||||
this.vertexProgram = vertexProgram;
|
||||
this.fragmentProgram = fragmentProgram;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default RenderPipeline;
|
||||
931
node_modules/three/examples/jsm/renderers/common/Renderer.js
generated
vendored
Normal file
931
node_modules/three/examples/jsm/renderers/common/Renderer.js
generated
vendored
Normal file
@@ -0,0 +1,931 @@
|
||||
import Animation from './Animation.js';
|
||||
import RenderObjects from './RenderObjects.js';
|
||||
import Attributes from './Attributes.js';
|
||||
import Geometries from './Geometries.js';
|
||||
import Info from './Info.js';
|
||||
import Pipelines from './Pipelines.js';
|
||||
import Bindings from './Bindings.js';
|
||||
import RenderLists from './RenderLists.js';
|
||||
import RenderContexts from './RenderContexts.js';
|
||||
import Textures from './Textures.js';
|
||||
import Background from './Background.js';
|
||||
import Nodes from './nodes/Nodes.js';
|
||||
import { Scene, Frustum, Matrix4, Vector2, Vector3, Vector4, Color, DoubleSide, BackSide, FrontSide, SRGBColorSpace, NoToneMapping } from 'three';
|
||||
|
||||
const _scene = new Scene();
|
||||
const _drawingBufferSize = new Vector2();
|
||||
const _screen = new Vector4();
|
||||
const _frustum = new Frustum();
|
||||
const _projScreenMatrix = new Matrix4();
|
||||
const _vector3 = new Vector3();
|
||||
|
||||
class Renderer {
|
||||
|
||||
constructor( backend ) {
|
||||
|
||||
this.isRenderer = true;
|
||||
|
||||
// public
|
||||
|
||||
this.domElement = backend.getDomElement();
|
||||
|
||||
this.backend = backend;
|
||||
|
||||
this.autoClear = true;
|
||||
this.autoClearColor = true;
|
||||
this.autoClearDepth = true;
|
||||
this.autoClearStencil = true;
|
||||
|
||||
this.outputColorSpace = SRGBColorSpace;
|
||||
|
||||
this.toneMapping = NoToneMapping;
|
||||
this.toneMappingExposure = 1.0;
|
||||
|
||||
this.sortObjects = true;
|
||||
|
||||
this.depth = true;
|
||||
this.stencil = true;
|
||||
|
||||
this.info = new Info();
|
||||
|
||||
// internals
|
||||
|
||||
this._pixelRatio = 1;
|
||||
this._width = this.domElement.width;
|
||||
this._height = this.domElement.height;
|
||||
|
||||
this._viewport = new Vector4( 0, 0, this._width, this._height );
|
||||
this._scissor = new Vector4( 0, 0, this._width, this._height );
|
||||
this._scissorTest = false;
|
||||
|
||||
this._properties = null;
|
||||
this._attributes = null;
|
||||
this._geometries = null;
|
||||
this._nodes = null;
|
||||
this._bindings = null;
|
||||
this._objects = null;
|
||||
this._pipelines = null;
|
||||
this._renderLists = null;
|
||||
this._renderContexts = null;
|
||||
this._textures = null;
|
||||
this._background = null;
|
||||
|
||||
this._animation = new Animation();
|
||||
|
||||
this._currentRenderContext = null;
|
||||
this._lastRenderContext = null;
|
||||
|
||||
this._opaqueSort = null;
|
||||
this._transparentSort = null;
|
||||
|
||||
this._clearAlpha = 1;
|
||||
this._clearColor = new Color( 0x000000 );
|
||||
this._clearDepth = 1;
|
||||
this._clearStencil = 0;
|
||||
|
||||
this._renderTarget = null;
|
||||
this._activeCubeFace = 0;
|
||||
this._activeMipmapLevel = 0;
|
||||
|
||||
this._initialized = false;
|
||||
this._initPromise = null;
|
||||
|
||||
// backwards compatibility
|
||||
|
||||
this.shadowMap = {
|
||||
enabled: false,
|
||||
type: null
|
||||
};
|
||||
|
||||
this.xr = {
|
||||
enabled: false
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
async init() {
|
||||
|
||||
if ( this._initialized ) {
|
||||
|
||||
throw new Error( 'Renderer: Backend has already been initialized.' );
|
||||
|
||||
}
|
||||
|
||||
if ( this._initPromise !== null ) {
|
||||
|
||||
return this._initPromise;
|
||||
|
||||
}
|
||||
|
||||
this._initPromise = new Promise( async ( resolve, reject ) => {
|
||||
|
||||
const backend = this.backend;
|
||||
|
||||
try {
|
||||
|
||||
await backend.init( this );
|
||||
|
||||
} catch ( error ) {
|
||||
|
||||
reject( error );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
this._nodes = new Nodes( this, backend );
|
||||
this._attributes = new Attributes( backend );
|
||||
this._background = new Background( this, this._nodes );
|
||||
this._geometries = new Geometries( this._attributes, this.info );
|
||||
this._textures = new Textures( backend, this.info );
|
||||
this._pipelines = new Pipelines( backend, this._nodes );
|
||||
this._bindings = new Bindings( backend, this._nodes, this._textures, this._attributes, this._pipelines, this.info );
|
||||
this._objects = new RenderObjects( this, this._nodes, this._geometries, this._pipelines, this._bindings, this.info );
|
||||
this._renderLists = new RenderLists();
|
||||
this._renderContexts = new RenderContexts();
|
||||
|
||||
//
|
||||
|
||||
this._animation.setNodes( this._nodes );
|
||||
this._animation.start();
|
||||
|
||||
this._initialized = true;
|
||||
|
||||
resolve();
|
||||
|
||||
} );
|
||||
|
||||
return this._initPromise;
|
||||
|
||||
}
|
||||
|
||||
get coordinateSystem() {
|
||||
|
||||
return this.backend.coordinateSystem;
|
||||
|
||||
}
|
||||
|
||||
async compile( /*scene, camera*/ ) {
|
||||
|
||||
console.warn( 'THREE.Renderer: .compile() is not implemented yet.' );
|
||||
|
||||
}
|
||||
|
||||
async render( scene, camera ) {
|
||||
|
||||
if ( this._initialized === false ) await this.init();
|
||||
|
||||
// preserve render tree
|
||||
|
||||
const nodeFrame = this._nodes.nodeFrame;
|
||||
|
||||
const previousRenderId = nodeFrame.renderId;
|
||||
const previousRenderState = this._currentRenderContext;
|
||||
|
||||
//
|
||||
|
||||
const sceneRef = ( scene.isScene === true ) ? scene : _scene;
|
||||
|
||||
const renderTarget = this._renderTarget;
|
||||
const renderContext = this._renderContexts.get( scene, camera, renderTarget );
|
||||
const activeCubeFace = this._activeCubeFace;
|
||||
const activeMipmapLevel = this._activeMipmapLevel;
|
||||
|
||||
this._currentRenderContext = renderContext;
|
||||
|
||||
nodeFrame.renderId ++;
|
||||
|
||||
//
|
||||
|
||||
const coordinateSystem = this.coordinateSystem;
|
||||
|
||||
if ( camera.coordinateSystem !== coordinateSystem ) {
|
||||
|
||||
camera.coordinateSystem = coordinateSystem;
|
||||
|
||||
camera.updateProjectionMatrix();
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
if ( this._animation.isAnimating === false ) nodeFrame.update();
|
||||
|
||||
if ( scene.matrixWorldAutoUpdate === true ) scene.updateMatrixWorld();
|
||||
|
||||
if ( camera.parent === null && camera.matrixWorldAutoUpdate === true ) camera.updateMatrixWorld();
|
||||
|
||||
if ( this.info.autoReset === true ) this.info.reset();
|
||||
|
||||
this.info.render.frame ++;
|
||||
|
||||
//
|
||||
|
||||
let viewport = this._viewport;
|
||||
let scissor = this._scissor;
|
||||
let pixelRatio = this._pixelRatio;
|
||||
|
||||
if ( renderTarget !== null ) {
|
||||
|
||||
viewport = renderTarget.viewport;
|
||||
scissor = renderTarget.scissor;
|
||||
pixelRatio = 1;
|
||||
|
||||
}
|
||||
|
||||
this.getDrawingBufferSize( _drawingBufferSize );
|
||||
|
||||
_screen.set( 0, 0, _drawingBufferSize.width, _drawingBufferSize.height );
|
||||
|
||||
const minDepth = ( viewport.minDepth === undefined ) ? 0 : viewport.minDepth;
|
||||
const maxDepth = ( viewport.maxDepth === undefined ) ? 1 : viewport.maxDepth;
|
||||
|
||||
renderContext.viewportValue.copy( viewport ).multiplyScalar( pixelRatio ).floor();
|
||||
renderContext.viewportValue.width >>= activeMipmapLevel;
|
||||
renderContext.viewportValue.height >>= activeMipmapLevel;
|
||||
renderContext.viewportValue.minDepth = minDepth;
|
||||
renderContext.viewportValue.maxDepth = maxDepth;
|
||||
renderContext.viewport = renderContext.viewportValue.equals( _screen ) === false;
|
||||
|
||||
renderContext.scissorValue.copy( scissor ).multiplyScalar( pixelRatio ).floor();
|
||||
renderContext.scissor = this._scissorTest && renderContext.scissorValue.equals( _screen ) === false;
|
||||
renderContext.scissorValue.width >>= activeMipmapLevel;
|
||||
renderContext.scissorValue.height >>= activeMipmapLevel;
|
||||
|
||||
renderContext.depth = this.depth;
|
||||
renderContext.stencil = this.stencil;
|
||||
|
||||
//
|
||||
|
||||
sceneRef.onBeforeRender( this, scene, camera, renderTarget );
|
||||
|
||||
//
|
||||
|
||||
_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
|
||||
_frustum.setFromProjectionMatrix( _projScreenMatrix, coordinateSystem );
|
||||
|
||||
const renderList = this._renderLists.get( scene, camera );
|
||||
renderList.begin();
|
||||
|
||||
this._projectObject( scene, camera, 0, renderList );
|
||||
|
||||
renderList.finish();
|
||||
|
||||
if ( this.sortObjects === true ) {
|
||||
|
||||
renderList.sort( this._opaqueSort, this._transparentSort );
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
if ( renderTarget !== null ) {
|
||||
|
||||
this._textures.updateRenderTarget( renderTarget, activeMipmapLevel );
|
||||
|
||||
const renderTargetData = this._textures.get( renderTarget );
|
||||
|
||||
renderContext.textures = renderTargetData.textures;
|
||||
renderContext.depthTexture = renderTargetData.depthTexture;
|
||||
renderContext.width = renderTargetData.width;
|
||||
renderContext.height = renderTargetData.height;
|
||||
|
||||
} else {
|
||||
|
||||
renderContext.textures = null;
|
||||
renderContext.depthTexture = null;
|
||||
renderContext.width = this.domElement.width;
|
||||
renderContext.height = this.domElement.height;
|
||||
|
||||
}
|
||||
|
||||
renderContext.width >>= activeMipmapLevel;
|
||||
renderContext.height >>= activeMipmapLevel;
|
||||
renderContext.activeCubeFace = activeCubeFace;
|
||||
renderContext.activeMipmapLevel = activeMipmapLevel;
|
||||
renderContext.occlusionQueryCount = renderList.occlusionQueryCount;
|
||||
|
||||
//
|
||||
|
||||
this._nodes.updateScene( sceneRef );
|
||||
|
||||
//
|
||||
|
||||
this._background.update( sceneRef, renderList, renderContext );
|
||||
|
||||
//
|
||||
|
||||
this.backend.beginRender( renderContext );
|
||||
|
||||
// process render lists
|
||||
|
||||
const opaqueObjects = renderList.opaque;
|
||||
const transparentObjects = renderList.transparent;
|
||||
const lightsNode = renderList.lightsNode;
|
||||
|
||||
if ( opaqueObjects.length > 0 ) this._renderObjects( opaqueObjects, camera, sceneRef, lightsNode );
|
||||
if ( transparentObjects.length > 0 ) this._renderObjects( transparentObjects, camera, sceneRef, lightsNode );
|
||||
|
||||
// finish render pass
|
||||
|
||||
this.backend.finishRender( renderContext );
|
||||
|
||||
// restore render tree
|
||||
|
||||
nodeFrame.renderId = previousRenderId;
|
||||
this._currentRenderContext = previousRenderState;
|
||||
|
||||
this._lastRenderContext = renderContext;
|
||||
|
||||
//
|
||||
|
||||
sceneRef.onAfterRender( this, scene, camera, renderTarget );
|
||||
|
||||
}
|
||||
|
||||
getActiveCubeFace() {
|
||||
|
||||
return this._activeCubeFace;
|
||||
|
||||
}
|
||||
|
||||
getActiveMipmapLevel() {
|
||||
|
||||
return this._activeMipmapLevel;
|
||||
|
||||
}
|
||||
|
||||
setAnimationLoop( callback ) {
|
||||
|
||||
if ( this._initialized === false ) this.init();
|
||||
|
||||
const animation = this._animation;
|
||||
|
||||
animation.setAnimationLoop( callback );
|
||||
|
||||
( callback === null ) ? animation.stop() : animation.start();
|
||||
|
||||
}
|
||||
|
||||
getArrayBuffer( attribute ) { // @deprecated, r155
|
||||
|
||||
console.warn( 'THREE.Renderer: getArrayBuffer() is deprecated. Use getArrayBufferAsync() instead.' );
|
||||
|
||||
return this.getArrayBufferAsync( attribute );
|
||||
|
||||
}
|
||||
|
||||
async getArrayBufferAsync( attribute ) {
|
||||
|
||||
return await this.backend.getArrayBufferAsync( attribute );
|
||||
|
||||
}
|
||||
|
||||
getContext() {
|
||||
|
||||
return this._context;
|
||||
|
||||
}
|
||||
|
||||
getPixelRatio() {
|
||||
|
||||
return this._pixelRatio;
|
||||
|
||||
}
|
||||
|
||||
getDrawingBufferSize( target ) {
|
||||
|
||||
return target.set( this._width * this._pixelRatio, this._height * this._pixelRatio ).floor();
|
||||
|
||||
}
|
||||
|
||||
getSize( target ) {
|
||||
|
||||
return target.set( this._width, this._height );
|
||||
|
||||
}
|
||||
|
||||
setPixelRatio( value = 1 ) {
|
||||
|
||||
this._pixelRatio = value;
|
||||
|
||||
this.setSize( this._width, this._height, false );
|
||||
|
||||
}
|
||||
|
||||
setDrawingBufferSize( width, height, pixelRatio ) {
|
||||
|
||||
this._width = width;
|
||||
this._height = height;
|
||||
|
||||
this._pixelRatio = pixelRatio;
|
||||
|
||||
this.domElement.width = Math.floor( width * pixelRatio );
|
||||
this.domElement.height = Math.floor( height * pixelRatio );
|
||||
|
||||
this.setViewport( 0, 0, width, height );
|
||||
|
||||
if ( this._initialized ) this.backend.updateSize();
|
||||
|
||||
}
|
||||
|
||||
setSize( width, height, updateStyle = true ) {
|
||||
|
||||
this._width = width;
|
||||
this._height = height;
|
||||
|
||||
this.domElement.width = Math.floor( width * this._pixelRatio );
|
||||
this.domElement.height = Math.floor( height * this._pixelRatio );
|
||||
|
||||
if ( updateStyle === true ) {
|
||||
|
||||
this.domElement.style.width = width + 'px';
|
||||
this.domElement.style.height = height + 'px';
|
||||
|
||||
}
|
||||
|
||||
this.setViewport( 0, 0, width, height );
|
||||
|
||||
if ( this._initialized ) this.backend.updateSize();
|
||||
|
||||
}
|
||||
|
||||
setOpaqueSort( method ) {
|
||||
|
||||
this._opaqueSort = method;
|
||||
|
||||
}
|
||||
|
||||
setTransparentSort( method ) {
|
||||
|
||||
this._transparentSort = method;
|
||||
|
||||
}
|
||||
|
||||
getScissor( target ) {
|
||||
|
||||
const scissor = this._scissor;
|
||||
|
||||
target.x = scissor.x;
|
||||
target.y = scissor.y;
|
||||
target.width = scissor.width;
|
||||
target.height = scissor.height;
|
||||
|
||||
return target;
|
||||
|
||||
}
|
||||
|
||||
setScissor( x, y, width, height ) {
|
||||
|
||||
const scissor = this._scissor;
|
||||
|
||||
if ( x.isVector4 ) {
|
||||
|
||||
scissor.copy( x );
|
||||
|
||||
} else {
|
||||
|
||||
scissor.set( x, y, width, height );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getScissorTest() {
|
||||
|
||||
return this._scissorTest;
|
||||
|
||||
}
|
||||
|
||||
setScissorTest( boolean ) {
|
||||
|
||||
this._scissorTest = boolean;
|
||||
|
||||
}
|
||||
|
||||
getViewport( target ) {
|
||||
|
||||
return target.copy( this._viewport );
|
||||
|
||||
}
|
||||
|
||||
setViewport( x, y, width, height, minDepth = 0, maxDepth = 1 ) {
|
||||
|
||||
const viewport = this._viewport;
|
||||
|
||||
if ( x.isVector4 ) {
|
||||
|
||||
viewport.copy( x );
|
||||
|
||||
} else {
|
||||
|
||||
viewport.set( x, y, width, height );
|
||||
|
||||
}
|
||||
|
||||
viewport.minDepth = minDepth;
|
||||
viewport.maxDepth = maxDepth;
|
||||
|
||||
}
|
||||
|
||||
getClearColor( target ) {
|
||||
|
||||
return target.copy( this._clearColor );
|
||||
|
||||
}
|
||||
|
||||
setClearColor( color, alpha = 1 ) {
|
||||
|
||||
this._clearColor.set( color );
|
||||
this._clearAlpha = alpha;
|
||||
|
||||
}
|
||||
|
||||
getClearAlpha() {
|
||||
|
||||
return this._clearAlpha;
|
||||
|
||||
}
|
||||
|
||||
setClearAlpha( alpha ) {
|
||||
|
||||
this._clearAlpha = alpha;
|
||||
|
||||
}
|
||||
|
||||
getClearDepth() {
|
||||
|
||||
return this._clearDepth;
|
||||
|
||||
}
|
||||
|
||||
setClearDepth( depth ) {
|
||||
|
||||
this._clearDepth = depth;
|
||||
|
||||
}
|
||||
|
||||
getClearStencil() {
|
||||
|
||||
return this._clearStencil;
|
||||
|
||||
}
|
||||
|
||||
setClearStencil( stencil ) {
|
||||
|
||||
this._clearStencil = stencil;
|
||||
|
||||
}
|
||||
|
||||
isOccluded( object ) {
|
||||
|
||||
const renderContext = this._currentRenderContext || this._lastRenderContext;
|
||||
|
||||
return renderContext && this.backend.isOccluded( renderContext, object );
|
||||
|
||||
}
|
||||
|
||||
clear( color = true, depth = true, stencil = true ) {
|
||||
|
||||
const renderContext = this._currentRenderContext || this._lastRenderContext;
|
||||
|
||||
if ( renderContext ) this.backend.clear( renderContext, color, depth, stencil );
|
||||
|
||||
}
|
||||
|
||||
clearColor() {
|
||||
|
||||
this.clear( true, false, false );
|
||||
|
||||
}
|
||||
|
||||
clearDepth() {
|
||||
|
||||
this.clear( false, true, false );
|
||||
|
||||
}
|
||||
|
||||
clearStencil() {
|
||||
|
||||
this.clear( false, false, true );
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this.info.dispose();
|
||||
|
||||
this._objects.dispose();
|
||||
this._properties.dispose();
|
||||
this._pipelines.dispose();
|
||||
this._nodes.dispose();
|
||||
this._bindings.dispose();
|
||||
this._renderLists.dispose();
|
||||
this._renderContexts.dispose();
|
||||
this._textures.dispose();
|
||||
|
||||
this.setRenderTarget( null );
|
||||
this.setAnimationLoop( null );
|
||||
|
||||
}
|
||||
|
||||
setRenderTarget( renderTarget, activeCubeFace = 0, activeMipmapLevel = 0 ) {
|
||||
|
||||
this._renderTarget = renderTarget;
|
||||
this._activeCubeFace = activeCubeFace;
|
||||
this._activeMipmapLevel = activeMipmapLevel;
|
||||
|
||||
}
|
||||
|
||||
getRenderTarget() {
|
||||
|
||||
return this._renderTarget;
|
||||
|
||||
}
|
||||
|
||||
async compute( computeNodes ) {
|
||||
|
||||
if ( this._initialized === false ) await this.init();
|
||||
|
||||
const backend = this.backend;
|
||||
const pipelines = this._pipelines;
|
||||
const bindings = this._bindings;
|
||||
const nodes = this._nodes;
|
||||
const computeList = Array.isArray( computeNodes ) ? computeNodes : [ computeNodes ];
|
||||
|
||||
backend.beginCompute( computeNodes );
|
||||
|
||||
for ( const computeNode of computeList ) {
|
||||
|
||||
// onInit
|
||||
|
||||
if ( pipelines.has( computeNode ) === false ) {
|
||||
|
||||
const dispose = () => {
|
||||
|
||||
computeNode.removeEventListener( 'dispose', dispose );
|
||||
|
||||
pipelines.delete( computeNode );
|
||||
bindings.delete( computeNode );
|
||||
nodes.delete( computeNode );
|
||||
|
||||
};
|
||||
|
||||
computeNode.addEventListener( 'dispose', dispose );
|
||||
|
||||
//
|
||||
|
||||
computeNode.onInit( { renderer: this } );
|
||||
|
||||
}
|
||||
|
||||
nodes.updateForCompute( computeNode );
|
||||
bindings.updateForCompute( computeNode );
|
||||
|
||||
const computeBindings = bindings.getForCompute( computeNode );
|
||||
const computePipeline = pipelines.getForCompute( computeNode, computeBindings );
|
||||
|
||||
backend.compute( computeNodes, computeNode, computeBindings, computePipeline );
|
||||
|
||||
}
|
||||
|
||||
backend.finishCompute( computeNodes );
|
||||
|
||||
}
|
||||
|
||||
hasFeature( name ) {
|
||||
|
||||
return this.backend.hasFeature( name );
|
||||
|
||||
}
|
||||
|
||||
copyFramebufferToTexture( framebufferTexture ) {
|
||||
|
||||
const renderContext = this._currentRenderContext || this._lastRenderContext;
|
||||
|
||||
this._textures.updateTexture( framebufferTexture );
|
||||
|
||||
this.backend.copyFramebufferToTexture( framebufferTexture, renderContext );
|
||||
|
||||
}
|
||||
|
||||
readRenderTargetPixelsAsync( renderTarget, x, y, width, height ) {
|
||||
|
||||
return this.backend.copyTextureToBuffer( renderTarget.texture, x, y, width, height );
|
||||
|
||||
}
|
||||
|
||||
_projectObject( object, camera, groupOrder, renderList ) {
|
||||
|
||||
if ( object.visible === false ) return;
|
||||
|
||||
const visible = object.layers.test( camera.layers );
|
||||
|
||||
if ( visible ) {
|
||||
|
||||
if ( object.isGroup ) {
|
||||
|
||||
groupOrder = object.renderOrder;
|
||||
|
||||
} else if ( object.isLOD ) {
|
||||
|
||||
if ( object.autoUpdate === true ) object.update( camera );
|
||||
|
||||
} else if ( object.isLight ) {
|
||||
|
||||
renderList.pushLight( object );
|
||||
|
||||
} else if ( object.isSprite ) {
|
||||
|
||||
if ( ! object.frustumCulled || _frustum.intersectsSprite( object ) ) {
|
||||
|
||||
if ( this.sortObjects === true ) {
|
||||
|
||||
_vector3.setFromMatrixPosition( object.matrixWorld ).applyMatrix4( _projScreenMatrix );
|
||||
|
||||
}
|
||||
|
||||
const geometry = object.geometry;
|
||||
const material = object.material;
|
||||
|
||||
if ( material.visible ) {
|
||||
|
||||
renderList.push( object, geometry, material, groupOrder, _vector3.z, null );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else if ( object.isLineLoop ) {
|
||||
|
||||
console.error( 'THREE.Renderer: Objects of type THREE.LineLoop are not supported. Please use THREE.Line or THREE.LineSegments.' );
|
||||
|
||||
} else if ( object.isMesh || object.isLine || object.isPoints ) {
|
||||
|
||||
if ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) {
|
||||
|
||||
const geometry = object.geometry;
|
||||
const material = object.material;
|
||||
|
||||
if ( this.sortObjects === true ) {
|
||||
|
||||
if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere();
|
||||
|
||||
_vector3
|
||||
.copy( geometry.boundingSphere.center )
|
||||
.applyMatrix4( object.matrixWorld )
|
||||
.applyMatrix4( _projScreenMatrix );
|
||||
|
||||
}
|
||||
|
||||
if ( Array.isArray( material ) ) {
|
||||
|
||||
const groups = geometry.groups;
|
||||
|
||||
for ( let i = 0, l = groups.length; i < l; i ++ ) {
|
||||
|
||||
const group = groups[ i ];
|
||||
const groupMaterial = material[ group.materialIndex ];
|
||||
|
||||
if ( groupMaterial && groupMaterial.visible ) {
|
||||
|
||||
renderList.push( object, geometry, groupMaterial, groupOrder, _vector3.z, group );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else if ( material.visible ) {
|
||||
|
||||
renderList.push( object, geometry, material, groupOrder, _vector3.z, null );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const children = object.children;
|
||||
|
||||
for ( let i = 0, l = children.length; i < l; i ++ ) {
|
||||
|
||||
this._projectObject( children[ i ], camera, groupOrder, renderList );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_renderObjects( renderList, camera, scene, lightsNode ) {
|
||||
|
||||
// process renderable objects
|
||||
|
||||
for ( let i = 0, il = renderList.length; i < il; i ++ ) {
|
||||
|
||||
const renderItem = renderList[ i ];
|
||||
|
||||
// @TODO: Add support for multiple materials per object. This will require to extract
|
||||
// the material from the renderItem object and pass it with its group data to _renderObject().
|
||||
|
||||
const { object, geometry, material, group } = renderItem;
|
||||
|
||||
if ( camera.isArrayCamera ) {
|
||||
|
||||
const cameras = camera.cameras;
|
||||
|
||||
for ( let j = 0, jl = cameras.length; j < jl; j ++ ) {
|
||||
|
||||
const camera2 = cameras[ j ];
|
||||
|
||||
if ( object.layers.test( camera2.layers ) ) {
|
||||
|
||||
const vp = camera2.viewport;
|
||||
const minDepth = ( vp.minDepth === undefined ) ? 0 : vp.minDepth;
|
||||
const maxDepth = ( vp.maxDepth === undefined ) ? 1 : vp.maxDepth;
|
||||
|
||||
const viewportValue = this._currentRenderContext.viewportValue;
|
||||
viewportValue.copy( vp ).multiplyScalar( this._pixelRatio ).floor();
|
||||
viewportValue.minDepth = minDepth;
|
||||
viewportValue.maxDepth = maxDepth;
|
||||
|
||||
this.backend.updateViewport( this._currentRenderContext );
|
||||
|
||||
this._renderObject( object, scene, camera2, geometry, material, group, lightsNode );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
this._renderObject( object, scene, camera, geometry, material, group, lightsNode );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_renderObject( object, scene, camera, geometry, material, group, lightsNode ) {
|
||||
|
||||
material = scene.overrideMaterial !== null ? scene.overrideMaterial : material;
|
||||
|
||||
//
|
||||
|
||||
object.onBeforeRender( this, scene, camera, geometry, material, group );
|
||||
|
||||
material.onBeforeRender( this, scene, camera, geometry, material, group );
|
||||
|
||||
//
|
||||
|
||||
if ( material.transparent === true && material.side === DoubleSide && material.forceSinglePass === false ) {
|
||||
|
||||
material.side = BackSide;
|
||||
this._renderObjectDirect( object, material, scene, camera, lightsNode, 'backSide' ); // create backSide pass id
|
||||
|
||||
material.side = FrontSide;
|
||||
this._renderObjectDirect( object, material, scene, camera, lightsNode ); // use default pass id
|
||||
|
||||
material.side = DoubleSide;
|
||||
|
||||
} else {
|
||||
|
||||
this._renderObjectDirect( object, material, scene, camera, lightsNode );
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
object.onAfterRender( this, scene, camera, geometry, material, group );
|
||||
|
||||
}
|
||||
|
||||
_renderObjectDirect( object, material, scene, camera, lightsNode, passId ) {
|
||||
|
||||
const renderObject = this._objects.get( object, material, scene, camera, lightsNode, this._currentRenderContext, passId );
|
||||
|
||||
//
|
||||
|
||||
this._nodes.updateBefore( renderObject );
|
||||
|
||||
//
|
||||
|
||||
object.modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, object.matrixWorld );
|
||||
object.normalMatrix.getNormalMatrix( object.modelViewMatrix );
|
||||
|
||||
//
|
||||
|
||||
this._nodes.updateForRender( renderObject );
|
||||
this._geometries.updateForRender( renderObject );
|
||||
this._bindings.updateForRender( renderObject );
|
||||
this._pipelines.updateForRender( renderObject );
|
||||
|
||||
//
|
||||
|
||||
this.backend.draw( renderObject, this.info );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Renderer;
|
||||
83
node_modules/three/examples/jsm/renderers/common/SampledTexture.js
generated
vendored
Normal file
83
node_modules/three/examples/jsm/renderers/common/SampledTexture.js
generated
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
import Binding from './Binding.js';
|
||||
|
||||
let id = 0;
|
||||
|
||||
class SampledTexture extends Binding {
|
||||
|
||||
constructor( name, texture ) {
|
||||
|
||||
super( name );
|
||||
|
||||
this.id = id ++;
|
||||
|
||||
this.texture = texture;
|
||||
this.version = texture ? texture.version : 0;
|
||||
this.store = false;
|
||||
|
||||
this.isSampledTexture = true;
|
||||
|
||||
}
|
||||
|
||||
get needsBindingsUpdate() {
|
||||
|
||||
const { texture, version } = this;
|
||||
|
||||
return texture.isVideoTexture ? true : version !== texture.version; // @TODO: version === 0 && texture.version > 0 ( add it just to External Textures like PNG,JPG )
|
||||
|
||||
}
|
||||
|
||||
update() {
|
||||
|
||||
const { texture, version } = this;
|
||||
|
||||
if ( version !== texture.version ) {
|
||||
|
||||
this.version = texture.version;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class SampledArrayTexture extends SampledTexture {
|
||||
|
||||
constructor( name, texture ) {
|
||||
|
||||
super( name, texture );
|
||||
|
||||
this.isSampledArrayTexture = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Sampled3DTexture extends SampledTexture {
|
||||
|
||||
constructor( name, texture ) {
|
||||
|
||||
super( name, texture );
|
||||
|
||||
this.isSampled3DTexture = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class SampledCubeTexture extends SampledTexture {
|
||||
|
||||
constructor( name, texture ) {
|
||||
|
||||
super( name, texture );
|
||||
|
||||
this.isSampledCubeTexture = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { SampledTexture, SampledArrayTexture, Sampled3DTexture, SampledCubeTexture };
|
||||
18
node_modules/three/examples/jsm/renderers/common/Sampler.js
generated
vendored
Normal file
18
node_modules/three/examples/jsm/renderers/common/Sampler.js
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
import Binding from './Binding.js';
|
||||
|
||||
class Sampler extends Binding {
|
||||
|
||||
constructor( name, texture ) {
|
||||
|
||||
super( name );
|
||||
|
||||
this.texture = texture;
|
||||
this.version = texture ? texture.version : 0;
|
||||
|
||||
this.isSampler = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Sampler;
|
||||
17
node_modules/three/examples/jsm/renderers/common/StorageBuffer.js
generated
vendored
Normal file
17
node_modules/three/examples/jsm/renderers/common/StorageBuffer.js
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
import Buffer from './Buffer.js';
|
||||
|
||||
class StorageBuffer extends Buffer {
|
||||
|
||||
constructor( name, attribute ) {
|
||||
|
||||
super( name, attribute ? attribute.array : null );
|
||||
|
||||
this.attribute = attribute;
|
||||
|
||||
this.isStorageBuffer = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default StorageBuffer;
|
||||
19
node_modules/three/examples/jsm/renderers/common/StorageTexture.js
generated
vendored
Normal file
19
node_modules/three/examples/jsm/renderers/common/StorageTexture.js
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
import { Texture, LinearFilter } from 'three';
|
||||
|
||||
class StorageTexture extends Texture {
|
||||
|
||||
constructor( width = 1, height = 1 ) {
|
||||
|
||||
super();
|
||||
|
||||
this.image = { width, height };
|
||||
|
||||
this.magFilter = LinearFilter;
|
||||
this.minFilter = LinearFilter;
|
||||
|
||||
this.isStorageTexture = true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
export default StorageTexture;
|
||||
331
node_modules/three/examples/jsm/renderers/common/Textures.js
generated
vendored
Normal file
331
node_modules/three/examples/jsm/renderers/common/Textures.js
generated
vendored
Normal file
@@ -0,0 +1,331 @@
|
||||
import DataMap from './DataMap.js';
|
||||
|
||||
import { Vector3, DepthTexture, DepthStencilFormat, UnsignedInt248Type, LinearFilter, NearestFilter, EquirectangularReflectionMapping, EquirectangularRefractionMapping, CubeReflectionMapping, CubeRefractionMapping } from 'three';
|
||||
|
||||
const _size = new Vector3();
|
||||
|
||||
class Textures extends DataMap {
|
||||
|
||||
constructor( backend, info ) {
|
||||
|
||||
super();
|
||||
|
||||
this.backend = backend;
|
||||
this.info = info;
|
||||
|
||||
}
|
||||
|
||||
updateRenderTarget( renderTarget, activeMipmapLevel = 0 ) {
|
||||
|
||||
const renderTargetData = this.get( renderTarget );
|
||||
|
||||
const sampleCount = renderTarget.samples === 0 ? 1 : renderTarget.samples;
|
||||
const depthTextureMips = renderTargetData.depthTextureMips || ( renderTargetData.depthTextureMips = {} );
|
||||
|
||||
let texture, textures;
|
||||
|
||||
if ( renderTarget.isWebGLMultipleRenderTargets ) {
|
||||
|
||||
textures = renderTarget.texture;
|
||||
texture = renderTarget.texture[ 0 ];
|
||||
|
||||
} else {
|
||||
|
||||
textures = [ renderTarget.texture ];
|
||||
texture = renderTarget.texture;
|
||||
|
||||
}
|
||||
|
||||
const size = this.getSize( texture );
|
||||
|
||||
const mipWidth = size.width >> activeMipmapLevel;
|
||||
const mipHeight = size.height >> activeMipmapLevel;
|
||||
|
||||
let depthTexture = renderTarget.depthTexture || depthTextureMips[ activeMipmapLevel ];
|
||||
let textureNeedsUpdate = false;
|
||||
|
||||
if ( depthTexture === undefined ) {
|
||||
|
||||
depthTexture = new DepthTexture();
|
||||
depthTexture.format = DepthStencilFormat;
|
||||
depthTexture.type = UnsignedInt248Type;
|
||||
depthTexture.image.width = mipWidth;
|
||||
depthTexture.image.height = mipHeight;
|
||||
|
||||
depthTextureMips[ activeMipmapLevel ] = depthTexture;
|
||||
|
||||
}
|
||||
|
||||
if ( renderTargetData.width !== size.width || size.height !== renderTargetData.height ) {
|
||||
|
||||
textureNeedsUpdate = true;
|
||||
depthTexture.needsUpdate = true;
|
||||
|
||||
depthTexture.image.width = mipWidth;
|
||||
depthTexture.image.height = mipHeight;
|
||||
|
||||
}
|
||||
|
||||
renderTargetData.width = size.width;
|
||||
renderTargetData.height = size.height;
|
||||
renderTargetData.textures = textures;
|
||||
renderTargetData.depthTexture = depthTexture;
|
||||
|
||||
if ( renderTargetData.sampleCount !== sampleCount ) {
|
||||
|
||||
textureNeedsUpdate = true;
|
||||
depthTexture.needsUpdate = true;
|
||||
|
||||
renderTargetData.sampleCount = sampleCount;
|
||||
|
||||
}
|
||||
|
||||
const options = { sampleCount };
|
||||
|
||||
|
||||
for ( let i = 0; i < textures.length; i ++ ) {
|
||||
|
||||
const texture = textures[ i ];
|
||||
|
||||
if ( textureNeedsUpdate ) texture.needsUpdate = true;
|
||||
|
||||
this.updateTexture( texture, options );
|
||||
|
||||
}
|
||||
|
||||
this.updateTexture( depthTexture, options );
|
||||
|
||||
// dispose handler
|
||||
|
||||
if ( renderTargetData.initialized !== true ) {
|
||||
|
||||
renderTargetData.initialized = true;
|
||||
|
||||
// dispose
|
||||
|
||||
const onDispose = () => {
|
||||
|
||||
renderTarget.removeEventListener( 'dispose', onDispose );
|
||||
|
||||
if ( textures !== undefined ) {
|
||||
|
||||
for ( let i = 0; i < textures.length; i ++ ) {
|
||||
|
||||
this._destroyTexture( textures[ i ] );
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
this._destroyTexture( texture );
|
||||
|
||||
}
|
||||
|
||||
this._destroyTexture( depthTexture );
|
||||
|
||||
};
|
||||
|
||||
renderTarget.addEventListener( 'dispose', onDispose );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
updateTexture( texture, options = {} ) {
|
||||
|
||||
const textureData = this.get( texture );
|
||||
if ( textureData.initialized === true && textureData.version === texture.version ) return;
|
||||
|
||||
const isRenderTarget = texture.isRenderTargetTexture || texture.isDepthTexture || texture.isFramebufferTexture;
|
||||
const backend = this.backend;
|
||||
|
||||
if ( isRenderTarget && textureData.initialized === true ) {
|
||||
|
||||
// it's an update
|
||||
|
||||
backend.destroySampler( texture );
|
||||
backend.destroyTexture( texture );
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
const { width, height, depth } = this.getSize( texture );
|
||||
|
||||
options.width = width;
|
||||
options.height = height;
|
||||
options.depth = depth;
|
||||
options.needsMipmaps = this.needsMipmaps( texture );
|
||||
options.levels = options.needsMipmaps ? this.getMipLevels( texture, width, height ) : 1;
|
||||
|
||||
//
|
||||
|
||||
if ( isRenderTarget || texture.isStorageTexture === true ) {
|
||||
|
||||
backend.createSampler( texture );
|
||||
backend.createTexture( texture, options );
|
||||
|
||||
} else {
|
||||
|
||||
const needsCreate = textureData.initialized !== true;
|
||||
|
||||
if ( needsCreate ) backend.createSampler( texture );
|
||||
|
||||
if ( texture.version > 0 ) {
|
||||
|
||||
const image = texture.image;
|
||||
|
||||
if ( image === undefined ) {
|
||||
|
||||
console.warn( 'THREE.Renderer: Texture marked for update but image is undefined.' );
|
||||
|
||||
} else if ( image.complete === false ) {
|
||||
|
||||
console.warn( 'THREE.Renderer: Texture marked for update but image is incomplete.' );
|
||||
|
||||
} else {
|
||||
|
||||
if ( texture.images ) {
|
||||
|
||||
const images = [];
|
||||
|
||||
for ( const image of texture.images ) {
|
||||
|
||||
images.push( image );
|
||||
|
||||
}
|
||||
|
||||
options.images = images;
|
||||
|
||||
} else {
|
||||
|
||||
options.image = image;
|
||||
|
||||
}
|
||||
|
||||
if ( textureData.isDefaultTexture === undefined || textureData.isDefaultTexture === true ) {
|
||||
|
||||
backend.createTexture( texture, options );
|
||||
|
||||
textureData.isDefaultTexture = false;
|
||||
|
||||
}
|
||||
|
||||
backend.updateTexture( texture, options );
|
||||
|
||||
if ( options.needsMipmaps && texture.mipmaps.length === 0 ) backend.generateMipmaps( texture );
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// async update
|
||||
|
||||
backend.createDefaultTexture( texture );
|
||||
|
||||
textureData.isDefaultTexture = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// dispose handler
|
||||
|
||||
if ( textureData.initialized !== true ) {
|
||||
|
||||
textureData.initialized = true;
|
||||
|
||||
//
|
||||
|
||||
this.info.memory.textures ++;
|
||||
|
||||
// dispose
|
||||
|
||||
const onDispose = () => {
|
||||
|
||||
texture.removeEventListener( 'dispose', onDispose );
|
||||
|
||||
this._destroyTexture( texture );
|
||||
|
||||
this.info.memory.textures --;
|
||||
|
||||
};
|
||||
|
||||
texture.addEventListener( 'dispose', onDispose );
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
textureData.version = texture.version;
|
||||
|
||||
}
|
||||
|
||||
getSize( texture, target = _size ) {
|
||||
|
||||
let image = texture.images ? texture.images[ 0 ] : texture.image;
|
||||
|
||||
if ( image ) {
|
||||
|
||||
if ( image.image !== undefined ) image = image.image;
|
||||
|
||||
target.width = image.width;
|
||||
target.height = image.height;
|
||||
target.depth = texture.isCubeTexture ? 6 : ( image.depth || 1 );
|
||||
|
||||
} else {
|
||||
|
||||
target.width = target.height = target.depth = 1;
|
||||
|
||||
}
|
||||
|
||||
return target;
|
||||
|
||||
}
|
||||
|
||||
getMipLevels( texture, width, height ) {
|
||||
|
||||
let mipLevelCount;
|
||||
|
||||
if ( texture.isCompressedTexture ) {
|
||||
|
||||
mipLevelCount = texture.mipmaps.length;
|
||||
|
||||
} else {
|
||||
|
||||
mipLevelCount = Math.floor( Math.log2( Math.max( width, height ) ) ) + 1;
|
||||
|
||||
}
|
||||
|
||||
return mipLevelCount;
|
||||
|
||||
}
|
||||
|
||||
needsMipmaps( texture ) {
|
||||
|
||||
if ( this.isEnvironmentTexture( texture ) ) return true;
|
||||
|
||||
return ( texture.isCompressedTexture === true ) || ( ( texture.minFilter !== NearestFilter ) && ( texture.minFilter !== LinearFilter ) );
|
||||
|
||||
}
|
||||
|
||||
isEnvironmentTexture( texture ) {
|
||||
|
||||
const mapping = texture.mapping;
|
||||
|
||||
return ( mapping === EquirectangularReflectionMapping || mapping === EquirectangularRefractionMapping ) || ( mapping === CubeReflectionMapping || mapping === CubeRefractionMapping );
|
||||
|
||||
}
|
||||
|
||||
_destroyTexture( texture ) {
|
||||
|
||||
this.backend.destroySampler( texture );
|
||||
this.backend.destroyTexture( texture );
|
||||
|
||||
this.delete( texture );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Textures;
|
||||
140
node_modules/three/examples/jsm/renderers/common/Uniform.js
generated
vendored
Normal file
140
node_modules/three/examples/jsm/renderers/common/Uniform.js
generated
vendored
Normal file
@@ -0,0 +1,140 @@
|
||||
import { Color, Matrix3, Matrix4, Vector2, Vector3, Vector4 } from 'three';
|
||||
|
||||
class Uniform {
|
||||
|
||||
constructor( name, value = null ) {
|
||||
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
|
||||
this.boundary = 0; // used to build the uniform buffer according to the STD140 layout
|
||||
this.itemSize = 0;
|
||||
|
||||
this.offset = 0; // this property is set by WebGPUUniformsGroup and marks the start position in the uniform buffer
|
||||
|
||||
}
|
||||
|
||||
setValue( value ) {
|
||||
|
||||
this.value = value;
|
||||
|
||||
}
|
||||
|
||||
getValue() {
|
||||
|
||||
return this.value;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class FloatUniform extends Uniform {
|
||||
|
||||
constructor( name, value = 0 ) {
|
||||
|
||||
super( name, value );
|
||||
|
||||
this.isFloatUniform = true;
|
||||
|
||||
this.boundary = 4;
|
||||
this.itemSize = 1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Vector2Uniform extends Uniform {
|
||||
|
||||
constructor( name, value = new Vector2() ) {
|
||||
|
||||
super( name, value );
|
||||
|
||||
this.isVector2Uniform = true;
|
||||
|
||||
this.boundary = 8;
|
||||
this.itemSize = 2;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Vector3Uniform extends Uniform {
|
||||
|
||||
constructor( name, value = new Vector3() ) {
|
||||
|
||||
super( name, value );
|
||||
|
||||
this.isVector3Uniform = true;
|
||||
|
||||
this.boundary = 16;
|
||||
this.itemSize = 3;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Vector4Uniform extends Uniform {
|
||||
|
||||
constructor( name, value = new Vector4() ) {
|
||||
|
||||
super( name, value );
|
||||
|
||||
this.isVector4Uniform = true;
|
||||
|
||||
this.boundary = 16;
|
||||
this.itemSize = 4;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ColorUniform extends Uniform {
|
||||
|
||||
constructor( name, value = new Color() ) {
|
||||
|
||||
super( name, value );
|
||||
|
||||
this.isColorUniform = true;
|
||||
|
||||
this.boundary = 16;
|
||||
this.itemSize = 3;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Matrix3Uniform extends Uniform {
|
||||
|
||||
constructor( name, value = new Matrix3() ) {
|
||||
|
||||
super( name, value );
|
||||
|
||||
this.isMatrix3Uniform = true;
|
||||
|
||||
this.boundary = 48;
|
||||
this.itemSize = 12;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Matrix4Uniform extends Uniform {
|
||||
|
||||
constructor( name, value = new Matrix4() ) {
|
||||
|
||||
super( name, value );
|
||||
|
||||
this.isMatrix4Uniform = true;
|
||||
|
||||
this.boundary = 64;
|
||||
this.itemSize = 16;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export {
|
||||
FloatUniform,
|
||||
Vector2Uniform, Vector3Uniform, Vector4Uniform, ColorUniform,
|
||||
Matrix3Uniform, Matrix4Uniform
|
||||
};
|
||||
15
node_modules/three/examples/jsm/renderers/common/UniformBuffer.js
generated
vendored
Normal file
15
node_modules/three/examples/jsm/renderers/common/UniformBuffer.js
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
import Buffer from './Buffer.js';
|
||||
|
||||
class UniformBuffer extends Buffer {
|
||||
|
||||
constructor( name, buffer = null ) {
|
||||
|
||||
super( name, buffer );
|
||||
|
||||
this.isUniformBuffer = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default UniformBuffer;
|
||||
299
node_modules/three/examples/jsm/renderers/common/UniformsGroup.js
generated
vendored
Normal file
299
node_modules/three/examples/jsm/renderers/common/UniformsGroup.js
generated
vendored
Normal file
@@ -0,0 +1,299 @@
|
||||
import UniformBuffer from './UniformBuffer.js';
|
||||
import { GPU_CHUNK_BYTES } from './Constants.js';
|
||||
|
||||
class UniformsGroup extends UniformBuffer {
|
||||
|
||||
constructor( name ) {
|
||||
|
||||
super( name );
|
||||
|
||||
this.isUniformsGroup = true;
|
||||
|
||||
// the order of uniforms in this array must match the order of uniforms in the shader
|
||||
|
||||
this.uniforms = [];
|
||||
|
||||
}
|
||||
|
||||
addUniform( uniform ) {
|
||||
|
||||
this.uniforms.push( uniform );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
removeUniform( uniform ) {
|
||||
|
||||
const index = this.uniforms.indexOf( uniform );
|
||||
|
||||
if ( index !== - 1 ) {
|
||||
|
||||
this.uniforms.splice( index, 1 );
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
get buffer() {
|
||||
|
||||
let buffer = this._buffer;
|
||||
|
||||
if ( buffer === null ) {
|
||||
|
||||
const byteLength = this.byteLength;
|
||||
|
||||
buffer = new Float32Array( new ArrayBuffer( byteLength ) );
|
||||
|
||||
this._buffer = buffer;
|
||||
|
||||
}
|
||||
|
||||
return buffer;
|
||||
|
||||
}
|
||||
|
||||
get byteLength() {
|
||||
|
||||
let offset = 0; // global buffer offset in bytes
|
||||
|
||||
for ( let i = 0, l = this.uniforms.length; i < l; i ++ ) {
|
||||
|
||||
const uniform = this.uniforms[ i ];
|
||||
|
||||
// offset within a single chunk in bytes
|
||||
|
||||
const chunkOffset = offset % GPU_CHUNK_BYTES;
|
||||
const remainingSizeInChunk = GPU_CHUNK_BYTES - chunkOffset;
|
||||
|
||||
// conformance tests
|
||||
|
||||
if ( chunkOffset !== 0 && ( remainingSizeInChunk - uniform.boundary ) < 0 ) {
|
||||
|
||||
// check for chunk overflow
|
||||
|
||||
offset += ( GPU_CHUNK_BYTES - chunkOffset );
|
||||
|
||||
} else if ( chunkOffset % uniform.boundary !== 0 ) {
|
||||
|
||||
// check for correct alignment
|
||||
|
||||
offset += ( chunkOffset % uniform.boundary );
|
||||
|
||||
}
|
||||
|
||||
uniform.offset = ( offset / this.bytesPerElement );
|
||||
|
||||
offset += ( uniform.itemSize * this.bytesPerElement );
|
||||
|
||||
}
|
||||
|
||||
return Math.ceil( offset / GPU_CHUNK_BYTES ) * GPU_CHUNK_BYTES;
|
||||
|
||||
}
|
||||
|
||||
update() {
|
||||
|
||||
let updated = false;
|
||||
|
||||
for ( const uniform of this.uniforms ) {
|
||||
|
||||
if ( this.updateByType( uniform ) === true ) {
|
||||
|
||||
updated = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return updated;
|
||||
|
||||
}
|
||||
|
||||
updateByType( uniform ) {
|
||||
|
||||
if ( uniform.isFloatUniform ) return this.updateNumber( uniform );
|
||||
if ( uniform.isVector2Uniform ) return this.updateVector2( uniform );
|
||||
if ( uniform.isVector3Uniform ) return this.updateVector3( uniform );
|
||||
if ( uniform.isVector4Uniform ) return this.updateVector4( uniform );
|
||||
if ( uniform.isColorUniform ) return this.updateColor( uniform );
|
||||
if ( uniform.isMatrix3Uniform ) return this.updateMatrix3( uniform );
|
||||
if ( uniform.isMatrix4Uniform ) return this.updateMatrix4( uniform );
|
||||
|
||||
console.error( 'THREE.WebGPUUniformsGroup: Unsupported uniform type.', uniform );
|
||||
|
||||
}
|
||||
|
||||
updateNumber( uniform ) {
|
||||
|
||||
let updated = false;
|
||||
|
||||
const a = this.buffer;
|
||||
const v = uniform.getValue();
|
||||
const offset = uniform.offset;
|
||||
|
||||
if ( a[ offset ] !== v ) {
|
||||
|
||||
a[ offset ] = v;
|
||||
updated = true;
|
||||
|
||||
}
|
||||
|
||||
return updated;
|
||||
|
||||
}
|
||||
|
||||
updateVector2( uniform ) {
|
||||
|
||||
let updated = false;
|
||||
|
||||
const a = this.buffer;
|
||||
const v = uniform.getValue();
|
||||
const offset = uniform.offset;
|
||||
|
||||
if ( a[ offset + 0 ] !== v.x || a[ offset + 1 ] !== v.y ) {
|
||||
|
||||
a[ offset + 0 ] = v.x;
|
||||
a[ offset + 1 ] = v.y;
|
||||
|
||||
updated = true;
|
||||
|
||||
}
|
||||
|
||||
return updated;
|
||||
|
||||
}
|
||||
|
||||
updateVector3( uniform ) {
|
||||
|
||||
let updated = false;
|
||||
|
||||
const a = this.buffer;
|
||||
const v = uniform.getValue();
|
||||
const offset = uniform.offset;
|
||||
|
||||
if ( a[ offset + 0 ] !== v.x || a[ offset + 1 ] !== v.y || a[ offset + 2 ] !== v.z ) {
|
||||
|
||||
a[ offset + 0 ] = v.x;
|
||||
a[ offset + 1 ] = v.y;
|
||||
a[ offset + 2 ] = v.z;
|
||||
|
||||
updated = true;
|
||||
|
||||
}
|
||||
|
||||
return updated;
|
||||
|
||||
}
|
||||
|
||||
updateVector4( uniform ) {
|
||||
|
||||
let updated = false;
|
||||
|
||||
const a = this.buffer;
|
||||
const v = uniform.getValue();
|
||||
const offset = uniform.offset;
|
||||
|
||||
if ( a[ offset + 0 ] !== v.x || a[ offset + 1 ] !== v.y || a[ offset + 2 ] !== v.z || a[ offset + 4 ] !== v.w ) {
|
||||
|
||||
a[ offset + 0 ] = v.x;
|
||||
a[ offset + 1 ] = v.y;
|
||||
a[ offset + 2 ] = v.z;
|
||||
a[ offset + 3 ] = v.w;
|
||||
|
||||
updated = true;
|
||||
|
||||
}
|
||||
|
||||
return updated;
|
||||
|
||||
}
|
||||
|
||||
updateColor( uniform ) {
|
||||
|
||||
let updated = false;
|
||||
|
||||
const a = this.buffer;
|
||||
const c = uniform.getValue();
|
||||
const offset = uniform.offset;
|
||||
|
||||
if ( a[ offset + 0 ] !== c.r || a[ offset + 1 ] !== c.g || a[ offset + 2 ] !== c.b ) {
|
||||
|
||||
a[ offset + 0 ] = c.r;
|
||||
a[ offset + 1 ] = c.g;
|
||||
a[ offset + 2 ] = c.b;
|
||||
|
||||
updated = true;
|
||||
|
||||
}
|
||||
|
||||
return updated;
|
||||
|
||||
}
|
||||
|
||||
updateMatrix3( uniform ) {
|
||||
|
||||
let updated = false;
|
||||
|
||||
const a = this.buffer;
|
||||
const e = uniform.getValue().elements;
|
||||
const offset = uniform.offset;
|
||||
|
||||
if ( a[ offset + 0 ] !== e[ 0 ] || a[ offset + 1 ] !== e[ 1 ] || a[ offset + 2 ] !== e[ 2 ] ||
|
||||
a[ offset + 4 ] !== e[ 3 ] || a[ offset + 5 ] !== e[ 4 ] || a[ offset + 6 ] !== e[ 5 ] ||
|
||||
a[ offset + 8 ] !== e[ 6 ] || a[ offset + 9 ] !== e[ 7 ] || a[ offset + 10 ] !== e[ 8 ] ) {
|
||||
|
||||
a[ offset + 0 ] = e[ 0 ];
|
||||
a[ offset + 1 ] = e[ 1 ];
|
||||
a[ offset + 2 ] = e[ 2 ];
|
||||
a[ offset + 4 ] = e[ 3 ];
|
||||
a[ offset + 5 ] = e[ 4 ];
|
||||
a[ offset + 6 ] = e[ 5 ];
|
||||
a[ offset + 8 ] = e[ 6 ];
|
||||
a[ offset + 9 ] = e[ 7 ];
|
||||
a[ offset + 10 ] = e[ 8 ];
|
||||
|
||||
updated = true;
|
||||
|
||||
}
|
||||
|
||||
return updated;
|
||||
|
||||
}
|
||||
|
||||
updateMatrix4( uniform ) {
|
||||
|
||||
let updated = false;
|
||||
|
||||
const a = this.buffer;
|
||||
const e = uniform.getValue().elements;
|
||||
const offset = uniform.offset;
|
||||
|
||||
if ( arraysEqual( a, e, offset ) === false ) {
|
||||
|
||||
a.set( e, offset );
|
||||
updated = true;
|
||||
|
||||
}
|
||||
|
||||
return updated;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function arraysEqual( a, b, offset ) {
|
||||
|
||||
for ( let i = 0, l = b.length; i < l; i ++ ) {
|
||||
|
||||
if ( a[ offset + i ] !== b[ i ] ) return false;
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
export default UniformsGroup;
|
||||
35
node_modules/three/examples/jsm/renderers/common/nodes/NodeBuilderState.js
generated
vendored
Normal file
35
node_modules/three/examples/jsm/renderers/common/nodes/NodeBuilderState.js
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
class NodeBuilderState {
|
||||
|
||||
constructor( vertexShader, fragmentShader, computeShader, nodeAttributes, bindings, updateNodes, updateBeforeNodes ) {
|
||||
|
||||
this.vertexShader = vertexShader;
|
||||
this.fragmentShader = fragmentShader;
|
||||
this.computeShader = computeShader;
|
||||
|
||||
this.nodeAttributes = nodeAttributes;
|
||||
this.bindings = bindings;
|
||||
|
||||
this.updateNodes = updateNodes;
|
||||
this.updateBeforeNodes = updateBeforeNodes;
|
||||
|
||||
this.usedTimes = 0;
|
||||
|
||||
}
|
||||
|
||||
createBindings() {
|
||||
|
||||
const bindingsArray = [];
|
||||
|
||||
for ( const binding of this.bindings ) {
|
||||
|
||||
bindingsArray.push( binding.clone() );
|
||||
|
||||
}
|
||||
|
||||
return bindingsArray;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default NodeBuilderState;
|
||||
49
node_modules/three/examples/jsm/renderers/common/nodes/NodeSampledTexture.js
generated
vendored
Normal file
49
node_modules/three/examples/jsm/renderers/common/nodes/NodeSampledTexture.js
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
import { SampledTexture } from '../SampledTexture.js';
|
||||
|
||||
class NodeSampledTexture extends SampledTexture {
|
||||
|
||||
constructor( name, textureNode ) {
|
||||
|
||||
super( name, textureNode ? textureNode.value : null );
|
||||
|
||||
this.textureNode = textureNode;
|
||||
|
||||
}
|
||||
|
||||
get needsBindingsUpdate() {
|
||||
|
||||
return this.textureNode.value !== this.texture || super.needsBindingsUpdate;
|
||||
|
||||
}
|
||||
|
||||
update() {
|
||||
|
||||
const { textureNode } = this;
|
||||
|
||||
if ( this.texture !== textureNode.value ) {
|
||||
|
||||
this.texture = textureNode.value;
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
return super.update();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class NodeSampledCubeTexture extends NodeSampledTexture {
|
||||
|
||||
constructor( name, textureNode ) {
|
||||
|
||||
super( name, textureNode );
|
||||
|
||||
this.isSampledCubeTexture = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { NodeSampledTexture, NodeSampledCubeTexture };
|
||||
15
node_modules/three/examples/jsm/renderers/common/nodes/NodeSampler.js
generated
vendored
Normal file
15
node_modules/three/examples/jsm/renderers/common/nodes/NodeSampler.js
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
import Sampler from '../Sampler.js';
|
||||
|
||||
class NodeSampler extends Sampler {
|
||||
|
||||
constructor( name, textureNode ) {
|
||||
|
||||
super( name, textureNode ? textureNode.value : null );
|
||||
|
||||
this.textureNode = textureNode;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default NodeSampler;
|
||||
135
node_modules/three/examples/jsm/renderers/common/nodes/NodeUniform.js
generated
vendored
Normal file
135
node_modules/three/examples/jsm/renderers/common/nodes/NodeUniform.js
generated
vendored
Normal file
@@ -0,0 +1,135 @@
|
||||
import {
|
||||
FloatUniform, Vector2Uniform, Vector3Uniform, Vector4Uniform,
|
||||
ColorUniform, Matrix3Uniform, Matrix4Uniform
|
||||
} from '../Uniform.js';
|
||||
|
||||
class FloatNodeUniform extends FloatUniform {
|
||||
|
||||
constructor( nodeUniform ) {
|
||||
|
||||
super( nodeUniform.name, nodeUniform.value );
|
||||
|
||||
this.nodeUniform = nodeUniform;
|
||||
|
||||
}
|
||||
|
||||
getValue() {
|
||||
|
||||
return this.nodeUniform.value;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Vector2NodeUniform extends Vector2Uniform {
|
||||
|
||||
constructor( nodeUniform ) {
|
||||
|
||||
super( nodeUniform.name, nodeUniform.value );
|
||||
|
||||
this.nodeUniform = nodeUniform;
|
||||
|
||||
}
|
||||
|
||||
getValue() {
|
||||
|
||||
return this.nodeUniform.value;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Vector3NodeUniform extends Vector3Uniform {
|
||||
|
||||
constructor( nodeUniform ) {
|
||||
|
||||
super( nodeUniform.name, nodeUniform.value );
|
||||
|
||||
this.nodeUniform = nodeUniform;
|
||||
|
||||
}
|
||||
|
||||
getValue() {
|
||||
|
||||
return this.nodeUniform.value;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Vector4NodeUniform extends Vector4Uniform {
|
||||
|
||||
constructor( nodeUniform ) {
|
||||
|
||||
super( nodeUniform.name, nodeUniform.value );
|
||||
|
||||
this.nodeUniform = nodeUniform;
|
||||
|
||||
}
|
||||
|
||||
getValue() {
|
||||
|
||||
return this.nodeUniform.value;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ColorNodeUniform extends ColorUniform {
|
||||
|
||||
constructor( nodeUniform ) {
|
||||
|
||||
super( nodeUniform.name, nodeUniform.value );
|
||||
|
||||
this.nodeUniform = nodeUniform;
|
||||
|
||||
}
|
||||
|
||||
getValue() {
|
||||
|
||||
return this.nodeUniform.value;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Matrix3NodeUniform extends Matrix3Uniform {
|
||||
|
||||
constructor( nodeUniform ) {
|
||||
|
||||
super( nodeUniform.name, nodeUniform.value );
|
||||
|
||||
this.nodeUniform = nodeUniform;
|
||||
|
||||
}
|
||||
|
||||
getValue() {
|
||||
|
||||
return this.nodeUniform.value;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Matrix4NodeUniform extends Matrix4Uniform {
|
||||
|
||||
constructor( nodeUniform ) {
|
||||
|
||||
super( nodeUniform.name, nodeUniform.value );
|
||||
|
||||
this.nodeUniform = nodeUniform;
|
||||
|
||||
}
|
||||
|
||||
getValue() {
|
||||
|
||||
return this.nodeUniform.value;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export {
|
||||
FloatNodeUniform, Vector2NodeUniform, Vector3NodeUniform, Vector4NodeUniform,
|
||||
ColorNodeUniform, Matrix3NodeUniform, Matrix4NodeUniform
|
||||
};
|
||||
426
node_modules/three/examples/jsm/renderers/common/nodes/Nodes.js
generated
vendored
Normal file
426
node_modules/three/examples/jsm/renderers/common/nodes/Nodes.js
generated
vendored
Normal file
@@ -0,0 +1,426 @@
|
||||
import DataMap from '../DataMap.js';
|
||||
import ChainMap from '../ChainMap.js';
|
||||
import NodeBuilderState from './NodeBuilderState.js';
|
||||
import { NoToneMapping, EquirectangularReflectionMapping, EquirectangularRefractionMapping } from 'three';
|
||||
import { NodeFrame, cubeTexture, texture, rangeFog, densityFog, reference, toneMapping, equirectUV, viewportBottomLeft, normalWorld } from '../../../nodes/Nodes.js';
|
||||
|
||||
class Nodes extends DataMap {
|
||||
|
||||
constructor( renderer, backend ) {
|
||||
|
||||
super();
|
||||
|
||||
this.renderer = renderer;
|
||||
this.backend = backend;
|
||||
this.nodeFrame = new NodeFrame();
|
||||
this.nodeBuilderCache = new Map();
|
||||
this.frameHashCache = new ChainMap();
|
||||
|
||||
}
|
||||
|
||||
getForRenderCacheKey( renderObject ) {
|
||||
|
||||
return renderObject.initialCacheKey;
|
||||
|
||||
}
|
||||
|
||||
getForRender( renderObject ) {
|
||||
|
||||
const renderObjectData = this.get( renderObject );
|
||||
|
||||
let nodeBuilderState = renderObjectData.nodeBuilderState;
|
||||
|
||||
if ( nodeBuilderState === undefined ) {
|
||||
|
||||
const { nodeBuilderCache } = this;
|
||||
|
||||
const cacheKey = this.getForRenderCacheKey( renderObject );
|
||||
|
||||
nodeBuilderState = nodeBuilderCache.get( cacheKey );
|
||||
|
||||
if ( nodeBuilderState === undefined ) {
|
||||
|
||||
const nodeBuilder = this.backend.createNodeBuilder( renderObject.object, this.renderer, renderObject.scene );
|
||||
nodeBuilder.material = renderObject.material;
|
||||
nodeBuilder.context.material = renderObject.material;
|
||||
nodeBuilder.lightsNode = renderObject.lightsNode;
|
||||
nodeBuilder.environmentNode = this.getEnvironmentNode( renderObject.scene );
|
||||
nodeBuilder.fogNode = this.getFogNode( renderObject.scene );
|
||||
nodeBuilder.toneMappingNode = this.getToneMappingNode();
|
||||
nodeBuilder.build();
|
||||
|
||||
nodeBuilderState = this._createNodeBuilderState( nodeBuilder );
|
||||
|
||||
nodeBuilderCache.set( cacheKey, nodeBuilderState );
|
||||
|
||||
}
|
||||
|
||||
nodeBuilderState.usedTimes ++;
|
||||
|
||||
renderObjectData.nodeBuilderState = nodeBuilderState;
|
||||
|
||||
}
|
||||
|
||||
return nodeBuilderState;
|
||||
|
||||
}
|
||||
|
||||
delete( object ) {
|
||||
|
||||
if ( object.isRenderObject ) {
|
||||
|
||||
const nodeBuilderState = this.get( object ).nodeBuilderState;
|
||||
nodeBuilderState.usedTimes --;
|
||||
|
||||
if ( nodeBuilderState.usedTimes === 0 ) {
|
||||
|
||||
this.nodeBuilderCache.delete( this.getForRenderCacheKey( object ) );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return super.delete( object );
|
||||
|
||||
}
|
||||
|
||||
getForCompute( computeNode ) {
|
||||
|
||||
const computeData = this.get( computeNode );
|
||||
|
||||
let nodeBuilderState = computeData.nodeBuilderState;
|
||||
|
||||
if ( nodeBuilderState === undefined ) {
|
||||
|
||||
const nodeBuilder = this.backend.createNodeBuilder( computeNode, this.renderer );
|
||||
nodeBuilder.build();
|
||||
|
||||
nodeBuilderState = this._createNodeBuilderState( nodeBuilder );
|
||||
|
||||
computeData.nodeBuilderState = nodeBuilder;
|
||||
|
||||
}
|
||||
|
||||
return nodeBuilderState;
|
||||
|
||||
}
|
||||
|
||||
_createNodeBuilderState( nodeBuilder ) {
|
||||
|
||||
return new NodeBuilderState(
|
||||
nodeBuilder.vertexShader,
|
||||
nodeBuilder.fragmentShader,
|
||||
nodeBuilder.computeShader,
|
||||
nodeBuilder.getAttributesArray(),
|
||||
nodeBuilder.getBindings(),
|
||||
nodeBuilder.updateNodes,
|
||||
nodeBuilder.updateBeforeNodes
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
getEnvironmentNode( scene ) {
|
||||
|
||||
return scene.environmentNode || this.get( scene ).environmentNode || null;
|
||||
|
||||
}
|
||||
|
||||
getBackgroundNode( scene ) {
|
||||
|
||||
return scene.backgroundNode || this.get( scene ).backgroundNode || null;
|
||||
|
||||
}
|
||||
|
||||
getFogNode( scene ) {
|
||||
|
||||
return scene.fogNode || this.get( scene ).fogNode || null;
|
||||
|
||||
}
|
||||
|
||||
getToneMappingNode() {
|
||||
|
||||
if ( this.isToneMappingState === false ) return null;
|
||||
|
||||
return this.renderer.toneMappingNode || this.get( this.renderer ).toneMappingNode || null;
|
||||
|
||||
}
|
||||
|
||||
getCacheKey( scene, lightsNode ) {
|
||||
|
||||
const chain = [ scene, lightsNode ];
|
||||
const frameId = this.nodeFrame.frameId;
|
||||
|
||||
let cacheKeyData = this.frameHashCache.get( chain );
|
||||
|
||||
if ( cacheKeyData === undefined || cacheKeyData.frameId !== frameId ) {
|
||||
|
||||
const environmentNode = this.getEnvironmentNode( scene );
|
||||
const fogNode = this.getFogNode( scene );
|
||||
const toneMappingNode = this.getToneMappingNode();
|
||||
|
||||
const cacheKey = [];
|
||||
|
||||
if ( lightsNode ) cacheKey.push( lightsNode.getCacheKey() );
|
||||
if ( environmentNode ) cacheKey.push( environmentNode.getCacheKey() );
|
||||
if ( fogNode ) cacheKey.push( fogNode.getCacheKey() );
|
||||
if ( toneMappingNode ) cacheKey.push( toneMappingNode.getCacheKey() );
|
||||
|
||||
cacheKeyData = {
|
||||
frameId,
|
||||
cacheKey: cacheKey.join( ',' )
|
||||
};
|
||||
|
||||
this.frameHashCache.set( chain, cacheKeyData );
|
||||
|
||||
}
|
||||
|
||||
return cacheKeyData.cacheKey;
|
||||
|
||||
}
|
||||
|
||||
updateScene( scene ) {
|
||||
|
||||
this.updateEnvironment( scene );
|
||||
this.updateFog( scene );
|
||||
this.updateBackground( scene );
|
||||
this.updateToneMapping();
|
||||
|
||||
}
|
||||
|
||||
get isToneMappingState() {
|
||||
|
||||
const renderer = this.renderer;
|
||||
const renderTarget = renderer.getRenderTarget();
|
||||
|
||||
return renderTarget && renderTarget.isCubeRenderTarget ? false : true;
|
||||
|
||||
}
|
||||
|
||||
updateToneMapping() {
|
||||
|
||||
const renderer = this.renderer;
|
||||
const rendererData = this.get( renderer );
|
||||
const rendererToneMapping = renderer.toneMapping;
|
||||
|
||||
if ( this.isToneMappingState && rendererToneMapping !== NoToneMapping ) {
|
||||
|
||||
if ( rendererData.toneMapping !== rendererToneMapping ) {
|
||||
|
||||
const rendererToneMappingNode = rendererData.rendererToneMappingNode || toneMapping( rendererToneMapping, reference( 'toneMappingExposure', 'float', renderer ) );
|
||||
rendererToneMappingNode.toneMapping = rendererToneMapping;
|
||||
|
||||
rendererData.rendererToneMappingNode = rendererToneMappingNode;
|
||||
rendererData.toneMappingNode = rendererToneMappingNode;
|
||||
rendererData.toneMapping = rendererToneMapping;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// Don't delete rendererData.rendererToneMappingNode
|
||||
delete rendererData.toneMappingNode;
|
||||
delete rendererData.toneMapping;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
updateBackground( scene ) {
|
||||
|
||||
const sceneData = this.get( scene );
|
||||
const background = scene.background;
|
||||
|
||||
if ( background ) {
|
||||
|
||||
if ( sceneData.background !== background ) {
|
||||
|
||||
let backgroundNode = null;
|
||||
|
||||
if ( background.isCubeTexture === true ) {
|
||||
|
||||
backgroundNode = cubeTexture( background, normalWorld );
|
||||
|
||||
} else if ( background.isTexture === true ) {
|
||||
|
||||
let nodeUV = null;
|
||||
|
||||
if ( background.mapping === EquirectangularReflectionMapping || background.mapping === EquirectangularRefractionMapping ) {
|
||||
|
||||
nodeUV = equirectUV();
|
||||
|
||||
} else {
|
||||
|
||||
nodeUV = viewportBottomLeft;
|
||||
|
||||
}
|
||||
|
||||
backgroundNode = texture( background, nodeUV ).setUpdateMatrix( true );
|
||||
|
||||
} else if ( background.isColor !== true ) {
|
||||
|
||||
console.error( 'WebGPUNodes: Unsupported background configuration.', background );
|
||||
|
||||
}
|
||||
|
||||
sceneData.backgroundNode = backgroundNode;
|
||||
sceneData.background = background;
|
||||
|
||||
}
|
||||
|
||||
} else if ( sceneData.backgroundNode ) {
|
||||
|
||||
delete sceneData.backgroundNode;
|
||||
delete sceneData.background;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
updateFog( scene ) {
|
||||
|
||||
const sceneData = this.get( scene );
|
||||
const fog = scene.fog;
|
||||
|
||||
if ( fog ) {
|
||||
|
||||
if ( sceneData.fog !== fog ) {
|
||||
|
||||
let fogNode = null;
|
||||
|
||||
if ( fog.isFogExp2 ) {
|
||||
|
||||
fogNode = densityFog( reference( 'color', 'color', fog ), reference( 'density', 'float', fog ) );
|
||||
|
||||
} else if ( fog.isFog ) {
|
||||
|
||||
fogNode = rangeFog( reference( 'color', 'color', fog ), reference( 'near', 'float', fog ), reference( 'far', 'float', fog ) );
|
||||
|
||||
} else {
|
||||
|
||||
console.error( 'WebGPUNodes: Unsupported fog configuration.', fog );
|
||||
|
||||
}
|
||||
|
||||
sceneData.fogNode = fogNode;
|
||||
sceneData.fog = fog;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
delete sceneData.fogNode;
|
||||
delete sceneData.fog;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
updateEnvironment( scene ) {
|
||||
|
||||
const sceneData = this.get( scene );
|
||||
const environment = scene.environment;
|
||||
|
||||
if ( environment ) {
|
||||
|
||||
if ( sceneData.environment !== environment ) {
|
||||
|
||||
let environmentNode = null;
|
||||
|
||||
if ( environment.isCubeTexture === true ) {
|
||||
|
||||
environmentNode = cubeTexture( environment );
|
||||
|
||||
} else if ( environment.isTexture === true ) {
|
||||
|
||||
environmentNode = texture( environment );
|
||||
|
||||
} else {
|
||||
|
||||
console.error( 'Nodes: Unsupported environment configuration.', environment );
|
||||
|
||||
}
|
||||
|
||||
sceneData.environmentNode = environmentNode;
|
||||
sceneData.environment = environment;
|
||||
|
||||
}
|
||||
|
||||
} else if ( sceneData.environmentNode ) {
|
||||
|
||||
delete sceneData.environmentNode;
|
||||
delete sceneData.environment;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
getNodeFrame( renderer = this.renderer, scene = null, object = null, camera = null, material = null ) {
|
||||
|
||||
const nodeFrame = this.nodeFrame;
|
||||
nodeFrame.renderer = renderer;
|
||||
nodeFrame.scene = scene;
|
||||
nodeFrame.object = object;
|
||||
nodeFrame.camera = camera;
|
||||
nodeFrame.material = material;
|
||||
|
||||
return nodeFrame;
|
||||
|
||||
}
|
||||
|
||||
getNodeFrameForRender( renderObject ) {
|
||||
|
||||
return this.getNodeFrame( renderObject.renderer, renderObject.scene, renderObject.object, renderObject.camera, renderObject.material );
|
||||
|
||||
}
|
||||
|
||||
updateBefore( renderObject ) {
|
||||
|
||||
const nodeFrame = this.getNodeFrameForRender( renderObject );
|
||||
const nodeBuilder = renderObject.getNodeBuilderState();
|
||||
|
||||
for ( const node of nodeBuilder.updateBeforeNodes ) {
|
||||
|
||||
nodeFrame.updateBeforeNode( node );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
updateForCompute( computeNode ) {
|
||||
|
||||
const nodeFrame = this.getNodeFrame();
|
||||
const nodeBuilder = this.getForCompute( computeNode );
|
||||
|
||||
for ( const node of nodeBuilder.updateNodes ) {
|
||||
|
||||
nodeFrame.updateNode( node );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
updateForRender( renderObject ) {
|
||||
|
||||
const nodeFrame = this.getNodeFrameForRender( renderObject );
|
||||
const nodeBuilder = renderObject.getNodeBuilderState();
|
||||
|
||||
for ( const node of nodeBuilder.updateNodes ) {
|
||||
|
||||
nodeFrame.updateNode( node );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
super.dispose();
|
||||
|
||||
this.nodeFrame = new NodeFrame();
|
||||
this.nodeBuilderCache = new Map();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Nodes;
|
||||
Reference in New Issue
Block a user