SPACE
to play / pauseARROW RIGHT
orL
to go forwardARROW LEFT
orJ
to go backwardARROW UP
to increase volumeARROW DOWN
to decrease volumeF
to toggle fullscreenM
to toggle mute0 to 9
to go to the corresponding part of the videoSHIFT
+,
to decrease playback speedSHIFT
+.
or;
to increase playback speed
Post-processing
React-three-postprocessing
- Github
- Documentation
- Effects (different from video)
- Custom effect (different from video)
General
Three.js documentation
Shortcuts ⌨️
⚠️ Update
If you get an error about the dependency tree unable to be resolved while trying to install postprocessing
, add the --force
parameter.
npm install --force postprocessing@6.35
⚠️ Update
Since we are using <ToneMapping>
, there is a difference and you can see everything glowing.
You can fix that by setting the luminanceThreshold
prop to 1.1
:
<Bloom luminanceThreshold={ 1.1 } />
More about this attribute later.
⚠️ Update
You’ll notice references to an effect named SSR
in the video and some leva controls associated with it.
As this effect is unstable, it has been removed from the lesson.
Unlock content 🔓
To get access to 93 hours of video, a members-only Discord server, subtitles, lesson resources, future updates and much more join us for only $95!
Want to learn more? 👋
That's the end of the free part 😔
To get access to 93 hours of video, a members-only Discord server and future updates, join us for only $95!
Introduction 00:00
Post-processing also benefits from the React and R3F system, as it has gotten easier to implement but is also optimized in some ways.
In this lesson, we are going to learn how it differs from the post-processing techniques we’ve covered before, implement a bunch of effects, and even create our own effects.
The issue with post-processing 01:11
In the previous lessons, we’ve used post-processing by adding passes.
Those passes had their own code and were completing one or multiple renders in order to achieve the desired result.
Then the next pass would do the same, and again, and again.
Those passes all occurred independently and some of them were doing the same renders (depth renders, normal renders, etc.), which resulted in performance issues and limited the number of passes we could add before getting a frame rate drop.
The solution 03:02
And this is exactly what Post Processing is trying to resolve.
The various passes will be merged into the least number of passes possible. In fact, we don’t talk about passes anymore, but we talk about “effects”.
Those effects will be merged together into one or multiple passes (if needed) automatically while keeping the order in which we added them.
We can even choose the blending of each effect (more about that later).
And, as you might’ve guessed, we can use Post Processing in R3F with @react-three/postprocessing.
Setup 04:27
In the starter, we have the classic orange sphere, purple cube, and green floor.
We also have a directional light source and an ambient light source.
The @react-three/drei
dependency is already installed within the project and we are using the OrbitControls
helper to be able to move the camera around.
We also have <Perf />
from r3f-perf
in order to keep an eye on performance.
Implement 04:56
We need two dependencies, @react-three/postprocessing
, and postprocessing
.
But for now, the only one we need to install is @react-three/postprocessing
since this dependency will also install postprocessing
.
In the terminal, use npm install @react-three/postprocessing@2.16
(we force the versions to prevent surprises, you can ignore potential vulnerability warnings).
In Experience.jsx
, import EffectComposer
from @react-three/postprocessing
:
import { EffectComposer } from '@react-three/postprocessing'
Although it’s the same name as the EffectComposer
we used in native Three.js, it’s not the same class.
Now, add it to the JSX:
export default function Experience()
{
return <>
<EffectComposer>
</EffectComposer>
{/* ... */}
</>
}
EffectComposer
is now running, but the colors are now completely off.
This is due to the tone mapping being deactivated in the post-processing rendering process for more appropriate color management.
We can fix that by adding the tone mapping ourselves as an effect at the end of the <EffectComposer>
.
Import ToneMapping
from @react-three/postprocessing
:
import { ToneMapping, EffectComposer } from '@react-three/postprocessing'
Then, add <ToneMapping>
inside <EffectComposer>
:
<EffectComposer>
<ToneMapping />
</EffectComposer>
That’s better, but the picture looks gray-ish.
This is due to the default tone mapping applied by ToneMapping
named AgX. AgX is a quite recent tone mapping which looks okay, but it’s not the default one used by R3F.
To change that, first we need to import the list from postprocessing
. Yes, I’m talking about the original postprocessing
library, not the React Three implementation.
Because we’ve added @react-three/postprocessing
to the project, we can already import things from postprocessing
directly, but it’s considered good practice to add it ourselves to the project so that we don’t have to rely on other dependencies.
In the terminal run npm install postprocessing@6.35
(we force the versions to prevent surprises, you can ignore potential vulnerability warnings).
If you get an error at this exact step, something about the dependency tree unable to be resolved, run npm install --force postprocessing@6.35
instead.
To get the list of blends, import available tone mappins from postprocessing
, we need to import ToneMappingMode
from postprocessing
:
import { ToneMappingMode } from 'postprocessing'
console.log(ToneMappingMode)
The one we want is ACES_FILMIC
and we can apply it to the <ToneMapping>
using the mode
prop:
<EffectComposer>
<ToneMapping mode={ ToneMappingMode.ACES_FILMIC } />
</EffectComposer>
The color is back.
Remove the console.log(ToneMappingMode)
.
Note that we don’t even need to add the first render, since Post Processing will take care of that.
Be careful, in the following parts, as you might have to reload the page after tweaking or adding an effect.
Multisampling
We can assign various attributes to the <EffectComposer>
, but the most interesting one is multisample
.
As discussed in the previous lessons, multi-sampling is used to prevent the aliasing effect (the little stairs on the edges of geometries).
By default, its value is at 8
and we can lower it down to 0
in order to disable it completely.
<EffectComposer multisampling={ 0 }>
<ToneMapping mode={ ToneMappingMode.ACES_FILMIC } />
</EffectComposer>
(Note that you will probably not see a big difference in the screenshot above because of the image compression)
Performance should be better when disabling multi-sampling, but we don’t really care about that in this lesson, so let’s remove it and keep the default value:
<EffectComposer>
<ToneMapping mode={ ToneMappingMode.ACES_FILMIC } />
</EffectComposer>
Finding effects and how to implement them 16:17
In the following part of the lesson, we are going to test a bunch of effects for the sake of learning.
We are going to set very specific values without going too much into detail because it would take ages and be boring.
But you should roam the documentation in order to discover the various effects, test them, and see how they work.
Unfortunately, the documentation (though useful) is a bit messy and spread across react-postprocessing and Post Processing, which means you’ll have to dig a little in order to find what you are looking for.
Here are the links that you might need.
Post Processing:
- The repository: https://github.com/pmndrs/postprocessing
- The documentation (generated from the code): https://pmndrs.github.io/postprocessing/public/docs/
- A demo page (you can change the effect within the debug UI): https://pmndrs.github.io/postprocessing/public/demo/
React-postprocessing:
- The repository: https://github.com/pmndrs/reactpostprocessing
- The list of effects implemented from postprocessing to React postprocessing: https://github.com/pmndrs/postprocessing#included-effects
- The documentation (very similar to the repo, but more user-friendly): https://docs.pmnd.rs/react-postprocessing/introduction
Vignette effect 21:10
Let’s start with a very common effect, the Vignette effect.
Vignette will make the corners of the render a little darker.
How to use it 🤔
- Download the Starter pack or Final project
- Unzip it
- Open your terminal and go to the unzip folder
-
Run
npm install
to install dependencies
(if your terminal warns you about vulnerabilities, ignore it) -
Run
npm run dev
to launch the local server
(project should open on your default browser automatically) - Start coding
- The JS is located in src/script.js
- The HTML is located in src/index.html
- The CSS is located in src/style.css