@bigmistqke/view.gl 0.1.2 → 0.1.4
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/.claude/settings.local.json +4 -1
- package/README.md +549 -151
- package/dev/src/examples/bezier.ts +3 -9
- package/dev/src/examples/{game_of_life.ts → game-of-life.ts} +2 -9
- package/dev/src/examples/glsl-composition.ts +131 -0
- package/dev/src/examples/grid.ts +4 -3
- package/dev/src/examples/overview.ts +7 -6
- package/dev/src/examples/{pix_sim.ts → pix-sim.ts} +3 -14
- package/dev/src/examples/symbol.ts +4 -3
- package/dev/src/index.ts +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs.map +1 -1
- package/dist/tag.d.mts +39 -21
- package/dist/tag.mjs +387 -47
- package/dist/tag.mjs.map +1 -1
- package/dist/{types-DoFAJoh-.d.mts → types-CGTxl3Eq.d.mts} +33 -11
- package/package.json +3 -2
- package/src/index.ts +4 -4
- package/src/tag.ts +205 -110
- package/src/types.ts +70 -5
- package/src/utils/index.ts +9 -9
- package/test/tag.test.ts +531 -82
package/README.md
CHANGED
|
@@ -1,34 +1,55 @@
|
|
|
1
|
-
# view.gl
|
|
1
|
+
# 👁️ @bigmistqke/view.gl
|
|
2
2
|
|
|
3
|
-
Minimal library for WebGL
|
|
3
|
+
🔧 Minimal library for managing WebGL uniforms / (interleaved) attributes / buffers / ...
|
|
4
|
+
|
|
5
|
+
- schema-based resource management [`view-gl`](#️-viewgl)
|
|
6
|
+
- type-safe GLSL template literals to compose schemas [`view-gl/tag`](#️-viewgltag)
|
|
4
7
|
|
|
5
8
|
## Table of Contents
|
|
6
9
|
|
|
7
|
-
- [
|
|
8
|
-
|
|
9
|
-
- [
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
- [
|
|
13
|
-
- [
|
|
14
|
-
|
|
15
|
-
- [
|
|
16
|
-
|
|
17
|
-
- [
|
|
18
|
-
- [
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
- [
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
10
|
+
- [📦 Install](#-install)
|
|
11
|
+
- [👁️ view.gl](#️-viewgl)
|
|
12
|
+
- [🚀 Basic Usage](#-basic-usage)
|
|
13
|
+
- [👁️ view](#️-view)
|
|
14
|
+
- [👀 Resource Views](#-resource-views)
|
|
15
|
+
- [🎯 uniformView](#-uniformview)
|
|
16
|
+
- [📝 attributeView](#-attributeview)
|
|
17
|
+
- [🔗 interleavedAttributeView](#-interleavedattributeview)
|
|
18
|
+
- [🗂️ bufferView](#-bufferview)
|
|
19
|
+
- [🏷️ view.gl/tag](#️-viewgltag)
|
|
20
|
+
- [🚀 Basic Usage](#-basic-usage-1)
|
|
21
|
+
- [📝 glsl](#-glsl)
|
|
22
|
+
- [🧩 GLSL Fragment](#-glsl-fragment)
|
|
23
|
+
- [🔒 Symbol Scoping](#-symbol-scoping)
|
|
24
|
+
- [WebGL Version Support](#webgl-version-support)
|
|
25
|
+
- [⚙️ Resource Tags](#️-resource-tags)
|
|
26
|
+
- [🎯 uniform[kind](name, options?)](#-uniformkindname-options)
|
|
27
|
+
- [📝 attribute[kind](name, options?)](#-attributekindname-options)
|
|
28
|
+
- [🔗 interleave(name, layout, options?)](#-interleavename-layout-options)
|
|
29
|
+
- [⚙️ compile(gl, vertex, fragment)](#️-compilegl-vertex-fragment)
|
|
30
|
+
- [🛠️ Utils](#️-utils)
|
|
31
|
+
- [🏗️ createProgram](#️-createprogram)
|
|
32
|
+
- [🖼️ createTexture](#️-createtexture)
|
|
33
|
+
- [🖥️ createFramebuffer](#️-createframebuffer)
|
|
34
|
+
- [🔍 WebGL Type Compatibility](#-webgl-type-compatibility)
|
|
35
|
+
- [🎯 Uniform Types](#-uniform-types)
|
|
36
|
+
- [📝 Attribute Types](#-attribute-types)
|
|
37
|
+
|
|
38
|
+
## 📦 Install
|
|
39
|
+
|
|
40
|
+
```shell
|
|
41
|
+
npm install @bigmistqke/view.gl
|
|
42
|
+
# or
|
|
43
|
+
pnpm add @bigmistqke/view.gl
|
|
44
|
+
# or
|
|
45
|
+
yarn add @bigmistqke/view.gl
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## 👁️ view.gl
|
|
49
|
+
|
|
50
|
+
The view system provides type-safe WebGL resource management for uniforms, attributes, and buffers
|
|
51
|
+
|
|
52
|
+
### 🚀 Basic Usage
|
|
32
53
|
|
|
33
54
|
```typescript
|
|
34
55
|
import { view } from '@bigmistqke/view.gl'
|
|
@@ -56,26 +77,74 @@ attributes.position.set(positionData)
|
|
|
56
77
|
attributes.position.bind()
|
|
57
78
|
```
|
|
58
79
|
|
|
59
|
-
###
|
|
80
|
+
### 👁️ view
|
|
60
81
|
|
|
61
|
-
|
|
82
|
+
The `view()` function creates type-safe WebGL resource managers from a schema.
|
|
62
83
|
|
|
63
84
|
```typescript
|
|
64
|
-
|
|
65
|
-
uniformView,
|
|
66
|
-
attributeView,
|
|
67
|
-
interleavedAttributeView,
|
|
68
|
-
bufferView,
|
|
69
|
-
} from '@bigmistqke/view.gl'
|
|
85
|
+
const { uniforms, attributes, buffers } = view(gl, program, schema)
|
|
70
86
|
```
|
|
71
87
|
|
|
72
|
-
|
|
88
|
+
**Parameters:**
|
|
73
89
|
|
|
74
|
-
|
|
90
|
+
- `gl`: WebGL rendering context
|
|
91
|
+
- `program`: Compiled WebGL program
|
|
92
|
+
- `schema`: Resource definitions object
|
|
93
|
+
|
|
94
|
+
**Returns:**
|
|
95
|
+
|
|
96
|
+
- `uniforms`: Type-safe uniform setters
|
|
97
|
+
- `attributes`: Attribute managers with buffer handling
|
|
98
|
+
- `buffers`: Generic buffer managers
|
|
99
|
+
|
|
100
|
+
**ViewSchema:**
|
|
101
|
+
The complete schema object that defines all WebGL resources. Contains optional mappings for uniforms, attributes, interleaved attributes, and buffers.
|
|
102
|
+
|
|
103
|
+
<details>
|
|
104
|
+
<summary>TypeScript Types</summary>
|
|
75
105
|
|
|
76
106
|
```typescript
|
|
77
|
-
|
|
107
|
+
interface ViewSchema {
|
|
108
|
+
uniforms?: Record<string | symbol, UniformOptions>
|
|
109
|
+
attributes?: Record<string | symbol, AttributeOptions>
|
|
110
|
+
interleavedAttributes?: Record<string | symbol, InterleavedAttributeOptions>
|
|
111
|
+
buffers?: Record<string | symbol, BufferOptions>
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
interface UniformOptions {
|
|
115
|
+
kind: UniformKind
|
|
116
|
+
size?: number // For array uniforms
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
interface AttributeOptions {
|
|
120
|
+
kind: AttributeKind
|
|
121
|
+
instanced?: boolean
|
|
122
|
+
buffer?: WebGLBuffer
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
interface InterleavedAttributeOptions {
|
|
126
|
+
layout: Array<{ key: string | symbol; kind: AttributeKind }>
|
|
127
|
+
instanced?: boolean
|
|
128
|
+
buffer?: WebGLBuffer
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
interface BufferOptions {
|
|
132
|
+
target: 'ARRAY_BUFFER' | 'ELEMENT_ARRAY_BUFFER'
|
|
133
|
+
usage?: 'STATIC_DRAW' | 'DYNAMIC_DRAW' | 'STREAM_DRAW'
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
</details>
|
|
138
|
+
|
|
139
|
+
### 👀 Resource Views
|
|
78
140
|
|
|
141
|
+
Each view type can be imported individually.
|
|
142
|
+
|
|
143
|
+
#### 🎯 uniformView
|
|
144
|
+
|
|
145
|
+
Manages shader uniform variables.
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
79
148
|
const uniforms = uniformView(gl, program, {
|
|
80
149
|
time: { kind: 'float' },
|
|
81
150
|
lights: { kind: 'vec3', size: 8 }, // Array uniform: vec3[8]
|
|
@@ -84,52 +153,118 @@ const uniforms = uniformView(gl, program, {
|
|
|
84
153
|
|
|
85
154
|
uniforms.time.set(performance.now())
|
|
86
155
|
uniforms.lights.set(lightData) // Takes Float32Array for array uniforms
|
|
87
|
-
uniforms.transform.set(transformMatrix)
|
|
88
156
|
```
|
|
89
157
|
|
|
90
|
-
**
|
|
158
|
+
**UniformSchema:**
|
|
159
|
+
A mapping of uniform names to their configuration. Each uniform has a GLSL type and optional array size.
|
|
91
160
|
|
|
92
|
-
|
|
93
|
-
|
|
161
|
+
```typescript
|
|
162
|
+
{
|
|
163
|
+
time: { kind: 'float' },
|
|
164
|
+
transform: { kind: 'mat4' },
|
|
165
|
+
lights: { kind: 'vec3', size: 8 }, // Array uniform
|
|
166
|
+
}
|
|
167
|
+
```
|
|
94
168
|
|
|
95
|
-
|
|
169
|
+
- `kind`: GLSL type (see [Uniform Types](#-uniform-types) for full list and WebGL compatibility)
|
|
170
|
+
- `size`: Array size (optional) - converts uniform to array type
|
|
96
171
|
|
|
97
|
-
|
|
172
|
+
<details>
|
|
173
|
+
<summary>TypeScript Types</summary>
|
|
98
174
|
|
|
99
175
|
```typescript
|
|
100
|
-
|
|
176
|
+
type UniformKind =
|
|
177
|
+
| 'float'
|
|
178
|
+
| 'int'
|
|
179
|
+
| 'bool'
|
|
180
|
+
| 'vec2'
|
|
181
|
+
| 'vec3'
|
|
182
|
+
| 'vec4'
|
|
183
|
+
| 'ivec2'
|
|
184
|
+
| 'ivec3'
|
|
185
|
+
| 'ivec4'
|
|
186
|
+
| 'bvec2'
|
|
187
|
+
| 'bvec3'
|
|
188
|
+
| 'bvec4'
|
|
189
|
+
| 'mat2'
|
|
190
|
+
| 'mat3'
|
|
191
|
+
| 'mat4'
|
|
192
|
+
| 'sampler2D'
|
|
193
|
+
| 'samplerCube'
|
|
194
|
+
|
|
195
|
+
interface UniformOptions {
|
|
196
|
+
kind: UniformKind
|
|
197
|
+
size?: number // Creates array uniform with Float32Array setter
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
type UniformSchema = Record<string | symbol, UniformOptions>
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
</details>
|
|
204
|
+
|
|
205
|
+
#### 📝 attributeView
|
|
206
|
+
|
|
207
|
+
Manages vertex attributes with automatic buffer creation and binding.
|
|
101
208
|
|
|
209
|
+
```typescript
|
|
102
210
|
const attributes = attributeView(gl, program, {
|
|
103
211
|
position: { kind: 'vec3' },
|
|
104
212
|
instanceOffset: { kind: 'vec2', instanced: true },
|
|
105
213
|
})
|
|
106
214
|
|
|
107
|
-
// Regular attribute for vertices
|
|
108
215
|
attributes.position.set(positionData).bind()
|
|
109
|
-
|
|
110
|
-
// Instanced attribute for per-instance data
|
|
111
216
|
attributes.instanceOffset.set(instanceData).bind()
|
|
112
217
|
|
|
113
|
-
// Draw regular geometry
|
|
114
|
-
gl.drawArrays(gl.TRIANGLES, 0, 3)
|
|
115
|
-
|
|
116
|
-
// Draw instanced geometry
|
|
117
218
|
gl.drawArraysInstanced(gl.TRIANGLES, 0, 3, 100)
|
|
118
219
|
```
|
|
119
220
|
|
|
120
|
-
**
|
|
221
|
+
**AttributeSchema:**
|
|
222
|
+
A mapping of attribute names to their configuration. Each attribute has a GLSL type, optional instancing, and optional custom buffer.
|
|
121
223
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
224
|
+
```typescript
|
|
225
|
+
{
|
|
226
|
+
position: { kind: 'vec3' },
|
|
227
|
+
instanceOffset: { kind: 'vec2', instanced: true },
|
|
228
|
+
}
|
|
229
|
+
```
|
|
125
230
|
|
|
126
|
-
|
|
231
|
+
- `kind`: GLSL type (see [Attribute Types](#-attribute-types) for full list and WebGL compatibility)
|
|
232
|
+
- `instanced`: Boolean - enables instanced rendering
|
|
233
|
+
- `buffer`: Custom WebGLBuffer (optional)
|
|
127
234
|
|
|
128
|
-
|
|
235
|
+
<details>
|
|
236
|
+
<summary>TypeScript Types</summary>
|
|
129
237
|
|
|
130
238
|
```typescript
|
|
131
|
-
|
|
239
|
+
type AttributeKind =
|
|
240
|
+
| 'float'
|
|
241
|
+
| 'vec2'
|
|
242
|
+
| 'vec3'
|
|
243
|
+
| 'vec4'
|
|
244
|
+
| 'mat2'
|
|
245
|
+
| 'mat3'
|
|
246
|
+
| 'mat4'
|
|
247
|
+
| 'int'
|
|
248
|
+
| 'ivec2'
|
|
249
|
+
| 'ivec3'
|
|
250
|
+
| 'ivec4'
|
|
251
|
+
|
|
252
|
+
interface AttributeOptions {
|
|
253
|
+
kind: AttributeKind
|
|
254
|
+
instanced?: boolean // Enables vertexAttribDivisor
|
|
255
|
+
buffer?: WebGLBuffer // Custom buffer, auto-created if not provided
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
type AttributeSchema = Record<string | symbol, AttributeOptions>
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
</details>
|
|
132
262
|
|
|
263
|
+
#### 🔗 interleavedAttributeView
|
|
264
|
+
|
|
265
|
+
Manages interleaved vertex data with automatic stride/offset calculation.
|
|
266
|
+
|
|
267
|
+
```typescript
|
|
133
268
|
const interleavedAttributes = interleavedAttributeView(gl, program, {
|
|
134
269
|
vertexData: {
|
|
135
270
|
layout: [
|
|
@@ -138,117 +273,98 @@ const interleavedAttributes = interleavedAttributeView(gl, program, {
|
|
|
138
273
|
{ key: 'uv', kind: 'vec2' },
|
|
139
274
|
],
|
|
140
275
|
},
|
|
141
|
-
instanceData: {
|
|
142
|
-
layout: [
|
|
143
|
-
{ key: 'instancePos', kind: 'vec2' },
|
|
144
|
-
{ key: 'instanceColor', kind: 'vec3' },
|
|
145
|
-
],
|
|
146
|
-
instanced: true,
|
|
147
|
-
},
|
|
148
276
|
})
|
|
149
277
|
|
|
150
|
-
|
|
151
|
-
interleavedAttributes.vertexData.set(interleavedVertexData)
|
|
152
|
-
interleavedAttributes.instanceData.set(interleavedInstanceData)
|
|
153
|
-
|
|
154
|
-
// Bind all attributes in layout
|
|
155
|
-
interleavedAttributes.vertexData.bind()
|
|
156
|
-
interleavedAttributes.instanceData.bind()
|
|
278
|
+
interleavedAttributes.vertexData.set(interleavedVertexData).bind()
|
|
157
279
|
```
|
|
158
280
|
|
|
159
|
-
**
|
|
160
|
-
|
|
161
|
-
- `layout`: Array of attribute definitions with `name` and `kind`
|
|
162
|
-
- `instanced`: Boolean - applies `vertexAttribDivisor` to all attributes in layout
|
|
163
|
-
|
|
164
|
-
#### bufferView
|
|
165
|
-
|
|
166
|
-
Manages generic WebGL buffers for various uses.
|
|
281
|
+
**InterleavedAttributeSchema:**
|
|
282
|
+
A mapping of interleaved buffer names to their layout configuration. Each layout defines multiple attributes packed into a single buffer.
|
|
167
283
|
|
|
168
284
|
```typescript
|
|
169
|
-
|
|
285
|
+
{
|
|
286
|
+
vertexData: {
|
|
287
|
+
layout: [
|
|
288
|
+
{ key: 'position', kind: 'vec3' },
|
|
289
|
+
{ key: 'normal', kind: 'vec3' },
|
|
290
|
+
{ key: 'uv', kind: 'vec2' },
|
|
291
|
+
],
|
|
292
|
+
},
|
|
293
|
+
}
|
|
294
|
+
```
|
|
170
295
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
data: { target: 'ARRAY_BUFFER', usage: 'DYNAMIC_DRAW' },
|
|
174
|
-
})
|
|
296
|
+
- `layout`: Array of attribute definitions with `key` and `kind` (see [Attribute Types](#-attribute-types) for WebGL compatibility)
|
|
297
|
+
- `instanced`: Boolean - applies to all attributes in layout
|
|
175
298
|
|
|
176
|
-
|
|
177
|
-
|
|
299
|
+
<details>
|
|
300
|
+
<summary>TypeScript Types</summary>
|
|
178
301
|
|
|
179
|
-
|
|
180
|
-
|
|
302
|
+
```typescript
|
|
303
|
+
interface InterleavedAttributeOptions {
|
|
304
|
+
layout: Array<{
|
|
305
|
+
key: string | symbol
|
|
306
|
+
kind: AttributeKind
|
|
307
|
+
}>
|
|
308
|
+
instanced?: boolean // Applies vertexAttribDivisor to all attributes
|
|
309
|
+
buffer?: WebGLBuffer // Custom buffer for interleaved data
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
type InterleavedAttributeSchema = Record<string | symbol, InterleavedAttributeOptions>
|
|
181
313
|
```
|
|
182
314
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
- `target`: Buffer target (`'ARRAY_BUFFER'`, `'ELEMENT_ARRAY_BUFFER'`)
|
|
186
|
-
- `usage`: Usage pattern (`'STATIC_DRAW'`, `'DYNAMIC_DRAW'`, `'STREAM_DRAW'`)
|
|
315
|
+
</details>
|
|
187
316
|
|
|
188
|
-
|
|
317
|
+
#### 🗂️ bufferView
|
|
189
318
|
|
|
190
|
-
|
|
319
|
+
Manages generic WebGL buffers.
|
|
191
320
|
|
|
192
321
|
```typescript
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
uv: { kind: 'vec2' },
|
|
197
|
-
},
|
|
322
|
+
const buffers = bufferView(gl, {
|
|
323
|
+
indices: { target: 'ELEMENT_ARRAY_BUFFER' },
|
|
324
|
+
data: { target: 'ARRAY_BUFFER', usage: 'DYNAMIC_DRAW' },
|
|
198
325
|
})
|
|
199
326
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
gl.drawArrays(gl.TRIANGLES, 0, vertexCount)
|
|
327
|
+
buffers.indices.set(indexData).bind()
|
|
328
|
+
buffers.data.set(dynamicData).bind()
|
|
204
329
|
```
|
|
205
330
|
|
|
206
|
-
|
|
331
|
+
**BufferSchema:**
|
|
332
|
+
A mapping of buffer names to their configuration. Each buffer has a target type and optional usage pattern.
|
|
207
333
|
|
|
208
334
|
```typescript
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
instanceColor: { kind: 'vec3', instanced: true },
|
|
214
|
-
},
|
|
215
|
-
})
|
|
216
|
-
|
|
217
|
-
attributes.position.set(triangleVertices).bind()
|
|
218
|
-
attributes.instanceOffset.set(instanceOffsets).bind()
|
|
219
|
-
attributes.instanceColor.set(instanceColors).bind()
|
|
220
|
-
|
|
221
|
-
gl.drawArraysInstanced(gl.TRIANGLES, 0, 3, instanceCount)
|
|
335
|
+
{
|
|
336
|
+
indices: { target: 'ELEMENT_ARRAY_BUFFER' },
|
|
337
|
+
data: { target: 'ARRAY_BUFFER', usage: 'DYNAMIC_DRAW' },
|
|
338
|
+
}
|
|
222
339
|
```
|
|
223
340
|
|
|
224
|
-
|
|
341
|
+
- `target`: Buffer target (`'ARRAY_BUFFER'`, `'ELEMENT_ARRAY_BUFFER'`)
|
|
342
|
+
- `usage`: Usage pattern (`'STATIC_DRAW'`, `'DYNAMIC_DRAW'`, `'STREAM_DRAW'`)
|
|
225
343
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
- **WebGL Extensions**: Automatic fallback for instanced arrays and vertex array objects
|
|
229
|
-
- **Memory Management**: AbortSignal support for scheduling cleanup of resources
|
|
344
|
+
<details>
|
|
345
|
+
<summary>TypeScript Types</summary>
|
|
230
346
|
|
|
231
|
-
|
|
347
|
+
```typescript
|
|
348
|
+
interface BufferOptions {
|
|
349
|
+
target: 'ARRAY_BUFFER' | 'ELEMENT_ARRAY_BUFFER'
|
|
350
|
+
usage?: 'STATIC_DRAW' | 'DYNAMIC_DRAW' | 'STREAM_DRAW' // Defaults to 'STATIC_DRAW'
|
|
351
|
+
}
|
|
232
352
|
|
|
233
|
-
|
|
353
|
+
type BufferSchema = Record<string | symbol, BufferOptions>
|
|
354
|
+
```
|
|
234
355
|
|
|
235
|
-
|
|
356
|
+
</details>
|
|
236
357
|
|
|
237
|
-
|
|
238
|
-
- **Type Safety**: Automatic schema generation from template literals
|
|
239
|
-
- **WebGL Version Support**: Automatic syntax conversion for WebGL1/2
|
|
240
|
-
- **Interleaved Attributes**: Multi-attribute layout support
|
|
241
|
-
- **Symbol Support**: Use JavaScript symbols as keys (see [View Features](#symbol-support))
|
|
358
|
+
## 🏷️ view.gl/tag
|
|
242
359
|
|
|
243
|
-
|
|
360
|
+
Type-safe GLSL template literals with automatic schema extraction.
|
|
244
361
|
|
|
245
|
-
-
|
|
246
|
-
-
|
|
247
|
-
-
|
|
248
|
-
-
|
|
249
|
-
- `compile(gl, vertex, fragment)`: Compile shaders and extract schema
|
|
362
|
+
- **Embedded Resources**: Define uniforms, attributes, and interleaved layouts directly in GLSL
|
|
363
|
+
- **Type Inference**: Automatically infers schema types and creates type-safe view
|
|
364
|
+
- **Scoped Variables**: Prevent naming collisions using symbols for private shader variables
|
|
365
|
+
- **GLSL Composition**: Compose reusable GLSL fragments with automatic dependency resolution
|
|
250
366
|
|
|
251
|
-
### Basic Usage
|
|
367
|
+
### 🚀 Basic Usage
|
|
252
368
|
|
|
253
369
|
```typescript
|
|
254
370
|
import { glsl, uniform, attribute, compile } from '@bigmistqke/view.gl/tag'
|
|
@@ -280,24 +396,233 @@ const fragmentShader = glsl`
|
|
|
280
396
|
const { program, schema } = compile(gl, vertexShader, fragmentShader)
|
|
281
397
|
```
|
|
282
398
|
|
|
283
|
-
###
|
|
399
|
+
### 📝 glsl
|
|
400
|
+
|
|
401
|
+
Template literal processor that handles GLSL code and embedded resources. Supports interpolation of:
|
|
284
402
|
|
|
285
|
-
|
|
403
|
+
- **[Resource tags](#️-resource-tags)**: `uniform.*()`, `attribute.*()`, `interleave()`
|
|
404
|
+
- **[Composed GLSL fragments](#-glsl-fragment)**: Reusable shader code snippets
|
|
405
|
+
- **[Symbols](#-symbol-scoping)**: Scoped variable names to prevent collisions
|
|
286
406
|
|
|
287
407
|
```typescript
|
|
288
|
-
|
|
289
|
-
|
|
408
|
+
import { glsl, uniform, attribute } from '@bigmistqke/view.gl/tag'
|
|
409
|
+
|
|
410
|
+
const shader = glsl`
|
|
411
|
+
${uniform.vec2('resolution')}
|
|
412
|
+
${attribute.vec3('position')}
|
|
413
|
+
|
|
414
|
+
void main() {
|
|
415
|
+
gl_Position = vec4(position, 1.0);
|
|
416
|
+
}
|
|
417
|
+
`
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
#### 🧩 GLSL Fragment
|
|
421
|
+
|
|
422
|
+
Compose reusable GLSL code fragments to build complex shaders:
|
|
423
|
+
|
|
424
|
+
```typescript
|
|
425
|
+
const lighting = glsl`
|
|
426
|
+
vec3 calculateLighting(vec3 normal, vec3 lightDir) {
|
|
427
|
+
float diff = max(dot(normal, lightDir), 0.0);
|
|
428
|
+
return vec3(diff);
|
|
429
|
+
}
|
|
430
|
+
`
|
|
431
|
+
|
|
432
|
+
const vertexShader = glsl`
|
|
433
|
+
${attribute.vec3('position')}
|
|
434
|
+
${attribute.vec3('normal')}
|
|
435
|
+
${lighting} // Include the lighting fragment
|
|
436
|
+
|
|
437
|
+
void main() {
|
|
438
|
+
vec3 light = calculateLighting(normal, vec3(0.0, 1.0, 0.0));
|
|
439
|
+
// Use the composed function
|
|
440
|
+
}
|
|
441
|
+
`
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
#### 🔒 Symbol Scoping
|
|
445
|
+
|
|
446
|
+
Use JavaScript symbols to prevent naming collisions:
|
|
447
|
+
|
|
448
|
+
```typescript
|
|
449
|
+
const sum = Symbol('sum')
|
|
450
|
+
|
|
451
|
+
const sumFragment = glsl`
|
|
452
|
+
float ${sum}(float a, float b){
|
|
453
|
+
return a + b;
|
|
454
|
+
}`
|
|
455
|
+
|
|
456
|
+
const shader = glsl`
|
|
457
|
+
${sumFragment}
|
|
458
|
+
|
|
459
|
+
void main(){
|
|
460
|
+
float result = ${sum}(1.0, 2.0);
|
|
461
|
+
}
|
|
462
|
+
`
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
Symbols are converted to unique identifiers in the shader.
|
|
466
|
+
|
|
467
|
+
#### WebGL Version Support
|
|
290
468
|
|
|
469
|
+
The glsl-function supports both WebGL1 and WebGL2 syntax, automatically using the correct keywords for resource tags:
|
|
470
|
+
|
|
471
|
+
```typescript
|
|
472
|
+
// WebGL1 (default)
|
|
291
473
|
const shader = glsl`
|
|
292
|
-
${attribute.vec3(
|
|
293
|
-
|
|
474
|
+
${attribute.vec3('position')} // → attribute vec3 position;
|
|
475
|
+
varying vec2 vUv;
|
|
476
|
+
`
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
If the shader starts with `#version 300 es`, resource tags generate WebGL2 syntax:
|
|
480
|
+
|
|
481
|
+
```typescript
|
|
482
|
+
// WebGL2
|
|
483
|
+
const shader = glsl`#version 300 es
|
|
484
|
+
${attribute.vec3('position')} // → in vec3 position;
|
|
485
|
+
out vec2 vUv;
|
|
486
|
+
`
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
### ⚙️ Resource Tags
|
|
490
|
+
|
|
491
|
+
Functions for defining WebGL resources directly in GLSL templates. These tags generate GLSL declarations and automatically extract type-safe schemas for use with the view system.
|
|
492
|
+
|
|
493
|
+
#### 🎯 uniform[kind](name, options?)
|
|
494
|
+
|
|
495
|
+
Define uniform variables in GLSL templates. Supports all GLSL uniform types (see [Uniform Types](#-uniform-types) for WebGL version compatibility).
|
|
496
|
+
|
|
497
|
+
```typescript
|
|
498
|
+
import { uniform, glsl } from '@bigmistqke/view.gl/tag'
|
|
499
|
+
|
|
500
|
+
const shader = glsl`
|
|
501
|
+
${uniform.float('time')}
|
|
502
|
+
${uniform.vec3('lights', { size: 8 })} // Array uniform: vec3[8]
|
|
503
|
+
|
|
504
|
+
void main() {
|
|
505
|
+
// Use uniforms in shader code
|
|
506
|
+
}
|
|
507
|
+
`
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
**Options**:
|
|
511
|
+
|
|
512
|
+
- `size`: Array size (creates array uniform with Float32Array setter)
|
|
513
|
+
|
|
514
|
+
#### 📝 attribute[kind](name, options?)
|
|
515
|
+
|
|
516
|
+
Define vertex attributes in GLSL templates (see [Attribute Types](#-attribute-types) for WebGL version compatibility).
|
|
517
|
+
|
|
518
|
+
**Regular rendering:**
|
|
519
|
+
|
|
520
|
+
```typescript
|
|
521
|
+
import { attribute, glsl } from '@bigmistqke/view.gl/tag'
|
|
522
|
+
|
|
523
|
+
const vertexShader = glsl`
|
|
524
|
+
${attribute.vec3('position')}
|
|
525
|
+
|
|
526
|
+
void main() {
|
|
527
|
+
gl_Position = vec4(position, 1.0);
|
|
528
|
+
}
|
|
529
|
+
`
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
**Instanced rendering:**
|
|
533
|
+
|
|
534
|
+
```typescript
|
|
535
|
+
const vertexShader = glsl`
|
|
536
|
+
${attribute.vec3('position')}
|
|
537
|
+
${attribute.vec2('offset', { instanced: true })}
|
|
538
|
+
|
|
539
|
+
void main() {
|
|
540
|
+
gl_Position = vec4(position + vec3(offset, 0.0), 1.0);
|
|
541
|
+
}
|
|
542
|
+
`
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
**Options**:
|
|
546
|
+
|
|
547
|
+
- `instanced`: Boolean - enables instanced rendering with `vertexAttribDivisor`
|
|
548
|
+
- `buffer`: Custom WebGLBuffer (optional)
|
|
549
|
+
|
|
550
|
+
#### 🔗 interleave(name, layout, options?)
|
|
551
|
+
|
|
552
|
+
Define interleaved attribute layouts for efficient vertex data.
|
|
553
|
+
|
|
554
|
+
```typescript
|
|
555
|
+
import { interleave, glsl } from '@bigmistqke/view.gl/tag'
|
|
556
|
+
|
|
557
|
+
const vertexShader = glsl`
|
|
558
|
+
${interleave('vertexData', [
|
|
559
|
+
{ key: 'position', kind: 'vec3' },
|
|
560
|
+
{ key: 'uv', kind: 'vec2' },
|
|
561
|
+
])}
|
|
294
562
|
|
|
295
563
|
void main() {
|
|
296
|
-
gl_Position = vec4(
|
|
564
|
+
gl_Position = vec4(position + vec3(uv, 0.0), 1.0);
|
|
297
565
|
}
|
|
298
566
|
`
|
|
299
567
|
```
|
|
300
568
|
|
|
569
|
+
**Layout format**:
|
|
570
|
+
|
|
571
|
+
- `key`: Attribute name
|
|
572
|
+
- `kind`: GLSL type (see [Attribute Types](#-attribute-types) for WebGL compatibility)
|
|
573
|
+
|
|
574
|
+
**Options**:
|
|
575
|
+
|
|
576
|
+
- `instanced`: Boolean - applies `vertexAttribDivisor` to all attributes
|
|
577
|
+
|
|
578
|
+
### ⚙️ compile(gl, vertex, fragment, overrideSchema?)
|
|
579
|
+
|
|
580
|
+
Compiles shaders and extracts schema from embedded resources. Returns both the compiled program and a ready-to-use view.
|
|
581
|
+
|
|
582
|
+
```typescript
|
|
583
|
+
import { compile } from '@bigmistqke/view.gl/tag'
|
|
584
|
+
|
|
585
|
+
const { program, schema, view } = compile(gl, vertexShader, fragmentShader)
|
|
586
|
+
|
|
587
|
+
// Use the view directly
|
|
588
|
+
view.uniforms.time.set(performance.now())
|
|
589
|
+
view.attributes.position.set(vertexData).bind()
|
|
590
|
+
|
|
591
|
+
// Or access the extracted schema
|
|
592
|
+
console.log(schema.uniforms) // { time: { kind: 'float' }, ... }
|
|
593
|
+
console.log(schema.attributes) // { position: { kind: 'vec3' }, ... }
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
**Override Schema:**
|
|
597
|
+
|
|
598
|
+
You can provide an optional override schema to enhance or override the automatically extracted schema:
|
|
599
|
+
|
|
600
|
+
```typescript
|
|
601
|
+
const { program, schema, view } = compile(gl, vertexShader, fragmentShader, {
|
|
602
|
+
uniforms: {
|
|
603
|
+
// Add additional uniforms not automatically inferred
|
|
604
|
+
customTime: { kind: 'float' },
|
|
605
|
+
},
|
|
606
|
+
buffers: {
|
|
607
|
+
// Add buffer definitions
|
|
608
|
+
indices: { target: 'ELEMENT_ARRAY_BUFFER' },
|
|
609
|
+
},
|
|
610
|
+
})
|
|
611
|
+
|
|
612
|
+
// The override schema is merged with the extracted schema
|
|
613
|
+
view.uniforms.customTime.set(123.45)
|
|
614
|
+
view.buffers.indices.set(indexData).bind()
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
**Returns**:
|
|
618
|
+
|
|
619
|
+
- `program`: Compiled WebGL program
|
|
620
|
+
- `schema`: Merged schema (extracted + override)
|
|
621
|
+
- `view`: Ready-to-use view with type-safe resource access
|
|
622
|
+
|
|
623
|
+
<details>
|
|
624
|
+
<summary>Usage with vanilla view.gl</summary>
|
|
625
|
+
|
|
301
626
|
When manually constructing GLSL strings, use `toID()` to convert symbols to valid identifiers:
|
|
302
627
|
|
|
303
628
|
```typescript
|
|
@@ -335,11 +660,11 @@ attributes[a_position].set(vertexData)
|
|
|
335
660
|
uniforms[u_time].set(performance.now())
|
|
336
661
|
```
|
|
337
662
|
|
|
338
|
-
|
|
663
|
+
</details>
|
|
339
664
|
|
|
340
|
-
|
|
665
|
+
## 🛠️ Utils
|
|
341
666
|
|
|
342
|
-
### createProgram
|
|
667
|
+
### 🏗️ createProgram
|
|
343
668
|
|
|
344
669
|
Creates and links a WebGL program from vertex and fragment shader sources.
|
|
345
670
|
|
|
@@ -349,7 +674,7 @@ import { createProgram } from '@bigmistqke/view.gl/utils'
|
|
|
349
674
|
const program = createProgram(gl, vertexShaderSource, fragmentShaderSource)
|
|
350
675
|
```
|
|
351
676
|
|
|
352
|
-
### createTexture
|
|
677
|
+
### 🖼️ createTexture
|
|
353
678
|
|
|
354
679
|
Creates a WebGL texture with specified parameters.
|
|
355
680
|
|
|
@@ -375,7 +700,7 @@ const texture = createTexture(
|
|
|
375
700
|
|
|
376
701
|
Automatically validates WebGL2-only formats and provides fallbacks for WebGL1.
|
|
377
702
|
|
|
378
|
-
### createFramebuffer
|
|
703
|
+
### 🖥️ createFramebuffer
|
|
379
704
|
|
|
380
705
|
Creates a framebuffer with attached texture for render-to-texture operations.
|
|
381
706
|
|
|
@@ -393,3 +718,76 @@ const { framebuffer, texture } = createFramebuffer(gl, {
|
|
|
393
718
|
```
|
|
394
719
|
|
|
395
720
|
Supports color, depth, stencil, and combined depth-stencil attachments with completeness validation.
|
|
721
|
+
|
|
722
|
+
## 🔍 WebGL Type Compatibility
|
|
723
|
+
|
|
724
|
+
### 🎯 Uniform Types
|
|
725
|
+
|
|
726
|
+
| Type | WebGL 1 | WebGL 2 |
|
|
727
|
+
| ---------------------- | ------- | ------- |
|
|
728
|
+
| `float` | ✅ | ✅ |
|
|
729
|
+
| `int` | ✅ | ✅ |
|
|
730
|
+
| `bool` | ✅ | ✅ |
|
|
731
|
+
| `vec2` | ✅ | ✅ |
|
|
732
|
+
| `vec3` | ✅ | ✅ |
|
|
733
|
+
| `vec4` | ✅ | ✅ |
|
|
734
|
+
| `ivec2` | ✅ | ✅ |
|
|
735
|
+
| `ivec3` | ✅ | ✅ |
|
|
736
|
+
| `ivec4` | ✅ | ✅ |
|
|
737
|
+
| `bvec2` | ✅ | ✅ |
|
|
738
|
+
| `bvec3` | ✅ | ✅ |
|
|
739
|
+
| `bvec4` | ✅ | ✅ |
|
|
740
|
+
| `mat2` | ✅ | ✅ |
|
|
741
|
+
| `mat3` | ✅ | ✅ |
|
|
742
|
+
| `mat4` | ✅ | ✅ |
|
|
743
|
+
| `sampler2D` | ✅ | ✅ |
|
|
744
|
+
| `samplerCube` | ✅ | ✅ |
|
|
745
|
+
| `uint` | ❌ | ✅ |
|
|
746
|
+
| `uvec2` | ❌ | ✅ |
|
|
747
|
+
| `uvec3` | ❌ | ✅ |
|
|
748
|
+
| `uvec4` | ❌ | ✅ |
|
|
749
|
+
| `mat2x3` | ❌ | ✅ |
|
|
750
|
+
| `mat2x4` | ❌ | ✅ |
|
|
751
|
+
| `mat3x2` | ❌ | ✅ |
|
|
752
|
+
| `mat3x4` | ❌ | ✅ |
|
|
753
|
+
| `mat4x2` | ❌ | ✅ |
|
|
754
|
+
| `mat4x3` | ❌ | ✅ |
|
|
755
|
+
| `sampler3D` | ❌ | ✅ |
|
|
756
|
+
| `sampler2DArray` | ❌ | ✅ |
|
|
757
|
+
| `sampler2DShadow` | ❌ | ✅ |
|
|
758
|
+
| `samplerCubeShadow` | ❌ | ✅ |
|
|
759
|
+
| `sampler2DArrayShadow` | ❌ | ✅ |
|
|
760
|
+
| `isampler2D` | ❌ | ✅ |
|
|
761
|
+
| `isampler3D` | ❌ | ✅ |
|
|
762
|
+
| `isamplerCube` | ❌ | ✅ |
|
|
763
|
+
| `isampler2DArray` | ❌ | ✅ |
|
|
764
|
+
| `usampler2D` | ❌ | ✅ |
|
|
765
|
+
| `usampler3D` | ❌ | ✅ |
|
|
766
|
+
| `usamplerCube` | ❌ | ✅ |
|
|
767
|
+
| `usampler2DArray` | ❌ | ✅ |
|
|
768
|
+
|
|
769
|
+
### 📝 Attribute Types
|
|
770
|
+
|
|
771
|
+
| Type | WebGL 1 | WebGL 2 |
|
|
772
|
+
| -------- | ------- | ------- |
|
|
773
|
+
| `float` | ✅ | ✅ |
|
|
774
|
+
| `vec2` | ✅ | ✅ |
|
|
775
|
+
| `vec3` | ✅ | ✅ |
|
|
776
|
+
| `vec4` | ✅ | ✅ |
|
|
777
|
+
| `mat2` | ✅ | ✅ |
|
|
778
|
+
| `mat3` | ✅ | ✅ |
|
|
779
|
+
| `mat4` | ✅ | ✅ |
|
|
780
|
+
| `int` | ❌ | ✅ |
|
|
781
|
+
| `ivec2` | ❌ | ✅ |
|
|
782
|
+
| `ivec3` | ❌ | ✅ |
|
|
783
|
+
| `ivec4` | ❌ | ✅ |
|
|
784
|
+
| `uint` | ❌ | ✅ |
|
|
785
|
+
| `uvec2` | ❌ | ✅ |
|
|
786
|
+
| `uvec3` | ❌ | ✅ |
|
|
787
|
+
| `uvec4` | ❌ | ✅ |
|
|
788
|
+
| `mat2x3` | ❌ | ✅ |
|
|
789
|
+
| `mat2x4` | ❌ | ✅ |
|
|
790
|
+
| `mat3x2` | ❌ | ✅ |
|
|
791
|
+
| `mat3x4` | ❌ | ✅ |
|
|
792
|
+
| `mat4x2` | ❌ | ✅ |
|
|
793
|
+
| `mat4x3` | ❌ | ✅ |
|