@bigmistqke/view.gl 0.1.3 → 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 +430 -177
- 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
|
@@ -10,50 +10,44 @@
|
|
|
10
10
|
- [📦 Install](#-install)
|
|
11
11
|
- [👁️ view.gl](#️-viewgl)
|
|
12
12
|
- [🚀 Basic Usage](#-basic-usage)
|
|
13
|
-
- [
|
|
13
|
+
- [👁️ view](#️-view)
|
|
14
|
+
- [👀 Resource Views](#-resource-views)
|
|
14
15
|
- [🎯 uniformView](#-uniformview)
|
|
15
16
|
- [📝 attributeView](#-attributeview)
|
|
16
17
|
- [🔗 interleavedAttributeView](#-interleavedattributeview)
|
|
17
18
|
- [🗂️ bufferView](#-bufferview)
|
|
18
|
-
- [🎨 Drawing Examples](#-drawing-examples)
|
|
19
|
-
- [🖼️ Regular Drawing](#-regular-drawing)
|
|
20
|
-
- [📱 Instanced Drawing](#-instanced-drawing)
|
|
21
19
|
- [🏷️ view.gl/tag](#️-viewgltag)
|
|
22
20
|
- [🚀 Basic Usage](#-basic-usage-1)
|
|
23
|
-
- [📝
|
|
24
|
-
|
|
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)
|
|
25
26
|
- [🎯 uniform[kind](name, options?)](#-uniformkindname-options)
|
|
26
27
|
- [📝 attribute[kind](name, options?)](#-attributekindname-options)
|
|
27
28
|
- [🔗 interleave(name, layout, options?)](#-interleavename-layout-options)
|
|
28
|
-
|
|
29
|
-
- [⚙️ compile(gl, vertex, fragment)](#️-compilegl-vertex-fragment)
|
|
30
|
-
- [🔣 Symbol Support](#-symbol-support)
|
|
29
|
+
- [⚙️ compile(gl, vertex, fragment)](#️-compilegl-vertex-fragment)
|
|
31
30
|
- [🛠️ Utils](#️-utils)
|
|
32
31
|
- [🏗️ createProgram](#️-createprogram)
|
|
33
32
|
- [🖼️ createTexture](#️-createtexture)
|
|
34
33
|
- [🖥️ createFramebuffer](#️-createframebuffer)
|
|
34
|
+
- [🔍 WebGL Type Compatibility](#-webgl-type-compatibility)
|
|
35
|
+
- [🎯 Uniform Types](#-uniform-types)
|
|
36
|
+
- [📝 Attribute Types](#-attribute-types)
|
|
35
37
|
|
|
36
38
|
## 📦 Install
|
|
37
39
|
|
|
38
40
|
```shell
|
|
39
41
|
npm install @bigmistqke/view.gl
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
```shell
|
|
42
|
+
# or
|
|
43
43
|
pnpm add @bigmistqke/view.gl
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
```shell
|
|
44
|
+
# or
|
|
47
45
|
yarn add @bigmistqke/view.gl
|
|
48
46
|
```
|
|
49
47
|
|
|
50
|
-
```shell
|
|
51
|
-
bun add @bigmistqke/view.gl
|
|
52
|
-
```
|
|
53
|
-
|
|
54
48
|
## 👁️ view.gl
|
|
55
49
|
|
|
56
|
-
The view system provides type-safe WebGL resource management for uniforms, attributes, and buffers
|
|
50
|
+
The view system provides type-safe WebGL resource management for uniforms, attributes, and buffers
|
|
57
51
|
|
|
58
52
|
### 🚀 Basic Usage
|
|
59
53
|
|
|
@@ -83,26 +77,74 @@ attributes.position.set(positionData)
|
|
|
83
77
|
attributes.position.bind()
|
|
84
78
|
```
|
|
85
79
|
|
|
86
|
-
###
|
|
80
|
+
### 👁️ view
|
|
81
|
+
|
|
82
|
+
The `view()` function creates type-safe WebGL resource managers from a schema.
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
const { uniforms, attributes, buffers } = view(gl, program, schema)
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Parameters:**
|
|
89
|
+
|
|
90
|
+
- `gl`: WebGL rendering context
|
|
91
|
+
- `program`: Compiled WebGL program
|
|
92
|
+
- `schema`: Resource definitions object
|
|
93
|
+
|
|
94
|
+
**Returns:**
|
|
87
95
|
|
|
88
|
-
|
|
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>
|
|
89
105
|
|
|
90
106
|
```typescript
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}
|
|
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
|
+
}
|
|
97
135
|
```
|
|
98
136
|
|
|
137
|
+
</details>
|
|
138
|
+
|
|
139
|
+
### 👀 Resource Views
|
|
140
|
+
|
|
141
|
+
Each view type can be imported individually.
|
|
142
|
+
|
|
99
143
|
#### 🎯 uniformView
|
|
100
144
|
|
|
101
145
|
Manages shader uniform variables.
|
|
102
146
|
|
|
103
147
|
```typescript
|
|
104
|
-
import { uniformView } from '@bigmistqke/view.gl'
|
|
105
|
-
|
|
106
148
|
const uniforms = uniformView(gl, program, {
|
|
107
149
|
time: { kind: 'float' },
|
|
108
150
|
lights: { kind: 'vec3', size: 8 }, // Array uniform: vec3[8]
|
|
@@ -111,52 +153,118 @@ const uniforms = uniformView(gl, program, {
|
|
|
111
153
|
|
|
112
154
|
uniforms.time.set(performance.now())
|
|
113
155
|
uniforms.lights.set(lightData) // Takes Float32Array for array uniforms
|
|
114
|
-
uniforms.transform.set(transformMatrix)
|
|
115
156
|
```
|
|
116
157
|
|
|
117
|
-
**
|
|
158
|
+
**UniformSchema:**
|
|
159
|
+
A mapping of uniform names to their configuration. Each uniform has a GLSL type and optional array size.
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
{
|
|
163
|
+
time: { kind: 'float' },
|
|
164
|
+
transform: { kind: 'mat4' },
|
|
165
|
+
lights: { kind: 'vec3', size: 8 }, // Array uniform
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
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
|
|
118
171
|
|
|
119
|
-
|
|
120
|
-
|
|
172
|
+
<details>
|
|
173
|
+
<summary>TypeScript Types</summary>
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
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>
|
|
121
204
|
|
|
122
205
|
#### 📝 attributeView
|
|
123
206
|
|
|
124
|
-
Manages vertex attributes with buffer creation
|
|
207
|
+
Manages vertex attributes with automatic buffer creation and binding.
|
|
125
208
|
|
|
126
209
|
```typescript
|
|
127
|
-
import { attributeView } from '@bigmistqke/view.gl'
|
|
128
|
-
|
|
129
210
|
const attributes = attributeView(gl, program, {
|
|
130
211
|
position: { kind: 'vec3' },
|
|
131
212
|
instanceOffset: { kind: 'vec2', instanced: true },
|
|
132
213
|
})
|
|
133
214
|
|
|
134
|
-
// Regular attribute for vertices
|
|
135
215
|
attributes.position.set(positionData).bind()
|
|
136
|
-
|
|
137
|
-
// Instanced attribute for per-instance data
|
|
138
216
|
attributes.instanceOffset.set(instanceData).bind()
|
|
139
217
|
|
|
140
|
-
// Draw regular geometry
|
|
141
|
-
gl.drawArrays(gl.TRIANGLES, 0, 3)
|
|
142
|
-
|
|
143
|
-
// Draw instanced geometry
|
|
144
218
|
gl.drawArraysInstanced(gl.TRIANGLES, 0, 3, 100)
|
|
145
219
|
```
|
|
146
220
|
|
|
147
|
-
**
|
|
221
|
+
**AttributeSchema:**
|
|
222
|
+
A mapping of attribute names to their configuration. Each attribute has a GLSL type, optional instancing, and optional custom buffer.
|
|
148
223
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
224
|
+
```typescript
|
|
225
|
+
{
|
|
226
|
+
position: { kind: 'vec3' },
|
|
227
|
+
instanceOffset: { kind: 'vec2', instanced: true },
|
|
228
|
+
}
|
|
229
|
+
```
|
|
152
230
|
|
|
153
|
-
|
|
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)
|
|
154
234
|
|
|
155
|
-
|
|
235
|
+
<details>
|
|
236
|
+
<summary>TypeScript Types</summary>
|
|
156
237
|
|
|
157
238
|
```typescript
|
|
158
|
-
|
|
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
|
+
```
|
|
159
260
|
|
|
261
|
+
</details>
|
|
262
|
+
|
|
263
|
+
#### 🔗 interleavedAttributeView
|
|
264
|
+
|
|
265
|
+
Manages interleaved vertex data with automatic stride/offset calculation.
|
|
266
|
+
|
|
267
|
+
```typescript
|
|
160
268
|
const interleavedAttributes = interleavedAttributeView(gl, program, {
|
|
161
269
|
vertexData: {
|
|
162
270
|
layout: [
|
|
@@ -165,92 +273,96 @@ const interleavedAttributes = interleavedAttributeView(gl, program, {
|
|
|
165
273
|
{ key: 'uv', kind: 'vec2' },
|
|
166
274
|
],
|
|
167
275
|
},
|
|
168
|
-
|
|
276
|
+
})
|
|
277
|
+
|
|
278
|
+
interleavedAttributes.vertexData.set(interleavedVertexData).bind()
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
**InterleavedAttributeSchema:**
|
|
282
|
+
A mapping of interleaved buffer names to their layout configuration. Each layout defines multiple attributes packed into a single buffer.
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
{
|
|
286
|
+
vertexData: {
|
|
169
287
|
layout: [
|
|
170
|
-
{ key: '
|
|
171
|
-
{ key: '
|
|
288
|
+
{ key: 'position', kind: 'vec3' },
|
|
289
|
+
{ key: 'normal', kind: 'vec3' },
|
|
290
|
+
{ key: 'uv', kind: 'vec2' },
|
|
172
291
|
],
|
|
173
|
-
instanced: true,
|
|
174
292
|
},
|
|
175
|
-
}
|
|
293
|
+
}
|
|
294
|
+
```
|
|
176
295
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
interleavedAttributes.instanceData.set(interleavedInstanceData)
|
|
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
|
|
180
298
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
interleavedAttributes.instanceData.bind()
|
|
184
|
-
```
|
|
299
|
+
<details>
|
|
300
|
+
<summary>TypeScript Types</summary>
|
|
185
301
|
|
|
186
|
-
|
|
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>
|
|
313
|
+
```
|
|
187
314
|
|
|
188
|
-
|
|
189
|
-
- `instanced`: Boolean - applies `vertexAttribDivisor` to all attributes in layout
|
|
315
|
+
</details>
|
|
190
316
|
|
|
191
317
|
#### 🗂️ bufferView
|
|
192
318
|
|
|
193
|
-
Manages generic WebGL buffers
|
|
319
|
+
Manages generic WebGL buffers.
|
|
194
320
|
|
|
195
321
|
```typescript
|
|
196
|
-
import { bufferView } from '@bigmistqke/view.gl'
|
|
197
|
-
|
|
198
322
|
const buffers = bufferView(gl, {
|
|
199
323
|
indices: { target: 'ELEMENT_ARRAY_BUFFER' },
|
|
200
324
|
data: { target: 'ARRAY_BUFFER', usage: 'DYNAMIC_DRAW' },
|
|
201
325
|
})
|
|
202
326
|
|
|
203
|
-
buffers.indices.set(indexData)
|
|
204
|
-
buffers.
|
|
205
|
-
|
|
206
|
-
buffers.data.set(dynamicData)
|
|
207
|
-
buffers.data.bind()
|
|
327
|
+
buffers.indices.set(indexData).bind()
|
|
328
|
+
buffers.data.set(dynamicData).bind()
|
|
208
329
|
```
|
|
209
330
|
|
|
210
|
-
**
|
|
331
|
+
**BufferSchema:**
|
|
332
|
+
A mapping of buffer names to their configuration. Each buffer has a target type and optional usage pattern.
|
|
333
|
+
|
|
334
|
+
```typescript
|
|
335
|
+
{
|
|
336
|
+
indices: { target: 'ELEMENT_ARRAY_BUFFER' },
|
|
337
|
+
data: { target: 'ARRAY_BUFFER', usage: 'DYNAMIC_DRAW' },
|
|
338
|
+
}
|
|
339
|
+
```
|
|
211
340
|
|
|
212
341
|
- `target`: Buffer target (`'ARRAY_BUFFER'`, `'ELEMENT_ARRAY_BUFFER'`)
|
|
213
342
|
- `usage`: Usage pattern (`'STATIC_DRAW'`, `'DYNAMIC_DRAW'`, `'STREAM_DRAW'`)
|
|
214
343
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
#### 🖼️ Regular Drawing
|
|
344
|
+
<details>
|
|
345
|
+
<summary>TypeScript Types</summary>
|
|
218
346
|
|
|
219
347
|
```typescript
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
},
|
|
225
|
-
})
|
|
226
|
-
|
|
227
|
-
attributes.position.set(vertices).bind()
|
|
228
|
-
attributes.uv.set(uvData).bind()
|
|
348
|
+
interface BufferOptions {
|
|
349
|
+
target: 'ARRAY_BUFFER' | 'ELEMENT_ARRAY_BUFFER'
|
|
350
|
+
usage?: 'STATIC_DRAW' | 'DYNAMIC_DRAW' | 'STREAM_DRAW' // Defaults to 'STATIC_DRAW'
|
|
351
|
+
}
|
|
229
352
|
|
|
230
|
-
|
|
353
|
+
type BufferSchema = Record<string | symbol, BufferOptions>
|
|
231
354
|
```
|
|
232
355
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
```typescript
|
|
236
|
-
const { attributes } = view(gl, program, {
|
|
237
|
-
attributes: {
|
|
238
|
-
position: { kind: 'vec3' },
|
|
239
|
-
instanceOffset: { kind: 'vec2', instanced: true },
|
|
240
|
-
instanceColor: { kind: 'vec3', instanced: true },
|
|
241
|
-
},
|
|
242
|
-
})
|
|
243
|
-
|
|
244
|
-
attributes.position.set(triangleVertices).bind()
|
|
245
|
-
attributes.instanceOffset.set(instanceOffsets).bind()
|
|
246
|
-
attributes.instanceColor.set(instanceColors).bind()
|
|
247
|
-
|
|
248
|
-
gl.drawArraysInstanced(gl.TRIANGLES, 0, 3, instanceCount)
|
|
249
|
-
```
|
|
356
|
+
</details>
|
|
250
357
|
|
|
251
358
|
## 🏷️ view.gl/tag
|
|
252
359
|
|
|
253
|
-
|
|
360
|
+
Type-safe GLSL template literals with automatic schema extraction.
|
|
361
|
+
|
|
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
|
|
254
366
|
|
|
255
367
|
### 🚀 Basic Usage
|
|
256
368
|
|
|
@@ -284,28 +396,109 @@ const fragmentShader = glsl`
|
|
|
284
396
|
const { program, schema } = compile(gl, vertexShader, fragmentShader)
|
|
285
397
|
```
|
|
286
398
|
|
|
287
|
-
### 📝
|
|
399
|
+
### 📝 glsl
|
|
400
|
+
|
|
401
|
+
Template literal processor that handles GLSL code and embedded resources. Supports interpolation of:
|
|
402
|
+
|
|
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
|
|
406
|
+
|
|
407
|
+
```typescript
|
|
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
|
|
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)
|
|
473
|
+
const shader = glsl`
|
|
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:
|
|
288
480
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
481
|
+
```typescript
|
|
482
|
+
// WebGL2
|
|
483
|
+
const shader = glsl`#version 300 es
|
|
484
|
+
${attribute.vec3('position')} // → in vec3 position;
|
|
485
|
+
out vec2 vUv;
|
|
486
|
+
`
|
|
487
|
+
```
|
|
294
488
|
|
|
295
|
-
### ⚙️
|
|
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.
|
|
296
492
|
|
|
297
493
|
#### 🎯 uniform[kind](name, options?)
|
|
298
494
|
|
|
299
|
-
Define uniform variables in GLSL templates. Supports all GLSL uniform types.
|
|
495
|
+
Define uniform variables in GLSL templates. Supports all GLSL uniform types (see [Uniform Types](#-uniform-types) for WebGL version compatibility).
|
|
300
496
|
|
|
301
497
|
```typescript
|
|
302
498
|
import { uniform, glsl } from '@bigmistqke/view.gl/tag'
|
|
303
499
|
|
|
304
500
|
const shader = glsl`
|
|
305
501
|
${uniform.float('time')}
|
|
306
|
-
${uniform.vec2('resolution')}
|
|
307
|
-
${uniform.mat4('projection')}
|
|
308
|
-
${uniform.sampler2D('texture')}
|
|
309
502
|
${uniform.vec3('lights', { size: 8 })} // Array uniform: vec3[8]
|
|
310
503
|
|
|
311
504
|
void main() {
|
|
@@ -314,32 +507,40 @@ const shader = glsl`
|
|
|
314
507
|
`
|
|
315
508
|
```
|
|
316
509
|
|
|
317
|
-
**Available types**: `float`, `int`, `bool`, `vec2`, `vec3`, `vec4`, `ivec2`, `ivec3`, `ivec4`, `bvec2`, `bvec3`, `bvec4`, `mat2`, `mat3`, `mat4`, `sampler2D`, `samplerCube`
|
|
318
|
-
|
|
319
510
|
**Options**:
|
|
320
511
|
|
|
321
512
|
- `size`: Array size (creates array uniform with Float32Array setter)
|
|
322
513
|
|
|
323
514
|
#### 📝 attribute[kind](name, options?)
|
|
324
515
|
|
|
325
|
-
Define vertex attributes in GLSL templates.
|
|
516
|
+
Define vertex attributes in GLSL templates (see [Attribute Types](#-attribute-types) for WebGL version compatibility).
|
|
517
|
+
|
|
518
|
+
**Regular rendering:**
|
|
326
519
|
|
|
327
520
|
```typescript
|
|
328
521
|
import { attribute, glsl } from '@bigmistqke/view.gl/tag'
|
|
329
522
|
|
|
330
523
|
const vertexShader = glsl`
|
|
331
524
|
${attribute.vec3('position')}
|
|
332
|
-
${attribute.vec2('uv')}
|
|
333
|
-
${attribute.vec3('normal')}
|
|
334
|
-
${attribute.vec2('instanceOffset', { instanced: true })}
|
|
335
525
|
|
|
336
526
|
void main() {
|
|
337
|
-
gl_Position = vec4(position
|
|
527
|
+
gl_Position = vec4(position, 1.0);
|
|
338
528
|
}
|
|
339
529
|
`
|
|
340
530
|
```
|
|
341
531
|
|
|
342
|
-
**
|
|
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
|
+
```
|
|
343
544
|
|
|
344
545
|
**Options**:
|
|
345
546
|
|
|
@@ -356,21 +557,11 @@ import { interleave, glsl } from '@bigmistqke/view.gl/tag'
|
|
|
356
557
|
const vertexShader = glsl`
|
|
357
558
|
${interleave('vertexData', [
|
|
358
559
|
{ key: 'position', kind: 'vec3' },
|
|
359
|
-
{ key: 'normal', kind: 'vec3' },
|
|
360
560
|
{ key: 'uv', kind: 'vec2' },
|
|
361
561
|
])}
|
|
362
562
|
|
|
363
|
-
${interleave(
|
|
364
|
-
'instanceData',
|
|
365
|
-
[
|
|
366
|
-
{ key: 'instancePos', kind: 'vec2' },
|
|
367
|
-
{ key: 'instanceColor', kind: 'vec3' },
|
|
368
|
-
],
|
|
369
|
-
{ instanced: true },
|
|
370
|
-
)}
|
|
371
|
-
|
|
372
563
|
void main() {
|
|
373
|
-
gl_Position = vec4(position + vec3(
|
|
564
|
+
gl_Position = vec4(position + vec3(uv, 0.0), 1.0);
|
|
374
565
|
}
|
|
375
566
|
`
|
|
376
567
|
```
|
|
@@ -378,68 +569,57 @@ const vertexShader = glsl`
|
|
|
378
569
|
**Layout format**:
|
|
379
570
|
|
|
380
571
|
- `key`: Attribute name
|
|
381
|
-
- `kind`: GLSL type
|
|
572
|
+
- `kind`: GLSL type (see [Attribute Types](#-attribute-types) for WebGL compatibility)
|
|
382
573
|
|
|
383
574
|
**Options**:
|
|
384
575
|
|
|
385
576
|
- `instanced`: Boolean - applies `vertexAttribDivisor` to all attributes
|
|
386
577
|
|
|
387
|
-
|
|
578
|
+
### ⚙️ compile(gl, vertex, fragment, overrideSchema?)
|
|
388
579
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
```typescript
|
|
392
|
-
import { glsl } from '@bigmistqke/view.gl/tag'
|
|
393
|
-
|
|
394
|
-
const shader = glsl`
|
|
395
|
-
precision mediump float;
|
|
396
|
-
|
|
397
|
-
${uniform.vec2('resolution')}
|
|
398
|
-
|
|
399
|
-
void main() {
|
|
400
|
-
vec2 uv = gl_FragCoord.xy / resolution;
|
|
401
|
-
gl_FragColor = vec4(uv, 0.0, 1.0);
|
|
402
|
-
}
|
|
403
|
-
`
|
|
404
|
-
```
|
|
405
|
-
|
|
406
|
-
#### ⚙️ compile(gl, vertex, fragment)
|
|
407
|
-
|
|
408
|
-
Compiles shaders and extracts schema from embedded resources.
|
|
580
|
+
Compiles shaders and extracts schema from embedded resources. Returns both the compiled program and a ready-to-use view.
|
|
409
581
|
|
|
410
582
|
```typescript
|
|
411
583
|
import { compile } from '@bigmistqke/view.gl/tag'
|
|
412
584
|
|
|
413
|
-
const { program, schema } = compile(gl, vertexShader, fragmentShader)
|
|
585
|
+
const { program, schema, view } = compile(gl, vertexShader, fragmentShader)
|
|
414
586
|
|
|
415
|
-
//
|
|
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
|
|
416
592
|
console.log(schema.uniforms) // { time: { kind: 'float' }, ... }
|
|
417
593
|
console.log(schema.attributes) // { position: { kind: 'vec3' }, ... }
|
|
418
594
|
```
|
|
419
595
|
|
|
420
|
-
**
|
|
421
|
-
|
|
422
|
-
- `program`: Compiled WebGL program
|
|
423
|
-
- `schema`: Extracted resource definitions for use with `view()`
|
|
424
|
-
|
|
425
|
-
### 🔣 Symbol Support
|
|
596
|
+
**Override Schema:**
|
|
426
597
|
|
|
427
|
-
|
|
598
|
+
You can provide an optional override schema to enhance or override the automatically extracted schema:
|
|
428
599
|
|
|
429
600
|
```typescript
|
|
430
|
-
const
|
|
431
|
-
|
|
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
|
+
})
|
|
432
611
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
void main() {
|
|
438
|
-
gl_Position = vec4(${a_position}, ${u_time});
|
|
439
|
-
}
|
|
440
|
-
`
|
|
612
|
+
// The override schema is merged with the extracted schema
|
|
613
|
+
view.uniforms.customTime.set(123.45)
|
|
614
|
+
view.buffers.indices.set(indexData).bind()
|
|
441
615
|
```
|
|
442
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
|
+
|
|
443
623
|
<details>
|
|
444
624
|
<summary>Usage with vanilla view.gl</summary>
|
|
445
625
|
|
|
@@ -538,3 +718,76 @@ const { framebuffer, texture } = createFramebuffer(gl, {
|
|
|
538
718
|
```
|
|
539
719
|
|
|
540
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` | ❌ | ✅ |
|