@neutrinoparticles/js-v1.1-phaser 1.0.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/CHANGELOG.md ADDED
@@ -0,0 +1,6 @@
1
+ # Changelog
2
+
3
+ ## CurrentVersion
4
+
5
+ - Initial Phaser 3 integration for the JS v1.1 export format (GPU geometry construction, data-texture renderer). Works on WebGL2 and, automatically, on WebGL1 contexts with float vertex textures — Phaser's default WebGL1 context works out of the box.
6
+ - Fixed strip texture seams: a ribbon whose atlas texture repeats along its length no longer shows a muddy "chewed" column at tile junctions when the texture has mipmaps (WebGL2).
package/README.md ADDED
@@ -0,0 +1,212 @@
1
+ # @neutrinoparticles/js-v1.1-phaser
2
+
3
+ Phaser 3 integration for [NeutrinoParticles](https://neutrinoparticles.com/) real-time particle effects (format **v1.1**).
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @neutrinoparticles/js-v1.1-phaser
9
+ ```
10
+
11
+ The core runtime (`@neutrinoparticles/js-v1.1`) is installed automatically as a dependency.
12
+
13
+ **Peer dependency:** Phaser 3.60+
14
+
15
+ ## Requirements
16
+
17
+ The v1.1 renderer reconstructs particle geometry on the GPU. It works on:
18
+
19
+ - **WebGL2** — the primary path;
20
+ - **WebGL1** (the Phaser 3 default) — supported automatically on contexts
21
+ that provide `OES_texture_float`, at least 2 vertex texture image units,
22
+ `highp` float in fragment shaders, and pass a one-time
23
+ vertex-float-texture smoke test at startup. The renderer detects the
24
+ context version and picks the path by itself — no configuration needed,
25
+ a plain `new Phaser.Game({ type: Phaser.WEBGL })` works out of the box.
26
+
27
+ On a WebGL1 context missing those capabilities, the plugin's `init` throws an
28
+ `Error` naming the missing capability (for example
29
+ `NeutrinoParticles (js-v1.1): WebGL1 context lacks OES_texture_float; WebGL2
30
+ or WebGL1 with vertex float textures is required.`).
31
+
32
+ ### WebGL2 vs WebGL1: which to use
33
+
34
+ **Prefer WebGL2 whenever it is available** — it is the faster and leaner
35
+ path. WebGL1 is a compatibility fallback for devices and embeds that cannot
36
+ create a WebGL2 context. Rough comparison of the same effect on the two
37
+ paths:
38
+
39
+ - **Rendering speed:** identical at typical particle counts (up to ~20k
40
+ live particles the difference is not measurable); on very heavy effects
41
+ (~100k live particles) WebGL1 costs roughly 10% more render time per
42
+ frame — the vertex shader does almost twice as many texture reads and
43
+ extra math to unpack data that WebGL2 reads directly.
44
+ - **GPU memory:** WebGL1 uses about 25% more per effect (an extra byte
45
+ texture carries the data WebGL1 shaders cannot decode from the float
46
+ texture).
47
+ - **Features/visuals:** identical — both paths render the same effects with
48
+ full parity (quads and ribbons).
49
+
50
+ Phaser 3 creates a **WebGL1** context by default. To run on the faster
51
+ WebGL2 path, create a WebGL2 context yourself and hand it to the game via
52
+ the `context` option — WebGL2 is a superset of WebGL1, so Phaser's own
53
+ rendering keeps working:
54
+
55
+ ```javascript
56
+ const canvas = document.createElement('canvas');
57
+ canvas.width = 800;
58
+ canvas.height = 600;
59
+ document.body.appendChild(canvas);
60
+ const gl2 = canvas.getContext('webgl2');
61
+
62
+ new Phaser.Game({
63
+ type: Phaser.WEBGL,
64
+ canvas: canvas,
65
+ context: gl2, // hand the WebGL2 context to Phaser
66
+ width: 800,
67
+ height: 600,
68
+ // ...
69
+ });
70
+ ```
71
+
72
+ ## Export Target in Editor
73
+
74
+ In the NeutrinoParticles Editor, set the export target to **JavaScript v1.1**.
75
+
76
+ Export the effect with **"For XHR Request"** format. After export you get a `.js`
77
+ file (e.g. `my_effect.js`) containing the effect model.
78
+
79
+ ## Quick Start
80
+
81
+ ```javascript
82
+ import Phaser from 'phaser'
83
+ import { GamePlugin } from '@neutrinoparticles/js-v1.1-phaser'
84
+
85
+ class GameScene extends Phaser.Scene {
86
+ constructor() {
87
+ super({ key: 'GameScene' });
88
+ }
89
+
90
+ preload() {
91
+ // Load exported effect (must be exported "For XHR Request")
92
+ this.load.neutrino('myEffect', 'export_js/my_effect.js');
93
+ }
94
+
95
+ create() {
96
+ // Get effect model from cache (created by the loader)
97
+ const effectModel = this.cache.binary.get('myEffect');
98
+
99
+ // Create effect instance
100
+ this.effect = this.add.neutrino(effectModel, {
101
+ position: [this.cameras.main.centerX, this.cameras.main.centerY, 0]
102
+ });
103
+ }
104
+ }
105
+
106
+ new Phaser.Game({
107
+ type: Phaser.WEBGL, // Phaser's default WebGL1 context works out of the box;
108
+ // see "WebGL2 vs WebGL1" above for the faster WebGL2 setup
109
+ width: 800,
110
+ height: 600,
111
+ scene: GameScene,
112
+ plugins: {
113
+ global: [{
114
+ key: 'neutrino',
115
+ plugin: GamePlugin,
116
+ start: true,
117
+ data: {
118
+ texturesBasePath: 'textures/',
119
+ generateNoise: true
120
+ }
121
+ }]
122
+ }
123
+ });
124
+ ```
125
+
126
+ For plain `<script>` tags (no bundler), reference the plugin as
127
+ `PhaserNeutrino.GamePlugin` and include the UMD builds of both
128
+ `@neutrinoparticles/js-v1.1` and `@neutrinoparticles/js-v1.1-phaser`.
129
+
130
+ ## How It Works
131
+
132
+ `scene.load.neutrino(key, url)` fetches the exported `.js` file via XHR and
133
+ creates an effect model internally. The model is then available via
134
+ `this.cache.binary.get(key)`. Use `this.add.neutrino(model, options)` to create
135
+ an effect instance that auto-updates and renders as part of the Phaser scene.
136
+
137
+ ## Instant Position Change (Teleporting)
138
+
139
+ Moving the effect via position creates a smooth trail of particles. To instantly teleport the effect without a trail:
140
+
141
+ ```javascript
142
+ effect.resetPosition({ position: [newX, newY, 0] });
143
+
144
+ // With new angle
145
+ effect.resetPosition({ position: [newX, newY, 0], angle: 45 }); // degrees
146
+ ```
147
+
148
+ ## Restart
149
+
150
+ Restart destroys all existing particles and starts the effect from scratch:
151
+
152
+ ```javascript
153
+ effect.restart({ position: [newX, newY, 0] });
154
+ ```
155
+
156
+ ## Pause
157
+
158
+ **Full pause** — all particles freeze, nothing is generated:
159
+
160
+ ```javascript
161
+ effect.pause();
162
+ effect.unpause();
163
+ ```
164
+
165
+ **Generators pause** — existing particles continue to live, but no new particles are created:
166
+
167
+ ```javascript
168
+ effect.pauseGenerators();
169
+ effect.unpauseGenerators();
170
+ ```
171
+
172
+ Set the initial pause state in the constructor:
173
+
174
+ ```javascript
175
+ import { Pause } from '@neutrinoparticles/js-v1.1-phaser'
176
+
177
+ const effect = this.add.neutrino(effectModel, {
178
+ position: [400, 300, 0],
179
+ pause: Pause.YES // starts paused
180
+ });
181
+ // ...later:
182
+ effect.unpause();
183
+ ```
184
+
185
+ ## Emitter Properties
186
+
187
+ Control exposed emitter properties at runtime. Properties are defined in Emitter Guide or Emitter Scheme in the Editor.
188
+
189
+ ```javascript
190
+ effect.setPropertyInAllEmitters('MyParticlesPerSecond', 100);
191
+ effect.setPropertyInAllEmitters('MyColor', [1.0, 0.5, 0.2]);
192
+ ```
193
+
194
+ ## Number of Particles
195
+
196
+ ```javascript
197
+ const numParticles = effect.getNumParticles();
198
+ ```
199
+
200
+ ## Common Issues
201
+
202
+ - **`Error: ... WebGL1 context lacks <capability>` at startup:** the (rare) WebGL1 context does not support the render technique — see [Requirements](#requirements). Running on a WebGL2 context (the `context` game option) lifts the requirement.
203
+ - **No particles visible:** Make sure the export target in the editor is set to JavaScript v1.1. Verify `texturesBasePath` points to the correct textures directory.
204
+ - **Turbulence not working:** Set `generateNoise: true` in the plugin config, or call the plugin's `generateNoise()` before creating effects that use noise.
205
+
206
+ ## Documentation
207
+
208
+ Full documentation at [neutrinoparticles.com](https://neutrinoparticles.com/en/docs/199).
209
+
210
+ ## License
211
+
212
+ Copyright (c) Yurii Miroshnyk. All rights reserved.
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Manages a small ring of RGBA32F WebGL textures that hold the runtime's flat
3
+ * particle data buffer. Each frame the current texture is re-uploaded (zero-copy
4
+ * from the runtime-owned Uint32Array via a Float32 view) and the ring advances,
5
+ * which avoids GPU pipeline stalls from re-uploading into a texture still in use.
6
+ *
7
+ * Unlike the pixi7 adapter this owns raw GL textures directly (no PIXI texture
8
+ * system), so the exact same class works for both the PIXI v8 and Phaser
9
+ * integrations, which both do their own raw WebGL2 draw.
10
+ */
11
+ export declare class DataTextureManager {
12
+ readonly textureWidth: number;
13
+ readonly textureHeight: number;
14
+ private readonly _gl;
15
+ private readonly _floatView;
16
+ private _textures;
17
+ private _currentIndex;
18
+ /**
19
+ * @param gl - WebGL2 context (from the host renderer)
20
+ * @param data - Uint32Array from the runtime. A Float32Array view over the
21
+ * same buffer is uploaded as RGBA32F — bit patterns (incl. NaN/Inf) pass
22
+ * through unchanged.
23
+ * @param textureWidth - from runtime (system.dataTextureWidth)
24
+ * @param textureHeight - from runtime (system.dataTextureHeight)
25
+ */
26
+ constructor(gl: WebGL2RenderingContext, data: Uint32Array, textureWidth: number, textureHeight: number);
27
+ get currentTexture(): WebGLTexture;
28
+ /** Bind the current texture to a unit and upload the latest particle data. */
29
+ uploadAndBind(unit: number): void;
30
+ advance(): void;
31
+ destroy(): void;
32
+ }
@@ -0,0 +1,76 @@
1
+ import Phaser from 'phaser';
2
+ import { Pause, Vec2, Vec3 } from './types';
3
+ import { GamePlugin } from './GamePlugin';
4
+ import { EffectModel } from './EffectModel';
5
+ import { NeutrinoSystem } from './types';
6
+ export interface EffectOptions {
7
+ position?: Vec3;
8
+ angle?: number;
9
+ scale?: number;
10
+ pause?: Pause;
11
+ generatorsPaused?: boolean;
12
+ }
13
+ /**
14
+ * A NeutrinoParticles effect on a Phaser scene (JS v1.1 runtime).
15
+ *
16
+ * Simulation runs in preUpdate(); rendering happens in renderWebGL() via a raw
17
+ * WebGL data-texture draw (WebGL2 or the WebGL1 variant, chosen by the shared
18
+ * NeutrinoContext). Phaser's active pipeline is flushed before and rebound
19
+ * after the draw so its state machine stays consistent.
20
+ */
21
+ export declare class Effect extends Phaser.GameObjects.GameObject {
22
+ gamePlugin: GamePlugin;
23
+ effectModel: EffectModel;
24
+ effect: NeutrinoSystem | null;
25
+ x: number;
26
+ y: number;
27
+ z: number;
28
+ angle: number;
29
+ rotation: number;
30
+ scaleX: number;
31
+ scaleY: number;
32
+ scrollFactorX: number;
33
+ scrollFactorY: number;
34
+ alpha: number;
35
+ depth: number;
36
+ blendMode: number;
37
+ private _dataTextureManager;
38
+ private _worldPosition;
39
+ private _worldScaledPosition;
40
+ private _worldRotation;
41
+ private _worldScale;
42
+ private _tempMatrix1;
43
+ private _tempMatrix2;
44
+ private _unpauseOnUpdateRender;
45
+ private _glTexturesScratch;
46
+ constructor(effectModel: EffectModel, scene: Phaser.Scene, options?: EffectOptions);
47
+ get ready(): boolean;
48
+ preUpdate(_time: number, ms: number): void;
49
+ renderWebGL(renderer: Phaser.Renderer.WebGL.WebGLRenderer, _src: Effect, camera: Phaser.Cameras.Scene2D.Camera): void;
50
+ restart(options?: {
51
+ position?: Vec3;
52
+ angle?: number;
53
+ rotation?: number;
54
+ }): void;
55
+ resetPosition(options?: {
56
+ position?: Vec3;
57
+ angle?: number;
58
+ rotation?: number;
59
+ }): void;
60
+ pause(): void;
61
+ unpause(): void;
62
+ get paused(): boolean;
63
+ pauseGenerators(): void;
64
+ unpauseGenerators(): void;
65
+ get generatorsPaused(): boolean;
66
+ setPropertyInAllEmitters(name: string, value: Vec3 | Vec2 | number): void;
67
+ getNumParticles(): number;
68
+ setScrollFactor(x: number, y?: number): this;
69
+ setAlpha(topLeft?: number, _topRight?: number, _bottomLeft?: number, _bottomRight?: number): this;
70
+ destroy(fromScene?: boolean): void;
71
+ private _applyTransformOptions;
72
+ private _updateWorldTransform;
73
+ private _renderPosition;
74
+ private _renderRotation;
75
+ private _checkUnpauseOnUpdateRender;
76
+ }
@@ -0,0 +1,27 @@
1
+ import Phaser from 'phaser';
2
+ import { GamePlugin } from './GamePlugin';
3
+ import { NeutrinoEffectModel, NeutrinoSubRect } from './types';
4
+ /**
5
+ * Wraps a neutrinoparticles.js v1.1 effect model for Phaser. Loads textures from
6
+ * standalone files or atlases via Phaser's loader, and computes atlas UV remaps
7
+ * as plain {x,y,width,height} objects (the v1.1 renderer reads them directly).
8
+ */
9
+ export declare class EffectModel {
10
+ readonly gamePlugin: GamePlugin;
11
+ readonly scene: Phaser.Scene;
12
+ readonly effectModel: NeutrinoEffectModel;
13
+ textureFrames: Array<Phaser.Textures.Frame | null>;
14
+ texturesRemap: Array<NeutrinoSubRect | null>;
15
+ private _numTexturesToLoadLeft;
16
+ constructor(scene: Phaser.Scene, scriptText: string, options?: {
17
+ atlases?: string[];
18
+ });
19
+ get ready(): boolean;
20
+ /** Raw WebGL texture handle for a given texture index (or null). */
21
+ glTexture(index: number): WebGLTexture | null;
22
+ private _startLoadTextures;
23
+ private _findFrameInAtlases;
24
+ private _onTextureLoaded;
25
+ private _fullCover;
26
+ private _initTexturesRemapIfNeeded;
27
+ }
package/dist/File.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ import Phaser from 'phaser';
2
+ export interface NeutrinoFileConfig {
3
+ key: string;
4
+ url: string;
5
+ options?: {
6
+ atlases?: string[];
7
+ };
8
+ xhrSettings?: Phaser.Types.Loader.XHRSettingsObject;
9
+ }
10
+ /**
11
+ * Custom Phaser loader file type for NeutrinoParticles effects (.js export).
12
+ * Parses the exported source into an {@link EffectModel} stored in the binary cache.
13
+ */
14
+ export declare class NeutrinoFile extends Phaser.Loader.File {
15
+ private _options?;
16
+ constructor(loader: Phaser.Loader.LoaderPlugin, config: NeutrinoFileConfig);
17
+ onProcess(): void;
18
+ }
@@ -0,0 +1,27 @@
1
+ import Phaser from 'phaser';
2
+ import { NeutrinoContext } from './NeutrinoContext';
3
+ export interface GamePluginOptions {
4
+ texturesBasePath?: string;
5
+ generateNoise?: boolean;
6
+ }
7
+ /**
8
+ * Main NeutrinoParticles plugin for Phaser (JS v1.1 runtime).
9
+ *
10
+ * Owns the shared {@link NeutrinoContext} (shader/index-buffer GL state) and
11
+ * the neutrino simulation context, and manages noise generation. A WebGL
12
+ * renderer is required — the v1.1 data-texture renderer has no Canvas
13
+ * fallback. Both WebGL2 and WebGL1 contexts are supported; the render path is
14
+ * selected automatically by {@link NeutrinoContext}.
15
+ */
16
+ export declare class GamePlugin extends Phaser.Plugins.BasePlugin {
17
+ game: Phaser.Game;
18
+ neutrino: any;
19
+ ctx: NeutrinoContext;
20
+ texturesBasePath: string;
21
+ init(options?: GamePluginOptions): void;
22
+ start(): void;
23
+ stop(): void;
24
+ destroy(): void;
25
+ loadNoise(path: string, success?: () => void, fail?: () => void): void;
26
+ generateNoise(): void;
27
+ }
@@ -0,0 +1,88 @@
1
+ import { NeutrinoRuntimeContext as INeutrinoContext } from './types';
2
+ /**
3
+ * Engine-agnostic WebGL state for the NeutrinoParticles data-texture renderer:
4
+ * the shader program, a static quad index buffer + VAO (WebGL2) or aId vertex
5
+ * stream (WebGL1), and uniform locations.
6
+ *
7
+ * This is the Phaser counterpart of the pixi adapters' Context, but it holds no
8
+ * reference to a host renderer — it works purely off a WebGL context. Owned by
9
+ * {@link GamePlugin} and shared by every effect in the game.
10
+ *
11
+ * The render path is selected automatically (TDD_js-v1.1-webgl1.md): a WebGL2
12
+ * context uses the texelFetch/gl_VertexID renderer unchanged; a WebGL1 context
13
+ * with the required capabilities (probed here, §4.2) uses the two-texture +
14
+ * static-aId variant; anything else throws a capability-specific Error.
15
+ */
16
+ export declare class NeutrinoContext {
17
+ readonly neutrino: INeutrinoContext;
18
+ readonly gl: WebGL2RenderingContext;
19
+ private _shaderProgram;
20
+ private _indexBuffer;
21
+ private _dummyVB;
22
+ private _indexBufferCapacity;
23
+ private _vao;
24
+ private _isWebGL1;
25
+ private _maxBatchTextures;
26
+ private _hasElementIndexUint;
27
+ private _vaoExt;
28
+ private _aIdBuffer;
29
+ private _aIdLocation;
30
+ static readonly MAX_BATCH_TEXTURES = 8;
31
+ private _uDataTexture;
32
+ private _uDataTextureWidth;
33
+ private _uMetaTexture;
34
+ private _uDataTexSize;
35
+ private _uCameraRight;
36
+ private _uCameraUp;
37
+ private _uCameraDir;
38
+ private _uViewProjMatrix;
39
+ private _uModelMatrix;
40
+ private _uViewportAspect;
41
+ private _uWorldAlpha;
42
+ private _uTextures;
43
+ private _uTexRemaps;
44
+ private _noiseInitialized;
45
+ constructor(gl: WebGL2RenderingContext, neutrino: INeutrinoContext);
46
+ initializeNoise(path: string, success: () => void, fail: () => void): void;
47
+ generateNoise(): void;
48
+ get shaderProgram(): WebGLProgram;
49
+ get isWebGL1(): boolean;
50
+ /**
51
+ * Textures usable in one batch. 8 on WebGL2; on WebGL1 reduced when the
52
+ * combined texture-unit budget is tight (the vertex stage takes 2 units).
53
+ * A lower cap only produces more batches, never wrong output.
54
+ */
55
+ get maxBatchTextures(): number;
56
+ get uDataTexture(): WebGLUniformLocation | null;
57
+ get uDataTextureWidth(): WebGLUniformLocation | null;
58
+ get uMetaTexture(): WebGLUniformLocation | null;
59
+ get uDataTexSize(): WebGLUniformLocation | null;
60
+ get uCameraRight(): WebGLUniformLocation | null;
61
+ get uCameraUp(): WebGLUniformLocation | null;
62
+ get uCameraDir(): WebGLUniformLocation | null;
63
+ get uViewProjMatrix(): WebGLUniformLocation | null;
64
+ get uModelMatrix(): WebGLUniformLocation | null;
65
+ get uViewportAspect(): WebGLUniformLocation | null;
66
+ get uWorldAlpha(): WebGLUniformLocation | null;
67
+ get uTextures(): (WebGLUniformLocation | null)[];
68
+ get uTexRemaps(): (WebGLUniformLocation | null)[];
69
+ ensureIndexBuffer(maxParticles: number): void;
70
+ get vao(): WebGLVertexArrayObject;
71
+ get indexBuffer(): WebGLBuffer;
72
+ get aIdBuffer(): WebGLBuffer;
73
+ get aIdLocation(): number;
74
+ get indexType(): number;
75
+ /** Unbind any VAO (incl. OES on WebGL1) before raw attribute setup. */
76
+ unbindVao(): void;
77
+ destroy(): void;
78
+ private _probeWebGL1Capabilities;
79
+ /**
80
+ * Compile/link alone does not prove vertex texture fetch works on a
81
+ * driver — some fail only at draw time. One-time 1×1 smoke draw: a point
82
+ * whose color is produced by sampling a float and a byte texture in the
83
+ * vertex shader, rendered into a 1×1 RGBA8 FBO and read back.
84
+ */
85
+ private _smokeTestVertexTextureFetch;
86
+ private _initShader;
87
+ private _compileShader;
88
+ }
@@ -0,0 +1,54 @@
1
+ import { NeutrinoContext } from "./NeutrinoContext";
2
+ import { DataTextureManager } from "./DataTextureManager";
3
+ import { DataTextureManagerGL1 } from "./gl1/DataTextureManagerGL1";
4
+ import { NeutrinoSubRect } from "./types";
5
+ export interface RenderParams {
6
+ /** Effect world transform (2x3) already including world scale. */
7
+ model: {
8
+ a: number;
9
+ b: number;
10
+ c: number;
11
+ d: number;
12
+ tx: number;
13
+ ty: number;
14
+ };
15
+ /** Canvas pixel dimensions, for the ortho projection. */
16
+ viewportWidth: number;
17
+ viewportHeight: number;
18
+ /** Camera scroll (subtracted in pixel space) and zoom. */
19
+ scrollX: number;
20
+ scrollY: number;
21
+ zoom: number;
22
+ /** Host scene-graph world alpha, multiplied into each particle's alpha. */
23
+ worldAlpha: number;
24
+ /** Per-particle GL textures (one per render-style texture index). */
25
+ glTextures: (WebGLTexture | null)[];
26
+ remaps: Array<NeutrinoSubRect | null>;
27
+ renderStyles: Array<{
28
+ materialIndex: number;
29
+ textureIndices: number[];
30
+ }>;
31
+ materials: number[];
32
+ }
33
+ /**
34
+ * Raw WebGL data-texture renderer for the Phaser integration.
35
+ *
36
+ * Mirrors the pixi adapters: builds blend-mode batches (≤maxBatchTextures each),
37
+ * patches the per-particle texture-slot byte, uploads the data texture and draws
38
+ * each batch with gl.drawElements. On WebGL1 the u32-packed fields travel via an
39
+ * RGBA8 meta texture and the slot patch goes there instead of the float buffer
40
+ * (TDD_js-v1.1-webgl1.md §4.3/§4.6). Because Phaser owns the GL state machine,
41
+ * the caller is responsible for flushing Phaser's batch and restoring pipeline
42
+ * state around a render() call (see Effect.renderWebGL).
43
+ */
44
+ export declare class NeutrinoRenderer {
45
+ private _orthoMatrix;
46
+ private _modelMatrix;
47
+ private _texSlotMap;
48
+ private _batchPool;
49
+ private _batchCount;
50
+ constructor();
51
+ render(ctx: NeutrinoContext, dtm: DataTextureManager | DataTextureManagerGL1, dataView: DataView, dataUint32: Uint32Array, instructions: any[], numParticles: number, params: RenderParams): void;
52
+ private _resolveBlend;
53
+ private _applyBlendMode;
54
+ }
@@ -0,0 +1,65 @@
1
+ /**
2
+ * The class implements perspective projection transformation.
3
+ *
4
+ * @example
5
+ * // Create effect instance using loaded model
6
+ * let effect = new PIXINeutrino.Effect(resources.effectModel, {
7
+ * position: [400, 300, 0],
8
+ * projection: new PIXINeutrino.PerspectiveProjection(60.0)
9
+ * });
10
+ *
11
+ * @param {number} [horizontalAngle] Horizontal angle of the perspective projection in degrees.
12
+ */
13
+ import { Vec2, Vec3 } from "./types";
14
+ export interface ScreenFrame {
15
+ x: number;
16
+ y: number;
17
+ width: number;
18
+ height: number;
19
+ }
20
+ export declare class PerspectiveProjection {
21
+ private _angleTan;
22
+ private _screenWidth;
23
+ private _screenPosX;
24
+ private _screenPosY;
25
+ private _z;
26
+ private _near;
27
+ set horizontalAngle(value: number);
28
+ constructor(horizontalAngle: number);
29
+ /**
30
+ * Changes horizontal angle of the projection.
31
+ *
32
+ * @param {number} value Angle in degrees.
33
+ */
34
+ /**
35
+ * Sets rendering frame for the projection.
36
+ *
37
+ * This method shouldn't be called manually when the class is used with effects. It is called
38
+ * on every render call for each effect automatically.
39
+ * @param {ScreenFrame} frame Rendering frame.
40
+ */
41
+ setScreenFrame(frame: ScreenFrame): void;
42
+ /**
43
+ * Transforms 3D point accordingly to the projection.
44
+ *
45
+ * Basically, point's position X and Y components are simply scaled dependently on Z position. The method
46
+ * is used in WebGL and Canvas rendering.
47
+ *
48
+ * @param {Array} out [x, y] Transformed position.
49
+ * @param {Array} pos [x, y, z] Untransformed input vertex position.
50
+ * @returns false, if a particle is on the back side of the camera and should be discarded. Otherwise - true.
51
+ */
52
+ transformPosition(out: Vec2, pos: Vec3): boolean;
53
+ /**
54
+ * Transforms 2D size of a particle accordingly to the projection.
55
+ *
56
+ * Basically, size is simply scaled dependently on Z position of a particle. The method is used
57
+ * only in Canvas rendering.
58
+ *
59
+ * @param {Array} outSize [width, height] Transformed size.
60
+ * @param {Array} pos [x, y, z] Untransformed particle position.
61
+ * @param {Array} size [width, height] Untransformed size.
62
+ */
63
+ transformSize(outSize: Vec2, pos: Vec3, size: Vec2): void;
64
+ _getScale(pos: Vec3): number;
65
+ }
@@ -0,0 +1,23 @@
1
+ import { MetaTextureManager } from "./MetaTextureManager";
2
+ export declare class DataTextureManagerGL1 {
3
+ readonly textureWidth: number;
4
+ readonly textureHeight: number;
5
+ readonly meta: MetaTextureManager;
6
+ private readonly _gl;
7
+ private readonly _floatView;
8
+ private _dataTextures;
9
+ private _metaTextures;
10
+ private _currentIndex;
11
+ constructor(gl: WebGLRenderingContext, data: Uint32Array, textureWidth: number, textureHeight: number);
12
+ get currentDataTexture(): WebGLTexture;
13
+ get currentMetaTexture(): WebGLTexture;
14
+ /**
15
+ * Upload the rows covering `numParticles` into the current ring textures,
16
+ * leaving them bound to `dataUnit` / `metaUnit`. The caller invalidates
17
+ * PIXI's bound-texture bookkeeping for those units.
18
+ */
19
+ upload(numParticles: number, dataUnit: number, metaUnit: number): void;
20
+ advance(): void;
21
+ destroy(): void;
22
+ private _createTexture;
23
+ }
@@ -0,0 +1,9 @@
1
+ export declare class MetaTextureManager {
2
+ readonly bytes: Uint8Array;
3
+ private readonly _u32;
4
+ constructor(textureWidth: number, textureHeight: number);
5
+ /** Repack the packed-u32 record fields for the first `numParticles` records. */
6
+ build(dataUint32: Uint32Array, numParticles: number): void;
7
+ /** Write the batch texture slot into byte0 of M0 (flags) per particle. */
8
+ patchSlot(startParticle: number, count: number, slot: number): void;
9
+ }