-
-
Notifications
You must be signed in to change notification settings - Fork 35.7k
/
Copy pathhow-to-use-post-processing.html
142 lines (111 loc) · 6.17 KB
/
how-to-use-post-processing.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
<!DOCTYPE html><html lang="en"><head>
<meta charset="utf-8">
<title>How to use Post Processing</title>
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@threejs">
<meta name="twitter:title" content="Three.js – How to use Post Processing">
<meta property="og:image" content="https://threejs.org/files/share.png">
<link rel="shortcut icon" href="../../files/favicon_white.ico" media="(prefers-color-scheme: dark)">
<link rel="shortcut icon" href="../../files/favicon.ico" media="(prefers-color-scheme: light)">
<link rel="stylesheet" href="../resources/lesson.css">
<link rel="stylesheet" href="../resources/lang.css">
<script type="importmap">
{
"imports": {
"three": "../../build/three.module.js"
}
}
</script>
</head>
<body>
<div class="container">
<div class="lesson-title">
<h1>How to use Post Processing</h1>
</div>
<div class="lesson">
<div class="lesson-main">
<p>
Many three.js applications render their 3D objects directly to the screen. Sometimes, however, you want to apply one or more graphical
effects like Depth-Of-Field, Bloom, Film Grain or various types of Anti-aliasing. Post-processing is a widely used approach
to implement such effects. First, the scene is rendered to a render target which represents a buffer in the video card's memory.
In the next step one or more post-processing passes apply filters and effects to the image buffer before it is eventually rendered to
the screen.
</p>
<p>
three.js provides a complete post-processing solution via `EffectComposer` to implement such a workflow.
</p>
<h2>Workflow</h2>
<p>
The first step in the process is to import all necessary files from the examples directory. The guide assumes you are using the official
[link:https://www.npmjs.com/package/three npm package] of three.js. For our basic demo in this guide we need the following files.
</p>
<pre class="prettyprint notranslate lang-js" translate="no">
import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js';
import { RenderPass } from 'three/addons/postprocessing/RenderPass.js';
import { GlitchPass } from 'three/addons/postprocessing/GlitchPass.js';
import { OutputPass } from 'three/addons/postprocessing/OutputPass.js';
</pre>
<p>
After all files are successfully imported, we can create our composer by passing in an instance of `WebGLRenderer`.
</p>
<pre class="prettyprint notranslate lang-js" translate="no">
const composer = new EffectComposer( renderer );
</pre>
<p>
When using a composer, it's necessary to change the application's animation loop. Instead of calling the render method of
`WebGLRenderer`, we now use the respective counterpart of `EffectComposer`.
</p>
<pre class="prettyprint notranslate lang-js" translate="no">
function animate() {
requestAnimationFrame( animate );
composer.render();
}
</pre>
<p>
Our composer is now ready so it's possible to configure the chain of post-processing passes. These passes are responsible for creating
the final visual output of the application. They are processed in order of their addition/insertion. In our example, the instance of `RenderPass`
is executed first, then the instance of `GlitchPass` and finally `OutputPass`. The last enabled pass in the chain is automatically rendered to the screen.
The setup of the passes looks like so:
</p>
<pre class="prettyprint notranslate lang-js" translate="no">
const renderPass = new RenderPass( scene, camera );
composer.addPass( renderPass );
const glitchPass = new GlitchPass();
composer.addPass( glitchPass );
const outputPass = new OutputPass();
composer.addPass( outputPass );
</pre>
<p>
`RenderPass` is normally placed at the beginning of the chain in order to provide the rendered scene as an input for the next post-processing step. In our case,
`GlitchPass` is going to use these image data to apply a wild glitch effect. `OutputPass` is usually the last pass in the chain which performs sRGB color space conversion and tone mapping.
Check out this [link:https://threejs.org/examples/webgl_postprocessing_glitch live example] to see it in action.
</p>
<h2>Built-in Passes</h2>
<p>
You can use a wide range of pre-defined post-processing passes provided by the engine. They are located in the
[link:https://github.com/mrdoob/three.js/tree/dev/examples/jsm/postprocessing postprocessing] directory.
</p>
<h2>Custom Passes</h2>
<p>
Sometimes you want to write a custom post-processing shader and include it into the chain of post-processing passes. For this scenario,
you can utilize `ShaderPass`. After importing the file and your custom shader, you can use the following code to setup the pass.
</p>
<pre class="prettyprint notranslate lang-js" translate="no">
import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js';
import { LuminosityShader } from 'three/addons/shaders/LuminosityShader.js';
// later in your init routine
const luminosityPass = new ShaderPass( LuminosityShader );
composer.addPass( luminosityPass );
</pre>
<p>
The repository provides a file called [link:https://github.com/mrdoob/three.js/blob/master/examples/jsm/shaders/CopyShader.js CopyShader] which is a
good starting code for your own custom shader. `CopyShader` just copies the image contents of the `EffectComposer`'s read buffer
to its write buffer without applying any effects.
</p>
</div>
</div>
</div>
<script src="../resources/prettify.js"></script>
<script src="../resources/lesson.js"></script>
</body></html>