【问题标题】:Deriving transformation matrix in wgsl shader在 wgsl 着色器中导出变换矩阵
【发布时间】:2021-11-19 12:45:27
【问题描述】:

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

【问题讨论】:

  • mat4x4 乘法在 WGSL 中可用。几乎不确定何时应该在着色器中计算 - 通常变换矩阵对于渲染对象的所有顶点都是统一的,例如相同的旋转应用于对象中的所有点。例如github.com/austinEng/webgpu-samples/blob/main/src/sample/…
  • 非常感谢分享链接。我正在使用实例,其中转换矩阵可能因实例而异。

标签: webgpu


【解决方案1】:

来自 WGSL 规范。

Multiplication(“矩阵算术”部分)

Transpose

【讨论】:

  • 非常感谢。没注意到!
  • 太棒了! WGSL 的语法是 Rusty。您是否成功实施了这些操作?
猜你喜欢
  • 2020-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多