Add post-processing effects chain#146
Merged
Merged
Conversation
Prepare the render graph for the post-processing chain. - TonemapPass becomes ResolvePass (resolve_pass.dart). It gains grading and overlays in later stages. - kHdrColorBlackboardKey becomes kSceneColorBlackboardKey, the current scene-color handle that post passes read and republish. - Mark the before and after resolve insertion points in Scene.render. Pure rename plus comment seams. Shaders are untouched, so the output is pixel-identical. Toward #47.
The first built-in post-processing effect. - PostProcessSettings with ColorGradingSettings (brightness, contrast, saturation, white balance, lift/gamma/gain), reached through Scene.postProcess. Effects default off. - The tonemap shader becomes the resolve shader (flutter_scene_resolve.frag): it applies exposure, then color grading, then the tone mapping operator and the display EOTF. Grading is gated by a uniform flag, so a disabled grade renders identically to before. - packResolveInfo packs the ResolveInfo uniform block as a pure, unit-tested function. Toward #47.
Add a collapsible settings sidebar (top-right), shared by every example and the stress tests, with a collapsible Post-processing section holding color grading controls. - ExampleSettings holds the shared config; each example applies it to its scene before rendering, so one set of controls drives every scene. - Move the stress-tests back button and the nav-route car-controls menu to the top-left, below the example picker, clear of the new sidebar.
Three more built-in post-processing effects, folded into the single resolve pass. - New VignetteSettings, ChromaticAberrationSettings, and FilmGrainSettings on PostProcessSettings. All off by default. - The resolve shader samples with per-channel offsets for chromatic aberration, then darkens the edges (vignette) and adds animated noise (film grain) after tone mapping. Each is gated by a flag, so the disabled path is unchanged. - ResolveInfo grows to carry the new controls plus a time value for the grain. packResolveInfo and its tests cover the new layout. Toward #47.
Extend the shared post-processing sidebar with collapsible sections for the three new effects, each with an enable switch and sliders. The shared settings are copied onto every example's scene as before.
A multi-pass HDR bloom built-in: a soft-knee threshold blurred through a downsample/upsample mip chain, composited back into the scene color before tone mapping. - New BloomPass builds the bloom texture from the HDR scene color with three shaders (threshold, 13-tap downsample, tent upsample) and a chain of transient mips. Each step is its own full-screen pass, so no compute or mipmap generation is needed and it runs on WebGL2. - New BloomSettings (threshold, intensity, scatter) on PostProcessSettings, off by default. Scene.render adds BloomPass only when enabled. - The resolve shader samples the bloom texture and adds it in HDR before exposure. ResolveInfo and packResolveInfo carry the bloom controls. Toward #47.
A Bloom section with an enable switch and threshold/intensity/scatter sliders, applied to every example's scene like the other effects.
Lets users author their own post-processing effects as fragment shaders, the post-processing twin of ShaderMaterial. - New PostEffect (a fragment shader + insertion point + named uniform and texture bindings) and a customEffects list on PostProcessSettings. - PostEffectPass runs one effect as a full-screen pass; the engine binds the current color as input_color and, when useFrameInfo is set, a PostFrameInfo block (resolution, texel size, time). - Scene.render chains the effects: beforeTonemap effects ping-pong on HDR buffers and feed bloom and the resolve; afterTonemap effects run on the resolved image, the last writing the swapchain. The resolve writes to a transient when afterTonemap effects need to chain. - ShaderUniformBindings factors the name-keyed uniform/texture binding so PostEffect packs and binds like ShaderMaterial. Toward #47.
A user-authored wave-distortion shader (shaders/example_wave.frag) wired through PostEffect and exposed in the settings sidebar with an enable switch, an after-tone-mapping toggle, and an amplitude slider. Loaded from the example shader bundle at startup.
POST_PROCESSING.md, a sibling of MATERIALS.md: the built-in suite via Scene.postProcess, the custom PostEffect shader-authoring contract (input_color, the opt-in PostFrameInfo block, named uniforms, the two insertion points and their output contracts), a worked example, and the limitations. The 0.15.0 CHANGELOG entry is prepared release notes; the version bump and consumer-constraint widening are left for the release step. Toward #47.
Rebasing onto the OpenGL ES Y-flip work moved the render-to-texture Y-flip into the full-screen vertex shader, which now requires a FlipInfo uniform. The resolve pass picked it up in the merge, but the bloom and custom-effect passes are new files that did not bind it, so their full-screen geometry would collapse. Bind FlipInfo (backendYFlipSign) in BloomPass and PostEffectPass, matching the resolve pass. Toward #47.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resolves #47
Implements the post-processing effects chain from #47: a declarative built-in suite plus a user-authored custom-effect path, configured per scene through
Scene.postProcess. Everything is off by default.Screen.Recording.2026-05-24.at.10.22.50.PM.mov
Built-in suite (folded into the resolve pass, except bloom):
Custom effects:
PostEffectwraps a user fragment shader, the post-processing twin ofShaderMaterial. The engine binds the current color asinput_color(and aPostFrameInfoblock whenuseFrameInfois set); the author sets their own uniforms and textures by name. Effects run before or after tone mapping and chain through ping-pong buffers.The example app gained a shared, collapsible settings sidebar (top-right) that drives every example and the stress tests, with controls for each built-in plus a sample custom wave effect.
POST_PROCESSING.mddocuments the authoring contract (sibling ofMATERIALS.md).Built in six staged commits (engine plus example per stage), each verified on macOS. Rebased onto the OpenGL ES Y-flip rework (#144) and verified right-side-up with effects working on web (WebGL2) and macOS (Metal); the final commit binds the new
FlipInfovertex uniform in the bloom and post-effect passes.The 0.15.0 CHANGELOG entry is included. The version bump and consumer constraint widening are left for the release step.