ThreeJS WebGLRenderer renderObject 源码

735 阅读1分钟
  • //遍历渲染列表,如果是 摄像机阵列,再遍历摄像机,将object, scene, camera, geometry, material, group丢给renderObject处理单个物体。
function renderObjects( renderList, scene, camera ) { //透明和非透明物体
        // // 10.强制使用场景的材质 overrideMaterial 来统一 render 物体。
        const overrideMaterial =
                scene.isScene === true ? scene.overrideMaterial : null;
        for ( let i = 0, l = renderList.length; i < l; i ++ ) {
                const renderItem = renderList[ i ];
                const object = renderItem.object;
                const geometry = renderItem.geometry;
                const material =
                        overrideMaterial === null ? renderItem.material : overrideMaterial;
                const group = renderItem.group;
                if ( camera.isArrayCamera ) {
                        const cameras = camera.cameras;
                        for ( let j = 0, jl = cameras.length; j < jl; j ++ ) {
                                const camera2 = cameras[ j ];
                                if ( object.layers.test( camera2.layers ) ) {
                                        state.viewport( _currentViewport.copy( camera2.viewport ) );
                                        currentRenderState.setupLightsView( camera2 );
                                        renderObject( object, scene, camera2, geometry, material, group );
                                }
                        }
                } else {
                        renderObject( object, scene, camera, geometry, material, group );
                }
        }
}
  • renderObject就一个作用,判断物体是否为立即渲染物体(object.isImmediateRenderObject)
  • 立即渲染物体和普通物体表现在代码上的区别是,没有用到顶点数组对象(Vertex Array Object,简称 VAO),立即渲染物体直接获取object上的position、normal、uv和color数据丢进buffer,进行绘制。普通物体会在第一次绘制保存下position、normal、uv和color数据,下一帧绘制,如果没有改变,直接bindVertexArrayOES,就可以了,不用一个个bindBuffer。采用VAO的方式可以降低数据传输,在大场景绘制时,可以提高性能。
  • renderBufferDirect()方法是一个比较重要的方法,在这里可以看到一个物体被渲染的“最小完整流程”。
function renderObject( object, scene, camera, geometry, material, group ) {
        object.onBeforeRender( _this, scene, camera, geometry, material, group );
        object.modelViewMatrix.multiplyMatrices(
                camera.matrixWorldInverse,
                object.matrixWorld
        );
        object.normalMatrix.getNormalMatrix( object.modelViewMatrix );
        if ( object.isImmediateRenderObject ) {//
                const program = setProgram( camera, scene, material, object );
                state.setMaterial( material );
                bindingStates.reset();
                renderObjectImmediate( object, program );
        } else {

                _this.renderBufferDirect(
                        camera,
                        scene,
                        geometry,
                        material,
                        object,
                        group
                );
        }
        object.onAfterRender( _this, scene, camera, geometry, material, group );
}