Refraction
App: apps/refraction_demo/
Demonstrates opaque-colour capture for transparent refraction (engine PLM-238 / ADR 0075). With
Graphics.opaqueCaptureEnabled(true), the engine renders the
opaque scene, copies it into a capture texture, then renders the transparent draws — which sample
that texture at a screen-space UV and offset it to refract. Four opaque colour bands sit behind one
transparent quad; the quad bends the bands through it.
Run from root
Section titled “Run from root”% ./plume3d refraction_demoFour full-height colour bands (red / green / blue / yellow) are drawn opaque at a far depth, with one transparent quad in front. The band boundaries are straight outside the quad and wavy inside it — because the quad samples the captured bands at a time-wobbled UV. That is the proof: the opaque phase is captured and reaches the transparent draw. With capture off (or no post effect) the quad reads white instead.
What it does
Section titled “What it does”-
Draws four opaque bands with an ordinary mesh shader (
Graphics.newMesh+Graphics.drawMesh). -
Marks the centre quad transparent so it renders in the second (post-copy) phase:
_quad.blendMode = "alpha" // classify as transparent → samples the opaque copy -
Each frame in
draw(), enables capture, draws the opaque bands then the quad, and adds a passthrough post effect (opaque capture needs the offscreen path):Graphics.opaqueCaptureEnabled(true) // split opaque → copy → transparentfor (b in _bands) Graphics.drawMesh(b) // opaque phaseGraphics.drawMesh(_quad) // transparent phase — samples the opaque copyGraphics.addPostEffect("shaders/present", []) // passthrough present drives the offscreen path -
The water shader
#include "plume3d.slang"(the mesh ABI) and samples the capture at set 0 binding 6 with a screen-space UV, wobbled by the frame clock:float2 wobble = float2(sin(input.ScreenUV.y * 30.0 + plume3d_time() * 3.0),cos(input.ScreenUV.x * 30.0 + plume3d_time() * 3.0)) * 0.035;float4 behind = plume3d_opaqueColor(input.ScreenUV + wobble);return float4(behind.rgb * float3(0.65, 0.82, 1.0), 1.0); // cool water tint
See Graphics.opaqueCaptureEnabled and the
opaque-colour refraction guide. Screenshot-verified (the bands bend
inside the quad).