plugin that imports and compiles Slang shaders directly to viable wgsl/glsl for vite typescript.
supports lazy loading and destruct importing efficinetly.
npm install -D @postred/viteslang
# or
pnpm add -D @postred/viteslang
# or
yarn add -D @postred/viteslangslangc compiler installed and available in your system's PATH.*
Add the plugin to your vite.config.ts:
import { defineConfig } from 'vite';
import { slangplugin } from '@postred/viteslang';
export default defineConfig({
plugins: [slangplugin()]
});this plugin automatically generates .d.ts files right next to the shader files. I suggest adding *.slang.d.ts to the .gitignore.
i also highly recommend using standard slang syntax with entry points that explicitly state the stage such as:
[shader("vertex")]
void vxmain() { ... }
[shader("fragment")]
float4 pxmain() { ... }if they are not provided the plugin defaults (falls back) to look for "main" function and assumes it's a fragment/pixel shader
all entry points are compiled but vite/rollup tree shakes the unimported ones then.
import { vertexMain, fragmentMain } from './ui.slang?target=wgsl';
console.log(`compiling ${vertexMain.stage} to ${vertexMain.target}`);
const pipeline = device.createRenderPipeline({
vertex: {
module: device.createShaderModule({ code: vertexMain.code }),
entryPoint: vertexMain.name
},
// ...
});using ?entry parameter compiles only the desired entry from "ideally" a massive slang file.
const heavyComputeModule = device.createShaderModule({
label: 'big compute',
code: await import('./big.slang?entry=randomizationPass&target=wgsl').then(m => m.randomizationPass.code)
});You can request multiple specific shaders asynchronously in a single network request by comma-separating the entries.
const loadPostProcessing = async () => {
if(condition){
const { bloomFrag, blurFrag } = await import('./post.slang?entry=bloomFrag,blurFrag&target=wgsl');
do stuff;
}else{
const { bloomFrag, blurFrag } = await import('./post.slang?entry=flareFrag,pxlFrag&target=wgsl');
do other stuff;
}
return {
bloom: device.createShaderModule({ code: bloomFrag.code }),
blur: device.createShaderModule({ code: blurFrag.code })
};
};| Parameter | Options | Description |
|---|---|---|
target |
wgsl | glsl |
The compilation target. defaults to glsl. |
entry |
string |
comma separated list of specific shader names to compile (e.g., ?entry=main,compute). Omit to compile all shaders in the file. |
- it just fires
slangcchild processes in parallel.
- fix multi line entries reading/writing from/to the same types file like:
import { vx } from './shader.slang?entry=vx';
import { fx } from './shader.slang?entry=fx';- add second exported function for fetching (probably not building) slang (maybe wasm version for complete cross platformability) for users who dont have slang on path or maybe for everyone? (probably will switch wasm to default and slang on path to be optional for people who want latest slang)