openGL 是如何得出公式 F_depth 的,这就是窗口视口变换吗

2023-12-03

#point no.1

after transforming points via the projection matrix , we end up with the point in the range [-1,1],
but, in the depth testing chapter , the author mentions that
F_depth = 1/z-1/far /(1/near - 1/far) converts the view space coordinates i.e. z=zeye is transformed from [-1,1] to [0,1] .

我已经关注了这个线程,其中一位成员告诉我这个公式F_depth实际上是完成的一系列步骤的组合,并概述了这一步:

    z_Clip = C*z_eye+D*W_eye
    w_Clip = -z_eye
    where C=-(f+n)/(f-n), D=-2fn/(f-n).
    Projective division:
    z_ndc = z_clip/w_clip
    Depth range:
    depth = a + (a-b)*(z_ndc+1)/2
    where glDepthRange(a,b) .

我尝试编写公式正如他所建议的,但这与F_depth公式中给出学习openGL.

#point no. 2

另一位成员告诉我,[-1,1] 到 [0,1] 是窗口视口变换,它有一个公式本身不同.

所以,所有这一切对我来说没有任何意义(对于 openGL 的同一件事有 3 个不同的公式和解释),我将列出我对这些相互矛盾的想法的疑问:

  • F_depth 是从视图空间到窗口的变换的组合 空间。
  • 深度范围变换和视口变换是 相同的?为什么他们有不同的论坛(其中一个Point no.1和 另一个在这个链接
  • F_depth公式是如何得到的呢?或者说构图怎么样 将世界空间点转换为 [0,1] 的转换次数 导致F_depth?

在 @horxCoder 的答案中缺少一些步骤,我想澄清一下。

在教程中LearnOpenGL - 深度测试据称深度为透视投影 is

depth = (1/z - 1/n) / (1/f - 1/n)

where z是到视点的距离,n是到近平面的距离,f是到远平面的距离视锥体.

问题是为什么片段的深度是由上面的公式给出的?


对称透视投影矩阵是(参见OpenGL 投影矩阵):

1/(ta*a)  0      0              0
0         1/ta   0              0
0         0     -(f+n)/(f-n)   -2fn/(f-n)
0         0     -1              0

对于深度,我们只感兴趣z and w成分。对于输入顶点(x_眼、y_眼、z_眼、w_眼),剪辑空间z_clip and w_clip分量的计算方法为:

z_Clip = C * z_eye + D * W_eye
w_Clip = -z_eye

where

C = -(f+n) / (f-n)
D = -2fn / (f-n)

标准化设备空间z坐标由以下公式计算观点分歧

z_ndc = z_clip / w_clip

标准化设备空间z坐标映射到深度范围[a, b] (see glDepthRange):

depth = a + (a-b) * (z_ndc+1)/2

当我们假设深度范围是[0, 1]输入顶点是笛卡尔坐标 (x_eye, y_eye, z_eye, 1),这导致以下结果:

             z_eye * -(f+n) / (f-n)  +  -2fn / (f-n)
depth  =  (------------------------------------------ + 1) / 2
                          -z_eye

并且可以变形

             -z_eye * (f+n)  -  2fn
depth  =  (-------------------------- + 1) / 2
               -z_eye  *  (f-n)
             -z_eye * (f+n)  -  2fn  +  -z_eye * (f-n)
depth  =  ---------------------------------------------
                      -z_eye  *  (f-n)  * 2
             -z_eye * (f+n+f-n)  -  2fn
depth  =  -------------------------------
               -z_eye  *  (f-n)  * 2
             -z_eye * f  -  fn           -f (n + z_eye)  
depth  =  -----------------------   =   ----------------
               -z_eye * (f-n)             z_eye (n - f)

由于视图空间 z 轴指向视口之外,因此z从视点到顶点的距离是z = -z_eye。这导致:

          f (n - z)        1/z - 1/n
depth  =  -----------  =  -----------
          z (n - f)        1/f - 1/n
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

openGL 是如何得出公式 F_depth 的,这就是窗口视口变换吗 的相关文章

  • libgdx 中帧缓冲区的结果不明确

    我得到以下奇怪的结果帧缓冲区 http libgdx badlogicgames com nightlies docs api com badlogic gdx graphics glutils FrameBuffer htmllibgdx
  • 如何以编程方式在 qml 中渲染 vtk 项目?

    到目前为止 我了解到我们在 QML 中有两个线程 我们的主应用程序线程和我们的 场景图 线程 http doc qt io qt 5 qtquick visualcanvas scenegraph html http doc qt io q
  • OpenGL 将着色器附加到程序

    有没有办法访问附加到程序的着色器 也就是说 给定一个程序 我可以做类似的事情 vertexShader getVertexShaderFromProgram program 我想在验证我的程序的函数中记录着色器编译状态 但我只保留对程序的引
  • 静态链接库时出现 glew 链接器错误

    我正在尝试在 Visual Studio 2012 中构建一个 opengl 项目 我想静态包含 glew 库 因此我从源代码构建它并将生成的 glew32sd lib 复制到我的 lib 目录 我将此 lib 路径提供给 Visual S
  • 将glm四元数转换为旋转矩阵并与opengl一起使用

    所以我将对象的方向存储在 glm fquat 中 我想用它来旋转我的模型 我怎么做 我试过这个 glPushMatrix glTranslatef position x position y position z glMultMatrixf
  • Opengl 非同步/非阻塞地图

    我刚刚找到以下内容OpenGL 规范ARB map buffer range http www opengl org registry specs ARB map buffer range txt 我想知道是否可以使用此扩展进行非阻塞地图调
  • 对 VBO 中的特定三角形使用不同的纹理

    我有 9 个由三角形组成的四边形 如下所示 我在用着VBO存储有关它们的数据 它们的位置和纹理坐标 我的问题是 是否可以仅使用一个来使四边形 5 具有与其余四边形不同的纹理VBO and shader 绿色代表纹理 1 黄色代表纹理 2 到
  • 没有着色器的 OpenGL

    我已经阅读了一些教程来编写以下代码 唯一的区别是原始教程使用 SDL 而不是 GLEW 我不明白这段代码有什么问题 它可以编译 但我没有看到三角形 教程也没有使用着色器 include
  • 哪个对缓存最友好?

    我试图很好地掌握面向数据的设计以及如何在考虑缓存的情况下进行最佳编程 基本上有两种情况我无法完全确定哪个更好以及为什么 是拥有一个对象向量更好 还是拥有对象原子数据的多个向量更好 A 对象向量示例 struct A GLsizei mInd
  • 数据编织转换

    我有 POST 方法的以下有效负载的输入 order Column X X Column Y Y Column Z Z Column W div 1 some text div 2 true div 3 2 mapper A
  • 使用 Qt 在 xoverlay 之上绘制

    我希望在使用 Xoverlay 渲染的视频流之上绘制一些 UI 我正在使用 gstreamer 播放视频并使用 xoverlay 在 xvimagesink 上渲染它 我的小部件继承自 QGLWidget 我希望使用 QPainter 绘制
  • 即使在顶点着色器中使用,glGetUniformLocation()也会返回-1

    我正在尝试用法线渲染一个简单的立方体 我使用以下代码来初始化着色器 void initShader const char vertexShaderPath const char fragmentShaderPath cout lt lt I
  • openGL转png

    我正在尝试将包含大量纹理 没有移动 的 openGL 编辑 我画的卡片 thx unwind 转换为一个 PNG 文件 我可以在框架的另一部分中使用该文件我正在与 有 C 库可以做到这一点吗 thanks 如果您的意思只是 获取由 Open
  • lwjgl 3 , glUniformMatrix4 导致 jre 崩溃

    我正在使用 lwjgl 3 并学习现代 opengl 3 我想将统一矩阵发送到顶点着色器 以便我可以应用转换 我尝试过 但程序因此错误而崩溃 A fatal error has been detected by the Java Runti
  • OpenGL 与 Eclipse CDT + MinGW + GLEW + GLFW:未定义的参考

    Edit 与此同时 我已经弄清楚了这一点 并在下面写了详细的答案 我刚刚尝试在 Win7 上从 Express 版本的 MSVC 10 切换到 Eclipse CDT 在配置时遇到了以下简单 OpenGL 代码的问题 在 Visual St
  • glut 库中缺少 glutInitContextVersion()

    我正在练习一些 opengl 代码 但是当我想通过以下方式强制 opengl 上下文使用特定版本的 opengl 时glutInitContextVersion 它编译过程失败并给出以下消息 使用未声明的标识符 glutInitContex
  • 在 GLUT 中使用鼠标滚轮

    我想在 OpenGL GLUT 程序中使用鼠标滚轮来放大和缩小场景 我怎么做 Freeglut 的 glutMouseWheelFunc 回调与版本相关 并且在 X 中不可靠 使用标准鼠标功能并测试按钮 3 和 4 OpenGlut 对 g
  • 在 Linux 上运行我自己的程序的权限被拒绝? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我有Ubuntu 9 4 我已经构建了程序 一些基本的 OpenGL 该程序只是制作一个旋转的正方形 然后运行它并 sh blabla p
  • 使用 Matrix.setPolyToPoly 选择位图上具有 4 个点的区域

    我正在 Android 上使用位图 在使用 4 个点选择位图上的区域时遇到问题 并非所有 4 点组都适合我 在某些情况下 结果只是一个空白位图 而不是裁剪后的位图 如图所示 并且 logcat 中没有任何错误 甚至是内存错误 这是我用来进行
  • 使用 JOGL 和 Android OpenGL 编写可移植 Java 应用程序

    我计划编写一款可以在 PC 和 Android 上运行的 Java 3D 游戏 不幸的是 这两个平台似乎没有通用的 OpenGL API API 是否有显着差异 有没有办法在两个版本中使用相同的 3D 代码 这是不是一个好主意 Androi

随机推荐