光线跟踪物体空间,转换法线

时间:2018-06-03 16:14:53

标签: graphics 3d raytracing

我有一个可用的光线跟踪器(使用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);

在对象中使用变换矩阵时,处理法线的正确方法是什么?我之后尝试过转换回世界空间,我已经尝试在移动交叉路口后计算正常值,但没有任何效果!

1 个答案:

答案 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);