OpenGL, 图像坐标系下z值转深度值计算

翻译:
Real depth in OpenGL / GLSL - Before I Forget…
有一个需求:用openGL做球形贴图。需要前后移动相机观测球体,当相机位置超出球体时看到的内容从球体内表面变成球体外表面。
方案一:超出时,计算哪些片段属于前半球,不要渲染这些片段;
方案二:在片段着色器用深度值判断;

首先看一下这个公式.

A   = -(zFar + zNear) / (zFar - zNear);
B   = -2*zFar*zNear / (zFar - zNear);

A 和B分别是视锥体透视投影(perspective)的投影矩阵的3行3列(3,3)和4列(3,4)。
通常线性照相机模型最后Project矩阵左乘顶点向量后gl_position值变成:

[...,..., Az+B, -z]

然后顶点shader跑完,openGL自动做透视划分:
g l _ p o s i t i o n = v e c 4 ( x , y , z , w ) ; o u t = ( x / w y / w z / w ) gl\_position =vec4(x,y,z,w); \\ out = \begin{pmatrix} x /w \\ y / w \\ z / w \end{pmatrix} gl_position=vec4(x,y,z,w);out=x/wy/wz/w
那么 z n = z / w z_n=z/w zn=z/w 就是点在vertex Shader最终输出的gl_position 做透视划分后的向量的z值.
所以 z n z_n zn的计算公式为:

z_n = -(Az_e + B) / z_e; // z_n in [-1, 1]
z_b = 0.5
z_n + 0.5; // z_b in [0, 1]

z_b 是把透视划分后的点从[-1,1]映射到[0,1](深度缓存值范围).

以上是片段着色器每个点的深度值计算原理。在片段着色器clip一下透明值,就可以解决绘制一个物体时被遮挡的问题。例如我只要视野内球体内部.其截面法线垂直于我的视线:
这里写图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值