wgsl-renderer 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE.md ADDED
@@ -0,0 +1,9 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2025 taiyuuki
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sub license, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,308 @@
1
+ # WGSL Multi-Pass Renderer
2
+
3
+ 一个基于WebGPU和WGSL的多通道渲染器。
4
+
5
+ ## ✨ 特性
6
+
7
+ - 🔗 **自动Pass链** - Binding 0自动绑定到上一个pass的输出
8
+ - 🖼️ **多Pass渲染** - 支持背景、纹理渲染、后处理效果等多通道
9
+ - ⚡ **高性能渲染循环** - 支持单帧渲染和循环渲染模式
10
+ - 🛠️ **TypeScript支持** - 完整的类型定义和清晰的API分离
11
+ - 🎮 **Uniform系统** - 内置uniform buffer管理,支持动态参数
12
+
13
+ ## 🚀 快速开始
14
+
15
+ ### 安装
16
+
17
+ ```bash
18
+ npm i wgls-renderer
19
+ ```
20
+
21
+ ### 基础使用
22
+
23
+ ```typescript
24
+ import { createWGSLRenderer } from 'wgls-renderer';
25
+
26
+ const canvas = document.getElementById('canvas');
27
+ const renderer = await createWGSLRenderer(canvas, {
28
+ backgroundColor: 0x66CCFF // 支持多种格式:0xRRGGBB, "#RRGGBB", {r, g, b}
29
+ });
30
+
31
+ // 创建采样器
32
+ const sampler = renderer.createSampler();
33
+
34
+ // 加载纹理
35
+ const { texture } = await renderer.loadTexture('image.jpg');
36
+
37
+ // 添加Pass 1: 渲染纹理
38
+ renderer.addPass({
39
+ name: 'texture_pass',
40
+ shaderCode: textureShader,
41
+ blendMode: 'alpha',
42
+ resources: [texture.createView(), sampler] // binding 1, 2
43
+ });
44
+
45
+ // 添加Pass 2: 后处理效果
46
+ const uniforms = renderer.createUniforms(4); // time, resolution.x, resolution.y, padding
47
+ renderer.addPass({
48
+ name: 'post_process',
49
+ shaderCode: postProcessShader,
50
+ blendMode: 'alpha',
51
+ resources: [sampler, uniforms.getBuffer()] // binding 1, 2
52
+ });
53
+
54
+ // 启动循环渲染,支持uniforms更新
55
+ renderer.loopRender(() => {
56
+ // 更新uniforms
57
+ uniforms.values[0] = performance.now() / 1000.0; // 时间
58
+ uniforms.values[1] = canvas.width; // 分辨率
59
+ uniforms.values[2] = canvas.height;
60
+ uniforms.apply();
61
+ });
62
+
63
+ // 或者单帧渲染
64
+ renderer.renderFrame();
65
+ ```
66
+
67
+ ## 📋 API
68
+
69
+ ### createWGSLRenderer(canvas, options?)
70
+
71
+ 创建WGSL渲染器实例。
72
+
73
+ ```typescript
74
+ const renderer = await createWGSLRenderer(canvas, {
75
+ backgroundColor: 0x66CCFF // 支持多种格式
76
+ });
77
+ ```
78
+
79
+
80
+ - `number`: 十六进制颜色 `0xRRGGBB`
81
+ - `string`: 十六进制字符串 `"#RRGGBB"`
82
+ - `object`: RGB对象 `{r: 0-1, g: 0-1, b: 0-1}`
83
+
84
+ ### 渲染控制
85
+
86
+ #### renderFrame()
87
+ 单帧渲染,不循环。
88
+
89
+ ```typescript
90
+ renderer.renderFrame();
91
+ ```
92
+
93
+ #### loopRender(callback?)
94
+ 循环渲染,支持每帧回调,可用于时时更新uniforms。
95
+
96
+ ```typescript
97
+ renderer.loopRender(() => {
98
+ // 每帧更新uniforms
99
+ myUniforms.values[0] = performance.now() / 1000.0;
100
+ myUniforms.apply();
101
+ });
102
+ ```
103
+
104
+ #### stopLoop()
105
+ 停止循环渲染。
106
+
107
+ ```typescript
108
+ renderer.stopLoop();
109
+ ```
110
+
111
+ ### addPass(descriptor)
112
+
113
+ 添加一个渲染通道。
114
+
115
+ ```typescript
116
+ renderer.addPass({
117
+ name: 'my_pass',
118
+ shaderCode: wgslShaderCode,
119
+ blendMode: 'alpha',
120
+ resources: [textureView, sampler] // 资源数组
121
+ });
122
+ ```
123
+
124
+ **资源数组绑定规则:**
125
+ - **Binding 0**: 自动绑定到上一个pass的输出(无需在数组中指定)
126
+ - **Binding 1**: `resources[0]`
127
+ - **Binding 2**: `resources[1]`
128
+ - 以此类推...
129
+
130
+ **对应的WGSL绑定:**
131
+ ```wgsl
132
+ @group(0) @binding(0) var prevTexture: texture_2d<f32>; // 自动
133
+ @group(0) @binding(1) var myTexture: texture_2d<f32>; // resources[0]
134
+ @group(0) @binding(2) var mySampler: sampler; // resources[1]
135
+ ```
136
+
137
+ ### Uniform
138
+
139
+ #### createUniforms(length)
140
+ 创建uniform buffer管理对象。
141
+
142
+ ```typescript
143
+ const uniforms = renderer.createUniforms(4); // 4个float
144
+ uniforms.values[0] = 1.0; // 设置值
145
+ uniforms.apply(); // 应用到GPU
146
+ const buffer = uniforms.getBuffer(); // 获取GPUBuffer
147
+ ```
148
+
149
+ #### getUniformsByID(id)
150
+ 通过symbol ID获取uniform对象。
151
+
152
+ ```typescript
153
+ const uniform = renderer.getUniformsByID(myUniformSymbol);
154
+ ```
155
+
156
+ ## 🎨 着色器示例
157
+
158
+ ### Pass 1: 纹理渲染
159
+
160
+ ```wgsl
161
+ struct VSOut {
162
+ @builtin(position) pos: vec4<f32>,
163
+ @location(0) uv: vec2<f32>,
164
+ };
165
+
166
+ @vertex
167
+ fn vs_main(@location(0) p: vec3<f32>) -> VSOut {
168
+ var o: VSOut;
169
+ o.pos = vec4<f32>(p, 1.0);
170
+ o.uv = p.xy * 0.5 + vec2<f32>(0.5, 0.5);
171
+ o.uv.y = 1.0 - o.uv.y;
172
+ return o;
173
+ }
174
+
175
+ @group(0) @binding(0) var prevTexture: texture_2d<f32>; // 内置的纯色背景纹理
176
+ @group(0) @binding(1) var myTexture: texture_2d<f32>;
177
+ @group(0) @binding(2) var mySampler: sampler;
178
+
179
+ @fragment
180
+ fn fs_main(@location(0) uv: vec2<f32>) -> @location(0) vec4<f32> {
181
+ let bgColor = textureSample(prevTexture, mySampler, uv);
182
+ let texColor = textureSample(myTexture, mySampler, uv);
183
+
184
+ // 背景与纹理混合
185
+ return vec4<f32>(
186
+ bgColor.r * (1.0 - texColor.a) + texColor.r * texColor.a,
187
+ bgColor.g * (1.0 - texColor.a) + texColor.g * texColor.a,
188
+ bgColor.b * (1.0 - texColor.a) + texColor.b * texColor.a,
189
+ 1.0
190
+ );
191
+ }
192
+ ```
193
+
194
+ ### Pass 2: 动态后处理效果
195
+
196
+ ```wgsl
197
+ struct Uniforms {
198
+ time: f32,
199
+ resolution: vec2<f32>,
200
+ }
201
+
202
+ @group(0) @binding(0) var prevTexture: texture_2d<f32>; // Pass 1的输出纹理
203
+ @group(0) @binding(1) var mySampler: sampler;
204
+ @group(0) @binding(2) var<uniform> uniforms: Uniforms;
205
+
206
+ @fragment
207
+ fn fs_main(@location(0) uv: vec2<f32>) -> @location(0) vec4<f32> {
208
+ var color = textureSample(prevTexture, mySampler, uv);
209
+
210
+ // 动态扫描线效果
211
+ let scanline = 0.8 + 0.2 * sin(uv.y * 600.0 + uniforms.time * 5.0);
212
+ color = vec4<f32>(color.r * scanline, color.g * scanline, color.b * scanline, color.a);
213
+
214
+ // 动态波纹效果
215
+ let waveAmplitude = 0.05 + 0.02 * sin(uniforms.time * 2.0);
216
+ let waveX = sin(uv.x * 10.0 + uniforms.time * 3.0) * cos(uv.y * 8.0 + uniforms.time * 2.0) * waveAmplitude;
217
+
218
+ let finalR = clamp(color.r + waveX, 0.0, 1.0);
219
+ let finalG = clamp(color.g - waveX * 0.5, 0.0, 1.0);
220
+ let finalB = clamp(color.b + waveX * 0.3, 0.0, 1.0);
221
+
222
+ return vec4<f32>(finalR, finalG, finalB, color.a);
223
+ }
224
+ ```
225
+
226
+ ## 🔧 内置方法
227
+
228
+ ### 纹理相关
229
+
230
+ ```typescript
231
+ // 加载纹理
232
+ const { texture, width, height } = await renderer.loadTexture('image.png');
233
+
234
+ // 创建采样器
235
+ const sampler = renderer.createSampler({
236
+ magFilter: 'linear',
237
+ minFilter: 'linear',
238
+ addressModeU: 'clamp-to-edge',
239
+ addressModeV: 'clamp-to-edge',
240
+ });
241
+
242
+ // 创建纹理绑定
243
+ const textureView = renderer.createTextureBinding(texture);
244
+ ```
245
+
246
+ ### 控制相关
247
+
248
+ ```typescript
249
+ // 调整画布大小
250
+ renderer.resize(800, 600);
251
+
252
+ // 停止渲染
253
+ renderer.stopLoop();
254
+ ```
255
+
256
+ ## 🎯 Pass流程
257
+
258
+ 渲染器自动管理以下pass流程:
259
+
260
+ 1. **Background Pass** (内置)
261
+ - 渲染纯色背景
262
+ - 输出到 `pass_0_output`
263
+
264
+ 2. **User Pass 1**
265
+ - Binding 0: 背景输出
266
+ - Binding 1+: 用户资源
267
+ - 输出到 `pass_1_output`
268
+
269
+ 3. **User Pass 2**
270
+ - Binding 0: Pass 1输出
271
+ - Binding 1+: 用户资源
272
+ - 输出到 `pass_2_output`
273
+
274
+ 4. **Final Pass**
275
+ - Binding 0: 上一个pass输出
276
+ - 渲染到canvas
277
+
278
+ ## 📁 项目结构
279
+
280
+ ```
281
+ src/
282
+ ├── index.ts # 主渲染器类,包含完整的API
283
+ ├── RenderPass.ts # Pass渲染逻辑和类型定义
284
+ ├── TextureManager.ts # 纹理管理
285
+ examples/
286
+ └── multi-pass-demo.html # 完整示例,包含纹理、动态uniforms效果
287
+ ```
288
+
289
+ ## 🛠️ 开发
290
+
291
+ ```bash
292
+ # 开发模式
293
+ npm run dev
294
+
295
+ # 构建
296
+ npm run build
297
+
298
+ # 类型检查
299
+ npm run type-check
300
+ ```
301
+
302
+ ## 📝 许可证
303
+
304
+ MIT License
305
+
306
+ ## 🤝 贡献
307
+
308
+ 欢迎提交Issue和Pull Request!