首页 > 其他 > 详细

关于OpenGL nativeZ 到 LinearZ 精度缺失问题探究

时间:2021-05-17 13:48:56      阅读:17      评论:0      收藏:0      [点我收藏+]

我再看其他引擎的时候看到一个点,就是他先渲染不透明物体到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 的精度

技术分享图片

可以看到这个精度缺失了比较多 ,都能差了15%了

 

关于OpenGL nativeZ 到 LinearZ 精度缺失问题探究

原文:https://www.cnblogs.com/dragon2012/p/14775696.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!