添加关照、全局等高线、修改图层问题
This commit is contained in:
322
dist/electron/static/sdk/three/jsm/renderers/common/Pipelines.js
vendored
Normal file
322
dist/electron/static/sdk/three/jsm/renderers/common/Pipelines.js
vendored
Normal file
@ -0,0 +1,322 @@
|
||||
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 nodeBuilderState = this.nodes.getForCompute( computeNode );
|
||||
|
||||
// programmable stage
|
||||
|
||||
let stageCompute = this.programs.compute.get( nodeBuilderState.computeShader );
|
||||
|
||||
if ( stageCompute === undefined ) {
|
||||
|
||||
if ( previousPipeline && previousPipeline.computeProgram.usedTimes === 0 ) this._releaseProgram( previousPipeline.computeProgram );
|
||||
|
||||
stageCompute = new ProgrammableStage( nodeBuilderState.computeShader, 'compute', nodeBuilderState.transforms, nodeBuilderState.nodeAttributes );
|
||||
this.programs.compute.set( nodeBuilderState.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, promises = null ) {
|
||||
|
||||
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, promises );
|
||||
|
||||
} 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, promises ) {
|
||||
|
||||
// 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, promises );
|
||||
|
||||
}
|
||||
|
||||
return pipeline;
|
||||
|
||||
}
|
||||
|
||||
_getComputeCacheKey( computeNode, stageCompute ) {
|
||||
|
||||
return computeNode.id + ',' + stageCompute.id;
|
||||
|
||||
}
|
||||
|
||||
_getRenderCacheKey( renderObject, stageVertex, stageFragment ) {
|
||||
|
||||
return stageVertex.id + ',' + stageFragment.id + ',' + this.backend.getRenderCacheKey( renderObject );
|
||||
|
||||
}
|
||||
|
||||
_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 );
|
||||
|
||||
return data.pipeline === undefined || this.backend.needsRenderUpdate( renderObject );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Pipelines;
|
Reference in New Issue
Block a user