物体空间中的光线追踪,变换法线

问题描述 投票:0回答:2

我有一个可用的光线追踪器(使用 gl-matrix 在 Node 中编写) 它与球体配合得很好,但现在我添加通用矩阵变换(平移、旋转、缩放)以支持其他对象类型。

每个对象有两个变换矩阵,一个是世界到对象的逆矩阵,称为

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。

挑战是在计算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);

为对象使用变换矩阵时处理法线的正确方法是什么?之后我尝试转换回世界空间,我尝试在将交叉点移回后计算法线,但没有任何效果!

graphics 3d raytracing
2个回答
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);

0
投票

当您将法线从对象坐标转换为世界坐标时,您可能还需要转置倒置矩阵以保持缩放!否则,它可能会给您带来不稳定的结果,尤其是在您的照明中! ^^ The Ray Tracer Challenge by Jamis Buck

© www.soinside.com 2019 - 2024. All rights reserved.