Chromatic Aberation

Hey! I’m mostly new to three.js and postprocessing. Is there a “easy” way to implement a chromatic aberration pass in a threejs scene? I’m already using Film and FXAA passes so I’m more or less familiar to how does work. thanks in advance!

I’ve created one that emulates lens distortion that lets you control the chromatic aberration and image barreling separately so it’s not necessarily physically correct but maybe you can get the look you’re going for. You’ll probably have to modify the script files to get them working in your project because they use a CDN but that shoulndn’t be too bad. Here’s a before / after image:

And here’s the project!

If you’re looking for one that separates colors consistently across the whole image rather than just at the edges then this may still serve as a good starting point.

4 Likes

Very cool.
What’s the best way to use a 2D mask to only apply the aberration and also blur to the corners of the camera image, a-la vignette?

For the aberration you could modify the shader in the example to adjust the intensity of the separation based on the distance to whatever “deadzone” you wanted for the effect or you could merge the aberration effect with the original image in another combination shader using a vignette mask.

You could do the same thing with blur – you’d have to pick whichever type of blur effect you were interested in adding and could then augment it or merge it based on the distance to the center of the frame. I don’t really think there’s a “best” way it just depends on what you’re trying to achieve in this case.

1 Like

Hey thanks for the reply.
I’ve searched, yet haven’t found example code showing a way of using a vignette mask to do so.
Would you know of any?
(Again, novice here)
Thanks!

Calling it a “mask” probably makes it sound easier than it is. At the moment there’s no way as far as I know to provide two rendered targets and a “mask” (generated or from an image) and have three.js blend them together. Visual shader nodes for materials may make this easier in the future but they’re still a ways off.

If no one else has written an effect that does what you want I would look into writing shaders with ShaderMaterial and postprocessing effects to make the effect your looking for.

Gotcha.
On a side note, I seem to recall someone somewhere talking about using something like a 2Dplane in three.js parented to a camera for this sort of thing… Thought I’d bring it up. Curious

If you just want tint the edges of the screen you can place a transparent plane in front of the camera with a texture and scale it so it exactly fits the camera frustum but you won’t be able to get any effects like blur or chromatic aberration that way. This is similar to a technique used in postprocessing, though, that just renders a plane in front of the camera with a material and uses the rendered frame as an input shader uniform. This is often called a “full screen quad” and there’s a utility in three.js’ postprocessing for it.

What about taking a render of the camera WITHOUT the full screen quad, but WITH the aberration and blur effects …having that rendered onto the fullscreen quad… Or a second one behind it… That uses the dark corners of a vignette as an alpha to show only the corners of the effects quad?

Then composite that on top of a plain render.

Kind of over extending here, but does any of what I said there have any workability?

I use all sorts of full screen quads for UI elements.
Surprised the compositing feature of three.js wouldn’t have a texture/alpha masking option to control where and when you’d like the effects to be in your final render.
(Or maybe I’m misunderstanding)

That’s basically what postprocessing does. Adding planes in front of the camera before rendering your normal scene I think overcomplicates things though and at some point you’ll just be rebuilding the postprocessing stack anyway. If you want to learn to add postprocessing effects I’d look into the three.js examples that provide blurs and vignettes already.

Surprised the compositing feature of three.js wouldn’t have a texture/alpha masking option to control where and when you’d like the effects to be in your final render.

It takes people wanting and contributing features to get them into a project. I’m also not necessarily sure it would be better. Again node materials will make this kind of thing easier but they are not built into three.js yet.