use*_*137 3 opengl 3d raytracing glsl perspectivecamera
我目前正在研究GLSL中的一些光线投射,效果很好.无论如何我现在想从正交投影到透视投影,但我不知道如何正确地做到这一点.关于如何使用投影矩阵与光线投射有任何良好的联系吗?我甚至不确定我应该将矩阵应用到(以某种方式对射线方向?).现在我这样做(伪代码):
vec3 rayDir = (0.0, 0.0, -1.0); //down the negative -z axis in parallel;
Run Code Online (Sandbox Code Playgroud)
但是现在我想使用一个类似于gluPerspective函数的projMatrix,这样我就可以简单地定义宽高比,fov以及近和远平面.所以基本上,任何人都可以为我提供一大堆代码来设置类似的proj矩阵gluProjection吗?其次告诉我将它与rayDirection相乘是否正确?
对于与标准渲染在同一场景中的光线跟踪,我发现以下适用于从屏幕坐标获取场景空间光线:(例如,将全屏四边形从 [-1,-1] 渲染到 [1,1 ],或该范围内的某个子区域)
uniform mat4 invprojview;
uniform float near;
uniform float far;
attribute vec2 pos; // from [-1,-1] to [1,1]
varying lowp vec3 origin;
varying lowp vec3 ray;
void main() {
gl_Position = vec4(pos, 0.0, 1.0);
origin = (invprojview * vec4(pos, -1.0, 1.0) * near).xyz;
ray = (invprojview * vec4(pos * (far - near), far + near, far - near)).xyz;
// equivalent calculation:
// ray = (invprojview * (vec4(pos, 1.0, 1.0) * far - vec4(pos, -1.0, 1.0) * near)).xyz
}
Run Code Online (Sandbox Code Playgroud)
varying lowp vec3 origin;
varying lowp vec3 ray;
void main() {
lowp vec3 rayDir = normalize(ray);
// Do raytracing from origin in direction rayDir
}
Run Code Online (Sandbox Code Playgroud)
请注意,您需要提供倒置的投影视图矩阵,以及近远裁剪距离。我确信有一种方法可以从矩阵中获得这些剪切距离,但我还没有弄清楚如何。
这将定义一条从近平面开始的射线,而不是相机的位置。这提供了在 OpenGL 将裁剪三角形的相同位置进行裁剪的优势,使您的光线跟踪对象与场景相匹配。由于ray变量将是到达远平面的正确长度,因此您也可以在那里进行剪辑。
至于首先获得透视矩阵(并理解其背后的数学原理),我总是使用这个参考页面:
http://www.songho.ca/opengl/gl_projectionmatrix.html
我建议查看该站点上的推导,但如果它不可用,这里是最终的投影矩阵定义:
2n/(r-l) 0 (r+l)/(r-l) 0
0 2n/(t-b) (t+b)/(t-b) 0
0 0 -(f+n)/(f-n) -2fn/(f-n)
0 0 -1 0
Run Code Online (Sandbox Code Playgroud)
小智 5
要将光线射入场景,您需要在应用投影矩阵后将自己(精神上)置于世界中.这意味着视图截头现在是一个2x2x1的盒子 - 这被称为规范视图体积.(方框的相对角是(-1,-1,0)和(1,1,-1).)你产生的光线(在投影后变换的世界中)从原点开始并击中后方剪切平面(位于z = -1).第一条射线的"目的地"应为(-1,1,-1) - 远剪裁平面的左上角.(后续光线"目的地"是根据视口的分辨率计算的.)
既然您已在规范视图体积中拥有此光线,则需要将其放入标准世界坐标中.你怎么做到这一点?简单 - 只需乘以投影矩阵的倒数,通常称为观察变换.这将使您的光线与场景中的对象处于相同的坐标系中,从而使光线碰撞测试更加轻松.