Skip to content

Angled Split Screen

App: apps/angled_split_demo/

A Kronnect-style angled split (Camera v2, ADR 0061): two players on one screen, divided by a diagonal whose angle is perpendicular to the on-screen direction between them — so the divider rotates as they move around each other. Each player renders full-screen from their own camera to an offscreen target, and the renderer composites the two complementary half-planes.

import "engine" for Scene, SplitScreen, SplitLayout
var split = SplitScreen.new(scene, [p1, p2]) // exactly 2 players
split.layout(SplitLayout.angled) // diagonal split; auto-enables the RTT composite path
split.distance(6)
split.height(2)

draw() is just scene.draw() + the mesh draws — no per-viewport camera code.

Terminal window
% ./plume3d angled_split_demo

The two players orbit the centre landmark in opposite phase, so the line between them sweeps through every orientation and the diagonal divider rotates to match.

How it works — the RTT composite path (PLM-190, ADR 0061)

Section titled “How it works — the RTT composite path (PLM-190, ADR 0061)”

The axis-aligned split-screen path (VkViewport sub-rects) cannot draw a diagonal divider — a half-plane is not an axis-aligned rectangle. So SplitLayout.angled switches on the composite path:

  1. Offscreen render — each viewport’s scene is drawn to its own offscreen colour target (an offscreen render pass that is render-pass-compatible with the mesh pipelines, so they’re reused unchanged), at full-screen aspect.
  2. Half-plane clip — the manager projects both players through the group camera to find their on-screen positions, sets the divider perpendicular to that direction through screen centre, and clips the unit square into two convex polygons (Sutherland–Hodgman).
  3. Composite — each polygon is drawn as a textured quad sampling its offscreen target (UV = screen fraction, so each player sees their full-screen view clipped to their half); the divider is a rotated quad along the split line.

The same composite path (SplitScreen.compositeMode(on)) also powers overlap / picture-in-picture and the animated rect-peel. It renders each viewport to a full-extent target, so a small viewport over-renders — fine at up to 4 viewports.