Zain Dana HarperRAW · the reference renderer

Render the frame. Then check it.

RAW is a dependency-free C++23 renderer that draws a scene on the CPU, checks its fast screen-space ambient occlusion against a ray-traced reference, and writes a JSON certificate saying whether the shortcut held.

It lights the frame twice, once with the cheap method real-time engines use and once with a ray-traced reference, and tells you how far the cheap one drifted. You get the picture and the evidence for it from the same run.

RAW 0.4.0 · C++23 · CPU, WebAssembly and WebGPU · no dependencies · FSL-1.1-MIT

Render it here.

This is the 0.4.0 renderer running in your browser. Pick a camera and it draws the frame, lights it both ways and writes the certificate, the same as the command line. If your browser has WebGPU, the frame is drawn on your GPU, and the same camera is drawn again on the CPU to check it: a second certificate says whether the two agree. Without WebGPU, the CPU build draws the frame on one thread, and the status lines say why. Your browser checks each module against its published SHA-256 before running it.

  • Needs JavaScript and WebAssembly.

Run it now.

See how it works, step by step: both occlusion estimators, the reconcile against the tolerance and the verifier, animated with values from the repository.

Download the binary for your system from the 0.4.0 release, check it against the published hashes, and point it at an empty folder. A 256 by 256 frame takes about a quarter of a second.

Windows x64: raw-native-0.4.0-windows-x64.zip  ·  Linux x64: raw-native-0.4.0-linux-x64.tar.gz (glibc 2.38 or newer)  ·  WebAssembly: raw-native-0.4.0-wasm.zip  ·  SHA256SUMS
# check the download, then render the default view
sha256sum -c SHA256SUMS
raw_native_cli --out ./out
raw_native_cli verify ./out    # recompute the error from the written files

# move the camera; a previous camera adds motion vectors
raw_native_cli --out ./out --width 512 --height 512 --eye 0,9,3 --target 0,0.5,0
raw_native_cli --out ./out --prev-eye 4.3,4,5.7

# or build it: CMake 3.24+ and any C++23 compiler
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --config Release
ctest --test-dir build -C Release --output-on-failure

Two views of one scene, and what each certificate says.

Every image here came out of the 0.2.0 command line at 512 by 512. The scene is a box on a ground plane under one light. The first panel is the shaded frame. The next two are the reference and the shortcut, where white means open sky and dark means occluded. The last is the error between them.

Exhibit I the default view · refuted
A red box on a grey ground plane, seen from above and to the side, with soft darkening where the box meets the ground.
Shaded frame
Ray-traced ambient occlusion: a soft dark halo on the ground around the box and grey shading on its sides.
Ray-traced AO, the reference
Screen-space ambient occlusion: almost all white, with only a thin dark line along the box's bottom edges.
Screen-space AO, the shortcut
Error map on black: the halo and box sides glow where the shortcut missed occlusion the reference found.
Error map
{"claim":"screen-space AO matches ray-traced ground truth within tolerance",
 "verdict":"refuted", "oracle":"raw-rt-ao-v1",
 "evidence":[["pixels","151984"],["rmse","0.1349"],["maxError","0.6406"],["tolerance","0.1200"]],
 "channels":{"ao_fidelity":0.881125,"motion_coherence":1,"hdr_headroom":0.875542}}

The shortcut misses the soft halo almost entirely. Its error is 0.135 RMSE against a tolerance of 0.12, so the certificate says refuted. That is the check working: a picture that looks fine at a glance came back with a measured reason not to trust its shading.

Exhibit II the high view · verified
The same red box seen from nearly straight above, its top face filling the centre of a grey ground plane.
Shaded frame
Ray-traced ambient occlusion from above: a soft dark ring on the ground around a white square.
Ray-traced AO, the reference
Screen-space ambient occlusion from above: white, with a thin line along one edge of the box.
Screen-space AO, the shortcut
Error map from above: a faint ring around the box on black.
Error map
{"claim":"screen-space AO matches ray-traced ground truth within tolerance",
 "verdict":"verified", "oracle":"raw-rt-ao-v1",
 "evidence":[["pixels","239854"],["rmse","0.0827"],["maxError","0.6250"],["tolerance","0.1200"]],
 "channels":{"ao_fidelity":0.923585,"motion_coherence":1,"hdr_headroom":0.875542}}

From above, most covered pixels are open ground where both methods agree, so the average error drops to 0.083 and the same check passes. The worst pixel is still off by 0.63. The certificate carries both numbers, so you can see that a pass on the average does not mean every pixel is right. Raw certificates: default, high.

The certificate

A certificate is a JSON file with a claim, a verdict, the oracle that judged it and the numbers behind the verdict. The verdict is verified, refuted or unverifiable. A channel with no data is written as null.

You can check one in two ways. From 0.3.0 the run writes its ambient occlusion as 32-bit floats beside a coverage mask, and raw_native_cli verify recomputes the error from those files alone. Or run the same command yourself, because the output is deterministic: the default frame and its certificate hash the same with MSVC 19.50 on Windows, with GCC 13.3 on Ubuntu and from the WebAssembly build, locally and on GitHub’s build runners. The renderer also measures exactly how many bytes the frame needs, renders again inside that budget, and refuses any allocation past it. A second certificate records whether the budget held.

The same scene gives different verdicts from different cameras:

ViewCamera flagsCovered pixelsRMSEVerdict
Defaultnone151,9840.1349refuted
High--eye 0,9,3 --target 0,0.5,0239,8540.0827verified
Low--eye 6,1.5,2 --target 0,1,0140,8380.1659refuted
Close--eye 2,2.5,3 --target 0,0.8,0 --fovy 0.7214,0430.2167refuted
Wide--eye 5,5,8 --target 0,0.5,0 --fovy 1.288,8690.0882verified

512 by 512, tolerance 0.12 RMSE. Each row is one run of the 0.2.0 binary with the flags shown.

Scope and speed

Where it came from.

RAW began as a Direct3D 11 effects platform for Skyrim SE: a proxy library that took over a closed game’s frame and added its own lighting passes mid-picture. That taught me how a frame is built and how quickly an effect can look right while being wrong. The new RAW keeps the lesson and drops the game. It owns its whole frame, and every frame carries a check against a reference. The Skyrim code stays public. Work on it is paused, and I plan to return to it.

Read the source.

C++23, built from the standard library and its own headers. The rasterizer, both ambient occlusion methods, the reconcile step, the certificate writer, the verifier and the bounded memory arena each have their own tests, 32 in all. From 0.3.0 the license is FSL-1.1-MIT, and each version becomes MIT two years after its release. Version 0.2.0 stays MIT, as released.

GitHub: HarperZ9/raw-native  ·  Paused: HarperZ9/raw (the Skyrim SE platform)  ·  ← the map  ·  the index