Cesium高阶学习五、离屏渲染

一、简介
离屏渲染 顾名思义就是离开屏幕的渲染,就是说场景的渲染结果不直接显示到屏幕上,而是作为纹理使用或者需要经过一些加工后再显示到屏幕上。WebGL编程指南可查详细解释(帧缓冲区对象 可以用来代替颜色缓冲区或深度缓冲区。绘制在帧缓冲区的对象并不会直接显示在canvas上,你可以先对帧缓冲区的内容进行一些处理再显示,或者直接用其中的内容作为纹理图像。在帧缓冲区中进行绘制的过程又称为离屏绘制。)
在这里插入图片描述

二、Cesium中的离屏渲染示例
Cesium是基于WebGL封装的,所以Cesium的离屏渲染也就是WebGL的离屏渲染,即通过帧缓冲区对象来实现,webgl中通过gl.createFramebuffer()来创建帧缓冲区对象,Cesium的渲染模块将对原生webgl的帧缓冲区相关的操作封装到了FrameBuffer类中。
在这里插入图片描述

如果您了解Ceisum的渲染流程或者观看过前一章节“Cesium绘制渲染流程”您就会知道Cesium默认的绘制就是使用的离屏渲染,先将场景渲染到到合适的FrameBuffer中,然后交交给后处理程序,最后才会显示到屏幕上。

Scene.prototype.resolveFramebuffers = function (passState) {
   
...
 if (usePostProcess) {
   
    view.sceneFramebuffer.prepareColorTextures(context);
    let inputFramebuffer = sceneFramebuffer;
    if (useGlobeDepthFramebuffer && !useOIT) {
   
      inputFramebuffer = globeFramebuffer;
    }

    const postProcess = this.postProcessStages;
    const colorTexture = inputFramebuffer.getColorTexture(0);
    const idTexture = idFramebuffer.getColorTexture(0);
    const depthTexture = defaultValue(
      globeFramebuffer,
      sceneFramebuffer
    ).getDepthStencilTexture();
    postProcess.execute(context, colorTexture, depthTexture, idTexture);
    postProcess.copy(context, defaultFramebuffer);
  }
  ...
}

1、Cesium中离屏渲染应用之Picking类:要使用Cesium的离屏渲染,我们还可以先参考Cesium对场景拾取类Picking的封装,Picking类主要封装了场景中拾取的相关方法,比如鼠标点击拾取位置、鼠标点击拾取对象,我们在使用时是通过scene.pickPosition()、scene.pick(),但其实内部都是通过Picking类来实现的。

/**
 * Returns an object with a <code>primitive</code> property that contains the first (top) primitive in the scene
 * at a particular window coordinate or undefined if nothing is at the location. Other properties may
 * potentially be set depending on the type of primitive and may be used to further identify the picked object.
 * <p>
 * When a feature of a 3D Tiles tileset is picked, <code>pick</code> returns a {@link Cesium3DTileFeature} object.
 * </p>
 * @param {Scene} scene
 * @param {Cartesian2} windowPosition Window coordinates to perform picking on.
 * @param {number} [width=3] Width of the pick rectangle.
 * @param {number} [height=3] Height of the pick rectangle.
 * @returns {object} Object containing the picked primitive.
 */
Picking.prototype.pick = function (scene, windowPosition, width, height) {
   
  ...
};

/**
 * Returns an object with information about the voxel sample rendered at
 * a particular window coordinate. Returns <code>undefined</code> if there is no
 * voxel at that position.
 *
 * @param {Scene} scene
 * @param {Cartesian2} windowPosition Window coordinates to perform picking on.
 * @param {number} [width=3] Width of the pick rectangle.
 * @param {number} [height=3] Height of the pick rectangle.
 * @returns {object|undefined} Object containing the picked primitive.
 */
Picking.prototype.pickVoxelCoordinate = function (
  scene,
  windowPosition,
  width,
  height
) {
   
  ...
};


Picking.prototype.pickPositionWorldCoordinates = function (
  scene,
  windowPosition,
  result
) {
    
  ...
}; 

Picking.prototype.pickPosition = function (scene, windowPosition, result) {
   
  ...
};
2、我们可以重点看一下pick方法的实现
Picking.prototype.pick = function (scene, windowPosition, width, height) {
   
  //>>includeStart('debug', pragmas.debug);
  Check.defined("windowPosition", windowPosition);
  //>>includeEnd('debug');

  scratchRectangleWidth = defaultValue(width, 3.0);
  scratchRectangleHeight = defaultValue(height, scratchRectangleWidth);

  const {
    context, frameState, defaultView } = scene;
  const {
    viewport, pickFramebuffer } = defaultView;

  scene.view = defaultView;

  viewport.x = 0;
  viewport.y = 0;
  viewport.width = context.drawingBufferWidth;
  viewport.height = context.drawingBufferHeight;

  let passState = defaultView.passState;
  passState.viewport = BoundingRectangle.clone(viewport, passState.viewport);

  const drawingBufferPosition = SceneTransforms.transformWindowToDrawingBuffer(
    scene,
    windowPosition,
    scratchPosition
  )
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cesium进阶学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值