同一场景中光线投射与光栅化的世界坐标不匹配问题
光线投射与光栅化立方体渲染不匹配问题
我正在渲染两个边长为1、以原点为中心(最小坐标[-.5, -.5, -.5],最大坐标[.5, .5, .5])的立方体:一个采用光栅化方式(通过顶点着色器设置顶点),另一个采用光线投射方式(每个像素发射一条射线穿过立方体)。问题在于,经过投影、视图、模型矩阵及其逆矩阵变换后,二者的世界空间坐标无法匹配。
光栅化立方体实现
光栅化立方体通过顶点着色器传入顶点坐标,用标准方式设置gl_Position:
gl_Position = proj * view * model * vec4(in_position, 1);
光线投射立方体实现
光线投射立方体使用逆投影矩阵和逆视图矩阵,模型矩阵设为单位矩阵。
射线生成逻辑
- 射线起点计算:
vec4 ray_origin = inverse(view) * vec4(0,0,0,1);
- 射线方向计算函数(注:原代码中
view_coords为笔误,已修正为eye):
uniform vec2 resolution; // 视口的宽高(像素) vec3 ray_dir(){ // 归一化设备坐标(透视除法后的状态) vec2 ndc = (gl_FragCoord.xy / resolution) * 2.0 - 1.0; // 从归一化屏幕空间计算裁剪空间坐标 vec4 clip = vec4( ndc.xy, -1, 0); // 通过逆投影矩阵转换到眼空间 vec4 eye = inverse(proj) * clip; eye = vec4(eye.xy, -1, 0); // 通过逆视图矩阵转换到世界空间 vec4 world = inverse(view) * eye; return normalize(world.xyz); }
射线-包围盒相交检测
uniform vec3 start; // 相机的世界空间位置 vec2 cube_intersection() { vec3 dir = ray_dir(); // 无相交时vec.x > vec.y float size = 0.5; vec3 t_min = (-vec3(size) - start) / dir; vec3 t_max = (+vec3(size) - start) / dir; vec3 t1 = min(t_min, t_max); vec3 t2 = max(t_min, t_max); float t_near = max(max(t1.x, t1.y), t1.z); float t_far = min(min(t2.x, t2.y), t2.z); return vec2(max(t_near, 0), t_far); }
其中start是存储相机世界空间位置的uniform变量,会丢弃所有t_near > t_far的片段。
问题现象
视图矩阵包含常规旋转和平移,投影矩阵是标准透视矩阵,理论上两个立方体在世界空间中应完全一致,但实际渲染结果存在偏差:
- 相机距离原点1个单位时:光线投射的立方体明显比光栅化的大
- 相机距离原点0.5个单位时:光线投射的立方体大小是预期的2倍
- 相机距离原点10个单位时:光线投射的立方体大小接近正确值
- 相机距离原点100个单位时:二者几乎完全匹配
注:每次测试都会调整投影矩阵的FOV以适配不同距离
可见规律:相机离原点越近,光线投射的立方体越大;离原点越远,立方体越小,渐近趋近于正确大小。
尝试的临时修复及遗留问题
若将相机位置start乘以(1.0 / length(start) + 1.0),立方体的大小会变得正确(比如距离1个单位时渲染匹配):
uniform vec3 start; // 相机的世界空间位置 vec2 cube_intersection() { vec3 dir = ray_dir(); // 无相交时vec.x > vec.y float size = 0.5; vec3 t_min = (-vec3(size) - start*(1.0 / length(start) + 1.0)) / dir; // 修改处 vec3 t_max = (+vec3(size) - start*(1.0 / length(start) + 1.0)) / dir; // 修改处 vec3 t1 = min(t_min, t_max); vec3 t2 = max(t_min, t_max); float t_near = max(max(t1.x, t1.y), t1.z); float t_far = min(min(t2.x, t2.y), t2.z); return vec2(max(t_near, 0), t_far); }
但当相机朝向偏离原点时(比如相机位于(sqrt(3), sqrt(3), sqrt(3)),看向(0,0,0.5)),光线投射的立方体偏移量是光栅化立方体的2倍,仍不匹配。
我怀疑问题与光栅化过程中片段着色器之后的w分量除法有关,但不确定具体原因及光线投射中的修复方法。光线投射与光栅化在世界空间中应该可以共存,求解决方案!
内容的提问来源于stack exchange,提问作者Jonny Hyman
相关产品推荐
相关产品推荐

