rsbuild-plugin-glsl is a Rsbuild plugin to process GLSL shader files.
Install:
npm i rsbuild-plugin-glsl -D
pnpm i rsbuild-plugin-glsl -D
Add plugin to your rsbuild.config.ts
:
// rsbuild.config.ts
import UnoCSS from '@unocss/postcss';
import { defineConfig } from '@rsbuild/core';
import { pluginGlsl } from 'rsbuild-plugin-glsl';
import { pluginReact } from '@rsbuild/plugin-react';
import { pluginLess } from '@rsbuild/plugin-less';
import AutoImport from 'unplugin-auto-import/rspack';
import { resolve } from 'path';
import IconsResolver from 'unplugin-icons/resolver';
export default defineConfig({
html: {
template: './index.html',
},
source: {
entry: {
index: './src/index.tsx',
},
alias: {
'@': resolve(__dirname, './src'),
},
define: {
'process.env.APP_TITLE': JSON.stringify(process.env.APP_TITLE),
},
},
output: {
externals: {
// 'mapbox-gl': 'mapboxgl',
},
assetPrefix: '/rsbuild-plugin-glsl/',
},
plugins: [pluginReact(), pluginLess(), pluginGlsl()],
tools: {
rspack: {
plugins: [
AutoImport({
// dts: path.resolve(pathSrc, 'typings', 'auto-imports.d.ts'),
dts: 'types/auto-imports.d.ts',
// dirs: ['./src/hooks'],
// Generate corresponding .eslintrc-auto-import.json file.
// eslint globals Docs - https://eslint.org/docs/user-guide/configuring/language-options#specifying-globals
eslintrc: {
enabled: true,
},
imports: [
'react',
{
// 全局使用 _.xxxx()
'lodash-es': [
// default imports
['*', '_'], // import { * as _ } from 'lodash-es',
],
},
],
// Auto import functions from UILibrary, e.g. Message, Spin, Loading, MessageBox... (with style)
resolvers: [
IconsResolver({
prefix: 'icon',
extension: 'jsx',
customCollections: ['custom'],
}),
],
}),
],
},
postcss: {
postcssOptions: {
plugins: [UnoCSS()],
},
},
},
server: {
proxy: {},
},
});
Add extension declarations to your types
in tsconfig.json
:
{
"compilerOptions": {
"types": [
"rsbuild-plugin-glsl/ext"
]
}
}
or as a package dependency directive to your global types:
/// <reference types="rsbuild-plugin-glsl/ext" />
Option | Desc | Type | Default |
---|---|---|---|
root | Directory for root imports | string |
/ |
include | Glob pattern, RegExp for include file | RegExp |
`/.(glsl |
exclude | Glob pattern, RegExp for ignore | RegExp |
undefined |
warnDuplicatedImports | Warn if the same chunk was imported multiple times | boolean |
true |
compress | Compress output shader code | boolean |
true |
defaultExtension | Shader suffix when no extension is specified | string |
glsl |
- Example:
pluginGlsl({
include: /\.(glsl|wgsl|vert|frag|vs|fs)$/,
exclude: undefined,
warnDuplicatedImports: true,
defaultExtension: 'glsl',
compress: false,
root: '/'
});
root
├── src/
│ ├── glsl/
│ │ ├── chunk0.frag
│ │ ├── chunk3.frag
│ │ ├── main.frag
│ │ ├── main.vert
│ │ └── utils/
│ │ ├── chunk1.glsl
│ │ └── chunk2.frag
│ └── main.js
├── rsbuild.config.ts
└── package.json
// main.js
import fragment from './glsl/main.frag';
// main.frag
#version 300 es
#ifndef GL_FRAGMENT_PRECISION_HIGH
precision mediump float;
#else
precision highp float;
#endif
out vec4 fragColor;
#include chunk0.frag;
void main (void) {
fragColor = chunkFn();
}
// chunk0.frag
// ".glsl" extension will be added automatically:
#include utils/chunk1;
vec4 chunkFn () {
return vec4(chunkRGB(), 1.0);
}
// utils/chunk1.glsl
#include chunk2.frag;
#include ../chunk3.frag;
vec3 chunkRGB () {
return vec3(chunkRed(), chunkGreen(), 0.0);
}
// utils/chunk2.frag
float chunkRed () {
return 0.0;
}
// chunk3.frag
float chunkGreen () {
return 0.8;
}
Will result in:
// main.frag
#version 300 es
#ifndef GL_FRAGMENT_PRECISION_HIGH
precision mediump float;
#else
precision highp float;
#endif
out vec4 fragColor;
float chunkRed () {
return 0.0;
}
float chunkGreen () {
return 0.8;
}
vec3 chunkRGB () {
return vec3(chunkRed(), chunkGreen(), 0.0);
}
vec4 chunkFn () {
return vec4(chunkRGB(), 1.0);
}
void main (void) {
fragColor = chunkFn();
}
MIT.