- render函数
// Rendering
this.render = function ( scene, camera ) {
let renderTarget, forceClear;
if ( arguments[ 2 ] !== undefined ) {
console.warn(
'THREE.WebGLRenderer.render(): the renderTarget argument has been removed. Use .setRenderTarget() instead.'
);
renderTarget = arguments[ 2 ];
}
if ( arguments[ 3 ] !== undefined ) {
console.warn(
'THREE.WebGLRenderer.render(): the forceClear argument has been removed. Use .clear() instead.'
);
forceClear = arguments[ 3 ];
}
if ( camera !== undefined && camera.isCamera !== true ) {
console.error(
'THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.'
);
return;
}
if ( _isContextLost === true ) return;
// update scene graph
//即更新整个场景图,主要就是更新每个物体的 matrix。如果其含有孩子节点,则还会逐级更新。在这里,每个物体的 matrix 是通过其 position,quaternion以及scale 计算得来的,也就是其模型矩阵,而 matrixWorld 又是根据 matrix 计算得来的。如果当前节点没有父节点,则 matrix 就是 matrixWorld。而如果有的话,那 matrixWorld 则为父节点的 matrixWorld 与当前节点 matrix 的叉乘。也就是说当前节点的 matrixWorld 是相对于其父亲节点的。
if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
// update camera matrices and frustum
if ( camera.parent === null ) camera.updateMatrixWorld();
if ( xr.enabled === true && xr.isPresenting === true ) {
camera = xr.getCamera( camera );
}
if ( scene.isScene === true )
scene.onBeforeRender(
_this,
scene,
camera,
renderTarget || _currentRenderTarget
);
// 4. init WebGLRenderState
currentRenderState = renderStates.get( scene, renderStateStack.length );
currentRenderState.init();
renderStateStack.push( currentRenderState );
// 5.视景体矩阵计算,为相机的投影矩阵与相机的世界矩阵的逆矩阵的叉乘?
_projScreenMatrix.multiplyMatrices(
camera.projectionMatrix,
camera.matrixWorldInverse
);
_frustum.setFromProjectionMatrix( _projScreenMatrix );
_localClippingEnabled = this.localClippingEnabled;
_clippingEnabled = clipping.init(
this.clippingPlanes,
_localClippingEnabled,
camera
);
// 6.WebGLRenderList 的初始化
// WebGLRenderList 的初始化init()方法本身并没有什么,其只是在 WebGLRenderLists 中通过将 scene.id 和 camera.id 建立起一定的关联。
currentRenderList = renderLists.get( scene, renderListStack.length );
currentRenderList.init();
renderListStack.push( currentRenderList );
//而这里更重要的目的是确定有哪些对象是要被渲染出来的,这个最主要的实现就在 projectObject() 方法中。
projectObject( scene, camera, 0, _this.sortObjects );
currentRenderList.finish();
if ( _this.sortObjects === true ) {
currentRenderList.sort( _opaqueSort, _transparentSort );
}
// 7. shadow 的绘制
if ( _clippingEnabled === true ) clipping.beginShadows();
const shadowsArray = currentRenderState.state.shadowsArray;
shadowMap.render( shadowsArray, scene, camera );
currentRenderState.setupLights();
currentRenderState.setupLightsView( camera );
if ( _clippingEnabled === true ) clipping.endShadows();
//
if ( this.info.autoReset === true ) this.info.reset();
if ( renderTarget !== undefined ) {
this.setRenderTarget( renderTarget );
}
// 8.背景的绘制
background.render( currentRenderList, scene, camera, forceClear );
// render scene
// 11.分别对 opaque 和 transparent 的物体进行 render
const opaqueObjects = currentRenderList.opaque; // 可见物体
const transparentObjects = currentRenderList.transparent; // 透明物体
// opaque pass (front-to-back order)
if ( opaqueObjects.length > 0 ) renderObjects( opaqueObjects, scene, camera ); //不同的流程
// transparent pass (back-to-front order)
if ( transparentObjects.length > 0 )
renderObjects( transparentObjects, scene, camera );
//
if ( _currentRenderTarget !== null ) {
// Generate mipmap if we're using any kind of mipmap filtering
textures.updateRenderTargetMipmap( _currentRenderTarget );
// resolve multisample renderbuffers to a single-sample texture if necessary
textures.updateMultisampleRenderTarget( _currentRenderTarget );
}
//
if ( scene.isScene === true ) scene.onAfterRender( _this, scene, camera );
// Ensure depth buffer writing is enabled so it can be cleared on next render
state.buffers.depth.setTest( true );
state.buffers.depth.setMask( true );
state.buffers.color.setMask( true );
state.setPolygonOffset( false );
// _gl.finish();
bindingStates.resetDefaultState();
_currentMaterialId = - 1;
_currentCamera = null;
renderStateStack.pop();
if ( renderStateStack.length > 0 ) {
currentRenderState = renderStateStack[ renderStateStack.length - 1 ];
} else {
currentRenderState = null;
}
renderListStack.pop();
if ( renderListStack.length > 0 ) {
currentRenderList = renderListStack[ renderListStack.length - 1 ];
} else {
currentRenderList = null;
}
};
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END