compute_deferred_lighting

compute_deferred_lighting

English | 日本語

compute_deferred_lighting

Overview

Deferred Lighting renders geometry into a G-buffer first, then evaluates lights per pixel afterward. In this sample, GeometryBufferPass outputs albedo, view-space normal, and depth, and DeferredLightingPass reads up to 128 point lights while computing the final lighting for each pixel

The reason DeferredLightingPass was moved into the core is that G-buffer based multi-light evaluation repeats the same setup work across samples. The application can stay focused on scene animation, light placement, and view selection, while the pass owns light-array validation, world-space to view-space conversion, uniform updates, and storage-texture output. That separation keeps the three frame stages clear in main.js: Geometry Pass, deferred lighting, and canvas copy

This is useful when you want the most direct baseline for G-buffer based lighting. Every pixel scans every active light, so the structure is easy to read, but the cost grows with light count. Practical large-light scenes usually move on to tiled or clustered lighting, yet this version is a good baseline for understanding the input contract and execution order first

const deferredPass = new DeferredLightingPass(app.getGPU(), {
  label: "compute-deferred",
  width: app.screen.getWidth(),
  height: app.screen.getHeight(),
  maxLights: 128
});

deferredPass.encode(app.getGPU().commandEncoder, gbuffer.getBindingResources(), {
  projection,
  viewMatrix,
  lights,
  lightCount: 64,
  view: "lighting"
});

In this example, projection is the 4-value array returned by createGBufferProjectionParams(), viewMatrix comes from createViewMatrix(app.eye), and lights is an array of objects with { position, color, radius, intensity }. DeferredLightingPass does not own G-buffer generation or the final canvas copy, so the frame order stays explicit in the application

How to Run

Checkpoints

Press V to switch between lighting / albedo / normal / depth. If lighting looks wrong, these debug views help separate G-buffer generation issues from light-evaluation issues

Use 1 and 2 to change the active light count through 16, 32, 64, 96, 128. Press Space to stop light animation so the same G-buffer and light count can be compared more easily

One caution: this implementation is intentionally a full light scan. Use it as a baseline to confirm that compute cost rises with light count, that the G-buffer only needs to be rendered once, and that debug views are effective when narrowing down rendering problems