Below I am sharing some TSL that I have been using to rotate a direction vector dir
by euler angles cameraWorldRotation
.
Is there a more efficient way to do this than repeatedly calling rotateVector
on the z, y, and x axis? Or is this the best way to do it? Can I perhaps incorporate camera.getWorldDirection(target)
or camera.matrixWorld
as uniforms to allow the TSL to be simplified?
function rotateVector(vector, axis, angle) {
const vxp = cross(axis, vector);
const vxvxp = cross(axis, vxp);
const a = mul(vxp, sin(angle));
const b = mul(vxvxp, cos(angle).oneMinus());
return vector.add(a).add(b);
}
const cameraWorldRotation = (() => {
const q = new THREE.Quaternion();
const e = new THREE.Euler();
return THREE.uniform("vec3").onRenderUpdate(() => {
// "camera" is a THREE.PerspectiveCamera
camera.getWorldQuaternion(q);
return e.setFromQuaternion(q);
});
})();
let dir = vec3(0.22, -1, -0.65); // let "dir" be any arbitrary vec3
// rotate around z
dir = rotateVector(dir, vec3(0, 0, 1), cameraWorldRotation.z);
// rotate around y
dir = rotateVector(dir, vec3(0, 1, 0), cameraWorldRotation.y);
// rotate around x
dir = rotateVector(dir, vec3(1, 0, 0), cameraWorldRotation.x);
// "dir" has now been successfully rotated by "cameraWorldRotation"