Skip to content

Camera3d should fail loudly when used with the Canvas renderer #1479

@obiot

Description

@obiot

Problem

`Camera3d` (#1464) silently does the wrong thing under the Canvas renderer. Its perspective projection + depth-test-driven painter sort presuppose a WebGL context — the Canvas backend has no `gl`, no depth buffer, no `drawMesh` path. Today the engine just runs and produces a broken picture (no 3D, no mesh rendering, sometimes a blank canvas), with no error to tell the dev why.

Repro

```ts
const app = new Application(800, 600, {
renderer: video.CANVAS, // ← explicit Canvas
cameraClass: Camera3d, // ← Camera3d
});
```

→ no error, scene renders with no perspective, meshes invisible, depth-sort ineffective. User has no clue why.

Same thing happens when `video.AUTO` falls back to Canvas (WebGL unavailable / failIfMajorPerformanceCaveat = true on a low-perf device + Camera3d in the app's cameraClass).

Proposed

In the `Camera3d` constructor (or in `Application`'s camera-class instantiation path), check the active renderer at construction time and throw a clear error if it isn't a `WebGLRenderer`:

```ts
if (!(video.renderer instanceof WebGLRenderer)) {
throw new Error(
"Camera3d requires the WebGL renderer (Canvas backend lacks the " +
"depth buffer + 3D projection path Camera3d depends on). Set " +
"{ renderer: video.WEBGL } on your Application — or fall back to " +
"Camera2d if WebGL isn't available on the target device."
);
}
```

Fail-fast at construction time is better than a silently broken scene at runtime.

Open question

Should the check be on `Camera3d` itself (constructor-time, requires Camera3d to import the renderer class — possible circular dep) or on `Application` (which already mediates renderer + cameraClass)? Probably Application — cleaner separation, no new import in Camera3d.

Scope

  • ~10 lines of code
  • One regression spec: `new Application({ renderer: video.CANVAS, cameraClass: Camera3d })` must throw with a useful message
  • CHANGELOG entry under `### Changed` (behavioural change — silent fallback → loud error)

Related

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions