OpenGL:关于获取渲染结果的深度信息的问题(二)

23 篇文章 4 订阅
19 篇文章 0 订阅

前面记录了一下存在的问题和大致的解决方法
OpenGL:关于获取渲染结果的深度信息的问题_六月的翅膀的博客-CSDN博客


下面就验证一下

先定义一个指针变量和一个成员函数
 

GLfloat* depth_value = NULL;//保存缓冲区里的深度信息

void updateDepthValue();

成员函数具体为
 

void GlWidget::updateDepthValue()
{
    int WINDOW_WIDTH = (int)_width;
    int WINDOW_HEIGHT = (int)_height;
    glReadPixels(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT,GL_DEPTH_COMPONENT, GL_FLOAT, depth_value);
}

注意,这里获得的深度值是0-1之间的(我查看的结果是非常接近1,大都在0.998以上,其实就是非线性变换的结果),就是Fdepth

这里关于深度值有个非线性变换,上图。这个非线性变换的曲线可以画出来看一下(这个在线画图的工具挺好用:数字王国 - 数学工具

大致形状就是这种,x轴越小表示具体观察者越近,相应的映射的范围就越大(即x轴正方向所有点全部映射到y轴0-1之间,而x轴0-2这段区间就占了y轴的90%左右了),这样变换的目的是越远的物体,需要的精度就可以越宽松一点。

其中near和far在我这里是自定义写入的


 near=0.01,far=10,将Fdepth、near和far代入,就可以求得Z,这个Z就是在near-far这个区间。

在paintGL()函数结尾调用updateDepthValue

void GlWidget::paintGL()
{
    ...//
    ...//渲染部分
    updateDepthValue();
    
}

然后通过一个按钮连接槽函数,每次按钮按下时,查看当前深度信息

for (int y = WINDOW_HEIGHT-1; y >=0 ; y--)
    {
        for (int x = 0; x < WINDOW_WIDTH; x++)
        {
            GLfloat iii=depth_value[(y*WINDOW_WIDTH + x)];
            uchar RGB_value = 1/(-99.9*iii+100);
            if(y==WINDOW_HEIGHT/2)
                qDebug()<<RGB_value ;
            //蓝色
            tmpBIT[0] = RGB_value;
            //绿色
            tmpBIT[1] = RGB_value;
            //红色
            tmpBIT[2] = RGB_value;
            tmpBIT[3] = 255;//不起作用
            tmpBIT += 4;
        }
    }

输出的结果如下:10代表距离无穷远

 然后可以把结果再次归一化到255之间,将深度信息保存为图像

void GlWidget::saveFrameBuff_2(const char *fileName)
{

    int WINDOW_WIDTH = (int)_width;
    int WINDOW_HEIGHT = (int)_height;
    QImage* img=new QImage(WINDOW_WIDTH,WINDOW_HEIGHT,QImage::Format_ARGB32);
    uchar* tmpBIT = img->bits();

    for (int y = WINDOW_HEIGHT-1; y >=0 ; y--)
    {
        for (int x = 0; x < WINDOW_WIDTH; x++)
        {
            GLfloat iii=depth_value[(y*WINDOW_WIDTH + x)];
            uchar RGB_value = 1/(-99.9*iii+100)/10*255;
            if(y==WINDOW_HEIGHT/2)
                qDebug()<<RGB_value;
            //蓝色
            tmpBIT[0] = RGB_value;
            //绿色
            tmpBIT[1] = RGB_value;
            //红色
            tmpBIT[2] = RGB_value;
            tmpBIT[3] = 255;//不起作用
            tmpBIT += 4;
        }
    }
    img->save("a.png");
}

渲染图

深度图


相关文章:

OpenGL Projection Matrix

OpenGL投影矩阵(Projection Matrix)构造方法 - 知乎 

OpenGL中的深度值winz与相机空间z值的关系推导_lysc_forever的博客-CSDN博客_opengl深度值与z值

OpenGL_深度测试_线性深度值_会敲code的猫的博客-CSDN博客_opengl深度值

opengl 投影矩阵转换获取得到near far,视场角等方法_XR风云的博客-CSDN博客 

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用Native OpenGL渲染Unity场景需要以下步骤: 1. 创建一个Native Plugin项目,并将OpenGL渲染代码添加到其中。 2. 在Unity中导入该Native Plugin,并在需要渲染的场景对象或摄像机上添加一个脚本,该脚本将调用Native Plugin中的OpenGL渲染函数。 3. 在渲染过程中,您需要将Unity场景中的模型、纹理、材质等信息转换为OpenGL可用的数据格式,并在OpenGL上下文中进行渲染。 下面是具体实现的步骤: 1. 创建一个Native Plugin项目 在Visual Studio中创建一个C++项目,选择“DLL”作为项目类型。然后将OpenGL渲染代码添加到该项目中。 2. 导入Native Plugin到Unity 将Native Plugin生成的DLL文件和相关头文件拷贝到Unity项目的Assets/Plugins目录下,然后在Unity中创建一个脚本,用于调用Native Plugin中的OpenGL渲染函数。 在脚本中使用DllImport特性引入Native Plugin中的函数,并在需要渲染的场景对象或摄像机上添加该脚本。 ``` using UnityEngine; using System.Runtime.InteropServices; public class OpenGLRenderer : MonoBehaviour { [DllImport("NativePlugin")] private static extern void RenderFrame(); void OnPostRender() { GL.PushMatrix(); GL.LoadOrtho(); RenderFrame(); GL.PopMatrix(); } } ``` 3. 渲染Unity场景 在OpenGL渲染函数中,您需要将Unity场景中的模型、纹理、材质等信息转换为OpenGL可用的数据格式,并在OpenGL上下文中进行渲染。 以下是一个简单的OpenGL渲染函数实现,用于渲染Unity场景: ``` void RenderFrame() { // 清空颜色缓冲区和深度缓冲区 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 获取摄像机矩阵 Matrix4x4 cameraMatrix = Camera.main.worldToCameraMatrix; float[] cameraMatrixArray = Matrix4x4ToArray(cameraMatrix); // 获取投影矩阵 Matrix4x4 projectionMatrix = Camera.main.projectionMatrix; float[] projectionMatrixArray = Matrix4x4ToArray(projectionMatrix); // 绑定Unity场景中的纹理 Texture2D texture = GetComponent<Renderer>().material.mainTexture; int textureID = texture.GetNativeTexturePtr().ToInt32(); glBindTexture(GL_TEXTURE_2D, textureID); // 绘制模型 glBegin(GL_TRIANGLES); // 顶点坐标 glVertex3f(0.0f, 0.5f, 0.0f); glVertex3f(-0.5f, -0.5f, 0.0f); glVertex3f(0.5f, -0.5f, 0.0f); // 纹理坐标 glTexCoord2f(0.0f, 1.0f); glTexCoord2f(1.0f, 0.0f); glTexCoord2f(0.0f, 0.0f); glEnd(); // 刷新OpenGL缓冲区 glFlush(); } ``` 以上是使用Native OpenGL渲染Unity场景的基本步骤,您可以根据自己的需求进行相应的调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值