Cesium渲染模块之Command

博客 动态
0 187
羽尘
羽尘 2023-03-15 01:26:27
悬赏:0 积分 收藏

Cesium渲染模块之Command

1. 引言

Cesium是一款三维地球和地图可视化开源JavaScript库,使用WebGL来进行硬件加速图形,使用时不需要任何插件支持,基于Apache2.0许可的开源程序,可以免费用于商业和非商业用途

Cesium官网:Cesium: The Platform for 3D Geospatial

Cesium GitHub站点:CesiumGS/cesium: An open-source JavaScript library for world-class 3D globes and maps (github.com)

API文档:Index - Cesium Documentation

通过阅读源码,理清代码逻辑,有助于扩展与开发,笔者主要参考了以下两个系列的文章

渲染是前端可视化的核心,本文描述Cesium渲染模块的Command

2. Cesium中的Command

Cesium中的Command对象包含执行的指令参数和执行方法,比如最简单的ClearCommand

function ClearCommand(options) {
  // ...
  this.color = options.color;
  this.depth = options.depth;
  this.stencil = options.stencil;
  this.renderState = options.renderState;
  this.framebuffer = options.framebuffer;
  this.owner = options.owner;
  this.pass = options.pass;
}
 
ClearCommand.prototype.execute = function (context, passState) {
  context.clear(this, passState);
};
 

ClearCommand包含颜色、深度、通道等指令参数和执行方法context.clear(this, passState)

Command对象主要有三类:

  • ClearCommand
  • DrawCommand
  • ComputeCommand

正如其名,ClearCommand用于清除,DrawCommand用于绘制,ComputeCommand用于计算

3. ClearCommand

ClearCommand的封装很简单,如上述代码所示:

function ClearCommand(options) {
  // ...
  this.color = options.color;
  this.depth = options.depth;
  this.stencil = options.stencil;
  this.renderState = options.renderState;
  this.framebuffer = options.framebuffer;
  this.owner = options.owner;
  this.pass = options.pass;
}
 
ClearCommand.prototype.execute = function (context, passState) {
  context.clear(this, passState);
};

context.clear()会执行清除的WebGL指令:

Context.prototype.clear = function (clearCommand, passState) {
  // ...
  const c = clearCommand.color;
  const d = clearCommand.depth;
  const s = clearCommand.stencil;

  gl.clearColor(c.red, c.green, c.blue, c.alpha);
  gl.clearDepth(d);
  gl.clearStencil(s);

  bindFramebuffer(this, framebuffer);
  gl.clear(bitmask);
};

ClearCommand在Scene中的调用:

初始化Scene时初始化ClearCommand

function Scene(options) {
  // ...
  this._clearColorCommand = new ClearCommand({
    color: new Color(),
    stencil: 0,
    owner: this,
  });
  // ...
}

执行更新时调用ClearCommandexecute()方法

Scene.prototype.updateAndExecuteCommands = function (passState, backgroundColor) {
    // ...
    updateAndClearFramebuffers(this, passState, backgroundColor);
    // ...
};
function updateAndClearFramebuffers(scene, passState, clearColor) {
  // ...
  // Clear the pass state framebuffer.
  const clear = scene._clearColorCommand;
  Color.clone(clearColor, clear.color);
  clear.execute(context, passState);
  // ...
}

4. DrawCommand

DrawCommand是最常用的指令,它是绘制的主角

DrawCommand封装如下:

function DrawCommand(options) {
  options = defaultValue(options, defaultValue.EMPTY_OBJECT);

  this._boundingVolume = options.boundingVolume;
  this._orientedBoundingBox = options.orientedBoundingBox;
  this._modelMatrix = options.modelMatrix;
  this._primitiveType = defaultValue(
    options.primitiveType,
    PrimitiveType.TRIANGLES
  );
  this._vertexArray = options.vertexArray;
  this._count = options.count;
  this._offset = defaultValue(options.offset, 0);
  this._instanceCount = defaultValue(options.instanceCount, 0);
  this._shaderProgram = options.shaderProgram;
  this._uniformMap = options.uniformMap;
  this._renderState = options.renderState;
  this._framebuffer = options.framebuffer;
  this._pass = options.pass;
  this._owner = options.owner;
  this._debugOverlappingFrustums = 0;
  this._pickId = options.pickId;
  // ...
}

DrawCommand.prototype.execute = function (context, passState) {
  context.draw(this, passState);
};

context.draw()执行WebGL的绘制指令:

Context.prototype.draw = function (drawCommand, passState, shaderProgram, uniformMap) {
  // ...
  beginDraw(this, framebuffer, passState, shaderProgram, renderState);
  continueDraw(this, drawCommand, shaderProgram, uniformMap);
};

function continueDraw(context, drawCommand, shaderProgram, uniformMap) {
  // ...
  va._bind();
  context._gl.drawArrays(primitiveType, offset, count);
  // ...
  va._unBind();
}
posted @ 2023-03-14 23:57  当时明月在曾照彩云归  阅读(1)  评论(0编辑  收藏  举报
回帖
    羽尘

    羽尘 (王者 段位)

    2335 积分 (2)粉丝 (11)源码

     

    温馨提示

    亦奇源码

    最新会员