A real post-processing stack, not a filter with a nice name: bright pass, golden-angle bloom, radial light shafts, ACES tonemapping, black point, grade and unsharp mask. One pass, on your own GPU, with a handle you can drag.
All of it happens in a single pass, which is why it holds a frame rate on a laptop. The same source runs in the popup, on this page, and in every render below.
Pixels above the threshold are kept and squared, so highlights bloom and midtones stay where they are.
An isotropic glow for a fraction of the cost of a separable blur, with no axis showing through.
Marched toward the sun position with 0.935 decay and tinted warm on the way out.
What keeps a blown-out sky from flattening into paper white when the exposure comes up.
Exposure, black point, contrast, saturation and a temperature tilt, applied in that order.
Unsharp mask, chromatic aberration, vignette and a grain dither to break up banding.
Not a video and not two exported images. On the left is a real, ungraded Roblox frame, exactly as it was sent to us. On the right are the same pixels after the shipped shader runs on your own GPU. The split follows the scroll until you take the handle.
No WebGL on this machine? The canvas falls back to the raw frame and the label says so, rather than pretending the grade applied.
Every frame in this section was captured in a real game by the people using this. Nothing here is a render of a scene we invented, and nothing has been touched up.
The ungraded capture above, pushed through each preset by the shader the extension ships. Vanilla is the frame itself, untouched, so you can see where the rest start from.
Three minutes, no store listing, no account. The archive is the complete source:
the shader you just dragged is the one in shader.js, readable end to end. Most of
the weight is frame.js, the real capture the lab grades.
Keep the unzipped folder somewhere permanent. Chrome re-reads it on every launch, so deleting the folder uninstalls the extension.
Type chrome://extensions in the address bar and press Enter. The same page sits
behind the three-dot menu under Extensions → Manage extensions.
The switch is in the top right corner. Flipping it reveals three buttons that were not there a moment ago: Load unpacked, Pack extension and Update.
Pick the folder that came out of the zip, the one that contains
manifest.json — not the zip, and not a folder one level above it. Chrome reads the
manifest and the card appears.
Chrome lists the extension with the id it generated for your copy and a link straight to the running service worker. Pin it from the puzzle icon, open the lab, pick a preset and press Apply to roblox.com. The grade is stored per device and survives a restart.
shader.js compiles a GLSL fragment shader and runs it on your
GPU through WebGL: bright pass, a 36-tap golden-angle bloom, 26 marched light shafts, the ACES
curve, black point, grade, unsharp mask, chromatic aberration, vignette and a grain dither. A CSS
filter cannot bloom a highlight or march toward a sun position, because it has no access to
neighbouring pixels.chrome.storage.local, a file in your own profile on your own disk.
There is no account, no sync and no server in this project. Unzip the archive and search every
file for fetch(: you will find none.storage, scripting and tabs, with host access limited to
*://*.roblox.com/*, and Chrome enforces that limit rather than the extension's good
intentions.PRESETS in
shader.js is a plain object, so adding a named look of your own is a few lines and a
reload.