简言
在 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