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)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值