• 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