我有一个OpenGL光线追踪器,可以加载OBJ文件并以光线追踪的方式进行可视化。我的应用使用Assimp加载OBJ文件,然后通过使用着色器存储缓冲区将所有三角形面(包括顶点及其索引)发送到片段着色器中。然后,片段着色器通过跟踪光线路径来计算像素的颜色。光线从相机位置(
目前,我正在处理相机问题。相机始终朝向
posCamera
)发出并穿过虚拟画布的像素。基本结构是将结果呈现到这个四边形形状的画布上。目前,我正在处理相机问题。相机始终朝向
0,0,0
点(viewPoint
),并可以通过以下函数围绕y轴旋转:void setCamera(float param) {
connect = posCamera - viewPoint;
posCamera = glm::vec3(connect.x * cos(param) + connect.z * sin(param), connect.y,
-connect.x * sin(param) + connect.z * cos(param)) + viewPoint;
canvasX = cross(upVector, connect) * getLength(connect) * tanf(fieldOfview / 2);
canvasY = cross(connect, canvasX) * getLength(connect) * tanf(fieldOfview / 2);
setCam(posCamera,viewPoint, canvasY, fieldOfview);
我只想将场景绕x轴旋转。为了解决这个问题,我创建了一个新的函数:
void rotateAroundX(float param) {
connect = posCamera - viewPoint;
posCamera = glm::vec3(posCamera.x,
connect.y * cos(param) + connect.z * sin(param),
-connect.y * sin(param) + connect.z * cos(param))+viewPoint;
canvasX = cross(upVector, connect) * getLength(connect) * tanf(fieldOfview / 2);
canvasY = cross(connect, canvasX) * getLength(connect) * tanf(fieldOfview / 2);
setCam(posCamera,viewPoint, canvasY, fieldOfview);
}
它可以工作,但不幸的是与比例有关的一些失真问题。更糟糕的是,有时相机只会在某个点周围旋转。这是一个涉及到该问题的视频:链接。您可以看到水平旋转效果良好。
以下是我的顶点着色器:
#version 460 core
layout(location = 0) in vec2 normQuadCoord;
uniform vec3 viewPoint;
uniform vec3 canvasX, canvasY;
out vec3 pixel;
void main()
{
pixel = canvasX * normQuadCoord.x + canvasY * normQuadCoord.y + viewPoint;
gl_Position = vec4(normQuadCoord, 0, 1);
}
以下是完整源代码的链接:source
除了相机旋转之外,我不知道是否可能使用这种“渲染到四边形”的概念来实现自由飞行的相机。非常感谢您的任何帮助!
更新1
我尝试了Rabbid76的建议并修改了源代码。我还进行了一些重构。下面是更新矩形画布尺寸的方法:
void Init::updateCanvasSizes() {
connect = camera.getPosCamera() - camera.getViewPoint();
float aspect = (float)SCR_W_H.first/(float)SCR_W_H.second;
float length = tanf(camera.getFieldOfview() / 2);
canvasX = glm::normalize(glm::cross(camera.upVector, connect)) / length / aspect;
canvasY = glm::normalize(glm::cross(connect, canvasX)) / length;
}
该方法,处理相机绕X轴的旋转已被修改为:
void Init::rotateCamAroundX(float param) {
camera.posCamera = glm::vec3(camera.posCamera.x,
(camera.posCamera.y - camera.viewPoint.y) * cos(param) + (camera.posCamera.z - camera.viewPoint.z) * sin(param) + camera.viewPoint.y,
-(camera.posCamera.y - camera.viewPoint.y) * sin(param) + (camera.posCamera.z - camera.viewPoint.z) * cos(param) + camera.viewPoint.z);
updateCanvasSizes();
}
视野已从 45
度修改为 45 * (float)M_PI / 180
,因此模型的比例变得更好了一些。不幸的是,在相机绕 X 轴旋转时,仍然可能出现场景拉伸和扭曲。当相机达到一定角度时,它还会回头看 camera.viewPoint
。我不知道如何“关闭”它。
结果可以在这个视频中看到:链接。首先可以看到绕 Y 轴的旋转,然后是绕 X 轴的旋转。