AzurIce / AzurIce/ranim

Improve handling of z-fighting between coplanar VItems

Open
#174 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
647
Forks
37
Avg merge
6h 12m
Merged PRs (30d)
17

Description

## Problem

Coplanar or nearly coplanar `VItem`s can exhibit z-fighting or unstable occlusion. This is particularly visible in the `basic` example: the paths that make up `Ghostscript_Tiger.svg` all lie on the same plane, and parts of the tiger may incorrectly occlude one another or disappear.

An SVG is imported as multiple independent `VItem`s, with each path normally placed at `z = 0`. Although these paths have the same intended geometric depth, their reconstructed planes use different origins. Projection and interpolation in `f32` can therefore produce very small depth differences.

The current VItem renderer uses:

- an opaque depth prepass with `Less`;
- an opaque color pass with `LessEqual`;
- OIT collection for fragments whose alpha is below the opaque threshold.

As a result, OIT does not resolve conflicts between opaque coplanar SVG paths. Tiny numerical depth differences can determine which path wins the depth test.

## Expected behavior

- Coplanar 2D compound objects such as SVGs and text should render deterministically.
- SVG path overlap should preserve the SVG painter's-order semantics where applicable.
- Normal 3D depth testing and order-independent transparency should continue to work.
- The solution should not require sorting all render items on the CPU.

## Possible directions

This needs investigation before committing to a specific design. Options may include:

- a stable coplanar tie-break or local layer within compound 2D objects;
- a depth bias derived from a local layer while retaining geometric depth as the primary key;
- separating geometric depth from a coplanar ordering key;
- extending OIT/resolve behavior for opaque or equal-depth fragments;
- eliminating inconsistent depth reconstruction for items that share a plane.

A general-purpose depth offset based only on submission order should be avoided, since it could alter real 3D occlusion and make rendering behavior depend on item packing order.

## Reproduction

Render the `basic` example and inspect the large Ghostscript tiger, especially regions where multiple opaque SVG paths overlap on the same plane.

## Acceptance criteria

- The tiger in the `basic` example renders without unstable coplanar occlusion artifacts.
- The result is deterministic across frames.
- Transparent VItems retain the intended OIT behavior.
- Ordinary non-coplanar 3D occlusion is not regressed.
- Add a focused regression example or test for overlapping coplanar VItems.

Contributor guide

Open the contributing guide

Research direction

Start by rendering the basic example and inspecting the VItem renderer's opaque depth prepass, color pass, and OIT handling while reproducing the Ghostscript tiger artifact. Compare overlapping coplanar paths across frames and evaluate the listed design directions without changing ordinary 3D depth or transparent behavior. Done means deterministic tiger rendering, preserved OIT, no non-coplanar regression, and a focused regression example or test.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
computer-graphics
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.