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

Cesium 和 three.js 对数深度缓冲原理简析

对数深度缓冲原理

为啥需要对数深度?

深度缓冲通常使用 浮点数 来存储深度值,但浮点数的精度有限,尤其是在处理远距离物体时,深度值之间的差异可能非常小,导致精度不足,出现 深度冲突 (Z-Fighting) 问题。

为了解决这个问题,可以使用 对数深度 (Logarithmic Depth) 技术。对数深度将线性深度值转换为对数空间,从而提高远距离物体的深度精度。

1、普通深度
float z_clip = gl_Position.z;// gl_Position.w = -z_view, 这是应用对数的关键点
float w_clip = gl_Position.w;// [-1, 1]
float z_ndc = z_clip/w_clip;// [0, 1]
float depth = z_ndc * 0.5 + 0.5;gl_FragDepth = gl_FragCoord.z = depth;
2、对数深度原理

普通对数变换到0~1之间:

请添加图片描述

普通 z n d c z_{ndc} zndc图像:

y n o r a m l = ( f + n ) f − n + 2 f n ( f − n ) z y_{noraml} =\ \frac{\left(f+n\right)}{f-n}+\frac{2fn}{\left(f-n\right)z} ynoraml= fn(f+n)+(fn)z2fn

使用直接对 z v i e w z_{view} zview取对数:

y l o g T h r e e = log ⁡ 2 ( − z + 1 ) ( 1 log ⁡ 2 ( f + 1 ) ) y_{logThree}=\log_{2}\left(-z+1\right)\left(\frac{1}{\log_{2}\left(f+1\right)}\right) ylogThree=log2(z+1)(log2(f+1)1)

$near = 0.1, far = 5 $时, 的图像:

请添加图片描述

3、Cesium 实现对数深度

y l o g C e s i u m = log ⁡ 2 ( − z − n + 1 ) ( 1 log ⁡ 2 ( f − n + 1 ) ) y_{logCesium} =\log_{2}\left(-z-n+1\right)\left(\frac{1}{\log_{2}\left(f-n+1\right)}\right) ylogCesium=log2(zn+1)(log2(fn+1)1)

const czm_oneOverLog2FarDepthFromNearPlusOne = 1.0 / CesiumMath.log2(frustum.far - frustum.near + 1.0);
void czm_writeLogDepth() {float depth = (gl_Position.w - czm_currentFrustum.x) + 1.0;gl_FragDepth = log2(depth) * czm_oneOverLog2FarDepthFromNearPlusOne;
}
4、three.js 实现对数深度
const logDepthBufFC = 2.0 / ( Math.log( camera.far + 1.0 ) / Math.LN2 );
gl_FragDepth = log2( 1.0 + gl_Position.w ) * logDepthBufFC * 0.5;

y l o g T h r e e = log ⁡ 2 ( − z + 1 ) ( 1 log ⁡ 2 ( f + 1 ) ) y_{logThree}=\log_{2}\left(-z+1\right)\left(\frac{1}{\log_{2}\left(f+1\right)}\right) ylogThree=log2(z+1)(log2(f+1)1)

处理一下 log ⁡ 2 ( f + 1 ) \log_{2}(f+1) log2(f+1), 应用对数的换底公式:
log ⁡ a b = log ⁡ c b log ⁡ c a \log_ab = \frac{\log_cb}{\log_ca} logab=logcalogcb

log ⁡ 2 ( f + 1 ) = log ⁡ e ( f + 1 ) log ⁡ e ( 2 ) \log_{2}(f+1) = \frac{\log_e(f+1)}{\log_e(2)} log2(f+1)=loge(2)loge(f+1)

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【58同城-注册安全分析报告】
  • 计算机网络 TCPUDP、IP、ARPRARP、NAT总结
  • 源代码加密软件有哪些?11款超好用的源代码加密软件推荐
  • chapter08-面向对象编程——(Object类详解)——day09
  • ubuntu c++ http服务端event使用
  • AI学习记录 - 模型训练中怎么反向传播以及学习率的影响
  • 《黑神话悟空》幽魂无脑攻略分享
  • Axure设计之Web端交互元件库
  • 设计模式之工厂模式和策略模式的区别
  • 深入垃圾回收:理解GC的核心算法与实现
  • 移位操作存储多个布尔值或标志位
  • 自闭症儿童上普校,会面临霸凌吗?
  • Datawhale X 李宏毅苹果书 AI夏令营_深度学习基础学习心得Task2.2
  • 【经验分享】CANOPEN协议驱动移植(基于CANfestival源码架构)
  • Unity3D DOTS中ECS核心架构详解
  • JavaScript-如何实现克隆(clone)函数
  • 2017年终总结、随想
  • bootstrap创建登录注册页面
  • canvas实际项目操作,包含:线条,圆形,扇形,图片绘制,图片圆角遮罩,矩形,弧形文字...
  • Java 23种设计模式 之单例模式 7种实现方式
  • java正则表式的使用
  • Map集合、散列表、红黑树介绍
  • Nginx 通过 Lua + Redis 实现动态封禁 IP
  • opencv python Meanshift 和 Camshift
  • 电商搜索引擎的架构设计和性能优化
  • 给初学者:JavaScript 中数组操作注意点
  • 后端_MYSQL
  • 记一次删除Git记录中的大文件的过程
  • 前端性能优化--懒加载和预加载
  • 微信公众号开发小记——5.python微信红包
  • 学习Vue.js的五个小例子
  • 云大使推广中的常见热门问题
  • Play Store发现SimBad恶意软件,1.5亿Android用户成受害者 ...
  • ​14:00面试,14:06就出来了,问的问题有点变态。。。
  • ​力扣解法汇总1802. 有界数组中指定下标处的最大值
  • # 详解 JS 中的事件循环、宏/微任务、Primise对象、定时器函数,以及其在工作中的应用和注意事项
  • #Linux(make工具和makefile文件以及makefile语法)
  • #NOIP 2014# day.2 T2 寻找道路
  • (22)C#传智:复习,多态虚方法抽象类接口,静态类,String与StringBuilder,集合泛型List与Dictionary,文件类,结构与类的区别
  • (delphi11最新学习资料) Object Pascal 学习笔记---第2章第五节(日期和时间)
  • (delphi11最新学习资料) Object Pascal 学习笔记---第5章第5节(delphi中的指针)
  • (el-Transfer)操作(不使用 ts):Element-plus 中 Select 组件动态设置 options 值需求的解决过程
  • (阿里云万网)-域名注册购买实名流程
  • (二)十分简易快速 自己训练样本 opencv级联lbp分类器 车牌识别
  • (附源码)springboot课程在线考试系统 毕业设计 655127
  • (个人笔记质量不佳)SQL 左连接、右连接、内连接的区别
  • (黑马出品_高级篇_01)SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式
  • (蓝桥杯每日一题)平方末尾及补充(常用的字符串函数功能)
  • (四)搭建容器云管理平台笔记—安装ETCD(不使用证书)
  • (转)Oracle存储过程编写经验和优化措施
  • (自适应手机端)行业协会机构网站模板
  • *p++,*(p++),*++p,(*p)++区别?
  • .java 9 找不到符号_java找不到符号
  • .mkp勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .NET Conf 2023 回顾 – 庆祝社区、创新和 .NET 8 的发布