cesium 渲染解析(Scene的调度机制)

在上一篇博文中,我们模拟了绘制太阳的方法,为地球添加了赤道平面, 美中不足的是,轨道平面常会被地球给挡住。下面我们详细分析scene的调度机制。

先看一下这个结构,Cesium把绘制命令(DrawCommand)分成不同的PASS, 处在不同PASS的对象,他们的绘制循序也不相同,这个跟osg里面的RenderBin的概念非常类似。

var Pass = {
  // If you add/modify/remove Pass constants, also change the automatic GLSL constants
  // that start with 'czm_pass'
  //
  // Commands are executed in order by pass up to the translucent pass.
  // Translucent geometry needs special handling (sorting/OIT). The compute pass
  // is executed first and the overlay pass is executed last. Both are not sorted
  // by frustum.
  ENVIRONMENT: 0,
  COMPUTE: 1,
  GLOBE: 2,
  TERRAIN_CLASSIFICATION: 3,
  CESIUM_3D_TILE: 4,
  CESIUM_3D_TILE_CLASSIFICATION: 5,
  CESIUM_3D_TILE_CLASSIFICATION_IGNORE_SHOW: 6,
  OPAQUE: 7,
  TRANSLUCENT: 8,
  OVERLAY: 9,
  NUMBER_OF_PASSES: 10,
};
function executeCommands(scene, passState) {
    var camera = scene.camera;
    var context = scene.context;
    var frameState = scene.frameState;
    var us = context.uniformState;

    us.updateCamera(camera);

executeCommand是场景调度的核心函数, 对所有的commands进行管理和调度。

    // Create a working frustum from the original camera frustum.
    var frustum;
    if (defined(camera.frustum.fov)) {
        frustum = camera.frustum.clone(scratchPerspectiveFrustum);
    } else if (defined(camera.frustum.infiniteProjectionMatrix)) {
        frustum = camera.frustum.clone(scratchPerspectiveOffCenterFrustum);
    } else if (defined(camera.frustum.width)) {
        frustum = camera.frustum.clone(scratchOrthographicFrustum);
    } else {
        frustum = camera.frustum.clone(scratchOrthographicOffCenterFrustum);
    }

上面的代码中对视锥进行赋值,为什么会有三种类型的视锥?他们有何区别? 这里我们先留下这个疑问。继续往下走代码

for (var i = 0; i < numFrustums; ++i) {
        var index = numFrustums - i - 1;
        var frustumCommands = frustumCommandsList[index];

        if (scene.mode === SceneMode.SCENE2D) {
            // To avoid z-fighting in 2D, move the camera to just before the frustum
            // and scale the frustum depth to be in [1.0, nearToFarDistance2D].
            camera.position.z = height2D - frustumCommands.near + 1.0;
            frustum.far = Math.max(1.0, frustumCommands.far - frustumCommands.near);
            frustum.near = 1.0;
            us.update(frameState);
            us.updateFrustum(frustum);
        } else {
            // Avoid tearing artifacts between adjacent frustums in the opaque passes
            frustum.near =
                index !== 0 ?
                frustumCommands.near * scene.opaqueFrustumNearOffset :
                frustumCommands.near;
            frustum.far = frustumCommands.far;
            us.updateFrustum(frustum);
        }
        ...
}

主要的内容都在这个大循环里面,针对每个视锥体做绘制。总体的流程 

Frustum|------pass0|---- command0

             |                 |-----command1

             |                 |-----command 2

             |------pass1|-----command0

             |                 |-----command1

             |                 |-----command2

下面开始分析这个大循环里面的东西:

        clearDepth.execute(context, passState);

        if (context.stencilBuffer) {
            clearStencil.execute(context, passState);
        }
        us.updatePass(Pass.GLOBE);
        var commands = frustumCommands.commands[Pass.GLOBE];
        var length = frustumCommands.indices[Pass.GLOBE];
        ......
        for (j = 0; j < length; ++j) {
                executeCommand(commands[j], scene, context, passState);
        }

开始Pass.GLOBE的绘制,在这之前,先执行了clearDepth, clearStencil命令。然后执行了所有的属于改Pass的绘制命令。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值