Built-in functions

shader-learning.com/module-view...

1. Fragment Shader

fragment 着色器需要返回vec4f的向量作为颜色,-> @location(0) vec4<f32>表示返回的颜色存储在@location(0)的公共位置上

wgsl 复制代码
#import bevy_sprite::mesh2d_vertex_output::VertexOutput

@fragment
fn fragment(in: VertexOutput) -> @location(0) vec4<f32> {
    return vec4f(1.0, 1.0, 0.0, 1.0);
}

结果

2. Vec

向量支持相加,相加时同位置分量相加

wgsl 复制代码
#import bevy_sprite::mesh2d_vertex_output::VertexOutput

@fragment
fn fragment(in: VertexOutput) -> @location(0) vec4<f32> {
  var blueChannel = vec4f(0.0, 0.0, 0.75, 0.0);
  var redChannel = vec4f(0.5, 0.0, 0.0, 0.0);
  var alphaChannel = vec4f(0.0, 0.0, 0.0, 1.0);
  
  return blueChannel + redChannel + alphaChannel;
}

结果

3. Swizzling

向量可以通过(x,y,z,w)或(r,g,b,a)或(s,t,p,q)访问,不同顺序最后展示值相应变化

wgsl 复制代码
#import bevy_sprite::mesh2d_vertex_output::VertexOutput

@fragment
fn fragment(in: VertexOutput) -> @location(0) vec4<f32> {
  var blueChannel = vec4f(0.0, 0.0, 0.75, 0.0);
  var redChannel = vec4f(0.5, 0.0, 0.0, 0.0);
  var alphaChannel = vec4f(0.0, 0.0, 0.0, 1.0);
  var color = blueChannel + redChannel + alphaChannel;
  return color.gbra;
}

结果

4. UV Coordinates & Uniforms

通过Bevy shader导入VertexOutput中获取uv,原始值与预期有diff,通过1.0 - uv.x将x值取反,反馈到结果是水平翻转,返回取uv.yx将xy值反转,返回到结果为沿/方向翻转

wgsl 复制代码
#import bevy_sprite::mesh2d_vertex_output::VertexOutput

@fragment
fn fragment(in: VertexOutput) -> @location(0) vec4<f32> {
    var uv = in.uv;
    uv.x = 1.0 - uv.x;
    return vec4f(uv.yx, 0.0, 1.0);
}

结果

5. Step

通过内置step函数第二个参数小于第一个参数返回0.0,大于第一个参数返回1.0,所以左半屏为黑uv.x<0.5,右半屏为红uv.x>0.5

wgsl 复制代码
#import bevy_sprite::mesh2d_vertex_output::VertexOutput

@fragment
fn fragment(in: VertexOutput) -> @location(0) vec4<f32> {
    var uv = in.uv;
    return vec4f(step(0.5, uv.x), 0.0, 0.0, 1.0);
}

结果

6. Step - Invert

因为分量都是0-1直接浮点数,所以可以通过1.0 - *对分量取反

wgsl 复制代码
#import bevy_sprite::mesh2d_vertex_output::VertexOutput

@fragment
fn fragment(in: VertexOutput) -> @location(0) vec4<f32> {
    var uv = in.uv;
    return vec4f(1.0 - step(0.5, uv.x), 0.0, 0.0, 1.0);
}

结果

7. Max

通过step函数判断像素区间,t1表示像素是否小于屏幕1/4,小于时t1值为1.0否则为0.0,t2表示像素是否大于屏幕3/4,大于时t1值为1.0否则为0.0,再通过max函数设置颜色,max函数返回两个参数中较大值,所以在小于屏幕1/4和大于屏幕3/4位置被上色了

wgsl 复制代码
#import bevy_sprite::mesh2d_vertex_output::VertexOutput

@fragment
fn fragment(in: VertexOutput) -> @location(0) vec4<f32> {
    var uv = in.uv;
    
    var color = vec3f(1.0, 0.3, 0.3);
    var t1 = 1.0 - step(0.25, uv.x);
    var t2 = step(0.75, uv.x);
    
    return vec4f(color * max(t1, t2), 1.0);
}

结果

8. Step Union

通过Bevy shader导入View并将其存入@group(0) @binding(0) var<uniform> view0组0位uniform类型,Viewviewport为vec4f向量,zw表示宽高,通过50.0 / view.viewport.z获得50像素占屏幕宽度的比例, 通过50.0 / view.viewport.w获得50像素占屏幕高度的比例,t1表示像素是否距离屏幕左侧50像素内,t2表示像素是否距离屏幕右侧50像素内,t3表示像素是否距离屏幕上方50像素内,t4表示像素是否距离屏幕下方50像素内,三次max函数取值为判断像素是否在屏幕四周50像素的边框内,拆解开来开,max(t3, t4)判断像素是否在上方或者下方50像素内,max(t2, max(t3, t4))判断像素是否在像素是否距离屏幕右侧50像素内且上方或者下方50像素内,max(t1, max(t2, max(t3, t4)))判断像素是否在像素是否距离屏幕左侧或右侧50像素内且上方或者下方50像素内,后续再进行预期的处理同#4

wgsl 复制代码
#import bevy_render::view::View
#import bevy_sprite::mesh2d_vertex_output::VertexOutput

@group(0) @binding(0) var<uniform> view: View;

@fragment
fn fragment(in: VertexOutput) -> @location(0) vec4<f32> {
    var uv = in.uv;
    var xw = 50.0 / view.viewport.z;
    var yh = 50.0 / view.viewport.w;

    var t1 = step(1.0 - xw, uv.x);
    var t2 = 1.0 - step(xw, uv.x);
    var t3 = step(1.0 - yh, uv.y);
    var t4 = 1.0 - step(yh, uv.y);
  
    var t = max(t1, max(t2, max(t3, t4)));
    uv.x = 1.0 - uv.x;
    return vec4(uv.yx * t, 0.0, 1.0);
}

结果

9. Fract

fract函数用于返回浮点值的小数部分,该函数接受单个参数,可以是floatvec2vec3vec4,并返回一个介于0.01.0之间的值,将像素x值放大10倍后取小数部分,判断小数部分是否大于0.5,即可知道像素在左半部分还是右半部分,例:

  • 0.153 * 10 -> 1.53 -> fract() -> 0.53 -> 0.53 > 0.5 需要着色
  • 0.314 * 10 -> 3.14 -> fract() -> 0.14 -> 0.14 < 0.5 不需要着色
wgsl 复制代码
@fragment
fn fragment(in: VertexOutput) -> @location(0) vec4<f32> {
    var uv = in.uv;
    var x = fract(uv.x * 10.0);

    return vec4f(step(0.5, x), 0.0, 0.0, 1.0);
}

结果

10. Tile Pattern

通过操作UV坐标并使用fract函数,可以在屏幕上创建重复模式

wgsl 复制代码
fn pattern(uv: vec2f) -> f32 {
    let new_uv = uv * 2.0 - 1.0;
    var t = pow(new_uv.x * new_uv.x, 0.3) + pow(new_uv.y * new_uv.y, 0.3) - 1.0;
    return step(0.0, t) * t * 10.0 + step(0.2, t);
  }

@fragment
fn fragment(in: VertexOutput) -> @location(0) vec4<f32> {
    var uv = in.uv;

    var columns = 5.0;
    var rows = 3.0;

    var repeated_uv = fract(uv * vec2(columns, rows));

    return vec4f(pattern(repeated_uv), 0.0, 0.0, 1.0);
}

结果

相关推荐
明月看潮生4 小时前
青少年编程与数学 02-019 Rust 编程基础 01课题、环境准备
开发语言·青少年编程·rust·编程与数学
液态不合群1 天前
rust程序静态编译的两种方法总结
开发语言·后端·rust
明月看潮生2 天前
青少年编程与数学 02-019 Rust 编程基础 02课题、开始编程
开发语言·算法·青少年编程·rust·编程与数学
rayylee2 天前
Ubuntu也开始锈化了?Ubuntu 计划在 25.10 版本开始引入 Rust Coreutils
linux·ubuntu·rust
Source.Liu3 天前
【PhysUnits】2.2 Scalar<T> 标量元组结构体(scalar/mod.rs)
rust
vivo互联网技术3 天前
FunProxy - 使用 Rust 构建跨平台全链路测试抓包代理工具
软件测试·rust·抓包·代理
@PHARAOH3 天前
WHAT - Rust 静态派发(Static Dispatch)和 动态派发(Dynamic Dispatch)
开发语言·后端·rust
Source.Liu3 天前
【PhysUnits】2 Scalar<T> 标量元组结构体(scalar/mod.rs)
rust
muyouking113 天前
Rust 中 Arc 的深度分析:从原理到性能优化实践
开发语言·性能优化·rust
muyouking113 天前
Rust 与 Golang 深度对决:从语法到应用场景的全方位解析
rust