关于OpenGL nativeZ 到 LinearZ 精度缺失问题探究
我再看其他引擎的时候看到一个点,就是他先渲染不透明物体到NativeZ,后面根据这个深度图,得到LinearZ
这里OpenGL教程里面也有
https://learnopengl.com/Advanced-OpenGL/Depth-testing
然后周末我自己也这样做了,后面反复思考这样有没有问题
下面是我做的实验代码
投影矩阵我是看这里写的
https://zhuanlan.zhihu.com/p/73034007
#include<stdio.h> #include<conio.h> #include<windows.h> #include<iostream> #include <cassert> //计算nativeZ float NativeZ(float nearv, float farv, float EyePosZ) { float zx = (farv + nearv) / (farv - nearv) + (2.0 * farv* nearv / (farv - nearv)) / EyePosZ; return zx; } //NativeZ to LinearZ float LinearizeDepth(float nearv,float farv,float Nativedepth) { float z = Nativedepth * 2.0 - 1.0; // back to NDC return (2.0 * nearv * farv) / (farv + nearv - z * (farv - nearv)) /(farv -nearv); } //自己计算LinearZ,不依赖NativeZ float MyLinearCalc(float nearv, float farv, float eyePosZ) { float zv = -eyePosZ; //Opengl相机空间里 z是负值 float x = (zv -nearv) / (farv - nearv); return x; } const float CameraFar = 4000; const float CameraNear = 2; int main() { const int stepN = 40; for (int n = 0; n < stepN; ++n) { float eyePosZ = -n * (CameraFar -CameraNear) / (float)stepN - CameraNear; float nativeZ = NativeZ(CameraNear, CameraFar, eyePosZ); float linearv = LinearizeDepth(CameraNear, CameraFar, nativeZ); float myCalcZ = MyLinearCalc(CameraNear, CameraFar, eyePosZ); printf("nativeZ:%f %f %f \n", nativeZ,linearv,myCalcZ); } int delay; scanf("%d",&delay); }
代码很容易,先计算NativeZ,然后这个NativeZ 变换到Linearz,这是float32 的精度
这里写错了,有空来改