pixospritz-core 0.10.1 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. package/README.md +36 -286
  2. package/dist/bundle.js +13 -3
  3. package/dist/bundle.js.map +1 -1
  4. package/dist/style.css +1 -0
  5. package/package.json +43 -44
  6. package/src/components/WebGLView.jsx +318 -0
  7. package/src/css/pixos.css +372 -0
  8. package/src/engine/actions/animate.js +41 -0
  9. package/src/engine/actions/changezone.js +135 -0
  10. package/src/engine/actions/chat.js +109 -0
  11. package/src/engine/actions/dialogue.js +90 -0
  12. package/src/engine/actions/face.js +22 -0
  13. package/src/engine/actions/greeting.js +28 -0
  14. package/src/engine/actions/interact.js +86 -0
  15. package/src/engine/actions/move.js +67 -0
  16. package/src/engine/actions/patrol.js +109 -0
  17. package/src/engine/actions/prompt.js +185 -0
  18. package/src/engine/actions/script.js +42 -0
  19. package/src/engine/core/audio/AudioSystem.js +543 -0
  20. package/src/engine/core/cutscene/PxcPlayer.js +956 -0
  21. package/src/engine/core/cutscene/manager.js +243 -0
  22. package/src/engine/core/database/index.js +75 -0
  23. package/src/engine/core/debug/index.js +371 -0
  24. package/src/engine/core/hud/index.js +765 -0
  25. package/src/engine/core/index.js +540 -0
  26. package/src/engine/core/input/gamepad/Controller.js +71 -0
  27. package/src/engine/core/input/gamepad/ControllerButtons.js +231 -0
  28. package/src/engine/core/input/gamepad/ControllerStick.js +173 -0
  29. package/src/engine/core/input/gamepad/index.js +592 -0
  30. package/src/engine/core/input/keyboard.js +196 -0
  31. package/src/engine/core/input/manager.js +485 -0
  32. package/src/engine/core/input/mouse.js +203 -0
  33. package/src/engine/core/input/touch.js +175 -0
  34. package/src/engine/core/mode/manager.js +199 -0
  35. package/src/engine/core/net/manager.js +535 -0
  36. package/src/engine/core/queue/action.js +83 -0
  37. package/src/engine/core/queue/event.js +82 -0
  38. package/src/engine/core/queue/index.js +44 -0
  39. package/src/engine/core/queue/loadable.js +33 -0
  40. package/src/engine/core/render/CameraEffects.js +494 -0
  41. package/src/engine/core/render/FrustumCuller.js +417 -0
  42. package/src/engine/core/render/LODManager.js +285 -0
  43. package/src/engine/core/render/ParticleManager.js +529 -0
  44. package/src/engine/core/render/TextureAtlas.js +465 -0
  45. package/src/engine/core/render/camera.js +338 -0
  46. package/src/engine/core/render/light.js +197 -0
  47. package/src/engine/core/render/manager.js +1079 -0
  48. package/src/engine/core/render/shaders.js +110 -0
  49. package/src/engine/core/render/skybox.js +342 -0
  50. package/src/engine/core/resource/manager.js +133 -0
  51. package/src/engine/core/resource/object.js +611 -0
  52. package/src/engine/core/resource/texture.js +103 -0
  53. package/src/engine/core/resource/tileset.js +177 -0
  54. package/src/engine/core/scene/avatar.js +215 -0
  55. package/src/engine/core/scene/speech.js +138 -0
  56. package/src/engine/core/scene/sprite.js +702 -0
  57. package/src/engine/core/scene/spritz.js +189 -0
  58. package/src/engine/core/scene/world.js +681 -0
  59. package/src/engine/core/scene/zone.js +1167 -0
  60. package/src/engine/core/store/index.js +110 -0
  61. package/src/engine/dynamic/animatedSprite.js +64 -0
  62. package/src/engine/dynamic/animatedTile.js +98 -0
  63. package/src/engine/dynamic/avatar.js +110 -0
  64. package/src/engine/dynamic/map.js +174 -0
  65. package/src/engine/dynamic/sprite.js +255 -0
  66. package/src/engine/dynamic/spritz.js +119 -0
  67. package/src/engine/events/EventSystem.js +609 -0
  68. package/src/engine/events/camera.js +142 -0
  69. package/src/engine/events/chat.js +75 -0
  70. package/src/engine/events/menu.js +186 -0
  71. package/src/engine/scripting/CallbackManager.js +514 -0
  72. package/src/engine/scripting/PixoScriptInterpreter.js +81 -0
  73. package/src/engine/scripting/PixoScriptLibrary.js +704 -0
  74. package/src/engine/shaders/effects/index.js +450 -0
  75. package/src/engine/shaders/fs.js +222 -0
  76. package/src/engine/shaders/particles/fs.js +41 -0
  77. package/src/engine/shaders/particles/vs.js +61 -0
  78. package/src/engine/shaders/picker/fs.js +34 -0
  79. package/src/engine/shaders/picker/init.js +62 -0
  80. package/src/engine/shaders/picker/vs.js +42 -0
  81. package/src/engine/shaders/pxsl/README.md +250 -0
  82. package/src/engine/shaders/pxsl/index.js +25 -0
  83. package/src/engine/shaders/pxsl/library.js +608 -0
  84. package/src/engine/shaders/pxsl/manager.js +338 -0
  85. package/src/engine/shaders/pxsl/specification.js +363 -0
  86. package/src/engine/shaders/pxsl/transpiler.js +753 -0
  87. package/src/engine/shaders/skybox/cosmic/fs.js +147 -0
  88. package/src/engine/shaders/skybox/cosmic/vs.js +23 -0
  89. package/src/engine/shaders/skybox/matrix/fs.js +127 -0
  90. package/src/engine/shaders/skybox/matrix/vs.js +23 -0
  91. package/src/engine/shaders/skybox/morning/fs.js +109 -0
  92. package/src/engine/shaders/skybox/morning/vs.js +23 -0
  93. package/src/engine/shaders/skybox/neon/fs.js +119 -0
  94. package/src/engine/shaders/skybox/neon/vs.js +23 -0
  95. package/src/engine/shaders/skybox/sky/fs.js +114 -0
  96. package/src/engine/shaders/skybox/sky/vs.js +23 -0
  97. package/src/engine/shaders/skybox/sunset/fs.js +101 -0
  98. package/src/engine/shaders/skybox/sunset/vs.js +23 -0
  99. package/src/engine/shaders/transition/blur/fs.js +42 -0
  100. package/src/engine/shaders/transition/blur/vs.js +26 -0
  101. package/src/engine/shaders/transition/cross/fs.js +36 -0
  102. package/src/engine/shaders/transition/cross/vs.js +26 -0
  103. package/src/engine/shaders/transition/crossBlur/fs.js +41 -0
  104. package/src/engine/shaders/transition/crossBlur/vs.js +25 -0
  105. package/src/engine/shaders/transition/dissolve/fs.js +78 -0
  106. package/src/engine/shaders/transition/dissolve/vs.js +24 -0
  107. package/src/engine/shaders/transition/fade/fs.js +31 -0
  108. package/src/engine/shaders/transition/fade/vs.js +27 -0
  109. package/src/engine/shaders/transition/iris/fs.js +52 -0
  110. package/src/engine/shaders/transition/iris/vs.js +24 -0
  111. package/src/engine/shaders/transition/pixelate/fs.js +44 -0
  112. package/src/engine/shaders/transition/pixelate/vs.js +24 -0
  113. package/src/engine/shaders/transition/slide/fs.js +53 -0
  114. package/src/engine/shaders/transition/slide/vs.js +24 -0
  115. package/src/engine/shaders/transition/swirl/fs.js +39 -0
  116. package/src/engine/shaders/transition/swirl/vs.js +26 -0
  117. package/src/engine/shaders/transition/wipe/fs.js +50 -0
  118. package/src/engine/shaders/transition/wipe/vs.js +24 -0
  119. package/src/engine/shaders/vs.js +60 -0
  120. package/src/engine/utils/CameraController.js +506 -0
  121. package/src/engine/utils/ObjHelper.js +551 -0
  122. package/src/engine/utils/debug-logger.js +110 -0
  123. package/src/engine/utils/enums.js +305 -0
  124. package/src/engine/utils/generator.js +156 -0
  125. package/src/engine/utils/index.js +21 -0
  126. package/src/engine/utils/loaders/ActionLoader.js +77 -0
  127. package/src/engine/utils/loaders/AudioLoader.js +157 -0
  128. package/src/engine/utils/loaders/EventLoader.js +66 -0
  129. package/src/engine/utils/loaders/ObjectLoader.js +67 -0
  130. package/src/engine/utils/loaders/SpriteLoader.js +77 -0
  131. package/src/engine/utils/loaders/TilesetLoader.js +103 -0
  132. package/src/engine/utils/loaders/index.js +21 -0
  133. package/src/engine/utils/math/matrix4.js +367 -0
  134. package/src/engine/utils/math/vector.js +458 -0
  135. package/src/engine/utils/obj/_old_js/index.js +46 -0
  136. package/src/engine/utils/obj/_old_js/layout.js +308 -0
  137. package/src/engine/utils/obj/_old_js/material.js +711 -0
  138. package/src/engine/utils/obj/_old_js/mesh.js +761 -0
  139. package/src/engine/utils/obj/_old_js/utils.js +647 -0
  140. package/src/engine/utils/obj/index.js +24 -0
  141. package/src/engine/utils/obj/js/index.js +277 -0
  142. package/src/engine/utils/obj/js/loader.js +232 -0
  143. package/src/engine/utils/obj/layout.js +246 -0
  144. package/src/engine/utils/obj/material.js +665 -0
  145. package/src/engine/utils/obj/mesh.js +657 -0
  146. package/src/engine/utils/obj/ts/index.ts +72 -0
  147. package/src/engine/utils/obj/ts/layout.ts +265 -0
  148. package/src/engine/utils/obj/ts/material.ts +760 -0
  149. package/src/engine/utils/obj/ts/mesh.ts +785 -0
  150. package/src/engine/utils/obj/ts/utils.ts +501 -0
  151. package/src/engine/utils/obj/utils.js +428 -0
  152. package/src/engine/utils/resources.js +18 -0
  153. package/src/index.jsx +55 -0
  154. package/src/spritz/player.js +18 -0
  155. package/src/spritz/readme.md +18 -0
  156. package/LICENSE +0 -437
  157. package/dist/bundle.js.LICENSE.txt +0 -31
@@ -0,0 +1,450 @@
1
+ /* *\
2
+ ** ----------------------------------------------- **
3
+ ** Calliope - Pixos Game Engine **
4
+ ** ----------------------------------------------- **
5
+ ** Copyright (c) 2020-2025 - Kyle Derby MacInnis **
6
+ ** **
7
+ ** Any unauthorized distribution or transfer **
8
+ ** of this work is strictly prohibited. **
9
+ ** **
10
+ ** All Rights Reserved. **
11
+ ** ----------------------------------------------- **
12
+ * */
13
+
14
+ /**
15
+ * Effect Shader Library - Post-processing visual effects
16
+ *
17
+ * Each effect exports a vertex shader (vs) and fragment shader (fs)
18
+ * for use with the post-processing pipeline.
19
+ */
20
+
21
+ // Common vertex shader for all post-processing effects
22
+ export const commonVS = `
23
+ attribute vec2 aPosition;
24
+ varying vec2 vUV;
25
+ void main() {
26
+ vUV = (aPosition + 1.0) * 0.5;
27
+ gl_Position = vec4(aPosition, 0.0, 1.0);
28
+ }
29
+ `;
30
+
31
+ /**
32
+ * CRT Monitor Effect
33
+ * Simulates a retro CRT monitor with curvature, scanlines, and color bleeding
34
+ */
35
+ export const crt = {
36
+ vs: commonVS,
37
+ fs: `
38
+ precision mediump float;
39
+ varying vec2 vUV;
40
+ uniform sampler2D uTexture;
41
+ uniform vec2 uResolution;
42
+ uniform float uTime;
43
+ uniform float uCurvature; // 0-1, barrel distortion amount
44
+ uniform float uScanlines; // 0-1, scanline intensity
45
+ uniform float uVignette; // 0-1, vignette intensity
46
+
47
+ vec2 curveUV(vec2 uv) {
48
+ uv = uv * 2.0 - 1.0;
49
+ vec2 offset = abs(uv.yx) / vec2(6.0, 4.0);
50
+ uv = uv + uv * offset * offset * uCurvature;
51
+ uv = uv * 0.5 + 0.5;
52
+ return uv;
53
+ }
54
+
55
+ void main() {
56
+ vec2 uv = curveUV(vUV);
57
+
58
+ // Check if outside screen bounds (black out)
59
+ if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0) {
60
+ gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
61
+ return;
62
+ }
63
+
64
+ // Sample with slight RGB offset for color bleeding
65
+ float offset = 0.001;
66
+ float r = texture2D(uTexture, uv + vec2(offset, 0.0)).r;
67
+ float g = texture2D(uTexture, uv).g;
68
+ float b = texture2D(uTexture, uv - vec2(offset, 0.0)).b;
69
+ vec3 color = vec3(r, g, b);
70
+
71
+ // Scanlines
72
+ float scanline = sin(uv.y * uResolution.y * 2.0) * 0.5 + 0.5;
73
+ color *= 1.0 - uScanlines * (1.0 - scanline) * 0.3;
74
+
75
+ // Vignette
76
+ float dist = length(vUV - 0.5);
77
+ color *= 1.0 - uVignette * dist * dist * 2.0;
78
+
79
+ // Slight flicker
80
+ color *= 0.98 + 0.02 * sin(uTime * 60.0);
81
+
82
+ gl_FragColor = vec4(color, 1.0);
83
+ }
84
+ `
85
+ };
86
+
87
+ /**
88
+ * Bloom/Glow Effect
89
+ * Adds a glow to bright areas of the image
90
+ */
91
+ export const bloom = {
92
+ vs: commonVS,
93
+ fs: `
94
+ precision mediump float;
95
+ varying vec2 vUV;
96
+ uniform sampler2D uTexture;
97
+ uniform vec2 uResolution;
98
+ uniform float uThreshold; // Brightness threshold for bloom
99
+ uniform float uIntensity; // Bloom intensity
100
+ uniform float uRadius; // Blur radius
101
+
102
+ void main() {
103
+ vec4 color = texture2D(uTexture, vUV);
104
+ vec3 bloom = vec3(0.0);
105
+
106
+ // Simple box blur for bloom
107
+ float total = 0.0;
108
+ int samples = 8;
109
+
110
+ for (int x = -4; x <= 4; x++) {
111
+ for (int y = -4; y <= 4; y++) {
112
+ vec2 offset = vec2(float(x), float(y)) * uRadius / uResolution;
113
+ vec4 sample = texture2D(uTexture, vUV + offset);
114
+
115
+ // Extract bright parts
116
+ float brightness = dot(sample.rgb, vec3(0.2126, 0.7152, 0.0722));
117
+ if (brightness > uThreshold) {
118
+ bloom += sample.rgb * (brightness - uThreshold);
119
+ total += 1.0;
120
+ }
121
+ }
122
+ }
123
+
124
+ if (total > 0.0) {
125
+ bloom /= total;
126
+ }
127
+
128
+ gl_FragColor = vec4(color.rgb + bloom * uIntensity, color.a);
129
+ }
130
+ `
131
+ };
132
+
133
+ /**
134
+ * Scanlines Effect
135
+ * Adds horizontal scanlines overlay
136
+ */
137
+ export const scanlines = {
138
+ vs: commonVS,
139
+ fs: `
140
+ precision mediump float;
141
+ varying vec2 vUV;
142
+ uniform sampler2D uTexture;
143
+ uniform vec2 uResolution;
144
+ uniform float uIntensity; // 0-1
145
+ uniform float uCount; // Number of scanlines
146
+ uniform float uSpeed; // Scroll speed
147
+ uniform float uTime;
148
+
149
+ void main() {
150
+ vec4 color = texture2D(uTexture, vUV);
151
+
152
+ // Moving scanlines
153
+ float y = vUV.y + uTime * uSpeed;
154
+ float scanline = sin(y * uCount * 3.14159) * 0.5 + 0.5;
155
+
156
+ // Apply scanline darkening
157
+ color.rgb *= 1.0 - uIntensity * (1.0 - scanline);
158
+
159
+ gl_FragColor = color;
160
+ }
161
+ `
162
+ };
163
+
164
+ /**
165
+ * Chromatic Aberration Effect
166
+ * Color channel separation for a distorted look
167
+ */
168
+ export const chromaticAberration = {
169
+ vs: commonVS,
170
+ fs: `
171
+ precision mediump float;
172
+ varying vec2 vUV;
173
+ uniform sampler2D uTexture;
174
+ uniform float uAmount; // Separation amount
175
+ uniform vec2 uDirection; // Direction of separation
176
+
177
+ void main() {
178
+ vec2 dir = normalize(vUV - 0.5);
179
+ float dist = length(vUV - 0.5);
180
+
181
+ // Stronger effect towards edges
182
+ float offset = uAmount * dist * dist;
183
+
184
+ float r = texture2D(uTexture, vUV + dir * offset).r;
185
+ float g = texture2D(uTexture, vUV).g;
186
+ float b = texture2D(uTexture, vUV - dir * offset).b;
187
+
188
+ gl_FragColor = vec4(r, g, b, 1.0);
189
+ }
190
+ `
191
+ };
192
+
193
+ /**
194
+ * Posterize Effect
195
+ * Reduces color palette for a stylized look
196
+ */
197
+ export const posterize = {
198
+ vs: commonVS,
199
+ fs: `
200
+ precision mediump float;
201
+ varying vec2 vUV;
202
+ uniform sampler2D uTexture;
203
+ uniform float uLevels; // Number of color levels (2-16)
204
+
205
+ void main() {
206
+ vec4 color = texture2D(uTexture, vUV);
207
+
208
+ // Quantize each channel
209
+ float levels = max(2.0, uLevels);
210
+ color.rgb = floor(color.rgb * levels) / (levels - 1.0);
211
+
212
+ gl_FragColor = color;
213
+ }
214
+ `
215
+ };
216
+
217
+ /**
218
+ * Grayscale Effect
219
+ * Converts image to black and white
220
+ */
221
+ export const grayscale = {
222
+ vs: commonVS,
223
+ fs: `
224
+ precision mediump float;
225
+ varying vec2 vUV;
226
+ uniform sampler2D uTexture;
227
+ uniform float uIntensity; // 0-1, blend with original
228
+
229
+ void main() {
230
+ vec4 color = texture2D(uTexture, vUV);
231
+
232
+ // Luminance-weighted grayscale
233
+ float gray = dot(color.rgb, vec3(0.2126, 0.7152, 0.0722));
234
+ vec3 grayColor = vec3(gray);
235
+
236
+ // Blend with original
237
+ color.rgb = mix(color.rgb, grayColor, uIntensity);
238
+
239
+ gl_FragColor = color;
240
+ }
241
+ `
242
+ };
243
+
244
+ /**
245
+ * Sepia Effect
246
+ * Vintage brown-tinted effect
247
+ */
248
+ export const sepia = {
249
+ vs: commonVS,
250
+ fs: `
251
+ precision mediump float;
252
+ varying vec2 vUV;
253
+ uniform sampler2D uTexture;
254
+ uniform float uIntensity; // 0-1
255
+
256
+ void main() {
257
+ vec4 color = texture2D(uTexture, vUV);
258
+
259
+ // Sepia matrix
260
+ vec3 sepia;
261
+ sepia.r = dot(color.rgb, vec3(0.393, 0.769, 0.189));
262
+ sepia.g = dot(color.rgb, vec3(0.349, 0.686, 0.168));
263
+ sepia.b = dot(color.rgb, vec3(0.272, 0.534, 0.131));
264
+
265
+ color.rgb = mix(color.rgb, sepia, uIntensity);
266
+
267
+ gl_FragColor = color;
268
+ }
269
+ `
270
+ };
271
+
272
+ /**
273
+ * Thermal/Heat Vision Effect
274
+ * False color heat map effect
275
+ */
276
+ export const thermal = {
277
+ vs: commonVS,
278
+ fs: `
279
+ precision mediump float;
280
+ varying vec2 vUV;
281
+ uniform sampler2D uTexture;
282
+ uniform float uIntensity; // 0-1
283
+
284
+ vec3 heatmap(float t) {
285
+ // Cold (blue) -> warm (red) -> hot (white)
286
+ vec3 cold = vec3(0.0, 0.0, 1.0);
287
+ vec3 warm = vec3(1.0, 1.0, 0.0);
288
+ vec3 hot = vec3(1.0, 0.0, 0.0);
289
+ vec3 white = vec3(1.0, 1.0, 1.0);
290
+
291
+ if (t < 0.33) {
292
+ return mix(cold, warm, t * 3.0);
293
+ } else if (t < 0.66) {
294
+ return mix(warm, hot, (t - 0.33) * 3.0);
295
+ } else {
296
+ return mix(hot, white, (t - 0.66) * 3.0);
297
+ }
298
+ }
299
+
300
+ void main() {
301
+ vec4 color = texture2D(uTexture, vUV);
302
+
303
+ // Calculate brightness as "heat"
304
+ float heat = dot(color.rgb, vec3(0.2126, 0.7152, 0.0722));
305
+ vec3 thermal = heatmap(heat);
306
+
307
+ color.rgb = mix(color.rgb, thermal, uIntensity);
308
+
309
+ gl_FragColor = color;
310
+ }
311
+ `
312
+ };
313
+
314
+ /**
315
+ * Displacement/Wave Effect
316
+ * Water ripple or wave distortion
317
+ */
318
+ export const displacement = {
319
+ vs: commonVS,
320
+ fs: `
321
+ precision mediump float;
322
+ varying vec2 vUV;
323
+ uniform sampler2D uTexture;
324
+ uniform float uTime;
325
+ uniform float uAmplitude; // Wave height
326
+ uniform float uFrequency; // Wave frequency
327
+ uniform float uSpeed; // Wave speed
328
+ uniform int uWaveType; // 0=horizontal, 1=vertical, 2=radial
329
+
330
+ void main() {
331
+ vec2 uv = vUV;
332
+
333
+ float wave;
334
+ if (uWaveType == 0) {
335
+ // Horizontal waves
336
+ wave = sin(uv.y * uFrequency + uTime * uSpeed) * uAmplitude;
337
+ uv.x += wave;
338
+ } else if (uWaveType == 1) {
339
+ // Vertical waves
340
+ wave = sin(uv.x * uFrequency + uTime * uSpeed) * uAmplitude;
341
+ uv.y += wave;
342
+ } else {
343
+ // Radial waves
344
+ float dist = length(uv - 0.5);
345
+ wave = sin(dist * uFrequency - uTime * uSpeed) * uAmplitude;
346
+ uv += normalize(uv - 0.5) * wave * 0.1;
347
+ }
348
+
349
+ gl_FragColor = texture2D(uTexture, uv);
350
+ }
351
+ `
352
+ };
353
+
354
+ /**
355
+ * Vignette Effect
356
+ * Darkens edges of screen
357
+ */
358
+ export const vignette = {
359
+ vs: commonVS,
360
+ fs: `
361
+ precision mediump float;
362
+ varying vec2 vUV;
363
+ uniform sampler2D uTexture;
364
+ uniform float uIntensity; // 0-1
365
+ uniform float uSoftness; // Edge softness
366
+
367
+ void main() {
368
+ vec4 color = texture2D(uTexture, vUV);
369
+
370
+ float dist = length(vUV - 0.5);
371
+ float vignette = smoothstep(0.5, 0.5 - uSoftness, dist);
372
+
373
+ color.rgb *= mix(1.0, vignette, uIntensity);
374
+
375
+ gl_FragColor = color;
376
+ }
377
+ `
378
+ };
379
+
380
+ /**
381
+ * Pixelate Effect
382
+ * Reduces resolution for retro look
383
+ */
384
+ export const pixelate = {
385
+ vs: commonVS,
386
+ fs: `
387
+ precision mediump float;
388
+ varying vec2 vUV;
389
+ uniform sampler2D uTexture;
390
+ uniform vec2 uResolution;
391
+ uniform float uPixelSize; // Size of pixels
392
+
393
+ void main() {
394
+ vec2 pixelatedUV = floor(vUV * uResolution / uPixelSize) * uPixelSize / uResolution;
395
+ gl_FragColor = texture2D(uTexture, pixelatedUV);
396
+ }
397
+ `
398
+ };
399
+
400
+ /**
401
+ * Film Grain Effect
402
+ * Adds noise for a filmic look
403
+ */
404
+ export const filmGrain = {
405
+ vs: commonVS,
406
+ fs: `
407
+ precision mediump float;
408
+ varying vec2 vUV;
409
+ uniform sampler2D uTexture;
410
+ uniform float uTime;
411
+ uniform float uIntensity; // 0-1
412
+
413
+ float random(vec2 co) {
414
+ return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453);
415
+ }
416
+
417
+ void main() {
418
+ vec4 color = texture2D(uTexture, vUV);
419
+
420
+ // Generate noise
421
+ float noise = random(vUV + fract(uTime));
422
+ noise = noise * 2.0 - 1.0;
423
+
424
+ // Apply grain
425
+ color.rgb += noise * uIntensity * 0.1;
426
+
427
+ gl_FragColor = color;
428
+ }
429
+ `
430
+ };
431
+
432
+ /**
433
+ * Get all available effects
434
+ */
435
+ export const effects = {
436
+ crt,
437
+ bloom,
438
+ scanlines,
439
+ chromaticAberration,
440
+ posterize,
441
+ grayscale,
442
+ sepia,
443
+ thermal,
444
+ displacement,
445
+ vignette,
446
+ pixelate,
447
+ filmGrain
448
+ };
449
+
450
+ export default effects;
@@ -0,0 +1,222 @@
1
+ /* *\
2
+ ** ----------------------------------------------- **
3
+ ** Calliope - Pixos Game Engine **
4
+ ** ----------------------------------------------- **
5
+ ** Copyright (c) 2020-2025 - Kyle Derby MacInnis **
6
+ ** **
7
+ ** Any unauthorized distribution or transfer **
8
+ ** of this work is strictly prohibited. **
9
+ ** **
10
+ ** All Rights Reserved. **
11
+ ** ----------------------------------------------- **
12
+ \* */
13
+ export default function fs() {
14
+ return `
15
+ precision mediump int;
16
+ precision mediump float;
17
+
18
+ const float Near = 0.1;
19
+ const float Far = 50.0;
20
+
21
+ struct PointLight {
22
+ float enabled;
23
+ vec3 color;
24
+ vec3 position;
25
+ vec3 attenuation;
26
+ vec3 direction;
27
+ vec3 scatteringCoefficients;
28
+ float density;
29
+ };
30
+
31
+ float unpack(vec4 color) {
32
+ const vec4 bitShifts = vec4(1.0, 1.0 / 255.0, 1.0 / (255.0 * 255.0), 1.0 / (255.0 * 255.0 * 255.0));
33
+ return dot(color, bitShifts);
34
+ }
35
+
36
+ varying vec4 vWorldVertex;
37
+ varying vec3 vWorldNormal;
38
+ varying vec3 vTransformedNormal;
39
+ varying vec4 vPosition;
40
+ varying vec2 vTextureCoord;
41
+
42
+ varying vec3 vLighting;
43
+
44
+ uniform PointLight uLights[32];
45
+ uniform sampler2D uDepthMap;
46
+ uniform vec4 u_id;
47
+
48
+ uniform float runTransition;
49
+ uniform float useSampler;
50
+ uniform float useDiffuse;
51
+ uniform float isSelected;
52
+ uniform vec4 uColorMultiplier;
53
+ uniform sampler2D uSampler;
54
+ uniform sampler2D uDiffuseMap;
55
+
56
+ uniform vec3 uDiffuse;
57
+ uniform vec3 uSpecular;
58
+ uniform float uSpecularExponent;
59
+
60
+ uniform vec3 uLightColor;
61
+ varying vec3 vFragPos;
62
+ varying vec3 vLightDir;
63
+ varying vec3 vViewDir;
64
+
65
+ float getAttenuation(PointLight light) {
66
+ float distance_from_light;
67
+ vec3 to_light;
68
+
69
+ to_light = light.position - vPosition.xyz;
70
+ distance_from_light = length(to_light);
71
+
72
+ float attenuation = 1.0 / (
73
+ 1.0 + light.attenuation.x
74
+ + light.attenuation.y * distance_from_light
75
+ + light.attenuation.z * pow(distance_from_light, 2.0)
76
+ );
77
+ return attenuation;
78
+ }
79
+
80
+ vec3 getReflectedLightColor(vec3 color) {
81
+ vec3 reflectedLightColor = vec3(0.0);
82
+
83
+ for(int i = 0; i < 32; i++) {
84
+ if(uLights[i].enabled <= 0.5) continue;
85
+
86
+ vec3 specular_color;
87
+ vec3 diffuse_color;
88
+ vec3 to_light;
89
+ vec3 reflection;
90
+ vec3 to_camera;
91
+ float cos_angle;
92
+ float attenuation;
93
+ vec3 normal;
94
+
95
+ // Calculate a vector from the fragment location to the light source
96
+ to_light = normalize(uLights[i].position - vFragPos);
97
+ normal = normalize(vWorldNormal);
98
+
99
+ // DIFFUSE calculations
100
+ if (useSampler == 1.0) {
101
+ cos_angle = 0.67; // billboard sprites
102
+ cos_angle += dot(to_camera, to_light);
103
+ } else {
104
+ cos_angle = dot(normal, to_light);
105
+ cos_angle = clamp(cos_angle, 0.0, 1.0);
106
+ }
107
+
108
+ // Scale the color of this fragment based on its angle to the light.
109
+ diffuse_color = uLights[i].color * cos_angle;
110
+
111
+ // SPECULAR calculations
112
+ reflection = 2.0 * dot(normal, to_light) * normal - to_light;
113
+ reflection = normalize(reflection);
114
+
115
+ to_camera = normalize(vViewDir);
116
+
117
+ cos_angle = dot(reflection, to_camera);
118
+ cos_angle = clamp(cos_angle, 0.0, 1.0);
119
+ specular_color = uLights[i].color * cos_angle;
120
+
121
+ // ATTENUATION calculations
122
+ attenuation = getAttenuation(uLights[i]);
123
+
124
+ // Combine and attenuate the colors from this light source
125
+ reflectedLightColor += attenuation * (diffuse_color + specular_color);
126
+ }
127
+
128
+ return clamp(0.5 * color + reflectedLightColor, 0.0, 1.0);
129
+ }
130
+
131
+ // Diffuse Colour Calculation
132
+ vec3 calculateDiffuse() {
133
+ vec4 texelColors = texture2D(uDiffuseMap, vTextureCoord);
134
+ vec3 color = uDiffuse;
135
+ if(useDiffuse == 1.0) {
136
+ // If texture has valid data, use it multiplied by material diffuse color
137
+ if(texelColors.a > 0.01) {
138
+ color = texelColors.rgb * uDiffuse;
139
+ }
140
+ }
141
+ return color;
142
+ }
143
+
144
+ // Sampler Texture Colour Calculation
145
+ vec3 calculateSampler(vec4 texelColors) {
146
+ vec3 color = texelColors.rgb;
147
+ if(texelColors.a < 0.1) discard;
148
+ return color;
149
+ }
150
+
151
+ // linearize depth
152
+ float LinearizeDepth(float depth) {
153
+ float z = depth * 2.0 - 1.0; // back to NDC
154
+ return (2.0 * Near * Far) / (Far + Near - z * (Far - Near));
155
+ }
156
+
157
+ // fog effect based on depth
158
+ vec4 fogEffect(vec4 color4) {
159
+ float depth = LinearizeDepth(gl_FragCoord.z) / Far;
160
+ vec4 depthVec4 = vec4(vec3(pow(depth, 1.4)), 1.0);
161
+ return (color4 * (1.0 - depth)) + depthVec4;
162
+ }
163
+
164
+ // Volumetric Calculation
165
+ vec4 volumetricCalculation(vec4 color4) {
166
+ vec3 finalColor;
167
+
168
+ for(int i = 0; i < 32; i++) {
169
+ if(uLights[i].enabled <= 0.5) continue;
170
+
171
+ // Calculate the distance from the fragment to the light
172
+ float distance = length(uLights[i].position - vec3(vWorldVertex));
173
+
174
+ // directional lighting - not working atm
175
+ // if(length(uLights[i].direction) > 0.0){
176
+ // // Calculate the angle between the light direction and the fragment
177
+ // float cos_angle = dot(normalize(uLights[i].direction), normalize(vFragPos - uLights[i].position));
178
+ // // If the fragment is not within the light cone, skip this light
179
+ // if(cos_angle <= 0.0) continue;
180
+ // }
181
+
182
+ // Calculate the scattering effect
183
+ float scattering = exp(-uLights[i].density * distance);
184
+ vec3 scatteredLight = uLights[i].color * scattering * uLights[i].scatteringCoefficients;
185
+ // Combine the scattered light with the existing lighting
186
+ finalColor += scatteredLight;
187
+ }
188
+
189
+ return color4 * vec4(finalColor, 1.0);
190
+ }
191
+
192
+ void main(void) {
193
+ vec4 finalColor = vec4(0.0, 0.0, 0.0, 1.0);
194
+
195
+ if(runTransition == 1.0) {
196
+ finalColor = vec4(0.0, 0.0, 0.0, 0.0);
197
+ gl_FragColor = finalColor;
198
+ return;
199
+ }
200
+
201
+ if(useSampler == 1.0) { // sampler
202
+ vec4 texelColors = texture2D(uSampler, vTextureCoord);
203
+ vec3 color = calculateSampler(texelColors);
204
+ vec4 color4 = vec4(getReflectedLightColor(color), texelColors.a);
205
+ finalColor = volumetricCalculation(vec4(color, texelColors.a)) * fogEffect(color4);
206
+ } else { // diffuse
207
+ vec3 color = calculateDiffuse();
208
+ vec4 color4 = vec4((getReflectedLightColor(color)), 1.0);
209
+ finalColor = volumetricCalculation(vec4(color,1.0)) * fogEffect(color4);
210
+ }
211
+
212
+ // flash on selection
213
+ if(isSelected == 1.0) {
214
+ finalColor = finalColor * uColorMultiplier;
215
+ }
216
+
217
+ // gl_FragColor = vec4(vec3(u_id),1.0);
218
+
219
+ gl_FragColor = finalColor;
220
+ }
221
+ `;
222
+ }
@@ -0,0 +1,41 @@
1
+ /* *\
2
+ ** ----------------------------------------------- **
3
+ ** Calliope - Pixos Game Engine **
4
+ ** ----------------------------------------------- **
5
+ ** Copyright (c) 2020-2025 - Kyle Derby MacInnis **
6
+ ** **
7
+ ** Any unauthorized distribution or transfer **
8
+ ** of this work is strictly prohibited. **
9
+ ** **
10
+ ** All Rights Reserved. **
11
+ ** ----------------------------------------------- **
12
+ \* */
13
+
14
+ export default function() {
15
+ return `
16
+ precision mediump float;
17
+
18
+ varying vec2 vTextureCoord;
19
+ varying vec3 vColor;
20
+ varying float vAlpha;
21
+
22
+ void main(void) {
23
+ // Calculate distance from center for soft circular particles
24
+ vec2 center = vTextureCoord - vec2(0.5);
25
+ float dist = length(center) * 2.0;
26
+
27
+ // Soft falloff from center - creates a glowing effect
28
+ float softEdge = 1.0 - smoothstep(0.0, 1.0, dist);
29
+
30
+ // Apply color with soft edge and alpha fade
31
+ float alpha = softEdge * vAlpha;
32
+
33
+ // Discard fully transparent pixels for performance
34
+ if (alpha < 0.01) discard;
35
+
36
+ // Output with glow effect - slightly brighter in center
37
+ vec3 glowColor = vColor * (1.0 + (1.0 - dist) * 0.5);
38
+ gl_FragColor = vec4(glowColor, alpha);
39
+ }
40
+ `;
41
+ }