glre 0.43.0 → 0.45.0

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.
@@ -1,28 +1,7 @@
1
1
  export const SWIZZLES = ['x', 'y', 'z', 'w', 'r', 'g', 'b', 'a', 's', 't', 'p', 'q'] as const
2
2
 
3
3
  // Unified order with TYPE_MAPPING array
4
- export const CONVERSIONS = [
5
- 'toBool',
6
- 'toUInt',
7
- 'toInt',
8
- 'toFloat',
9
- 'toBVec2',
10
- 'toIVec2',
11
- 'toUVec2',
12
- 'toVec2',
13
- 'toBVec3',
14
- 'toIVec3',
15
- 'toUVec3',
16
- 'toVec3',
17
- 'toBVec4',
18
- 'toIVec4',
19
- 'toUVec4',
20
- 'toVec4',
21
- 'toColor',
22
- 'toMat2',
23
- 'toMat3',
24
- 'toMat4',
25
- ] as const
4
+ export const CONVERSIONS = ['toBool', 'toUInt', 'toInt', 'toFloat', 'toBVec2', 'toIVec2', 'toUVec2', 'toVec2', 'toBVec3', 'toIVec3', 'toUVec3', 'toVec3', 'toBVec4', 'toIVec4', 'toUVec4', 'toVec4', 'toColor', 'toMat2', 'toMat3', 'toMat4'] as const
26
5
 
27
6
  // Unified order with CONVERSIONS array
28
7
  export const TYPE_MAPPING = {
@@ -134,14 +113,7 @@ export const BUILTIN_TYPES = {
134
113
  color: 'vec4',
135
114
  } as const
136
115
 
137
- export const COMPARISON_OPERATORS = [
138
- 'equal',
139
- 'notEqual',
140
- 'lessThan',
141
- 'lessThanEqual',
142
- 'greaterThan',
143
- 'greaterThanEqual',
144
- ] as const
116
+ export const COMPARISON_OPERATORS = ['equal', 'notEqual', 'lessThan', 'lessThanEqual', 'greaterThan', 'greaterThanEqual'] as const
145
117
 
146
118
  export const LOGICAL_OPERATORS = ['and', 'or'] as const
147
119
 
@@ -270,9 +242,7 @@ const isSameType = (L: string, R: string): boolean => L === R
270
242
 
271
243
  // Check if combination exists in rules (handles bidirectional matching)
272
244
  const isValidCombination = (L: string, R: string): boolean => {
273
- return OPERATOR_TYPE_RULES.some(
274
- ([left, right, _]) => (left === L && right === R) || (left === R && right === L)
275
- )
245
+ return OPERATOR_TYPE_RULES.some(([left, right, _]) => (left === L && right === R) || (left === R && right === L))
276
246
  }
277
247
 
278
248
  // Type constraint validation for operators ([L, R, Result] format)
@@ -287,8 +257,6 @@ export const getOperatorResultType = (L: string, R: string, op: string): string
287
257
  if (COMPARISON_OPERATORS.includes(op as any) || LOGICAL_OPERATORS.includes(op as any)) return 'bool'
288
258
  // Same type operations return the same type
289
259
  if (isSameType(L, R)) return L
290
- const rule = OPERATOR_TYPE_RULES.find(
291
- ([left, right, _]) => (left === L && right === R) || (left === R && right === L)
292
- )
260
+ const rule = OPERATOR_TYPE_RULES.find(([left, right, _]) => (left === L && right === R) || (left === R && right === L))
293
261
  return rule ? rule[2] : L
294
262
  }
@@ -1,23 +1,6 @@
1
1
  import { infer } from './infer'
2
- import {
3
- parseArray,
4
- parseAttribHead,
5
- parseConstantHead,
6
- parseDeclare,
7
- parseDefine,
8
- parseGather,
9
- parseIf,
10
- parseLoop,
11
- parseScatter,
12
- parseStorageHead,
13
- parseStruct,
14
- parseStructHead,
15
- parseSwitch,
16
- parseTexture,
17
- parseUniformHead,
18
- parseVaryingHead,
19
- } from './parse'
20
- import { getBluiltin, getConversions, getOperator, initNodeContext, isElement, isX, setupEvent } from './utils'
2
+ import { parseArray, parseAttribHead, parseConstantHead, parseDeclare, parseDefine, parseGather, parseIf, parseLoop, parseScatter, parseStorageHead, parseStruct, parseStructHead, parseSwitch, parseTexture, parseUniformHead, parseVaryingHead } from './parse'
3
+ import { getBluiltin, getConversions, getOperator, initNodeContext, isX, setupEvent } from './utils'
21
4
  import { is } from '../../utils/helpers'
22
5
  import { mod } from '..'
23
6
  import type { Constants as C, NodeContext, Y } from '../types'
@@ -58,10 +41,7 @@ export const code = <T extends C>(target: Y<T>, c?: NodeContext | null): string
58
41
  ? parseScatter(c, storageNode, y) // indexNode is not using
59
42
  : `${code(storageNode, c)}[${code(indexNode, c)}] = ${code(y, c)};`
60
43
  }
61
- if (type === 'ternary')
62
- return c.isWebGL
63
- ? `(${code(z, c)} ? ${code(x, c)} : ${code(y, c)})`
64
- : `select(${code(x, c)}, ${code(y, c)}, ${code(z, c)})`
44
+ if (type === 'ternary') return c.isWebGL ? `(${code(z, c)} ? ${code(x, c)} : ${code(y, c)})` : `select(${code(x, c)}, ${code(y, c)}, ${code(z, c)})`
65
45
  if (type === 'conversion') return `${getConversions(x, c)}(${parseArray(children.slice(1), c)})`
66
46
  if (type === 'operator') {
67
47
  if (x === 'not' || x === 'bitNot') return `!${code(y, c)}`
@@ -110,7 +90,7 @@ export const code = <T extends C>(target: Y<T>, c?: NodeContext | null): string
110
90
  const field = parseVaryingHead(c, id, infer(target, c))
111
91
  c.code?.fragInputs.set(id, field)
112
92
  c.code?.vertOutputs.set(id, field)
113
- c.code?.vertVaryings.set(id, code(x, c))
93
+ c.code?.vertVaryings.set(id, { node: x })
114
94
  return c.isWebGL ? `${id}` : `out.${id}`
115
95
  }
116
96
  if (type === 'builtin') {
@@ -1,14 +1,6 @@
1
- import {
2
- CONSTANTS,
3
- CONVERSIONS,
4
- FUNCTIONS,
5
- OPERATOR_KEYS,
6
- OPERATORS,
7
- TYPE_MAPPING,
8
- WGSL_TO_GLSL_BUILTIN,
9
- } from './const'
1
+ import { CONSTANTS, CONVERSIONS, FUNCTIONS, OPERATOR_KEYS, OPERATORS, TYPE_MAPPING, WGSL_TO_GLSL_BUILTIN } from './const'
10
2
  import { is } from '../../utils/helpers'
11
- import type { Constants as C, Conversions, Functions, NodeContext, Operators, Swizzles, X, Y } from '../types'
3
+ import type { Constants as C, Conversions, Functions, NodeContext, Operators, Swizzles, VaryingInfo, X, Y } from '../types'
12
4
  import { storageSize } from '../../utils/program'
13
5
 
14
6
  export const isSwizzle = (key: unknown): key is Swizzles => {
package/src/types.ts CHANGED
@@ -21,6 +21,7 @@ export type GL = EventState<{
21
21
  count: number
22
22
  instanceCount: number
23
23
  particleCount: number | [number, number] | [number, number, number]
24
+ precision: 'lowp' | 'mediump' | 'highp'
24
25
  loading: number
25
26
  el: HTMLCanvasElement
26
27
  vs?: string | Vec4
@@ -123,7 +124,7 @@ export interface WebGPUState {
123
124
  * for webgl
124
125
  */
125
126
  export interface WebGLState {
126
- context: WebGLRenderingContext
127
+ context: WebGL2RenderingContext
127
128
  program: WebGLProgram
128
- storages: any
129
+ uniforms: Nested<WebGLUniformLocation | null>
129
130
  }
@@ -94,7 +94,8 @@ export const getStride = (arrayLength: number, count = 1, error = console.warn)
94
94
 
95
95
  export const GLSL_FS = /* cpp */ `
96
96
  #version 300 es
97
- precision mediump float;
97
+ precision highp float;
98
+ precision highp int;
98
99
  out vec4 fragColor;
99
100
  uniform vec2 iResolution;
100
101
  void main() {
@@ -32,12 +32,7 @@ export const createArrayBuffer = (c: WebGL2RenderingContext, data: number[]) =>
32
32
  return { array, buffer }
33
33
  }
34
34
 
35
- export const setArrayBuffer = (
36
- c: WebGL2RenderingContext,
37
- array: Float32Array,
38
- buffer: WebGLBuffer,
39
- value: number[]
40
- ) => {
35
+ export const setArrayBuffer = (c: WebGL2RenderingContext, array: Float32Array, buffer: WebGLBuffer, value: number[]) => {
41
36
  array.set(value)
42
37
  c.bindBuffer(c.ARRAY_BUFFER, buffer)
43
38
  c.bufferData(c.ARRAY_BUFFER, array, c.STATIC_DRAW)
@@ -65,13 +60,7 @@ export const updateUniform = (c: WebGL2RenderingContext, loc: WebGLUniformLocati
65
60
  c[`uniformMatrix${l as 2}fv`](loc, false, value)
66
61
  }
67
62
 
68
- export const createTexture = (
69
- c: WebGL2RenderingContext,
70
- el: HTMLImageElement | HTMLVideoElement,
71
- loc: WebGLUniformLocation,
72
- unit: number,
73
- isVideo = false
74
- ) => {
63
+ export const createTexture = (c: WebGL2RenderingContext, el: HTMLImageElement | HTMLVideoElement, loc: WebGLUniformLocation, unit: number, isVideo = false) => {
75
64
  const texture = c.createTexture()
76
65
  c.bindTexture(c.TEXTURE_2D, texture)
77
66
  c.texImage2D(c.TEXTURE_2D, 0, c.RGBA, c.RGBA, c.UNSIGNED_BYTE, el)
@@ -100,16 +89,7 @@ interface TextureBuffer {
100
89
  buffer: WebGLFramebuffer
101
90
  }
102
91
 
103
- export const createStorage = (
104
- c: WebGL2RenderingContext,
105
- value: number[],
106
- width: number,
107
- height: number,
108
- ping: TextureBuffer,
109
- pong: TextureBuffer,
110
- unit: number,
111
- array: Float32Array
112
- ) => {
92
+ export const createStorage = (c: WebGL2RenderingContext, value: number[], width: number, height: number, ping: TextureBuffer, pong: TextureBuffer, unit: number, array: Float32Array) => {
113
93
  const particleCount = width * height
114
94
  const vectorSize = value.length / particleCount
115
95
  for (let i = 0; i < particleCount; i++) {
@@ -132,10 +112,7 @@ export const createStorage = (
132
112
  c.texParameteri(c.TEXTURE_2D, c.TEXTURE_WRAP_T, c.CLAMP_TO_EDGE)
133
113
  }
134
114
 
135
- export const cleanStorage = (
136
- c: WebGL2RenderingContext,
137
- map: Iterable<{ ping: TextureBuffer; pong: TextureBuffer }>
138
- ) => {
115
+ export const cleanStorage = (c: WebGL2RenderingContext, map: Iterable<{ ping: TextureBuffer; pong: TextureBuffer }>) => {
139
116
  for (const { ping, pong } of map) {
140
117
  c.deleteTexture(ping.texture)
141
118
  c.deleteTexture(pong.texture)
@@ -144,14 +121,7 @@ export const cleanStorage = (
144
121
  }
145
122
  }
146
123
 
147
- export const createAttachment = (
148
- c: WebGL2RenderingContext,
149
- i: TextureBuffer,
150
- o: TextureBuffer,
151
- loc: WebGLUniformLocation,
152
- unit: number,
153
- index: number
154
- ) => {
124
+ export const createAttachment = (c: WebGL2RenderingContext, i: TextureBuffer, o: TextureBuffer, loc: WebGLUniformLocation, unit: number, index: number) => {
155
125
  c.activeTexture(c.TEXTURE0 + unit)
156
126
  c.bindTexture(c.TEXTURE_2D, i.texture)
157
127
  c.uniform1i(loc, unit)
@@ -168,19 +138,13 @@ export const storageSize = (particleCount: number | number[] = 1024) => {
168
138
  if (is.num(particleCount)) {
169
139
  const sqrt = Math.sqrt(particleCount)
170
140
  const size = Math.ceil(sqrt)
171
- if (!Number.isInteger(sqrt)) {
172
- console.warn(
173
- `GLRE Storage Warning: particleCount (${particleCount}) is not a square. Using ${size}x${size} texture may waste GPU memory. Consider using [width, height] format for optimal storage.`
174
- )
175
- }
141
+ if (!Number.isInteger(sqrt)) console.warn(`GLRE Storage Warning: particleCount (${particleCount}) is not a square. Using ${size}x${size} texture may waste GPU memory. Consider using [width, height] format for optimal storage.`)
176
142
  return { x: size, y: size }
177
143
  }
178
144
  const [x, y, z] = particleCount
179
145
  if (z !== undefined) {
180
146
  const yz = y * z
181
- console.warn(
182
- `GLRE Storage Warning: 3D particleCount [${x}, ${y}, ${z}] specified but WebGL storage textures only support 2D. Flattening to 2D by multiplying height=${y} * depth=${z} = ${yz}.`
183
- )
147
+ console.warn(`GLRE Storage Warning: 3D particleCount [${x}, ${y}, ${z}] specified but WebGL storage textures only support 2D. Flattening to 2D by multiplying height=${y} * depth=${z} = ${yz}.`)
184
148
  return { x, y: yz }
185
149
  }
186
150
  return { x, y }
@@ -1,19 +1,7 @@
1
1
  import { nested as cached } from 'reev'
2
2
  import { is, getStride, GLSL_VS, GLSL_FS, loadingTexture } from './helpers'
3
- import {
4
- createArrayBuffer,
5
- cleanStorage,
6
- createAttachment,
7
- createProgram,
8
- createStorage,
9
- createTexture,
10
- setArrayBuffer,
11
- storageSize,
12
- updateAttrib,
13
- updateInstance,
14
- updateUniform,
15
- } from './program'
16
- import type { GL, WebGLState } from '../types'
3
+ import { createArrayBuffer, cleanStorage, createAttachment, createProgram, createStorage, createTexture, setArrayBuffer, storageSize, updateAttrib, updateInstance, updateUniform } from './program'
4
+ import type { GL } from '../types'
17
5
 
18
6
  const computeProgram = (gl: GL, c: WebGL2RenderingContext) => {
19
7
  if (!gl.cs) return null // ignore if no compute shader
@@ -67,17 +55,17 @@ const computeProgram = (gl: GL, c: WebGL2RenderingContext) => {
67
55
 
68
56
  export const webgl = async (gl: GL) => {
69
57
  const config = { isWebGL: true, gl }
70
- const c = gl.el!.getContext('webgl2')!
58
+ const c = (gl.webgl.context = gl.el!.getContext('webgl2')!)
71
59
  const cp = computeProgram(gl, c)
72
60
  const fs = gl.fs ? (is.str(gl.fs) ? gl.fs : gl.fs!.fragment(config)) : GLSL_FS
73
61
  const vs = gl.vs ? (is.str(gl.vs) ? gl.vs : gl.vs!.vertex(config)) : GLSL_VS
74
- const pg = createProgram(c, fs, vs, gl)!
62
+ const pg = (gl.webgl.program = createProgram(c, fs, vs, gl)!)
75
63
  c.useProgram(pg)
76
64
 
77
65
  let activeUnit = 0 // for texture units
78
66
 
79
67
  const units = cached(() => activeUnit++)
80
- const uniforms = cached((key) => c.getUniformLocation(pg, key))
68
+ const uniforms = (gl.webgl.uniforms = cached((key) => c.getUniformLocation(pg, key)))
81
69
 
82
70
  const attribs = cached((key, value: number[], isInstance = false) => {
83
71
  const stride = getStride(value.length, isInstance ? gl.instanceCount : gl.count, gl.error)
@@ -143,7 +131,5 @@ export const webgl = async (gl: GL) => {
143
131
  ext.polygonModeWEBGL(c.FRONT_AND_BACK, ext.LINE_WEBGL)
144
132
  }
145
133
 
146
- const webgl: WebGLState = { context: c, program: pg, storages: cp?.storages }
147
-
148
- return { webgl, render, clean, _attribute, _instance, _uniform, _texture, _storage: cp?._storage }
134
+ return { render, clean, _attribute, _instance, _uniform, _texture, _storage: cp?._storage }
149
135
  }