littlejsengine 1.19.3 → 1.20.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.
- package/FAQ.md +841 -820
- package/README.md +29 -25
- package/dist/littlejs.d.ts +2455 -935
- package/dist/littlejs.esm.js +30344 -21110
- package/dist/littlejs.esm.min.js +4 -3
- package/dist/littlejs.js +30259 -21052
- package/dist/littlejs.min.js +2 -2
- package/dist/littlejs.release.js +26567 -20455
- package/package.json +10 -5
- package/plugins/audioEffects.js +28 -24
- package/plugins/box2d.js +2516 -2073
- package/plugins/drawUtilities.js +206 -31
- package/plugins/gltf.js +740 -0
- package/plugins/jsconfig.json +19 -0
- package/plugins/lightSystem.js +719 -332
- package/plugins/math3d.js +58 -17
- package/plugins/medalSystem.js +326 -280
- package/plugins/newgrounds.js +400 -199
- package/plugins/pathFinder.js +208 -175
- package/plugins/pluginExport.js +15 -0
- package/plugins/postProcess.js +56 -13
- package/plugins/render3d.js +1643 -1577
- package/plugins/render3dDebug.js +109 -0
- package/plugins/render3dExtras.js +1754 -0
- package/plugins/render3dVoxels.js +502 -0
- package/plugins/textureSheet.js +496 -458
- package/plugins/threejs.js +183 -163
- package/plugins/tweakables.js +411 -0
- package/plugins/tweenSystem.js +263 -145
- package/plugins/uiSystem.js +2024 -1687
- package/plugins/zzfxm.js +159 -159
- package/src/engine.js +191 -75
- package/src/engineAudio.js +229 -125
- package/src/engineBuild.mjs +289 -256
- package/src/engineDebug.js +912 -742
- package/src/engineDraw.js +295 -193
- package/src/engineEditor.js +2431 -0
- package/src/engineExport.js +12 -0
- package/src/engineInput.js +1462 -1293
- package/src/engineMath.js +1274 -1252
- package/src/engineObject.js +194 -80
- package/src/engineParticles.js +583 -532
- package/src/engineRelease.js +67 -45
- package/src/engineSettings.js +77 -29
- package/src/engineTileLayer.js +995 -741
- package/src/engineUtilities.js +19 -13
- package/src/engineWebGL.js +239 -82
- package/src/jsconfig.json +17 -13
- package/plugins/box2d.wasm.js +0 -630
- package/plugins/box2d.wasm.wasm +0 -0
package/plugins/postProcess.js
CHANGED
|
@@ -24,20 +24,24 @@ let postProcess;
|
|
|
24
24
|
* Post Process Plugin - Applies a full screen shader to the rendered output
|
|
25
25
|
* - Create it after any plugin that draws, since plugins render in the order they are made
|
|
26
26
|
* and this one shades what is on the canvas when its turn comes
|
|
27
|
+
* - It runs after gameRenderPost, so a HUD drawn there with WebGL is shaded (and bloomed) too;
|
|
28
|
+
* draw the HUD with useWebGL=false (the main canvas) or from a plugin created after this one
|
|
27
29
|
* @memberof PostProcess
|
|
28
30
|
*/
|
|
29
31
|
class PostProcessPlugin
|
|
30
32
|
{
|
|
31
33
|
/** Create global post processing shader
|
|
32
|
-
* @param {string} shaderCode
|
|
34
|
+
* @param {string} [shaderCode] - Shadertoy style mainImage code, a pass-through when left out
|
|
33
35
|
* @param {boolean} [includeMainCanvas] - combine mainCanvas onto glCanvas
|
|
34
|
-
* @param {boolean} [feedbackTexture] -
|
|
36
|
+
* @param {boolean} [feedbackTexture] - also pass the shader's own output from the previous frame as iChannel1,
|
|
37
|
+
* for trails and echoes; iChannel0 is still the frame just drawn
|
|
35
38
|
* @example
|
|
36
39
|
* // create the post process plugin object
|
|
37
40
|
* new PostProcessPlugin(shaderCode);
|
|
38
41
|
*/
|
|
39
42
|
constructor(shaderCode, includeMainCanvas=false, feedbackTexture=false)
|
|
40
43
|
{
|
|
44
|
+
ASSERT(engineInitialized || headlessMode, 'create the plugin after engineInit, e.g. in gameInit');
|
|
41
45
|
ASSERT(!postProcess, 'Post process already initialized');
|
|
42
46
|
ASSERT(!(includeMainCanvas && feedbackTexture), 'Post process cannot both include main canvas and use feedback texture');
|
|
43
47
|
postProcess = this;
|
|
@@ -51,6 +55,9 @@ class PostProcessPlugin
|
|
|
51
55
|
/** @property {WebGLTexture|undefined} - Texture for post processing
|
|
52
56
|
* @type {WebGLTexture|undefined} */
|
|
53
57
|
this.texture = undefined;
|
|
58
|
+
/** @property {WebGLTexture|undefined} - The previous frame's output, iChannel1, when feedbackTexture is set
|
|
59
|
+
* @type {WebGLTexture|undefined} */
|
|
60
|
+
this.feedbackTexture = undefined;
|
|
54
61
|
/** @property {WebGLVertexArrayObject|undefined} - Vertex array object
|
|
55
62
|
* @type {WebGLVertexArrayObject|undefined} */
|
|
56
63
|
this.vao = undefined;
|
|
@@ -68,7 +75,15 @@ class PostProcessPlugin
|
|
|
68
75
|
return;
|
|
69
76
|
}
|
|
70
77
|
|
|
71
|
-
// create resources
|
|
78
|
+
// create resources, the feedback starting black, as if the frame before the first were empty
|
|
79
|
+
if (feedbackTexture)
|
|
80
|
+
{
|
|
81
|
+
postProcess.feedbackTexture = glCreateTexture();
|
|
82
|
+
glContext.bindTexture(glContext.TEXTURE_2D, postProcess.feedbackTexture);
|
|
83
|
+
glContext.texImage2D(glContext.TEXTURE_2D, 0, glContext.RGBA, 1, 1, 0, glContext.RGBA,
|
|
84
|
+
glContext.UNSIGNED_BYTE, new Uint8Array([0, 0, 0, 255]));
|
|
85
|
+
glContext.bindTexture(glContext.TEXTURE_2D, glActiveTexture);
|
|
86
|
+
}
|
|
72
87
|
postProcess.texture = glCreateTexture();
|
|
73
88
|
postProcess.shader = glCreateProgram(
|
|
74
89
|
'#version 300 es\n' + // specify GLSL ES version
|
|
@@ -81,6 +96,7 @@ class PostProcessPlugin
|
|
|
81
96
|
'#version 300 es\n' + // specify GLSL ES version
|
|
82
97
|
'precision highp float;'+ // use highp for accuracy
|
|
83
98
|
'uniform sampler2D iChannel0;'+ // input texture
|
|
99
|
+
'uniform sampler2D iChannel1;'+ // the previous frame's output, when feedbackTexture is set
|
|
84
100
|
'uniform vec3 iResolution;'+ // size of output texture
|
|
85
101
|
'uniform float iTime;'+ // time
|
|
86
102
|
'out vec4 c;'+ // out color
|
|
@@ -106,6 +122,7 @@ class PostProcessPlugin
|
|
|
106
122
|
{
|
|
107
123
|
postProcess.shader = undefined;
|
|
108
124
|
postProcess.texture = undefined;
|
|
125
|
+
postProcess.feedbackTexture = undefined;
|
|
109
126
|
LOG('PostProcessPlugin: WebGL context lost');
|
|
110
127
|
}
|
|
111
128
|
function postProcessContextRestored()
|
|
@@ -117,6 +134,13 @@ class PostProcessPlugin
|
|
|
117
134
|
{
|
|
118
135
|
if (headlessMode || !glEnable) return;
|
|
119
136
|
|
|
137
|
+
// made now if WebGL was off when the plugin was made, or when a lost context came back
|
|
138
|
+
if (!postProcess.shader)
|
|
139
|
+
{
|
|
140
|
+
if (glContext.isContextLost()) return;
|
|
141
|
+
initPostProcess();
|
|
142
|
+
}
|
|
143
|
+
|
|
120
144
|
// clear out the buffer
|
|
121
145
|
glFlush();
|
|
122
146
|
|
|
@@ -128,6 +152,9 @@ class PostProcessPlugin
|
|
|
128
152
|
glContext.useProgram(postProcess.shader);
|
|
129
153
|
glContext.bindVertexArray(postProcess.vao);
|
|
130
154
|
glContext.pixelStorei(glContext.UNPACK_FLIP_Y_WEBGL, true);
|
|
155
|
+
// upload the canvas the way it shows, premultiplied, since the shader writes full alpha; unpremultiplied
|
|
156
|
+
// a see-through pixel would come out at its full brightness instead of faded over the background
|
|
157
|
+
glContext.pixelStorei(glContext.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
|
|
131
158
|
glContext.disable(glContext.BLEND);
|
|
132
159
|
|
|
133
160
|
// setup texture
|
|
@@ -141,37 +168,52 @@ class PostProcessPlugin
|
|
|
141
168
|
workCanvas.height = mainCanvas.height;
|
|
142
169
|
glCopyToContext(workContext);
|
|
143
170
|
workContext.drawImage(mainCanvas, 0, 0);
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
//
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
mainContext.
|
|
171
|
+
// clear the main canvas with clearRect, resizing it would also
|
|
172
|
+
// reset the context state (smoothing, line caps) for anything
|
|
173
|
+
// drawn after this and reallocate the canvas every frame
|
|
174
|
+
mainContext.save();
|
|
175
|
+
mainContext.setTransform(1, 0, 0, 1, 0, 0);
|
|
176
|
+
mainContext.clearRect(0, 0, mainCanvas.width, mainCanvas.height);
|
|
177
|
+
mainContext.restore();
|
|
150
178
|
|
|
151
179
|
// copy work canvas to texture
|
|
152
180
|
glContext.texImage2D(glContext.TEXTURE_2D, 0, glContext.RGBA, glContext.RGBA, glContext.UNSIGNED_BYTE, workCanvas);
|
|
153
181
|
}
|
|
154
|
-
else
|
|
182
|
+
else
|
|
155
183
|
{
|
|
156
184
|
// copy glCanvas to texture
|
|
157
185
|
glContext.texImage2D(glContext.TEXTURE_2D, 0, glContext.RGBA, glContext.RGBA, glContext.UNSIGNED_BYTE, glCanvas);
|
|
158
186
|
}
|
|
159
187
|
|
|
188
|
+
// the previous frame's output, on the second texture unit
|
|
189
|
+
if (feedbackTexture)
|
|
190
|
+
{
|
|
191
|
+
glContext.activeTexture(glContext.TEXTURE1);
|
|
192
|
+
glContext.bindTexture(glContext.TEXTURE_2D, postProcess.feedbackTexture);
|
|
193
|
+
}
|
|
194
|
+
|
|
160
195
|
// set uniforms and draw
|
|
161
|
-
const uniformLocation = (name)=>
|
|
196
|
+
const uniformLocation = (name)=>glUniformLocation(postProcess.shader, name);
|
|
162
197
|
glContext.uniform1i(uniformLocation('iChannel0'), 0);
|
|
198
|
+
glContext.uniform1i(uniformLocation('iChannel1'), 1);
|
|
163
199
|
glContext.uniform1f(uniformLocation('iTime'), time);
|
|
164
200
|
glContext.uniform3f(uniformLocation('iResolution'), mainCanvas.width, mainCanvas.height, 1);
|
|
165
201
|
glContext.drawArrays(glContext.TRIANGLE_STRIP, 0, 4);
|
|
166
202
|
|
|
167
203
|
if (feedbackTexture)
|
|
168
204
|
{
|
|
169
|
-
//
|
|
205
|
+
// keep this frame's output for the next one, then hand the first texture unit back to the engine
|
|
170
206
|
glContext.texImage2D(glContext.TEXTURE_2D, 0, glContext.RGBA, glContext.RGBA, glContext.UNSIGNED_BYTE, glCanvas);
|
|
207
|
+
glContext.activeTexture(glContext.TEXTURE0);
|
|
171
208
|
}
|
|
172
209
|
|
|
173
|
-
// restore
|
|
210
|
+
// restore defaults so subsequent dynamic texture uploads aren't flipped or premultiplied
|
|
174
211
|
glContext.pixelStorei(glContext.UNPACK_FLIP_Y_WEBGL, false);
|
|
212
|
+
glContext.pixelStorei(glContext.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
|
|
213
|
+
|
|
214
|
+
// bind back the texture the 2D batch thinks is bound, a plugin drawing after this one uses it
|
|
215
|
+
if (glActiveTexture)
|
|
216
|
+
glContext.bindTexture(glContext.TEXTURE_2D, glActiveTexture);
|
|
175
217
|
|
|
176
218
|
// force it to set instanced mode
|
|
177
219
|
glSetInstancedMode(true);
|
|
@@ -232,6 +274,7 @@ function postProcessBloomShader(threshold=.6, strength=1, size=6)
|
|
|
232
274
|
* @param {number} [strength] - How much glow to add
|
|
233
275
|
* @param {number} [size] - How far the glow spreads in pixels
|
|
234
276
|
* @param {boolean} [includeMainCanvas] - Glow the 2D canvas too, off by default so HUD text stays crisp
|
|
277
|
+
* (a HUD drawn with WebGL in gameRenderPost glows either way, draw it with useWebGL=false)
|
|
235
278
|
* @return {PostProcessPlugin}
|
|
236
279
|
* @memberof PostProcess
|
|
237
280
|
* @example
|