跳到主要内容

WGSL 着色器

着色器目前仅在早期访问中可用。运行时支持正在开发中,或作为实验性构建提供。

有反馈吗?加入早期访问社区分享您的想法,并帮助塑造该功能。

Rive 中的着色器让您编写自定义 WGSL 程序,这些程序在 GPU 上运行并渲染到 GPU 画布,然后可以绘制到您的 Rive 文件中。它们适用于效果、程序化图形以及超出矢量渲染器和标准节点脚本所能产生的视觉效果。

什么是着色器?

着色器是在 GPU 上运行的小型程序。GPU 擅长在多个顶点或像素上并行运行同一程序,这使得着色器非常适用于图形效果。

典型的 GPU 管线使用两个着色器函数:

  • 顶点着色器 - 决定顶点绘制的位置。
  • 片段着色器 - 决定这些顶点覆盖的每个像素的颜色。

创建着色器资源

创建一个新脚本,选择 Shader 作为类型,并将其命名为 BasicShader

AI Agent 可以成为创建或迭代着色器代码的有用方式。描述您想要的效果,然后审查并测试文件中生成的 WGSL。

基本 WGSL 着色器

此着色器绘制一个覆盖渲染目标的大三角形。这是一种称为全屏三角形的常见技术。然后片段着色器使用渐变对每个像素进行着色。

不需要顶点或索引缓冲区,因为三角形点直接定义在着色器中。

基本渐变着色器预览
struct VertexOutput {
@builtin(position) position: vec4<f32>,
@location(0) uv: vec2<f32>,
}

@vertex
fn vs_main(@builtin(vertex_index) vertexIndex: u32) -> VertexOutput {
var pos = array<vec2<f32>, 3>(
vec2<f32>(-1.0, -1.0),
vec2<f32>(3.0, -1.0),
vec2<f32>(-1.0, 3.0),
);
let p = pos[vertexIndex];
var out: VertexOutput;
out.position = vec4<f32>(p, 0.0, 1.0);
out.uv = p * 0.5 + vec2<f32>(0.5, 0.5);
return out;
}

@fragment
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
return vec4<f32>(in.uv.x, in.uv.y, 0.5, 1.0);
}

使用脚本渲染着色器

type ShaderDemo = {
canvas: GPUCanvas?,
pipeline: GPUPipeline?,
}

function init(self: ShaderDemo, context: Context): boolean
self.canvas = context:gpuCanvas({ width = 200, height = 200 })
local shader = context:shader("BasicShader")
if shader and self.canvas then
self.pipeline = GPUPipeline.new({
vertex = shader,
fragment = shader,
vertexLayout = {},
colorTargets = { { format = self.canvas.format } },
})
end
return true
end

function drawCanvas(self: ShaderDemo)
if self.canvas and self.pipeline then
local pass = self.canvas:beginRenderPass({
color = { { loadOp = "clear", storeOp = "store", clearColor = { 0, 0, 0, 1 } } },
})
pass:setPipeline(self.pipeline)
pass:draw(3)
pass:finish()
end
end

function draw(self: ShaderDemo, renderer: Renderer)
if self.canvas then
local sampler = ImageSampler("clamp", "clamp", "bilinear")
renderer:drawImage(self.canvas.image, sampler, "srcOver", 1)
end
end

return function(): Node<ShaderDemo>
return {
canvas = nil,
pipeline = nil,
init = init,
drawCanvas = drawCanvas,
draw = draw,
}
end

工作原理

context:shader

context:shader("BasicShader") 通过名称检索编译后的着色器资源。

GPUCanvas

context:gpuCanvas() 创建着色器绘制到的渲染目标。

GPUPipeline

GPUPipeline.new() 将着色器与渲染设置结合。

drawCanvas

使用 drawCanvas 进行 GPU 渲染。

draw

使用 draw 将渲染后的画布图像绘制到 Rive 场景中。

着色器目标

当编辑器中未选择任何内容时,检查器会显示文件级别的着色器目标选项。

使用这些选项选择 Rive 应从您的 WGSL 着色器生成的着色器语言:

  • Metal (MSL)
  • GLSL ES 300
  • HLSL
  • SPIR-V

启用您的文件将使用的运行时和平台所需的目标。

检查器中的着色器目标选项