c++ - 从正交投影切换到透视投影
问题描述
我正在尝试向现有引擎添加视差效果。到目前为止,引擎使用正交投影。对象被放置在屏幕上的像素坐标中。问题是我无法弄清楚如何使用透视投影矩阵等复制相同的投影。我可以为深度添加 Z 坐标。
我已经尝试了矩阵和 z 坐标的各种组合,结果总是黑屏。
我要替换的矩阵:
glm::mat4 projection = glm::ortho(0.0f, static_cast<GLfloat>(1280.0f), static_cast<GLfloat>(720.0f), 0.0f, 0.0f, -100.0f);
顶点着色器:
// Shader code (I tested this while having identity matrices for view and model
#version 330 core
layout (location = 0) in vec2 vertex;
uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;
void main() {
gl_Position = projection * view * model * vec4(vertex.xy, 1.0f, 1.0f);
}
我认为可能有效的投影代码:
glm::mat4 model = glm::mat4(1.0f);
model = glm::translate(model, glm::vec3(-640, -310.0f, 0.0f));
model = glm::scale(model, glm::vec3(1.0f / 1280.0f, 1.0f / 720.0f, 1.0f));
glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 0.0f);
glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f);
glm::vec3 cameraUp = glm::vec3(0.0f, 1.0f, 0.0f);
glm::mat4 view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp);
glm::mat4 projection = glm::perspective(glm::radians(45.0f), 1.0f, 0.1f, -100.0f);
预期的是,一个矩形仍然显示在相似的位置(一旦某些东西起作用,我可以更正细节)而没有黑屏。
解决方案
透视投影矩阵的规范是错误的。
glm::perspective(glm::radians(45.0f), 1.0f, 0.1f, -100.0f);
glm::perspective
通过沿 y 轴的视场角、纵横比以及到近平面和远平面的距离来定义视锥。
因此,近平面和远平面必须是正值(> 0),并且近平面必须小于远平面:
0 < near < far
例如:
glm::perspective(glm::radians(45.0f), 1.0f, 0.1f, 100.0f);
几何图形必须位于近平面和远平面之间,否则会被剪裁。
投影面积大小与深度之比是线性的,可以计算出来。它取决于视场角:
float fov_y = glm::radians(45.0f);
float ratio_size_depth = tan(fov_y / 2.0f) * 2.0f;
请注意,如果对象在视口上的投影中显示为一半大小,则对象到相机的距离(深度)必须加倍。
推荐阅读
- reactjs - 如何更改句柄提交中的数据?
- matlab - 在 MATLAB 中,有没有办法在 3-D 矩阵上将 find() 的结果作为线性索引的锯齿状数组?
- python - Python Pandas:分组按和平均,计数,中位数
- javascript - CSS Image overflow hidden without stretch
- http - 为什么我不能在邮递员中向不同的网络发出获取请求
- android - android:retrofit2 总是返回空体
- ios - SwiftUI Expandable list 实现问题
- android - 通过长按拖动重新排序 LazyVerticalGrid 中的项目
- node.js - 在 vscode 测试运行脚本 (index.ts) 中传递命令行参数
- javascript - 在角度/电子应用程序中使用带有 socket.io 的 nodejs 脚本