Skip to content

20.11: linear-mipmap, effects sharing a draw, seam-free tiles and fixes - #1767

Merged
obiot merged 2 commits into
masterfrom
feat/linear-mipmap-and-fixes
Oct 25, 2026
Merged

obiot merged 2 commits into
masterfrom
feat/linear-mipmap-and-fixes

Conversation

@obiot

@obiot obiot commented Oct 25, 2026

Copy link
Copy Markdown
Member

Summary

The 20.11 rendering batch, plus the fixes found while testing it and in an adversarial review.

Added

  • textureFilter: "linear-mipmap": textures drawn smaller than their size sample their mipmaps. Every sprite vertex now carries its frame (the opposite corner's UV), so sprites, text and tile layers keep their samples inside their own frame of the atlas, at the level read (WebGL and WebGPU).
  • Renderable#visibilityLayer and Camera2d#cullMask: what each camera draws (a container left out hides its subtree; a Light2d left out neither glows nor cuts its hole).
  • syncToDisplay: frame times counted in whole display frames, so a 60/120 Hz display gets a steady update pattern; the display's rate is relearned when it changes.
  • Tiled trans / transparentcolor: the color key of tileset images, collection tiles and image layers.

Changed

  • renderer.uvOffset and the undocumented textureSeamFix setting are removed: tiles are no longer drawn a pixel larger on Canvas.

Fixed (released bugs)

  • Tile layers: no seams between tiles under smooth filtering on WebGL/WebGPU (each sample kept half a texel inside its tile); Canvas with antiAlias: false no longer draws smoothed after a resize (the 2D context state is restored).
  • GPU tile layers fade with their opacity and their container's fade (opacity faded the alpha only).
  • Pre-rendered layers hold every tile on hexagonal, staggered and oblique maps and with oversized/offset tiles, and show setTile / clearTile (also on WebGL/WebGPU and on tinted Canvas layers).
  • Isometric ellipse objects are projected with the map (circles stay Ellipse, other ellipses become polygons), on top of Project isometric collision shapes with the map's tile ratio #1766.
  • SquishEffect keeps to its frame; setTexture between batched effect sprites; no WebGL error after an effect texture is replaced or destroyed.
  • A maxfps above 120 no longer stops the game; the camera deadzone sits on whole pixels.

Performance

  • Sprites drawn through the same ShaderEffect share one draw call, even from different atlas frames.

Known limits (documented)

  • An effect's own texture read is not kept to the frame under linear-mipmap (effects are GLSL 1.00; only visible on effect sprites drawn small from tightly packed atlases).
  • At the smallest mip levels, a frame whose edges are not on a power-of-two grid can mix a little of its neighbour; padding the atlas removes it.
  • A Light3d lights every camera's meshes regardless of cullMask.
  • On isometric maps whose tiles are not 2:1, ellipses follow their projected box; Tiled itself draws them partly outside that box.

The 20.11 changelog section is consolidated (53 entries down to 44, credits kept).

Test plan

  • Full suite: 352 files, 8767 tests pass; root pnpm lint passes
  • New specs: sprite frame clamp, effect batching, texture mipmaps, Canvas resize state, pre-rendered layers (12 orientations/tile layouts, pixel-compared against tile-by-tile drawing), transparent color, syncToDisplay (incl. display changes, resets, 10 seeds), cull mask, isometric ellipses
  • Mutation tested: about 60 targeted reversions of the fixes this round, each caught by a test
  • Real GPU (Apple M4 Max, WebGL over Metal and WebGPU): all 54 examples run with no new errors; the 12 maps of the Tiled map loader match their pre-rendered bake pixel for pixel at their own settings on Canvas, WebGL and WebGPU
  • Isometric ellipses checked against Tiled's tmxrasterizer: within 0.71 px on 2:1 maps

🤖 Generated with Claude Code

https://claude.ai/code/session_01SeWCkETjW35ZbXDRswV1hx

obiot and others added 2 commits October 25, 2026 19:48
- Rendering: textureFilter "linear-mipmap"; every sprite vertex carries
  its frame, so sprites, text and tile layers keep their samples inside
  their own frame of the atlas (WebGL and WebGPU)
- Effects: sprites through the same ShaderEffect share one draw call
- Camera: Renderable#visibilityLayer and Camera2d#cullMask; the follow
  deadzone on whole pixels
- Application: syncToDisplay; a maxfps above 120 no longer stops the game
- Tiled: no seams between tiles on any renderer (uvOffset and
  textureSeamFix removed); GPU tile layer opacity and container fade;
  pre-rendered layers on every orientation, with setTile/clearTile;
  the trans color key; isometric ellipses projected with the tile ratio
- Effects: SquishEffect kept to its frame; setTexture between batched
  sprites; no WebGL error after replacing or destroying a texture
- Canvas keeps its drawing state across a resize; a Light2d in a hidden
  container is hidden too
- Tests, skills, changelog (20.11 section consolidated) and the 20.11.0
  version

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SeWCkETjW35ZbXDRswV1hx
Collision shapes are placed in the frame the sprite draws in, whatever its
anchor, so the hit box no longer needs shifting by half the sprite.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SeWCkETjW35ZbXDRswV1hx
Copilot AI balanced review requested due to automatic review settings October 25, 2026 11:49

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.

@obiot
obiot merged commit d9abca5 into master Oct 25, 2026
6 checks passed
@obiot
obiot deleted the feat/linear-mipmap-and-fixes branch October 25, 2026 12:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants