three.js 中的 perspectiveDepthToViewZ

three.js 中的 perspectiveDepthToViewZ

ref:
https://blog.csdn.net/qq_35158695/article/details/120907217

https://mynameismjp.wordpress.com/2010/09/05/position-from-depth-3/

https://mynameismjp.wordpress.com/2009/03/10/reconstructing-position-from-depth/

https://blog.csdn.net/qq_35158695/article/details/120907217

投影矩阵

P c l i p = [ 2 n r − l 0 r + l r − l 0 0 2 n t − b t + b t − b 0 0 0 A B 0 0 − 1 0 ] ∗ P v i e w P_{clip} = \left[ \begin{matrix} \frac{2n}{r-l} & 0 & \frac{r+l}{r-l} & 0 \\ 0 & \frac{2n}{t-b} & \frac{t+b}{t-b} & 0 \\ 0 & 0 & A &B \\ 0 & 0 & -1 & 0 \end{matrix} \right] * P_{view} Pclip=rl2n0000tb2n00rlr+ltbt+bA100B0Pview

其中:
A = − f + n f − n A = -\frac{f+n}{f-n} A=fnf+n

B = − 2 f n f − n B= \frac{-2fn}{f-n} B=fn2fn

那么:

z c l i p = − ( f + n ) f − n z v i e w + − 2 f n f − n (1-1) z_{clip} = \frac{-(f+n)}{f-n} z_{view}+ \frac{-2fn}{f-n} \tag{1-1} zclip=fn(f+n)zview+fn2fn(1-1)

z = z v i e w z = z_{view} z=zview, z n d c z_{ndc} zndc有:

z n d c = − ( f + n ) f − n z + − 2 f n f − n − z = f + n + 2 f n 1 z f − n = f z + n z + 2 f n ( f − n ) z (1-2) \begin{aligned} z_{ndc} &= \frac{ \frac{-(f+n)}{f-n} z + \frac{-2fn}{f-n}} {-z} \\ &= \frac{f+n+2fn \frac{1}{z}}{f-n} \\ &= \frac{fz+nz+2fn } {(f-n)z} \\ \end{aligned} \tag{1-2} zndc=zfn(f+n)z+fn2fn=fnf+n+2fnz1=(fn)zfz+nz+2fn(1-2)

2 深度纹理

深度纹理 depthBuffer 的 depth 范围是 0 ~ 1, z n d c z_{ndc} zndc范围是 -1~1

d e p t h = z n d c 1 2 + 1 2 (1-3) depth = z_{ndc} \frac{1}{2} + \frac{1}{2} \tag{1-3} depth=zndc21+21(1-3)

式子(1-2)带入到(1-3),有:

d e p t h = f z + n z + 2 f n 2 ( f − n ) z + ( f − n ) z 2 ( f − n ) z = f z + n z + 2 f n + f z − n z 2 f z − 2 n z = f z + f n f z − n z = ( n + z ) f ( f − n ) z (1-4) \begin{aligned} depth &= \frac{fz+nz+2fn } {2(f-n)z} + \frac{(f-n)z}{2(f-n)z} \\ &= \frac{fz+nz+2fn+fz-nz}{2fz-2nz} \\ &= \frac{fz+fn}{fz-nz} \\ &= \frac{(n+z)f}{(f-n)z} \end{aligned} \tag{1-4} depth=2(fn)zfz+nz+2fn+2(fn)z(fn)z=2fz2nzfz+nz+2fn+fznz=fznzfz+fn=(fn)z(n+z)f(1-4)

z v i e w = n f d ( f − n ) − f z_{view} = \frac{nf}{d(f-n)-f} zview=d(fn)fnf

code
// NOTE: https://twitter.com/gonnavis/status/1377183786949959682
// 根据viewZ得到深度
float viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {
	return ( ( near + viewZ ) * far ) / ( ( far - near ) * viewZ );
}

// 根据深度信息得到 viewZ
float perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {
	return ( near * far ) / ( ( far - near ) * invClipZ - far );
}
可视化深度
float readDepth( sampler2D depthSampler, vec2 coord ) {
    float fragCoordZ = texture2D( depthSampler, coord ).x;

    // viewZ 即渲染片段和摄影机之间的z距离
    float viewZ = perspectiveDepthToViewZ( fragCoordZ, cameraNear, cameraFar );
    return viewZToOrthographicDepth( viewZ, cameraNear, cameraFar );
}

void main() {
    // readDepth() will return a linearized depth value that will be used to compute the fragment's color value
    float depth = readDepth( tDepth, vUv );

    gl_FragColor.rgb = 1.0 - vec3( depth ); // change this bit to invert colors
    gl_FragColor.a = 1.0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值