forked from pmndrs/postprocessing
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRealisticBokehEffect.js
More file actions
225 lines (158 loc) · 4.66 KB
/
RealisticBokehEffect.js
File metadata and controls
225 lines (158 loc) · 4.66 KB
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
import { Uniform, Vector4 } from "three";
import { EffectAttribute } from "../enums/index.js";
import { Effect } from "./Effect.js";
import fragmentShader from "./glsl/realistic-bokeh.frag";
/**
* Depth of Field shader v2.4.
*
* Yields more realistic results but is also more demanding.
*
* Original shader code by Martins Upitis:
* http://blenderartists.org/forum/showthread.php?237488-GLSL-depth-of-field-with-bokeh-v2-4-(update)
*
* @deprecated Use DepthOfFieldEffect instead.
*/
export class RealisticBokehEffect extends Effect {
/**
* Constructs a new bokeh effect.
*
* @param {Object} [options] - The options.
* @param {BlendFunction} [options.blendFunction] - The blend function of this effect.
* @param {Number} [options.focus=1.0] - The focus distance in world units.
* @param {Number} [options.focalLength=24.0] - The focal length of the main camera.
* @param {Number} [options.fStop=0.9] - The ratio of the lens focal length to the diameter of the entrance pupil (aperture).
* @param {Number} [options.luminanceThreshold=0.5] - A luminance threshold.
* @param {Number} [options.luminanceGain=2.0] - A luminance gain factor.
* @param {Number} [options.bias=0.5] - A blur bias.
* @param {Number} [options.fringe=0.7] - A blur offset.
* @param {Number} [options.maxBlur=1.0] - The maximum blur strength.
* @param {Boolean} [options.rings=3] - The number of blur iterations.
* @param {Boolean} [options.samples=2] - The amount of samples taken per ring.
* @param {Boolean} [options.showFocus=false] - Whether the focal point should be highlighted. Useful for debugging.
* @param {Boolean} [options.manualDoF=false] - Enables manual control over the depth of field.
* @param {Boolean} [options.pentagon=false] - Enables pentagonal blur shapes. Requires a high number of rings and samples.
*/
constructor({
blendFunction,
focus = 1.0,
focalLength = 24.0,
fStop = 0.9,
luminanceThreshold = 0.5,
luminanceGain = 2.0,
bias = 0.5,
fringe = 0.7,
maxBlur = 1.0,
rings = 3,
samples = 2,
showFocus = false,
manualDoF = false,
pentagon = false
} = {}) {
super("RealisticBokehEffect", fragmentShader, {
blendFunction,
attributes: EffectAttribute.CONVOLUTION | EffectAttribute.DEPTH,
uniforms: new Map([
["focus", new Uniform(focus)],
["focalLength", new Uniform(focalLength)],
["fStop", new Uniform(fStop)],
["luminanceThreshold", new Uniform(luminanceThreshold)],
["luminanceGain", new Uniform(luminanceGain)],
["bias", new Uniform(bias)],
["fringe", new Uniform(fringe)],
["maxBlur", new Uniform(maxBlur)],
["dof", new Uniform(null)]
])
});
this.rings = rings;
this.samples = samples;
this.showFocus = showFocus;
this.manualDoF = manualDoF;
this.pentagon = pentagon;
}
/**
* The amount of blur iterations.
*
* @type {Number}
*/
get rings() {
return Number.parseInt(this.defines.get("RINGS_INT"));
}
set rings(value) {
const r = Math.floor(value);
this.defines.set("RINGS_INT", r.toFixed(0));
this.defines.set("RINGS_FLOAT", r.toFixed(1));
this.setChanged();
}
/**
* The amount of blur samples per ring.
*
* @type {Number}
*/
get samples() {
return Number.parseInt(this.defines.get("SAMPLES_INT"));
}
set samples(value) {
const s = Math.floor(value);
this.defines.set("SAMPLES_INT", s.toFixed(0));
this.defines.set("SAMPLES_FLOAT", s.toFixed(1));
this.setChanged();
}
/**
* Indicates whether the focal point will be highlighted.
*
* @type {Boolean}
*/
get showFocus() {
return this.defines.has("SHOW_FOCUS");
}
set showFocus(value) {
if(this.showFocus !== value) {
if(value) {
this.defines.set("SHOW_FOCUS", "1");
} else {
this.defines.delete("SHOW_FOCUS");
}
this.setChanged();
}
}
/**
* Indicates whether the Depth of Field should be calculated manually.
*
* If enabled, the Depth of Field can be adjusted via the `dof` uniform.
*
* @type {Boolean}
*/
get manualDoF() {
return this.defines.has("MANUAL_DOF");
}
set manualDoF(value) {
if(this.manualDoF !== value) {
if(value) {
this.defines.set("MANUAL_DOF", "1");
this.uniforms.get("dof").value = new Vector4(0.2, 1.0, 0.2, 2.0);
} else {
this.defines.delete("MANUAL_DOF");
this.uniforms.get("dof").value = null;
}
this.setChanged();
}
}
/**
* Indicates whether the blur shape should be pentagonal.
*
* @type {Boolean}
*/
get pentagon() {
return this.defines.has("PENTAGON");
}
set pentagon(value) {
if(this.pentagon !== value) {
if(value) {
this.defines.set("PENTAGON", "1");
} else {
this.defines.delete("PENTAGON");
}
this.setChanged();
}
}
}