I've got a working ray tracer (written in Node using gl-matrix) It's working great with spheres but now I'm adding general purpose matrix transforms (translate, rotate, scale) in order to support other object types.
I have two transformation matrices per object, an inverse one for world to object called trans
and one back again transFwd
, set up with 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);
I'm transforming all rays using the trans
transform into object space calculating my ray-object intersection (value of t) about the origin, with spheres of radius of 1.
The challenge is after calculating t, working with my intersection & normals. When I add any sort of rotation to my transform they all get distorted
// 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);
What is the correct way to deal with normals when using transformation matrixes for your objects? I've tried transforming back to world space afterwards, I've tried calculating the normal after moving intersection back, but nothing works!
intersect
(at least if your transform is only made up of rotations, translations, and uniform scalings). Just make sure that you have a w-component of 0 and normalize afterwards. - Nico Schertler(0,0,0)
. Scaling is a big problem as it changes the vector size so in some cases you need to addnormalize
. Also different scales between axises could break relationship between vectors so some algorithms/equations could be wrong afterwards. I use all the objects in the same coordinate system (they are constructed from triangles and spheres) here Reflection and refraction impossible without recursive ray tracing? is how I do it. - Spektre