- if ( material.version === materialProperties.__version ) { //这里涉及到更新
function setProgram( camera, scene, material, object ) {
if ( scene.isScene !== true ) scene = _emptyScene;
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;
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;
refreshMaterial = true;
refreshLights = true;
}
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 );
}
}
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 ) {
let size = Math.sqrt( bones.length * 4 );
size = MathUtils.ceilPowerOfTwo( size );
size = Math.max( size, 4 );
const boneMatrices = new Float32Array( size * size * 4 );
boneMatrices.set( skeleton.boneMatrices );
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 ) {
markUniformsLightsNeedsUpdate( m_uniforms, refreshLights );
}
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 );
}
p_uniforms.setValue( _gl, 'modelViewMatrix', object.modelViewMatrix );
p_uniforms.setValue( _gl, 'normalMatrix', object.normalMatrix );
p_uniforms.setValue( _gl, 'modelMatrix', object.matrixWorld );
return program;
}