我有一个可用的光线跟踪器(使用gl-matrix编写的节点) 它适用于球体,但现在我正在添加通用矩阵变换(平移,旋转,缩放)以支持其他对象类型。
每个对象有两个转换矩阵,一个名为trans
的世界到对象的反向矩阵,另一个回复transFwd
,用 fromRotationTranslationScale
// Here pos is center of sphere and r is radius
mat4.fromRotationTranslationScale(this.transFwd, rotation, [pos[0], pos[1], pos[2]], [r, r, r]);
mat4.invert(this.trans, this.transFwd);
我正在使用trans
变换将所有光线转换为对象空间,计算关于原点的光线 - 物体交点( t 的值),半径为1的球体。 / p>
挑战是在计算 t 之后,与我的交叉点&法线。当我为我的变换添加任何类型的旋转时,它们都会变形
// ray has already been transformed to object space
// getPoint simply returns ray.pos + t * ray.dir
let intersect: vec4 = ray.getPoint(t);
let normal: vec4 = vec4.sub(vec4.create(), i, [0, 0, 0, 1]);
vec4.normalize(n, n);
// move intersect back to world space
vec4.transformMat4(intersect, intersect, this.transFwd);
在对象中使用变换矩阵时,处理法线的正确方法是什么?我之后尝试过转换回世界空间,我已经尝试在移动交叉路口后计算正常值,但没有任何效果!
答案 0 :(得分:0)
我设法解决了这个问题。我正走在正确的道路上,因为我没有改变我的法线和反射光线所以它仍然看起来很奇怪。光线跟踪的难点在于您可以通过“视觉检查”进行的唯一测试
以下是对象空间中球体的工作交叉点代码的摘要
// Intersection in object space
let intersect: vec4 = ray.getPoint(t);
// Normal is pointing from center of sphere (0,0,0) to intersect (i)
// Divide by sphere radius
vec4.div(normal, intersect, [radius, radius, radius, 1]);
n[3] = 0;
// Move i back to world space
vec4.transformMat4(intersect, intersect, transFwd);
// Reflected ray about the normal, & move to world
let reflect: vec4 = ray.reflect(normal);
vec4.transformMat4(reflect, r, transFwd);
vec4.normalize(reflect, reflect);
// Move normal into world & normalize
vec4.transformMat4(normal, normal, transFwd);
vec4.normalize(normal, normal);