OpenTK 矩阵变换

2023-12-01

这是顶点着色器:

uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;

void main(void)
{
    gl_Position = projection * view * model * gl_Vertex;
    gl_TexCoord[0] = gl_MultiTexCoord0;
}

我的理解是,使用各种变换,模型空间最终会变成剪辑空间,这是一个由每个轴中的每个单元绑定的盒子,直接绘制到视口,即(-1, 1,0)处的东西位于顶部视口的左侧。当我从着色器中删除所有矩阵变换时,

gl_Position = gl_Vertex;

并传入一个简单的四边形作为模型

public Vector3[] verts = new Vector3[] {
    new Vector3(-1f, -1f, 0),
    new Vector3(1f, -1f, 0),
    new Vector3(1f, 1f, 0),
    new Vector3(-1f, 1f, 0),
};

public Vector2[] coords = new Vector2[] {
    new Vector2(0, 1f),
    new Vector2(1f, 1f),
    new Vector2(1f, 0f),
    new Vector2(0f, 0f),
};

public uint[] indices = new uint[] {
    0,1,2,
    0,2,3,
};

我得到了预期的全屏图像。当我应用转换时,图像显示为 正如您所期望的,屏幕中央的一个小方块。当我尝试在 CPU 上的剪辑坐标中计算模型顶点的位置时,出现了问题:

public Vector4 testMult(Vector4 v, Matrix4 m)
{
    return new Vector4(
        m.M11 * v.X + m.M12 * v.Y + m.M13 * v.Z + m.M14 * v.W,
        m.M21 * v.X + m.M22 * v.Y + m.M23 * v.Z + m.M24 * v.W,
        m.M31 * v.X + m.M32 * v.Y + m.M33 * v.Z + m.M34 * v.W,
        m.M41 * v.X + m.M42 * v.Y + m.M43 * v.Z + m.M44 * v.W);
}

Matrix4 test = (GlobalDrawer.projectionMatrix * GlobalDrawer.viewMatrix) * modelMatrix;

Vector4 testv = (new Vector4(1f, 1f, 0, 1));
Console.WriteLine("Test Input: " + testv);
Console.WriteLine("Test Output: " + Vector4.Transform(testv, test));
Vector4 testv2 = testMult(testv, test);
Console.WriteLine("Test Output: " + testv2);
Console.WriteLine("Test Output division: " + testv2 / testv2.W);

(传入的矩阵与传递给着色器的矩阵相同)

然后程序继续在剪辑空间之外给出输出,除以 W 导致除以 0:

Test Input: (1, 1, 0, 1)
Test Output: (0.9053301, 1.207107, -2.031746, 0)
Test Output: (0.9053301, 1.207107, -1, 0)
Test Output division: (Infinity, Infinity, -Infinity, NaN)

矩阵创建如下:

projectionMatrix = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 4, window.Width / (float)window.Height, 1.0f, 64.0f);
projectionMatrix =
(1.81066, 0, 0, 0)
(0, 2.414213, 0, 0)
(0, 0, -1.031746, -1)
(0, 0, -2.031746, 0)

viewMatrix = Matrix4.LookAt(new Vector3(0,0,4), -Vector3.UnitZ, Vector3.UnitY);
viewMatrix = 
(1, 0, 0, 0)
(0, 1, 0, 0)
(0, 0, 1, 0)
(0, 0, -4, 1)

modelMatrix = 
(0.5, 0  , 0  , 0)
(0  , 0.5, 0  , 0)
(0  , 0  , 1  , 0)
(0  , 0  , 0  , 1)

所以,问题是为什么;我究竟做错了什么?


Edit (添加评论中的真实答案)

默认情况下,您的 OpenTK 矩阵是转置的。它看起来使用行向量而不是列向量。因此,您需要将乘法计算为 (model * view * proj),而不是 (proj * view * model)。或者在上传之前转置所有矩阵。


实际上剪辑空间不是从-1到1,而是从-W到W,其中W是剪辑空间向量的第四个分量。

你可能想到的叫做标准化设备坐标,每个轴上的范围为 -1 到 1。通过将剪辑空间向量的 X、Y 和 Z 坐标除以剪辑空间 W 分量即可获得该值。这个部门被称为透视划分.

这是在将剪辑空间坐标传递给 gl_Position 后在幕后完成的。

不过你的剪辑空间坐标是 0,这对我来说似乎不正确。

这里还有一些更多细节:OpenGL 常见问题解答:转换.

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

OpenTK 矩阵变换 的相关文章

  • OpenGL:仅获取模板缓冲区而没有深度缓冲区?

    我想获取一个模板缓冲区 但如果可能的话 不要承受附加深度缓冲区的开销 因为我不会使用它 我发现的大多数资源表明 虽然模板缓冲区是可选的 例如 排除它以利于获得更高的深度缓冲区精度 但我还没有看到任何请求并成功获取仅 8 位模板缓冲区的代码
  • 朱莉娅在矩阵中查找(行,列)而不是索引

    在 Julia 中 您可以通过以下方式找到矩阵中元素的坐标 julia gt find x gt x 2 1 2 3 2 3 4 1 0 2 3 element Array Int64 1 2 4 9 这些值是正确的 但我更希望得到 row
  • 使用 JOGL 和 Android OpenGL 编写可移植 Java 应用程序

    我计划编写一款可以在 PC 和 Android 上运行的 Java 3D 游戏 不幸的是 这两个平台似乎没有通用的 OpenGL API API 是否有显着差异 有没有办法在两个版本中使用相同的 3D 代码 这是不是一个好主意 Androi
  • 在网格中查找具有相同值的相邻单元格。想法如何改进这个功能?

    我是 Python 新手 学习了 1 个多月 我尝试创建 Tic Tac Toe 然而 一旦我完成了它 我决定扩展棋盘 从 3x3 到 9x9 具体取决于客户的输入 并通过在棋盘上的任意位置连接 4 个行 列或对角线来获胜 因此 我需要一个
  • 使用 pyclutter 进行编程

    我是混乱 和 pyclutter 的新手 我一直在尝试使用 pyclutter 到目前为止我还没有找到任何好的教程 我的意思是没有真正正确解释的内容 我看到了几个示例程序 但是当我尝试使用 pyclutter 时 我没有得到任何好的结果 这
  • 编译 GLUI 库,VS2010 给我一个奇怪的命名空间错误

    我有一个针对我所在班级的 OpenGL 项目 它基于 GLUI 提供的 GLUI 库无法工作 这就是我尝试自己编译它的原因 因此 我从 SourceForge 下载了源代码并尝试编译 glui 库 它给了我这个 但我找不到任何相关信息 1
  • Python模糊字符串匹配作为相关样式表/矩阵

    我有一个文件 其中包含 x 个字符串名称及其关联的 ID 本质上是两列数据 我想要的是一个格式为 x by x 的相关样式表 将相关数据作为 x 轴和 y 轴 但我想要 fuzzywuzzy 库的函数 fuzz ratio x y 作为输出
  • 在windows + opengl中选择图形设备

    我知道如何使用 openGL 打开窗口 使用 Win32 或其他工具包 但是当系统有2块显卡时 如何选择要渲染的图形设备 我的编程语言是 C 我专注于 Windows 但任何示例都将受到欢迎 编辑 也许更好地解释我的问题是个好主意 以便添加
  • LWJGL3:重载的 glBufferData 方法

    我正在使用 LWJGL 调用 OpenGL 函数 方法org lwjgl opengl GL15 glBufferData http javadoc lwjgl org org lwjgl opengl GL15 html glBuffer
  • 用 R 将矩阵划分为 N 个大小相等的块

    如何使用 R 将矩阵或数据帧划分为 N 个大小相等的块 我想水平切割矩阵或数据框 例如 给定 r 8 c 10 number of chunks 4 data matrix seq r c nrow r ncol c gt gt gt da
  • 如何在不使用 Kinect SDK 函数的情况下将深度空间中的点转换为 Kinect 中的颜色空间?

    我正在做一个增强现实应用程序 将 3D 对象叠加在用户的彩色视频之上 使用 Kinect 1 7 版本 虚拟对象的渲染在 OpenGL 中完成 我已经成功地在深度视频上叠加了 3D 对象 只需使用 NuiSensor h 标头中深度相机的固
  • glVertexAttribDivisor 和 glVertexBindingDivisor 有什么区别?

    我一直在寻找将属性与任意顶点分组关联起来的方法 起初似乎是我实现这一目标的唯一方法 但后来我偶然发现了这个问题 https stackoverflow com questions 14169228 opengl single vertex
  • 如何在 GLSL 1.3 和 OpenGL 2.1 中使用位运算

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

    我有两个数组A 1 2 3 and B 1 0 1 0 问题是如何在 python 中执行张量点积 我期待得到 C 1 2 3 0 0 0 1 2 3 0 0 0 函数 np tensordot 返回有关数组形状的错误 对这个问题稍微补充一
  • 如何从列中创建对称矩阵?

    例如 我想转动以下列 90 175 600 650 655 660 代入矩阵 90 175 600 650 655 660 175 600 650 655 660 655 600 650 655 660 655 650 650 655 66
  • 在 QML 中控制纹理 3D 对象的不透明度

    我对 QML 中的 Qt 3D 有点陌生 我正在尝试控制 Qt 3D 的不透明度textured3D 对象 我正在使用简单qml3d https github com tripolskypetr simpleqml3d测试项目来做到这一点
  • 在 OpenGL 中使用不同的着色器程序?

    我必须在 OpenGL 中针对不同的对象使用两个不同的着色器程序 我发现我必须使用glUseProgram 在不同的着色器程序之间切换 但对此没有太多信息 鉴于我有两个用于不同对象的不同着色器程序 如何为每个着色器程序生成和绑定 VAO 和
  • GLSL 中统一浮点行为和常量浮点行为的不同

    我正在尝试在 GLSL 中实现模拟双精度 并且观察到一种奇怪的行为差异 导致 GLSL 中出现细微的浮点错误 考虑以下片段着色器 写入 4 浮点纹理以打印输出 layout location 0 out vec4 Output unifor
  • 使用 glGetFloatv 检索 pyglet 中的模型视图矩阵

    我正在使用 pyglet 在 python 中进行 3D 可视化 并且需要检索模型视图和投影矩阵来进行一些选择 我使用以下方式定义我的窗口 from pyglet gl import from pyglet window import wi
  • 在每次迭代中使用 for 循环的索引命名图像

    我正在使用 MATLAB 进行图像处理项目 我使用 for 循环在每次循环迭代时生成某种图像数据 图像大小不同 我的问题是如何阻止它在下一次迭代中覆盖图像 Img i j data 理想情况下我希望它有 Img 1 data for 1st

随机推荐

  • 使用 LibreOffice(soffice.exe) 作为 Process.Start() 从代码隐藏不能在 IIS 服务器上工作

    我使用 LibreOffice 作为命令行将 docx 转换为 pdf 我正在使用下面的代码片段 using Process pdfprocess new Process pdfprocess StartInfo UseShellExecu
  • 如何在 vue js 2 上将变量放入 href 中?

    当我运行这个时 nextPage 结果 http chelseashop dev search result page 2 但是当我输入这样的 href 时
  • 返回函数 c 中的结构

    我正在尝试返回一个struct来自一个函数 看起来是这样的 struct read struct returnera returnDuo struct vara varuArray char varunr LISTNUMBER varuna
  • 在本地开发时在 Cloud Run 中模拟事件驱动设计?

    我正在开发一个在 Google Cloud Run 完全托管 上 运行的微服务架构应用程序 我想将事件通信添加到我的服务中 据我所知 唯一的选择是使用 Eventarc 我很好奇在本地开发时重现事件驱动设计的最佳方法是什么 以及如何使部署尽
  • 如何在 Scala Spark 中从 Excel(xls、xlsx)文件构造 Dataframe?

    我有一个大Excel xlsx and xls 包含多个工作表的文件 我需要将其转换为RDD or Dataframe以便它可以连接到其他dataframe之后 我正在考虑使用阿帕奇兴趣点并将其另存为CSV然后阅读csv in datafr
  • 如何在没有注解的情况下使用Spring Data JDBC?

    我正在开发一个新项目 使用干净架构等概念 保护我的模型和业务规则免受外部依赖项和框架的影响 另外 我不喜欢使用传统的 ORM 库 如 JPA Hibernate 而是选择使用纯 jdbc 通过 spring jdbctemplate 一切进
  • 如何按添加顺序绘制 X、Y 坐标?

    我想按照我输入的顺序连接 X 和 Y 坐标以形成一个圆 我找到了一个用Java绘制X Y坐标的程序 然后我添加了圆的数据 但程序连接了最近的 X Y 坐标 而不是排序 X Y public Graph final String title
  • SQLAlchemy ORM 无法使用复合外键

    我正在尝试使用几个相关模型构建一个示例 如下所示 我们有一个模型 B 与模型 C 具有 1 n 关系 那么我们就有一个模型 A 与 B 之间存在 n 1 关系 与 C 之间存在 n 1 关系 C 有 2 列主键 我尝试了这段代码 class
  • 按键在 Mozilla Firefox 中不起作用

    我有一项任务限制文本框的字母值 只能使用浮点值 小数点后我们必须写出两位数 我这样做了 但它在 Mozilla Firefox 中不起作用 我怎么解决这个问题 我的脚本是 function name bind paste function
  • 如何使用正则表达式提取大括号中的单词?

    我想提取全部words用花括号括起来 所以我有这样的表达式 foo bar moo mar 要匹配的字符串可能有任意数量的这些单词 但我开始认为我正在以错误的方式处理这个问题 我的尝试 我尝试将大括号中的单词提取到组中 以便我可以使用每个匹
  • Cocoa:隐藏其他应用程序和自身

    我需要一种方法让应用程序与所有其他应用程序一起隐藏自身 我目前隐藏了其他应用程序 但我的应用程序保持打开状态 我通过单击按钮并将其拖动到实用程序中的 应用程序 区域来完成此操作 然后我选择 隐藏其他应用程序 好的 所以 如果你只是想show
  • 在 React 和 Next.js 构造函数中,我收到“引用错误:本地存储未定义”

    我在 React 中创建了一个系统 jsonwebtoken 并使用 Next js 在浏览器中运行代码时发现一个问题 那就是 本地存储未定义 我该如何修复它 这是我在文件中的代码AuthStudentContext js import R
  • 如何翻译/移动 numpy 数组?

    我不确定要搜索什么关键字 因此如果已被询问 请链接响应并关闭此线程 我试图按固定方向移动 numpy 数组的非零条目 例如 假设我有一个二维数组 0 1 2 0 0 3 0 0 0 0 0 0 0 0 0 0 将其移位 1 1 将产生以下数
  • 海龟图形在自身上绘制

    这应该是一个非常简单的问题 然而 事实证明这对我来说很难 我对海龟图形相当陌生 因此 我正在尝试完成简单的绘图 我的乌龟会画一行 拿起笔 向上移动一个像素 放下笔 然后继续绘画 到目前为止 这是我的代码 for y in range hei
  • 如何从 spring mvc multipartfile 进入 zipinputstream

    我有一个 Spring MVC 控制器 它接受 MultipartFile 它将是一个 zip 文件 问题是我似乎无法从那里转到 ZipInputStream 或 ZipFile 以便我可以浏览条目 它要么提前关闭流 生成一个空文件 要么像
  • 如何在从服务器获取数据的动态表的每一行中添加下拉列表?

    我想添加静态下拉列表到从服务器获取数据的动态表的每一行 我将如何做到这一点 我想做同样的像这样 请检查下拉列表类型 但它也会从服务器获取数据 并且每一行列都会有下拉列表 以下是更新和工作代码 感谢 angu 下拉列表的结构
  • C++中的输出流什么时候必须刷新?

    我明白cout lt lt n 优先于cout lt lt endl but cout lt lt n 不刷新输出流 何时应该刷新输出流以及何时出现问题 究竟什么是潮红 刷新强制输出流写入任何缓冲的字符 读取流式输入 输出 这取决于您的应用
  • 如何解决带有日期值的 h:inputText 中的“‘null Converter’的转换错误设置值‘2013-10-26’”?

    当我按下插入按钮时 标题上显示错误 空转换器 的转换错误设置值 2013 10 26
  • 为什么我不能先定义 main(),然后再定义它调用的函数?

    如果我将 main 放在源文件的顶部并调用一些自定义函数 它会告诉我找不到这些函数 但如果我将 main 放在源文件的底部 它将起作用 为什么 是不是因为编译器从上到下解析程序并在main的定义处中断 和main没有关系 C 编译器从上到下
  • OpenTK 矩阵变换

    这是顶点着色器 uniform mat4 projection uniform mat4 view uniform mat4 model void main void gl Position projection view model gl