Skip to content

Remove depthTest setting, improve container sorting, clean up renderer#1377

Merged
obiot merged 7 commits intomasterfrom
cleanup/remove-depthtest-improve-sorting
Apr 12, 2026
Merged

Remove depthTest setting, improve container sorting, clean up renderer#1377
obiot merged 7 commits intomasterfrom
cleanup/remove-depthtest-improve-sorting

Conversation

@obiot
Copy link
Copy Markdown
Member

@obiot obiot commented Apr 12, 2026

Summary

  • Remove depthTest application setting — GPU depth sorting is incompatible with 2D alpha blending. The "z-buffer" option never worked correctly for 2D sprites (see Enable GPU depth sorting for 2D sprite rendering in WebGL #1370 for full analysis). Depth testing remains available internally for 3D mesh rendering only.
  • Improve container sorting — cache comparator function via sortOn getter/setter, simplify comparators by removing legacy null guards
  • Clean up renderer — move customShader to base Renderer class so Renderable no longer checks renderer type

Changes

Removed

  • DepthTest type and depthTest setting from ApplicationSettings
  • depthTest from defaultApplicationSettings
  • Depth test toggle from WebGL renderer init (always disabled for 2D)
  • Depth buffer clear from clear() (only drawMesh uses it, clears locally)
  • depthTest: "z-buffer" from platformer example
  • Depth test info from console header

Improved

  • Container.sortOn is now a getter/setter that caches the comparator — avoids "_sort" + sortOn.toUpperCase() lookup on each sort
  • Sort comparators simplified: _sortZ, _sortReverseZ, _sortX, _sortY — removed null guards, use || short-circuit

Cleaned up

  • customShader moved to base Renderer class
  • Renderable.preDraw/postDraw no longer checks typeof renderer.gl !== "undefined"
  • drawMesh simplified: always restores depth to disabled state (no conditional)

Test plan

  • All 2388 tests pass
  • New tests for sort comparators (_sortZ, _sortReverseZ, _sortX, _sortY) and sortOn caching
  • Platformer example renders correctly
  • 3D mesh rendering still works (drawMesh enables/disables depth locally)

🤖 Generated with Claude Code

GPU depth sorting is incompatible with 2D alpha blending — the depth
buffer and painter's algorithm cannot coexist for transparent sprites.
The "z-buffer" option never worked correctly and has been removed.

Changes:
- Remove depthTest application setting, DepthTest type, and z-buffer
  option from settings, defaults, header, and renderer initialization
- Simplify WebGL renderer: depth test disabled by default, only enabled
  temporarily inside drawMesh() for 3D mesh rendering
- Remove depth buffer from clear() (drawMesh clears it locally)
- Move customShader property to base Renderer class so Renderable
  preDraw/postDraw no longer checks renderer type via renderer.gl
- Container: cache sort comparator via sortOn getter/setter
- Container: simplify sort comparators, remove legacy null guards
- Remove depthTest: "z-buffer" from platformer example
- Add tests for sort comparators and sortOn caching

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 12, 2026 02:53
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR removes the depthTest application setting (WebGL depth sorting for 2D) and simplifies WebGL renderer state handling, while also optimizing Container child sorting by caching the comparator and simplifying comparator implementations.

Changes:

  • Remove depthTest from application settings/defaults and WebGL renderer initialization/clearing behavior.
  • Optimize Container sorting via cached comparator (sortOn getter/setter) and simplified comparator functions.
  • Move customShader to the base Renderer to avoid renderer-type checks in Renderable.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/melonjs/tests/container.spec.js Adds unit tests for container comparators and sortOn comparator caching.
packages/melonjs/src/video/webgl/webgl_renderer.js Disables depth testing for 2D by default; updates clear behavior; simplifies depth enable/restore in drawMesh.
packages/melonjs/src/video/renderer.js Declares customShader on the base renderer.
packages/melonjs/src/renderable/renderable.js Removes renderer-type guard when setting/resetting customShader.
packages/melonjs/src/renderable/container.js Introduces cached comparator via sortOn accessor; simplifies sort comparators.
packages/melonjs/src/application/settings.ts Removes DepthTest type and depthTest from ApplicationSettings.
packages/melonjs/src/application/header.ts Removes depth test info from the console header.
packages/melonjs/src/application/defaultApplicationSettings.ts Removes the depthTest default setting.
packages/melonjs/src/application/application.ts Removes depthTest normalization and related world.autoSort toggling logic.
packages/melonjs/CHANGELOG.md Documents breaking removal of depthTest and related renderer/container changes.
packages/examples/src/examples/platformer/createGame.ts Removes depthTest: "z-buffer" from the platformer example.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

obiot and others added 3 commits April 12, 2026 11:00
Throw an error if sortOn is set to an unsupported value (only "x",
"y", "z" are valid). Prevents undefined comparator from falling back
to Array.sort's default lexicographic ordering.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Tweens use event-based lifecycle since #1365 and are no longer
added as container children.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- addChild() and addChildAt() now throw if child is not a Renderable
- Remove redundant isRenderable checks throughout Container (update,
  draw, updateBounds) since addChild guarantees all children are
  Renderable instances
- Remove dead "non renderable" else branch in update loop
- Remove Tween from addChild JSDoc (no longer added to containers)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 12, 2026 03:08
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

obiot and others added 3 commits April 12, 2026 11:18
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Renderable/Container cleanup:
- Remove redundant typeof checks for ancestor, updateBounds, pos,
  getAbsolutePosition (guaranteed by addChild instanceof guard)
- Simplify mask, _absPos, _bounds, _tint cleanup to truthiness checks
- Simplify parentApp and isFloating ancestor checks
- Remove currentTransform undefined check in Container.reset()
- Remove unused Color and Bounds imports

Matrix optimization:
- Reorder isIdentity() comparisons in Matrix2d and Matrix3d to check
  translation components first (most commonly non-zero), enabling
  early exit for non-identity matrices in the hot path

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 12, 2026 03:41
@obiot obiot merged commit a2e3e84 into master Apr 12, 2026
8 checks passed
@obiot obiot deleted the cleanup/remove-depthtest-improve-sorting branch April 12, 2026 03:46
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

}
if (!this._parentApp && this.ancestor) {
// the `app` property is only defined in the world "root" container
this._parentApp = this.ancestor.getRootAncestor().app;
Copy link

Copilot AI Apr 12, 2026

Choose a reason for hiding this comment

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

Renderable.parentApp now assumes this.ancestor.getRootAncestor() exists whenever this.ancestor is set. This is not always true: Entity assigns this.children[0].ancestor = this (see entity.js), so calling parentApp on an Entity's child renderable will throw at runtime. Please restore a safe guard (e.g., check for getRootAncestor before calling, or walk up .ancestor until reaching a Container/root that has .app).

Suggested change
this._parentApp = this.ancestor.getRootAncestor().app;
if (typeof this.ancestor.getRootAncestor === "function") {
const rootAncestor = this.ancestor.getRootAncestor();
this._parentApp = rootAncestor && rootAncestor.app;
} else {
let ancestor = this.ancestor;
while (ancestor) {
if (ancestor.app) {
this._parentApp = ancestor.app;
break;
}
ancestor = ancestor.ancestor;
}
}

Copilot uses AI. Check for mistakes.
// allocated a GUID value (use child.id as based index if defined)
child.GUID = createGUID(child.id);
}
child.GUID = createGUID(child.id);
Copy link

Copilot AI Apr 12, 2026

Choose a reason for hiding this comment

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

addChild() now always calls createGUID(child.id). Several renderables (e.g. Entity) default id to an empty string, and createGUID() does arithmetic on the index parameter (GUID_index += index), so passing a non-number can coerce GUID_index into a string and break GUID generation. Consider only passing child.id when it is a finite number, otherwise call createGUID() without an argument (or normalize with Number(child.id) and a fallback).

Suggested change
child.GUID = createGUID(child.id);
child.GUID = Number.isFinite(child.id)
? createGUID(child.id)
: createGUID();

Copilot uses AI. Check for mistakes.
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