cnblog_触发器

发布时间 2023-06-04 11:56:59作者: 虎虎生威啊

webgpu的中的顶点插值

  1. 正常情况下,顶点着色器都是返回一个四维向量,如果要画一个三角形,呢么就是pos就是我们传入的三个顶点坐标,返回值就是将这些坐标转换成四维向量返回
// 顶点着色器代码
@vertex
fn main(@location(0) pos: vec3<f32>) -> @builtin(position) vec4<f32> {
    return vec4<f32>(pos,1.0);//缩放矩阵对顶点缩放变换
}
  1. 插值的意思,就是GPU会根据你的传入的三个点的坐标,在之内在生成其他的点,你可以理解一个大的三角形是有许许多多小的三角形组成的,所以自动会生出其他的点

  2. 这个时候顶点着色器就不能返回一个四维向量了,就必须定义一个结构体返回.
    结构体的第一个成员就是原来的那个四维向量,也就是我们输入的坐标,转换后的四维坐标.
    第二个成员就是自动生成的三维向量,也就是gpu根据你传入的两个点,然后生成的中间点的坐标.

struct Out{
    @builtin(position) position:vec4<f32>,
    // 位置变量vPosition表示顶点位置坐标插值后的坐标,vPosition用来表示每个片元的xyz坐标, 通过location标记改变量,location的参数可以是0、1、2等
    @location(0) vPosition:vec3<f32>,
}

@vertex
fn main(@location(0) pos: vec3<f32>) -> Out {
    var out:Out;//通过结构体声明一个变量
    out.position = vec4<f32>(pos,1.0);
    out.vPosition = pos;//插值计算,生成的每个片元对应的xyz坐标
    return out;
}
  1. 然后在片元着色器中绑定变量就是可以使用.
    需要注意的是,这个插值的值是基于webgpu 3d 标准设备坐标系的.
    即x和y的返回是-1到1,z的返回是0到1.

img

// 片元着色器代码
// main参数通过@location(0)声明一个变量,和顶点着色器中vPosition变量关联起来
@fragment
fn main(@location(0) vPosition:vec3<f32>) -> @location(0) vec4<f32> {
    // 根据x坐标设置片元颜色
    if(vPosition.x<0.5){
        return vec4<f32>(1.0, 0.0, 0.0, 1.0);
    }else{
        return vec4<f32>(0.0, 1.0, 0.0, 1.0);
    }
}

webgpu中不要考虑模型矩阵对顶点插值的影响

  1. 一开始我我也是怀疑这个模型既然对需要对原坐标产生影响,
    呢么我也需要对其插值坐标产生影响,才能够消除影响,
    实际上不需要这样,模型矩形的变换,直接作用于原坐标就行了,
    插值的坐标会自动的收到影响,
    原因么,可能插值的坐标采用的相对的坐标.
// 顶点着色器代码
const vertexShader = /* wgsl */ `
struct Out{
    @builtin(position) position:vec4<f32>,
    @location(0) vPosition:vec3<f32>,
}
@vertex
fn main(@location(0) pos: vec3<f32>) -> Out {
    var out:Out;//通过结构体声明一个变量

    var T = mat4x4<f32>(1.0,0.0,0.0,0.0,  0.0,1.0,0.0,0.0,  0.0,0.0,1.0,0.0,  -0.5,-0.5,0.0,1.0);

    // 平移矩阵肯定是对position,也就是我们传入的坐标值是产生影响的,所以这里肯定要计算
    out.position = T * vec4<f32>(pos,1.0);

    // 但是对插值就是不要写一遍了,直接赋值就行,但是当我们再次进行矩阵影响的时候,反倒不起作用了.
    // out.vPosition = (T* vec4<f32>(pos,1.0)).xyz;
    out.vPosition = pos; 

    return out;
}