- If (material.version === materialProperties.__version) {// Update is involved here
function setProgram( camera, scene, material, object ) {
if( scene.isScene ! = =true ) scene = _emptyScene; // scene could be a Mesh, Line, Points, ...
textures.resetTextureUnits();
const fog = scene.fog;
const environment = material.isMeshStandardMaterial ? scene.environment : null;
const encoding = ( _currentRenderTarget === null)? _this.outputEncoding : _currentRenderTarget.texture.encoding;const envMap = cubemaps.get( material.envMap || environment );
const materialProperties = properties.get( material );
const lights = currentRenderState.state.lights;
if ( _clippingEnabled === true ) {
if ( _localClippingEnabled === true|| camera ! == _currentCamera ) {const useCache =
camera === _currentCamera &&
material.id === _currentMaterialId;
// we might want to call this function with some ClippingGroup
// object instead of the material, once it becomes feasible
/ / (# 8465, # 8379)clipping.setState( material, camera, useCache ); }}if ( material.version === materialProperties.__version ) {
if( material.fog && materialProperties.fog ! == fog ) { initMaterial( material, scene, object ); }else if( materialProperties.environment ! == environment ) { initMaterial( material, scene, object ); }else if( materialProperties.needsLights && ( materialProperties.lightsStateVersion ! == lights.state.version ) ) { initMaterial( material, scene, object ); }else if( materialProperties.numClippingPlanes ! = =undefined&& ( materialProperties.numClippingPlanes ! == clipping.numPlanes || materialProperties.numIntersection ! == clipping.numIntersection ) ) { initMaterial( material, scene, object ); }else if( materialProperties.outputEncoding ! == encoding ) { initMaterial( material, scene, object ); }else if ( materialProperties.envMap !== envMap ) {
initMaterial( material, scene, object );
}
} else {
initMaterial( material, scene, object );
materialProperties.__version = material.version;
}
let refreshProgram = false;
let refreshMaterial = false;
let refreshLights = false;
const program = materialProperties.program,
p_uniforms = program.getUniforms(),
m_uniforms = materialProperties.uniforms;
if ( state.useProgram( program.program ) ) {
refreshProgram = true;
refreshMaterial = true;
refreshLights = true;
}
if( material.id ! == _currentMaterialId ) { _currentMaterialId = material.id; refreshMaterial =true;
}
if( refreshProgram || _currentCamera ! == camera ) { p_uniforms.setValue( _gl,'projectionMatrix', camera.projectionMatrix );
if ( capabilities.logarithmicDepthBuffer ) {
p_uniforms.setValue( _gl, 'logDepthBufFC'.2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 ) );
}
if( _currentCamera ! == camera ) { _currentCamera = camera;// lighting uniforms depend on the camera so enforce an update
// now, in case this material supports lights - or later, when
// the next material that does gets activated:
refreshMaterial = true; // set to true on material change
refreshLights = true; // remains set until update done
}
// load material specific uniforms
// (shader material also gets them for the sake of genericity)
if ( material.isShaderMaterial ||
material.isMeshPhongMaterial ||
material.isMeshToonMaterial ||
material.isMeshStandardMaterial ||
material.envMap ) {
const uCamPos = p_uniforms.map.cameraPosition;
if( uCamPos ! = =undefined) { uCamPos.setValue( _gl, _vector3.setFromMatrixPosition( camera.matrixWorld ) ); }}if ( material.isMeshPhongMaterial ||
material.isMeshToonMaterial ||
material.isMeshLambertMaterial ||
material.isMeshBasicMaterial ||
material.isMeshStandardMaterial ||
material.isShaderMaterial ) {
p_uniforms.setValue( _gl, 'isOrthographic', camera.isOrthographicCamera === true );
}
if ( material.isMeshPhongMaterial ||
material.isMeshToonMaterial ||
material.isMeshLambertMaterial ||
material.isMeshBasicMaterial ||
material.isMeshStandardMaterial ||
material.isShaderMaterial ||
material.isShadowMaterial ||
material.skinning ) {
p_uniforms.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse ); }}// skinning uniforms must be set even if material didn't change
// auto-setting of texture unit for bone texture must go before other textures
// otherwise textures used for skinning can take over texture units reserved for other material textures
if ( material.skinning ) {
p_uniforms.setOptional( _gl, object, 'bindMatrix' );
p_uniforms.setOptional( _gl, object, 'bindMatrixInverse' );
const skeleton = object.skeleton;
if ( skeleton ) {
const bones = skeleton.bones;
if ( capabilities.floatVertexTextures ) {
if ( skeleton.boneTexture === null ) {
// layout (1 matrix = 4 pixels)
// RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)
// with 8x8 pixel texture max 16 bones * 4 pixels = (8 * 8)
// 16x16 pixel texture max 64 bones * 4 pixels = (16 * 16)
// 32x32 pixel texture max 256 bones * 4 pixels = (32 * 32)
// 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64)
let size = Math.sqrt( bones.length * 4 ); // 4 pixels needed for 1 matrix
size = MathUtils.ceilPowerOfTwo( size );
size = Math.max( size, 4 );
const boneMatrices = new Float32Array( size * size * 4 ); // 4 floats per RGBA pixel
boneMatrices.set( skeleton.boneMatrices ); // copy current values
const boneTexture = new DataTexture( boneMatrices, size, size, RGBAFormat, FloatType );
skeleton.boneMatrices = boneMatrices;
skeleton.boneTexture = boneTexture;
skeleton.boneTextureSize = size;
}
p_uniforms.setValue( _gl, 'boneTexture', skeleton.boneTexture, textures );
p_uniforms.setValue( _gl, 'boneTextureSize', skeleton.boneTextureSize );
} else {
p_uniforms.setOptional( _gl, skeleton, 'boneMatrices'); }}}if( refreshMaterial || materialProperties.receiveShadow ! == object.receiveShadow ) { materialProperties.receiveShadow = object.receiveShadow; p_uniforms.setValue( _gl,'receiveShadow', object.receiveShadow );
}
if ( refreshMaterial ) {
p_uniforms.setValue( _gl, 'toneMappingExposure', _this.toneMappingExposure );
if ( materialProperties.needsLights ) {
// the current material requires lighting info
// note: all lighting uniforms are always set correctly
// they simply reference the renderer's state for their
// values
//
// use the current material's .needsUpdate flags to set
// the GL state when required
markUniformsLightsNeedsUpdate( m_uniforms, refreshLights );
}
// refresh uniforms common to several materials
if ( fog && material.fog ) {
materials.refreshFogUniforms( m_uniforms, fog );
}
materials.refreshMaterialUniforms( m_uniforms, material, _pixelRatio, _height );
WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, textures );
}
if ( material.isShaderMaterial && material.uniformsNeedUpdate === true ) {
WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, textures );
material.uniformsNeedUpdate = false;
}
if ( material.isSpriteMaterial ) {
p_uniforms.setValue( _gl, 'center', object.center );
}
// common matrices
p_uniforms.setValue( _gl, 'modelViewMatrix', object.modelViewMatrix );
p_uniforms.setValue( _gl, 'normalMatrix', object.normalMatrix );
p_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );
return program;
}
Copy the code