Skip to content

Comments

Add native perspective projection mode and tests#1033

Open
RaulDurand wants to merge 2 commits intocetz-package:masterfrom
RaulDurand:feature/perspective-projection
Open

Add native perspective projection mode and tests#1033
RaulDurand wants to merge 2 commits intocetz-package:masterfrom
RaulDurand:feature/perspective-projection

Conversation

@RaulDurand
Copy link
Contributor

This PR adds a native perspective projection mode to CeTZ and includes docs/tests for it.

#cetz.canvas({
  import cetz.draw: *

  perspective(x: 28deg, y: -35deg, distance: auto, {
    on-xz({ rect((-1, -1), (1, 1)) })
    line((0, 0, 0), (1, 1, 1), stroke: red)
  })
})

What’s included

  • Added draw.perspective(...) in src/draw/projection.typ
  • Exported perspective from src/draw.typ
  • Added API docs page:
    • docs/api/draw-functions/projections/perspective.mdx
    • docs/api/sidebar.js entry under Projections
  • Added projection regression test:
    • tests/projection/perspective/test.typ
    • tests/projection/perspective/ref/1.png

Perspective behavior

  • Uses the same default camera angles as ortho (x: 35.264deg, y: 45deg, z: 0deg)
  • Applies perspective divide with internal near/depth handling
  • Computes and uses a reference depth (d_ref, corresponding to the nearest depth) to anchor projection scale:
    • projected coordinates use x' = d_ref * x / w, y' = d_ref * y / w
    • with w = max(-z, near) in view space
  • At the reference depth (the nearest visible depth in camera space), projected lengths are approximately preserved because scale is anchored to that plane; objects farther in depth are progressively smaller, which helps keep deep scenes from overflowing the canvas.
  • distance controls camera distance and therefore perspective strength:
    • smaller distance => stronger perspective (more foreshortening)
    • larger distance => flatter look (closer to orthographic)
  • distance is internally constrained to stay in front of the nearest geometry, preventing extreme camera placements that would cause distorted projections.
  • distance: auto derives a stable value from scene depth
  • Supports sorting and cull-face options like existing projection paths
  • Mark handling in perspective forces transformed-shape placement, avoiding oversized/distorted marks/arrows.

Validation

  • tt run projection/perspective projection/ortho mark/shape/transform
  • All passed locally.
1

@johannes-wolf johannes-wolf self-requested a review February 22, 2026 15:13
@johannes-wolf johannes-wolf added the feature Feature Request label Feb 22, 2026
@johannes-wolf johannes-wolf added this to the 0.5.0 milestone Feb 22, 2026
Copy link
Member

@johannes-wolf johannes-wolf left a comment

Choose a reason for hiding this comment

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

This is great! Thank you. :)
Some small things…

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature Feature Request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants