0

导出变换矩阵是着色器相当普遍的要求。是否有和 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; 
}

4

1 回答 1

0

来自 WGSL 规范。

乘法(“矩阵算术”部分)

转置

于 2021-09-27T13:28:19.067 回答