@bigmistqke/view.gl 0.1.3 → 0.1.5

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/README.md CHANGED
@@ -10,56 +10,48 @@
10
10
  - [📦 Install](#-install)
11
11
  - [👁️ view.gl](#️-viewgl)
12
12
  - [🚀 Basic Usage](#-basic-usage)
13
- - [👀 View Types](#-view-types)
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
- - [📝 Template Features](#-template-features)
24
- - [⚙️ Tag Functions](#️-tag-functions)
21
+ - [📝 glsl](#-glsl)
22
+ - [🧩 GLSL Fragment](#-glsl-fragment)
23
+ - [🔒 Symbol Variables](#-symbol-variables)
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
- - [📝 glsl](#-glsl)
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
 
60
54
  ```typescript
61
- import { view } from '@bigmistqke/view.gl'
62
-
63
55
  const { uniforms, attributes } = view(gl, program, {
64
56
  uniforms: {
65
57
  time: { kind: 'float' },
@@ -83,26 +75,74 @@ attributes.position.set(positionData)
83
75
  attributes.position.bind()
84
76
  ```
85
77
 
86
- ### 👀 View Types
78
+ ### 👁️ view
87
79
 
88
- Each view type can be imported individually too.
80
+ The `view()` function creates type-safe WebGL resource managers from a schema.
89
81
 
90
82
  ```typescript
91
- import {
92
- uniformView,
93
- attributeView,
94
- interleavedAttributeView,
95
- bufferView,
96
- } from '@bigmistqke/view.gl'
83
+ const { uniforms, attributes, buffers } = view(gl, program, schema)
97
84
  ```
98
85
 
86
+ **Parameters:**
87
+
88
+ - `gl`: WebGL rendering context
89
+ - `program`: Compiled WebGL program
90
+ - `schema`: Resource definitions object
91
+
92
+ **Returns:**
93
+
94
+ - `uniforms`: Type-safe uniform setters
95
+ - `attributes`: Attribute managers with buffer handling
96
+ - `buffers`: Generic buffer managers
97
+
98
+ **ViewSchema:**
99
+ The complete schema object that defines all WebGL resources. Contains optional mappings for uniforms, attributes, interleaved attributes, and buffers.
100
+
101
+ <details>
102
+ <summary>TypeScript Types</summary>
103
+
104
+ ```typescript
105
+ interface ViewSchema {
106
+ uniforms?: Record<string | symbol, UniformOptions>
107
+ attributes?: Record<string | symbol, AttributeOptions>
108
+ interleavedAttributes?: Record<string | symbol, InterleavedAttributeOptions>
109
+ buffers?: Record<string | symbol, BufferOptions>
110
+ }
111
+
112
+ interface UniformOptions {
113
+ kind: UniformKind
114
+ size?: number // For array uniforms
115
+ }
116
+
117
+ interface AttributeOptions {
118
+ kind: AttributeKind
119
+ instanced?: boolean
120
+ buffer?: WebGLBuffer
121
+ }
122
+
123
+ interface InterleavedAttributeOptions {
124
+ layout: Array<{ key: string | symbol; kind: AttributeKind }>
125
+ instanced?: boolean
126
+ buffer?: WebGLBuffer
127
+ }
128
+
129
+ interface BufferOptions {
130
+ target: 'ARRAY_BUFFER' | 'ELEMENT_ARRAY_BUFFER'
131
+ usage?: 'STATIC_DRAW' | 'DYNAMIC_DRAW' | 'STREAM_DRAW'
132
+ }
133
+ ```
134
+
135
+ </details>
136
+
137
+ ### 👀 Resource Views
138
+
139
+ Each view type can be imported individually.
140
+
99
141
  #### 🎯 uniformView
100
142
 
101
143
  Manages shader uniform variables.
102
144
 
103
145
  ```typescript
104
- import { uniformView } from '@bigmistqke/view.gl'
105
-
106
146
  const uniforms = uniformView(gl, program, {
107
147
  time: { kind: 'float' },
108
148
  lights: { kind: 'vec3', size: 8 }, // Array uniform: vec3[8]
@@ -111,52 +151,103 @@ const uniforms = uniformView(gl, program, {
111
151
 
112
152
  uniforms.time.set(performance.now())
113
153
  uniforms.lights.set(lightData) // Takes Float32Array for array uniforms
114
- uniforms.transform.set(transformMatrix)
115
154
  ```
116
155
 
117
- **Settings:**
156
+ **UniformSchema:**
157
+ A mapping of uniform names to their configuration. Each uniform has a GLSL type and optional array size.
118
158
 
119
- - `kind`: GLSL type (`'float'`, `'vec2'`, `'mat4'`, `'sampler2D'`, etc.)
120
- - `size`: Array size (optional) - converts uniform to array type with Float32Array setter
159
+ - `kind`: GLSL type (see [Uniform Types](#-uniform-types) for full list and WebGL compatibility)
160
+ - `size`: Array size (optional) - converts uniform to array type
161
+
162
+ <details>
163
+ <summary>TypeScript Types</summary>
164
+
165
+ ```typescript
166
+ type UniformKind =
167
+ | 'float'
168
+ | 'int'
169
+ | 'bool'
170
+ | 'vec2'
171
+ | 'vec3'
172
+ | 'vec4'
173
+ | 'ivec2'
174
+ | 'ivec3'
175
+ | 'ivec4'
176
+ | 'bvec2'
177
+ | 'bvec3'
178
+ | 'bvec4'
179
+ | 'mat2'
180
+ | 'mat3'
181
+ | 'mat4'
182
+ | 'sampler2D'
183
+ | 'samplerCube'
184
+
185
+ interface UniformOptions {
186
+ kind: UniformKind
187
+ size?: number // Creates array uniform with Float32Array setter
188
+ }
189
+
190
+ type UniformSchema = Record<string | symbol, UniformOptions>
191
+ ```
192
+
193
+ </details>
121
194
 
122
195
  #### 📝 attributeView
123
196
 
124
- Manages vertex attributes with buffer creation, binding, and data management.
197
+ Manages vertex attributes with automatic buffer creation and binding.
125
198
 
126
199
  ```typescript
127
- import { attributeView } from '@bigmistqke/view.gl'
128
-
129
200
  const attributes = attributeView(gl, program, {
130
201
  position: { kind: 'vec3' },
131
202
  instanceOffset: { kind: 'vec2', instanced: true },
132
203
  })
133
204
 
134
- // Regular attribute for vertices
135
205
  attributes.position.set(positionData).bind()
136
-
137
- // Instanced attribute for per-instance data
138
206
  attributes.instanceOffset.set(instanceData).bind()
139
207
 
140
- // Draw regular geometry
141
- gl.drawArrays(gl.TRIANGLES, 0, 3)
142
-
143
- // Draw instanced geometry
144
208
  gl.drawArraysInstanced(gl.TRIANGLES, 0, 3, 100)
145
209
  ```
146
210
 
147
- **Settings:**
211
+ **AttributeSchema:**
212
+ A mapping of attribute names to their configuration. Each attribute has a GLSL type, optional instancing, and optional custom buffer.
213
+
214
+ - `kind`: GLSL type (see [Attribute Types](#-attribute-types) for full list and WebGL compatibility)
215
+ - `instanced`: Boolean - enables instanced rendering
216
+ - `buffer`: Custom WebGLBuffer (optional)
148
217
 
149
- - `kind`: GLSL type (`'float'`, `'vec2'`, `'vec3'`, `'vec4'`, `'mat2'`, `'mat3'`, `'mat4'`, integer types)
150
- - `instanced`: Boolean - enables instanced rendering with `vertexAttribDivisor`
151
- - `buffer`: Custom WebGLBuffer (optional) - uses auto-created buffer if not provided
218
+ <details>
219
+ <summary>TypeScript Types</summary>
220
+
221
+ ```typescript
222
+ type AttributeKind =
223
+ | 'float'
224
+ | 'vec2'
225
+ | 'vec3'
226
+ | 'vec4'
227
+ | 'mat2'
228
+ | 'mat3'
229
+ | 'mat4'
230
+ | 'int'
231
+ | 'ivec2'
232
+ | 'ivec3'
233
+ | 'ivec4'
234
+
235
+ interface AttributeOptions {
236
+ kind: AttributeKind
237
+ instanced?: boolean // Enables vertexAttribDivisor
238
+ buffer?: WebGLBuffer // Custom buffer, auto-created if not provided
239
+ }
240
+
241
+ type AttributeSchema = Record<string | symbol, AttributeOptions>
242
+ ```
243
+
244
+ </details>
152
245
 
153
246
  #### 🔗 interleavedAttributeView
154
247
 
155
- Manages interleaved vertex data with automatic stride/offset calculation and VAO optimization.
248
+ Manages interleaved vertex data with automatic stride/offset calculation.
156
249
 
157
250
  ```typescript
158
- import { interleavedAttributeView } from '@bigmistqke/view.gl'
159
-
160
251
  const interleavedAttributes = interleavedAttributeView(gl, program, {
161
252
  vertexData: {
162
253
  layout: [
@@ -165,109 +256,90 @@ const interleavedAttributes = interleavedAttributeView(gl, program, {
165
256
  { key: 'uv', kind: 'vec2' },
166
257
  ],
167
258
  },
168
- instanceData: {
169
- layout: [
170
- { key: 'instancePos', kind: 'vec2' },
171
- { key: 'instanceColor', kind: 'vec3' },
172
- ],
173
- instanced: true,
174
- },
175
259
  })
176
260
 
177
- // Upload interleaved data
178
- interleavedAttributes.vertexData.set(interleavedVertexData)
179
- interleavedAttributes.instanceData.set(interleavedInstanceData)
180
-
181
- // Bind all attributes in layout
182
- interleavedAttributes.vertexData.bind()
183
- interleavedAttributes.instanceData.bind()
261
+ interleavedAttributes.vertexData.set(interleavedVertexData).bind()
184
262
  ```
185
263
 
186
- **Settings:**
264
+ **InterleavedAttributeSchema:**
265
+ A mapping of interleaved buffer names to their layout configuration. Each layout defines multiple attributes packed into a single buffer.
266
+
267
+ - `layout`: Array of attribute definitions with `key` and `kind` (see [Attribute Types](#-attribute-types))
268
+ - `instanced`: Boolean - applies to all attributes in layout
187
269
 
188
- - `layout`: Array of attribute definitions with `name` and `kind`
189
- - `instanced`: Boolean - applies `vertexAttribDivisor` to all attributes in layout
270
+ <details>
271
+ <summary>TypeScript Types</summary>
272
+
273
+ ```typescript
274
+ interface InterleavedAttributeOptions {
275
+ layout: Array<{
276
+ key: string | symbol
277
+ kind: AttributeKind
278
+ }>
279
+ instanced?: boolean // Applies vertexAttribDivisor to all attributes
280
+ buffer?: WebGLBuffer // Custom buffer for interleaved data
281
+ }
282
+
283
+ type InterleavedAttributeSchema = Record<string | symbol, InterleavedAttributeOptions>
284
+ ```
285
+
286
+ </details>
190
287
 
191
288
  #### 🗂️ bufferView
192
289
 
193
- Manages generic WebGL buffers for various uses.
290
+ Manages generic WebGL buffers.
194
291
 
195
292
  ```typescript
196
- import { bufferView } from '@bigmistqke/view.gl'
197
-
198
293
  const buffers = bufferView(gl, {
199
294
  indices: { target: 'ELEMENT_ARRAY_BUFFER' },
200
295
  data: { target: 'ARRAY_BUFFER', usage: 'DYNAMIC_DRAW' },
201
296
  })
202
297
 
203
- buffers.indices.set(indexData)
204
- buffers.indices.bind()
205
-
206
- buffers.data.set(dynamicData)
207
- buffers.data.bind()
298
+ buffers.indices.set(indexData).bind()
299
+ buffers.data.set(dynamicData).bind()
208
300
  ```
209
301
 
210
- **Settings:**
302
+ **BufferSchema:**
303
+ A mapping of buffer names to their configuration. Each buffer has a target type and optional usage pattern.
211
304
 
212
305
  - `target`: Buffer target (`'ARRAY_BUFFER'`, `'ELEMENT_ARRAY_BUFFER'`)
213
306
  - `usage`: Usage pattern (`'STATIC_DRAW'`, `'DYNAMIC_DRAW'`, `'STREAM_DRAW'`)
214
307
 
215
- ### 🎨 Drawing Examples
216
-
217
- #### 🖼️ Regular Drawing
308
+ <details>
309
+ <summary>TypeScript Types</summary>
218
310
 
219
311
  ```typescript
220
- const { attributes } = view(gl, program, {
221
- attributes: {
222
- position: { kind: 'vec3' },
223
- uv: { kind: 'vec2' },
224
- },
225
- })
312
+ interface BufferOptions {
313
+ target: 'ARRAY_BUFFER' | 'ELEMENT_ARRAY_BUFFER'
314
+ usage?: 'STATIC_DRAW' | 'DYNAMIC_DRAW' | 'STREAM_DRAW' // Defaults to 'STATIC_DRAW'
315
+ }
226
316
 
227
- attributes.position.set(vertices).bind()
228
- attributes.uv.set(uvData).bind()
229
-
230
- gl.drawArrays(gl.TRIANGLES, 0, vertexCount)
317
+ type BufferSchema = Record<string | symbol, BufferOptions>
231
318
  ```
232
319
 
233
- #### 📱 Instanced Drawing
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
- ```
320
+ </details>
250
321
 
251
322
  ## 🏷️ view.gl/tag
252
323
 
253
- The tag system provides GLSL template literal support with embedded schema definitions.
324
+ Type-safe GLSL template literals with automatic schema extraction.
325
+
326
+ - **Embedded Resources**: Define uniforms, attributes, and interleaved layouts directly in GLSL
327
+ - **Type Inference**: Automatically infers schema types and creates type-safe view
328
+ - **Unique Variables**: Prevent naming collisions using symbols for unique shader variables
329
+ - **GLSL Composition**: Compose reusable GLSL fragments with automatic dependency resolution
254
330
 
255
331
  ### 🚀 Basic Usage
256
332
 
257
333
  ```typescript
258
- import { glsl, uniform, attribute, compile } from '@bigmistqke/view.gl/tag'
259
-
260
334
  const vertexShader = glsl`
261
335
  ${attribute.vec3('position')}
262
- ${attribute.vec2('uv')}
263
- ${uniform.mat4('projection')}
264
336
  ${uniform.mat4('model')}
265
337
 
266
338
  varying vec2 vUv;
267
339
 
268
340
  void main() {
269
341
  vUv = uv;
270
- gl_Position = projection * model * vec4(position, 1.0);
342
+ gl_Position = model * vec4(position, 1.0);
271
343
  }
272
344
  `
273
345
 
@@ -284,170 +356,247 @@ const fragmentShader = glsl`
284
356
  const { program, schema } = compile(gl, vertexShader, fragmentShader)
285
357
  ```
286
358
 
287
- ### 📝 Template Features
359
+ ### 📝 glsl
288
360
 
289
- - **Embedded Resources**: Define uniforms and attributes directly in GLSL
290
- - **Type Safety**: Automatic schema generation from template literals
291
- - **WebGL Version Support**: Automatic syntax conversion for WebGL1/2
292
- - **Interleaved Attributes**: Multi-attribute layout support
293
- - **Symbol Support**: Use JavaScript symbols as keys (see [Symbol Support](#-symbol-support))
361
+ Template literal processor that handles GLSL code and embedded resources. Supports interpolation of:
294
362
 
295
- ### ⚙️ Tag Functions
296
-
297
- #### 🎯 uniform[kind](name, options?)
298
-
299
- Define uniform variables in GLSL templates. Supports all GLSL uniform types.
363
+ - **[Resource tags](#️-resource-tags)**: `uniform.*()`, `attribute.*()`, `interleave()`
364
+ - **[GLSL fragments](#-glsl-fragment)**: Reusable shader code snippets
365
+ - **[Symbol Variables](#-symbol-variables)**: Unique variable names to prevent collisions
366
+ - **Strings**: Interpolated as-is into the shader code
367
+ - **Arrays**: Arrays of any supported interpolation types
300
368
 
301
369
  ```typescript
302
- import { uniform, glsl } from '@bigmistqke/view.gl/tag'
370
+ const precision = 'precision mediump float;'
371
+ const functionName = Symbol('function')
303
372
 
304
373
  const shader = glsl`
305
- ${uniform.float('time')}
374
+ ${precision} // String interpolated as-is
306
375
  ${uniform.vec2('resolution')}
307
- ${uniform.mat4('projection')}
308
- ${uniform.sampler2D('texture')}
309
- ${uniform.vec3('lights', { size: 8 })} // Array uniform: vec3[8]
376
+ ${[attribute.vec3('position'), attribute.vec2('uv')]} // Array interpolation
377
+
378
+ vec3 ${functionName}(vec2 uv) { // Symbol interpolated to unique identifier
379
+ return vec3(uv, 0.5);
380
+ }
310
381
 
311
382
  void main() {
312
- // Use uniforms in shader code
383
+ gl_Position = vec4(position, 1.0);
313
384
  }
314
385
  `
315
386
  ```
316
387
 
317
- **Available types**: `float`, `int`, `bool`, `vec2`, `vec3`, `vec4`, `ivec2`, `ivec3`, `ivec4`, `bvec2`, `bvec3`, `bvec4`, `mat2`, `mat3`, `mat4`, `sampler2D`, `samplerCube`
388
+ #### 🧩 GLSL Fragment
318
389
 
319
- **Options**:
320
-
321
- - `size`: Array size (creates array uniform with Float32Array setter)
322
-
323
- #### 📝 attribute[kind](name, options?)
324
-
325
- Define vertex attributes in GLSL templates.
390
+ Compose reusable GLSL code fragments to build complex shaders:
326
391
 
327
392
  ```typescript
328
- import { attribute, glsl } from '@bigmistqke/view.gl/tag'
393
+ const lighting = glsl`
394
+ vec3 calculateLighting(vec3 normal, vec3 lightDir) {
395
+ float diff = max(dot(normal, lightDir), 0.0);
396
+ return vec3(diff);
397
+ }
398
+ `
329
399
 
330
400
  const vertexShader = glsl`
331
- ${attribute.vec3('position')}
332
- ${attribute.vec2('uv')}
401
+ ${attribute.vec3('direction')}
333
402
  ${attribute.vec3('normal')}
334
- ${attribute.vec2('instanceOffset', { instanced: true })}
403
+ ${lighting} // Include the lighting fragment
404
+
405
+ varying vec3 vLighting;
335
406
 
336
407
  void main() {
337
- gl_Position = vec4(position + vec3(instanceOffset, 0.0), 1.0);
408
+ vLighting = calculateLighting(normal, direction);
338
409
  }
339
410
  `
340
411
  ```
341
412
 
342
- **Available types**: `float`, `vec2`, `vec3`, `vec4`, `mat2`, `mat3`, `mat4`, `int`, `ivec2`, `ivec3`, `ivec4`
413
+ #### 🔒 Symbol Variables
343
414
 
344
- **Options**:
415
+ Use JavaScript symbols to prevent naming collisions:
345
416
 
346
- - `instanced`: Boolean - enables instanced rendering with `vertexAttribDivisor`
347
- - `buffer`: Custom WebGLBuffer (optional)
417
+ ```typescript
418
+ const sum = Symbol('sum')
348
419
 
349
- #### 🔗 interleave(name, layout, options?)
420
+ const sumFragment = glsl`
421
+ float ${sum}(float a, float b){
422
+ return a + b;
423
+ }`
350
424
 
351
- Define interleaved attribute layouts for efficient vertex data.
425
+ const shader = glsl`
426
+ ${sumFragment}
352
427
 
353
- ```typescript
354
- import { interleave, glsl } from '@bigmistqke/view.gl/tag'
428
+ void main(){
429
+ float result = ${sum}(1.0, 2.0);
430
+ }
431
+ `
432
+ ```
355
433
 
356
- const vertexShader = glsl`
357
- ${interleave('vertexData', [
358
- { key: 'position', kind: 'vec3' },
359
- { key: 'normal', kind: 'vec3' },
360
- { key: 'uv', kind: 'vec2' },
361
- ])}
362
-
363
- ${interleave(
364
- 'instanceData',
365
- [
366
- { key: 'instancePos', kind: 'vec2' },
367
- { key: 'instanceColor', kind: 'vec3' },
368
- ],
369
- { instanced: true },
370
- )}
371
-
372
- void main() {
373
- gl_Position = vec4(position + vec3(instancePos, 0.0), 1.0);
374
- }
434
+ Symbols are converted to unique identifiers during the compilation of the shader.
435
+
436
+ #### WebGL Version Support
437
+
438
+ The glsl-function supports both WebGL1 and WebGL2 syntax, automatically using the correct keywords for resource tags:
439
+
440
+ ```typescript
441
+ // WebGL1 (default)
442
+ const shader = glsl`
443
+ ${attribute.vec3('position')} // → attribute vec3 position;
444
+ varying vec2 vUv;
375
445
  `
376
446
  ```
377
447
 
378
- **Layout format**:
448
+ If the shader starts with `#version 300 es`, resource tags generate WebGL2 syntax:
379
449
 
380
- - `key`: Attribute name
381
- - `kind`: GLSL type
450
+ ```typescript
451
+ // WebGL2
452
+ const shader = glsl`#version 300 es
453
+ ${attribute.vec3('position')} // → in vec3 position;
454
+ out vec2 vUv;
455
+ `
456
+ ```
382
457
 
383
- **Options**:
458
+ ### ⚙️ Resource Tags
384
459
 
385
- - `instanced`: Boolean - applies `vertexAttribDivisor` to all attributes
460
+ 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.
386
461
 
387
- #### 📝 glsl
462
+ #### 🎯 uniform[kind](name, options?)
388
463
 
389
- Template literal processor that handles GLSL code and embedded resources.
464
+ Define uniform variables in GLSL templates (see [Uniform Types](#-uniform-types)).
390
465
 
391
466
  ```typescript
392
- import { glsl } from '@bigmistqke/view.gl/tag'
467
+ const uniqueTime = Symbol('time')
393
468
 
394
469
  const shader = glsl`
395
- precision mediump float;
396
-
397
- ${uniform.vec2('resolution')}
470
+ ${uniform.float('time')} // String key
471
+ ${uniform.float(uniqueTime)} // Symbol key
472
+ ${uniform.vec3('lights', { size: 8 })} // Array uniform: vec3[8]
398
473
 
399
474
  void main() {
400
- vec2 uv = gl_FragCoord.xy / resolution;
401
- gl_FragColor = vec4(uv, 0.0, 1.0);
475
+ float wave = sin(time * 2.0 + ${uniqueTime});
476
+ vec3 totalLight = vec3(0.0);
477
+ for(int i = 0; i < 8; i++) {
478
+ totalLight += lights[i] * wave;
479
+ }
480
+ gl_FragColor = vec4(totalLight, 1.0);
402
481
  }
403
482
  `
404
483
  ```
405
484
 
406
- #### ⚙️ compile(gl, vertex, fragment)
485
+ **Parameters**:
407
486
 
408
- Compiles shaders and extracts schema from embedded resources.
487
+ - `name`: Uniform name (string or symbol for unique variables)
488
+ - `options`: Optional configuration object
489
+ - `size`: Array size (creates array uniform with Float32Array setter)
409
490
 
410
- ```typescript
411
- import { compile } from '@bigmistqke/view.gl/tag'
491
+ #### 📝 attribute[kind](name, options?)
412
492
 
413
- const { program, schema } = compile(gl, vertexShader, fragmentShader)
493
+ Define vertex attributes in GLSL templates (see [Attribute Types](#-attribute-types)).
494
+
495
+ ```typescript
496
+ const uniquePosition = Symbol('position')
414
497
 
415
- // Schema contains extracted uniforms, attributes, and buffers
416
- console.log(schema.uniforms) // { time: { kind: 'float' }, ... }
417
- console.log(schema.attributes) // { position: { kind: 'vec3' }, ... }
498
+ const vertexShader = glsl`
499
+ ${attribute.vec3('position')} // String key
500
+ ${attribute.vec3(uniquePosition)} // Symbol key
501
+ ${attribute.vec2('offset', { instanced: true })}
502
+
503
+ void main() {
504
+ gl_Position = vec4(position + vec3(offset, 0.0), 1.0);
505
+ }
506
+ `
418
507
  ```
419
508
 
420
- **Returns**:
509
+ **Parameters**:
421
510
 
422
- - `program`: Compiled WebGL program
423
- - `schema`: Extracted resource definitions for use with `view()`
511
+ - `name`: Attribute name (string or symbol for unique variables)
512
+ - `options`: Optional configuration object
513
+ - `instanced`: Boolean - enables instanced rendering with `vertexAttribDivisor`
514
+ - `buffer`: Custom WebGLBuffer (optional)
424
515
 
425
- ### 🔣 Symbol Support
516
+ #### 🔗 interleave(name, layout, options?)
426
517
 
427
- Symbols are supported as keys for uniforms, attributes, and buffers. When interpolated in glsl templates, they're automatically converted to valid GLSL identifiers. This prevents naming collisions between different shader modules and enables private scoping of shader variables.
518
+ Define interleaved attribute layouts for efficient vertex data.
428
519
 
429
520
  ```typescript
430
- const u_time = Symbol('time')
431
- const a_position = Symbol('position')
521
+ const uniqueVertexData = Symbol('vertexData')
522
+ const uniquePosition = Symbol('position')
432
523
 
433
- const shader = glsl`
434
- ${attribute.vec3(a_position)}
435
- ${uniform.float(u_time)}
524
+ const vertexShader = glsl`
525
+ ${interleave('vertexData', [
526
+ // String key
527
+ { key: 'position', kind: 'vec3' },
528
+ { key: 'uv', kind: 'vec2' },
529
+ ])}
530
+ ${interleave(uniqueVertexData, [
531
+ // Symbol key
532
+ { key: uniquePosition, kind: 'vec3' }, // Symbol keys in layout
533
+ { key: 'uv', kind: 'vec2' },
534
+ ])}
436
535
 
437
536
  void main() {
438
- gl_Position = vec4(${a_position}, ${u_time});
537
+ gl_Position = vec4(position + vec3(uv, 0.0), 1.0);
439
538
  }
440
539
  `
441
540
  ```
442
541
 
542
+ **Parameters**:
543
+
544
+ - `name`: Buffer name (string or symbol for unique variables)
545
+ - `layout`: Array of attribute definitions
546
+ - `key`: Attribute name (string or symbol for unique variables)
547
+ - `kind`: GLSL type (see [Attribute Types](#-attribute-types))
548
+ - `options`: Optional configuration object
549
+ - `instanced`: Boolean - applies `vertexAttribDivisor` to all attributes
550
+
551
+ ### ⚙️ compile(gl, vertex, fragment, overrideSchema?)
552
+
553
+ Compiles shaders and extracts schema from embedded resources. Returns both the compiled program and a ready-to-use view.
554
+
555
+ ```typescript
556
+ const { program, schema, view } = compile(gl, vertexShader, fragmentShader)
557
+
558
+ // Use the view directly
559
+ view.uniforms.time.set(performance.now())
560
+ view.attributes.position.set(vertexData).bind()
561
+
562
+ // Or access the extracted schema
563
+ console.log(schema.uniforms) // { time: { kind: 'float' }, ... }
564
+ console.log(schema.attributes) // { position: { kind: 'vec3' }, ... }
565
+ ```
566
+
567
+ **Override Schema:**
568
+
569
+ You can provide an optional override schema to enhance or override the automatically extracted schema:
570
+
571
+ ```typescript
572
+ const { program, schema, view } = compile(gl, vertexShader, fragmentShader, {
573
+ uniforms: {
574
+ // Add additional uniforms not automatically inferred
575
+ customTime: { kind: 'float' },
576
+ },
577
+ buffers: {
578
+ // Add buffer definitions
579
+ indices: { target: 'ELEMENT_ARRAY_BUFFER' },
580
+ },
581
+ })
582
+
583
+ // The override schema is merged with the extracted schema
584
+ view.uniforms.customTime.set(123.45)
585
+ view.buffers.indices.set(indexData).bind()
586
+ ```
587
+
588
+ **Returns**:
589
+
590
+ - `program`: Compiled WebGL program
591
+ - `schema`: Merged schema (extracted + override)
592
+ - `view`: Ready-to-use view with type-safe resource access
593
+
443
594
  <details>
444
595
  <summary>Usage with vanilla view.gl</summary>
445
596
 
446
- When manually constructing GLSL strings, use `toID()` to convert symbols to valid identifiers:
597
+ When manually constructing GLSL strings, use `toID()` to convert symbols to valid, unique identifiers:
447
598
 
448
599
  ```typescript
449
- import { createProgram, view, toID } from 'view.gl'
450
-
451
600
  const u_time = Symbol('time')
452
601
  const a_position = Symbol('position')
453
602
 
@@ -489,8 +638,6 @@ uniforms[u_time].set(performance.now())
489
638
  Creates and links a WebGL program from vertex and fragment shader sources.
490
639
 
491
640
  ```typescript
492
- import { createProgram } from '@bigmistqke/view.gl/utils'
493
-
494
641
  const program = createProgram(gl, vertexShaderSource, fragmentShaderSource)
495
642
  ```
496
643
 
@@ -499,8 +646,6 @@ const program = createProgram(gl, vertexShaderSource, fragmentShaderSource)
499
646
  Creates a WebGL texture with specified parameters.
500
647
 
501
648
  ```typescript
502
- import { createTexture } from '@bigmistqke/view.gl/utils'
503
-
504
649
  const texture = createTexture(
505
650
  gl,
506
651
  {
@@ -525,8 +670,6 @@ Automatically validates WebGL2-only formats and provides fallbacks for WebGL1.
525
670
  Creates a framebuffer with attached texture for render-to-texture operations.
526
671
 
527
672
  ```typescript
528
- import { createFramebuffer } from '@bigmistqke/view.gl/utils'
529
-
530
673
  const { framebuffer, texture } = createFramebuffer(gl, {
531
674
  width: 512,
532
675
  height: 512,
@@ -538,3 +681,76 @@ const { framebuffer, texture } = createFramebuffer(gl, {
538
681
  ```
539
682
 
540
683
  Supports color, depth, stencil, and combined depth-stencil attachments with completeness validation.
684
+
685
+ ## 🔍 WebGL Type Compatibility
686
+
687
+ ### 🎯 Uniform Types
688
+
689
+ | Type | WebGL 1 | WebGL 2 |
690
+ | ---------------------- | ------- | ------- |
691
+ | `float` | ✅ | ✅ |
692
+ | `int` | ✅ | ✅ |
693
+ | `bool` | ✅ | ✅ |
694
+ | `vec2` | ✅ | ✅ |
695
+ | `vec3` | ✅ | ✅ |
696
+ | `vec4` | ✅ | ✅ |
697
+ | `ivec2` | ✅ | ✅ |
698
+ | `ivec3` | ✅ | ✅ |
699
+ | `ivec4` | ✅ | ✅ |
700
+ | `bvec2` | ✅ | ✅ |
701
+ | `bvec3` | ✅ | ✅ |
702
+ | `bvec4` | ✅ | ✅ |
703
+ | `mat2` | ✅ | ✅ |
704
+ | `mat3` | ✅ | ✅ |
705
+ | `mat4` | ✅ | ✅ |
706
+ | `sampler2D` | ✅ | ✅ |
707
+ | `samplerCube` | ✅ | ✅ |
708
+ | `uint` | ❌ | ✅ |
709
+ | `uvec2` | ❌ | ✅ |
710
+ | `uvec3` | ❌ | ✅ |
711
+ | `uvec4` | ❌ | ✅ |
712
+ | `mat2x3` | ❌ | ✅ |
713
+ | `mat2x4` | ❌ | ✅ |
714
+ | `mat3x2` | ❌ | ✅ |
715
+ | `mat3x4` | ❌ | ✅ |
716
+ | `mat4x2` | ❌ | ✅ |
717
+ | `mat4x3` | ❌ | ✅ |
718
+ | `sampler3D` | ❌ | ✅ |
719
+ | `sampler2DArray` | ❌ | ✅ |
720
+ | `sampler2DShadow` | ❌ | ✅ |
721
+ | `samplerCubeShadow` | ❌ | ✅ |
722
+ | `sampler2DArrayShadow` | ❌ | ✅ |
723
+ | `isampler2D` | ❌ | ✅ |
724
+ | `isampler3D` | ❌ | ✅ |
725
+ | `isamplerCube` | ❌ | ✅ |
726
+ | `isampler2DArray` | ❌ | ✅ |
727
+ | `usampler2D` | ❌ | ✅ |
728
+ | `usampler3D` | ❌ | ✅ |
729
+ | `usamplerCube` | ❌ | ✅ |
730
+ | `usampler2DArray` | ❌ | ✅ |
731
+
732
+ ### 📝 Attribute Types
733
+
734
+ | Type | WebGL 1 | WebGL 2 |
735
+ | -------- | ------- | ------- |
736
+ | `float` | ✅ | ✅ |
737
+ | `vec2` | ✅ | ✅ |
738
+ | `vec3` | ✅ | ✅ |
739
+ | `vec4` | ✅ | ✅ |
740
+ | `mat2` | ✅ | ✅ |
741
+ | `mat3` | ✅ | ✅ |
742
+ | `mat4` | ✅ | ✅ |
743
+ | `int` | ❌ | ✅ |
744
+ | `ivec2` | ❌ | ✅ |
745
+ | `ivec3` | ❌ | ✅ |
746
+ | `ivec4` | ❌ | ✅ |
747
+ | `uint` | ❌ | ✅ |
748
+ | `uvec2` | ❌ | ✅ |
749
+ | `uvec3` | ❌ | ✅ |
750
+ | `uvec4` | ❌ | ✅ |
751
+ | `mat2x3` | ❌ | ✅ |
752
+ | `mat2x4` | ❌ | ✅ |
753
+ | `mat3x2` | ❌ | ✅ |
754
+ | `mat3x4` | ❌ | ✅ |
755
+ | `mat4x2` | ❌ | ✅ |
756
+ | `mat4x3` | ❌ | ✅ |