从深度缓冲区获取真实的 z 值

2023-11-26

正如预期的那样,从着色器中的深度缓冲区采样会返回 0 到 1 之间的值。 给定相机的近剪裁平面和远剪裁平面,如何计算此时的真实 z 值,即距相机的距离?


From http://web.archive.org/web/20130416194336/http://olivers.posterous.com/linear-depth-in-glsl-for-real

// == Post-process frag shader ===========================================
uniform sampler2D depthBuffTex;
uniform float zNear;
uniform float zFar;
varying vec2 vTexCoord;
void main(void)
{
    float z_b = texture2D(depthBuffTex, vTexCoord).x;
    float z_n = 2.0 * z_b - 1.0;
    float z_e = 2.0 * zNear * zFar / (zFar + zNear - z_n * (zFar - zNear));
}

[编辑] 所以这是解释(有两个错误,请参阅下面克里斯蒂安的评论):

An OpenGL perspective matrix looks like this : from songho.ca

当你将该矩阵乘以齐次点 [x,y,z,1] 时,它会给出:[不关心,不关心,Az+B,-z](A 和 B 是 2 个大分量在矩阵中)。

OpenGL 接下来进行透视除法:它将这个向量除以它的 w 分量。此操作不是在着色器中完成的(除了阴影贴图等特殊情况),而是在硬件中完成;你无法控制它。 w = -z,因此Z值变为-A/z -B。

我们现在处于标准化设备坐标中。 Z值在0和1之间。由于某些愚蠢的原因,OpenGL要求它应该移动到[-1,1]范围(就像x和y一样)。应用缩放和偏移。

然后将该最终值存储在缓冲区中。

上面的代码恰恰相反:

  • z_b 是存储在缓冲区中的原始值
  • z_n 将 z_b 从 [-1,1] 线性变换到 [0,1]
  • z_e 与 z_n=-A/z_e -B 的公式相同,但求解为 z_e。它相当于 z_e = -A / (z_n+B)。顺便说一句,A 和 B 应该在 CPU 上计算并作为制服发送。

相反的函数是:

varying float depth; // Linear depth, in world units
void main(void)
{
    float A = gl_ProjectionMatrix[2].z;
    float B = gl_ProjectionMatrix[3].z;
    gl_FragDepth  = 0.5*(-A*depth + B) / depth + 0.5;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从深度缓冲区获取真实的 z 值 的相关文章

  • 根据 GLSL 中向量的特定分量执行最小-最大的最快方法?

    我需要在我的 GLSL 代码中多次调用这种函数 vec2 minx vec2 a vec2 b if a x lt b x return a else return b 我担心过度分支 有没有办法避免 if else 结构 我建议使用 GL
  • 数学/算法使图像适合屏幕保留纵横比

    我需要数学 算法方面的帮助来拍摄已知尺寸的图像并适合两个屏幕尺寸之一 720 x 480 或 1280 x 1024 图像尺寸来自 XML 文件 但这些尺寸是 Web 尺寸 我还从 XML 中选择了一些图像 这些图像的分辨率可能比 Web
  • 关闭 Löve2D 中的抗锯齿功能

    我在用着L ve2D http love2d org用于编写一个小游戏 L ve2D 是 Lua 的开源游戏引擎 我遇到的问题是 当您在非整数位置绘制精灵时 某些抗锯齿过滤器会自动应用于精灵 love graphics draw sprit
  • 将签名位图转换为签名字符串(很奇怪的一个)

    基本上我需要将位图图像转换为字符串 但这不是常见的 困境在于该字符串由两部分组成 1 积分 2 线路 我需要将图像转换为由 分隔的两个部分 我得到的一个例子是 221A 221A270A270A25032503200720071716171
  • 即使手动设置显示环境变量后,WSL Ubuntu 也会显示“错误:无法打开显示”

    我在 WSL Ubuntu 上使用 g 我使用 git 克隆了 GLFW 存储库 使用了ccmake命令配置并生成二进制文件 然后使用make在 build 目录中最终创建 a文件 我安装了所有OpenGL相关的库 usr ld 我不记得我
  • 如何使用边缘和内部镶嵌因子完成三角形面片镶嵌?

    I am just learning tessellation and i came across with below example for triangle patch tessellation but i am not sure h
  • 更改组合框下拉列表边框的颜色

    My code Private Sub ComboBox2 DrawItem sender As Object e As DrawItemEventArgs Handles ComboBox2 DrawItem If e Index lt
  • 更改 GLUT 调用以与 MFC/C++ 一起使用

    我有一个使用 GLUT 进行 OpenGL 渲染的程序 现在我需要它位于 MFC 项目内部 以便它可以与另一个程序组件一起使用 我已经按照这个教程进行操作 http www codeguru com cpp g m opengl openf
  • 致命错误 gl.h 包含在 glew.h 之前

    include
  • 在 C++ GPGPU 库中嵌入 cg 着色器

    我正在编写一个 GPGPU 流体模拟 它使用 C OpenGL Cg 运行 目前 该库要求用户指定着色器的路径 然后从中读取它 我发现必须在我自己的项目和测试中指定这一点非常烦人 因此我希望将着色器内容与其余内容链接起来 理想情况下 我的
  • 编译 GLUI 库,VS2010 给我一个奇怪的命名空间错误

    我有一个针对我所在班级的 OpenGL 项目 它基于 GLUI 提供的 GLUI 库无法工作 这就是我尝试自己编译它的原因 因此 我从 SourceForge 下载了源代码并尝试编译 glui 库 它给了我这个 但我找不到任何相关信息 1
  • 简单的openGL程序无法在ubuntu中链接

    我正在尝试进入 opengl 编程 但无法编译我的第一个非常非常简单的程序 链接过程每次都会失败 我发现这个答案 https stackoverflow com questions 859501 learning opengl in ubu
  • 什么是稀疏体素八叉树?

    我读了很多关于稀疏体素八叉树在未来图形引擎中的潜在用途的文章 但是我一直无法找到有关它们的技术信息 我理解体素是什么 但是我不知道稀疏体素八叉树是什么 或者它们如何比现在使用的多边形技术更有效 有人可以解释或指出我对此的解释吗 这是一个关于
  • x86 asm 图形设置的分辨率高于 640x480?

    我刚刚开始使用汇编语言 感觉像学习新东西 并且遇到了一些问题 到目前为止 我一直在浏览的所有教程都没有回答 或者太旧而无法知道 1 我尝试了一些搜索 也许我只是不知道正确的关键字 但我找不到用于更改屏幕分辨率等的图形模式的更新列表 我发现的
  • 如何在 GLSL 1.3 和 OpenGL 2.1 中使用位运算

    我正在尝试编写一个使用许多位操作的着色器 事实上 从 glsl 1 30 开始就支持它们 但我只使用 OpenGL 2 1 有没有办法在我的 OpenGL 版本中使用位运算 所有 SM3 兼容 OpenGL 2 1 硬件支持limited整
  • OpenGL:顶点越多,性能越慢

    我正在开发一个程序的一部分 其中给定 xyz 坐标集合 制作 3D 模型 我已经完成了这张图片所需的所有功能 即平移 旋转 缩放 但是给出的 xyz 坐标越多 程序运行速度就越慢 我的程序在处理 29 000 个坐标时运行得非常流畅 但当我
  • 为什么 OpenGL 有远裁剪平面,以及使用什么惯用法来处理这个问题?

    我一直在学习 OpenGL 持续困扰我的一个话题是远裁剪平面 虽然我可以理解近剪裁平面和侧剪裁平面 它们永远不会产生任何实际效果 因为它们之外的对象无论如何都不会被渲染 背后的推理 但远剪裁平面似乎只是一个烦恼 由于 OpenGL 背后的人
  • 如何在 SceneKit 中以编程方式将 png 纹理包裹在立方体周围

    我是 SceneKit 的新手 试图让一些基本的东西工作 但到目前为止还没有取得多大成功 由于某种原因 当我尝试将 png 纹理应用于 CNBox 时 我最终除了黑色之外什么也没有 这是我在 viewDidLoad 中的简单代码片段 let
  • 在 QML 中控制纹理 3D 对象的不透明度

    我对 QML 中的 Qt 3D 有点陌生 我正在尝试控制 Qt 3D 的不透明度textured3D 对象 我正在使用简单qml3d https github com tripolskypetr simpleqml3d测试项目来做到这一点
  • 在 3D 场景中实现“抓取”相机平移工具

    在我的场景中 我有想要 抓取 的地形 然后在移动光标时让相机平移 其高度 视图向量 视野等全部保持不变 因此 最初的 抓取 点将是世界空间中的工作点 我希望在拖动时该点保留在光标下方 我当前的解决方案是获取前一个和当前的屏幕点 取消投影它们

随机推荐

  • 创建圆形启动器图标

    我试图在 Android Studio 2 2 中创建圆形启动器图标 但它们总是呈方形 有人遇到过这种情况么 难道我做错了什么 点击后Next你应该得到圆形启动器图标 预览可能会产生误导 因为它们以背景作为图标 毕竟 如果您没有得到您所期望
  • C++ 如何初始化部分模板特化的静态变量

    我应该如何初始化静态变量以实现部分特化 template
  • 如何将变量写入文件?

    我想储存 Username 输出文件中的值 E g If Username equals 0401190926729000 该值将存储在文件中 这是一个建议 Settings Library OperatingSystem Library
  • 共享与非共享定点组合器

    这是 Haskell 中定点组合器的通常定义 fix a gt a gt a fix f let x f x in x On https wiki haskell org Prime numbers 他们定义了一个不同的定点组合器 Y t
  • 如何使用 Javascript/jQuery 从 div 内容中去除 HTML 标签?

    我做了一个div标签并将其内容存储在变量中 如果这个标签包含p b或任何其他标签 那么应该将其从字符串中删除 我怎样才能实现这个目标 使用正则表达式 var regex lt gt gt ig var body p test p var r
  • 如何在 mac osx 上安装 libksba?

    根据rvm要求 对于Ruby 1 9 3 安装libksba 如果使用Homebrew brew install libksba 我是全新的 不熟悉终端命令 如何在不使用 homebrew 的情况下安装 libksba 请帮忙 我刚刚从源代
  • 基于 GUI 或基于 Web 的 JSON 编辑器,其工作方式类似于属性资源管理器 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心以获得指导 背景 这是对可能尚不存在的
  • sbt 0.11:使用企业 Maven 存储库

    如何将企业 Maven 存储库与 sbt 0 11 x 一起使用 排除其他存储库 如中所述如何让 sbt 使用本地 Maven 代理存储库 Nexus 没有提到ivyRepositories在 github 的新 sbt wiki 中 所以
  • C++ 预处理器元编程图灵完备吗?

    我知道 C 模板元编程是图灵完备的 同样的事情也适用于预处理器元编程吗 宏不会直接递归扩展 但我们可以通过一些方法来解决这个问题 在预处理器中执行递归的最简单方法是使用延迟表达式 延迟表达式是需要更多扫描才能完全扩展的表达式 define
  • 当文本框获得焦点时选择文本框的内容

    我在中找到了与我类似的问题使 WinForms TextBox 的行为类似于浏览器的地址栏 现在我正在尝试通过使其通用来修改或使其更加不同 我想对表单中的所有文本框应用相同的操作 而不需要为每个文本框编写代码 我不知道有多少 一旦我在表单中
  • 打包一个Python应用程序

    如何打包和分发由多个文件组成的Python应用程序 我的应用程序需要一个必须由用户填写的配置文件 我想我正在寻找类似于我在 Linux 机器上使用的配置 制作 制作安装 制作文档的步骤 有不同的解决方案可用 每种解决方案都涉及您的代码库遵守
  • PowerShell/CLI:具有多个数组的“Foreach”循环

    我有一个 PowerCLI 脚本 可以关闭虚拟机电源 更改其内存和 CPU 然后重新启动 我已经调整了脚本以利用变量 这一切都很完美 我现在正在尝试修改脚本以利用数组 以便循环遍历多个虚拟机 关闭和打开虚拟机电源的脚本部分运行良好 我遇到的
  • 在Java中查询系统(不是JVM)正常运行时间[重复]

    这个问题在这里已经有答案了 JavaSE 6 中是否有一种与操作系统无关的方法来查询系统 不是 JVM 我知道 RuntimeMXBean getUptime 正常运行时间 Thanks 是和不是 有系统特定查询正常运行时间的方式 例如 n
  • 使用 C# SQL 插入查询

    我目前遇到一个问题 正在尝试解决 我只是尝试在 C 的帮助下访问数据库并插入一些值 我尝试过的事情 有效 String query INSERT INTO dbo SMS PW id username password email VALU
  • 使用与列同名的变量对 data.table 进行子集化

    我想对 a 进行子集化data table使用与列同名的变量会导致一些问题 dt lt data table a sample c a b c 20 replace TRUE b sample c a b c 20 replace TRUE
  • 如何在jquery中的特定字符之后分割字符串[重复]

    这个问题在这里已经有答案了 这是我的代码 var string1 Hello how are you 我想要一个在 之后的字符串 即整个字符串中的 you 假设该字符串始终有一个 字符 并且我希望该字符之后的所有字符串都位于 jquery
  • 有没有办法将系统日志消息重定向到标准输出?

    我有一个可以以两种模式运行的应用程序 使用 CLI 或作为守护程序 我在用syslog 用于记录 但是 当在 CLI 模式下运行时 我想要所有日志记录 除了那些标记的日志记录LOG DEBUG 消息发送到控制台而不是记录 我尝试过使用set
  • 异步生成器和 Observables 之间有什么区别?

    异步生成器 一个示例案例是可读流 可观测值 处理异步数据流的基本协议 这两种方法似乎都是解决异步数据流同一问题的不同方法 除了品味问题之外 两者之间还有实际区别吗 从建议的API描述来看 observables 可以有多个订阅者 广播 异步
  • tf.audio.decode_wav 如何获取其内容?

    我正在尝试使用以下命令将一些音频文件拉入 Tensorflowtf audio decode wav 我可以看到有人正在考虑在文档中提供更多信息 但是有人有任何关于这应该如何工作的示例吗 tf audio decode wav conten
  • 从深度缓冲区获取真实的 z 值

    正如预期的那样 从着色器中的深度缓冲区采样会返回 0 到 1 之间的值 给定相机的近剪裁平面和远剪裁平面 如何计算此时的真实 z 值 即距相机的距离 From http web archive org web 20130416194336