当前位置: 首页 > ai >正文

cesium FBO(四)自定义相机渲染到Canvas(离屏渲染)

前面几节的例子是将Cesium默认的相机渲染到纹理(RTT)或Canvas,这片文章讲解如何将自定义的一个camera的画面渲染到Canvas上,有了前面几篇的基础了,也能将自定义的画面渲染纹理、也可以灰度处理,原理是一样的。

一、效果

左上一是渲染到Canvas(灰度处理)的画面,右上一是渲染到Canvas正常画面,左下一是渲染到纹理的画面,右下一是自定义的camera视锥体。

二、实现

实现的原理还是基于第一篇的阐述的原理,主要分为以下步骤:

1.创建FBO

2.创建相机

3.将相机内容渲染到FBO

4.将FBO绘制到Canvas

通过前面几篇文章的讲解,其中1、4环节我们已经很熟悉了,这里说明一下2和3。

1)创建相机
    createFboCamera(scene) {let camera = new Cesium.Camera(scene);camera.setView({destination: Cesium.Cartesian3.fromDegrees(126.30158892175582, 35.02368795804565, 200000),orientation: {heading: Cesium.Math.toRadians(0.0), // 航向角,转换为弧度pitch: Cesium.Math.toRadians(-45),     // 俯仰角,转换为弧度  roll: Cesium.Math.toRadians(0.0),       // 翻滚角,转换为弧度}})//这里采用透视投影camera.frustum = new Cesium.PerspectiveFrustum({fov: Cesium.Math.toRadians(60),              // 视场角aspectRatio: 1, // 宽高比near: 1,            // 近裁剪面far: 500000               // 远裁剪面});let primitive = new Cesium.DebugCameraPrimitive({camera: camera,color: Cesium.Color.RED,show: true,});scene.primitives.add(primitive);return camera;}
2)将相机内容渲染到FBO

核心的思路是将场景默认的相机替换成自定义的相机,等渲染完成后再替换回来。主场景已经有一个事件循序在渲染了,我们再加一个势必会影响到性能。

cameraRenderToFbo(fbo, scene, fboCamera) {// 保存原始相机,并将fbo相机设置为当前相机let camera = scene._defaultView.camera;scene._defaultView.camera = fboCamera;// 获取场景的帧状态、WebGL上下文和uniform状态const frameState = scene._frameState;const context = scene.context;const us = context.uniformState;// 设置默认视图const view = scene._defaultView;scene._view = view;// 更新场景帧状态scene.updateFrameState();// 设置3DTiles渲染通道状态const renderTilesetPassState = Cesium.Cesium3DTilePass.getPassOptions(Cesium.Cesium3DTilePass.RENDER);frameState.passes.render = true;frameState.passes.postProcess = scene.postProcessStages.hasSelected;frameState.tilesetPassState = renderTilesetPassState;// 设置背景颜色,如果不是HDR模式需要进行gamma校正let backgroundColor = Cesium.defaultValue(scene.backgroundColor, Cesium.Color.BLACK);let scratchBackgroundColor = new Cesium.Color();if (!scene._hdr) {backgroundColor = Cesium.Color.clone(backgroundColor, scratchBackgroundColor);backgroundColor.red = Math.pow(backgroundColor.red, scene.gamma);backgroundColor.green = Math.pow(backgroundColor.green, scene.gamma);backgroundColor.blue = Math.pow(backgroundColor.blue, scene.gamma);}frameState.backgroundColor = backgroundColor;// 更新大气和雾效果frameState.atmosphere = scene.atmosphere;scene.fog.update(frameState);// 更新uniform状态us.update(frameState);// 处理阴影贴图const shadowMap = scene.shadowMap;if (Cesium.defined(shadowMap) && shadowMap.enabled) {if (!Cesium.defined(scene.light) || scene.light instanceof Cesium.SunLight) {// 将太阳方向取反,使其从太阳射向场景Cesium.Cartesian3.negate(us.sunDirectionWC, scene._shadowMapCamera.direction);} else {Cesium.Cartesian3.clone(scene.light.direction, scene._shadowMapCamera.direction);}frameState.shadowMaps.push(shadowMap);}// 清空命令列表scene._computeCommandList.length = 0;scene._overlayCommandList.length = 0;// 设置视口尺寸const viewport = view.viewport;viewport.x = 0;viewport.y = 0;viewport.width = context.drawingBufferWidth;viewport.height = context.drawingBufferHeight;// 设置通道状态const passState = view.passState;passState.framebuffer = fbo;passState.blendingEnabled = undefined;passState.scissorTest = undefined;passState.viewport = Cesium.BoundingRectangle.clone(viewport, passState.viewport);// 更新并执行渲染scene.updateEnvironment();scene.updateAndExecuteCommands(passState, backgroundColor);scene.resolveFramebuffers(passState);// 清理状态passState.framebuffer = undefined;context.endFrame();// 恢复原始相机和地球显示scene._defaultView.camera = camera;scene.globe.show = true;}

 好啦,关于Cesium的FBO的话题暂时搞一段了,请各位老铁点个赞,评个论啥的,感谢。

http://www.xdnf.cn/news/16739.html

相关文章:

  • 数据处理四件套:NumPy/Pandas/Matplotlib/Seaborn速通指南
  • ACM SIGCOMM 2024论文精选-01:5G【Prism5G】
  • Docker设置容器时间
  • 深度学习(鱼书)day08--误差反向传播(后三节)
  • PyTorch基础——张量计算
  • datax-cloud 智数通修订版(去除mapstruct)本地部署-记录
  • C语言-字符串(定义)、字符串函数(strlen、strcat、strcpy、strcmp、strlwr、strupr)
  • [CISCN 2022 初赛]online_crt
  • 【支持Ubuntu22】Ambari3.0.0+Bigtop3.2.0——Step7—Mariadb初始化
  • 【兆易创新】单片机GD32F103C8T6系列入门资料
  • xcode swift项目运行、连接真机运行报错,引入文件夹失败
  • 伞状Meta分析重构癌症幸存者照护指南:从矛盾证据到精准决策
  • 法国彩虹重磅发布EmVue:解锁能源监控新方式
  • 电商一键上货软件推荐:实在Agent、面兜兜、京老虎、妙手、青虎
  • 如何快速给PDF加书签--保姆级教程
  • Elasticsearch IK 中文分词器指南:从安装、配置到自定义词典
  • Java 22 新特性解析与代码示例
  • C++ 构造函数语义学
  • c++详解(宏与内联函数,nullptr)
  • MongoDB 详细用法与 Java 集成完整指南
  • Java应用服务器选型指南:WebLogic vs. Tomcat、WebSphere、JBoss/Wildfly
  • C++ 前缀和、双指针
  • Linux 硬盘分区管理
  • 代理IP并发控制:多线程爬虫的加速引擎
  • CSS的2D转换
  • 用 Ubuntu 22.04 (Jammy) 的 MongoDB 源
  • SpringBoot AI应用实战:从图像识别到预测分析
  • EasyExcel 格式设置大全
  • 3ds Max V-Ray渲染崩溃?8招告别卡顿冻结
  • [2025CVPR-图象生成方向]ODA-GAN:由弱监督学习辅助的正交解耦比对GAN 虚拟免疫组织化学染色