@react-three/postprocessing 2.15.4 → 2.15.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,9 +1,172 @@
|
|
|
1
1
|
import { Effect, Selection, Pass, RenderPass, DepthPass } from "postprocessing";
|
|
2
2
|
import { ShaderChunk, Color, Vector2, WebGLCubeRenderTarget, Uniform, CubeCamera, PMREMGenerator, LinearFilter, Vector3, Texture, WebGLRenderTarget, HalfFloatType, WebGLMultipleRenderTargets, Quaternion, NearestFilter, FramebufferTexture, RGBAFormat, ShaderMaterial, Matrix3, REVISION, TangentSpaceNormalMap, GLSL3, Matrix4, VideoTexture, DataTexture, FloatType } from "three";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
const boxBlur = (
|
|
4
|
+
/* glsl */
|
|
5
|
+
`
|
|
6
|
+
uniform float blur;
|
|
7
|
+
uniform float blurSharpness;
|
|
8
|
+
uniform int blurKernel;
|
|
9
|
+
|
|
10
|
+
vec3 denoise(
|
|
11
|
+
vec3 center,
|
|
12
|
+
sampler2D tex,
|
|
13
|
+
vec2 uv,
|
|
14
|
+
vec2 invTexSize,
|
|
15
|
+
float blur,
|
|
16
|
+
float blurSharpness,
|
|
17
|
+
int blurKernel
|
|
18
|
+
) {
|
|
19
|
+
vec3 color, col;
|
|
20
|
+
float total, weight;
|
|
21
|
+
|
|
22
|
+
for (int x = -blurKernel; x <= blurKernel; x++) {
|
|
23
|
+
for (int y=-blurKernel; y<=blurKernel; y++) {
|
|
24
|
+
col = textureLod(tex, uv + vec2(x,y) * invTexSize, 0.0).rgb;
|
|
25
|
+
weight = 1.0-abs(dot(col - center, vec3(0.25)));
|
|
26
|
+
weight = pow(weight, blurSharpness);
|
|
27
|
+
color += col * weight;
|
|
28
|
+
total += weight;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return color / total;
|
|
33
|
+
}
|
|
34
|
+
`
|
|
35
|
+
);
|
|
36
|
+
const finalSSRShader = (
|
|
37
|
+
/* glsl */
|
|
38
|
+
`
|
|
39
|
+
#define MODE_DEFAULT 0
|
|
40
|
+
#define MODE_REFLECTIONS 1
|
|
41
|
+
#define MODE_RAW_REFLECTION 2
|
|
42
|
+
#define MODE_BLURRED_REFLECTIONS 3
|
|
43
|
+
#define MODE_INPUT 4
|
|
44
|
+
#define MODE_BLUR_MIX 5
|
|
45
|
+
#define FLOAT_EPSILON 0.00001
|
|
46
|
+
// uniform sampler2D inputTexture;
|
|
47
|
+
uniform sampler2D reflectionsTexture;
|
|
48
|
+
// uniform float samples;
|
|
49
|
+
|
|
50
|
+
${boxBlur}
|
|
51
|
+
|
|
52
|
+
void mainImage(const in vec4 inputColor, const in vec2 uv, out vec4 outputColor) {
|
|
53
|
+
vec4 reflectionsTexel=texture2D(reflectionsTexture, vUv);
|
|
54
|
+
ivec2 size = textureSize(reflectionsTexture, 0);
|
|
55
|
+
vec2 invTexSize= 1.0 / vec2(size.x, size.y);
|
|
56
|
+
vec3 reflectionClr = reflectionsTexel.xyz;
|
|
57
|
+
if (blur > FLOAT_EPSILON) {
|
|
58
|
+
vec3 blurredReflectionsColor = denoise(
|
|
59
|
+
reflectionsTexel.rgb,
|
|
60
|
+
reflectionsTexture,
|
|
61
|
+
vUv,
|
|
62
|
+
invTexSize,
|
|
63
|
+
blur,
|
|
64
|
+
blurSharpness,
|
|
65
|
+
blurKernel
|
|
66
|
+
);
|
|
67
|
+
reflectionClr = mix(reflectionClr, blurredReflectionsColor.rgb, blur);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
#if RENDER_MODE == MODE_DEFAULT
|
|
71
|
+
outputColor = vec4(inputColor.rgb+reflectionClr, 1.0);
|
|
72
|
+
#endif
|
|
73
|
+
#if RENDER_MODE == MODE_REFLECTIONS
|
|
74
|
+
outputColor = vec4(reflectionClr, 1.0);
|
|
75
|
+
#endif
|
|
76
|
+
#if RENDER_MODE == MODE_RAW_REFLECTION
|
|
77
|
+
outputColor = vec4(reflectionsTexel.xyz, 1.0);
|
|
78
|
+
#endif
|
|
79
|
+
#if RENDER_MODE == MODE_BLURRED_REFLECTIONS
|
|
80
|
+
outputColor = vec4(blurredReflectionsTexel.xyz, 1.0);
|
|
81
|
+
#endif
|
|
82
|
+
#if RENDER_MODE == MODE_INPUT
|
|
83
|
+
outputColor = vec4(inputColor.xyz, 1.0);
|
|
84
|
+
#endif
|
|
85
|
+
#if RENDER_MODE == MODE_BLUR_MIX
|
|
86
|
+
outputColor = vec4(vec3(blur), 1.0);
|
|
87
|
+
#endif
|
|
88
|
+
}
|
|
89
|
+
`
|
|
90
|
+
);
|
|
91
|
+
const helperFunctions = (
|
|
92
|
+
/* glsl */
|
|
93
|
+
`
|
|
94
|
+
vec3 getViewPosition(const float depth) {
|
|
95
|
+
float clipW= _projectionMatrix[2][3] * depth + _projectionMatrix[3][3];
|
|
96
|
+
vec4 clipPosition = vec4((vec3(vUv, depth) - 0.5) * 2.0, 1.0);
|
|
97
|
+
clipPosition *= clipW;
|
|
98
|
+
return(_inverseProjectionMatrix * clipPosition).xyz;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
float getViewZ(const in float depth) {
|
|
102
|
+
#ifdef PERSPECTIVE_CAMERA
|
|
103
|
+
return perspectiveDepthToViewZ(depth, cameraNear, cameraFar);
|
|
104
|
+
#else
|
|
105
|
+
return orthographicDepthToViewZ(depth, cameraNear, cameraFar);
|
|
106
|
+
#endif
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
vec3 screenSpaceToWorldSpace(const vec2 uv,const float depth){
|
|
110
|
+
vec4 ndc = vec4((uv.x - 0.5) * 2.0,(uv.y - 0.5)* 2.0, (depth - 0.5) * 2.0, 1.0);
|
|
111
|
+
vec4 clip= _inverseProjectionMatrix*ndc;
|
|
112
|
+
vec4 view = cameraMatrixWorld * (clip / clip.w);
|
|
113
|
+
return view.xyz;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
#define Scale (vec3(0.8, 0.8, 0.8))
|
|
117
|
+
#define K (19.19)
|
|
118
|
+
|
|
119
|
+
vec3 hash(vec3 a) {
|
|
120
|
+
a = fract(a * Scale);
|
|
121
|
+
a += dot(a, a.yxz + K);
|
|
122
|
+
return fract((a.xxy + a.yxx) * a.zyx);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
float fresnel_dielectric_cos(float cosi, float eta){
|
|
126
|
+
float c = abs(cosi);
|
|
127
|
+
float g = eta * eta - 1.0 + c* c;
|
|
128
|
+
float result;
|
|
129
|
+
|
|
130
|
+
if (g > 0.0){
|
|
131
|
+
g = sqrt(g);
|
|
132
|
+
float A = (g - c) / (g + c);
|
|
133
|
+
float B = (c* (g + c) - 1.0) / (c * (g - c) + 1.0);
|
|
134
|
+
result = 0.5 * A * A * (1.0 + B * B);
|
|
135
|
+
} else {
|
|
136
|
+
result = 1.0;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return result;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
float fresnel_dielectric(vec3 Incoming, vec3 Normal, float eta){
|
|
143
|
+
float cosine = dot(Incoming, Normal);
|
|
144
|
+
return min(1.0, 5.0 * fresnel_dielectric_cos(cosine, eta));
|
|
145
|
+
}
|
|
146
|
+
`
|
|
147
|
+
);
|
|
148
|
+
const trCompose = (
|
|
149
|
+
/* glsl */
|
|
150
|
+
`
|
|
151
|
+
#define INV_EULER 0.36787944117144233
|
|
152
|
+
|
|
153
|
+
alpha = velocityDisocclusion < FLOAT_EPSILON ? (alpha + 0.0075) : 0.0;
|
|
154
|
+
alpha = clamp(alpha, 0.0, 1.0);
|
|
155
|
+
bool needsBlur = !didReproject || velocityDisocclusion > 0.5;
|
|
156
|
+
|
|
157
|
+
#ifdef boxBlur
|
|
158
|
+
if (needsBlur) inputColor = boxBlurredColor;
|
|
159
|
+
#endif
|
|
160
|
+
|
|
161
|
+
if (alpha == 1.0) {
|
|
162
|
+
outputColor = accumulatedColor;
|
|
163
|
+
} else {
|
|
164
|
+
float m = mix(alpha, 1.0, blend);
|
|
165
|
+
if (needsBlur) m = 0.0;
|
|
166
|
+
outputColor = accumulatedColor * m + inputColor * (1.0 - m);
|
|
167
|
+
}
|
|
168
|
+
`
|
|
169
|
+
);
|
|
7
170
|
class MRTMaterial extends ShaderMaterial {
|
|
8
171
|
constructor() {
|
|
9
172
|
super({
|
|
@@ -23,103 +186,102 @@ class MRTMaterial extends ShaderMaterial {
|
|
|
23
186
|
vertexShader: (
|
|
24
187
|
/* glsl */
|
|
25
188
|
`
|
|
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
|
-
|
|
189
|
+
#ifdef USE_MRT
|
|
190
|
+
varying vec2 vHighPrecisionZW;
|
|
191
|
+
#endif
|
|
192
|
+
#define NORMAL
|
|
193
|
+
#if defined(FLAT_SHADED) || defined(USE_BUMPMAP) || defined(TANGENTSPACE_NORMALMAP)
|
|
194
|
+
varying vec3 vViewPosition;
|
|
195
|
+
#endif
|
|
196
|
+
#include <common>
|
|
197
|
+
#include <uv_pars_vertex>
|
|
198
|
+
#include <displacementmap_pars_vertex>
|
|
199
|
+
#include <normal_pars_vertex>
|
|
200
|
+
#include <morphtarget_pars_vertex>
|
|
201
|
+
#include <skinning_pars_vertex>
|
|
202
|
+
#include <logdepthbuf_pars_vertex>
|
|
203
|
+
#include <clipping_planes_pars_vertex>
|
|
204
|
+
#ifdef USE_UV
|
|
205
|
+
${REVISION.replace(/\D+/g, "") >= 151 ? "uniform mat3 uvTransform;" : ""}
|
|
206
|
+
#endif
|
|
207
|
+
void main() {
|
|
208
|
+
#include <uv_vertex>
|
|
209
|
+
#include <beginnormal_vertex>
|
|
210
|
+
#include <morphnormal_vertex>
|
|
211
|
+
#include <skinbase_vertex>
|
|
212
|
+
#include <skinnormal_vertex>
|
|
213
|
+
#include <defaultnormal_vertex>
|
|
214
|
+
#include <normal_vertex>
|
|
215
|
+
#include <begin_vertex>
|
|
216
|
+
#include <morphtarget_vertex>
|
|
217
|
+
#include <skinning_vertex>
|
|
218
|
+
#include <displacementmap_vertex>
|
|
219
|
+
#include <project_vertex>
|
|
220
|
+
#include <logdepthbuf_vertex>
|
|
221
|
+
#include <clipping_planes_vertex>
|
|
222
|
+
#if defined(FLAT_SHADED) || defined(USE_BUMPMAP) || defined(TANGENTSPACE_NORMALMAP)
|
|
223
|
+
vViewPosition = -mvPosition.xyz;
|
|
224
|
+
#endif
|
|
225
|
+
#ifdef USE_MRT
|
|
226
|
+
vHighPrecisionZW = gl_Position.zw;
|
|
227
|
+
#endif
|
|
228
|
+
#ifdef USE_UV
|
|
229
|
+
vUv = (uvTransform * vec3(uv, 1)).xy;
|
|
230
|
+
#endif
|
|
231
|
+
}
|
|
232
|
+
`
|
|
70
233
|
),
|
|
71
234
|
fragmentShader: (
|
|
72
235
|
/* glsl */
|
|
73
236
|
`
|
|
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
|
-
`
|
|
237
|
+
#define NORMAL
|
|
238
|
+
#if defined(FLAT_SHADED) || defined(USE_BUMPMAP) || defined(TANGENTSPACE_NORMALMAP)
|
|
239
|
+
varying vec3 vViewPosition;
|
|
240
|
+
#endif
|
|
241
|
+
#include <packing>
|
|
242
|
+
#include <uv_pars_fragment>
|
|
243
|
+
#include <normal_pars_fragment>
|
|
244
|
+
#include <bumpmap_pars_fragment>
|
|
245
|
+
#include <normalmap_pars_fragment>
|
|
246
|
+
#include <logdepthbuf_pars_fragment>
|
|
247
|
+
#include <clipping_planes_pars_fragment>
|
|
248
|
+
#include <roughnessmap_pars_fragment>
|
|
249
|
+
|
|
250
|
+
#ifdef USE_MRT
|
|
251
|
+
layout(location = 0) out vec4 gNormal;
|
|
252
|
+
layout(location = 1) out vec4 gDepth;
|
|
253
|
+
varying vec2 vHighPrecisionZW;
|
|
254
|
+
#endif
|
|
255
|
+
uniform float roughness;
|
|
256
|
+
void main() {
|
|
257
|
+
#include <clipping_planes_fragment>
|
|
258
|
+
#include <logdepthbuf_fragment>
|
|
259
|
+
#include <normal_fragment_begin>
|
|
260
|
+
#include <normal_fragment_maps>
|
|
261
|
+
|
|
262
|
+
float roughnessFactor = roughness;
|
|
263
|
+
|
|
264
|
+
if (roughness > 10.0e9){
|
|
265
|
+
roughnessFactor = 1.;
|
|
266
|
+
} else {
|
|
267
|
+
#ifdef useRoughnessMap
|
|
268
|
+
vec4 texelRoughness = texture2D(roughnessMap, vUv);
|
|
269
|
+
// reads channel G, compatible with a combined OcclusionRoughnessMetallic (RGB) texture
|
|
270
|
+
roughnessFactor *= texelRoughness.g;
|
|
271
|
+
#endif
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
vec3 normalColor = packNormalToRGB(normal);
|
|
275
|
+
#ifdef USE_MRT
|
|
276
|
+
float fragCoordZ = 0.5 * vHighPrecisionZW[0] / vHighPrecisionZW[1] + 0.5;
|
|
277
|
+
vec4 depthColor = packDepthToRGBA(fragCoordZ);
|
|
278
|
+
gNormal = vec4(normalColor, roughnessFactor);
|
|
279
|
+
gDepth = depthColor;
|
|
280
|
+
#else
|
|
281
|
+
gl_FragColor = vec4(normalColor, roughnessFactor);
|
|
282
|
+
#endif
|
|
283
|
+
}
|
|
284
|
+
`
|
|
123
285
|
),
|
|
124
286
|
toneMapped: false
|
|
125
287
|
});
|
|
@@ -134,8 +296,254 @@ class MRTMaterial extends ShaderMaterial {
|
|
|
134
296
|
});
|
|
135
297
|
}
|
|
136
298
|
}
|
|
137
|
-
|
|
138
|
-
|
|
299
|
+
const vertexShader = (
|
|
300
|
+
/* glsl */
|
|
301
|
+
`
|
|
302
|
+
varying vec2 vUv;
|
|
303
|
+
|
|
304
|
+
void main() {
|
|
305
|
+
vUv = position.xy * 0.5 + 0.5;
|
|
306
|
+
gl_Position = vec4(position.xy, 1.0, 1.0);
|
|
307
|
+
}
|
|
308
|
+
`
|
|
309
|
+
);
|
|
310
|
+
const fragmentShader = (
|
|
311
|
+
/* glsl */
|
|
312
|
+
`
|
|
313
|
+
varying vec2 vUv;
|
|
314
|
+
uniform sampler2D inputTexture;
|
|
315
|
+
uniform sampler2D accumulatedTexture;
|
|
316
|
+
uniform sampler2D normalTexture;
|
|
317
|
+
uniform sampler2D depthTexture;
|
|
318
|
+
uniform sampler2D envMap;
|
|
319
|
+
uniform mat4 _projectionMatrix;
|
|
320
|
+
uniform mat4 _inverseProjectionMatrix;
|
|
321
|
+
uniform mat4 cameraMatrixWorld;
|
|
322
|
+
uniform float cameraNear;
|
|
323
|
+
uniform float cameraFar;
|
|
324
|
+
uniform float rayDistance;
|
|
325
|
+
uniform float intensity;
|
|
326
|
+
uniform float maxDepthDifference;
|
|
327
|
+
uniform float roughnessFade;
|
|
328
|
+
uniform float maxRoughness;
|
|
329
|
+
uniform float fade;
|
|
330
|
+
uniform float thickness;
|
|
331
|
+
uniform float ior;
|
|
332
|
+
uniform float samples;
|
|
333
|
+
uniform float jitter;
|
|
334
|
+
uniform float jitterRoughness;
|
|
335
|
+
|
|
336
|
+
#define INVALID_RAY_COORDS vec2(-1.0);
|
|
337
|
+
|
|
338
|
+
#define EARLY_OUT_COLOR vec4(0.0, 0.0, 0.0, 1.0)
|
|
339
|
+
#define FLOAT_EPSILON 0.00001
|
|
340
|
+
float nearMinusFar;
|
|
341
|
+
float nearMulFar;
|
|
342
|
+
float farMinusNear;
|
|
343
|
+
|
|
344
|
+
#include <packing>
|
|
345
|
+
|
|
346
|
+
${helperFunctions}
|
|
347
|
+
|
|
348
|
+
vec2 RayMarch(vec3 dir, inout vec3 hitPos, inout float rayHitDepthDifference);
|
|
349
|
+
vec2 BinarySearch(in vec3 dir, inout vec3 hitPos, inout float rayHitDepthDifference);
|
|
350
|
+
float fastGetViewZ(const in float depth);
|
|
351
|
+
vec3 getIBLRadiance(const in vec3 viewDir, const in vec3 normal, const in float roughness);
|
|
352
|
+
|
|
353
|
+
void main() {
|
|
354
|
+
vec4 depthTexel = textureLod(depthTexture, vUv, 0.0);
|
|
355
|
+
|
|
356
|
+
if (dot(depthTexel.rgb, depthTexel.rgb) < FLOAT_EPSILON) {
|
|
357
|
+
gl_FragColor = EARLY_OUT_COLOR;
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
float unpackedDepth = unpackRGBAToDepth(depthTexel);
|
|
362
|
+
vec4 normalTexel = textureLod(normalTexture, vUv, 0.0);
|
|
363
|
+
float roughness = normalTexel.a;
|
|
364
|
+
float specular = 1.0 - roughness;
|
|
365
|
+
|
|
366
|
+
nearMinusFar = cameraNear - cameraFar;
|
|
367
|
+
nearMulFar = cameraNear * cameraFar;
|
|
368
|
+
farMinusNear = cameraFar - cameraNear;
|
|
369
|
+
|
|
370
|
+
normalTexel.rgb = unpackRGBToNormal(normalTexel.rgb);
|
|
371
|
+
|
|
372
|
+
float depth = fastGetViewZ(unpackedDepth);
|
|
373
|
+
vec3 viewPos = getViewPosition(depth);
|
|
374
|
+
vec3 viewDir = normalize(viewPos);
|
|
375
|
+
vec3 viewNormal = normalTexel.xyz;
|
|
376
|
+
vec3 worldPos = screenSpaceToWorldSpace(vUv, unpackedDepth);
|
|
377
|
+
|
|
378
|
+
vec3 jitt=vec3(0.0);
|
|
379
|
+
if (jitterRoughness != 0.0 || jitter!=0.0){
|
|
380
|
+
vec3 randomJitter = hash(50.0 * samples * worldPos) - 0.5;
|
|
381
|
+
float spread= ((2.0 - specular) + roughness * jitterRoughness);
|
|
382
|
+
float jitterMix = jitter * 0.25 + jitterRoughness * roughness;
|
|
383
|
+
if (jitterMix > 1.0) jitterMix = 1.0;
|
|
384
|
+
jitt = mix(vec3(0.0), randomJitter * spread, jitterMix);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
viewNormal += jitt;
|
|
388
|
+
float fresnelFactor = fresnel_dielectric(viewDir, viewNormal, ior);
|
|
389
|
+
vec3 iblRadiance = getIBLRadiance(-viewDir, viewNormal, 0.0) * fresnelFactor;
|
|
390
|
+
float lastFrameAlpha = textureLod(accumulatedTexture, vUv, 0.0).a;
|
|
391
|
+
if (roughness > maxRoughness || (roughness > 1.0 - FLOAT_EPSILON && roughnessFade > 1.0 - FLOAT_EPSILON)) {
|
|
392
|
+
gl_FragColor=vec4(iblRadiance,lastFrameAlpha);
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
vec3 reflected = reflect(viewDir, viewNormal);
|
|
397
|
+
vec3 rayDir = reflected *- viewPos.z;
|
|
398
|
+
vec3 hitPos = viewPos;
|
|
399
|
+
float rayHitDepthDifference;
|
|
400
|
+
vec2 coords = RayMarch(rayDir, hitPos, rayHitDepthDifference);
|
|
401
|
+
if (coords.x == -1.0){
|
|
402
|
+
gl_FragColor=vec4(iblRadiance, lastFrameAlpha);
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
vec4 SSRTexel = textureLod(inputTexture, coords.xy, 0.0);
|
|
407
|
+
vec4 SSRTexelReflected = textureLod(accumulatedTexture, coords.xy, 0.0);
|
|
408
|
+
vec3 SSR = SSRTexel.rgb + SSRTexelReflected.rgb;
|
|
409
|
+
float roughnessFactor = mix(specular, 1.0, max(0.0, 1.0 - roughnessFade));
|
|
410
|
+
vec2 coordsNDC = (coords.xy * 2.0 - 1.0);
|
|
411
|
+
float screenFade = 0.1;
|
|
412
|
+
float maxDimension = min(1.0, max(abs(coordsNDC.x), abs(coordsNDC.y)));
|
|
413
|
+
float reflectionIntensity = 1.0 - (max(0.0, maxDimension - screenFade) / (1.0 - screenFade));
|
|
414
|
+
reflectionIntensity = max(0.0, reflectionIntensity);
|
|
415
|
+
vec3 finalSSR = mix(iblRadiance, SSR, reflectionIntensity) * roughnessFactor;
|
|
416
|
+
|
|
417
|
+
if (fade != 0.0) {
|
|
418
|
+
vec3 hitWorldPos = screenSpaceToWorldSpace(coords, rayHitDepthDifference);
|
|
419
|
+
float reflectionDistance = distance(hitWorldPos, worldPos) + 1.0;
|
|
420
|
+
float opacity = 1.0 / (reflectionDistance * fade * 0.1);
|
|
421
|
+
if(opacity > 1.0) opacity=1.0;
|
|
422
|
+
finalSSR *= opacity;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
finalSSR *= fresnelFactor * intensity;
|
|
426
|
+
finalSSR = min(vec3(1.0), finalSSR);
|
|
427
|
+
float alpha = hitPos.z == 1.0 ? 1.0 : SSRTexelReflected.a;
|
|
428
|
+
alpha = min(lastFrameAlpha, alpha);
|
|
429
|
+
gl_FragColor = vec4(finalSSR, alpha);
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
vec2 RayMarch(vec3 dir, inout vec3 hitPos, inout float rayHitDepthDifference) {
|
|
433
|
+
dir=normalize(dir);
|
|
434
|
+
dir *= rayDistance / float(steps);
|
|
435
|
+
float depth;
|
|
436
|
+
vec4 projectedCoord;
|
|
437
|
+
vec4 lastProjectedCoord;
|
|
438
|
+
float unpackedDepth;
|
|
439
|
+
vec4 depthTexel;
|
|
440
|
+
|
|
441
|
+
for (int i = 0; i < steps; i++) {
|
|
442
|
+
hitPos += dir;
|
|
443
|
+
projectedCoord = _projectionMatrix * vec4(hitPos, 1.0);
|
|
444
|
+
projectedCoord.xy /= projectedCoord.w;
|
|
445
|
+
projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
|
|
446
|
+
|
|
447
|
+
#ifndef missedRays
|
|
448
|
+
if (
|
|
449
|
+
projectedCoord.x < 0.0 ||
|
|
450
|
+
projectedCoord.x > 1.0 ||
|
|
451
|
+
projectedCoord.y < 0.0 ||
|
|
452
|
+
projectedCoord.y > 1.0
|
|
453
|
+
) {
|
|
454
|
+
return INVALID_RAY_COORDS;
|
|
455
|
+
}
|
|
456
|
+
#endif
|
|
457
|
+
|
|
458
|
+
depthTexel = textureLod(depthTexture, projectedCoord.xy, 0.0);
|
|
459
|
+
unpackedDepth = unpackRGBAToDepth(depthTexel);
|
|
460
|
+
depth = fastGetViewZ(unpackedDepth);
|
|
461
|
+
rayHitDepthDifference = depth - hitPos.z;
|
|
462
|
+
|
|
463
|
+
if (rayHitDepthDifference >= 0.0 && rayHitDepthDifference < thickness){
|
|
464
|
+
#if refineSteps == 0
|
|
465
|
+
if (dot(depthTexel.rgb, depthTexel.rgb) < FLOAT_EPSILON) return INVALID_RAY_COORDS;
|
|
466
|
+
#else
|
|
467
|
+
return BinarySearch(dir, hitPos, rayHitDepthDifference);
|
|
468
|
+
#endif
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
#ifndef missedRays
|
|
472
|
+
if (hitPos.z > 0.0) return INVALID_RAY_COORDS;
|
|
473
|
+
#endif
|
|
474
|
+
|
|
475
|
+
lastProjectedCoord = projectedCoord;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
hitPos.z = 1.0;
|
|
479
|
+
|
|
480
|
+
#ifndef missedRays
|
|
481
|
+
return INVALID_RAY_COORDS;
|
|
482
|
+
#endif
|
|
483
|
+
|
|
484
|
+
rayHitDepthDifference = unpackedDepth;
|
|
485
|
+
|
|
486
|
+
return projectedCoord.xy;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
vec2 BinarySearch(in vec3 dir, inout vec3 hitPos, inout float rayHitDepthDifference) {
|
|
490
|
+
float depth;
|
|
491
|
+
vec4 projectedCoord;
|
|
492
|
+
vec2 lastMinProjectedCoordXY;
|
|
493
|
+
float unpackedDepth;
|
|
494
|
+
vec4 depthTexel;
|
|
495
|
+
|
|
496
|
+
for (int i = 0; i < refineSteps; i++){
|
|
497
|
+
projectedCoord = _projectionMatrix * vec4(hitPos, 1.0);
|
|
498
|
+
projectedCoord.xy /= projectedCoord.w;
|
|
499
|
+
projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
|
|
500
|
+
depthTexel = textureLod(depthTexture, projectedCoord.xy, 0.0);
|
|
501
|
+
unpackedDepth = unpackRGBAToDepth(depthTexel);
|
|
502
|
+
depth = fastGetViewZ(unpackedDepth);
|
|
503
|
+
rayHitDepthDifference = depth - hitPos.z;
|
|
504
|
+
dir *= 0.5;
|
|
505
|
+
|
|
506
|
+
if (rayHitDepthDifference > 0.0) {
|
|
507
|
+
hitPos -= dir;
|
|
508
|
+
} else {
|
|
509
|
+
hitPos += dir;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
if (dot(depthTexel.rgb, depthTexel.rgb) < FLOAT_EPSILON) return INVALID_RAY_COORDS;
|
|
514
|
+
if (abs(rayHitDepthDifference) > maxDepthDifference) return INVALID_RAY_COORDS;
|
|
515
|
+
|
|
516
|
+
projectedCoord = _projectionMatrix*vec4(hitPos, 1.0);
|
|
517
|
+
projectedCoord.xy /= projectedCoord.w;
|
|
518
|
+
projectedCoord.xy = projectedCoord.xy * 0.5 + 0.5;
|
|
519
|
+
rayHitDepthDifference = unpackedDepth;
|
|
520
|
+
return projectedCoord.xy;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
float fastGetViewZ(const in float depth){
|
|
524
|
+
#ifdef PERSPECTIVE_CAMERA
|
|
525
|
+
return nearMulFar / (farMinusNear * depth - cameraFar);
|
|
526
|
+
#else
|
|
527
|
+
return depth * nearMinusFar - cameraNear;
|
|
528
|
+
#endif
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
#include <common>
|
|
532
|
+
#include <cube_uv_reflection_fragment>
|
|
533
|
+
|
|
534
|
+
vec3 getIBLRadiance(const in vec3 viewDir, const in vec3 normal, const in float roughness){
|
|
535
|
+
#if defined(ENVMAP_TYPE_CUBE_UV)
|
|
536
|
+
vec3 reflectVec = reflect(-viewDir, normal);
|
|
537
|
+
reflectVec = normalize(mix(reflectVec, normal,roughness * roughness));
|
|
538
|
+
reflectVec = inverseTransformDirection(reflectVec, viewMatrix);
|
|
539
|
+
vec4 envMapColor = textureCubeUV(envMap, reflectVec, roughness);
|
|
540
|
+
return envMapColor.rgb * intensity;
|
|
541
|
+
#else
|
|
542
|
+
return vec3(0.0);
|
|
543
|
+
#endif
|
|
544
|
+
}
|
|
545
|
+
`
|
|
546
|
+
);
|
|
139
547
|
class ReflectionsMaterial extends ShaderMaterial {
|
|
140
548
|
constructor() {
|
|
141
549
|
super({
|
|
@@ -174,8 +582,8 @@ class ReflectionsMaterial extends ShaderMaterial {
|
|
|
174
582
|
CUBEUV_MAX_MIP: 0,
|
|
175
583
|
vWorldPosition: "worldPos"
|
|
176
584
|
},
|
|
177
|
-
fragmentShader
|
|
178
|
-
vertexShader
|
|
585
|
+
fragmentShader,
|
|
586
|
+
vertexShader,
|
|
179
587
|
toneMapped: false,
|
|
180
588
|
depthWrite: false,
|
|
181
589
|
depthTest: false
|
|
@@ -397,8 +805,160 @@ const defaultSSROptions = {
|
|
|
397
805
|
resolutionScale: 1,
|
|
398
806
|
velocityResolutionScale: 1
|
|
399
807
|
};
|
|
400
|
-
|
|
401
|
-
|
|
808
|
+
const temporalResolve = (
|
|
809
|
+
/* glsl */
|
|
810
|
+
`
|
|
811
|
+
uniform sampler2D inputTexture;
|
|
812
|
+
uniform sampler2D accumulatedTexture;
|
|
813
|
+
uniform sampler2D velocityTexture;
|
|
814
|
+
uniform sampler2D lastVelocityTexture;
|
|
815
|
+
uniform float blend;
|
|
816
|
+
uniform float correction;
|
|
817
|
+
uniform float exponent;
|
|
818
|
+
uniform float samples;
|
|
819
|
+
uniform vec2 invTexSize;
|
|
820
|
+
uniform mat4 curInverseProjectionMatrix;
|
|
821
|
+
uniform mat4 curCameraMatrixWorld;
|
|
822
|
+
uniform mat4 prevInverseProjectionMatrix;
|
|
823
|
+
uniform mat4 prevCameraMatrixWorld;
|
|
824
|
+
varying vec2 vUv;
|
|
825
|
+
|
|
826
|
+
#define MAX_NEIGHBOR_DEPTH_DIFFERENCE 0.001
|
|
827
|
+
#define FLOAT_EPSILON 0.00001
|
|
828
|
+
#define FLOAT_ONE_MINUS_EPSILON 0.99999
|
|
829
|
+
|
|
830
|
+
vec3 transformexponent;
|
|
831
|
+
vec3 undoColorTransformExponent;
|
|
832
|
+
|
|
833
|
+
vec3 transformColor(vec3 color) {
|
|
834
|
+
if (exponent == 1.0) return color;
|
|
835
|
+
return pow(abs(color), transformexponent);
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
vec3 undoColorTransform(vec3 color) {
|
|
839
|
+
if (exponent == 1.0) return color;
|
|
840
|
+
return max(pow(abs(color), undoColorTransformExponent), vec3(0.0));
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
void main() {
|
|
844
|
+
if (exponent != 1.0){
|
|
845
|
+
transformexponent = vec3(1.0 / exponent);
|
|
846
|
+
undoColorTransformExponent = vec3(exponent);
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
vec4 inputTexel = textureLod(inputTexture, vUv, 0.0);
|
|
850
|
+
vec4 accumulatedTexel;
|
|
851
|
+
vec3 inputColor = transformColor(inputTexel.rgb);
|
|
852
|
+
vec3 accumulatedColor;
|
|
853
|
+
float alpha = inputTexel.a;
|
|
854
|
+
float velocityDisocclusion;
|
|
855
|
+
bool didReproject = false;
|
|
856
|
+
|
|
857
|
+
#ifdef boxBlur
|
|
858
|
+
vec3 boxBlurredColor = inputTexel.rgb;
|
|
859
|
+
#endif
|
|
860
|
+
|
|
861
|
+
vec4 velocity = textureLod(velocityTexture, vUv, 0.0);
|
|
862
|
+
bool isMoving = alpha < 1.0 || dot(velocity.xy, velocity.xy) > 0.0;
|
|
863
|
+
if (isMoving) {
|
|
864
|
+
vec3 minNeighborColor = inputColor;
|
|
865
|
+
vec3 maxNeighborColor = inputColor;
|
|
866
|
+
vec3 col;
|
|
867
|
+
vec2 neighborUv;
|
|
868
|
+
vec2 reprojectedUv = vUv-velocity.xy;
|
|
869
|
+
vec4 lastVelocity = textureLod(lastVelocityTexture, reprojectedUv, 0.0);
|
|
870
|
+
float depth = velocity.b;
|
|
871
|
+
float closestDepth = depth;
|
|
872
|
+
float lastClosestDepth = lastVelocity.b;
|
|
873
|
+
float neighborDepth;
|
|
874
|
+
float lastNeighborDepth;
|
|
875
|
+
|
|
876
|
+
for (int x = -correctionRadius; x <= correctionRadius; x++) {
|
|
877
|
+
for (int y = -correctionRadius; y <= correctionRadius; y++) {
|
|
878
|
+
if (x != 0 || y != 0) {
|
|
879
|
+
neighborUv = vUv + vec2(x,y) * invTexSize;
|
|
880
|
+
vec4 neigborVelocity = textureLod(velocityTexture, neighborUv, 0.0);
|
|
881
|
+
neighborDepth = neigborVelocity.b;
|
|
882
|
+
col = textureLod(inputTexture, neighborUv, 0.0).xyz;
|
|
883
|
+
int absX = abs(x);
|
|
884
|
+
int absY = abs(y);
|
|
885
|
+
|
|
886
|
+
#ifdef dilation
|
|
887
|
+
if (absX == 1 && absY == 1) {
|
|
888
|
+
if (neighborDepth > closestDepth) {
|
|
889
|
+
velocity=neigborVelocity;
|
|
890
|
+
closestDepth=neighborDepth;
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
vec4 lastNeighborVelocity = textureLod(velocityTexture, vUv + vec2(x, y) * invTexSize, 0.0);
|
|
894
|
+
lastNeighborDepth = lastNeighborVelocity.b;
|
|
895
|
+
|
|
896
|
+
if (neighborDepth > closestDepth) {
|
|
897
|
+
lastVelocity = lastNeighborVelocity;
|
|
898
|
+
lastClosestDepth = lastNeighborDepth;
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
#endif
|
|
902
|
+
|
|
903
|
+
if (abs(depth-neighborDepth) < MAX_NEIGHBOR_DEPTH_DIFFERENCE) {
|
|
904
|
+
#ifdef boxBlur
|
|
905
|
+
if (absX <= 2 && absY <= 2) boxBlurredColor += col;
|
|
906
|
+
#endif
|
|
907
|
+
|
|
908
|
+
col = transformColor(col);
|
|
909
|
+
minNeighborColor = min(col, minNeighborColor);
|
|
910
|
+
maxNeighborColor = max(col, maxNeighborColor);
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
float velocityLength = length(lastVelocity.xy - velocity.xy);
|
|
917
|
+
velocityDisocclusion = (velocityLength - 0.000005) * 10.0;
|
|
918
|
+
velocityDisocclusion *= velocityDisocclusion;
|
|
919
|
+
reprojectedUv = vUv - velocity.xy;
|
|
920
|
+
|
|
921
|
+
#ifdef boxBlur
|
|
922
|
+
float pxRadius = correctionRadius > 5 ? 121.0 : pow(float(correctionRadius * 2 + 1), 2.0);
|
|
923
|
+
boxBlurredColor /= pxRadius;
|
|
924
|
+
boxBlurredColor = transformColor(boxBlurredColor);
|
|
925
|
+
#endif
|
|
926
|
+
|
|
927
|
+
if (
|
|
928
|
+
reprojectedUv.x >=0.0 &&
|
|
929
|
+
reprojectedUv.x <= 1.0 &&
|
|
930
|
+
reprojectedUv.y >= 0.0 &&
|
|
931
|
+
reprojectedUv.y <= 1.0
|
|
932
|
+
) {
|
|
933
|
+
accumulatedTexel = textureLod(accumulatedTexture, reprojectedUv, 0.0);
|
|
934
|
+
accumulatedColor = transformColor(accumulatedTexel.rgb);
|
|
935
|
+
vec3 clampedColor = clamp(accumulatedColor, minNeighborColor, maxNeighborColor);
|
|
936
|
+
accumulatedColor = mix(accumulatedColor, clampedColor, correction);
|
|
937
|
+
didReproject = true;
|
|
938
|
+
} else {
|
|
939
|
+
#ifdef boxBlur
|
|
940
|
+
accumulatedColor=boxBlurredColor;
|
|
941
|
+
#else
|
|
942
|
+
accumulatedColor=inputColor;
|
|
943
|
+
#endif
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
if (velocity.r > FLOAT_ONE_MINUS_EPSILON && velocity.g > FLOAT_ONE_MINUS_EPSILON) {
|
|
947
|
+
alpha = 0.0;
|
|
948
|
+
velocityDisocclusion = 1.0;
|
|
949
|
+
}
|
|
950
|
+
} else {
|
|
951
|
+
accumulatedColor = transformColor(textureLod(accumulatedTexture, vUv, 0.0).rgb);
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
vec3 outputColor = inputColor;
|
|
955
|
+
|
|
956
|
+
#include <custom_compose_shader>
|
|
957
|
+
|
|
958
|
+
gl_FragColor = vec4(undoColorTransform(outputColor), alpha);
|
|
959
|
+
}
|
|
960
|
+
`
|
|
961
|
+
);
|
|
402
962
|
class TemporalResolveMaterial extends ShaderMaterial {
|
|
403
963
|
constructor(customComposeShader) {
|
|
404
964
|
const fragmentShader2 = temporalResolve.replace("#include <custom_compose_shader>", customComposeShader);
|
|
@@ -906,7 +1466,6 @@ function useBoxProjectedEnvMap(shader, envMapPosition, envMapSize) {
|
|
|
906
1466
|
${getIBLRadiance_patch}`
|
|
907
1467
|
);
|
|
908
1468
|
}
|
|
909
|
-
const finalFragmentShader = finalSSRShader.replace("#include <helperFunctions>", helperFunctions).replace("#include <boxBlur>", boxBlur);
|
|
910
1469
|
const noResetSamplesProperties = ["blur", "blurSharpness", "blurKernel"];
|
|
911
1470
|
const defaultCubeRenderTarget = new WebGLCubeRenderTarget(1);
|
|
912
1471
|
let pmremGenerator;
|
|
@@ -917,7 +1476,7 @@ class SSREffect extends Effect {
|
|
|
917
1476
|
* @param {SSROptions} [options] The optional options for the SSR effect
|
|
918
1477
|
*/
|
|
919
1478
|
constructor(scene, camera, options = defaultSSROptions) {
|
|
920
|
-
super("SSREffect",
|
|
1479
|
+
super("SSREffect", finalSSRShader, {
|
|
921
1480
|
type: "FinalSSRMaterial",
|
|
922
1481
|
uniforms: /* @__PURE__ */ new Map([
|
|
923
1482
|
["reflectionsTexture", new Uniform(null)],
|