bloody-engine 1.1.4 → 1.1.6

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
@@ -6,11 +6,14 @@ A WebGL-based 2.5D graphics engine for isometric rendering on Node.js, written i
6
6
 
7
7
  - **Structure of Arrays (SoA)** - Entity storage with typed arrays for zero-copy GPU transfers and cache-friendly access
8
8
  - **2.5D Rendering** - Optimized for isometric and dimetric projections with depth sorting
9
+ - **Instanced Rendering** - WebGL2 GPU instancing for rendering thousands of identical meshes in a single draw call
10
+ - **Ring Buffer Streaming** - Triple-buffered GPU streaming for zero-copy dynamic updates
9
11
  - **Server-Side Rendering** - Headless WebGL rendering on Node.js using `gl` and `@kmamal/sdl`
10
12
  - **Batch Rendering** - Efficient sprite batching with GPU-accelerated transformations
11
13
  - **Persistent Buffer Mapping** - WebGL2 zero-copy GPU transfers for maximum performance
12
14
  - **Resource Management** - Unified asset loading pipeline for textures and shaders
13
15
  - **Input System** - Command queue pattern supporting SDL and network input sources
16
+ - **Collision Detection** - Spatial hashing with O(N) collision detection and configurable responses
14
17
  - **Networking** - Client-side prediction, server reconciliation, and state synchronization
15
18
  - **Simulation** - Pure game logic simulation system with entity management
16
19
  - **Game Loop** - Fixed timestep ticker for deterministic game logic
@@ -75,6 +78,9 @@ Bloody Engine uses different coordinate systems for different purposes. Mixing t
75
78
  |-------|-------------|
76
79
  | [BatchRenderer](src/rendering/batch-renderer.ts) | Generic quad batch rendering |
77
80
  | [SpriteBatchRenderer](src/rendering/batch-renderer.ts) | Sprite-specific batch renderer with depth sorting |
81
+ | [InstancedRenderer](src/rendering/instanced-renderer.ts) | WebGL2 GPU instancing for thousands of instances in single draw call |
82
+ | [HybridRenderer](src/rendering/hybrid-renderer.ts) | Automatic detection between instanced and batch rendering |
83
+ | [RingBuffer](src/rendering/ring-buffer.ts) | Triple-buffered GPU ring buffer for zero-copy streaming |
78
84
  | [ProjectionConfig](src/rendering/projection.ts) | Isometric/dimetric projection utilities |
79
85
  | [SpatialHash](src/rendering/spatial-hash.ts) | Spatial partitioning for efficient queries |
80
86
 
@@ -203,6 +209,108 @@ batchRenderer.render(camera);
203
209
  device.present();
204
210
  ```
205
211
 
212
+ ### Instanced Rendering (WebGL2)
213
+
214
+ For rendering thousands of identical meshes (floor tiles, sprites, particles), use the instanced renderer for massive performance gains:
215
+
216
+ ```typescript
217
+ import {
218
+ HybridRenderer,
219
+ InstancedRenderer,
220
+ GraphicsDevice,
221
+ Camera
222
+ } from 'bloody-engine';
223
+ import { SHADERS_V4 } from 'bloody-engine/scene';
224
+
225
+ // Create graphics device
226
+ const device = new GraphicsDevice(800, 600);
227
+
228
+ // Check WebGL2 support
229
+ if (!device.isWebGL2()) {
230
+ throw new Error('Instanced rendering requires WebGL2');
231
+ }
232
+
233
+ if (!device.supportsInstancing()) {
234
+ throw new Error('GPU instancing not supported');
235
+ }
236
+
237
+ // Get WebGL2 context
238
+ const gl = device.getWebGL2Context();
239
+
240
+ // Create shaders
241
+ const instancedShader = device.createShader(
242
+ SHADERS_V4.vertex,
243
+ SHADERS_V4.fragment
244
+ );
245
+
246
+ // Use existing V3 shader for batch rendering
247
+ const batchShader = device.createShader(
248
+ SHADERS_V3.vertex,
249
+ SHADERS_V3.fragment
250
+ );
251
+
252
+ // Create hybrid renderer (auto-detects when to use instancing)
253
+ const renderer = new HybridRenderer(gl, instancedShader, batchShader, {
254
+ instancingThreshold: 100, // Use instancing for 100+ instances
255
+ maxInstances: 10000,
256
+ tileSize: { width: 64, height: 32 },
257
+ zScale: 1.0
258
+ });
259
+
260
+ // Create camera
261
+ const camera = new Camera(0, 0, 1.0);
262
+
263
+ // Set texture
264
+ renderer.setTexture(texture);
265
+
266
+ // Add thousands of floor tiles
267
+ for (let x = 0; x < 100; x++) {
268
+ for (let y = 0; y < 100; y++) {
269
+ renderer.addSprite({
270
+ gridX: x,
271
+ gridY: y,
272
+ z: 0,
273
+ width: 32,
274
+ height: 32,
275
+ texIndex: 0,
276
+ color: { r: 1, g: 1, b: 1, a: 1 },
277
+ rotation: 0
278
+ });
279
+ }
280
+ }
281
+
282
+ // Render (automatically uses instancing for large batches)
283
+ device.clear({ r: 0.1, g: 0.1, b: 0.1, a: 1.0 });
284
+ const metrics = renderer.render(camera);
285
+ device.present();
286
+
287
+ // Check performance metrics
288
+ console.log(`Instanced: ${metrics.instancedInstances} instances in ${metrics.instancedDrawCalls} draw calls`);
289
+ console.log(`Batched: ${metrics.batchedInstances} instances in ${metrics.batchedDrawCalls} draw calls`);
290
+
291
+ // Output with 10,000 tiles:
292
+ // Instanced: 10000 instances in 1 draw calls
293
+ // Batched: 0 instances in 0 draw calls
294
+ // (100x performance improvement!)
295
+ ```
296
+
297
+ **Performance Comparison:**
298
+
299
+ | Instance Count | Batch Renderer | Instanced Renderer | Speedup |
300
+ |----------------|----------------|-------------------|---------|
301
+ | 100 | ~1ms | ~0.5ms | 2x |
302
+ | 1,000 | ~10ms | ~1ms | 10x |
303
+ | 10,000 | ~100ms | ~5ms | 20x |
304
+
305
+ **When to Use Instanced Rendering:**
306
+ - ✅ Floor tiles, walls, terrain (many identical meshes)
307
+ - ✅ Particles, projectiles (same geometry, different positions)
308
+ - ✅ Sprites with same texture and size
309
+ - ❌ Unique sprites with different textures
310
+ - ❌ Small batches (< 100 instances)
311
+
312
+ The `HybridRenderer` automatically detects when to use instancing, so you get the best of both worlds!
313
+
206
314
  ### Resource Loading
207
315
 
208
316
  ```typescript
@@ -705,6 +813,9 @@ src/
705
813
  │ ├── batch-renderer.ts
706
814
  │ ├── camera.ts
707
815
  │ ├── projection.ts
816
+ │ ├── instanced-renderer.ts # WebGL2 GPU instancing
817
+ │ ├── hybrid-renderer.ts # Auto-detection (instanced vs batch)
818
+ │ ├── ring-buffer.ts # Triple-buffered GPU streaming
708
819
  │ ├── soa-webgl-renderer.ts # WebGL2 zero-copy renderer
709
820
  │ └── spatial-hash.ts
710
821
  ├── input/ # Input system (command queue)