导出变换矩阵是着色器相当普遍的要求。是否有和 wgsl 标准库来做这种事情?即,即使是 mat4x4 - mat4x4 乘法也会很有用!
我在下面写了一个粗略的草稿,但这似乎是一种相当冗长的方式
// Create a homogeneous transformation matrix from a translation vector.
fn mk_translation_matrix(v: vec3<f32>) -> mat4x4<f32>{
let c_1: vec4<f32> = vec4<f32>(1., 0., 0., v.x);
let c_2: vec4<f32> = vec4<f32>(0., 1., 0., v.y);
let c_3: vec4<f32> = vec4<f32>(0., 0., 1., v.z);
let c_4: vec4<f32> = vec4<f32>(0., 0., 0., 1.);
let translation_matrix = mat4x4<f32>(c_1, c_2, c_3, c_4);
return translation_matrix;
}
fn mk_rotation_matrix(q: vec4<f32>) -> mat4x4<f32> {
let m11 = 2. * (q.x * q.x + q.y * q.y) - 1.;
let m12 = 2. * (q.y * q.z - q.x * q.w);
let m13 = 2. * (q.y * q.w - q.x * q.z);
let m21 = 2. * (q.y * q.z + q.x * q.w);
let m22 = 2. * (q.x * q.x + q.z * q.z) - 1.;
let m23 = 2. * (q.z * q.w + q.x * q.y);
let m31 = 2. * (q.y * q.w - q.x * q.z);
let m32 = 2. * (q.z * q.w + q.x * q.y);
let m33 = 2. * (q.x * q.x + q.w * q.w) - 1.;
let c_1: vec4<f32> = vec4<f32>(m11, m21, m31, 0.);
let c_2: vec4<f32> = vec4<f32>(m12, m22, m32, 0.);
let c_3: vec4<f32> = vec4<f32>(m13, m23, m33, 0.);
let c_4: vec4<f32> = vec4<f32>(0., 0., 0., 1.);
let rotation_matrix: mat4x4<f32> = mat4x4<f32>(c_1, c_2, c_3, c_4);
return rotation_matrix;
}
fn mat4_mul(A: mat4x4<f32>, B: mat4x4<f32> ) -> mat4x4<f32> {
// rows of A
let r_1: vec4<f32> = transpose(A)[0];
let r_2: vec4<f32> = transpose(A)[1];
let r_3: vec4<f32> = transpose(A)[2];
let r_4: vec4<f32> = transpose(A)[3];
//cols of B
let c_1: vec4<f32> = B[0];
let c_2: vec4<f32> = B[1];
let c_3: vec4<f32> = B[2];
let c_4: vec4<f32> = B[3];
let multiplied = mat4x4<f32>(
vec4<f32>(dot(r_1 , c_1), dot(r_2, c_1), dot(r_3, c_1), dot(c_4,c_1)),
vec4<f32>(dot(r_1, c_2), dot(r_2, c_2), dot(r_3, c_2), dot(c_4, c_2)),
vec4<f32>(dot(r_1, c_3), dot(r_2, c_3), dot(r_3, c_3), dot(c_4, c_3)),
vec4<f32>(dot(r_1, c_4), dot(r_2, c_4), dot(r_3, c_4), dot(c_4, c_4)),
);
return multiplied;
}
fn mk_transformation_matrix(position: vec3<f32>, rotation: vec4<f32>) -> mat4x4<f32> {
let transformation_matrix = mat4_mul(mk_translation_matrix(position), mk_rotation_matrix(rotation));
return transformation_matrix;
}