Anlegen vom Raum-Scanner
This commit is contained in:
53
node_modules/three/src/renderers/webgl/WebGLAnimation.js
generated
vendored
Normal file
53
node_modules/three/src/renderers/webgl/WebGLAnimation.js
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
function WebGLAnimation() {
|
||||
|
||||
let context = null;
|
||||
let isAnimating = false;
|
||||
let animationLoop = null;
|
||||
let requestId = null;
|
||||
|
||||
function onAnimationFrame( time, frame ) {
|
||||
|
||||
animationLoop( time, frame );
|
||||
|
||||
requestId = context.requestAnimationFrame( onAnimationFrame );
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
start: function () {
|
||||
|
||||
if ( isAnimating === true ) return;
|
||||
if ( animationLoop === null ) return;
|
||||
|
||||
requestId = context.requestAnimationFrame( onAnimationFrame );
|
||||
|
||||
isAnimating = true;
|
||||
|
||||
},
|
||||
|
||||
stop: function () {
|
||||
|
||||
context.cancelAnimationFrame( requestId );
|
||||
|
||||
isAnimating = false;
|
||||
|
||||
},
|
||||
|
||||
setAnimationLoop: function ( callback ) {
|
||||
|
||||
animationLoop = callback;
|
||||
|
||||
},
|
||||
|
||||
setContext: function ( value ) {
|
||||
|
||||
context = value;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
export { WebGLAnimation };
|
||||
237
node_modules/three/src/renderers/webgl/WebGLAttributes.js
generated
vendored
Normal file
237
node_modules/three/src/renderers/webgl/WebGLAttributes.js
generated
vendored
Normal file
@@ -0,0 +1,237 @@
|
||||
function WebGLAttributes( gl ) {
|
||||
|
||||
const buffers = new WeakMap();
|
||||
|
||||
function createBuffer( attribute, bufferType ) {
|
||||
|
||||
const array = attribute.array;
|
||||
const usage = attribute.usage;
|
||||
const size = array.byteLength;
|
||||
|
||||
const buffer = gl.createBuffer();
|
||||
|
||||
gl.bindBuffer( bufferType, buffer );
|
||||
gl.bufferData( bufferType, array, usage );
|
||||
|
||||
attribute.onUploadCallback();
|
||||
|
||||
let type;
|
||||
|
||||
if ( array instanceof Float32Array ) {
|
||||
|
||||
type = gl.FLOAT;
|
||||
|
||||
} else if ( typeof Float16Array !== 'undefined' && array instanceof Float16Array ) {
|
||||
|
||||
type = gl.HALF_FLOAT;
|
||||
|
||||
} else if ( array instanceof Uint16Array ) {
|
||||
|
||||
if ( attribute.isFloat16BufferAttribute ) {
|
||||
|
||||
type = gl.HALF_FLOAT;
|
||||
|
||||
} else {
|
||||
|
||||
type = gl.UNSIGNED_SHORT;
|
||||
|
||||
}
|
||||
|
||||
} else if ( array instanceof Int16Array ) {
|
||||
|
||||
type = gl.SHORT;
|
||||
|
||||
} else if ( array instanceof Uint32Array ) {
|
||||
|
||||
type = gl.UNSIGNED_INT;
|
||||
|
||||
} else if ( array instanceof Int32Array ) {
|
||||
|
||||
type = gl.INT;
|
||||
|
||||
} else if ( array instanceof Int8Array ) {
|
||||
|
||||
type = gl.BYTE;
|
||||
|
||||
} else if ( array instanceof Uint8Array ) {
|
||||
|
||||
type = gl.UNSIGNED_BYTE;
|
||||
|
||||
} else if ( array instanceof Uint8ClampedArray ) {
|
||||
|
||||
type = gl.UNSIGNED_BYTE;
|
||||
|
||||
} else {
|
||||
|
||||
throw new Error( 'THREE.WebGLAttributes: Unsupported buffer data format: ' + array );
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
buffer: buffer,
|
||||
type: type,
|
||||
bytesPerElement: array.BYTES_PER_ELEMENT,
|
||||
version: attribute.version,
|
||||
size: size
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
function updateBuffer( buffer, attribute, bufferType ) {
|
||||
|
||||
const array = attribute.array;
|
||||
const updateRanges = attribute.updateRanges;
|
||||
|
||||
gl.bindBuffer( bufferType, buffer );
|
||||
|
||||
if ( updateRanges.length === 0 ) {
|
||||
|
||||
// Not using update ranges
|
||||
gl.bufferSubData( bufferType, 0, array );
|
||||
|
||||
} else {
|
||||
|
||||
// Before applying update ranges, we merge any adjacent / overlapping
|
||||
// ranges to reduce load on `gl.bufferSubData`. Empirically, this has led
|
||||
// to performance improvements for applications which make heavy use of
|
||||
// update ranges. Likely due to GPU command overhead.
|
||||
//
|
||||
// Note that to reduce garbage collection between frames, we merge the
|
||||
// update ranges in-place. This is safe because this method will clear the
|
||||
// update ranges once updated.
|
||||
|
||||
updateRanges.sort( ( a, b ) => a.start - b.start );
|
||||
|
||||
// To merge the update ranges in-place, we work from left to right in the
|
||||
// existing updateRanges array, merging ranges. This may result in a final
|
||||
// array which is smaller than the original. This index tracks the last
|
||||
// index representing a merged range, any data after this index can be
|
||||
// trimmed once the merge algorithm is completed.
|
||||
let mergeIndex = 0;
|
||||
|
||||
for ( let i = 1; i < updateRanges.length; i ++ ) {
|
||||
|
||||
const previousRange = updateRanges[ mergeIndex ];
|
||||
const range = updateRanges[ i ];
|
||||
|
||||
// We add one here to merge adjacent ranges. This is safe because ranges
|
||||
// operate over positive integers.
|
||||
if ( range.start <= previousRange.start + previousRange.count + 1 ) {
|
||||
|
||||
previousRange.count = Math.max(
|
||||
previousRange.count,
|
||||
range.start + range.count - previousRange.start
|
||||
);
|
||||
|
||||
} else {
|
||||
|
||||
++ mergeIndex;
|
||||
updateRanges[ mergeIndex ] = range;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Trim the array to only contain the merged ranges.
|
||||
updateRanges.length = mergeIndex + 1;
|
||||
|
||||
for ( let i = 0, l = updateRanges.length; i < l; i ++ ) {
|
||||
|
||||
const range = updateRanges[ i ];
|
||||
|
||||
gl.bufferSubData( bufferType, range.start * array.BYTES_PER_ELEMENT,
|
||||
array, range.start, range.count );
|
||||
|
||||
}
|
||||
|
||||
attribute.clearUpdateRanges();
|
||||
|
||||
}
|
||||
|
||||
attribute.onUploadCallback();
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
function get( attribute ) {
|
||||
|
||||
if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data;
|
||||
|
||||
return buffers.get( attribute );
|
||||
|
||||
}
|
||||
|
||||
function remove( attribute ) {
|
||||
|
||||
if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data;
|
||||
|
||||
const data = buffers.get( attribute );
|
||||
|
||||
if ( data ) {
|
||||
|
||||
gl.deleteBuffer( data.buffer );
|
||||
|
||||
buffers.delete( attribute );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function update( attribute, bufferType ) {
|
||||
|
||||
if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data;
|
||||
|
||||
if ( attribute.isGLBufferAttribute ) {
|
||||
|
||||
const cached = buffers.get( attribute );
|
||||
|
||||
if ( ! cached || cached.version < attribute.version ) {
|
||||
|
||||
buffers.set( attribute, {
|
||||
buffer: attribute.buffer,
|
||||
type: attribute.type,
|
||||
bytesPerElement: attribute.elementSize,
|
||||
version: attribute.version
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
const data = buffers.get( attribute );
|
||||
|
||||
if ( data === undefined ) {
|
||||
|
||||
buffers.set( attribute, createBuffer( attribute, bufferType ) );
|
||||
|
||||
} else if ( data.version < attribute.version ) {
|
||||
|
||||
if ( data.size !== attribute.array.byteLength ) {
|
||||
|
||||
throw new Error( 'THREE.WebGLAttributes: The size of the buffer attribute\'s array buffer does not match the original size. Resizing buffer attributes is not supported.' );
|
||||
|
||||
}
|
||||
|
||||
updateBuffer( data.buffer, attribute, bufferType );
|
||||
|
||||
data.version = attribute.version;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
get: get,
|
||||
remove: remove,
|
||||
update: update
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { WebGLAttributes };
|
||||
303
node_modules/three/src/renderers/webgl/WebGLBackground.js
generated
vendored
Normal file
303
node_modules/three/src/renderers/webgl/WebGLBackground.js
generated
vendored
Normal file
@@ -0,0 +1,303 @@
|
||||
import { BackSide, FrontSide, CubeUVReflectionMapping, SRGBTransfer } from '../../constants.js';
|
||||
import { BoxGeometry } from '../../geometries/BoxGeometry.js';
|
||||
import { PlaneGeometry } from '../../geometries/PlaneGeometry.js';
|
||||
import { ShaderMaterial } from '../../materials/ShaderMaterial.js';
|
||||
import { Color } from '../../math/Color.js';
|
||||
import { ColorManagement } from '../../math/ColorManagement.js';
|
||||
import { Euler } from '../../math/Euler.js';
|
||||
import { Matrix4 } from '../../math/Matrix4.js';
|
||||
import { Mesh } from '../../objects/Mesh.js';
|
||||
import { ShaderLib } from '../shaders/ShaderLib.js';
|
||||
import { cloneUniforms, getUnlitUniformColorSpace } from '../shaders/UniformsUtils.js';
|
||||
|
||||
const _rgb = { r: 0, b: 0, g: 0 };
|
||||
const _e1 = /*@__PURE__*/ new Euler();
|
||||
const _m1 = /*@__PURE__*/ new Matrix4();
|
||||
|
||||
function WebGLBackground( renderer, environments, state, objects, alpha, premultipliedAlpha ) {
|
||||
|
||||
const clearColor = new Color( 0x000000 );
|
||||
let clearAlpha = alpha === true ? 0 : 1;
|
||||
|
||||
let planeMesh;
|
||||
let boxMesh;
|
||||
|
||||
let currentBackground = null;
|
||||
let currentBackgroundVersion = 0;
|
||||
let currentTonemapping = null;
|
||||
|
||||
function getBackground( scene ) {
|
||||
|
||||
let background = scene.isScene === true ? scene.background : null;
|
||||
|
||||
if ( background && background.isTexture ) {
|
||||
|
||||
const usePMREM = scene.backgroundBlurriness > 0; // use PMREM if the user wants to blur the background
|
||||
background = environments.get( background, usePMREM );
|
||||
|
||||
}
|
||||
|
||||
return background;
|
||||
|
||||
}
|
||||
|
||||
function render( scene ) {
|
||||
|
||||
let forceClear = false;
|
||||
const background = getBackground( scene );
|
||||
|
||||
if ( background === null ) {
|
||||
|
||||
setClear( clearColor, clearAlpha );
|
||||
|
||||
} else if ( background && background.isColor ) {
|
||||
|
||||
setClear( background, 1 );
|
||||
forceClear = true;
|
||||
|
||||
}
|
||||
|
||||
const environmentBlendMode = renderer.xr.getEnvironmentBlendMode();
|
||||
|
||||
if ( environmentBlendMode === 'additive' ) {
|
||||
|
||||
state.buffers.color.setClear( 0, 0, 0, 1, premultipliedAlpha );
|
||||
|
||||
} else if ( environmentBlendMode === 'alpha-blend' ) {
|
||||
|
||||
state.buffers.color.setClear( 0, 0, 0, 0, premultipliedAlpha );
|
||||
|
||||
}
|
||||
|
||||
if ( renderer.autoClear || forceClear ) {
|
||||
|
||||
// buffers might not be writable which is required to ensure a correct clear
|
||||
|
||||
state.buffers.depth.setTest( true );
|
||||
state.buffers.depth.setMask( true );
|
||||
state.buffers.color.setMask( true );
|
||||
|
||||
renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function addToRenderList( renderList, scene ) {
|
||||
|
||||
const background = getBackground( scene );
|
||||
|
||||
if ( background && ( background.isCubeTexture || background.mapping === CubeUVReflectionMapping ) ) {
|
||||
|
||||
if ( boxMesh === undefined ) {
|
||||
|
||||
boxMesh = new Mesh(
|
||||
new BoxGeometry( 1, 1, 1 ),
|
||||
new ShaderMaterial( {
|
||||
name: 'BackgroundCubeMaterial',
|
||||
uniforms: cloneUniforms( ShaderLib.backgroundCube.uniforms ),
|
||||
vertexShader: ShaderLib.backgroundCube.vertexShader,
|
||||
fragmentShader: ShaderLib.backgroundCube.fragmentShader,
|
||||
side: BackSide,
|
||||
depthTest: false,
|
||||
depthWrite: false,
|
||||
fog: false,
|
||||
allowOverride: false
|
||||
} )
|
||||
);
|
||||
|
||||
boxMesh.geometry.deleteAttribute( 'normal' );
|
||||
boxMesh.geometry.deleteAttribute( 'uv' );
|
||||
|
||||
boxMesh.onBeforeRender = function ( renderer, scene, camera ) {
|
||||
|
||||
this.matrixWorld.copyPosition( camera.matrixWorld );
|
||||
|
||||
};
|
||||
|
||||
// add "envMap" material property so the renderer can evaluate it like for built-in materials
|
||||
Object.defineProperty( boxMesh.material, 'envMap', {
|
||||
|
||||
get: function () {
|
||||
|
||||
return this.uniforms.envMap.value;
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
objects.update( boxMesh );
|
||||
|
||||
}
|
||||
|
||||
_e1.copy( scene.backgroundRotation );
|
||||
|
||||
// accommodate left-handed frame
|
||||
_e1.x *= - 1; _e1.y *= - 1; _e1.z *= - 1;
|
||||
|
||||
if ( background.isCubeTexture && background.isRenderTargetTexture === false ) {
|
||||
|
||||
// environment maps which are not cube render targets or PMREMs follow a different convention
|
||||
_e1.y *= - 1;
|
||||
_e1.z *= - 1;
|
||||
|
||||
}
|
||||
|
||||
boxMesh.material.uniforms.envMap.value = background;
|
||||
boxMesh.material.uniforms.flipEnvMap.value = ( background.isCubeTexture && background.isRenderTargetTexture === false ) ? - 1 : 1;
|
||||
boxMesh.material.uniforms.backgroundBlurriness.value = scene.backgroundBlurriness;
|
||||
boxMesh.material.uniforms.backgroundIntensity.value = scene.backgroundIntensity;
|
||||
boxMesh.material.uniforms.backgroundRotation.value.setFromMatrix4( _m1.makeRotationFromEuler( _e1 ) );
|
||||
boxMesh.material.toneMapped = ColorManagement.getTransfer( background.colorSpace ) !== SRGBTransfer;
|
||||
|
||||
if ( currentBackground !== background ||
|
||||
currentBackgroundVersion !== background.version ||
|
||||
currentTonemapping !== renderer.toneMapping ) {
|
||||
|
||||
boxMesh.material.needsUpdate = true;
|
||||
|
||||
currentBackground = background;
|
||||
currentBackgroundVersion = background.version;
|
||||
currentTonemapping = renderer.toneMapping;
|
||||
|
||||
}
|
||||
|
||||
boxMesh.layers.enableAll();
|
||||
|
||||
// push to the pre-sorted opaque render list
|
||||
renderList.unshift( boxMesh, boxMesh.geometry, boxMesh.material, 0, 0, null );
|
||||
|
||||
} else if ( background && background.isTexture ) {
|
||||
|
||||
if ( planeMesh === undefined ) {
|
||||
|
||||
planeMesh = new Mesh(
|
||||
new PlaneGeometry( 2, 2 ),
|
||||
new ShaderMaterial( {
|
||||
name: 'BackgroundMaterial',
|
||||
uniforms: cloneUniforms( ShaderLib.background.uniforms ),
|
||||
vertexShader: ShaderLib.background.vertexShader,
|
||||
fragmentShader: ShaderLib.background.fragmentShader,
|
||||
side: FrontSide,
|
||||
depthTest: false,
|
||||
depthWrite: false,
|
||||
fog: false,
|
||||
allowOverride: false
|
||||
} )
|
||||
);
|
||||
|
||||
planeMesh.geometry.deleteAttribute( 'normal' );
|
||||
|
||||
// add "map" material property so the renderer can evaluate it like for built-in materials
|
||||
Object.defineProperty( planeMesh.material, 'map', {
|
||||
|
||||
get: function () {
|
||||
|
||||
return this.uniforms.t2D.value;
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
objects.update( planeMesh );
|
||||
|
||||
}
|
||||
|
||||
planeMesh.material.uniforms.t2D.value = background;
|
||||
planeMesh.material.uniforms.backgroundIntensity.value = scene.backgroundIntensity;
|
||||
planeMesh.material.toneMapped = ColorManagement.getTransfer( background.colorSpace ) !== SRGBTransfer;
|
||||
|
||||
if ( background.matrixAutoUpdate === true ) {
|
||||
|
||||
background.updateMatrix();
|
||||
|
||||
}
|
||||
|
||||
planeMesh.material.uniforms.uvTransform.value.copy( background.matrix );
|
||||
|
||||
if ( currentBackground !== background ||
|
||||
currentBackgroundVersion !== background.version ||
|
||||
currentTonemapping !== renderer.toneMapping ) {
|
||||
|
||||
planeMesh.material.needsUpdate = true;
|
||||
|
||||
currentBackground = background;
|
||||
currentBackgroundVersion = background.version;
|
||||
currentTonemapping = renderer.toneMapping;
|
||||
|
||||
}
|
||||
|
||||
planeMesh.layers.enableAll();
|
||||
|
||||
// push to the pre-sorted opaque render list
|
||||
renderList.unshift( planeMesh, planeMesh.geometry, planeMesh.material, 0, 0, null );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function setClear( color, alpha ) {
|
||||
|
||||
color.getRGB( _rgb, getUnlitUniformColorSpace( renderer ) );
|
||||
|
||||
state.buffers.color.setClear( _rgb.r, _rgb.g, _rgb.b, alpha, premultipliedAlpha );
|
||||
|
||||
}
|
||||
|
||||
function dispose() {
|
||||
|
||||
if ( boxMesh !== undefined ) {
|
||||
|
||||
boxMesh.geometry.dispose();
|
||||
boxMesh.material.dispose();
|
||||
|
||||
boxMesh = undefined;
|
||||
|
||||
}
|
||||
|
||||
if ( planeMesh !== undefined ) {
|
||||
|
||||
planeMesh.geometry.dispose();
|
||||
planeMesh.material.dispose();
|
||||
|
||||
planeMesh = undefined;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
getClearColor: function () {
|
||||
|
||||
return clearColor;
|
||||
|
||||
},
|
||||
setClearColor: function ( color, alpha = 1 ) {
|
||||
|
||||
clearColor.set( color );
|
||||
clearAlpha = alpha;
|
||||
setClear( clearColor, clearAlpha );
|
||||
|
||||
},
|
||||
getClearAlpha: function () {
|
||||
|
||||
return clearAlpha;
|
||||
|
||||
},
|
||||
setClearAlpha: function ( alpha ) {
|
||||
|
||||
clearAlpha = alpha;
|
||||
setClear( clearColor, clearAlpha );
|
||||
|
||||
},
|
||||
render: render,
|
||||
addToRenderList: addToRenderList,
|
||||
dispose: dispose
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { WebGLBackground };
|
||||
666
node_modules/three/src/renderers/webgl/WebGLBindingStates.js
generated
vendored
Normal file
666
node_modules/three/src/renderers/webgl/WebGLBindingStates.js
generated
vendored
Normal file
@@ -0,0 +1,666 @@
|
||||
import { IntType } from '../../constants.js';
|
||||
|
||||
function WebGLBindingStates( gl, attributes ) {
|
||||
|
||||
const maxVertexAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );
|
||||
|
||||
const bindingStates = {};
|
||||
|
||||
const defaultState = createBindingState( null );
|
||||
let currentState = defaultState;
|
||||
let forceUpdate = false;
|
||||
|
||||
function setup( object, material, program, geometry, index ) {
|
||||
|
||||
let updateBuffers = false;
|
||||
|
||||
const state = getBindingState( object, geometry, program, material );
|
||||
|
||||
if ( currentState !== state ) {
|
||||
|
||||
currentState = state;
|
||||
bindVertexArrayObject( currentState.object );
|
||||
|
||||
}
|
||||
|
||||
updateBuffers = needsUpdate( object, geometry, program, index );
|
||||
|
||||
if ( updateBuffers ) saveCache( object, geometry, program, index );
|
||||
|
||||
if ( index !== null ) {
|
||||
|
||||
attributes.update( index, gl.ELEMENT_ARRAY_BUFFER );
|
||||
|
||||
}
|
||||
|
||||
if ( updateBuffers || forceUpdate ) {
|
||||
|
||||
forceUpdate = false;
|
||||
|
||||
setupVertexAttributes( object, material, program, geometry );
|
||||
|
||||
if ( index !== null ) {
|
||||
|
||||
gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, attributes.get( index ).buffer );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function createVertexArrayObject() {
|
||||
|
||||
return gl.createVertexArray();
|
||||
|
||||
}
|
||||
|
||||
function bindVertexArrayObject( vao ) {
|
||||
|
||||
return gl.bindVertexArray( vao );
|
||||
|
||||
}
|
||||
|
||||
function deleteVertexArrayObject( vao ) {
|
||||
|
||||
return gl.deleteVertexArray( vao );
|
||||
|
||||
}
|
||||
|
||||
function getBindingState( object, geometry, program, material ) {
|
||||
|
||||
const wireframe = ( material.wireframe === true );
|
||||
|
||||
let objectMap = bindingStates[ geometry.id ];
|
||||
|
||||
if ( objectMap === undefined ) {
|
||||
|
||||
objectMap = {};
|
||||
bindingStates[ geometry.id ] = objectMap;
|
||||
|
||||
}
|
||||
|
||||
// Each InstancedMesh requires unique binding states because it contains instanced attributes.
|
||||
const objectId = ( object.isInstancedMesh === true ) ? object.id : 0;
|
||||
|
||||
let programMap = objectMap[ objectId ];
|
||||
|
||||
if ( programMap === undefined ) {
|
||||
|
||||
programMap = {};
|
||||
objectMap[ objectId ] = programMap;
|
||||
|
||||
}
|
||||
|
||||
let stateMap = programMap[ program.id ];
|
||||
|
||||
if ( stateMap === undefined ) {
|
||||
|
||||
stateMap = {};
|
||||
programMap[ program.id ] = stateMap;
|
||||
|
||||
}
|
||||
|
||||
let state = stateMap[ wireframe ];
|
||||
|
||||
if ( state === undefined ) {
|
||||
|
||||
state = createBindingState( createVertexArrayObject() );
|
||||
stateMap[ wireframe ] = state;
|
||||
|
||||
}
|
||||
|
||||
return state;
|
||||
|
||||
}
|
||||
|
||||
function createBindingState( vao ) {
|
||||
|
||||
const newAttributes = [];
|
||||
const enabledAttributes = [];
|
||||
const attributeDivisors = [];
|
||||
|
||||
for ( let i = 0; i < maxVertexAttributes; i ++ ) {
|
||||
|
||||
newAttributes[ i ] = 0;
|
||||
enabledAttributes[ i ] = 0;
|
||||
attributeDivisors[ i ] = 0;
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
// for backward compatibility on non-VAO support browser
|
||||
geometry: null,
|
||||
program: null,
|
||||
wireframe: false,
|
||||
|
||||
newAttributes: newAttributes,
|
||||
enabledAttributes: enabledAttributes,
|
||||
attributeDivisors: attributeDivisors,
|
||||
object: vao,
|
||||
attributes: {},
|
||||
index: null
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
function needsUpdate( object, geometry, program, index ) {
|
||||
|
||||
const cachedAttributes = currentState.attributes;
|
||||
const geometryAttributes = geometry.attributes;
|
||||
|
||||
let attributesNum = 0;
|
||||
|
||||
const programAttributes = program.getAttributes();
|
||||
|
||||
for ( const name in programAttributes ) {
|
||||
|
||||
const programAttribute = programAttributes[ name ];
|
||||
|
||||
if ( programAttribute.location >= 0 ) {
|
||||
|
||||
const cachedAttribute = cachedAttributes[ name ];
|
||||
let geometryAttribute = geometryAttributes[ name ];
|
||||
|
||||
if ( geometryAttribute === undefined ) {
|
||||
|
||||
if ( name === 'instanceMatrix' && object.instanceMatrix ) geometryAttribute = object.instanceMatrix;
|
||||
if ( name === 'instanceColor' && object.instanceColor ) geometryAttribute = object.instanceColor;
|
||||
|
||||
}
|
||||
|
||||
if ( cachedAttribute === undefined ) return true;
|
||||
|
||||
if ( cachedAttribute.attribute !== geometryAttribute ) return true;
|
||||
|
||||
if ( geometryAttribute && cachedAttribute.data !== geometryAttribute.data ) return true;
|
||||
|
||||
attributesNum ++;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( currentState.attributesNum !== attributesNum ) return true;
|
||||
|
||||
if ( currentState.index !== index ) return true;
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
function saveCache( object, geometry, program, index ) {
|
||||
|
||||
const cache = {};
|
||||
const attributes = geometry.attributes;
|
||||
let attributesNum = 0;
|
||||
|
||||
const programAttributes = program.getAttributes();
|
||||
|
||||
for ( const name in programAttributes ) {
|
||||
|
||||
const programAttribute = programAttributes[ name ];
|
||||
|
||||
if ( programAttribute.location >= 0 ) {
|
||||
|
||||
let attribute = attributes[ name ];
|
||||
|
||||
if ( attribute === undefined ) {
|
||||
|
||||
if ( name === 'instanceMatrix' && object.instanceMatrix ) attribute = object.instanceMatrix;
|
||||
if ( name === 'instanceColor' && object.instanceColor ) attribute = object.instanceColor;
|
||||
|
||||
}
|
||||
|
||||
const data = {};
|
||||
data.attribute = attribute;
|
||||
|
||||
if ( attribute && attribute.data ) {
|
||||
|
||||
data.data = attribute.data;
|
||||
|
||||
}
|
||||
|
||||
cache[ name ] = data;
|
||||
|
||||
attributesNum ++;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
currentState.attributes = cache;
|
||||
currentState.attributesNum = attributesNum;
|
||||
|
||||
currentState.index = index;
|
||||
|
||||
}
|
||||
|
||||
function initAttributes() {
|
||||
|
||||
const newAttributes = currentState.newAttributes;
|
||||
|
||||
for ( let i = 0, il = newAttributes.length; i < il; i ++ ) {
|
||||
|
||||
newAttributes[ i ] = 0;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function enableAttribute( attribute ) {
|
||||
|
||||
enableAttributeAndDivisor( attribute, 0 );
|
||||
|
||||
}
|
||||
|
||||
function enableAttributeAndDivisor( attribute, meshPerAttribute ) {
|
||||
|
||||
const newAttributes = currentState.newAttributes;
|
||||
const enabledAttributes = currentState.enabledAttributes;
|
||||
const attributeDivisors = currentState.attributeDivisors;
|
||||
|
||||
newAttributes[ attribute ] = 1;
|
||||
|
||||
if ( enabledAttributes[ attribute ] === 0 ) {
|
||||
|
||||
gl.enableVertexAttribArray( attribute );
|
||||
enabledAttributes[ attribute ] = 1;
|
||||
|
||||
}
|
||||
|
||||
if ( attributeDivisors[ attribute ] !== meshPerAttribute ) {
|
||||
|
||||
gl.vertexAttribDivisor( attribute, meshPerAttribute );
|
||||
attributeDivisors[ attribute ] = meshPerAttribute;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function disableUnusedAttributes() {
|
||||
|
||||
const newAttributes = currentState.newAttributes;
|
||||
const enabledAttributes = currentState.enabledAttributes;
|
||||
|
||||
for ( let i = 0, il = enabledAttributes.length; i < il; i ++ ) {
|
||||
|
||||
if ( enabledAttributes[ i ] !== newAttributes[ i ] ) {
|
||||
|
||||
gl.disableVertexAttribArray( i );
|
||||
enabledAttributes[ i ] = 0;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function vertexAttribPointer( index, size, type, normalized, stride, offset, integer ) {
|
||||
|
||||
if ( integer === true ) {
|
||||
|
||||
gl.vertexAttribIPointer( index, size, type, stride, offset );
|
||||
|
||||
} else {
|
||||
|
||||
gl.vertexAttribPointer( index, size, type, normalized, stride, offset );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function setupVertexAttributes( object, material, program, geometry ) {
|
||||
|
||||
initAttributes();
|
||||
|
||||
const geometryAttributes = geometry.attributes;
|
||||
|
||||
const programAttributes = program.getAttributes();
|
||||
|
||||
const materialDefaultAttributeValues = material.defaultAttributeValues;
|
||||
|
||||
for ( const name in programAttributes ) {
|
||||
|
||||
const programAttribute = programAttributes[ name ];
|
||||
|
||||
if ( programAttribute.location >= 0 ) {
|
||||
|
||||
let geometryAttribute = geometryAttributes[ name ];
|
||||
|
||||
if ( geometryAttribute === undefined ) {
|
||||
|
||||
if ( name === 'instanceMatrix' && object.instanceMatrix ) geometryAttribute = object.instanceMatrix;
|
||||
if ( name === 'instanceColor' && object.instanceColor ) geometryAttribute = object.instanceColor;
|
||||
|
||||
}
|
||||
|
||||
if ( geometryAttribute !== undefined ) {
|
||||
|
||||
const normalized = geometryAttribute.normalized;
|
||||
const size = geometryAttribute.itemSize;
|
||||
|
||||
const attribute = attributes.get( geometryAttribute );
|
||||
|
||||
// TODO Attribute may not be available on context restore
|
||||
|
||||
if ( attribute === undefined ) continue;
|
||||
|
||||
const buffer = attribute.buffer;
|
||||
const type = attribute.type;
|
||||
const bytesPerElement = attribute.bytesPerElement;
|
||||
|
||||
// check for integer attributes
|
||||
|
||||
const integer = ( type === gl.INT || type === gl.UNSIGNED_INT || geometryAttribute.gpuType === IntType );
|
||||
|
||||
if ( geometryAttribute.isInterleavedBufferAttribute ) {
|
||||
|
||||
const data = geometryAttribute.data;
|
||||
const stride = data.stride;
|
||||
const offset = geometryAttribute.offset;
|
||||
|
||||
if ( data.isInstancedInterleavedBuffer ) {
|
||||
|
||||
for ( let i = 0; i < programAttribute.locationSize; i ++ ) {
|
||||
|
||||
enableAttributeAndDivisor( programAttribute.location + i, data.meshPerAttribute );
|
||||
|
||||
}
|
||||
|
||||
if ( object.isInstancedMesh !== true && geometry._maxInstanceCount === undefined ) {
|
||||
|
||||
geometry._maxInstanceCount = data.meshPerAttribute * data.count;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
for ( let i = 0; i < programAttribute.locationSize; i ++ ) {
|
||||
|
||||
enableAttribute( programAttribute.location + i );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
gl.bindBuffer( gl.ARRAY_BUFFER, buffer );
|
||||
|
||||
for ( let i = 0; i < programAttribute.locationSize; i ++ ) {
|
||||
|
||||
vertexAttribPointer(
|
||||
programAttribute.location + i,
|
||||
size / programAttribute.locationSize,
|
||||
type,
|
||||
normalized,
|
||||
stride * bytesPerElement,
|
||||
( offset + ( size / programAttribute.locationSize ) * i ) * bytesPerElement,
|
||||
integer
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if ( geometryAttribute.isInstancedBufferAttribute ) {
|
||||
|
||||
for ( let i = 0; i < programAttribute.locationSize; i ++ ) {
|
||||
|
||||
enableAttributeAndDivisor( programAttribute.location + i, geometryAttribute.meshPerAttribute );
|
||||
|
||||
}
|
||||
|
||||
if ( object.isInstancedMesh !== true && geometry._maxInstanceCount === undefined ) {
|
||||
|
||||
geometry._maxInstanceCount = geometryAttribute.meshPerAttribute * geometryAttribute.count;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
for ( let i = 0; i < programAttribute.locationSize; i ++ ) {
|
||||
|
||||
enableAttribute( programAttribute.location + i );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
gl.bindBuffer( gl.ARRAY_BUFFER, buffer );
|
||||
|
||||
for ( let i = 0; i < programAttribute.locationSize; i ++ ) {
|
||||
|
||||
vertexAttribPointer(
|
||||
programAttribute.location + i,
|
||||
size / programAttribute.locationSize,
|
||||
type,
|
||||
normalized,
|
||||
size * bytesPerElement,
|
||||
( size / programAttribute.locationSize ) * i * bytesPerElement,
|
||||
integer
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else if ( materialDefaultAttributeValues !== undefined ) {
|
||||
|
||||
const value = materialDefaultAttributeValues[ name ];
|
||||
|
||||
if ( value !== undefined ) {
|
||||
|
||||
switch ( value.length ) {
|
||||
|
||||
case 2:
|
||||
gl.vertexAttrib2fv( programAttribute.location, value );
|
||||
break;
|
||||
|
||||
case 3:
|
||||
gl.vertexAttrib3fv( programAttribute.location, value );
|
||||
break;
|
||||
|
||||
case 4:
|
||||
gl.vertexAttrib4fv( programAttribute.location, value );
|
||||
break;
|
||||
|
||||
default:
|
||||
gl.vertexAttrib1fv( programAttribute.location, value );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
disableUnusedAttributes();
|
||||
|
||||
}
|
||||
|
||||
function dispose() {
|
||||
|
||||
reset();
|
||||
|
||||
for ( const geometryId in bindingStates ) {
|
||||
|
||||
const objectMap = bindingStates[ geometryId ];
|
||||
|
||||
for ( const objectId in objectMap ) {
|
||||
|
||||
const programMap = objectMap[ objectId ];
|
||||
|
||||
for ( const programId in programMap ) {
|
||||
|
||||
const stateMap = programMap[ programId ];
|
||||
|
||||
for ( const wireframe in stateMap ) {
|
||||
|
||||
deleteVertexArrayObject( stateMap[ wireframe ].object );
|
||||
|
||||
delete stateMap[ wireframe ];
|
||||
|
||||
}
|
||||
|
||||
delete programMap[ programId ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
delete bindingStates[ geometryId ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function releaseStatesOfGeometry( geometry ) {
|
||||
|
||||
if ( bindingStates[ geometry.id ] === undefined ) return;
|
||||
|
||||
const objectMap = bindingStates[ geometry.id ];
|
||||
|
||||
for ( const objectId in objectMap ) {
|
||||
|
||||
const programMap = objectMap[ objectId ];
|
||||
|
||||
for ( const programId in programMap ) {
|
||||
|
||||
const stateMap = programMap[ programId ];
|
||||
|
||||
for ( const wireframe in stateMap ) {
|
||||
|
||||
deleteVertexArrayObject( stateMap[ wireframe ].object );
|
||||
|
||||
delete stateMap[ wireframe ];
|
||||
|
||||
}
|
||||
|
||||
delete programMap[ programId ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
delete bindingStates[ geometry.id ];
|
||||
|
||||
}
|
||||
|
||||
function releaseStatesOfProgram( program ) {
|
||||
|
||||
for ( const geometryId in bindingStates ) {
|
||||
|
||||
const objectMap = bindingStates[ geometryId ];
|
||||
|
||||
for ( const objectId in objectMap ) {
|
||||
|
||||
const programMap = objectMap[ objectId ];
|
||||
|
||||
if ( programMap[ program.id ] === undefined ) continue;
|
||||
|
||||
const stateMap = programMap[ program.id ];
|
||||
|
||||
for ( const wireframe in stateMap ) {
|
||||
|
||||
deleteVertexArrayObject( stateMap[ wireframe ].object );
|
||||
|
||||
delete stateMap[ wireframe ];
|
||||
|
||||
}
|
||||
|
||||
delete programMap[ program.id ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function releaseStatesOfObject( object ) {
|
||||
|
||||
for ( const geometryId in bindingStates ) {
|
||||
|
||||
const objectMap = bindingStates[ geometryId ];
|
||||
|
||||
const objectId = ( object.isInstancedMesh === true ) ? object.id : 0;
|
||||
|
||||
const programMap = objectMap[ objectId ];
|
||||
|
||||
if ( programMap === undefined ) continue;
|
||||
|
||||
for ( const programId in programMap ) {
|
||||
|
||||
const stateMap = programMap[ programId ];
|
||||
|
||||
for ( const wireframe in stateMap ) {
|
||||
|
||||
deleteVertexArrayObject( stateMap[ wireframe ].object );
|
||||
|
||||
delete stateMap[ wireframe ];
|
||||
|
||||
}
|
||||
|
||||
delete programMap[ programId ];
|
||||
|
||||
}
|
||||
|
||||
delete objectMap[ objectId ];
|
||||
|
||||
if ( Object.keys( objectMap ).length === 0 ) {
|
||||
|
||||
delete bindingStates[ geometryId ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
function reset() {
|
||||
|
||||
resetDefaultState();
|
||||
forceUpdate = true;
|
||||
|
||||
if ( currentState === defaultState ) return;
|
||||
|
||||
currentState = defaultState;
|
||||
bindVertexArrayObject( currentState.object );
|
||||
|
||||
}
|
||||
|
||||
// for backward-compatibility
|
||||
|
||||
function resetDefaultState() {
|
||||
|
||||
defaultState.geometry = null;
|
||||
defaultState.program = null;
|
||||
defaultState.wireframe = false;
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
setup: setup,
|
||||
reset: reset,
|
||||
resetDefaultState: resetDefaultState,
|
||||
dispose: dispose,
|
||||
releaseStatesOfGeometry: releaseStatesOfGeometry,
|
||||
releaseStatesOfObject: releaseStatesOfObject,
|
||||
releaseStatesOfProgram: releaseStatesOfProgram,
|
||||
|
||||
initAttributes: initAttributes,
|
||||
enableAttribute: enableAttribute,
|
||||
disableUnusedAttributes: disableUnusedAttributes
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { WebGLBindingStates };
|
||||
89
node_modules/three/src/renderers/webgl/WebGLBufferRenderer.js
generated
vendored
Normal file
89
node_modules/three/src/renderers/webgl/WebGLBufferRenderer.js
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
function WebGLBufferRenderer( gl, extensions, info ) {
|
||||
|
||||
let mode;
|
||||
|
||||
function setMode( value ) {
|
||||
|
||||
mode = value;
|
||||
|
||||
}
|
||||
|
||||
function render( start, count ) {
|
||||
|
||||
gl.drawArrays( mode, start, count );
|
||||
|
||||
info.update( count, mode, 1 );
|
||||
|
||||
}
|
||||
|
||||
function renderInstances( start, count, primcount ) {
|
||||
|
||||
if ( primcount === 0 ) return;
|
||||
|
||||
gl.drawArraysInstanced( mode, start, count, primcount );
|
||||
|
||||
info.update( count, mode, primcount );
|
||||
|
||||
}
|
||||
|
||||
function renderMultiDraw( starts, counts, drawCount ) {
|
||||
|
||||
if ( drawCount === 0 ) return;
|
||||
|
||||
const extension = extensions.get( 'WEBGL_multi_draw' );
|
||||
extension.multiDrawArraysWEBGL( mode, starts, 0, counts, 0, drawCount );
|
||||
|
||||
let elementCount = 0;
|
||||
for ( let i = 0; i < drawCount; i ++ ) {
|
||||
|
||||
elementCount += counts[ i ];
|
||||
|
||||
}
|
||||
|
||||
info.update( elementCount, mode, 1 );
|
||||
|
||||
}
|
||||
|
||||
function renderMultiDrawInstances( starts, counts, drawCount, primcount ) {
|
||||
|
||||
if ( drawCount === 0 ) return;
|
||||
|
||||
const extension = extensions.get( 'WEBGL_multi_draw' );
|
||||
|
||||
if ( extension === null ) {
|
||||
|
||||
for ( let i = 0; i < starts.length; i ++ ) {
|
||||
|
||||
renderInstances( starts[ i ], counts[ i ], primcount[ i ] );
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
extension.multiDrawArraysInstancedWEBGL( mode, starts, 0, counts, 0, primcount, 0, drawCount );
|
||||
|
||||
let elementCount = 0;
|
||||
for ( let i = 0; i < drawCount; i ++ ) {
|
||||
|
||||
elementCount += counts[ i ] * primcount[ i ];
|
||||
|
||||
}
|
||||
|
||||
info.update( elementCount, mode, 1 );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
this.setMode = setMode;
|
||||
this.render = render;
|
||||
this.renderInstances = renderInstances;
|
||||
this.renderMultiDraw = renderMultiDraw;
|
||||
this.renderMultiDrawInstances = renderMultiDrawInstances;
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { WebGLBufferRenderer };
|
||||
144
node_modules/three/src/renderers/webgl/WebGLCapabilities.js
generated
vendored
Normal file
144
node_modules/three/src/renderers/webgl/WebGLCapabilities.js
generated
vendored
Normal file
@@ -0,0 +1,144 @@
|
||||
import { FloatType, HalfFloatType, RGBAFormat, UnsignedByteType } from '../../constants.js';
|
||||
import { warn } from '../../utils.js';
|
||||
|
||||
function WebGLCapabilities( gl, extensions, parameters, utils ) {
|
||||
|
||||
let maxAnisotropy;
|
||||
|
||||
function getMaxAnisotropy() {
|
||||
|
||||
if ( maxAnisotropy !== undefined ) return maxAnisotropy;
|
||||
|
||||
if ( extensions.has( 'EXT_texture_filter_anisotropic' ) === true ) {
|
||||
|
||||
const extension = extensions.get( 'EXT_texture_filter_anisotropic' );
|
||||
|
||||
maxAnisotropy = gl.getParameter( extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT );
|
||||
|
||||
} else {
|
||||
|
||||
maxAnisotropy = 0;
|
||||
|
||||
}
|
||||
|
||||
return maxAnisotropy;
|
||||
|
||||
}
|
||||
|
||||
function textureFormatReadable( textureFormat ) {
|
||||
|
||||
if ( textureFormat !== RGBAFormat && utils.convert( textureFormat ) !== gl.getParameter( gl.IMPLEMENTATION_COLOR_READ_FORMAT ) ) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
function textureTypeReadable( textureType ) {
|
||||
|
||||
const halfFloatSupportedByExt = ( textureType === HalfFloatType ) && ( extensions.has( 'EXT_color_buffer_half_float' ) || extensions.has( 'EXT_color_buffer_float' ) );
|
||||
|
||||
if ( textureType !== UnsignedByteType && utils.convert( textureType ) !== gl.getParameter( gl.IMPLEMENTATION_COLOR_READ_TYPE ) && // Edge and Chrome Mac < 52 (#9513)
|
||||
textureType !== FloatType && ! halfFloatSupportedByExt ) {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
function getMaxPrecision( precision ) {
|
||||
|
||||
if ( precision === 'highp' ) {
|
||||
|
||||
if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.HIGH_FLOAT ).precision > 0 &&
|
||||
gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.HIGH_FLOAT ).precision > 0 ) {
|
||||
|
||||
return 'highp';
|
||||
|
||||
}
|
||||
|
||||
precision = 'mediump';
|
||||
|
||||
}
|
||||
|
||||
if ( precision === 'mediump' ) {
|
||||
|
||||
if ( gl.getShaderPrecisionFormat( gl.VERTEX_SHADER, gl.MEDIUM_FLOAT ).precision > 0 &&
|
||||
gl.getShaderPrecisionFormat( gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT ).precision > 0 ) {
|
||||
|
||||
return 'mediump';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 'lowp';
|
||||
|
||||
}
|
||||
|
||||
let precision = parameters.precision !== undefined ? parameters.precision : 'highp';
|
||||
const maxPrecision = getMaxPrecision( precision );
|
||||
|
||||
if ( maxPrecision !== precision ) {
|
||||
|
||||
warn( 'WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.' );
|
||||
precision = maxPrecision;
|
||||
|
||||
}
|
||||
|
||||
const logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true;
|
||||
const reversedDepthBuffer = parameters.reversedDepthBuffer === true && extensions.has( 'EXT_clip_control' );
|
||||
|
||||
const maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );
|
||||
const maxVertexTextures = gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS );
|
||||
const maxTextureSize = gl.getParameter( gl.MAX_TEXTURE_SIZE );
|
||||
const maxCubemapSize = gl.getParameter( gl.MAX_CUBE_MAP_TEXTURE_SIZE );
|
||||
|
||||
const maxAttributes = gl.getParameter( gl.MAX_VERTEX_ATTRIBS );
|
||||
const maxVertexUniforms = gl.getParameter( gl.MAX_VERTEX_UNIFORM_VECTORS );
|
||||
const maxVaryings = gl.getParameter( gl.MAX_VARYING_VECTORS );
|
||||
const maxFragmentUniforms = gl.getParameter( gl.MAX_FRAGMENT_UNIFORM_VECTORS );
|
||||
|
||||
const maxSamples = gl.getParameter( gl.MAX_SAMPLES );
|
||||
const samples = gl.getParameter( gl.SAMPLES );
|
||||
|
||||
return {
|
||||
|
||||
isWebGL2: true, // keeping this for backwards compatibility
|
||||
|
||||
getMaxAnisotropy: getMaxAnisotropy,
|
||||
getMaxPrecision: getMaxPrecision,
|
||||
|
||||
textureFormatReadable: textureFormatReadable,
|
||||
textureTypeReadable: textureTypeReadable,
|
||||
|
||||
precision: precision,
|
||||
logarithmicDepthBuffer: logarithmicDepthBuffer,
|
||||
reversedDepthBuffer: reversedDepthBuffer,
|
||||
|
||||
maxTextures: maxTextures,
|
||||
maxVertexTextures: maxVertexTextures,
|
||||
maxTextureSize: maxTextureSize,
|
||||
maxCubemapSize: maxCubemapSize,
|
||||
|
||||
maxAttributes: maxAttributes,
|
||||
maxVertexUniforms: maxVertexUniforms,
|
||||
maxVaryings: maxVaryings,
|
||||
maxFragmentUniforms: maxFragmentUniforms,
|
||||
|
||||
maxSamples: maxSamples,
|
||||
|
||||
samples: samples
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { WebGLCapabilities };
|
||||
171
node_modules/three/src/renderers/webgl/WebGLClipping.js
generated
vendored
Normal file
171
node_modules/three/src/renderers/webgl/WebGLClipping.js
generated
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
import { Matrix3 } from '../../math/Matrix3.js';
|
||||
import { Plane } from '../../math/Plane.js';
|
||||
|
||||
function WebGLClipping( properties ) {
|
||||
|
||||
const scope = this;
|
||||
|
||||
let globalState = null,
|
||||
numGlobalPlanes = 0,
|
||||
localClippingEnabled = false,
|
||||
renderingShadows = false;
|
||||
|
||||
const plane = new Plane(),
|
||||
viewNormalMatrix = new Matrix3(),
|
||||
|
||||
uniform = { value: null, needsUpdate: false };
|
||||
|
||||
this.uniform = uniform;
|
||||
this.numPlanes = 0;
|
||||
this.numIntersection = 0;
|
||||
|
||||
this.init = function ( planes, enableLocalClipping ) {
|
||||
|
||||
const enabled =
|
||||
planes.length !== 0 ||
|
||||
enableLocalClipping ||
|
||||
// enable state of previous frame - the clipping code has to
|
||||
// run another frame in order to reset the state:
|
||||
numGlobalPlanes !== 0 ||
|
||||
localClippingEnabled;
|
||||
|
||||
localClippingEnabled = enableLocalClipping;
|
||||
|
||||
numGlobalPlanes = planes.length;
|
||||
|
||||
return enabled;
|
||||
|
||||
};
|
||||
|
||||
this.beginShadows = function () {
|
||||
|
||||
renderingShadows = true;
|
||||
projectPlanes( null );
|
||||
|
||||
};
|
||||
|
||||
this.endShadows = function () {
|
||||
|
||||
renderingShadows = false;
|
||||
|
||||
};
|
||||
|
||||
this.setGlobalState = function ( planes, camera ) {
|
||||
|
||||
globalState = projectPlanes( planes, camera, 0 );
|
||||
|
||||
};
|
||||
|
||||
this.setState = function ( material, camera, useCache ) {
|
||||
|
||||
const planes = material.clippingPlanes,
|
||||
clipIntersection = material.clipIntersection,
|
||||
clipShadows = material.clipShadows;
|
||||
|
||||
const materialProperties = properties.get( material );
|
||||
|
||||
if ( ! localClippingEnabled || planes === null || planes.length === 0 || renderingShadows && ! clipShadows ) {
|
||||
|
||||
// there's no local clipping
|
||||
|
||||
if ( renderingShadows ) {
|
||||
|
||||
// there's no global clipping
|
||||
|
||||
projectPlanes( null );
|
||||
|
||||
} else {
|
||||
|
||||
resetGlobalState();
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
const nGlobal = renderingShadows ? 0 : numGlobalPlanes,
|
||||
lGlobal = nGlobal * 4;
|
||||
|
||||
let dstArray = materialProperties.clippingState || null;
|
||||
|
||||
uniform.value = dstArray; // ensure unique state
|
||||
|
||||
dstArray = projectPlanes( planes, camera, lGlobal, useCache );
|
||||
|
||||
for ( let i = 0; i !== lGlobal; ++ i ) {
|
||||
|
||||
dstArray[ i ] = globalState[ i ];
|
||||
|
||||
}
|
||||
|
||||
materialProperties.clippingState = dstArray;
|
||||
this.numIntersection = clipIntersection ? this.numPlanes : 0;
|
||||
this.numPlanes += nGlobal;
|
||||
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
function resetGlobalState() {
|
||||
|
||||
if ( uniform.value !== globalState ) {
|
||||
|
||||
uniform.value = globalState;
|
||||
uniform.needsUpdate = numGlobalPlanes > 0;
|
||||
|
||||
}
|
||||
|
||||
scope.numPlanes = numGlobalPlanes;
|
||||
scope.numIntersection = 0;
|
||||
|
||||
}
|
||||
|
||||
function projectPlanes( planes, camera, dstOffset, skipTransform ) {
|
||||
|
||||
const nPlanes = planes !== null ? planes.length : 0;
|
||||
let dstArray = null;
|
||||
|
||||
if ( nPlanes !== 0 ) {
|
||||
|
||||
dstArray = uniform.value;
|
||||
|
||||
if ( skipTransform !== true || dstArray === null ) {
|
||||
|
||||
const flatSize = dstOffset + nPlanes * 4,
|
||||
viewMatrix = camera.matrixWorldInverse;
|
||||
|
||||
viewNormalMatrix.getNormalMatrix( viewMatrix );
|
||||
|
||||
if ( dstArray === null || dstArray.length < flatSize ) {
|
||||
|
||||
dstArray = new Float32Array( flatSize );
|
||||
|
||||
}
|
||||
|
||||
for ( let i = 0, i4 = dstOffset; i !== nPlanes; ++ i, i4 += 4 ) {
|
||||
|
||||
plane.copy( planes[ i ] ).applyMatrix4( viewMatrix, viewNormalMatrix );
|
||||
|
||||
plane.normal.toArray( dstArray, i4 );
|
||||
dstArray[ i4 + 3 ] = plane.constant;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uniform.value = dstArray;
|
||||
uniform.needsUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
scope.numPlanes = nPlanes;
|
||||
scope.numIntersection = 0;
|
||||
|
||||
return dstArray;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { WebGLClipping };
|
||||
228
node_modules/three/src/renderers/webgl/WebGLEnvironments.js
generated
vendored
Normal file
228
node_modules/three/src/renderers/webgl/WebGLEnvironments.js
generated
vendored
Normal file
@@ -0,0 +1,228 @@
|
||||
import { CubeReflectionMapping, CubeRefractionMapping, EquirectangularReflectionMapping, EquirectangularRefractionMapping } from '../../constants.js';
|
||||
import { PMREMGenerator } from '../../extras/PMREMGenerator.js';
|
||||
import { WebGLCubeRenderTarget } from '../WebGLCubeRenderTarget.js';
|
||||
|
||||
function WebGLEnvironments( renderer ) {
|
||||
|
||||
let cubeMaps = new WeakMap();
|
||||
let pmremMaps = new WeakMap();
|
||||
|
||||
let pmremGenerator = null;
|
||||
|
||||
function get( texture, usePMREM = false ) {
|
||||
|
||||
if ( texture === null || texture === undefined ) return null;
|
||||
|
||||
if ( usePMREM ) {
|
||||
|
||||
return getPMREM( texture );
|
||||
|
||||
}
|
||||
|
||||
return getCube( texture );
|
||||
|
||||
}
|
||||
|
||||
function getCube( texture ) {
|
||||
|
||||
if ( texture && texture.isTexture ) {
|
||||
|
||||
const mapping = texture.mapping;
|
||||
|
||||
if ( mapping === EquirectangularReflectionMapping || mapping === EquirectangularRefractionMapping ) {
|
||||
|
||||
if ( cubeMaps.has( texture ) ) {
|
||||
|
||||
const cubemap = cubeMaps.get( texture ).texture;
|
||||
return mapTextureMapping( cubemap, texture.mapping );
|
||||
|
||||
} else {
|
||||
|
||||
const image = texture.image;
|
||||
|
||||
if ( image && image.height > 0 ) {
|
||||
|
||||
const renderTarget = new WebGLCubeRenderTarget( image.height );
|
||||
renderTarget.fromEquirectangularTexture( renderer, texture );
|
||||
cubeMaps.set( texture, renderTarget );
|
||||
|
||||
texture.addEventListener( 'dispose', onCubemapDispose );
|
||||
|
||||
return mapTextureMapping( renderTarget.texture, texture.mapping );
|
||||
|
||||
} else {
|
||||
|
||||
// image not yet ready. try the conversion next frame
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return texture;
|
||||
|
||||
}
|
||||
|
||||
function getPMREM( texture ) {
|
||||
|
||||
if ( texture && texture.isTexture ) {
|
||||
|
||||
const mapping = texture.mapping;
|
||||
|
||||
const isEquirectMap = ( mapping === EquirectangularReflectionMapping || mapping === EquirectangularRefractionMapping );
|
||||
const isCubeMap = ( mapping === CubeReflectionMapping || mapping === CubeRefractionMapping );
|
||||
|
||||
// equirect/cube map to cubeUV conversion
|
||||
|
||||
if ( isEquirectMap || isCubeMap ) {
|
||||
|
||||
let renderTarget = pmremMaps.get( texture );
|
||||
|
||||
const currentPMREMVersion = renderTarget !== undefined ? renderTarget.texture.pmremVersion : 0;
|
||||
|
||||
if ( texture.isRenderTargetTexture && texture.pmremVersion !== currentPMREMVersion ) {
|
||||
|
||||
if ( pmremGenerator === null ) pmremGenerator = new PMREMGenerator( renderer );
|
||||
|
||||
renderTarget = isEquirectMap ? pmremGenerator.fromEquirectangular( texture, renderTarget ) : pmremGenerator.fromCubemap( texture, renderTarget );
|
||||
renderTarget.texture.pmremVersion = texture.pmremVersion;
|
||||
|
||||
pmremMaps.set( texture, renderTarget );
|
||||
|
||||
return renderTarget.texture;
|
||||
|
||||
} else {
|
||||
|
||||
if ( renderTarget !== undefined ) {
|
||||
|
||||
return renderTarget.texture;
|
||||
|
||||
} else {
|
||||
|
||||
const image = texture.image;
|
||||
|
||||
if ( ( isEquirectMap && image && image.height > 0 ) || ( isCubeMap && image && isCubeTextureComplete( image ) ) ) {
|
||||
|
||||
if ( pmremGenerator === null ) pmremGenerator = new PMREMGenerator( renderer );
|
||||
|
||||
renderTarget = isEquirectMap ? pmremGenerator.fromEquirectangular( texture ) : pmremGenerator.fromCubemap( texture );
|
||||
renderTarget.texture.pmremVersion = texture.pmremVersion;
|
||||
|
||||
pmremMaps.set( texture, renderTarget );
|
||||
|
||||
texture.addEventListener( 'dispose', onPMREMDispose );
|
||||
|
||||
return renderTarget.texture;
|
||||
|
||||
} else {
|
||||
|
||||
// image not yet ready. try the conversion next frame
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return texture;
|
||||
|
||||
}
|
||||
|
||||
function mapTextureMapping( texture, mapping ) {
|
||||
|
||||
if ( mapping === EquirectangularReflectionMapping ) {
|
||||
|
||||
texture.mapping = CubeReflectionMapping;
|
||||
|
||||
} else if ( mapping === EquirectangularRefractionMapping ) {
|
||||
|
||||
texture.mapping = CubeRefractionMapping;
|
||||
|
||||
}
|
||||
|
||||
return texture;
|
||||
|
||||
}
|
||||
|
||||
function isCubeTextureComplete( image ) {
|
||||
|
||||
let count = 0;
|
||||
const length = 6;
|
||||
|
||||
for ( let i = 0; i < length; i ++ ) {
|
||||
|
||||
if ( image[ i ] !== undefined ) count ++;
|
||||
|
||||
}
|
||||
|
||||
return count === length;
|
||||
|
||||
}
|
||||
|
||||
function onCubemapDispose( event ) {
|
||||
|
||||
const texture = event.target;
|
||||
|
||||
texture.removeEventListener( 'dispose', onCubemapDispose );
|
||||
|
||||
const cubemap = cubeMaps.get( texture );
|
||||
|
||||
if ( cubemap !== undefined ) {
|
||||
|
||||
cubeMaps.delete( texture );
|
||||
cubemap.dispose();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function onPMREMDispose( event ) {
|
||||
|
||||
const texture = event.target;
|
||||
|
||||
texture.removeEventListener( 'dispose', onPMREMDispose );
|
||||
|
||||
const pmrem = pmremMaps.get( texture );
|
||||
|
||||
if ( pmrem !== undefined ) {
|
||||
|
||||
pmremMaps.delete( texture );
|
||||
pmrem.dispose();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function dispose() {
|
||||
|
||||
cubeMaps = new WeakMap();
|
||||
pmremMaps = new WeakMap();
|
||||
|
||||
if ( pmremGenerator !== null ) {
|
||||
|
||||
pmremGenerator.dispose();
|
||||
pmremGenerator = null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
get: get,
|
||||
dispose: dispose
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
export { WebGLEnvironments };
|
||||
61
node_modules/three/src/renderers/webgl/WebGLExtensions.js
generated
vendored
Normal file
61
node_modules/three/src/renderers/webgl/WebGLExtensions.js
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
import { warnOnce } from '../../utils.js';
|
||||
|
||||
function WebGLExtensions( gl ) {
|
||||
|
||||
const extensions = {};
|
||||
|
||||
function getExtension( name ) {
|
||||
|
||||
if ( extensions[ name ] !== undefined ) {
|
||||
|
||||
return extensions[ name ];
|
||||
|
||||
}
|
||||
|
||||
const extension = gl.getExtension( name );
|
||||
|
||||
extensions[ name ] = extension;
|
||||
|
||||
return extension;
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
has: function ( name ) {
|
||||
|
||||
return getExtension( name ) !== null;
|
||||
|
||||
},
|
||||
|
||||
init: function () {
|
||||
|
||||
getExtension( 'EXT_color_buffer_float' );
|
||||
getExtension( 'WEBGL_clip_cull_distance' );
|
||||
getExtension( 'OES_texture_float_linear' );
|
||||
getExtension( 'EXT_color_buffer_half_float' );
|
||||
getExtension( 'WEBGL_multisampled_render_to_texture' );
|
||||
getExtension( 'WEBGL_render_shared_exponent' );
|
||||
|
||||
},
|
||||
|
||||
get: function ( name ) {
|
||||
|
||||
const extension = getExtension( name );
|
||||
|
||||
if ( extension === null ) {
|
||||
|
||||
warnOnce( 'WebGLRenderer: ' + name + ' extension not supported.' );
|
||||
|
||||
}
|
||||
|
||||
return extension;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { WebGLExtensions };
|
||||
186
node_modules/three/src/renderers/webgl/WebGLGeometries.js
generated
vendored
Normal file
186
node_modules/three/src/renderers/webgl/WebGLGeometries.js
generated
vendored
Normal file
@@ -0,0 +1,186 @@
|
||||
import { Uint16BufferAttribute, Uint32BufferAttribute } from '../../core/BufferAttribute.js';
|
||||
|
||||
function WebGLGeometries( gl, attributes, info, bindingStates ) {
|
||||
|
||||
const geometries = {};
|
||||
const wireframeAttributes = new WeakMap();
|
||||
|
||||
function onGeometryDispose( event ) {
|
||||
|
||||
const geometry = event.target;
|
||||
|
||||
if ( geometry.index !== null ) {
|
||||
|
||||
attributes.remove( geometry.index );
|
||||
|
||||
}
|
||||
|
||||
for ( const name in geometry.attributes ) {
|
||||
|
||||
attributes.remove( geometry.attributes[ name ] );
|
||||
|
||||
}
|
||||
|
||||
geometry.removeEventListener( 'dispose', onGeometryDispose );
|
||||
|
||||
delete geometries[ geometry.id ];
|
||||
|
||||
const attribute = wireframeAttributes.get( geometry );
|
||||
|
||||
if ( attribute ) {
|
||||
|
||||
attributes.remove( attribute );
|
||||
wireframeAttributes.delete( geometry );
|
||||
|
||||
}
|
||||
|
||||
bindingStates.releaseStatesOfGeometry( geometry );
|
||||
|
||||
if ( geometry.isInstancedBufferGeometry === true ) {
|
||||
|
||||
delete geometry._maxInstanceCount;
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
info.memory.geometries --;
|
||||
|
||||
}
|
||||
|
||||
function get( object, geometry ) {
|
||||
|
||||
if ( geometries[ geometry.id ] === true ) return geometry;
|
||||
|
||||
geometry.addEventListener( 'dispose', onGeometryDispose );
|
||||
|
||||
geometries[ geometry.id ] = true;
|
||||
|
||||
info.memory.geometries ++;
|
||||
|
||||
return geometry;
|
||||
|
||||
}
|
||||
|
||||
function update( geometry ) {
|
||||
|
||||
const geometryAttributes = geometry.attributes;
|
||||
|
||||
// Updating index buffer in VAO now. See WebGLBindingStates.
|
||||
|
||||
for ( const name in geometryAttributes ) {
|
||||
|
||||
attributes.update( geometryAttributes[ name ], gl.ARRAY_BUFFER );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function updateWireframeAttribute( geometry ) {
|
||||
|
||||
const indices = [];
|
||||
|
||||
const geometryIndex = geometry.index;
|
||||
const geometryPosition = geometry.attributes.position;
|
||||
let version = 0;
|
||||
|
||||
if ( geometryPosition === undefined ) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if ( geometryIndex !== null ) {
|
||||
|
||||
const array = geometryIndex.array;
|
||||
version = geometryIndex.version;
|
||||
|
||||
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;
|
||||
version = geometryPosition.version;
|
||||
|
||||
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 );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// check whether a 32 bit or 16 bit buffer is required to store the indices
|
||||
// account for PRIMITIVE_RESTART_FIXED_INDEX, #24565
|
||||
const attribute = new ( geometryPosition.count >= 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( indices, 1 );
|
||||
attribute.version = version;
|
||||
|
||||
// Updating index buffer in VAO now. See WebGLBindingStates
|
||||
|
||||
//
|
||||
|
||||
const previousAttribute = wireframeAttributes.get( geometry );
|
||||
|
||||
if ( previousAttribute ) attributes.remove( previousAttribute );
|
||||
|
||||
//
|
||||
|
||||
wireframeAttributes.set( geometry, attribute );
|
||||
|
||||
}
|
||||
|
||||
function getWireframeAttribute( geometry ) {
|
||||
|
||||
const currentAttribute = wireframeAttributes.get( geometry );
|
||||
|
||||
if ( currentAttribute ) {
|
||||
|
||||
const geometryIndex = geometry.index;
|
||||
|
||||
if ( geometryIndex !== null ) {
|
||||
|
||||
// if the attribute is obsolete, create a new one
|
||||
|
||||
if ( currentAttribute.version < geometryIndex.version ) {
|
||||
|
||||
updateWireframeAttribute( geometry );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
updateWireframeAttribute( geometry );
|
||||
|
||||
}
|
||||
|
||||
return wireframeAttributes.get( geometry );
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
get: get,
|
||||
update: update,
|
||||
|
||||
getWireframeAttribute: getWireframeAttribute
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { WebGLGeometries };
|
||||
100
node_modules/three/src/renderers/webgl/WebGLIndexedBufferRenderer.js
generated
vendored
Normal file
100
node_modules/three/src/renderers/webgl/WebGLIndexedBufferRenderer.js
generated
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
function WebGLIndexedBufferRenderer( gl, extensions, info ) {
|
||||
|
||||
let mode;
|
||||
|
||||
function setMode( value ) {
|
||||
|
||||
mode = value;
|
||||
|
||||
}
|
||||
|
||||
let type, bytesPerElement;
|
||||
|
||||
function setIndex( value ) {
|
||||
|
||||
type = value.type;
|
||||
bytesPerElement = value.bytesPerElement;
|
||||
|
||||
}
|
||||
|
||||
function render( start, count ) {
|
||||
|
||||
gl.drawElements( mode, count, type, start * bytesPerElement );
|
||||
|
||||
info.update( count, mode, 1 );
|
||||
|
||||
}
|
||||
|
||||
function renderInstances( start, count, primcount ) {
|
||||
|
||||
if ( primcount === 0 ) return;
|
||||
|
||||
gl.drawElementsInstanced( mode, count, type, start * bytesPerElement, primcount );
|
||||
|
||||
info.update( count, mode, primcount );
|
||||
|
||||
}
|
||||
|
||||
function renderMultiDraw( starts, counts, drawCount ) {
|
||||
|
||||
if ( drawCount === 0 ) return;
|
||||
|
||||
const extension = extensions.get( 'WEBGL_multi_draw' );
|
||||
extension.multiDrawElementsWEBGL( mode, counts, 0, type, starts, 0, drawCount );
|
||||
|
||||
let elementCount = 0;
|
||||
for ( let i = 0; i < drawCount; i ++ ) {
|
||||
|
||||
elementCount += counts[ i ];
|
||||
|
||||
}
|
||||
|
||||
info.update( elementCount, mode, 1 );
|
||||
|
||||
|
||||
}
|
||||
|
||||
function renderMultiDrawInstances( starts, counts, drawCount, primcount ) {
|
||||
|
||||
if ( drawCount === 0 ) return;
|
||||
|
||||
const extension = extensions.get( 'WEBGL_multi_draw' );
|
||||
|
||||
if ( extension === null ) {
|
||||
|
||||
for ( let i = 0; i < starts.length; i ++ ) {
|
||||
|
||||
renderInstances( starts[ i ] / bytesPerElement, counts[ i ], primcount[ i ] );
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
extension.multiDrawElementsInstancedWEBGL( mode, counts, 0, type, starts, 0, primcount, 0, drawCount );
|
||||
|
||||
let elementCount = 0;
|
||||
for ( let i = 0; i < drawCount; i ++ ) {
|
||||
|
||||
elementCount += counts[ i ] * primcount[ i ];
|
||||
|
||||
}
|
||||
|
||||
info.update( elementCount, mode, 1 );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
this.setMode = setMode;
|
||||
this.setIndex = setIndex;
|
||||
this.render = render;
|
||||
this.renderInstances = renderInstances;
|
||||
this.renderMultiDraw = renderMultiDraw;
|
||||
this.renderMultiDrawInstances = renderMultiDrawInstances;
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { WebGLIndexedBufferRenderer };
|
||||
73
node_modules/three/src/renderers/webgl/WebGLInfo.js
generated
vendored
Normal file
73
node_modules/three/src/renderers/webgl/WebGLInfo.js
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
import { error } from '../../utils.js';
|
||||
|
||||
function WebGLInfo( gl ) {
|
||||
|
||||
const memory = {
|
||||
geometries: 0,
|
||||
textures: 0
|
||||
};
|
||||
|
||||
const render = {
|
||||
frame: 0,
|
||||
calls: 0,
|
||||
triangles: 0,
|
||||
points: 0,
|
||||
lines: 0
|
||||
};
|
||||
|
||||
function update( count, mode, instanceCount ) {
|
||||
|
||||
render.calls ++;
|
||||
|
||||
switch ( mode ) {
|
||||
|
||||
case gl.TRIANGLES:
|
||||
render.triangles += instanceCount * ( count / 3 );
|
||||
break;
|
||||
|
||||
case gl.LINES:
|
||||
render.lines += instanceCount * ( count / 2 );
|
||||
break;
|
||||
|
||||
case gl.LINE_STRIP:
|
||||
render.lines += instanceCount * ( count - 1 );
|
||||
break;
|
||||
|
||||
case gl.LINE_LOOP:
|
||||
render.lines += instanceCount * count;
|
||||
break;
|
||||
|
||||
case gl.POINTS:
|
||||
render.points += instanceCount * count;
|
||||
break;
|
||||
|
||||
default:
|
||||
error( 'WebGLInfo: Unknown draw mode:', mode );
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function reset() {
|
||||
|
||||
render.calls = 0;
|
||||
render.triangles = 0;
|
||||
render.points = 0;
|
||||
render.lines = 0;
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
memory: memory,
|
||||
render: render,
|
||||
programs: null,
|
||||
autoReset: true,
|
||||
reset: reset,
|
||||
update: update
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { WebGLInfo };
|
||||
584
node_modules/three/src/renderers/webgl/WebGLLights.js
generated
vendored
Normal file
584
node_modules/three/src/renderers/webgl/WebGLLights.js
generated
vendored
Normal file
@@ -0,0 +1,584 @@
|
||||
import { Color } from '../../math/Color.js';
|
||||
import { Matrix4 } from '../../math/Matrix4.js';
|
||||
import { Vector2 } from '../../math/Vector2.js';
|
||||
import { Vector3 } from '../../math/Vector3.js';
|
||||
import { UniformsLib } from '../shaders/UniformsLib.js';
|
||||
import { RGFormat } from '../../constants.js';
|
||||
|
||||
function UniformsCache() {
|
||||
|
||||
const lights = {};
|
||||
|
||||
return {
|
||||
|
||||
get: function ( light ) {
|
||||
|
||||
if ( lights[ light.id ] !== undefined ) {
|
||||
|
||||
return lights[ light.id ];
|
||||
|
||||
}
|
||||
|
||||
let uniforms;
|
||||
|
||||
switch ( light.type ) {
|
||||
|
||||
case 'DirectionalLight':
|
||||
uniforms = {
|
||||
direction: new Vector3(),
|
||||
color: new Color()
|
||||
};
|
||||
break;
|
||||
|
||||
case 'SpotLight':
|
||||
uniforms = {
|
||||
position: new Vector3(),
|
||||
direction: new Vector3(),
|
||||
color: new Color(),
|
||||
distance: 0,
|
||||
coneCos: 0,
|
||||
penumbraCos: 0,
|
||||
decay: 0
|
||||
};
|
||||
break;
|
||||
|
||||
case 'PointLight':
|
||||
uniforms = {
|
||||
position: new Vector3(),
|
||||
color: new Color(),
|
||||
distance: 0,
|
||||
decay: 0
|
||||
};
|
||||
break;
|
||||
|
||||
case 'HemisphereLight':
|
||||
uniforms = {
|
||||
direction: new Vector3(),
|
||||
skyColor: new Color(),
|
||||
groundColor: new Color()
|
||||
};
|
||||
break;
|
||||
|
||||
case 'RectAreaLight':
|
||||
uniforms = {
|
||||
color: new Color(),
|
||||
position: new Vector3(),
|
||||
halfWidth: new Vector3(),
|
||||
halfHeight: new Vector3()
|
||||
};
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
lights[ light.id ] = uniforms;
|
||||
|
||||
return uniforms;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
function ShadowUniformsCache() {
|
||||
|
||||
const lights = {};
|
||||
|
||||
return {
|
||||
|
||||
get: function ( light ) {
|
||||
|
||||
if ( lights[ light.id ] !== undefined ) {
|
||||
|
||||
return lights[ light.id ];
|
||||
|
||||
}
|
||||
|
||||
let uniforms;
|
||||
|
||||
switch ( light.type ) {
|
||||
|
||||
case 'DirectionalLight':
|
||||
uniforms = {
|
||||
shadowIntensity: 1,
|
||||
shadowBias: 0,
|
||||
shadowNormalBias: 0,
|
||||
shadowRadius: 1,
|
||||
shadowMapSize: new Vector2()
|
||||
};
|
||||
break;
|
||||
|
||||
case 'SpotLight':
|
||||
uniforms = {
|
||||
shadowIntensity: 1,
|
||||
shadowBias: 0,
|
||||
shadowNormalBias: 0,
|
||||
shadowRadius: 1,
|
||||
shadowMapSize: new Vector2()
|
||||
};
|
||||
break;
|
||||
|
||||
case 'PointLight':
|
||||
uniforms = {
|
||||
shadowIntensity: 1,
|
||||
shadowBias: 0,
|
||||
shadowNormalBias: 0,
|
||||
shadowRadius: 1,
|
||||
shadowMapSize: new Vector2(),
|
||||
shadowCameraNear: 1,
|
||||
shadowCameraFar: 1000
|
||||
};
|
||||
break;
|
||||
|
||||
// TODO (abelnation): set RectAreaLight shadow uniforms
|
||||
|
||||
}
|
||||
|
||||
lights[ light.id ] = uniforms;
|
||||
|
||||
return uniforms;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
let nextVersion = 0;
|
||||
|
||||
function shadowCastingAndTexturingLightsFirst( lightA, lightB ) {
|
||||
|
||||
return ( lightB.castShadow ? 2 : 0 ) - ( lightA.castShadow ? 2 : 0 ) + ( lightB.map ? 1 : 0 ) - ( lightA.map ? 1 : 0 );
|
||||
|
||||
}
|
||||
|
||||
function WebGLLights( extensions ) {
|
||||
|
||||
const cache = new UniformsCache();
|
||||
|
||||
const shadowCache = ShadowUniformsCache();
|
||||
|
||||
const state = {
|
||||
|
||||
version: 0,
|
||||
|
||||
hash: {
|
||||
directionalLength: - 1,
|
||||
pointLength: - 1,
|
||||
spotLength: - 1,
|
||||
rectAreaLength: - 1,
|
||||
hemiLength: - 1,
|
||||
|
||||
numDirectionalShadows: - 1,
|
||||
numPointShadows: - 1,
|
||||
numSpotShadows: - 1,
|
||||
numSpotMaps: - 1,
|
||||
|
||||
numLightProbes: - 1
|
||||
},
|
||||
|
||||
ambient: [ 0, 0, 0 ],
|
||||
probe: [],
|
||||
directional: [],
|
||||
directionalShadow: [],
|
||||
directionalShadowMap: [],
|
||||
directionalShadowMatrix: [],
|
||||
spot: [],
|
||||
spotLightMap: [],
|
||||
spotShadow: [],
|
||||
spotShadowMap: [],
|
||||
spotLightMatrix: [],
|
||||
rectArea: [],
|
||||
rectAreaLTC1: null,
|
||||
rectAreaLTC2: null,
|
||||
point: [],
|
||||
pointShadow: [],
|
||||
pointShadowMap: [],
|
||||
pointShadowMatrix: [],
|
||||
hemi: [],
|
||||
numSpotLightShadowsWithMaps: 0,
|
||||
numLightProbes: 0
|
||||
|
||||
};
|
||||
|
||||
for ( let i = 0; i < 9; i ++ ) state.probe.push( new Vector3() );
|
||||
|
||||
const vector3 = new Vector3();
|
||||
const matrix4 = new Matrix4();
|
||||
const matrix42 = new Matrix4();
|
||||
|
||||
function setup( lights ) {
|
||||
|
||||
let r = 0, g = 0, b = 0;
|
||||
|
||||
for ( let i = 0; i < 9; i ++ ) state.probe[ i ].set( 0, 0, 0 );
|
||||
|
||||
let directionalLength = 0;
|
||||
let pointLength = 0;
|
||||
let spotLength = 0;
|
||||
let rectAreaLength = 0;
|
||||
let hemiLength = 0;
|
||||
|
||||
let numDirectionalShadows = 0;
|
||||
let numPointShadows = 0;
|
||||
let numSpotShadows = 0;
|
||||
let numSpotMaps = 0;
|
||||
let numSpotShadowsWithMaps = 0;
|
||||
|
||||
let numLightProbes = 0;
|
||||
|
||||
// ordering : [shadow casting + map texturing, map texturing, shadow casting, none ]
|
||||
lights.sort( shadowCastingAndTexturingLightsFirst );
|
||||
|
||||
for ( let i = 0, l = lights.length; i < l; i ++ ) {
|
||||
|
||||
const light = lights[ i ];
|
||||
|
||||
const color = light.color;
|
||||
const intensity = light.intensity;
|
||||
const distance = light.distance;
|
||||
|
||||
let shadowMap = null;
|
||||
|
||||
if ( light.shadow && light.shadow.map ) {
|
||||
|
||||
if ( light.shadow.map.texture.format === RGFormat ) {
|
||||
|
||||
// VSM uses color texture with blurred mean/std_dev
|
||||
shadowMap = light.shadow.map.texture;
|
||||
|
||||
} else {
|
||||
|
||||
// Other types use depth texture
|
||||
shadowMap = light.shadow.map.depthTexture || light.shadow.map.texture;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( light.isAmbientLight ) {
|
||||
|
||||
r += color.r * intensity;
|
||||
g += color.g * intensity;
|
||||
b += color.b * intensity;
|
||||
|
||||
} else if ( light.isLightProbe ) {
|
||||
|
||||
for ( let j = 0; j < 9; j ++ ) {
|
||||
|
||||
state.probe[ j ].addScaledVector( light.sh.coefficients[ j ], intensity );
|
||||
|
||||
}
|
||||
|
||||
numLightProbes ++;
|
||||
|
||||
} else if ( light.isDirectionalLight ) {
|
||||
|
||||
const uniforms = cache.get( light );
|
||||
|
||||
uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
|
||||
|
||||
if ( light.castShadow ) {
|
||||
|
||||
const shadow = light.shadow;
|
||||
|
||||
const shadowUniforms = shadowCache.get( light );
|
||||
|
||||
shadowUniforms.shadowIntensity = shadow.intensity;
|
||||
shadowUniforms.shadowBias = shadow.bias;
|
||||
shadowUniforms.shadowNormalBias = shadow.normalBias;
|
||||
shadowUniforms.shadowRadius = shadow.radius;
|
||||
shadowUniforms.shadowMapSize = shadow.mapSize;
|
||||
|
||||
state.directionalShadow[ directionalLength ] = shadowUniforms;
|
||||
state.directionalShadowMap[ directionalLength ] = shadowMap;
|
||||
state.directionalShadowMatrix[ directionalLength ] = light.shadow.matrix;
|
||||
|
||||
numDirectionalShadows ++;
|
||||
|
||||
}
|
||||
|
||||
state.directional[ directionalLength ] = uniforms;
|
||||
|
||||
directionalLength ++;
|
||||
|
||||
} else if ( light.isSpotLight ) {
|
||||
|
||||
const uniforms = cache.get( light );
|
||||
|
||||
uniforms.position.setFromMatrixPosition( light.matrixWorld );
|
||||
|
||||
uniforms.color.copy( color ).multiplyScalar( intensity );
|
||||
uniforms.distance = distance;
|
||||
|
||||
uniforms.coneCos = Math.cos( light.angle );
|
||||
uniforms.penumbraCos = Math.cos( light.angle * ( 1 - light.penumbra ) );
|
||||
uniforms.decay = light.decay;
|
||||
|
||||
state.spot[ spotLength ] = uniforms;
|
||||
|
||||
const shadow = light.shadow;
|
||||
|
||||
if ( light.map ) {
|
||||
|
||||
state.spotLightMap[ numSpotMaps ] = light.map;
|
||||
numSpotMaps ++;
|
||||
|
||||
// make sure the lightMatrix is up to date
|
||||
// TODO : do it if required only
|
||||
shadow.updateMatrices( light );
|
||||
|
||||
if ( light.castShadow ) numSpotShadowsWithMaps ++;
|
||||
|
||||
}
|
||||
|
||||
state.spotLightMatrix[ spotLength ] = shadow.matrix;
|
||||
|
||||
if ( light.castShadow ) {
|
||||
|
||||
const shadowUniforms = shadowCache.get( light );
|
||||
|
||||
shadowUniforms.shadowIntensity = shadow.intensity;
|
||||
shadowUniforms.shadowBias = shadow.bias;
|
||||
shadowUniforms.shadowNormalBias = shadow.normalBias;
|
||||
shadowUniforms.shadowRadius = shadow.radius;
|
||||
shadowUniforms.shadowMapSize = shadow.mapSize;
|
||||
|
||||
state.spotShadow[ spotLength ] = shadowUniforms;
|
||||
state.spotShadowMap[ spotLength ] = shadowMap;
|
||||
|
||||
numSpotShadows ++;
|
||||
|
||||
}
|
||||
|
||||
spotLength ++;
|
||||
|
||||
} else if ( light.isRectAreaLight ) {
|
||||
|
||||
const uniforms = cache.get( light );
|
||||
|
||||
uniforms.color.copy( color ).multiplyScalar( intensity );
|
||||
|
||||
uniforms.halfWidth.set( light.width * 0.5, 0.0, 0.0 );
|
||||
uniforms.halfHeight.set( 0.0, light.height * 0.5, 0.0 );
|
||||
|
||||
state.rectArea[ rectAreaLength ] = uniforms;
|
||||
|
||||
rectAreaLength ++;
|
||||
|
||||
} else if ( light.isPointLight ) {
|
||||
|
||||
const uniforms = cache.get( light );
|
||||
|
||||
uniforms.color.copy( light.color ).multiplyScalar( light.intensity );
|
||||
uniforms.distance = light.distance;
|
||||
uniforms.decay = light.decay;
|
||||
|
||||
if ( light.castShadow ) {
|
||||
|
||||
const shadow = light.shadow;
|
||||
|
||||
const shadowUniforms = shadowCache.get( light );
|
||||
|
||||
shadowUniforms.shadowIntensity = shadow.intensity;
|
||||
shadowUniforms.shadowBias = shadow.bias;
|
||||
shadowUniforms.shadowNormalBias = shadow.normalBias;
|
||||
shadowUniforms.shadowRadius = shadow.radius;
|
||||
shadowUniforms.shadowMapSize = shadow.mapSize;
|
||||
shadowUniforms.shadowCameraNear = shadow.camera.near;
|
||||
shadowUniforms.shadowCameraFar = shadow.camera.far;
|
||||
|
||||
state.pointShadow[ pointLength ] = shadowUniforms;
|
||||
state.pointShadowMap[ pointLength ] = shadowMap;
|
||||
state.pointShadowMatrix[ pointLength ] = light.shadow.matrix;
|
||||
|
||||
numPointShadows ++;
|
||||
|
||||
}
|
||||
|
||||
state.point[ pointLength ] = uniforms;
|
||||
|
||||
pointLength ++;
|
||||
|
||||
} else if ( light.isHemisphereLight ) {
|
||||
|
||||
const uniforms = cache.get( light );
|
||||
|
||||
uniforms.skyColor.copy( light.color ).multiplyScalar( intensity );
|
||||
uniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );
|
||||
|
||||
state.hemi[ hemiLength ] = uniforms;
|
||||
|
||||
hemiLength ++;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( rectAreaLength > 0 ) {
|
||||
|
||||
if ( extensions.has( 'OES_texture_float_linear' ) === true ) {
|
||||
|
||||
state.rectAreaLTC1 = UniformsLib.LTC_FLOAT_1;
|
||||
state.rectAreaLTC2 = UniformsLib.LTC_FLOAT_2;
|
||||
|
||||
} else {
|
||||
|
||||
state.rectAreaLTC1 = UniformsLib.LTC_HALF_1;
|
||||
state.rectAreaLTC2 = UniformsLib.LTC_HALF_2;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
state.ambient[ 0 ] = r;
|
||||
state.ambient[ 1 ] = g;
|
||||
state.ambient[ 2 ] = b;
|
||||
|
||||
const hash = state.hash;
|
||||
|
||||
if ( hash.directionalLength !== directionalLength ||
|
||||
hash.pointLength !== pointLength ||
|
||||
hash.spotLength !== spotLength ||
|
||||
hash.rectAreaLength !== rectAreaLength ||
|
||||
hash.hemiLength !== hemiLength ||
|
||||
hash.numDirectionalShadows !== numDirectionalShadows ||
|
||||
hash.numPointShadows !== numPointShadows ||
|
||||
hash.numSpotShadows !== numSpotShadows ||
|
||||
hash.numSpotMaps !== numSpotMaps ||
|
||||
hash.numLightProbes !== numLightProbes ) {
|
||||
|
||||
state.directional.length = directionalLength;
|
||||
state.spot.length = spotLength;
|
||||
state.rectArea.length = rectAreaLength;
|
||||
state.point.length = pointLength;
|
||||
state.hemi.length = hemiLength;
|
||||
|
||||
state.directionalShadow.length = numDirectionalShadows;
|
||||
state.directionalShadowMap.length = numDirectionalShadows;
|
||||
state.pointShadow.length = numPointShadows;
|
||||
state.pointShadowMap.length = numPointShadows;
|
||||
state.spotShadow.length = numSpotShadows;
|
||||
state.spotShadowMap.length = numSpotShadows;
|
||||
state.directionalShadowMatrix.length = numDirectionalShadows;
|
||||
state.pointShadowMatrix.length = numPointShadows;
|
||||
state.spotLightMatrix.length = numSpotShadows + numSpotMaps - numSpotShadowsWithMaps;
|
||||
state.spotLightMap.length = numSpotMaps;
|
||||
state.numSpotLightShadowsWithMaps = numSpotShadowsWithMaps;
|
||||
state.numLightProbes = numLightProbes;
|
||||
|
||||
hash.directionalLength = directionalLength;
|
||||
hash.pointLength = pointLength;
|
||||
hash.spotLength = spotLength;
|
||||
hash.rectAreaLength = rectAreaLength;
|
||||
hash.hemiLength = hemiLength;
|
||||
|
||||
hash.numDirectionalShadows = numDirectionalShadows;
|
||||
hash.numPointShadows = numPointShadows;
|
||||
hash.numSpotShadows = numSpotShadows;
|
||||
hash.numSpotMaps = numSpotMaps;
|
||||
|
||||
hash.numLightProbes = numLightProbes;
|
||||
|
||||
state.version = nextVersion ++;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function setupView( lights, camera ) {
|
||||
|
||||
let directionalLength = 0;
|
||||
let pointLength = 0;
|
||||
let spotLength = 0;
|
||||
let rectAreaLength = 0;
|
||||
let hemiLength = 0;
|
||||
|
||||
const viewMatrix = camera.matrixWorldInverse;
|
||||
|
||||
for ( let i = 0, l = lights.length; i < l; i ++ ) {
|
||||
|
||||
const light = lights[ i ];
|
||||
|
||||
if ( light.isDirectionalLight ) {
|
||||
|
||||
const uniforms = state.directional[ directionalLength ];
|
||||
|
||||
uniforms.direction.setFromMatrixPosition( light.matrixWorld );
|
||||
vector3.setFromMatrixPosition( light.target.matrixWorld );
|
||||
uniforms.direction.sub( vector3 );
|
||||
uniforms.direction.transformDirection( viewMatrix );
|
||||
|
||||
directionalLength ++;
|
||||
|
||||
} else if ( light.isSpotLight ) {
|
||||
|
||||
const uniforms = state.spot[ spotLength ];
|
||||
|
||||
uniforms.position.setFromMatrixPosition( light.matrixWorld );
|
||||
uniforms.position.applyMatrix4( viewMatrix );
|
||||
|
||||
uniforms.direction.setFromMatrixPosition( light.matrixWorld );
|
||||
vector3.setFromMatrixPosition( light.target.matrixWorld );
|
||||
uniforms.direction.sub( vector3 );
|
||||
uniforms.direction.transformDirection( viewMatrix );
|
||||
|
||||
spotLength ++;
|
||||
|
||||
} else if ( light.isRectAreaLight ) {
|
||||
|
||||
const uniforms = state.rectArea[ rectAreaLength ];
|
||||
|
||||
uniforms.position.setFromMatrixPosition( light.matrixWorld );
|
||||
uniforms.position.applyMatrix4( viewMatrix );
|
||||
|
||||
// extract local rotation of light to derive width/height half vectors
|
||||
matrix42.identity();
|
||||
matrix4.copy( light.matrixWorld );
|
||||
matrix4.premultiply( viewMatrix );
|
||||
matrix42.extractRotation( matrix4 );
|
||||
|
||||
uniforms.halfWidth.set( light.width * 0.5, 0.0, 0.0 );
|
||||
uniforms.halfHeight.set( 0.0, light.height * 0.5, 0.0 );
|
||||
|
||||
uniforms.halfWidth.applyMatrix4( matrix42 );
|
||||
uniforms.halfHeight.applyMatrix4( matrix42 );
|
||||
|
||||
rectAreaLength ++;
|
||||
|
||||
} else if ( light.isPointLight ) {
|
||||
|
||||
const uniforms = state.point[ pointLength ];
|
||||
|
||||
uniforms.position.setFromMatrixPosition( light.matrixWorld );
|
||||
uniforms.position.applyMatrix4( viewMatrix );
|
||||
|
||||
pointLength ++;
|
||||
|
||||
} else if ( light.isHemisphereLight ) {
|
||||
|
||||
const uniforms = state.hemi[ hemiLength ];
|
||||
|
||||
uniforms.direction.setFromMatrixPosition( light.matrixWorld );
|
||||
uniforms.direction.transformDirection( viewMatrix );
|
||||
|
||||
hemiLength ++;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
setup: setup,
|
||||
setupView: setupView,
|
||||
state: state
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { WebGLLights };
|
||||
603
node_modules/three/src/renderers/webgl/WebGLMaterials.js
generated
vendored
Normal file
603
node_modules/three/src/renderers/webgl/WebGLMaterials.js
generated
vendored
Normal file
@@ -0,0 +1,603 @@
|
||||
import { BackSide } from '../../constants.js';
|
||||
import { getUnlitUniformColorSpace } from '../shaders/UniformsUtils.js';
|
||||
import { Euler } from '../../math/Euler.js';
|
||||
import { Matrix4 } from '../../math/Matrix4.js';
|
||||
|
||||
const _e1 = /*@__PURE__*/ new Euler();
|
||||
const _m1 = /*@__PURE__*/ new Matrix4();
|
||||
|
||||
function WebGLMaterials( renderer, properties ) {
|
||||
|
||||
function refreshTransformUniform( map, uniform ) {
|
||||
|
||||
if ( map.matrixAutoUpdate === true ) {
|
||||
|
||||
map.updateMatrix();
|
||||
|
||||
}
|
||||
|
||||
uniform.value.copy( map.matrix );
|
||||
|
||||
}
|
||||
|
||||
function refreshFogUniforms( uniforms, fog ) {
|
||||
|
||||
fog.color.getRGB( uniforms.fogColor.value, getUnlitUniformColorSpace( renderer ) );
|
||||
|
||||
if ( fog.isFog ) {
|
||||
|
||||
uniforms.fogNear.value = fog.near;
|
||||
uniforms.fogFar.value = fog.far;
|
||||
|
||||
} else if ( fog.isFogExp2 ) {
|
||||
|
||||
uniforms.fogDensity.value = fog.density;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function refreshMaterialUniforms( uniforms, material, pixelRatio, height, transmissionRenderTarget ) {
|
||||
|
||||
if ( material.isMeshBasicMaterial ) {
|
||||
|
||||
refreshUniformsCommon( uniforms, material );
|
||||
|
||||
} else if ( material.isMeshLambertMaterial ) {
|
||||
|
||||
refreshUniformsCommon( uniforms, material );
|
||||
|
||||
if ( material.envMap ) {
|
||||
|
||||
uniforms.envMapIntensity.value = material.envMapIntensity;
|
||||
|
||||
}
|
||||
|
||||
} else if ( material.isMeshToonMaterial ) {
|
||||
|
||||
refreshUniformsCommon( uniforms, material );
|
||||
refreshUniformsToon( uniforms, material );
|
||||
|
||||
} else if ( material.isMeshPhongMaterial ) {
|
||||
|
||||
refreshUniformsCommon( uniforms, material );
|
||||
refreshUniformsPhong( uniforms, material );
|
||||
|
||||
if ( material.envMap ) {
|
||||
|
||||
uniforms.envMapIntensity.value = material.envMapIntensity;
|
||||
|
||||
}
|
||||
|
||||
} else if ( material.isMeshStandardMaterial ) {
|
||||
|
||||
refreshUniformsCommon( uniforms, material );
|
||||
refreshUniformsStandard( uniforms, material );
|
||||
|
||||
if ( material.isMeshPhysicalMaterial ) {
|
||||
|
||||
refreshUniformsPhysical( uniforms, material, transmissionRenderTarget );
|
||||
|
||||
}
|
||||
|
||||
} else if ( material.isMeshMatcapMaterial ) {
|
||||
|
||||
refreshUniformsCommon( uniforms, material );
|
||||
refreshUniformsMatcap( uniforms, material );
|
||||
|
||||
} else if ( material.isMeshDepthMaterial ) {
|
||||
|
||||
refreshUniformsCommon( uniforms, material );
|
||||
|
||||
} else if ( material.isMeshDistanceMaterial ) {
|
||||
|
||||
refreshUniformsCommon( uniforms, material );
|
||||
refreshUniformsDistance( uniforms, material );
|
||||
|
||||
} else if ( material.isMeshNormalMaterial ) {
|
||||
|
||||
refreshUniformsCommon( uniforms, material );
|
||||
|
||||
} else if ( material.isLineBasicMaterial ) {
|
||||
|
||||
refreshUniformsLine( uniforms, material );
|
||||
|
||||
if ( material.isLineDashedMaterial ) {
|
||||
|
||||
refreshUniformsDash( uniforms, material );
|
||||
|
||||
}
|
||||
|
||||
} else if ( material.isPointsMaterial ) {
|
||||
|
||||
refreshUniformsPoints( uniforms, material, pixelRatio, height );
|
||||
|
||||
} else if ( material.isSpriteMaterial ) {
|
||||
|
||||
refreshUniformsSprites( uniforms, material );
|
||||
|
||||
} else if ( material.isShadowMaterial ) {
|
||||
|
||||
uniforms.color.value.copy( material.color );
|
||||
uniforms.opacity.value = material.opacity;
|
||||
|
||||
} else if ( material.isShaderMaterial ) {
|
||||
|
||||
material.uniformsNeedUpdate = false; // #15581
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function refreshUniformsCommon( uniforms, material ) {
|
||||
|
||||
uniforms.opacity.value = material.opacity;
|
||||
|
||||
if ( material.color ) {
|
||||
|
||||
uniforms.diffuse.value.copy( material.color );
|
||||
|
||||
}
|
||||
|
||||
if ( material.emissive ) {
|
||||
|
||||
uniforms.emissive.value.copy( material.emissive ).multiplyScalar( material.emissiveIntensity );
|
||||
|
||||
}
|
||||
|
||||
if ( material.map ) {
|
||||
|
||||
uniforms.map.value = material.map;
|
||||
|
||||
refreshTransformUniform( material.map, uniforms.mapTransform );
|
||||
|
||||
}
|
||||
|
||||
if ( material.alphaMap ) {
|
||||
|
||||
uniforms.alphaMap.value = material.alphaMap;
|
||||
|
||||
refreshTransformUniform( material.alphaMap, uniforms.alphaMapTransform );
|
||||
|
||||
}
|
||||
|
||||
if ( material.bumpMap ) {
|
||||
|
||||
uniforms.bumpMap.value = material.bumpMap;
|
||||
|
||||
refreshTransformUniform( material.bumpMap, uniforms.bumpMapTransform );
|
||||
|
||||
uniforms.bumpScale.value = material.bumpScale;
|
||||
|
||||
if ( material.side === BackSide ) {
|
||||
|
||||
uniforms.bumpScale.value *= - 1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( material.normalMap ) {
|
||||
|
||||
uniforms.normalMap.value = material.normalMap;
|
||||
|
||||
refreshTransformUniform( material.normalMap, uniforms.normalMapTransform );
|
||||
|
||||
uniforms.normalScale.value.copy( material.normalScale );
|
||||
|
||||
if ( material.side === BackSide ) {
|
||||
|
||||
uniforms.normalScale.value.negate();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( material.displacementMap ) {
|
||||
|
||||
uniforms.displacementMap.value = material.displacementMap;
|
||||
|
||||
refreshTransformUniform( material.displacementMap, uniforms.displacementMapTransform );
|
||||
|
||||
uniforms.displacementScale.value = material.displacementScale;
|
||||
uniforms.displacementBias.value = material.displacementBias;
|
||||
|
||||
}
|
||||
|
||||
if ( material.emissiveMap ) {
|
||||
|
||||
uniforms.emissiveMap.value = material.emissiveMap;
|
||||
|
||||
refreshTransformUniform( material.emissiveMap, uniforms.emissiveMapTransform );
|
||||
|
||||
}
|
||||
|
||||
if ( material.specularMap ) {
|
||||
|
||||
uniforms.specularMap.value = material.specularMap;
|
||||
|
||||
refreshTransformUniform( material.specularMap, uniforms.specularMapTransform );
|
||||
|
||||
}
|
||||
|
||||
if ( material.alphaTest > 0 ) {
|
||||
|
||||
uniforms.alphaTest.value = material.alphaTest;
|
||||
|
||||
}
|
||||
|
||||
const materialProperties = properties.get( material );
|
||||
|
||||
const envMap = materialProperties.envMap;
|
||||
const envMapRotation = materialProperties.envMapRotation;
|
||||
|
||||
if ( envMap ) {
|
||||
|
||||
uniforms.envMap.value = envMap;
|
||||
|
||||
_e1.copy( envMapRotation );
|
||||
|
||||
// accommodate left-handed frame
|
||||
_e1.x *= - 1; _e1.y *= - 1; _e1.z *= - 1;
|
||||
|
||||
if ( envMap.isCubeTexture && envMap.isRenderTargetTexture === false ) {
|
||||
|
||||
// environment maps which are not cube render targets or PMREMs follow a different convention
|
||||
_e1.y *= - 1;
|
||||
_e1.z *= - 1;
|
||||
|
||||
}
|
||||
|
||||
uniforms.envMapRotation.value.setFromMatrix4( _m1.makeRotationFromEuler( _e1 ) );
|
||||
|
||||
uniforms.flipEnvMap.value = ( envMap.isCubeTexture && envMap.isRenderTargetTexture === false ) ? - 1 : 1;
|
||||
|
||||
uniforms.reflectivity.value = material.reflectivity;
|
||||
uniforms.ior.value = material.ior;
|
||||
uniforms.refractionRatio.value = material.refractionRatio;
|
||||
|
||||
}
|
||||
|
||||
if ( material.lightMap ) {
|
||||
|
||||
uniforms.lightMap.value = material.lightMap;
|
||||
uniforms.lightMapIntensity.value = material.lightMapIntensity;
|
||||
|
||||
refreshTransformUniform( material.lightMap, uniforms.lightMapTransform );
|
||||
|
||||
}
|
||||
|
||||
if ( material.aoMap ) {
|
||||
|
||||
uniforms.aoMap.value = material.aoMap;
|
||||
uniforms.aoMapIntensity.value = material.aoMapIntensity;
|
||||
|
||||
refreshTransformUniform( material.aoMap, uniforms.aoMapTransform );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function refreshUniformsLine( uniforms, material ) {
|
||||
|
||||
uniforms.diffuse.value.copy( material.color );
|
||||
uniforms.opacity.value = material.opacity;
|
||||
|
||||
if ( material.map ) {
|
||||
|
||||
uniforms.map.value = material.map;
|
||||
|
||||
refreshTransformUniform( material.map, uniforms.mapTransform );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function refreshUniformsDash( uniforms, material ) {
|
||||
|
||||
uniforms.dashSize.value = material.dashSize;
|
||||
uniforms.totalSize.value = material.dashSize + material.gapSize;
|
||||
uniforms.scale.value = material.scale;
|
||||
|
||||
}
|
||||
|
||||
function refreshUniformsPoints( uniforms, material, pixelRatio, height ) {
|
||||
|
||||
uniforms.diffuse.value.copy( material.color );
|
||||
uniforms.opacity.value = material.opacity;
|
||||
uniforms.size.value = material.size * pixelRatio;
|
||||
uniforms.scale.value = height * 0.5;
|
||||
|
||||
if ( material.map ) {
|
||||
|
||||
uniforms.map.value = material.map;
|
||||
|
||||
refreshTransformUniform( material.map, uniforms.uvTransform );
|
||||
|
||||
}
|
||||
|
||||
if ( material.alphaMap ) {
|
||||
|
||||
uniforms.alphaMap.value = material.alphaMap;
|
||||
|
||||
refreshTransformUniform( material.alphaMap, uniforms.alphaMapTransform );
|
||||
|
||||
}
|
||||
|
||||
if ( material.alphaTest > 0 ) {
|
||||
|
||||
uniforms.alphaTest.value = material.alphaTest;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function refreshUniformsSprites( uniforms, material ) {
|
||||
|
||||
uniforms.diffuse.value.copy( material.color );
|
||||
uniforms.opacity.value = material.opacity;
|
||||
uniforms.rotation.value = material.rotation;
|
||||
|
||||
if ( material.map ) {
|
||||
|
||||
uniforms.map.value = material.map;
|
||||
|
||||
refreshTransformUniform( material.map, uniforms.mapTransform );
|
||||
|
||||
}
|
||||
|
||||
if ( material.alphaMap ) {
|
||||
|
||||
uniforms.alphaMap.value = material.alphaMap;
|
||||
|
||||
refreshTransformUniform( material.alphaMap, uniforms.alphaMapTransform );
|
||||
|
||||
}
|
||||
|
||||
if ( material.alphaTest > 0 ) {
|
||||
|
||||
uniforms.alphaTest.value = material.alphaTest;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function refreshUniformsPhong( uniforms, material ) {
|
||||
|
||||
uniforms.specular.value.copy( material.specular );
|
||||
uniforms.shininess.value = Math.max( material.shininess, 1e-4 ); // to prevent pow( 0.0, 0.0 )
|
||||
|
||||
}
|
||||
|
||||
function refreshUniformsToon( uniforms, material ) {
|
||||
|
||||
if ( material.gradientMap ) {
|
||||
|
||||
uniforms.gradientMap.value = material.gradientMap;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function refreshUniformsStandard( uniforms, material ) {
|
||||
|
||||
uniforms.metalness.value = material.metalness;
|
||||
|
||||
if ( material.metalnessMap ) {
|
||||
|
||||
uniforms.metalnessMap.value = material.metalnessMap;
|
||||
|
||||
refreshTransformUniform( material.metalnessMap, uniforms.metalnessMapTransform );
|
||||
|
||||
}
|
||||
|
||||
uniforms.roughness.value = material.roughness;
|
||||
|
||||
if ( material.roughnessMap ) {
|
||||
|
||||
uniforms.roughnessMap.value = material.roughnessMap;
|
||||
|
||||
refreshTransformUniform( material.roughnessMap, uniforms.roughnessMapTransform );
|
||||
|
||||
}
|
||||
|
||||
if ( material.envMap ) {
|
||||
|
||||
//uniforms.envMap.value = material.envMap; // part of uniforms common
|
||||
|
||||
uniforms.envMapIntensity.value = material.envMapIntensity;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function refreshUniformsPhysical( uniforms, material, transmissionRenderTarget ) {
|
||||
|
||||
uniforms.ior.value = material.ior; // also part of uniforms common
|
||||
|
||||
if ( material.sheen > 0 ) {
|
||||
|
||||
uniforms.sheenColor.value.copy( material.sheenColor ).multiplyScalar( material.sheen );
|
||||
|
||||
uniforms.sheenRoughness.value = material.sheenRoughness;
|
||||
|
||||
if ( material.sheenColorMap ) {
|
||||
|
||||
uniforms.sheenColorMap.value = material.sheenColorMap;
|
||||
|
||||
refreshTransformUniform( material.sheenColorMap, uniforms.sheenColorMapTransform );
|
||||
|
||||
}
|
||||
|
||||
if ( material.sheenRoughnessMap ) {
|
||||
|
||||
uniforms.sheenRoughnessMap.value = material.sheenRoughnessMap;
|
||||
|
||||
refreshTransformUniform( material.sheenRoughnessMap, uniforms.sheenRoughnessMapTransform );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( material.clearcoat > 0 ) {
|
||||
|
||||
uniforms.clearcoat.value = material.clearcoat;
|
||||
uniforms.clearcoatRoughness.value = material.clearcoatRoughness;
|
||||
|
||||
if ( material.clearcoatMap ) {
|
||||
|
||||
uniforms.clearcoatMap.value = material.clearcoatMap;
|
||||
|
||||
refreshTransformUniform( material.clearcoatMap, uniforms.clearcoatMapTransform );
|
||||
|
||||
}
|
||||
|
||||
if ( material.clearcoatRoughnessMap ) {
|
||||
|
||||
uniforms.clearcoatRoughnessMap.value = material.clearcoatRoughnessMap;
|
||||
|
||||
refreshTransformUniform( material.clearcoatRoughnessMap, uniforms.clearcoatRoughnessMapTransform );
|
||||
|
||||
}
|
||||
|
||||
if ( material.clearcoatNormalMap ) {
|
||||
|
||||
uniforms.clearcoatNormalMap.value = material.clearcoatNormalMap;
|
||||
|
||||
refreshTransformUniform( material.clearcoatNormalMap, uniforms.clearcoatNormalMapTransform );
|
||||
|
||||
uniforms.clearcoatNormalScale.value.copy( material.clearcoatNormalScale );
|
||||
|
||||
if ( material.side === BackSide ) {
|
||||
|
||||
uniforms.clearcoatNormalScale.value.negate();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( material.dispersion > 0 ) {
|
||||
|
||||
uniforms.dispersion.value = material.dispersion;
|
||||
|
||||
}
|
||||
|
||||
if ( material.iridescence > 0 ) {
|
||||
|
||||
uniforms.iridescence.value = material.iridescence;
|
||||
uniforms.iridescenceIOR.value = material.iridescenceIOR;
|
||||
uniforms.iridescenceThicknessMinimum.value = material.iridescenceThicknessRange[ 0 ];
|
||||
uniforms.iridescenceThicknessMaximum.value = material.iridescenceThicknessRange[ 1 ];
|
||||
|
||||
if ( material.iridescenceMap ) {
|
||||
|
||||
uniforms.iridescenceMap.value = material.iridescenceMap;
|
||||
|
||||
refreshTransformUniform( material.iridescenceMap, uniforms.iridescenceMapTransform );
|
||||
|
||||
}
|
||||
|
||||
if ( material.iridescenceThicknessMap ) {
|
||||
|
||||
uniforms.iridescenceThicknessMap.value = material.iridescenceThicknessMap;
|
||||
|
||||
refreshTransformUniform( material.iridescenceThicknessMap, uniforms.iridescenceThicknessMapTransform );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( material.transmission > 0 ) {
|
||||
|
||||
uniforms.transmission.value = material.transmission;
|
||||
uniforms.transmissionSamplerMap.value = transmissionRenderTarget.texture;
|
||||
uniforms.transmissionSamplerSize.value.set( transmissionRenderTarget.width, transmissionRenderTarget.height );
|
||||
|
||||
if ( material.transmissionMap ) {
|
||||
|
||||
uniforms.transmissionMap.value = material.transmissionMap;
|
||||
|
||||
refreshTransformUniform( material.transmissionMap, uniforms.transmissionMapTransform );
|
||||
|
||||
}
|
||||
|
||||
uniforms.thickness.value = material.thickness;
|
||||
|
||||
if ( material.thicknessMap ) {
|
||||
|
||||
uniforms.thicknessMap.value = material.thicknessMap;
|
||||
|
||||
refreshTransformUniform( material.thicknessMap, uniforms.thicknessMapTransform );
|
||||
|
||||
}
|
||||
|
||||
uniforms.attenuationDistance.value = material.attenuationDistance;
|
||||
uniforms.attenuationColor.value.copy( material.attenuationColor );
|
||||
|
||||
}
|
||||
|
||||
if ( material.anisotropy > 0 ) {
|
||||
|
||||
uniforms.anisotropyVector.value.set( material.anisotropy * Math.cos( material.anisotropyRotation ), material.anisotropy * Math.sin( material.anisotropyRotation ) );
|
||||
|
||||
if ( material.anisotropyMap ) {
|
||||
|
||||
uniforms.anisotropyMap.value = material.anisotropyMap;
|
||||
|
||||
refreshTransformUniform( material.anisotropyMap, uniforms.anisotropyMapTransform );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uniforms.specularIntensity.value = material.specularIntensity;
|
||||
uniforms.specularColor.value.copy( material.specularColor );
|
||||
|
||||
if ( material.specularColorMap ) {
|
||||
|
||||
uniforms.specularColorMap.value = material.specularColorMap;
|
||||
|
||||
refreshTransformUniform( material.specularColorMap, uniforms.specularColorMapTransform );
|
||||
|
||||
}
|
||||
|
||||
if ( material.specularIntensityMap ) {
|
||||
|
||||
uniforms.specularIntensityMap.value = material.specularIntensityMap;
|
||||
|
||||
refreshTransformUniform( material.specularIntensityMap, uniforms.specularIntensityMapTransform );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function refreshUniformsMatcap( uniforms, material ) {
|
||||
|
||||
if ( material.matcap ) {
|
||||
|
||||
uniforms.matcap.value = material.matcap;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function refreshUniformsDistance( uniforms, material ) {
|
||||
|
||||
const light = properties.get( material ).light;
|
||||
|
||||
uniforms.referencePosition.value.setFromMatrixPosition( light.matrixWorld );
|
||||
uniforms.nearDistance.value = light.shadow.camera.near;
|
||||
uniforms.farDistance.value = light.shadow.camera.far;
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
refreshFogUniforms: refreshFogUniforms,
|
||||
refreshMaterialUniforms: refreshMaterialUniforms
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
export { WebGLMaterials };
|
||||
168
node_modules/three/src/renderers/webgl/WebGLMorphtargets.js
generated
vendored
Normal file
168
node_modules/three/src/renderers/webgl/WebGLMorphtargets.js
generated
vendored
Normal file
@@ -0,0 +1,168 @@
|
||||
import { FloatType } from '../../constants.js';
|
||||
import { DataArrayTexture } from '../../textures/DataArrayTexture.js';
|
||||
import { Vector4 } from '../../math/Vector4.js';
|
||||
import { Vector2 } from '../../math/Vector2.js';
|
||||
|
||||
function WebGLMorphtargets( gl, capabilities, textures ) {
|
||||
|
||||
const morphTextures = new WeakMap();
|
||||
const morph = new Vector4();
|
||||
|
||||
function update( object, geometry, program ) {
|
||||
|
||||
const objectInfluences = object.morphTargetInfluences;
|
||||
|
||||
// the following encodes morph targets into an array of data textures. Each layer represents a single morph target.
|
||||
|
||||
const morphAttribute = geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color;
|
||||
const morphTargetsCount = ( morphAttribute !== undefined ) ? morphAttribute.length : 0;
|
||||
|
||||
let entry = morphTextures.get( geometry );
|
||||
|
||||
if ( entry === undefined || entry.count !== morphTargetsCount ) {
|
||||
|
||||
if ( entry !== undefined ) entry.texture.dispose();
|
||||
|
||||
const hasMorphPosition = geometry.morphAttributes.position !== undefined;
|
||||
const hasMorphNormals = geometry.morphAttributes.normal !== undefined;
|
||||
const hasMorphColors = geometry.morphAttributes.color !== undefined;
|
||||
|
||||
const morphTargets = geometry.morphAttributes.position || [];
|
||||
const morphNormals = geometry.morphAttributes.normal || [];
|
||||
const morphColors = geometry.morphAttributes.color || [];
|
||||
|
||||
let vertexDataCount = 0;
|
||||
|
||||
if ( hasMorphPosition === true ) vertexDataCount = 1;
|
||||
if ( hasMorphNormals === true ) vertexDataCount = 2;
|
||||
if ( hasMorphColors === true ) vertexDataCount = 3;
|
||||
|
||||
let width = geometry.attributes.position.count * vertexDataCount;
|
||||
let height = 1;
|
||||
|
||||
if ( width > capabilities.maxTextureSize ) {
|
||||
|
||||
height = Math.ceil( width / capabilities.maxTextureSize );
|
||||
width = capabilities.maxTextureSize;
|
||||
|
||||
}
|
||||
|
||||
const buffer = new Float32Array( width * height * 4 * morphTargetsCount );
|
||||
|
||||
const texture = new DataArrayTexture( buffer, width, height, morphTargetsCount );
|
||||
texture.type = FloatType;
|
||||
texture.needsUpdate = true;
|
||||
|
||||
// fill buffer
|
||||
|
||||
const vertexDataStride = vertexDataCount * 4;
|
||||
|
||||
for ( let i = 0; i < morphTargetsCount; i ++ ) {
|
||||
|
||||
const morphTarget = morphTargets[ i ];
|
||||
const morphNormal = morphNormals[ i ];
|
||||
const morphColor = morphColors[ i ];
|
||||
|
||||
const offset = width * height * 4 * i;
|
||||
|
||||
for ( let j = 0; j < morphTarget.count; j ++ ) {
|
||||
|
||||
const stride = j * vertexDataStride;
|
||||
|
||||
if ( hasMorphPosition === true ) {
|
||||
|
||||
morph.fromBufferAttribute( morphTarget, j );
|
||||
|
||||
buffer[ offset + stride + 0 ] = morph.x;
|
||||
buffer[ offset + stride + 1 ] = morph.y;
|
||||
buffer[ offset + stride + 2 ] = morph.z;
|
||||
buffer[ offset + stride + 3 ] = 0;
|
||||
|
||||
}
|
||||
|
||||
if ( hasMorphNormals === true ) {
|
||||
|
||||
morph.fromBufferAttribute( morphNormal, j );
|
||||
|
||||
buffer[ offset + stride + 4 ] = morph.x;
|
||||
buffer[ offset + stride + 5 ] = morph.y;
|
||||
buffer[ offset + stride + 6 ] = morph.z;
|
||||
buffer[ offset + stride + 7 ] = 0;
|
||||
|
||||
}
|
||||
|
||||
if ( hasMorphColors === true ) {
|
||||
|
||||
morph.fromBufferAttribute( morphColor, j );
|
||||
|
||||
buffer[ offset + stride + 8 ] = morph.x;
|
||||
buffer[ offset + stride + 9 ] = morph.y;
|
||||
buffer[ offset + stride + 10 ] = morph.z;
|
||||
buffer[ offset + stride + 11 ] = ( morphColor.itemSize === 4 ) ? morph.w : 1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
entry = {
|
||||
count: morphTargetsCount,
|
||||
texture: texture,
|
||||
size: new Vector2( width, height )
|
||||
};
|
||||
|
||||
morphTextures.set( geometry, entry );
|
||||
|
||||
function disposeTexture() {
|
||||
|
||||
texture.dispose();
|
||||
|
||||
morphTextures.delete( geometry );
|
||||
|
||||
geometry.removeEventListener( 'dispose', disposeTexture );
|
||||
|
||||
}
|
||||
|
||||
geometry.addEventListener( 'dispose', disposeTexture );
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
if ( object.isInstancedMesh === true && object.morphTexture !== null ) {
|
||||
|
||||
program.getUniforms().setValue( gl, 'morphTexture', object.morphTexture, textures );
|
||||
|
||||
} else {
|
||||
|
||||
let morphInfluencesSum = 0;
|
||||
|
||||
for ( let i = 0; i < objectInfluences.length; i ++ ) {
|
||||
|
||||
morphInfluencesSum += objectInfluences[ i ];
|
||||
|
||||
}
|
||||
|
||||
const morphBaseInfluence = geometry.morphTargetsRelative ? 1 : 1 - morphInfluencesSum;
|
||||
|
||||
|
||||
program.getUniforms().setValue( gl, 'morphTargetBaseInfluence', morphBaseInfluence );
|
||||
program.getUniforms().setValue( gl, 'morphTargetInfluences', objectInfluences );
|
||||
|
||||
}
|
||||
|
||||
program.getUniforms().setValue( gl, 'morphTargetsTexture', entry.texture, textures );
|
||||
program.getUniforms().setValue( gl, 'morphTargetsTextureSize', entry.size );
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
update: update
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { WebGLMorphtargets };
|
||||
94
node_modules/three/src/renderers/webgl/WebGLObjects.js
generated
vendored
Normal file
94
node_modules/three/src/renderers/webgl/WebGLObjects.js
generated
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
function WebGLObjects( gl, geometries, attributes, bindingStates, info ) {
|
||||
|
||||
let updateMap = new WeakMap();
|
||||
|
||||
function update( object ) {
|
||||
|
||||
const frame = info.render.frame;
|
||||
|
||||
const geometry = object.geometry;
|
||||
const buffergeometry = geometries.get( object, geometry );
|
||||
|
||||
// Update once per frame
|
||||
|
||||
if ( updateMap.get( buffergeometry ) !== frame ) {
|
||||
|
||||
geometries.update( buffergeometry );
|
||||
|
||||
updateMap.set( buffergeometry, frame );
|
||||
|
||||
}
|
||||
|
||||
if ( object.isInstancedMesh ) {
|
||||
|
||||
if ( object.hasEventListener( 'dispose', onInstancedMeshDispose ) === false ) {
|
||||
|
||||
object.addEventListener( 'dispose', onInstancedMeshDispose );
|
||||
|
||||
}
|
||||
|
||||
if ( updateMap.get( object ) !== frame ) {
|
||||
|
||||
attributes.update( object.instanceMatrix, gl.ARRAY_BUFFER );
|
||||
|
||||
if ( object.instanceColor !== null ) {
|
||||
|
||||
attributes.update( object.instanceColor, gl.ARRAY_BUFFER );
|
||||
|
||||
}
|
||||
|
||||
updateMap.set( object, frame );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( object.isSkinnedMesh ) {
|
||||
|
||||
const skeleton = object.skeleton;
|
||||
|
||||
if ( updateMap.get( skeleton ) !== frame ) {
|
||||
|
||||
skeleton.update();
|
||||
|
||||
updateMap.set( skeleton, frame );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return buffergeometry;
|
||||
|
||||
}
|
||||
|
||||
function dispose() {
|
||||
|
||||
updateMap = new WeakMap();
|
||||
|
||||
}
|
||||
|
||||
function onInstancedMeshDispose( event ) {
|
||||
|
||||
const instancedMesh = event.target;
|
||||
|
||||
instancedMesh.removeEventListener( 'dispose', onInstancedMeshDispose );
|
||||
|
||||
bindingStates.releaseStatesOfObject( instancedMesh );
|
||||
|
||||
attributes.remove( instancedMesh.instanceMatrix );
|
||||
|
||||
if ( instancedMesh.instanceColor !== null ) attributes.remove( instancedMesh.instanceColor );
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
update: update,
|
||||
dispose: dispose
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { WebGLObjects };
|
||||
267
node_modules/three/src/renderers/webgl/WebGLOutput.js
generated
vendored
Normal file
267
node_modules/three/src/renderers/webgl/WebGLOutput.js
generated
vendored
Normal file
@@ -0,0 +1,267 @@
|
||||
import {
|
||||
NoToneMapping,
|
||||
LinearToneMapping,
|
||||
ReinhardToneMapping,
|
||||
CineonToneMapping,
|
||||
ACESFilmicToneMapping,
|
||||
AgXToneMapping,
|
||||
NeutralToneMapping,
|
||||
CustomToneMapping,
|
||||
SRGBTransfer,
|
||||
HalfFloatType
|
||||
} from '../../constants.js';
|
||||
import { BufferGeometry } from '../../core/BufferGeometry.js';
|
||||
import { Float32BufferAttribute } from '../../core/BufferAttribute.js';
|
||||
import { RawShaderMaterial } from '../../materials/RawShaderMaterial.js';
|
||||
import { Mesh } from '../../objects/Mesh.js';
|
||||
import { OrthographicCamera } from '../../cameras/OrthographicCamera.js';
|
||||
import { WebGLRenderTarget } from '../WebGLRenderTarget.js';
|
||||
import { ColorManagement } from '../../math/ColorManagement.js';
|
||||
|
||||
const toneMappingMap = {
|
||||
[ LinearToneMapping ]: 'LINEAR_TONE_MAPPING',
|
||||
[ ReinhardToneMapping ]: 'REINHARD_TONE_MAPPING',
|
||||
[ CineonToneMapping ]: 'CINEON_TONE_MAPPING',
|
||||
[ ACESFilmicToneMapping ]: 'ACES_FILMIC_TONE_MAPPING',
|
||||
[ AgXToneMapping ]: 'AGX_TONE_MAPPING',
|
||||
[ NeutralToneMapping ]: 'NEUTRAL_TONE_MAPPING',
|
||||
[ CustomToneMapping ]: 'CUSTOM_TONE_MAPPING'
|
||||
};
|
||||
|
||||
function WebGLOutput( type, width, height, depth, stencil ) {
|
||||
|
||||
// render targets for scene and post-processing
|
||||
const targetA = new WebGLRenderTarget( width, height, {
|
||||
type: type,
|
||||
depthBuffer: depth,
|
||||
stencilBuffer: stencil
|
||||
} );
|
||||
|
||||
const targetB = new WebGLRenderTarget( width, height, {
|
||||
type: HalfFloatType,
|
||||
depthBuffer: false,
|
||||
stencilBuffer: false
|
||||
} );
|
||||
|
||||
// create fullscreen triangle geometry
|
||||
const geometry = new BufferGeometry();
|
||||
geometry.setAttribute( 'position', new Float32BufferAttribute( [ - 1, 3, 0, - 1, - 1, 0, 3, - 1, 0 ], 3 ) );
|
||||
geometry.setAttribute( 'uv', new Float32BufferAttribute( [ 0, 2, 0, 0, 2, 0 ], 2 ) );
|
||||
|
||||
// create output material with tone mapping support
|
||||
const material = new RawShaderMaterial( {
|
||||
uniforms: {
|
||||
tDiffuse: { value: null }
|
||||
},
|
||||
vertexShader: /* glsl */`
|
||||
precision highp float;
|
||||
|
||||
uniform mat4 modelViewMatrix;
|
||||
uniform mat4 projectionMatrix;
|
||||
|
||||
attribute vec3 position;
|
||||
attribute vec2 uv;
|
||||
|
||||
varying vec2 vUv;
|
||||
|
||||
void main() {
|
||||
vUv = uv;
|
||||
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
|
||||
}`,
|
||||
fragmentShader: /* glsl */`
|
||||
precision highp float;
|
||||
|
||||
uniform sampler2D tDiffuse;
|
||||
|
||||
varying vec2 vUv;
|
||||
|
||||
#include <tonemapping_pars_fragment>
|
||||
#include <colorspace_pars_fragment>
|
||||
|
||||
void main() {
|
||||
gl_FragColor = texture2D( tDiffuse, vUv );
|
||||
|
||||
#ifdef LINEAR_TONE_MAPPING
|
||||
gl_FragColor.rgb = LinearToneMapping( gl_FragColor.rgb );
|
||||
#elif defined( REINHARD_TONE_MAPPING )
|
||||
gl_FragColor.rgb = ReinhardToneMapping( gl_FragColor.rgb );
|
||||
#elif defined( CINEON_TONE_MAPPING )
|
||||
gl_FragColor.rgb = CineonToneMapping( gl_FragColor.rgb );
|
||||
#elif defined( ACES_FILMIC_TONE_MAPPING )
|
||||
gl_FragColor.rgb = ACESFilmicToneMapping( gl_FragColor.rgb );
|
||||
#elif defined( AGX_TONE_MAPPING )
|
||||
gl_FragColor.rgb = AgXToneMapping( gl_FragColor.rgb );
|
||||
#elif defined( NEUTRAL_TONE_MAPPING )
|
||||
gl_FragColor.rgb = NeutralToneMapping( gl_FragColor.rgb );
|
||||
#elif defined( CUSTOM_TONE_MAPPING )
|
||||
gl_FragColor.rgb = CustomToneMapping( gl_FragColor.rgb );
|
||||
#endif
|
||||
|
||||
#ifdef SRGB_TRANSFER
|
||||
gl_FragColor = sRGBTransferOETF( gl_FragColor );
|
||||
#endif
|
||||
}`,
|
||||
depthTest: false,
|
||||
depthWrite: false
|
||||
} );
|
||||
|
||||
const mesh = new Mesh( geometry, material );
|
||||
const camera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );
|
||||
|
||||
let _outputColorSpace = null;
|
||||
let _outputToneMapping = null;
|
||||
let _isCompositing = false;
|
||||
let _savedToneMapping;
|
||||
let _savedRenderTarget = null;
|
||||
let _effects = [];
|
||||
let _hasRenderPass = false;
|
||||
|
||||
this.setSize = function ( width, height ) {
|
||||
|
||||
targetA.setSize( width, height );
|
||||
targetB.setSize( width, height );
|
||||
|
||||
for ( let i = 0; i < _effects.length; i ++ ) {
|
||||
|
||||
const effect = _effects[ i ];
|
||||
if ( effect.setSize ) effect.setSize( width, height );
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
this.setEffects = function ( effects ) {
|
||||
|
||||
_effects = effects;
|
||||
_hasRenderPass = _effects.length > 0 && _effects[ 0 ].isRenderPass === true;
|
||||
|
||||
const width = targetA.width;
|
||||
const height = targetA.height;
|
||||
|
||||
for ( let i = 0; i < _effects.length; i ++ ) {
|
||||
|
||||
const effect = _effects[ i ];
|
||||
if ( effect.setSize ) effect.setSize( width, height );
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
this.begin = function ( renderer, renderTarget ) {
|
||||
|
||||
// Don't begin during compositing phase (post-processing effects call render())
|
||||
if ( _isCompositing ) return false;
|
||||
|
||||
if ( renderer.toneMapping === NoToneMapping && _effects.length === 0 ) return false;
|
||||
|
||||
_savedRenderTarget = renderTarget;
|
||||
|
||||
// resize internal buffers to match render target (e.g. XR resolution)
|
||||
if ( renderTarget !== null ) {
|
||||
|
||||
const width = renderTarget.width;
|
||||
const height = renderTarget.height;
|
||||
|
||||
if ( targetA.width !== width || targetA.height !== height ) {
|
||||
|
||||
this.setSize( width, height );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// if first effect is a RenderPass, it will set its own render target
|
||||
if ( _hasRenderPass === false ) {
|
||||
|
||||
renderer.setRenderTarget( targetA );
|
||||
|
||||
}
|
||||
|
||||
// disable tone mapping during render - it will be applied in end()
|
||||
_savedToneMapping = renderer.toneMapping;
|
||||
renderer.toneMapping = NoToneMapping;
|
||||
|
||||
return true;
|
||||
|
||||
};
|
||||
|
||||
this.hasRenderPass = function () {
|
||||
|
||||
return _hasRenderPass;
|
||||
|
||||
};
|
||||
|
||||
this.end = function ( renderer, deltaTime ) {
|
||||
|
||||
// restore tone mapping
|
||||
renderer.toneMapping = _savedToneMapping;
|
||||
|
||||
_isCompositing = true;
|
||||
|
||||
// run post-processing effects
|
||||
let readBuffer = targetA;
|
||||
let writeBuffer = targetB;
|
||||
|
||||
for ( let i = 0; i < _effects.length; i ++ ) {
|
||||
|
||||
const effect = _effects[ i ];
|
||||
|
||||
if ( effect.enabled === false ) continue;
|
||||
|
||||
effect.render( renderer, writeBuffer, readBuffer, deltaTime );
|
||||
|
||||
if ( effect.needsSwap !== false ) {
|
||||
|
||||
const temp = readBuffer;
|
||||
readBuffer = writeBuffer;
|
||||
writeBuffer = temp;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// update output material defines if settings changed
|
||||
if ( _outputColorSpace !== renderer.outputColorSpace || _outputToneMapping !== renderer.toneMapping ) {
|
||||
|
||||
_outputColorSpace = renderer.outputColorSpace;
|
||||
_outputToneMapping = renderer.toneMapping;
|
||||
|
||||
material.defines = {};
|
||||
|
||||
if ( ColorManagement.getTransfer( _outputColorSpace ) === SRGBTransfer ) material.defines.SRGB_TRANSFER = '';
|
||||
|
||||
const toneMapping = toneMappingMap[ _outputToneMapping ];
|
||||
if ( toneMapping ) material.defines[ toneMapping ] = '';
|
||||
|
||||
material.needsUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
// final output to canvas (or XR render target)
|
||||
material.uniforms.tDiffuse.value = readBuffer.texture;
|
||||
renderer.setRenderTarget( _savedRenderTarget );
|
||||
renderer.render( mesh, camera );
|
||||
|
||||
_savedRenderTarget = null;
|
||||
_isCompositing = false;
|
||||
|
||||
};
|
||||
|
||||
this.isCompositing = function () {
|
||||
|
||||
return _isCompositing;
|
||||
|
||||
};
|
||||
|
||||
this.dispose = function () {
|
||||
|
||||
targetA.dispose();
|
||||
targetB.dispose();
|
||||
geometry.dispose();
|
||||
material.dispose();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
export { WebGLOutput };
|
||||
1027
node_modules/three/src/renderers/webgl/WebGLProgram.js
generated
vendored
Normal file
1027
node_modules/three/src/renderers/webgl/WebGLProgram.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
663
node_modules/three/src/renderers/webgl/WebGLPrograms.js
generated
vendored
Normal file
663
node_modules/three/src/renderers/webgl/WebGLPrograms.js
generated
vendored
Normal file
@@ -0,0 +1,663 @@
|
||||
import { BackSide, DoubleSide, CubeUVReflectionMapping, ObjectSpaceNormalMap, TangentSpaceNormalMap, NoToneMapping, NormalBlending, LinearSRGBColorSpace, SRGBTransfer } from '../../constants.js';
|
||||
import { Layers } from '../../core/Layers.js';
|
||||
import { WebGLProgram } from './WebGLProgram.js';
|
||||
import { WebGLShaderCache } from './WebGLShaderCache.js';
|
||||
import { ShaderLib } from '../shaders/ShaderLib.js';
|
||||
import { UniformsUtils } from '../shaders/UniformsUtils.js';
|
||||
import { ColorManagement } from '../../math/ColorManagement.js';
|
||||
import { warn } from '../../utils.js';
|
||||
|
||||
function WebGLPrograms( renderer, environments, extensions, capabilities, bindingStates, clipping ) {
|
||||
|
||||
const _programLayers = new Layers();
|
||||
const _customShaders = new WebGLShaderCache();
|
||||
const _activeChannels = new Set();
|
||||
const programs = [];
|
||||
const programsMap = new Map();
|
||||
|
||||
const logarithmicDepthBuffer = capabilities.logarithmicDepthBuffer;
|
||||
|
||||
let precision = capabilities.precision;
|
||||
|
||||
const shaderIDs = {
|
||||
MeshDepthMaterial: 'depth',
|
||||
MeshDistanceMaterial: 'distance',
|
||||
MeshNormalMaterial: 'normal',
|
||||
MeshBasicMaterial: 'basic',
|
||||
MeshLambertMaterial: 'lambert',
|
||||
MeshPhongMaterial: 'phong',
|
||||
MeshToonMaterial: 'toon',
|
||||
MeshStandardMaterial: 'physical',
|
||||
MeshPhysicalMaterial: 'physical',
|
||||
MeshMatcapMaterial: 'matcap',
|
||||
LineBasicMaterial: 'basic',
|
||||
LineDashedMaterial: 'dashed',
|
||||
PointsMaterial: 'points',
|
||||
ShadowMaterial: 'shadow',
|
||||
SpriteMaterial: 'sprite'
|
||||
};
|
||||
|
||||
function getChannel( value ) {
|
||||
|
||||
_activeChannels.add( value );
|
||||
|
||||
if ( value === 0 ) return 'uv';
|
||||
|
||||
return `uv${ value }`;
|
||||
|
||||
}
|
||||
|
||||
function getParameters( material, lights, shadows, scene, object ) {
|
||||
|
||||
const fog = scene.fog;
|
||||
const geometry = object.geometry;
|
||||
const environment = ( material.isMeshStandardMaterial || material.isMeshLambertMaterial || material.isMeshPhongMaterial ) ? scene.environment : null;
|
||||
|
||||
const usePMREM = material.isMeshStandardMaterial || ( material.isMeshLambertMaterial && ! material.envMap ) || ( material.isMeshPhongMaterial && ! material.envMap );
|
||||
const envMap = environments.get( material.envMap || environment, usePMREM );
|
||||
const envMapCubeUVHeight = ( !! envMap ) && ( envMap.mapping === CubeUVReflectionMapping ) ? envMap.image.height : null;
|
||||
|
||||
const shaderID = shaderIDs[ material.type ];
|
||||
|
||||
// heuristics to create shader parameters according to lights in the scene
|
||||
// (not to blow over maxLights budget)
|
||||
|
||||
if ( material.precision !== null ) {
|
||||
|
||||
precision = capabilities.getMaxPrecision( material.precision );
|
||||
|
||||
if ( precision !== material.precision ) {
|
||||
|
||||
warn( 'WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.' );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
const morphAttribute = geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color;
|
||||
const morphTargetsCount = ( morphAttribute !== undefined ) ? morphAttribute.length : 0;
|
||||
|
||||
let morphTextureStride = 0;
|
||||
|
||||
if ( geometry.morphAttributes.position !== undefined ) morphTextureStride = 1;
|
||||
if ( geometry.morphAttributes.normal !== undefined ) morphTextureStride = 2;
|
||||
if ( geometry.morphAttributes.color !== undefined ) morphTextureStride = 3;
|
||||
|
||||
//
|
||||
|
||||
let vertexShader, fragmentShader;
|
||||
let customVertexShaderID, customFragmentShaderID;
|
||||
|
||||
if ( shaderID ) {
|
||||
|
||||
const shader = ShaderLib[ shaderID ];
|
||||
|
||||
vertexShader = shader.vertexShader;
|
||||
fragmentShader = shader.fragmentShader;
|
||||
|
||||
} else {
|
||||
|
||||
vertexShader = material.vertexShader;
|
||||
fragmentShader = material.fragmentShader;
|
||||
|
||||
_customShaders.update( material );
|
||||
|
||||
customVertexShaderID = _customShaders.getVertexShaderID( material );
|
||||
customFragmentShaderID = _customShaders.getFragmentShaderID( material );
|
||||
|
||||
}
|
||||
|
||||
const currentRenderTarget = renderer.getRenderTarget();
|
||||
const reversedDepthBuffer = renderer.state.buffers.depth.getReversed();
|
||||
|
||||
const IS_INSTANCEDMESH = object.isInstancedMesh === true;
|
||||
const IS_BATCHEDMESH = object.isBatchedMesh === true;
|
||||
|
||||
const HAS_MAP = !! material.map;
|
||||
const HAS_MATCAP = !! material.matcap;
|
||||
const HAS_ENVMAP = !! envMap;
|
||||
const HAS_AOMAP = !! material.aoMap;
|
||||
const HAS_LIGHTMAP = !! material.lightMap;
|
||||
const HAS_BUMPMAP = !! material.bumpMap;
|
||||
const HAS_NORMALMAP = !! material.normalMap;
|
||||
const HAS_DISPLACEMENTMAP = !! material.displacementMap;
|
||||
const HAS_EMISSIVEMAP = !! material.emissiveMap;
|
||||
|
||||
const HAS_METALNESSMAP = !! material.metalnessMap;
|
||||
const HAS_ROUGHNESSMAP = !! material.roughnessMap;
|
||||
|
||||
const HAS_ANISOTROPY = material.anisotropy > 0;
|
||||
const HAS_CLEARCOAT = material.clearcoat > 0;
|
||||
const HAS_DISPERSION = material.dispersion > 0;
|
||||
const HAS_IRIDESCENCE = material.iridescence > 0;
|
||||
const HAS_SHEEN = material.sheen > 0;
|
||||
const HAS_TRANSMISSION = material.transmission > 0;
|
||||
|
||||
const HAS_ANISOTROPYMAP = HAS_ANISOTROPY && !! material.anisotropyMap;
|
||||
|
||||
const HAS_CLEARCOATMAP = HAS_CLEARCOAT && !! material.clearcoatMap;
|
||||
const HAS_CLEARCOAT_NORMALMAP = HAS_CLEARCOAT && !! material.clearcoatNormalMap;
|
||||
const HAS_CLEARCOAT_ROUGHNESSMAP = HAS_CLEARCOAT && !! material.clearcoatRoughnessMap;
|
||||
|
||||
const HAS_IRIDESCENCEMAP = HAS_IRIDESCENCE && !! material.iridescenceMap;
|
||||
const HAS_IRIDESCENCE_THICKNESSMAP = HAS_IRIDESCENCE && !! material.iridescenceThicknessMap;
|
||||
|
||||
const HAS_SHEEN_COLORMAP = HAS_SHEEN && !! material.sheenColorMap;
|
||||
const HAS_SHEEN_ROUGHNESSMAP = HAS_SHEEN && !! material.sheenRoughnessMap;
|
||||
|
||||
const HAS_SPECULARMAP = !! material.specularMap;
|
||||
const HAS_SPECULAR_COLORMAP = !! material.specularColorMap;
|
||||
const HAS_SPECULAR_INTENSITYMAP = !! material.specularIntensityMap;
|
||||
|
||||
const HAS_TRANSMISSIONMAP = HAS_TRANSMISSION && !! material.transmissionMap;
|
||||
const HAS_THICKNESSMAP = HAS_TRANSMISSION && !! material.thicknessMap;
|
||||
|
||||
const HAS_GRADIENTMAP = !! material.gradientMap;
|
||||
|
||||
const HAS_ALPHAMAP = !! material.alphaMap;
|
||||
|
||||
const HAS_ALPHATEST = material.alphaTest > 0;
|
||||
|
||||
const HAS_ALPHAHASH = !! material.alphaHash;
|
||||
|
||||
const HAS_EXTENSIONS = !! material.extensions;
|
||||
|
||||
let toneMapping = NoToneMapping;
|
||||
|
||||
if ( material.toneMapped ) {
|
||||
|
||||
if ( currentRenderTarget === null || currentRenderTarget.isXRRenderTarget === true ) {
|
||||
|
||||
toneMapping = renderer.toneMapping;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const parameters = {
|
||||
|
||||
shaderID: shaderID,
|
||||
shaderType: material.type,
|
||||
shaderName: material.name,
|
||||
|
||||
vertexShader: vertexShader,
|
||||
fragmentShader: fragmentShader,
|
||||
defines: material.defines,
|
||||
|
||||
customVertexShaderID: customVertexShaderID,
|
||||
customFragmentShaderID: customFragmentShaderID,
|
||||
|
||||
isRawShaderMaterial: material.isRawShaderMaterial === true,
|
||||
glslVersion: material.glslVersion,
|
||||
|
||||
precision: precision,
|
||||
|
||||
batching: IS_BATCHEDMESH,
|
||||
batchingColor: IS_BATCHEDMESH && object._colorsTexture !== null,
|
||||
instancing: IS_INSTANCEDMESH,
|
||||
instancingColor: IS_INSTANCEDMESH && object.instanceColor !== null,
|
||||
instancingMorph: IS_INSTANCEDMESH && object.morphTexture !== null,
|
||||
|
||||
outputColorSpace: ( currentRenderTarget === null ) ? renderer.outputColorSpace : ( currentRenderTarget.isXRRenderTarget === true ? currentRenderTarget.texture.colorSpace : LinearSRGBColorSpace ),
|
||||
alphaToCoverage: !! material.alphaToCoverage,
|
||||
|
||||
map: HAS_MAP,
|
||||
matcap: HAS_MATCAP,
|
||||
envMap: HAS_ENVMAP,
|
||||
envMapMode: HAS_ENVMAP && envMap.mapping,
|
||||
envMapCubeUVHeight: envMapCubeUVHeight,
|
||||
aoMap: HAS_AOMAP,
|
||||
lightMap: HAS_LIGHTMAP,
|
||||
bumpMap: HAS_BUMPMAP,
|
||||
normalMap: HAS_NORMALMAP,
|
||||
displacementMap: HAS_DISPLACEMENTMAP,
|
||||
emissiveMap: HAS_EMISSIVEMAP,
|
||||
|
||||
normalMapObjectSpace: HAS_NORMALMAP && material.normalMapType === ObjectSpaceNormalMap,
|
||||
normalMapTangentSpace: HAS_NORMALMAP && material.normalMapType === TangentSpaceNormalMap,
|
||||
|
||||
metalnessMap: HAS_METALNESSMAP,
|
||||
roughnessMap: HAS_ROUGHNESSMAP,
|
||||
|
||||
anisotropy: HAS_ANISOTROPY,
|
||||
anisotropyMap: HAS_ANISOTROPYMAP,
|
||||
|
||||
clearcoat: HAS_CLEARCOAT,
|
||||
clearcoatMap: HAS_CLEARCOATMAP,
|
||||
clearcoatNormalMap: HAS_CLEARCOAT_NORMALMAP,
|
||||
clearcoatRoughnessMap: HAS_CLEARCOAT_ROUGHNESSMAP,
|
||||
|
||||
dispersion: HAS_DISPERSION,
|
||||
|
||||
iridescence: HAS_IRIDESCENCE,
|
||||
iridescenceMap: HAS_IRIDESCENCEMAP,
|
||||
iridescenceThicknessMap: HAS_IRIDESCENCE_THICKNESSMAP,
|
||||
|
||||
sheen: HAS_SHEEN,
|
||||
sheenColorMap: HAS_SHEEN_COLORMAP,
|
||||
sheenRoughnessMap: HAS_SHEEN_ROUGHNESSMAP,
|
||||
|
||||
specularMap: HAS_SPECULARMAP,
|
||||
specularColorMap: HAS_SPECULAR_COLORMAP,
|
||||
specularIntensityMap: HAS_SPECULAR_INTENSITYMAP,
|
||||
|
||||
transmission: HAS_TRANSMISSION,
|
||||
transmissionMap: HAS_TRANSMISSIONMAP,
|
||||
thicknessMap: HAS_THICKNESSMAP,
|
||||
|
||||
gradientMap: HAS_GRADIENTMAP,
|
||||
|
||||
opaque: material.transparent === false && material.blending === NormalBlending && material.alphaToCoverage === false,
|
||||
|
||||
alphaMap: HAS_ALPHAMAP,
|
||||
alphaTest: HAS_ALPHATEST,
|
||||
alphaHash: HAS_ALPHAHASH,
|
||||
|
||||
combine: material.combine,
|
||||
|
||||
//
|
||||
|
||||
mapUv: HAS_MAP && getChannel( material.map.channel ),
|
||||
aoMapUv: HAS_AOMAP && getChannel( material.aoMap.channel ),
|
||||
lightMapUv: HAS_LIGHTMAP && getChannel( material.lightMap.channel ),
|
||||
bumpMapUv: HAS_BUMPMAP && getChannel( material.bumpMap.channel ),
|
||||
normalMapUv: HAS_NORMALMAP && getChannel( material.normalMap.channel ),
|
||||
displacementMapUv: HAS_DISPLACEMENTMAP && getChannel( material.displacementMap.channel ),
|
||||
emissiveMapUv: HAS_EMISSIVEMAP && getChannel( material.emissiveMap.channel ),
|
||||
|
||||
metalnessMapUv: HAS_METALNESSMAP && getChannel( material.metalnessMap.channel ),
|
||||
roughnessMapUv: HAS_ROUGHNESSMAP && getChannel( material.roughnessMap.channel ),
|
||||
|
||||
anisotropyMapUv: HAS_ANISOTROPYMAP && getChannel( material.anisotropyMap.channel ),
|
||||
|
||||
clearcoatMapUv: HAS_CLEARCOATMAP && getChannel( material.clearcoatMap.channel ),
|
||||
clearcoatNormalMapUv: HAS_CLEARCOAT_NORMALMAP && getChannel( material.clearcoatNormalMap.channel ),
|
||||
clearcoatRoughnessMapUv: HAS_CLEARCOAT_ROUGHNESSMAP && getChannel( material.clearcoatRoughnessMap.channel ),
|
||||
|
||||
iridescenceMapUv: HAS_IRIDESCENCEMAP && getChannel( material.iridescenceMap.channel ),
|
||||
iridescenceThicknessMapUv: HAS_IRIDESCENCE_THICKNESSMAP && getChannel( material.iridescenceThicknessMap.channel ),
|
||||
|
||||
sheenColorMapUv: HAS_SHEEN_COLORMAP && getChannel( material.sheenColorMap.channel ),
|
||||
sheenRoughnessMapUv: HAS_SHEEN_ROUGHNESSMAP && getChannel( material.sheenRoughnessMap.channel ),
|
||||
|
||||
specularMapUv: HAS_SPECULARMAP && getChannel( material.specularMap.channel ),
|
||||
specularColorMapUv: HAS_SPECULAR_COLORMAP && getChannel( material.specularColorMap.channel ),
|
||||
specularIntensityMapUv: HAS_SPECULAR_INTENSITYMAP && getChannel( material.specularIntensityMap.channel ),
|
||||
|
||||
transmissionMapUv: HAS_TRANSMISSIONMAP && getChannel( material.transmissionMap.channel ),
|
||||
thicknessMapUv: HAS_THICKNESSMAP && getChannel( material.thicknessMap.channel ),
|
||||
|
||||
alphaMapUv: HAS_ALPHAMAP && getChannel( material.alphaMap.channel ),
|
||||
|
||||
//
|
||||
|
||||
vertexTangents: !! geometry.attributes.tangent && ( HAS_NORMALMAP || HAS_ANISOTROPY ),
|
||||
vertexColors: material.vertexColors,
|
||||
vertexAlphas: material.vertexColors === true && !! geometry.attributes.color && geometry.attributes.color.itemSize === 4,
|
||||
|
||||
pointsUvs: object.isPoints === true && !! geometry.attributes.uv && ( HAS_MAP || HAS_ALPHAMAP ),
|
||||
|
||||
fog: !! fog,
|
||||
useFog: material.fog === true,
|
||||
fogExp2: ( !! fog && fog.isFogExp2 ),
|
||||
|
||||
flatShading: material.wireframe === false && (
|
||||
material.flatShading === true ||
|
||||
( geometry.attributes.normal === undefined && HAS_NORMALMAP === false &&
|
||||
( material.isMeshLambertMaterial || material.isMeshPhongMaterial || material.isMeshStandardMaterial || material.isMeshPhysicalMaterial )
|
||||
)
|
||||
),
|
||||
|
||||
sizeAttenuation: material.sizeAttenuation === true,
|
||||
logarithmicDepthBuffer: logarithmicDepthBuffer,
|
||||
reversedDepthBuffer: reversedDepthBuffer,
|
||||
|
||||
skinning: object.isSkinnedMesh === true,
|
||||
|
||||
morphTargets: geometry.morphAttributes.position !== undefined,
|
||||
morphNormals: geometry.morphAttributes.normal !== undefined,
|
||||
morphColors: geometry.morphAttributes.color !== undefined,
|
||||
morphTargetsCount: morphTargetsCount,
|
||||
morphTextureStride: morphTextureStride,
|
||||
|
||||
numDirLights: lights.directional.length,
|
||||
numPointLights: lights.point.length,
|
||||
numSpotLights: lights.spot.length,
|
||||
numSpotLightMaps: lights.spotLightMap.length,
|
||||
numRectAreaLights: lights.rectArea.length,
|
||||
numHemiLights: lights.hemi.length,
|
||||
|
||||
numDirLightShadows: lights.directionalShadowMap.length,
|
||||
numPointLightShadows: lights.pointShadowMap.length,
|
||||
numSpotLightShadows: lights.spotShadowMap.length,
|
||||
numSpotLightShadowsWithMaps: lights.numSpotLightShadowsWithMaps,
|
||||
|
||||
numLightProbes: lights.numLightProbes,
|
||||
|
||||
numClippingPlanes: clipping.numPlanes,
|
||||
numClipIntersection: clipping.numIntersection,
|
||||
|
||||
dithering: material.dithering,
|
||||
|
||||
shadowMapEnabled: renderer.shadowMap.enabled && shadows.length > 0,
|
||||
shadowMapType: renderer.shadowMap.type,
|
||||
|
||||
toneMapping: toneMapping,
|
||||
|
||||
decodeVideoTexture: HAS_MAP && ( material.map.isVideoTexture === true ) && ( ColorManagement.getTransfer( material.map.colorSpace ) === SRGBTransfer ),
|
||||
decodeVideoTextureEmissive: HAS_EMISSIVEMAP && ( material.emissiveMap.isVideoTexture === true ) && ( ColorManagement.getTransfer( material.emissiveMap.colorSpace ) === SRGBTransfer ),
|
||||
|
||||
premultipliedAlpha: material.premultipliedAlpha,
|
||||
|
||||
doubleSided: material.side === DoubleSide,
|
||||
flipSided: material.side === BackSide,
|
||||
|
||||
useDepthPacking: material.depthPacking >= 0,
|
||||
depthPacking: material.depthPacking || 0,
|
||||
|
||||
index0AttributeName: material.index0AttributeName,
|
||||
|
||||
extensionClipCullDistance: HAS_EXTENSIONS && material.extensions.clipCullDistance === true && extensions.has( 'WEBGL_clip_cull_distance' ),
|
||||
extensionMultiDraw: ( HAS_EXTENSIONS && material.extensions.multiDraw === true || IS_BATCHEDMESH ) && extensions.has( 'WEBGL_multi_draw' ),
|
||||
|
||||
rendererExtensionParallelShaderCompile: extensions.has( 'KHR_parallel_shader_compile' ),
|
||||
|
||||
customProgramCacheKey: material.customProgramCacheKey()
|
||||
|
||||
};
|
||||
|
||||
// the usage of getChannel() determines the active texture channels for this shader
|
||||
|
||||
parameters.vertexUv1s = _activeChannels.has( 1 );
|
||||
parameters.vertexUv2s = _activeChannels.has( 2 );
|
||||
parameters.vertexUv3s = _activeChannels.has( 3 );
|
||||
|
||||
_activeChannels.clear();
|
||||
|
||||
return parameters;
|
||||
|
||||
}
|
||||
|
||||
function getProgramCacheKey( parameters ) {
|
||||
|
||||
const array = [];
|
||||
|
||||
if ( parameters.shaderID ) {
|
||||
|
||||
array.push( parameters.shaderID );
|
||||
|
||||
} else {
|
||||
|
||||
array.push( parameters.customVertexShaderID );
|
||||
array.push( parameters.customFragmentShaderID );
|
||||
|
||||
}
|
||||
|
||||
if ( parameters.defines !== undefined ) {
|
||||
|
||||
for ( const name in parameters.defines ) {
|
||||
|
||||
array.push( name );
|
||||
array.push( parameters.defines[ name ] );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( parameters.isRawShaderMaterial === false ) {
|
||||
|
||||
getProgramCacheKeyParameters( array, parameters );
|
||||
getProgramCacheKeyBooleans( array, parameters );
|
||||
array.push( renderer.outputColorSpace );
|
||||
|
||||
}
|
||||
|
||||
array.push( parameters.customProgramCacheKey );
|
||||
|
||||
return array.join();
|
||||
|
||||
}
|
||||
|
||||
function getProgramCacheKeyParameters( array, parameters ) {
|
||||
|
||||
array.push( parameters.precision );
|
||||
array.push( parameters.outputColorSpace );
|
||||
array.push( parameters.envMapMode );
|
||||
array.push( parameters.envMapCubeUVHeight );
|
||||
array.push( parameters.mapUv );
|
||||
array.push( parameters.alphaMapUv );
|
||||
array.push( parameters.lightMapUv );
|
||||
array.push( parameters.aoMapUv );
|
||||
array.push( parameters.bumpMapUv );
|
||||
array.push( parameters.normalMapUv );
|
||||
array.push( parameters.displacementMapUv );
|
||||
array.push( parameters.emissiveMapUv );
|
||||
array.push( parameters.metalnessMapUv );
|
||||
array.push( parameters.roughnessMapUv );
|
||||
array.push( parameters.anisotropyMapUv );
|
||||
array.push( parameters.clearcoatMapUv );
|
||||
array.push( parameters.clearcoatNormalMapUv );
|
||||
array.push( parameters.clearcoatRoughnessMapUv );
|
||||
array.push( parameters.iridescenceMapUv );
|
||||
array.push( parameters.iridescenceThicknessMapUv );
|
||||
array.push( parameters.sheenColorMapUv );
|
||||
array.push( parameters.sheenRoughnessMapUv );
|
||||
array.push( parameters.specularMapUv );
|
||||
array.push( parameters.specularColorMapUv );
|
||||
array.push( parameters.specularIntensityMapUv );
|
||||
array.push( parameters.transmissionMapUv );
|
||||
array.push( parameters.thicknessMapUv );
|
||||
array.push( parameters.combine );
|
||||
array.push( parameters.fogExp2 );
|
||||
array.push( parameters.sizeAttenuation );
|
||||
array.push( parameters.morphTargetsCount );
|
||||
array.push( parameters.morphAttributeCount );
|
||||
array.push( parameters.numDirLights );
|
||||
array.push( parameters.numPointLights );
|
||||
array.push( parameters.numSpotLights );
|
||||
array.push( parameters.numSpotLightMaps );
|
||||
array.push( parameters.numHemiLights );
|
||||
array.push( parameters.numRectAreaLights );
|
||||
array.push( parameters.numDirLightShadows );
|
||||
array.push( parameters.numPointLightShadows );
|
||||
array.push( parameters.numSpotLightShadows );
|
||||
array.push( parameters.numSpotLightShadowsWithMaps );
|
||||
array.push( parameters.numLightProbes );
|
||||
array.push( parameters.shadowMapType );
|
||||
array.push( parameters.toneMapping );
|
||||
array.push( parameters.numClippingPlanes );
|
||||
array.push( parameters.numClipIntersection );
|
||||
array.push( parameters.depthPacking );
|
||||
|
||||
}
|
||||
|
||||
function getProgramCacheKeyBooleans( array, parameters ) {
|
||||
|
||||
_programLayers.disableAll();
|
||||
|
||||
if ( parameters.instancing )
|
||||
_programLayers.enable( 0 );
|
||||
if ( parameters.instancingColor )
|
||||
_programLayers.enable( 1 );
|
||||
if ( parameters.instancingMorph )
|
||||
_programLayers.enable( 2 );
|
||||
if ( parameters.matcap )
|
||||
_programLayers.enable( 3 );
|
||||
if ( parameters.envMap )
|
||||
_programLayers.enable( 4 );
|
||||
if ( parameters.normalMapObjectSpace )
|
||||
_programLayers.enable( 5 );
|
||||
if ( parameters.normalMapTangentSpace )
|
||||
_programLayers.enable( 6 );
|
||||
if ( parameters.clearcoat )
|
||||
_programLayers.enable( 7 );
|
||||
if ( parameters.iridescence )
|
||||
_programLayers.enable( 8 );
|
||||
if ( parameters.alphaTest )
|
||||
_programLayers.enable( 9 );
|
||||
if ( parameters.vertexColors )
|
||||
_programLayers.enable( 10 );
|
||||
if ( parameters.vertexAlphas )
|
||||
_programLayers.enable( 11 );
|
||||
if ( parameters.vertexUv1s )
|
||||
_programLayers.enable( 12 );
|
||||
if ( parameters.vertexUv2s )
|
||||
_programLayers.enable( 13 );
|
||||
if ( parameters.vertexUv3s )
|
||||
_programLayers.enable( 14 );
|
||||
if ( parameters.vertexTangents )
|
||||
_programLayers.enable( 15 );
|
||||
if ( parameters.anisotropy )
|
||||
_programLayers.enable( 16 );
|
||||
if ( parameters.alphaHash )
|
||||
_programLayers.enable( 17 );
|
||||
if ( parameters.batching )
|
||||
_programLayers.enable( 18 );
|
||||
if ( parameters.dispersion )
|
||||
_programLayers.enable( 19 );
|
||||
if ( parameters.batchingColor )
|
||||
_programLayers.enable( 20 );
|
||||
if ( parameters.gradientMap )
|
||||
_programLayers.enable( 21 );
|
||||
|
||||
array.push( _programLayers.mask );
|
||||
_programLayers.disableAll();
|
||||
|
||||
if ( parameters.fog )
|
||||
_programLayers.enable( 0 );
|
||||
if ( parameters.useFog )
|
||||
_programLayers.enable( 1 );
|
||||
if ( parameters.flatShading )
|
||||
_programLayers.enable( 2 );
|
||||
if ( parameters.logarithmicDepthBuffer )
|
||||
_programLayers.enable( 3 );
|
||||
if ( parameters.reversedDepthBuffer )
|
||||
_programLayers.enable( 4 );
|
||||
if ( parameters.skinning )
|
||||
_programLayers.enable( 5 );
|
||||
if ( parameters.morphTargets )
|
||||
_programLayers.enable( 6 );
|
||||
if ( parameters.morphNormals )
|
||||
_programLayers.enable( 7 );
|
||||
if ( parameters.morphColors )
|
||||
_programLayers.enable( 8 );
|
||||
if ( parameters.premultipliedAlpha )
|
||||
_programLayers.enable( 9 );
|
||||
if ( parameters.shadowMapEnabled )
|
||||
_programLayers.enable( 10 );
|
||||
if ( parameters.doubleSided )
|
||||
_programLayers.enable( 11 );
|
||||
if ( parameters.flipSided )
|
||||
_programLayers.enable( 12 );
|
||||
if ( parameters.useDepthPacking )
|
||||
_programLayers.enable( 13 );
|
||||
if ( parameters.dithering )
|
||||
_programLayers.enable( 14 );
|
||||
if ( parameters.transmission )
|
||||
_programLayers.enable( 15 );
|
||||
if ( parameters.sheen )
|
||||
_programLayers.enable( 16 );
|
||||
if ( parameters.opaque )
|
||||
_programLayers.enable( 17 );
|
||||
if ( parameters.pointsUvs )
|
||||
_programLayers.enable( 18 );
|
||||
if ( parameters.decodeVideoTexture )
|
||||
_programLayers.enable( 19 );
|
||||
if ( parameters.decodeVideoTextureEmissive )
|
||||
_programLayers.enable( 20 );
|
||||
if ( parameters.alphaToCoverage )
|
||||
_programLayers.enable( 21 );
|
||||
|
||||
array.push( _programLayers.mask );
|
||||
|
||||
}
|
||||
|
||||
function getUniforms( material ) {
|
||||
|
||||
const shaderID = shaderIDs[ material.type ];
|
||||
let uniforms;
|
||||
|
||||
if ( shaderID ) {
|
||||
|
||||
const shader = ShaderLib[ shaderID ];
|
||||
uniforms = UniformsUtils.clone( shader.uniforms );
|
||||
|
||||
} else {
|
||||
|
||||
uniforms = material.uniforms;
|
||||
|
||||
}
|
||||
|
||||
return uniforms;
|
||||
|
||||
}
|
||||
|
||||
function acquireProgram( parameters, cacheKey ) {
|
||||
|
||||
let program = programsMap.get( cacheKey );
|
||||
|
||||
if ( program !== undefined ) {
|
||||
|
||||
++ program.usedTimes;
|
||||
|
||||
} else {
|
||||
|
||||
program = new WebGLProgram( renderer, cacheKey, parameters, bindingStates );
|
||||
programs.push( program );
|
||||
|
||||
programsMap.set( cacheKey, program );
|
||||
|
||||
}
|
||||
|
||||
return program;
|
||||
|
||||
}
|
||||
|
||||
function releaseProgram( program ) {
|
||||
|
||||
if ( -- program.usedTimes === 0 ) {
|
||||
|
||||
// Remove from unordered set
|
||||
const i = programs.indexOf( program );
|
||||
programs[ i ] = programs[ programs.length - 1 ];
|
||||
programs.pop();
|
||||
|
||||
// Remove from map
|
||||
programsMap.delete( program.cacheKey );
|
||||
|
||||
// Free WebGL resources
|
||||
program.destroy();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function releaseShaderCache( material ) {
|
||||
|
||||
_customShaders.remove( material );
|
||||
|
||||
}
|
||||
|
||||
function dispose() {
|
||||
|
||||
_customShaders.dispose();
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
getParameters: getParameters,
|
||||
getProgramCacheKey: getProgramCacheKey,
|
||||
getUniforms: getUniforms,
|
||||
acquireProgram: acquireProgram,
|
||||
releaseProgram: releaseProgram,
|
||||
releaseShaderCache: releaseShaderCache,
|
||||
// Exposed for resource monitoring & error feedback via renderer.info:
|
||||
programs: programs,
|
||||
dispose: dispose
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
export { WebGLPrograms };
|
||||
55
node_modules/three/src/renderers/webgl/WebGLProperties.js
generated
vendored
Normal file
55
node_modules/three/src/renderers/webgl/WebGLProperties.js
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
function WebGLProperties() {
|
||||
|
||||
let properties = new WeakMap();
|
||||
|
||||
function has( object ) {
|
||||
|
||||
return properties.has( object );
|
||||
|
||||
}
|
||||
|
||||
function get( object ) {
|
||||
|
||||
let map = properties.get( object );
|
||||
|
||||
if ( map === undefined ) {
|
||||
|
||||
map = {};
|
||||
properties.set( object, map );
|
||||
|
||||
}
|
||||
|
||||
return map;
|
||||
|
||||
}
|
||||
|
||||
function remove( object ) {
|
||||
|
||||
properties.delete( object );
|
||||
|
||||
}
|
||||
|
||||
function update( object, key, value ) {
|
||||
|
||||
properties.get( object )[ key ] = value;
|
||||
|
||||
}
|
||||
|
||||
function dispose() {
|
||||
|
||||
properties = new WeakMap();
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
has: has,
|
||||
get: get,
|
||||
remove: remove,
|
||||
update: update,
|
||||
dispose: dispose
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { WebGLProperties };
|
||||
253
node_modules/three/src/renderers/webgl/WebGLRenderLists.js
generated
vendored
Normal file
253
node_modules/three/src/renderers/webgl/WebGLRenderLists.js
generated
vendored
Normal file
@@ -0,0 +1,253 @@
|
||||
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.materialVariant !== b.materialVariant ) {
|
||||
|
||||
return a.materialVariant - b.materialVariant;
|
||||
|
||||
} 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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
function WebGLRenderList() {
|
||||
|
||||
const renderItems = [];
|
||||
let renderItemsIndex = 0;
|
||||
|
||||
const opaque = [];
|
||||
const transmissive = [];
|
||||
const transparent = [];
|
||||
|
||||
function init() {
|
||||
|
||||
renderItemsIndex = 0;
|
||||
|
||||
opaque.length = 0;
|
||||
transmissive.length = 0;
|
||||
transparent.length = 0;
|
||||
|
||||
}
|
||||
|
||||
function materialVariant( object ) {
|
||||
|
||||
let variant = 0;
|
||||
if ( object.isInstancedMesh ) variant += 2;
|
||||
if ( object.isSkinnedMesh ) variant += 1;
|
||||
return variant;
|
||||
|
||||
}
|
||||
|
||||
function getNextRenderItem( object, geometry, material, groupOrder, z, group ) {
|
||||
|
||||
let renderItem = renderItems[ renderItemsIndex ];
|
||||
|
||||
if ( renderItem === undefined ) {
|
||||
|
||||
renderItem = {
|
||||
id: object.id,
|
||||
object: object,
|
||||
geometry: geometry,
|
||||
material: material,
|
||||
materialVariant: materialVariant( object ),
|
||||
groupOrder: groupOrder,
|
||||
renderOrder: object.renderOrder,
|
||||
z: z,
|
||||
group: group
|
||||
};
|
||||
|
||||
renderItems[ renderItemsIndex ] = renderItem;
|
||||
|
||||
} else {
|
||||
|
||||
renderItem.id = object.id;
|
||||
renderItem.object = object;
|
||||
renderItem.geometry = geometry;
|
||||
renderItem.material = material;
|
||||
renderItem.materialVariant = materialVariant( object );
|
||||
renderItem.groupOrder = groupOrder;
|
||||
renderItem.renderOrder = object.renderOrder;
|
||||
renderItem.z = z;
|
||||
renderItem.group = group;
|
||||
|
||||
}
|
||||
|
||||
renderItemsIndex ++;
|
||||
|
||||
return renderItem;
|
||||
|
||||
}
|
||||
|
||||
function push( object, geometry, material, groupOrder, z, group ) {
|
||||
|
||||
const renderItem = getNextRenderItem( object, geometry, material, groupOrder, z, group );
|
||||
|
||||
if ( material.transmission > 0.0 ) {
|
||||
|
||||
transmissive.push( renderItem );
|
||||
|
||||
} else if ( material.transparent === true ) {
|
||||
|
||||
transparent.push( renderItem );
|
||||
|
||||
} else {
|
||||
|
||||
opaque.push( renderItem );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function unshift( object, geometry, material, groupOrder, z, group ) {
|
||||
|
||||
const renderItem = getNextRenderItem( object, geometry, material, groupOrder, z, group );
|
||||
|
||||
if ( material.transmission > 0.0 ) {
|
||||
|
||||
transmissive.unshift( renderItem );
|
||||
|
||||
} else if ( material.transparent === true ) {
|
||||
|
||||
transparent.unshift( renderItem );
|
||||
|
||||
} else {
|
||||
|
||||
opaque.unshift( renderItem );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function sort( customOpaqueSort, customTransparentSort ) {
|
||||
|
||||
if ( opaque.length > 1 ) opaque.sort( customOpaqueSort || painterSortStable );
|
||||
if ( transmissive.length > 1 ) transmissive.sort( customTransparentSort || reversePainterSortStable );
|
||||
if ( transparent.length > 1 ) transparent.sort( customTransparentSort || reversePainterSortStable );
|
||||
|
||||
}
|
||||
|
||||
function finish() {
|
||||
|
||||
// Clear references from inactive renderItems in the list
|
||||
|
||||
for ( let i = renderItemsIndex, il = renderItems.length; i < il; i ++ ) {
|
||||
|
||||
const renderItem = renderItems[ i ];
|
||||
|
||||
if ( renderItem.id === null ) break;
|
||||
|
||||
renderItem.id = null;
|
||||
renderItem.object = null;
|
||||
renderItem.geometry = null;
|
||||
renderItem.material = null;
|
||||
renderItem.group = null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
opaque: opaque,
|
||||
transmissive: transmissive,
|
||||
transparent: transparent,
|
||||
|
||||
init: init,
|
||||
push: push,
|
||||
unshift: unshift,
|
||||
finish: finish,
|
||||
|
||||
sort: sort
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
function WebGLRenderLists() {
|
||||
|
||||
let lists = new WeakMap();
|
||||
|
||||
function get( scene, renderCallDepth ) {
|
||||
|
||||
const listArray = lists.get( scene );
|
||||
let list;
|
||||
|
||||
if ( listArray === undefined ) {
|
||||
|
||||
list = new WebGLRenderList();
|
||||
lists.set( scene, [ list ] );
|
||||
|
||||
} else {
|
||||
|
||||
if ( renderCallDepth >= listArray.length ) {
|
||||
|
||||
list = new WebGLRenderList();
|
||||
listArray.push( list );
|
||||
|
||||
} else {
|
||||
|
||||
list = listArray[ renderCallDepth ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return list;
|
||||
|
||||
}
|
||||
|
||||
function dispose() {
|
||||
|
||||
lists = new WeakMap();
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
get: get,
|
||||
dispose: dispose
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { WebGLRenderLists, WebGLRenderList };
|
||||
113
node_modules/three/src/renderers/webgl/WebGLRenderStates.js
generated
vendored
Normal file
113
node_modules/three/src/renderers/webgl/WebGLRenderStates.js
generated
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
import { WebGLLights } from './WebGLLights.js';
|
||||
|
||||
function WebGLRenderState( extensions ) {
|
||||
|
||||
const lights = new WebGLLights( extensions );
|
||||
|
||||
const lightsArray = [];
|
||||
const shadowsArray = [];
|
||||
|
||||
function init( camera ) {
|
||||
|
||||
state.camera = camera;
|
||||
|
||||
lightsArray.length = 0;
|
||||
shadowsArray.length = 0;
|
||||
|
||||
}
|
||||
|
||||
function pushLight( light ) {
|
||||
|
||||
lightsArray.push( light );
|
||||
|
||||
}
|
||||
|
||||
function pushShadow( shadowLight ) {
|
||||
|
||||
shadowsArray.push( shadowLight );
|
||||
|
||||
}
|
||||
|
||||
function setupLights() {
|
||||
|
||||
lights.setup( lightsArray );
|
||||
|
||||
}
|
||||
|
||||
function setupLightsView( camera ) {
|
||||
|
||||
lights.setupView( lightsArray, camera );
|
||||
|
||||
}
|
||||
|
||||
const state = {
|
||||
lightsArray: lightsArray,
|
||||
shadowsArray: shadowsArray,
|
||||
|
||||
camera: null,
|
||||
|
||||
lights: lights,
|
||||
|
||||
transmissionRenderTarget: {}
|
||||
};
|
||||
|
||||
return {
|
||||
init: init,
|
||||
state: state,
|
||||
setupLights: setupLights,
|
||||
setupLightsView: setupLightsView,
|
||||
|
||||
pushLight: pushLight,
|
||||
pushShadow: pushShadow
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
function WebGLRenderStates( extensions ) {
|
||||
|
||||
let renderStates = new WeakMap();
|
||||
|
||||
function get( scene, renderCallDepth = 0 ) {
|
||||
|
||||
const renderStateArray = renderStates.get( scene );
|
||||
let renderState;
|
||||
|
||||
if ( renderStateArray === undefined ) {
|
||||
|
||||
renderState = new WebGLRenderState( extensions );
|
||||
renderStates.set( scene, [ renderState ] );
|
||||
|
||||
} else {
|
||||
|
||||
if ( renderCallDepth >= renderStateArray.length ) {
|
||||
|
||||
renderState = new WebGLRenderState( extensions );
|
||||
renderStateArray.push( renderState );
|
||||
|
||||
} else {
|
||||
|
||||
renderState = renderStateArray[ renderCallDepth ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return renderState;
|
||||
|
||||
}
|
||||
|
||||
function dispose() {
|
||||
|
||||
renderStates = new WeakMap();
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
get: get,
|
||||
dispose: dispose
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { WebGLRenderStates };
|
||||
12
node_modules/three/src/renderers/webgl/WebGLShader.js
generated
vendored
Normal file
12
node_modules/three/src/renderers/webgl/WebGLShader.js
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
function WebGLShader( gl, type, string ) {
|
||||
|
||||
const shader = gl.createShader( type );
|
||||
|
||||
gl.shaderSource( shader, string );
|
||||
gl.compileShader( shader );
|
||||
|
||||
return shader;
|
||||
|
||||
}
|
||||
|
||||
export { WebGLShader };
|
||||
124
node_modules/three/src/renderers/webgl/WebGLShaderCache.js
generated
vendored
Normal file
124
node_modules/three/src/renderers/webgl/WebGLShaderCache.js
generated
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
let _id = 0;
|
||||
|
||||
class WebGLShaderCache {
|
||||
|
||||
constructor() {
|
||||
|
||||
this.shaderCache = new Map();
|
||||
this.materialCache = new Map();
|
||||
|
||||
}
|
||||
|
||||
update( material ) {
|
||||
|
||||
const vertexShader = material.vertexShader;
|
||||
const fragmentShader = material.fragmentShader;
|
||||
|
||||
const vertexShaderStage = this._getShaderStage( vertexShader );
|
||||
const fragmentShaderStage = this._getShaderStage( fragmentShader );
|
||||
|
||||
const materialShaders = this._getShaderCacheForMaterial( material );
|
||||
|
||||
if ( materialShaders.has( vertexShaderStage ) === false ) {
|
||||
|
||||
materialShaders.add( vertexShaderStage );
|
||||
vertexShaderStage.usedTimes ++;
|
||||
|
||||
}
|
||||
|
||||
if ( materialShaders.has( fragmentShaderStage ) === false ) {
|
||||
|
||||
materialShaders.add( fragmentShaderStage );
|
||||
fragmentShaderStage.usedTimes ++;
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
remove( material ) {
|
||||
|
||||
const materialShaders = this.materialCache.get( material );
|
||||
|
||||
for ( const shaderStage of materialShaders ) {
|
||||
|
||||
shaderStage.usedTimes --;
|
||||
|
||||
if ( shaderStage.usedTimes === 0 ) this.shaderCache.delete( shaderStage.code );
|
||||
|
||||
}
|
||||
|
||||
this.materialCache.delete( material );
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
getVertexShaderID( material ) {
|
||||
|
||||
return this._getShaderStage( material.vertexShader ).id;
|
||||
|
||||
}
|
||||
|
||||
getFragmentShaderID( material ) {
|
||||
|
||||
return this._getShaderStage( material.fragmentShader ).id;
|
||||
|
||||
}
|
||||
|
||||
dispose() {
|
||||
|
||||
this.shaderCache.clear();
|
||||
this.materialCache.clear();
|
||||
|
||||
}
|
||||
|
||||
_getShaderCacheForMaterial( material ) {
|
||||
|
||||
const cache = this.materialCache;
|
||||
let set = cache.get( material );
|
||||
|
||||
if ( set === undefined ) {
|
||||
|
||||
set = new Set();
|
||||
cache.set( material, set );
|
||||
|
||||
}
|
||||
|
||||
return set;
|
||||
|
||||
}
|
||||
|
||||
_getShaderStage( code ) {
|
||||
|
||||
const cache = this.shaderCache;
|
||||
let stage = cache.get( code );
|
||||
|
||||
if ( stage === undefined ) {
|
||||
|
||||
stage = new WebGLShaderStage( code );
|
||||
cache.set( code, stage );
|
||||
|
||||
}
|
||||
|
||||
return stage;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class WebGLShaderStage {
|
||||
|
||||
constructor( code ) {
|
||||
|
||||
this.id = _id ++;
|
||||
|
||||
this.code = code;
|
||||
this.usedTimes = 0;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export { WebGLShaderCache };
|
||||
600
node_modules/three/src/renderers/webgl/WebGLShadowMap.js
generated
vendored
Normal file
600
node_modules/three/src/renderers/webgl/WebGLShadowMap.js
generated
vendored
Normal file
@@ -0,0 +1,600 @@
|
||||
import { FrontSide, BackSide, DoubleSide, NearestFilter, LinearFilter, PCFShadowMap, VSMShadowMap, NoBlending, LessEqualCompare, GreaterEqualCompare, DepthFormat, UnsignedIntType, RGFormat, HalfFloatType, FloatType, PCFSoftShadowMap } from '../../constants.js';
|
||||
import { WebGLRenderTarget } from '../WebGLRenderTarget.js';
|
||||
import { WebGLCubeRenderTarget } from '../WebGLCubeRenderTarget.js';
|
||||
import { MeshDepthMaterial } from '../../materials/MeshDepthMaterial.js';
|
||||
import { MeshDistanceMaterial } from '../../materials/MeshDistanceMaterial.js';
|
||||
import { ShaderMaterial } from '../../materials/ShaderMaterial.js';
|
||||
import { BufferAttribute } from '../../core/BufferAttribute.js';
|
||||
import { BufferGeometry } from '../../core/BufferGeometry.js';
|
||||
import { Mesh } from '../../objects/Mesh.js';
|
||||
import { Vector4 } from '../../math/Vector4.js';
|
||||
import { Vector2 } from '../../math/Vector2.js';
|
||||
import { Matrix4 } from '../../math/Matrix4.js';
|
||||
import { Frustum } from '../../math/Frustum.js';
|
||||
import { DepthTexture } from '../../textures/DepthTexture.js';
|
||||
import { CubeDepthTexture } from '../../textures/CubeDepthTexture.js';
|
||||
|
||||
import * as vsm from '../shaders/ShaderLib/vsm.glsl.js';
|
||||
import { warn } from '../../utils.js';
|
||||
import { Vector3 } from '../../math/Vector3.js';
|
||||
|
||||
const _cubeDirections = [
|
||||
/*@__PURE__*/ new Vector3( 1, 0, 0 ), /*@__PURE__*/ new Vector3( - 1, 0, 0 ), /*@__PURE__*/ new Vector3( 0, 1, 0 ),
|
||||
/*@__PURE__*/ new Vector3( 0, - 1, 0 ), /*@__PURE__*/ new Vector3( 0, 0, 1 ), /*@__PURE__*/ new Vector3( 0, 0, - 1 )
|
||||
];
|
||||
|
||||
const _cubeUps = [
|
||||
/*@__PURE__*/ new Vector3( 0, - 1, 0 ), /*@__PURE__*/ new Vector3( 0, - 1, 0 ), /*@__PURE__*/ new Vector3( 0, 0, 1 ),
|
||||
/*@__PURE__*/ new Vector3( 0, 0, - 1 ), /*@__PURE__*/ new Vector3( 0, - 1, 0 ), /*@__PURE__*/ new Vector3( 0, - 1, 0 )
|
||||
];
|
||||
|
||||
const _projScreenMatrix = /*@__PURE__*/ new Matrix4();
|
||||
const _lightPositionWorld = /*@__PURE__*/ new Vector3();
|
||||
const _lookTarget = /*@__PURE__*/ new Vector3();
|
||||
|
||||
function WebGLShadowMap( renderer, objects, capabilities ) {
|
||||
|
||||
let _frustum = new Frustum();
|
||||
|
||||
const _shadowMapSize = new Vector2(),
|
||||
_viewportSize = new Vector2(),
|
||||
|
||||
_viewport = new Vector4(),
|
||||
|
||||
_depthMaterial = new MeshDepthMaterial(),
|
||||
_distanceMaterial = new MeshDistanceMaterial(),
|
||||
|
||||
_materialCache = {},
|
||||
|
||||
_maxTextureSize = capabilities.maxTextureSize;
|
||||
|
||||
const shadowSide = { [ FrontSide ]: BackSide, [ BackSide ]: FrontSide, [ DoubleSide ]: DoubleSide };
|
||||
|
||||
const shadowMaterialVertical = new ShaderMaterial( {
|
||||
defines: {
|
||||
VSM_SAMPLES: 8
|
||||
},
|
||||
uniforms: {
|
||||
shadow_pass: { value: null },
|
||||
resolution: { value: new Vector2() },
|
||||
radius: { value: 4.0 }
|
||||
},
|
||||
|
||||
vertexShader: vsm.vertex,
|
||||
fragmentShader: vsm.fragment
|
||||
|
||||
} );
|
||||
|
||||
const shadowMaterialHorizontal = shadowMaterialVertical.clone();
|
||||
shadowMaterialHorizontal.defines.HORIZONTAL_PASS = 1;
|
||||
|
||||
const fullScreenTri = new BufferGeometry();
|
||||
fullScreenTri.setAttribute(
|
||||
'position',
|
||||
new BufferAttribute(
|
||||
new Float32Array( [ - 1, - 1, 0.5, 3, - 1, 0.5, - 1, 3, 0.5 ] ),
|
||||
3
|
||||
)
|
||||
);
|
||||
|
||||
const fullScreenMesh = new Mesh( fullScreenTri, shadowMaterialVertical );
|
||||
|
||||
const scope = this;
|
||||
|
||||
this.enabled = false;
|
||||
|
||||
this.autoUpdate = true;
|
||||
this.needsUpdate = false;
|
||||
|
||||
this.type = PCFShadowMap;
|
||||
let _previousType = this.type;
|
||||
|
||||
this.render = function ( lights, scene, camera ) {
|
||||
|
||||
if ( scope.enabled === false ) return;
|
||||
if ( scope.autoUpdate === false && scope.needsUpdate === false ) return;
|
||||
|
||||
if ( lights.length === 0 ) return;
|
||||
|
||||
if ( this.type === PCFSoftShadowMap ) {
|
||||
|
||||
warn( 'WebGLShadowMap: PCFSoftShadowMap has been deprecated. Using PCFShadowMap instead.' );
|
||||
this.type = PCFShadowMap;
|
||||
|
||||
}
|
||||
|
||||
const currentRenderTarget = renderer.getRenderTarget();
|
||||
const activeCubeFace = renderer.getActiveCubeFace();
|
||||
const activeMipmapLevel = renderer.getActiveMipmapLevel();
|
||||
|
||||
const _state = renderer.state;
|
||||
|
||||
// Set GL state for depth map.
|
||||
_state.setBlending( NoBlending );
|
||||
|
||||
if ( _state.buffers.depth.getReversed() === true ) {
|
||||
|
||||
_state.buffers.color.setClear( 0, 0, 0, 0 );
|
||||
|
||||
} else {
|
||||
|
||||
_state.buffers.color.setClear( 1, 1, 1, 1 );
|
||||
|
||||
}
|
||||
|
||||
_state.buffers.depth.setTest( true );
|
||||
_state.setScissorTest( false );
|
||||
|
||||
// check for shadow map type changes
|
||||
|
||||
const typeChanged = _previousType !== this.type;
|
||||
|
||||
// When shadow map type changes, materials need recompilation because sampler types change
|
||||
// (sampler2DShadow for PCF vs sampler2D for Basic)
|
||||
if ( typeChanged ) {
|
||||
|
||||
scene.traverse( function ( object ) {
|
||||
|
||||
if ( object.material ) {
|
||||
|
||||
if ( Array.isArray( object.material ) ) {
|
||||
|
||||
object.material.forEach( mat => mat.needsUpdate = true );
|
||||
|
||||
} else {
|
||||
|
||||
object.material.needsUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
// render depth map
|
||||
|
||||
for ( let i = 0, il = lights.length; i < il; i ++ ) {
|
||||
|
||||
const light = lights[ i ];
|
||||
const shadow = light.shadow;
|
||||
|
||||
if ( shadow === undefined ) {
|
||||
|
||||
warn( 'WebGLShadowMap:', light, 'has no shadow.' );
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
if ( shadow.autoUpdate === false && shadow.needsUpdate === false ) continue;
|
||||
|
||||
_shadowMapSize.copy( shadow.mapSize );
|
||||
|
||||
const shadowFrameExtents = shadow.getFrameExtents();
|
||||
|
||||
_shadowMapSize.multiply( shadowFrameExtents );
|
||||
|
||||
_viewportSize.copy( shadow.mapSize );
|
||||
|
||||
if ( _shadowMapSize.x > _maxTextureSize || _shadowMapSize.y > _maxTextureSize ) {
|
||||
|
||||
if ( _shadowMapSize.x > _maxTextureSize ) {
|
||||
|
||||
_viewportSize.x = Math.floor( _maxTextureSize / shadowFrameExtents.x );
|
||||
_shadowMapSize.x = _viewportSize.x * shadowFrameExtents.x;
|
||||
shadow.mapSize.x = _viewportSize.x;
|
||||
|
||||
}
|
||||
|
||||
if ( _shadowMapSize.y > _maxTextureSize ) {
|
||||
|
||||
_viewportSize.y = Math.floor( _maxTextureSize / shadowFrameExtents.y );
|
||||
_shadowMapSize.y = _viewportSize.y * shadowFrameExtents.y;
|
||||
shadow.mapSize.y = _viewportSize.y;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const reversedDepthBuffer = renderer.state.buffers.depth.getReversed();
|
||||
shadow.camera._reversedDepth = reversedDepthBuffer;
|
||||
|
||||
if ( shadow.map === null || typeChanged === true ) {
|
||||
|
||||
if ( shadow.map !== null ) {
|
||||
|
||||
if ( shadow.map.depthTexture !== null ) {
|
||||
|
||||
shadow.map.depthTexture.dispose();
|
||||
shadow.map.depthTexture = null;
|
||||
|
||||
}
|
||||
|
||||
shadow.map.dispose();
|
||||
|
||||
}
|
||||
|
||||
if ( this.type === VSMShadowMap ) {
|
||||
|
||||
if ( light.isPointLight ) {
|
||||
|
||||
warn( 'WebGLShadowMap: VSM shadow maps are not supported for PointLights. Use PCF or BasicShadowMap instead.' );
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
shadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, {
|
||||
format: RGFormat,
|
||||
type: HalfFloatType,
|
||||
minFilter: LinearFilter,
|
||||
magFilter: LinearFilter,
|
||||
generateMipmaps: false
|
||||
} );
|
||||
shadow.map.texture.name = light.name + '.shadowMap';
|
||||
|
||||
// Native depth texture for VSM - depth is captured here, then blurred into the color texture
|
||||
shadow.map.depthTexture = new DepthTexture( _shadowMapSize.x, _shadowMapSize.y, FloatType );
|
||||
shadow.map.depthTexture.name = light.name + '.shadowMapDepth';
|
||||
shadow.map.depthTexture.format = DepthFormat;
|
||||
shadow.map.depthTexture.compareFunction = null; // For regular sampling (not shadow comparison)
|
||||
shadow.map.depthTexture.minFilter = NearestFilter;
|
||||
shadow.map.depthTexture.magFilter = NearestFilter;
|
||||
|
||||
} else {
|
||||
|
||||
if ( light.isPointLight ) {
|
||||
|
||||
shadow.map = new WebGLCubeRenderTarget( _shadowMapSize.x );
|
||||
shadow.map.depthTexture = new CubeDepthTexture( _shadowMapSize.x, UnsignedIntType );
|
||||
|
||||
} else {
|
||||
|
||||
shadow.map = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y );
|
||||
shadow.map.depthTexture = new DepthTexture( _shadowMapSize.x, _shadowMapSize.y, UnsignedIntType );
|
||||
|
||||
}
|
||||
|
||||
shadow.map.depthTexture.name = light.name + '.shadowMap';
|
||||
shadow.map.depthTexture.format = DepthFormat;
|
||||
|
||||
if ( this.type === PCFShadowMap ) {
|
||||
|
||||
shadow.map.depthTexture.compareFunction = reversedDepthBuffer ? GreaterEqualCompare : LessEqualCompare;
|
||||
shadow.map.depthTexture.minFilter = LinearFilter;
|
||||
shadow.map.depthTexture.magFilter = LinearFilter;
|
||||
|
||||
} else {
|
||||
|
||||
shadow.map.depthTexture.compareFunction = null;
|
||||
shadow.map.depthTexture.minFilter = NearestFilter;
|
||||
shadow.map.depthTexture.magFilter = NearestFilter;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
shadow.camera.updateProjectionMatrix();
|
||||
|
||||
}
|
||||
|
||||
// For cube render targets (PointLights), render all 6 faces. Otherwise, render once.
|
||||
const faceCount = shadow.map.isWebGLCubeRenderTarget ? 6 : 1;
|
||||
|
||||
for ( let face = 0; face < faceCount; face ++ ) {
|
||||
|
||||
// For cube render targets, render to each face separately
|
||||
if ( shadow.map.isWebGLCubeRenderTarget ) {
|
||||
|
||||
renderer.setRenderTarget( shadow.map, face );
|
||||
renderer.clear();
|
||||
|
||||
} else {
|
||||
|
||||
// For 2D render targets, use viewports
|
||||
if ( face === 0 ) {
|
||||
|
||||
renderer.setRenderTarget( shadow.map );
|
||||
renderer.clear();
|
||||
|
||||
}
|
||||
|
||||
const viewport = shadow.getViewport( face );
|
||||
|
||||
_viewport.set(
|
||||
_viewportSize.x * viewport.x,
|
||||
_viewportSize.y * viewport.y,
|
||||
_viewportSize.x * viewport.z,
|
||||
_viewportSize.y * viewport.w
|
||||
);
|
||||
|
||||
_state.viewport( _viewport );
|
||||
|
||||
}
|
||||
|
||||
if ( light.isPointLight ) {
|
||||
|
||||
const camera = shadow.camera;
|
||||
const shadowMatrix = shadow.matrix;
|
||||
|
||||
const far = light.distance || camera.far;
|
||||
|
||||
if ( far !== camera.far ) {
|
||||
|
||||
camera.far = far;
|
||||
camera.updateProjectionMatrix();
|
||||
|
||||
}
|
||||
|
||||
_lightPositionWorld.setFromMatrixPosition( light.matrixWorld );
|
||||
camera.position.copy( _lightPositionWorld );
|
||||
|
||||
_lookTarget.copy( camera.position );
|
||||
_lookTarget.add( _cubeDirections[ face ] );
|
||||
camera.up.copy( _cubeUps[ face ] );
|
||||
camera.lookAt( _lookTarget );
|
||||
camera.updateMatrixWorld();
|
||||
|
||||
shadowMatrix.makeTranslation( - _lightPositionWorld.x, - _lightPositionWorld.y, - _lightPositionWorld.z );
|
||||
|
||||
_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
|
||||
shadow._frustum.setFromProjectionMatrix( _projScreenMatrix, camera.coordinateSystem, camera.reversedDepth );
|
||||
|
||||
} else {
|
||||
|
||||
shadow.updateMatrices( light );
|
||||
|
||||
}
|
||||
|
||||
_frustum = shadow.getFrustum();
|
||||
|
||||
renderObject( scene, camera, shadow.camera, light, this.type );
|
||||
|
||||
}
|
||||
|
||||
// do blur pass for VSM
|
||||
|
||||
if ( shadow.isPointLightShadow !== true && this.type === VSMShadowMap ) {
|
||||
|
||||
VSMPass( shadow, camera );
|
||||
|
||||
}
|
||||
|
||||
shadow.needsUpdate = false;
|
||||
|
||||
}
|
||||
|
||||
_previousType = this.type;
|
||||
|
||||
scope.needsUpdate = false;
|
||||
|
||||
renderer.setRenderTarget( currentRenderTarget, activeCubeFace, activeMipmapLevel );
|
||||
|
||||
};
|
||||
|
||||
function VSMPass( shadow, camera ) {
|
||||
|
||||
const geometry = objects.update( fullScreenMesh );
|
||||
|
||||
if ( shadowMaterialVertical.defines.VSM_SAMPLES !== shadow.blurSamples ) {
|
||||
|
||||
shadowMaterialVertical.defines.VSM_SAMPLES = shadow.blurSamples;
|
||||
shadowMaterialHorizontal.defines.VSM_SAMPLES = shadow.blurSamples;
|
||||
|
||||
shadowMaterialVertical.needsUpdate = true;
|
||||
shadowMaterialHorizontal.needsUpdate = true;
|
||||
|
||||
}
|
||||
|
||||
if ( shadow.mapPass === null ) {
|
||||
|
||||
shadow.mapPass = new WebGLRenderTarget( _shadowMapSize.x, _shadowMapSize.y, {
|
||||
format: RGFormat,
|
||||
type: HalfFloatType
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
// vertical pass - read from native depth texture
|
||||
|
||||
shadowMaterialVertical.uniforms.shadow_pass.value = shadow.map.depthTexture;
|
||||
shadowMaterialVertical.uniforms.resolution.value = shadow.mapSize;
|
||||
shadowMaterialVertical.uniforms.radius.value = shadow.radius;
|
||||
renderer.setRenderTarget( shadow.mapPass );
|
||||
renderer.clear();
|
||||
renderer.renderBufferDirect( camera, null, geometry, shadowMaterialVertical, fullScreenMesh, null );
|
||||
|
||||
// horizontal pass
|
||||
|
||||
shadowMaterialHorizontal.uniforms.shadow_pass.value = shadow.mapPass.texture;
|
||||
shadowMaterialHorizontal.uniforms.resolution.value = shadow.mapSize;
|
||||
shadowMaterialHorizontal.uniforms.radius.value = shadow.radius;
|
||||
renderer.setRenderTarget( shadow.map );
|
||||
renderer.clear();
|
||||
renderer.renderBufferDirect( camera, null, geometry, shadowMaterialHorizontal, fullScreenMesh, null );
|
||||
|
||||
}
|
||||
|
||||
function getDepthMaterial( object, material, light, type ) {
|
||||
|
||||
let result = null;
|
||||
|
||||
const customMaterial = ( light.isPointLight === true ) ? object.customDistanceMaterial : object.customDepthMaterial;
|
||||
|
||||
if ( customMaterial !== undefined ) {
|
||||
|
||||
result = customMaterial;
|
||||
|
||||
} else {
|
||||
|
||||
result = ( light.isPointLight === true ) ? _distanceMaterial : _depthMaterial;
|
||||
|
||||
if ( ( renderer.localClippingEnabled && material.clipShadows === true && Array.isArray( material.clippingPlanes ) && material.clippingPlanes.length !== 0 ) ||
|
||||
( material.displacementMap && material.displacementScale !== 0 ) ||
|
||||
( material.alphaMap && material.alphaTest > 0 ) ||
|
||||
( material.map && material.alphaTest > 0 ) ||
|
||||
( material.alphaToCoverage === true ) ) {
|
||||
|
||||
// in this case we need a unique material instance reflecting the
|
||||
// appropriate state
|
||||
|
||||
const keyA = result.uuid, keyB = material.uuid;
|
||||
|
||||
let materialsForVariant = _materialCache[ keyA ];
|
||||
|
||||
if ( materialsForVariant === undefined ) {
|
||||
|
||||
materialsForVariant = {};
|
||||
_materialCache[ keyA ] = materialsForVariant;
|
||||
|
||||
}
|
||||
|
||||
let cachedMaterial = materialsForVariant[ keyB ];
|
||||
|
||||
if ( cachedMaterial === undefined ) {
|
||||
|
||||
cachedMaterial = result.clone();
|
||||
materialsForVariant[ keyB ] = cachedMaterial;
|
||||
material.addEventListener( 'dispose', onMaterialDispose );
|
||||
|
||||
}
|
||||
|
||||
result = cachedMaterial;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
result.visible = material.visible;
|
||||
result.wireframe = material.wireframe;
|
||||
|
||||
if ( type === VSMShadowMap ) {
|
||||
|
||||
result.side = ( material.shadowSide !== null ) ? material.shadowSide : material.side;
|
||||
|
||||
} else {
|
||||
|
||||
result.side = ( material.shadowSide !== null ) ? material.shadowSide : shadowSide[ material.side ];
|
||||
|
||||
}
|
||||
|
||||
result.alphaMap = material.alphaMap;
|
||||
result.alphaTest = ( material.alphaToCoverage === true ) ? 0.5 : material.alphaTest; // approximate alphaToCoverage by using a fixed alphaTest value
|
||||
result.map = material.map;
|
||||
|
||||
result.clipShadows = material.clipShadows;
|
||||
result.clippingPlanes = material.clippingPlanes;
|
||||
result.clipIntersection = material.clipIntersection;
|
||||
|
||||
result.displacementMap = material.displacementMap;
|
||||
result.displacementScale = material.displacementScale;
|
||||
result.displacementBias = material.displacementBias;
|
||||
|
||||
result.wireframeLinewidth = material.wireframeLinewidth;
|
||||
result.linewidth = material.linewidth;
|
||||
|
||||
if ( light.isPointLight === true && result.isMeshDistanceMaterial === true ) {
|
||||
|
||||
const materialProperties = renderer.properties.get( result );
|
||||
materialProperties.light = light;
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
function renderObject( object, camera, shadowCamera, light, type ) {
|
||||
|
||||
if ( object.visible === false ) return;
|
||||
|
||||
const visible = object.layers.test( camera.layers );
|
||||
|
||||
if ( visible && ( object.isMesh || object.isLine || object.isPoints ) ) {
|
||||
|
||||
if ( ( object.castShadow || ( object.receiveShadow && type === VSMShadowMap ) ) && ( ! object.frustumCulled || _frustum.intersectsObject( object ) ) ) {
|
||||
|
||||
object.modelViewMatrix.multiplyMatrices( shadowCamera.matrixWorldInverse, object.matrixWorld );
|
||||
|
||||
const geometry = objects.update( object );
|
||||
const material = object.material;
|
||||
|
||||
if ( Array.isArray( material ) ) {
|
||||
|
||||
const groups = geometry.groups;
|
||||
|
||||
for ( let k = 0, kl = groups.length; k < kl; k ++ ) {
|
||||
|
||||
const group = groups[ k ];
|
||||
const groupMaterial = material[ group.materialIndex ];
|
||||
|
||||
if ( groupMaterial && groupMaterial.visible ) {
|
||||
|
||||
const depthMaterial = getDepthMaterial( object, groupMaterial, light, type );
|
||||
|
||||
object.onBeforeShadow( renderer, object, camera, shadowCamera, geometry, depthMaterial, group );
|
||||
|
||||
renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, group );
|
||||
|
||||
object.onAfterShadow( renderer, object, camera, shadowCamera, geometry, depthMaterial, group );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else if ( material.visible ) {
|
||||
|
||||
const depthMaterial = getDepthMaterial( object, material, light, type );
|
||||
|
||||
object.onBeforeShadow( renderer, object, camera, shadowCamera, geometry, depthMaterial, null );
|
||||
|
||||
renderer.renderBufferDirect( shadowCamera, null, geometry, depthMaterial, object, null );
|
||||
|
||||
object.onAfterShadow( renderer, object, camera, shadowCamera, geometry, depthMaterial, null );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const children = object.children;
|
||||
|
||||
for ( let i = 0, l = children.length; i < l; i ++ ) {
|
||||
|
||||
renderObject( children[ i ], camera, shadowCamera, light, type );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function onMaterialDispose( event ) {
|
||||
|
||||
const material = event.target;
|
||||
|
||||
material.removeEventListener( 'dispose', onMaterialDispose );
|
||||
|
||||
// make sure to remove the unique distance/depth materials used for shadow map rendering
|
||||
|
||||
for ( const id in _materialCache ) {
|
||||
|
||||
const cache = _materialCache[ id ];
|
||||
|
||||
const uuid = event.target.uuid;
|
||||
|
||||
if ( uuid in cache ) {
|
||||
|
||||
const shadowMaterial = cache[ uuid ];
|
||||
shadowMaterial.dispose();
|
||||
delete cache[ uuid ];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { WebGLShadowMap };
|
||||
1327
node_modules/three/src/renderers/webgl/WebGLState.js
generated
vendored
Normal file
1327
node_modules/three/src/renderers/webgl/WebGLState.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
2403
node_modules/three/src/renderers/webgl/WebGLTextures.js
generated
vendored
Normal file
2403
node_modules/three/src/renderers/webgl/WebGLTextures.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1203
node_modules/three/src/renderers/webgl/WebGLUniforms.js
generated
vendored
Normal file
1203
node_modules/three/src/renderers/webgl/WebGLUniforms.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
394
node_modules/three/src/renderers/webgl/WebGLUniformsGroups.js
generated
vendored
Normal file
394
node_modules/three/src/renderers/webgl/WebGLUniformsGroups.js
generated
vendored
Normal file
@@ -0,0 +1,394 @@
|
||||
import { error, warn } from '../../utils.js';
|
||||
|
||||
function WebGLUniformsGroups( gl, info, capabilities, state ) {
|
||||
|
||||
let buffers = {};
|
||||
let updateList = {};
|
||||
let allocatedBindingPoints = [];
|
||||
|
||||
const maxBindingPoints = gl.getParameter( gl.MAX_UNIFORM_BUFFER_BINDINGS ); // binding points are global whereas block indices are per shader program
|
||||
|
||||
function bind( uniformsGroup, program ) {
|
||||
|
||||
const webglProgram = program.program;
|
||||
state.uniformBlockBinding( uniformsGroup, webglProgram );
|
||||
|
||||
}
|
||||
|
||||
function update( uniformsGroup, program ) {
|
||||
|
||||
let buffer = buffers[ uniformsGroup.id ];
|
||||
|
||||
if ( buffer === undefined ) {
|
||||
|
||||
prepareUniformsGroup( uniformsGroup );
|
||||
|
||||
buffer = createBuffer( uniformsGroup );
|
||||
buffers[ uniformsGroup.id ] = buffer;
|
||||
|
||||
uniformsGroup.addEventListener( 'dispose', onUniformsGroupsDispose );
|
||||
|
||||
}
|
||||
|
||||
// ensure to update the binding points/block indices mapping for this program
|
||||
|
||||
const webglProgram = program.program;
|
||||
state.updateUBOMapping( uniformsGroup, webglProgram );
|
||||
|
||||
// update UBO once per frame
|
||||
|
||||
const frame = info.render.frame;
|
||||
|
||||
if ( updateList[ uniformsGroup.id ] !== frame ) {
|
||||
|
||||
updateBufferData( uniformsGroup );
|
||||
|
||||
updateList[ uniformsGroup.id ] = frame;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function createBuffer( uniformsGroup ) {
|
||||
|
||||
// the setup of an UBO is independent of a particular shader program but global
|
||||
|
||||
const bindingPointIndex = allocateBindingPointIndex();
|
||||
uniformsGroup.__bindingPointIndex = bindingPointIndex;
|
||||
|
||||
const buffer = gl.createBuffer();
|
||||
const size = uniformsGroup.__size;
|
||||
const usage = uniformsGroup.usage;
|
||||
|
||||
gl.bindBuffer( gl.UNIFORM_BUFFER, buffer );
|
||||
gl.bufferData( gl.UNIFORM_BUFFER, size, usage );
|
||||
gl.bindBuffer( gl.UNIFORM_BUFFER, null );
|
||||
gl.bindBufferBase( gl.UNIFORM_BUFFER, bindingPointIndex, buffer );
|
||||
|
||||
return buffer;
|
||||
|
||||
}
|
||||
|
||||
function allocateBindingPointIndex() {
|
||||
|
||||
for ( let i = 0; i < maxBindingPoints; i ++ ) {
|
||||
|
||||
if ( allocatedBindingPoints.indexOf( i ) === - 1 ) {
|
||||
|
||||
allocatedBindingPoints.push( i );
|
||||
return i;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
error( 'WebGLRenderer: Maximum number of simultaneously usable uniforms groups reached.' );
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
function updateBufferData( uniformsGroup ) {
|
||||
|
||||
const buffer = buffers[ uniformsGroup.id ];
|
||||
const uniforms = uniformsGroup.uniforms;
|
||||
const cache = uniformsGroup.__cache;
|
||||
|
||||
gl.bindBuffer( gl.UNIFORM_BUFFER, buffer );
|
||||
|
||||
for ( let i = 0, il = uniforms.length; i < il; i ++ ) {
|
||||
|
||||
const uniformArray = Array.isArray( uniforms[ i ] ) ? uniforms[ i ] : [ uniforms[ i ] ];
|
||||
|
||||
for ( let j = 0, jl = uniformArray.length; j < jl; j ++ ) {
|
||||
|
||||
const uniform = uniformArray[ j ];
|
||||
|
||||
if ( hasUniformChanged( uniform, i, j, cache ) === true ) {
|
||||
|
||||
const offset = uniform.__offset;
|
||||
|
||||
const values = Array.isArray( uniform.value ) ? uniform.value : [ uniform.value ];
|
||||
|
||||
let arrayOffset = 0;
|
||||
|
||||
for ( let k = 0; k < values.length; k ++ ) {
|
||||
|
||||
const value = values[ k ];
|
||||
|
||||
const info = getUniformSize( value );
|
||||
|
||||
// TODO add integer and struct support
|
||||
if ( typeof value === 'number' || typeof value === 'boolean' ) {
|
||||
|
||||
uniform.__data[ 0 ] = value;
|
||||
gl.bufferSubData( gl.UNIFORM_BUFFER, offset + arrayOffset, uniform.__data );
|
||||
|
||||
} else if ( value.isMatrix3 ) {
|
||||
|
||||
// manually converting 3x3 to 3x4
|
||||
|
||||
uniform.__data[ 0 ] = value.elements[ 0 ];
|
||||
uniform.__data[ 1 ] = value.elements[ 1 ];
|
||||
uniform.__data[ 2 ] = value.elements[ 2 ];
|
||||
uniform.__data[ 3 ] = 0;
|
||||
uniform.__data[ 4 ] = value.elements[ 3 ];
|
||||
uniform.__data[ 5 ] = value.elements[ 4 ];
|
||||
uniform.__data[ 6 ] = value.elements[ 5 ];
|
||||
uniform.__data[ 7 ] = 0;
|
||||
uniform.__data[ 8 ] = value.elements[ 6 ];
|
||||
uniform.__data[ 9 ] = value.elements[ 7 ];
|
||||
uniform.__data[ 10 ] = value.elements[ 8 ];
|
||||
uniform.__data[ 11 ] = 0;
|
||||
|
||||
} else {
|
||||
|
||||
value.toArray( uniform.__data, arrayOffset );
|
||||
|
||||
arrayOffset += info.storage / Float32Array.BYTES_PER_ELEMENT;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
gl.bufferSubData( gl.UNIFORM_BUFFER, offset, uniform.__data );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
gl.bindBuffer( gl.UNIFORM_BUFFER, null );
|
||||
|
||||
}
|
||||
|
||||
function hasUniformChanged( uniform, index, indexArray, cache ) {
|
||||
|
||||
const value = uniform.value;
|
||||
const indexString = index + '_' + indexArray;
|
||||
|
||||
if ( cache[ indexString ] === undefined ) {
|
||||
|
||||
// cache entry does not exist so far
|
||||
|
||||
if ( typeof value === 'number' || typeof value === 'boolean' ) {
|
||||
|
||||
cache[ indexString ] = value;
|
||||
|
||||
} else {
|
||||
|
||||
cache[ indexString ] = value.clone();
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
} else {
|
||||
|
||||
const cachedObject = cache[ indexString ];
|
||||
|
||||
// compare current value with cached entry
|
||||
|
||||
if ( typeof value === 'number' || typeof value === 'boolean' ) {
|
||||
|
||||
if ( cachedObject !== value ) {
|
||||
|
||||
cache[ indexString ] = value;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if ( cachedObject.equals( value ) === false ) {
|
||||
|
||||
cachedObject.copy( value );
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
function prepareUniformsGroup( uniformsGroup ) {
|
||||
|
||||
// determine total buffer size according to the STD140 layout
|
||||
// Hint: STD140 is the only supported layout in WebGL 2
|
||||
|
||||
const uniforms = uniformsGroup.uniforms;
|
||||
|
||||
let offset = 0; // global buffer offset in bytes
|
||||
const chunkSize = 16; // size of a chunk in bytes
|
||||
|
||||
for ( let i = 0, l = uniforms.length; i < l; i ++ ) {
|
||||
|
||||
const uniformArray = Array.isArray( uniforms[ i ] ) ? uniforms[ i ] : [ uniforms[ i ] ];
|
||||
|
||||
for ( let j = 0, jl = uniformArray.length; j < jl; j ++ ) {
|
||||
|
||||
const uniform = uniformArray[ j ];
|
||||
|
||||
const values = Array.isArray( uniform.value ) ? uniform.value : [ uniform.value ];
|
||||
|
||||
for ( let k = 0, kl = values.length; k < kl; k ++ ) {
|
||||
|
||||
const value = values[ k ];
|
||||
|
||||
const info = getUniformSize( value );
|
||||
|
||||
const chunkOffset = offset % chunkSize; // offset in the current chunk
|
||||
const chunkPadding = chunkOffset % info.boundary; // required padding to match boundary
|
||||
const chunkStart = chunkOffset + chunkPadding; // the start position in the current chunk for the data
|
||||
|
||||
offset += chunkPadding;
|
||||
|
||||
// Check for chunk overflow
|
||||
if ( chunkStart !== 0 && ( chunkSize - chunkStart ) < info.storage ) {
|
||||
|
||||
// Add padding and adjust offset
|
||||
offset += ( chunkSize - chunkStart );
|
||||
|
||||
}
|
||||
|
||||
// the following two properties will be used for partial buffer updates
|
||||
uniform.__data = new Float32Array( info.storage / Float32Array.BYTES_PER_ELEMENT );
|
||||
uniform.__offset = offset;
|
||||
|
||||
// Update the global offset
|
||||
offset += info.storage;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ensure correct final padding
|
||||
|
||||
const chunkOffset = offset % chunkSize;
|
||||
|
||||
if ( chunkOffset > 0 ) offset += ( chunkSize - chunkOffset );
|
||||
|
||||
//
|
||||
|
||||
uniformsGroup.__size = offset;
|
||||
uniformsGroup.__cache = {};
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
function getUniformSize( value ) {
|
||||
|
||||
const info = {
|
||||
boundary: 0, // bytes
|
||||
storage: 0 // bytes
|
||||
};
|
||||
|
||||
// determine sizes according to STD140
|
||||
|
||||
if ( typeof value === 'number' || typeof value === 'boolean' ) {
|
||||
|
||||
// float/int/bool
|
||||
|
||||
info.boundary = 4;
|
||||
info.storage = 4;
|
||||
|
||||
} else if ( value.isVector2 ) {
|
||||
|
||||
// vec2
|
||||
|
||||
info.boundary = 8;
|
||||
info.storage = 8;
|
||||
|
||||
} else if ( value.isVector3 || value.isColor ) {
|
||||
|
||||
// vec3
|
||||
|
||||
info.boundary = 16;
|
||||
info.storage = 12; // evil: vec3 must start on a 16-byte boundary but it only consumes 12 bytes
|
||||
|
||||
} else if ( value.isVector4 ) {
|
||||
|
||||
// vec4
|
||||
|
||||
info.boundary = 16;
|
||||
info.storage = 16;
|
||||
|
||||
} else if ( value.isMatrix3 ) {
|
||||
|
||||
// mat3 (in STD140 a 3x3 matrix is represented as 3x4)
|
||||
|
||||
info.boundary = 48;
|
||||
info.storage = 48;
|
||||
|
||||
} else if ( value.isMatrix4 ) {
|
||||
|
||||
// mat4
|
||||
|
||||
info.boundary = 64;
|
||||
info.storage = 64;
|
||||
|
||||
} else if ( value.isTexture ) {
|
||||
|
||||
warn( 'WebGLRenderer: Texture samplers can not be part of an uniforms group.' );
|
||||
|
||||
} else {
|
||||
|
||||
warn( 'WebGLRenderer: Unsupported uniform value type.', value );
|
||||
|
||||
}
|
||||
|
||||
return info;
|
||||
|
||||
}
|
||||
|
||||
function onUniformsGroupsDispose( event ) {
|
||||
|
||||
const uniformsGroup = event.target;
|
||||
|
||||
uniformsGroup.removeEventListener( 'dispose', onUniformsGroupsDispose );
|
||||
|
||||
const index = allocatedBindingPoints.indexOf( uniformsGroup.__bindingPointIndex );
|
||||
allocatedBindingPoints.splice( index, 1 );
|
||||
|
||||
gl.deleteBuffer( buffers[ uniformsGroup.id ] );
|
||||
|
||||
delete buffers[ uniformsGroup.id ];
|
||||
delete updateList[ uniformsGroup.id ];
|
||||
|
||||
}
|
||||
|
||||
function dispose() {
|
||||
|
||||
for ( const id in buffers ) {
|
||||
|
||||
gl.deleteBuffer( buffers[ id ] );
|
||||
|
||||
}
|
||||
|
||||
allocatedBindingPoints = [];
|
||||
buffers = {};
|
||||
updateList = {};
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
bind: bind,
|
||||
update: update,
|
||||
|
||||
dispose: dispose
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { WebGLUniformsGroups };
|
||||
217
node_modules/three/src/renderers/webgl/WebGLUtils.js
generated
vendored
Normal file
217
node_modules/three/src/renderers/webgl/WebGLUtils.js
generated
vendored
Normal file
@@ -0,0 +1,217 @@
|
||||
import { RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_10x10_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGB_ETC1_Format, RGB_ETC2_Format, RGBA_ETC2_EAC_Format, R11_EAC_Format, SIGNED_R11_EAC_Format, RG11_EAC_Format, SIGNED_RG11_EAC_Format, RGBA_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGB_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT5_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT1_Format, RGB_S3TC_DXT1_Format, DepthFormat, DepthStencilFormat, RedFormat, RGBAFormat, AlphaFormat, RedIntegerFormat, RGFormat, RGIntegerFormat, RGBAIntegerFormat, HalfFloatType, FloatType, UnsignedIntType, IntType, UnsignedShortType, ShortType, ByteType, UnsignedInt248Type, UnsignedShort5551Type, UnsignedShort4444Type, UnsignedByteType, RGBA_BPTC_Format, RGB_BPTC_SIGNED_Format, RGB_BPTC_UNSIGNED_Format, RED_RGTC1_Format, SIGNED_RED_RGTC1_Format, RED_GREEN_RGTC2_Format, SIGNED_RED_GREEN_RGTC2_Format, NoColorSpace, SRGBTransfer, UnsignedInt5999Type, RGBFormat, UnsignedInt101111Type } from '../../constants.js';
|
||||
import { ColorManagement } from '../../math/ColorManagement.js';
|
||||
|
||||
function WebGLUtils( gl, extensions ) {
|
||||
|
||||
function convert( p, colorSpace = NoColorSpace ) {
|
||||
|
||||
let extension;
|
||||
|
||||
const transfer = ColorManagement.getTransfer( colorSpace );
|
||||
|
||||
if ( p === UnsignedByteType ) return gl.UNSIGNED_BYTE;
|
||||
if ( p === UnsignedShort4444Type ) return gl.UNSIGNED_SHORT_4_4_4_4;
|
||||
if ( p === UnsignedShort5551Type ) return gl.UNSIGNED_SHORT_5_5_5_1;
|
||||
if ( p === UnsignedInt5999Type ) return gl.UNSIGNED_INT_5_9_9_9_REV;
|
||||
if ( p === UnsignedInt101111Type ) return gl.UNSIGNED_INT_10F_11F_11F_REV;
|
||||
|
||||
if ( p === ByteType ) return gl.BYTE;
|
||||
if ( p === ShortType ) return gl.SHORT;
|
||||
if ( p === UnsignedShortType ) return gl.UNSIGNED_SHORT;
|
||||
if ( p === IntType ) return gl.INT;
|
||||
if ( p === UnsignedIntType ) return gl.UNSIGNED_INT;
|
||||
if ( p === FloatType ) return gl.FLOAT;
|
||||
if ( p === HalfFloatType ) return gl.HALF_FLOAT;
|
||||
|
||||
if ( p === AlphaFormat ) return gl.ALPHA;
|
||||
if ( p === RGBFormat ) return gl.RGB;
|
||||
if ( p === RGBAFormat ) return gl.RGBA;
|
||||
if ( p === DepthFormat ) return gl.DEPTH_COMPONENT;
|
||||
if ( p === DepthStencilFormat ) return gl.DEPTH_STENCIL;
|
||||
|
||||
// WebGL2 formats.
|
||||
|
||||
if ( p === RedFormat ) return gl.RED;
|
||||
if ( p === RedIntegerFormat ) return gl.RED_INTEGER;
|
||||
if ( p === RGFormat ) return gl.RG;
|
||||
if ( p === RGIntegerFormat ) return gl.RG_INTEGER;
|
||||
if ( p === RGBAIntegerFormat ) return gl.RGBA_INTEGER;
|
||||
|
||||
// S3TC
|
||||
|
||||
if ( p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format || p === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format ) {
|
||||
|
||||
if ( transfer === SRGBTransfer ) {
|
||||
|
||||
extension = extensions.get( 'WEBGL_compressed_texture_s3tc_srgb' );
|
||||
|
||||
if ( extension !== null ) {
|
||||
|
||||
if ( p === RGB_S3TC_DXT1_Format ) return extension.COMPRESSED_SRGB_S3TC_DXT1_EXT;
|
||||
if ( p === RGBA_S3TC_DXT1_Format ) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
|
||||
if ( p === RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;
|
||||
if ( p === RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
|
||||
|
||||
} else {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
extension = extensions.get( 'WEBGL_compressed_texture_s3tc' );
|
||||
|
||||
if ( extension !== null ) {
|
||||
|
||||
if ( p === RGB_S3TC_DXT1_Format ) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT;
|
||||
if ( p === RGBA_S3TC_DXT1_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT;
|
||||
if ( p === RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT;
|
||||
if ( p === RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT;
|
||||
|
||||
} else {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// PVRTC
|
||||
|
||||
if ( p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format || p === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format ) {
|
||||
|
||||
extension = extensions.get( 'WEBGL_compressed_texture_pvrtc' );
|
||||
|
||||
if ( extension !== null ) {
|
||||
|
||||
if ( p === RGB_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
|
||||
if ( p === RGB_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
|
||||
if ( p === RGBA_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
|
||||
if ( p === RGBA_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
|
||||
|
||||
} else {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ETC
|
||||
|
||||
if ( p === RGB_ETC1_Format || p === RGB_ETC2_Format || p === RGBA_ETC2_EAC_Format || p === R11_EAC_Format || p === SIGNED_R11_EAC_Format || p === RG11_EAC_Format || p === SIGNED_RG11_EAC_Format ) {
|
||||
|
||||
extension = extensions.get( 'WEBGL_compressed_texture_etc' );
|
||||
|
||||
if ( extension !== null ) {
|
||||
|
||||
if ( p === RGB_ETC1_Format || p === RGB_ETC2_Format ) return ( transfer === SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ETC2 : extension.COMPRESSED_RGB8_ETC2;
|
||||
if ( p === RGBA_ETC2_EAC_Format ) return ( transfer === SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC : extension.COMPRESSED_RGBA8_ETC2_EAC;
|
||||
if ( p === R11_EAC_Format ) return extension.COMPRESSED_R11_EAC;
|
||||
if ( p === SIGNED_R11_EAC_Format ) return extension.COMPRESSED_SIGNED_R11_EAC;
|
||||
if ( p === RG11_EAC_Format ) return extension.COMPRESSED_RG11_EAC;
|
||||
if ( p === SIGNED_RG11_EAC_Format ) return extension.COMPRESSED_SIGNED_RG11_EAC;
|
||||
|
||||
} else {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ASTC
|
||||
|
||||
if ( p === RGBA_ASTC_4x4_Format || p === RGBA_ASTC_5x4_Format || p === RGBA_ASTC_5x5_Format ||
|
||||
p === RGBA_ASTC_6x5_Format || p === RGBA_ASTC_6x6_Format || p === RGBA_ASTC_8x5_Format ||
|
||||
p === RGBA_ASTC_8x6_Format || p === RGBA_ASTC_8x8_Format || p === RGBA_ASTC_10x5_Format ||
|
||||
p === RGBA_ASTC_10x6_Format || p === RGBA_ASTC_10x8_Format || p === RGBA_ASTC_10x10_Format ||
|
||||
p === RGBA_ASTC_12x10_Format || p === RGBA_ASTC_12x12_Format ) {
|
||||
|
||||
extension = extensions.get( 'WEBGL_compressed_texture_astc' );
|
||||
|
||||
if ( extension !== null ) {
|
||||
|
||||
if ( p === RGBA_ASTC_4x4_Format ) return ( transfer === SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR : extension.COMPRESSED_RGBA_ASTC_4x4_KHR;
|
||||
if ( p === RGBA_ASTC_5x4_Format ) return ( transfer === SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR : extension.COMPRESSED_RGBA_ASTC_5x4_KHR;
|
||||
if ( p === RGBA_ASTC_5x5_Format ) return ( transfer === SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR : extension.COMPRESSED_RGBA_ASTC_5x5_KHR;
|
||||
if ( p === RGBA_ASTC_6x5_Format ) return ( transfer === SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR : extension.COMPRESSED_RGBA_ASTC_6x5_KHR;
|
||||
if ( p === RGBA_ASTC_6x6_Format ) return ( transfer === SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR : extension.COMPRESSED_RGBA_ASTC_6x6_KHR;
|
||||
if ( p === RGBA_ASTC_8x5_Format ) return ( transfer === SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR : extension.COMPRESSED_RGBA_ASTC_8x5_KHR;
|
||||
if ( p === RGBA_ASTC_8x6_Format ) return ( transfer === SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR : extension.COMPRESSED_RGBA_ASTC_8x6_KHR;
|
||||
if ( p === RGBA_ASTC_8x8_Format ) return ( transfer === SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR : extension.COMPRESSED_RGBA_ASTC_8x8_KHR;
|
||||
if ( p === RGBA_ASTC_10x5_Format ) return ( transfer === SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR : extension.COMPRESSED_RGBA_ASTC_10x5_KHR;
|
||||
if ( p === RGBA_ASTC_10x6_Format ) return ( transfer === SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR : extension.COMPRESSED_RGBA_ASTC_10x6_KHR;
|
||||
if ( p === RGBA_ASTC_10x8_Format ) return ( transfer === SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR : extension.COMPRESSED_RGBA_ASTC_10x8_KHR;
|
||||
if ( p === RGBA_ASTC_10x10_Format ) return ( transfer === SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR : extension.COMPRESSED_RGBA_ASTC_10x10_KHR;
|
||||
if ( p === RGBA_ASTC_12x10_Format ) return ( transfer === SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR : extension.COMPRESSED_RGBA_ASTC_12x10_KHR;
|
||||
if ( p === RGBA_ASTC_12x12_Format ) return ( transfer === SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR : extension.COMPRESSED_RGBA_ASTC_12x12_KHR;
|
||||
|
||||
} else {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// BPTC
|
||||
|
||||
if ( p === RGBA_BPTC_Format || p === RGB_BPTC_SIGNED_Format || p === RGB_BPTC_UNSIGNED_Format ) {
|
||||
|
||||
extension = extensions.get( 'EXT_texture_compression_bptc' );
|
||||
|
||||
if ( extension !== null ) {
|
||||
|
||||
if ( p === RGBA_BPTC_Format ) return ( transfer === SRGBTransfer ) ? extension.COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT : extension.COMPRESSED_RGBA_BPTC_UNORM_EXT;
|
||||
if ( p === RGB_BPTC_SIGNED_Format ) return extension.COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT;
|
||||
if ( p === RGB_BPTC_UNSIGNED_Format ) return extension.COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT;
|
||||
|
||||
} else {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// RGTC
|
||||
|
||||
if ( p === RED_RGTC1_Format || p === SIGNED_RED_RGTC1_Format || p === RED_GREEN_RGTC2_Format || p === SIGNED_RED_GREEN_RGTC2_Format ) {
|
||||
|
||||
extension = extensions.get( 'EXT_texture_compression_rgtc' );
|
||||
|
||||
if ( extension !== null ) {
|
||||
|
||||
if ( p === RED_RGTC1_Format ) return extension.COMPRESSED_RED_RGTC1_EXT;
|
||||
if ( p === SIGNED_RED_RGTC1_Format ) return extension.COMPRESSED_SIGNED_RED_RGTC1_EXT;
|
||||
if ( p === RED_GREEN_RGTC2_Format ) return extension.COMPRESSED_RED_GREEN_RGTC2_EXT;
|
||||
if ( p === SIGNED_RED_GREEN_RGTC2_Format ) return extension.COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT;
|
||||
|
||||
} else {
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
if ( p === UnsignedInt248Type ) return gl.UNSIGNED_INT_24_8;
|
||||
|
||||
// if "p" can't be resolved, assume the user defines a WebGL constant as a string (fallback/workaround for packed RGB formats)
|
||||
|
||||
return ( gl[ p ] !== undefined ) ? gl[ p ] : null;
|
||||
|
||||
}
|
||||
|
||||
return { convert: convert };
|
||||
|
||||
}
|
||||
|
||||
|
||||
export { WebGLUtils };
|
||||
Reference in New Issue
Block a user