webgpu的中的顶点插值
- 正常情况下,顶点着色器都是返回一个四维向量,如果要画一个三角形,呢么就是pos就是我们传入的三个顶点坐标,返回值就是将这些坐标转换成四维向量返回
// 顶点着色器代码
@vertex
fn main(@location(0) pos: vec3<f32>) -> @builtin(position) vec4<f32> {
return vec4<f32>(pos,1.0);//缩放矩阵对顶点缩放变换
}
-
插值的意思,就是GPU会根据你的传入的三个点的坐标,在之内在生成其他的点,你可以理解一个大的三角形是有许许多多小的三角形组成的,所以自动会生出其他的点
-
这个时候顶点着色器就不能返回一个四维向量了,就必须定义一个结构体返回.
结构体的第一个成员就是原来的那个四维向量,也就是我们输入的坐标,转换后的四维坐标.
第二个成员就是自动生成的三维向量,也就是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;
}
- 然后在片元着色器中绑定变量就是可以使用.
需要注意的是,这个插值的值是基于webgpu 3d 标准设备坐标系的.
即x和y的返回是-1到1,z的返回是0到1.
// 片元着色器代码
// 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中不要考虑模型矩阵对顶点插值的影响
- 一开始我我也是怀疑这个模型既然对需要对原坐标产生影响,
呢么我也需要对其插值坐标产生影响,才能够消除影响,
实际上不需要这样,模型矩形的变换,直接作用于原坐标就行了,
插值的坐标会自动的收到影响,
原因么,可能插值的坐标采用的相对的坐标.
// 顶点着色器代码
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;
}