Quartz UI ↗
Browse docs
On this page
Private preview · 0.57.0-devView Markdown

Rendering and spatial UI

0.57.0-dev · beta source documentation. Native, Blueprint, Editor and rendering examples are source-reviewed, not executed in Unreal during this scan. See validation and limits.

Choose the presentation path before tuning raster size. Each browser has a rendering cost; a browser per unit marker is usually the wrong architecture. None of these APIs changes gameplay authority.

PathOwnership and purposeCurrent boundary
UMG/Slate screen UIwidget presents one logical viewRaster follows actual Slate geometry/DPI
Direct world surfacestatic mesh samples stable browser texturePassive; Win64 D3D11/D3D12 capability gate
Compatibility spatial widgetUWidgetComponent presents browser through its render targetPassive; extra world-widget composition
DOM projected markersone page renders bounded position snapshotsBrowser cadence adds latency
Retained HTML projectionnative render view positions HTML atlas pixelsExperimental; fixed-cell atlas and limited interaction

Scene backdrop

For a transparent screen-space browser, mark a panel:

<aside data-quartzui-backdrop="frost"
       style="backdrop-filter:blur(24px);border-radius:18px;background:#15203344">
  <h2>Inventory</h2>
</aside>

The native observer maps its geometry to the exact local player's viewport and filters the post-tonemap scene before browser composition. SetSceneBackdropEnabled(false) disables it per widget. A standalone Slate host must supply its owning LocalPlayer. No scene capture or CPU readback is needed for this effect.

Bounds: eight rounded rectangles, blur 0–64 CSS pixels, screen-space SDR. DOM-behind-DOM blur stays normal CSS. Separate browser views cannot blur each other. Arbitrary filter chains, transformed clipping, HDR/stereo, world-space blur, and a fully qualified split-screen rendering matrix are not established. Hiding retained panels must remove their regions; the shipped observer tests cover hidden ancestors and in-flight updates.

A passive panel in the world

Add QuartzUI Direct World Surface (UQuartzUIWorldSurfaceComponent) to an actor. Its defaults supply an engine plane and pass-through material. Set Raster Size, then call InitializeApp(AppAsset, LocalPlayer) for normal project contracts/providers. A custom material needs a Texture2D parameter whose name matches Texture Parameter Name (default SlateUI).

The mesh transform controls physical size; raster pixels control sharpness. The default engine plane is 100×100 units before scale. Match aspect ratios explicitly. AttachToView(View) instead borrows an existing unpresented view; InitializeStandalone(Definition) supplies only the core contract. Use exactly one path.

UQuartzUISurfaceTexture is a stable facade over Epic's existing browser texture. Do not recreate it every frame. The component owns heartbeat, resizing, binding generations, visibility suspension, and teardown. ReleaseQuartzUI releases its presentation/session; owned versus borrowed view behavior follows the initialization path. Auto-suspension normally begins when hidden or not recently rendered, with lower-frequency visibility polling. Providers are refreshed when revealed.

Transparent browser output is premultiplied alpha. Prefer a matching AlphaComposite material; inspect UV orientation and gamma on target hardware. Sizes are capped by both axis and project memory budgets; avoid continuously resizing with distance.

The transfer is reported as BackendManaged, not zero-copy. The facade adds no second full-size copy, but Epic's backend may copy/synchronize. D3D12 historical host evidence is recorded upstream; D3D11 remains runtime-unvalidated there due to a stock host/device failure. This scan ran neither RHI. Input rays, mesh-UV hit mapping, keyboard/IME, and multi-user focus are not implemented by the direct surface.

Compatibility spatial widget

Use UQuartzUIWidgetComponent only when the standard UWidgetComponent path is needed. Initialize with the same app/view/standalone choice. World space uses authored world geometry and draw size; screen space projects the anchor to a player widget layer. It disables hardware interaction and hit testing. Suspend it explicitly when pooling/hiding it and release its browser on owner teardown. Budget the browser raster and the additional UWidgetComponent render target separately.

Project world points into one DOM

FQuartzUISpatialProjection and UQuartzUISpatialBlueprintLibrary::ProjectWorldLocations accept the exact PlayerController, a bounded point array, and FQuartzUISpatialProjectionSettings. They return one FQuartzUISpatialProjectionResult per input index, including invalid/behind-camera entries. Use projection success/on-screen flags before displaying records.

Minimal Blueprint flow: after camera updates, Project World Locations → pair results with your stable IDs → publish a compact struct snapshot → update keyed web elements. Choose physical pixels or DPI-converted viewport/widget coordinates once; do not divide by DPI twice. Separate high-frequency positions from ordinary inventory data. FlushOutboundMessagesNow can reduce one native tick delay but cannot make asynchronous Chromium paint synchronous.

Experimental retained HTML projection

FQuartzUIHtmlProjection accepts Player, owning View, a permitted page URL, atlas dimensions, cell pixels, and an interactive flag. Its separate document needs its own normal contract handshake. Create it once in a native owner; call Update after pose updates with copied FQuartzUIHtmlAnchor values; destroy it before the player/view lifetime ends.

Minimal recipe: a 2×1 atlas with 64×64 cells paints normal/hover artwork; add one anchor with a stable Key, world Position, and cell indices 0/1. For passive nameplates set bInteractive=false. PublishContent sends retained projection.content only when artwork metadata changes; world positions belong in Update, not repeated browser messages. SetCallbacks receives validated activation/hover keys for the interactive path.

Limits: at most 128 anchors; uniform bounded cells; no world occlusion, general DOM partitioning, differently sized cells, or full input per cell. Browser Ready and frame ID do not prove a particular content revision is painted. The host must manage allocation/repaint consistency; never reuse a live cell for another identity without a strategy. This prototype is an opt-in advanced page, not a general production replacement for the shell.

Measure what the user sees

Use stat QuartzUI for plugin counters, Unreal Insights/GPU profiling for composition, and Chromium tools for page cost. Surface estimates are not full GPU/process memory. The development FrameProbe measures composed-backbuffer timing and optional frame capture, not monitor scanout. Historical benchmark figures in the original docs are not promises for this revision or hardware.

Rendering guide (source: Documentation/Rendering.md), direct surfaces (source: Documentation/DirectWorldSurfaces.md), projection (source: Documentation/HtmlProjectionPrototype.md). All rendering recipes require host/RHI validation; none were rendered during this scan.