使用WebGL和WebGPU片段着色器创建GPU渲染的Svelte组件。
支持Svelte 4和Svelte 5。
简而言之,可以将片段着色器写为一个程序,该程序将像素在屏幕上的坐标中返回并返回该像素应具有的颜色。该程序可以在GPU上执行,以确保大量的并行性和速度。
要了解有关如何编写片段着色器的更多信息,请查看着色书书。
以下是使用SVADER制作的示例的集合。所有这些的实时版本可以在svader.vercel.app上预览,并且可以在src/routes/ Directory中找到源代码。
# npm
npm i -D svader
# pnpm
pnpm i -D svader
# Bun
bun i -D svader
# Yarn
yarn add -D svader要使用碎片着色器组件,您首先需要决定是使用WebGL还是WebGPU。如果您不确定使用什么,请参见WebGL与WebGPU部分。
以下是WebGL片段着色器组件的最小示例。
查看repl
< script >
import { WebGlShader } from " svader " ;
const shaderCode = ` #version 300 es
precision mediump float;
out vec4 fragColor;
uniform vec2 u_resolution;
uniform vec2 u_offset;
void main() {
vec2 pos = gl_FragCoord.xy + u_offset;
vec2 st = pos / u_resolution;
fragColor = vec4(st, 0.0, 1.0);
}
` ;
</ script >
< WebGlShader
width = " 500px "
height = " 500px "
code ={ shaderCode }
parameters ={[
{
name: " u_resolution " ,
value: " resolution " ,
},
{
name: " u_offset " ,
value: " offset " ,
},
]}
>
< div class = " fallback " >WebGL not supported in this environment.</ div >
</ WebGlShader >这会产生以下输出:
在这里, shaderCode变量是包含GLES着色器代码的字符串。为简单起见,它作为字符串存储,但通常将其存储在单独的myShader.frag文件中。从文件加载着色器时,知道code属性同时接受string和Promise<string>可能很有用。
该代码的作用是:
u_offset统一添加到gl_FragCoord.xy给出的像素的2D坐标中。u_resolution统一,以将坐标标准化为0到1之间。x坐标成为红色通道,而y坐标为绿色通道。蓝色通道始终设置为0,并且alpha(不透明度)通道始终设置为1(完全不透明)。在GLE中,统一是该功能的输入,屏幕上的每个像素都相同。这些需要通过<WebGlShader>组件的parameters属性传递。在这种情况下,我们需要穿过两个制服: u_resolution和u_offset 。由于这些特定参数非常常用,因此它们是在SVADER中专门实现的,因此每个参数的value属性可以简单地设置为"resolution"和"offset" 。
最后, <WebGlShader>组件接受一个后备插槽,当浏览器无法渲染着色器时,它将呈现。
parameters属性是具有以下属性的对象数组:
name :统一参数的名称,例如"my_uniform" 。这必须与着色器代码中的参数名称匹配。
type :在着色器代码中编写的统一参数的类型,例如"float" 。如果value属性是内置值,例如"resolution" ,则该type将自动确定,不应设置。
value :统一参数的值或指定内置值的字符串。如果不是内置值,则该属性的类型必须与type属性相对应,以便:
float , int , uint是一个number ,vecN , ivecN , uvecN是一个number[] ,长度为N ,例如vec2 > [1.2, 3.4] 。matN是一个number[] ,长度为N * N ,例如mat2 > [1, 2, 3, 4] 。 某些类型的制服经常使用。这些是在SVADER本身中实现的,并称为内置值。要使用这些,必须将参数对象的value属性设置为匹配以下一个的字符串:
"resolution" :物理设备像素中画布宽度和高度的vec2 。
"scale" :CSS像素和物理设备像素之间的比率的float ,即缩放级别。例如,如果将浏览器缩放到150%,则scale参数为1.5 。
"time" :当前时间的float数秒。注意:将此参数传递给着色器将导致其恢复每个帧。
"offset" :将添加到碎片着色器的gl_FragCoord.xy中的vec2 。有时,画布的大小受到硬件的限制。为了弥补这一点,Svader创建了一个虚拟画布,较小的切口转移以盖住屏幕。自动调整"resolution"参数以匹配此虚拟画布的大小,但是由于技术原因, gl_FragCoord.xy无法从外部调整。因此,提供了"offset"参数,以手动添加到这些坐标中。
以下是WebGPU片段着色器组件的最小示例。
查看repl
< script >
import { WebGpuShader } from " svader " ;
const shaderCode = `
@group(0) @binding(0) var<uniform> resolution: vec2f;
@group(0) @binding(1) var<uniform> offset: vec2f;
@fragment
fn main(@builtin(position) raw_pos: vec4f) -> @location(0) vec4f {
let pos = raw_pos.xy + offset;
let st = pos / resolution;
return vec4f(st, 0.0, 1.0);
}
` ;
</ script >
< WebGpuShader
width = " 500px "
height = " 500px "
code ={ shaderCode }
parameters ={[
{
label: " Resolution " ,
binding: 0 ,
value: " resolution " ,
},
{
label: " Offset " ,
binding: 1 ,
value: " offset " ,
},
]}
>
< div class = " fallback " >WebGPU not supported in this environment.</ div >
</ WebGpuShader >这会产生以下输出:
在这里, shaderCode变量是一个包含WGSL着色器代码的字符串。为简单起见,它作为字符串存储,但通常将其存储在单独的myShader.wgsl文件中。从文件加载着色器时,知道code属性同时接受string和Promise<string>可能很有用。
该代码的作用是:
offset统一变量添加到raw_pos.xy给出的像素的2D坐标中。resolution统一,以在0到1之间将坐标归一化。x坐标成为红色通道,而y坐标为绿色通道。蓝色通道始终设置为0,并且alpha(不透明度)通道始终设置为1(完全不透明)。在WGSL中,这些var<uniform> >是将参数传递给着色器的主要方法。这些需要通过<WebGpuShader>组件的parameters属性传递。在这种情况下,我们需要穿过两个制服: resolution和offset 。由于这些特定参数非常常用,因此它们是在SVADER中专门实现的,因此每个参数的value属性可以简单地设置为"resolution"和"offset" 。
最后, <WebGpuShader>组件接受一个后备插槽,当浏览器无法渲染着色器时,它将呈现。
parameters属性是具有以下属性的对象数组:
label :用于调试的参数的名称。这不必对应着着色器代码中的参数名称。
binding :用于将参数匹配到着色器代码中的变量的整数。这必须匹配着色器代码中参数的binding属性,例如,变量声明
@ group ( 0 ) @ binding ( 42 ) var < uniform > my_variable : f32 ; binding特性应为42 。
value :参数的值或指定内置值的字符串。如果不是内置值,则此参数应为ArrayBuffer / ArrayBufferView 。例如,要将数字传递到f32参数,它可以像new Float32Array([myNumberValue])一样构造。
storage :[可选 - 默认为false ]参数是否是存储变量而不是统一变量。这必须与着色器代码中的声明匹配,例如变量声明
@ group ( 0 ) @ binding ( 0 ) var < uniform > my_variable : f32 ; storage属性应为false或省略,对于
@ group ( 0 ) @ binding ( 0 ) var < storage , read > my_variable : f32 ;应该是true 。请注意,Svader当前仅支持var<storage, read>而不是var<storage, read_write> 。
某些类型的输入经常使用。这些是在SVADER本身中实现的,并称为内置值。要使用这些,必须将参数对象的value属性设置为匹配以下一个的字符串:
"resolution" :物理设备像素中画布宽度和高度的vec2f 。
"scale" :CSS像素和物理设备像素之间比率的f32 ,即缩放级别。例如,如果将浏览器缩放到150%,则scale参数为1.5 。
"time" :当前时间的f32秒。注意:将此参数传递给着色器将导致其恢复每个帧。
"offset" :将添加到片段着色器的@builtin(position)中的vec2f 。有时,画布的大小受到硬件的限制。为了弥补这一点,Svader创建了一个虚拟画布,较小的切口转移以盖住屏幕。自动调整"resolution"参数以匹配此虚拟画布的大小,但是出于技术原因, @builtin(position)无法从外部调整。因此,提供了"offset"参数,以手动添加到这些坐标中。
对于实际应用程序,默认使用WebGL。
WebGL和WebGPU都是渲染API,允许Web应用程序呈现GPU加速图形。
WebGL是两个年龄段的人,并得到所有现代浏览器的支持。
WebGPU仍处于实验阶段,仅在一些浏览器中得到支持。但是,它支持WebGL没有的某些功能。例如,在撰写本文时,Google Chrome中的WebGL仅支持一次在文档中活跃的8个画布,而WebGPU支持一个实际上无限的数字。
SVADER已获得MIT许可证的许可。