Erstellen Sie GPU-gerenderte Svelte-Komponenten mit WebGL- und WebGPU-Fragment-Shadern.
Unterstützt Sufle 4 und Sufelte 5.
Kurz gesagt, ein Fragment -Shader kann als Programm geschrieben werden, das die Koordinaten eines Pixels auf dem Bildschirm nimmt und die Farbe zurückgibt, die dieses Pixel haben sollte. Dieses Programm kann an der GPU ausgeführt werden, um eine massive Parallelität und Geschwindigkeit zu gewährleisten.
Um mehr darüber zu erfahren, wie Sie Fragment -Shader schreiben, lesen Sie das Buch der Shader.
Das Folgende ist eine Sammlung von Beispielen, die alle mit Svader hergestellt wurden. Die Live -Version all dieser kann auf svader.vercel.app vorsichtigen und der Quellcode finden Sie im Verzeichnis src/routes/ Verzeichnisse.
# npm
npm i -D svader
# pnpm
pnpm i -D svader
# Bun
bun i -D svader
# Yarn
yarn add -D svaderUm eine Fragment -Shader -Komponente zu verwenden, müssen Sie zunächst entscheiden, ob Sie WebGL oder WebGPU verwenden möchten. Wenn Sie sich nicht sicher sind, was Sie verwenden sollen, finden Sie im Bereich WebGL vs. WebGPU.
Das Folgende ist ein minimales Beispiel für eine WebGL -Fragment -Shader -Komponente.
Ansicht in 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 >Dies erzeugt die folgende Ausgabe:
Hier ist die shaderCode -Variable eine Zeichenfolge, die den Gles Shader -Code enthält. Der Einfachheit halber wird dies als Zeichenfolge gespeichert, wird jedoch normalerweise in einer separaten myShader.frag -Datei gespeichert. Beim Laden des Shaders aus einer Datei ist es möglicherweise nützlich zu wissen, dass die code sowohl eine string als auch eine Promise<string> akzeptiert.
Was dieser Code tut, ist:
u_offset -Uniform zu den 2D -Koordinaten des von gl_FragCoord.xy angegebenen Pixels hinzu.u_resolution 1.x -Koordinate zum roten Kanal wird und die y -Koordinate zum grünen Kanal wird. Der blaue Kanal ist immer auf 0 gesetzt, und der Alpha -Kanal (Opazität) ist immer auf 1 (vollständig undurchsichtig) eingestellt. In GLES sind Uniformen Eingänge für die Funktion, die für jedes Pixel auf dem Bildschirm gleich sind. Diese müssen über die parameters der <WebGlShader> -Komponente übergeben werden. In diesem Fall müssen wir zwei Uniformen übergeben: u_resolution und u_offset . Da diese spezifischen Parameter sehr häufig verwendet werden, werden sie speziell in Svader implementiert, so dass die value jedes Parameters einfach auf "resolution" und "offset" eingestellt werden kann.
Schließlich akzeptiert die <WebGlShader> -Komponente einen Fallback -Slot, der wiedergegeben wird, wenn der Browser den Shader nicht rendern kann.
Die parameters ist ein Array von Objekten mit den folgenden Eigenschaften:
name : Der Name des einheitlichen Parameters zB "my_uniform" . Dies muss mit dem Namen des Parameters im Shader -Code übereinstimmen.
type : Der Typ des gleichmäßigen Parameters, wie er im Shader -Code "float" geschrieben ist. Wenn die value ein integrierter Wert wie "resolution" ist, wird der type automatisch bestimmt und sollte nicht festgelegt werden.
value : Der Wert des einheitlichen Parameters oder eine Zeichenfolge, die einen integrierten Wert angibt. Wenn nicht ein integrierter Wert, muss der Typ dieser Eigenschaft der type Eigenschaft entsprechen, damit:
float , int , uint ist eine number ,vecN , ivecN , uvecN ist eine number[] mit einer Länge von N , z. B. vec2 -> [1.2, 3.4] .matN ist eine number[] mit einer Länge von N * N , z. B. mat2 -> [1, 2, 3, 4] . Einige Arten von Uniformen werden sehr oft verwendet. Diese werden in Svader selbst implementiert und als integrierte Werte bezeichnet. Um diese zu verwenden, muss die value des Parameterobjekts auf eine Zeichenfolge festgelegt werden, die einem der folgenden Punkte entspricht:
"resolution" : Ein vec2 der Leinwandbreite und -höhe in Pixeln für physikalische Geräte.
"scale" : Ein float des Verhältnisses zwischen CSS -Pixeln und Pixel für physikalische Geräte, dh Zoomebene. Wenn der Browser beispielsweise auf 150%vergrenzt wurde, beträgt der scale -Parameter 1.5 .
"time" : Ein float der aktuellen Zeit in Sekunden. HINWEIS: Wenn Sie diesen Parameter an den Shader übergeben, wird er jeden Frame erneut weiterentwickelt.
"offset" : Ein vec2 der zum gl_FragCoord.xy des Fragment -Shaders hinzugefügt werden soll. Manchmal ist die Größe der Leinwand durch Hardware begrenzt. Um dies zu kompensieren, erstellt Svader eine virtuelle Leinwand mit einem kleineren Ausschnitt, der sich um den Bildschirm abhebt. Der Parameter "resolution" wird automatisch so eingestellt, dass sie der Größe dieser virtuellen Leinwand entspricht, aber aus technischen Gründen kann der gl_FragCoord.xy nicht von außen angepasst werden. Daher soll der Parameter "offset" zu diesen Koordinaten manuell hinzugefügt werden.
Das Folgende ist ein minimales Beispiel für eine WebGPU -Fragment -Shader -Komponente.
Ansicht in 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 >Dies erzeugt die folgende Ausgabe:
Hier ist die shaderCode -Variable eine Zeichenfolge, die den WGSL -Shader -Code enthält. Der Einfachheit halber wird dies als Zeichenfolge gespeichert, wird jedoch normalerweise in einer separaten myShader.wgsl -Datei gespeichert. Beim Laden des Shaders aus einer Datei ist es möglicherweise nützlich zu wissen, dass die code sowohl eine string als auch eine Promise<string> akzeptiert.
Was dieser Code tut, ist:
raw_pos.xy angegebenen Pixel die gegebene offset -Uniformvariable hinzu.resolution normalieren Sie die Koordinaten zwischen 0 und 1.x -Koordinate zum roten Kanal wird und die y -Koordinate zum grünen Kanal wird. Der blaue Kanal ist immer auf 0 gesetzt, und der Alpha -Kanal (Opazität) ist immer auf 1 (vollständig undurchsichtig) eingestellt. In WGSL sind diese var<uniform> s die primäre Möglichkeit, Parameter an den Shader zu übergeben. Diese müssen über die parameters der <WebGpuShader> -Komponente übergeben werden. In diesem Fall müssen wir zwei Uniformen übergeben: resolution und offset . Da diese spezifischen Parameter sehr häufig verwendet werden, werden sie speziell in Svader implementiert, so dass die value jedes Parameters einfach auf "resolution" und "offset" eingestellt werden kann.
Zuletzt akzeptiert die <WebGpuShader> -Komponente einen Fallback -Steckplatz, der wiedergegeben wird, wenn der Browser den Shader nicht rendern.
Die parameters ist ein Array von Objekten mit den folgenden Eigenschaften:
label : Der Name des Parameters zum Debuggen. Dies muss nicht dem Namen des Parameters im Shader -Code entsprechen.
binding : Eine Ganzzahl, die verwendet wird, um den Parameter mit der Variablen im Shader -Code anzupassen. Dies muss mit der binding des Parameters im Shader -Code übereinstimmen, z. B. für die Variablenerklärung
@ group ( 0 ) @ binding ( 42 ) var < uniform > my_variable : f32 ; Die binding sollte 42 sein.
value : Der Wert des Parameters oder eine Zeichenfolge, die einen integrierten Wert angibt. Wenn nicht ein integrierter Wert, sollte dieser Parameter ein ArrayBuffer / ArrayBufferView sein. Um beispielsweise eine Zahl an einen f32 -Parameter zu übergeben, kann es wie new Float32Array([myNumberValue]) konstruiert werden.
storage : [Optional - Standardeinstellungen zu false ] Ob der Parameter eher eine Speichervariable als eine einheitliche Variable ist. Dies muss mit der Erklärung im Shader Code übereinstimmen, z. B. für die Variablenerklärung
@ group ( 0 ) @ binding ( 0 ) var < uniform > my_variable : f32 ; Die storage sollte false oder weggelassen sein und für
@ group ( 0 ) @ binding ( 0 ) var < storage , read > my_variable : f32 ; Es sollte true sein. Beachten Sie, dass Svader derzeit nur var<storage, read> und nicht var<storage, read_write> unterstützt.
Einige Arten von Eingängen werden sehr oft verwendet. Diese werden in Svader selbst implementiert und als integrierte Werte bezeichnet. Um diese zu verwenden, muss die value des Parameterobjekts auf eine Zeichenfolge festgelegt werden, die einem der folgenden Punkte entspricht:
"resolution" : Ein vec2f der Leinwandbreite und -höhe in Pixeln für physikalische Geräte.
"scale" : Ein f32 des Verhältnisses zwischen CSS -Pixeln und Pixel für physikalische Geräte, dh Zoomebene. Wenn der Browser beispielsweise auf 150%vergrenzt wurde, beträgt der scale -Parameter 1.5 .
"time" : ein f32 der aktuellen Zeit in Sekunden. HINWEIS: Wenn Sie diesen Parameter an den Shader übergeben, wird er jeden Frame erneut weiterentwickelt.
"offset" : Ein vec2f der zum @builtin(position) des Fragment -Shaders hinzugefügt werden soll. Manchmal ist die Größe der Leinwand durch Hardware begrenzt. Um dies zu kompensieren, erstellt Svader eine virtuelle Leinwand mit einem kleineren Ausschnitt, der sich um den Bildschirm abhebt. Der Parameter "resolution" wird automatisch so eingestellt, dass sie der Größe dieser virtuellen Leinwand entspricht. Aus technischen Gründen kann die @builtin(position) jedoch nicht von außen angepasst werden. Daher soll der Parameter "offset" zu diesen Koordinaten manuell hinzugefügt werden.
Für praktische Anwendungen standardmäßig die Verwendung von WebGL.
WebGL und WebGPU rendern APIs, mit denen Webanwendungen GPU-beschleunigte Grafiken rendern.
WebGL ist der ältere der beiden und wird von allen modernen Browsern unterstützt.
WebGPU befindet sich noch in der experimentellen Phase und wird nur in wenigen Browsern unterstützt. Es unterstützt jedoch bestimmte Funktionen, die WebGL nicht erledigt. Zum Beispiel unterstützt WebGL in Google Chrome nach dem Schreiben nur 8 Leinwände, die im Dokument gleichzeitig aktiv sind, während WebGPU eine praktisch unbegrenzte Nummer unterstützt.
Svader ist unter der MIT -Lizenz lizenziert.