RTT Monitor
App: apps/rtt_monitor_demo/
Demonstrates script render-to-texture capture (engine PLM-242 / ADR 0077). The scene is a top-down
ring of six coloured cubes; a small picture-in-picture monitor panel in the top-right shows the same
cubes from a second, low-front camera. Each frame the demo renders that second view into a persistent
capture texture with Graphics.submitCapture, then
samples the texture onto the panel through the ordinary custom-material set-5
path — proving a capture is just a Texture that flows through a normal draw with no descriptor-ABI change.
Run from root
Section titled “Run from root”% ./plume3d rtt_monitor_demoThe main view is a top-down orbit over the ring of cubes; the PiP panel top-right shows the low-front camera’s view of the same ring, updated every frame. The demo captures a screenshot at frame 90.
What it does
Section titled “What it does”-
Allocates one persistent capture target in
init()(allocate once — never per frame), and a second scene camera (fromScene.addCamera) that supplies the capture’s view/proj but is never made the active view:_cap = Graphics.newCaptureTarget(400, 400) // persistent sRGB colour target -> a Texture_capNode = _scene.addNode("capcam")_capNode.setPosition(0, 4, 13)_capCam = _scene.addCamera() // a REAL scene camera — a bare Camera.new() is inert_capCam.setNode(_capNode)_capCam.setFovYRadians(0.9) -
Each frame in
draw()(notupdate()— the frame clears pending submissions between the two), binds the view/proj to locals, then submits the scene render into the target:var view = _capCam.getViewMatrix()var proj = _capCam.getProjectionMatrix(1.0)Graphics.submitCapture(_cap, view, proj) // render the whole scene from the second camera into _cap_scene.draw()// ... draw the ground + ring of cubes ... -
Binds the capture at set-5 slot 0 on the monitor panel and draws it — a capture is a
Texture, sosetCustomTexturetakes it exactly like a loaded image:_screen.setCustomTexture(0, _cap) // the capture, sampled on the PiP panelGraphics.drawMesh(_screen) -
The panel’s set-5 shader (
shaders/src/monitor.slang) samples slot 0 withplume3d_customTex(0, uv). Note the MoltenVK gotcha called out in the shader: a set-5 shader must reference enough of the set-5 ABI orslangcstrips the unused bindings and the pipeline silently renders nothing.
- The capture is single-camera in v1 — one submitted capture per frame.
submitCapturerecords the whole scene, including screen-space overlays. Because the monitor panel is itself in the scene it captures, you see the expected live video-feedback recursion; adrawSubsetfilter to exclude overlays (and to capture a named layer only, for interaction/displacement maps) is a documented follow-up (ADR 0077).- Use
Graphics.newDataCaptureTargetinstead for data maps (grass-bending, water displacement) where you want the linear/UNORM view, not sRGB colour.
See Graphics → Render-to-texture capture (A#7) and the custom material (set 5) sampling path. Screenshot-verified (the PiP panel shows the ring from the second camera).