使用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許可證的許可。