后端 Shader中depth信息的存储与使用

这篇博客探讨了在Shader中如何使用和计算场景的深度数据。内容包括OpenGL投影矩阵的计算,顶点如何转化为投影空间,以及深度值在NDC空间和深度纹理中的存储方式。还介绍了使用浮点纹理存储深度信息的方法,如16位和32位的编码与解码过程,并提供了相关的代码示例。
摘要由CSDN通过智能技术生成

简言

在 shader 中我们会经常用到场景的 depth 数据,这里记录的是相关的坐标计算过程以及 depth 使用的技巧。

数学推算记录

在 OpenGL Projection Matrix 这里给出了投影矩阵的具体计算

顶点计算过程:
相机空间某点 point [x,y,z,1] 经过投影矩阵计算得到点–[xxx, xxx, Az+B, -z]–//point in 投影空间 A= -(f+n)/(f-n) B=-2fn/(f-n)
再经过 perspective division 得到———————–z_n=-A/z -B ———-//z in NDC 空间 z_n [-1,1]
depthBuffer 存储的深度值范围是【0,1】————–z_b=z_n*0.5+0.5;——//z in depthBuffer/Texture z_b [0,1]

推算:
z_view to z_b:

z_b= (far (z_view + near))/(z_view (far - near)); //———-range:[0,1]

z_b to z_view:

Reference

opengl - Getting the true z value from the depth buffer - Stack Overflow
Good night, Posterous

存储深度数据

介绍

  • 使用 DEPTH TEXTURE 存储深度信息

  • 利用 color encode 存储深度信息

利用 rgba 存储深度数据

vec2 PackDepth16( in float depth )
{
    float depthVal = depth * (256.0*256.0 - 1.0) / (256.0*256.0);
    vec3 encode = fract( depthVal * vec3(1.0, 256.0, 256.0*256.0) );
    return encode.xy - encode.yz / 256.0 + 1.0/512.0;
}

float UnpackDepth16( in vec2 pack )
{
  float depth = dot( pack, 1.0 / vec2(1.0, 256.0) );
  return depth * (256.0*256.0) / (256.0*256.0 - 1.0);
}

vec4 PackDepth32_orig(in float frag_depth) {
  vec4 bitSh = vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0);
  vec4 bitMsk = vec4(0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0);
  vec4 enc = fract(frag_depth * bitSh);
  enc -= enc.xxyz * bitMsk;
  return enc;
}

float UnpackDepth32_orig( const in vec4 enc ) {
  const vec4 bit_shift = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 );
  float decoded = dot( enc, bit_shift );
  return decoded;
}

Reference

javascript - Pack depth information in a RGBA texture using mediump precison - Stack Overflow
Encoding floats to RGBA - the final? · Aras' website

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值