three-base 2.0.87 → 2.0.89

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,561 +0,0 @@
1
- /*
2
- * @Author: xiaosihan
3
- * @Date: 2023-05-09 00:35:17
4
- * @Last Modified by: xiaosihan
5
- * @Last Modified time: 2023-05-09 02:33:28
6
- */
7
-
8
- import { Camera, LinearFilter, Object3D, RGBAFormat, Vector2, WebGLRenderTarget, WebGLRenderer, ShaderMaterial, NoBlending, Scene, RawShaderMaterial, Color, NormalBlending, ShaderChunk, DepthTexture, DepthFormat, UnsignedShortType } from "three";
9
- import FullScreenQuad from "./FullScreenQuad";
10
-
11
-
12
- // 选中对象的深度纹理
13
- const selectDepthTexture = (() => {
14
- const baseDepthTexture = new DepthTexture(4096, 4096);
15
- baseDepthTexture.format = DepthFormat;
16
- baseDepthTexture.type = UnsignedShortType;
17
- baseDepthTexture.anisotropy = 16;
18
- return baseDepthTexture;
19
- })();
20
-
21
- // 选中对象的纹理
22
- const selectTextureTarget = new WebGLRenderTarget(512, 512, {
23
- minFilter: LinearFilter,
24
- magFilter: LinearFilter,
25
- format: RGBAFormat,
26
- depthTexture: selectDepthTexture,
27
- anisotropy: 16,
28
- });
29
-
30
- // 深度测试后的选中纹理
31
- const selectDethpTestTextureTarget = new WebGLRenderTarget(512, 512, {
32
- minFilter: LinearFilter,
33
- magFilter: LinearFilter,
34
- format: RGBAFormat,
35
- anisotropy: 16,
36
- });
37
-
38
- // 由于不能同时读写自己的纹理
39
- const blur1TextureTarget = new WebGLRenderTarget(512, 512, { minFilter: LinearFilter, magFilter: LinearFilter, format: RGBAFormat });
40
-
41
- // 所以需要用2个模糊纹理相互读写
42
- const blur2TextureTarget = new WebGLRenderTarget(512, 512, { minFilter: LinearFilter, magFilter: LinearFilter, format: RGBAFormat });
43
-
44
- const size = new Vector2();
45
-
46
- // 创建一个渲染工具 用于处理纹理
47
- const fsQuad = new FullScreenQuad(); // 渲染辅助器
48
-
49
- //深度比对纹理
50
- const depthTestShader = new ShaderMaterial({
51
- uniforms: {
52
- map: { value: null }, // 贴图纹理
53
- baseDepth: { value: null }, // 整个场景的深度纹理
54
- selectDepth: { value: null }, // 选中的对象深度纹理
55
- },
56
- vertexShader: `
57
- ${ShaderChunk.common}
58
- ${ShaderChunk.logdepthbuf_pars_vertex}
59
- varying vec2 vUv;
60
- void main() {
61
- vUv = uv;
62
- // gl_Position = vec4(position, 1.0);
63
- // gl_Position = projectionMatrix * modelViewMatrix * instanceMatrix * vec4(position, 1.0);
64
- gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
65
- ${ShaderChunk.logdepthbuf_vertex}
66
- }
67
- `,
68
- fragmentShader: `
69
- ${ShaderChunk.logdepthbuf_pars_fragment}
70
- uniform sampler2D map;
71
- uniform sampler2D baseDepth;
72
- uniform sampler2D selectDepth;
73
- varying vec2 vUv;
74
- void main() {
75
- if(texture2D(baseDepth, vUv).r < texture2D(selectDepth, vUv).r){
76
- discard;
77
- }
78
- gl_FragColor = texture2D(map, vUv);
79
- ${ShaderChunk.logdepthbuf_fragment}
80
- }
81
- `,
82
- blending: NoBlending, // 渲染时不与背景融合计算 直接替换
83
- depthTest: true,
84
- depthWrite: true,
85
- transparent: true
86
- });
87
-
88
- // 抗锯齿着色器
89
- const FXAAShaderMaterial = new ShaderMaterial({
90
- uniforms: {
91
- tDiffuse: { value: null }, // 贴图纹理
92
- resolution: { value: new Vector2(1 / 1024, 1 / 1024) }
93
- },
94
- vertexShader: `
95
- ${ShaderChunk.common}
96
- ${ShaderChunk.logdepthbuf_pars_vertex}
97
- varying vec2 vUv;
98
- void main() {
99
- vUv = uv;
100
- gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
101
- ${ShaderChunk.logdepthbuf_vertex}
102
- }
103
- `,
104
- fragmentShader: `
105
- ${ShaderChunk.logdepthbuf_pars_fragment}
106
- precision highp float;
107
-
108
- uniform sampler2D tDiffuse;
109
-
110
- uniform vec2 resolution;
111
-
112
- varying vec2 vUv;
113
-
114
- #ifndef FXAA_DISCARD
115
- //
116
- // Only valid for PC OpenGL currently.
117
- // Probably will not work when FXAA_GREEN_AS_LUMA = 1.
118
- //
119
- // 1 = Use discard on pixels which don't need AA.
120
- // For APIs which enable concurrent TEX+ROP from same surface.
121
- // 0 = Return unchanged color on pixels which don't need AA.
122
- //
123
- #define FXAA_DISCARD 0
124
- #endif
125
-
126
- /*--------------------------------------------------------------------------*/
127
- #define FxaaTexTop(t, p) texture2D(t, p, -100.0)
128
- #define FxaaTexOff(t, p, o, r) texture2D(t, p + (o * r), -100.0)
129
- /*--------------------------------------------------------------------------*/
130
-
131
- #define NUM_SAMPLES 5
132
-
133
- // assumes colors have premultipliedAlpha, so that the calculated color contrast is scaled by alpha
134
- float contrast( vec4 a, vec4 b ) {
135
- vec4 diff = abs( a - b );
136
- return max( max( max( diff.r, diff.g ), diff.b ), diff.a );
137
- }
138
-
139
- /*============================================================================
140
-
141
- FXAA3 QUALITY - PC
142
-
143
- ============================================================================*/
144
-
145
- /*--------------------------------------------------------------------------*/
146
- vec4 FxaaPixelShader(
147
- vec2 posM,
148
- sampler2D tex,
149
- vec2 fxaaQualityRcpFrame,
150
- float fxaaQualityEdgeThreshold,
151
- float fxaaQualityinvEdgeThreshold
152
- ) {
153
- vec4 rgbaM = FxaaTexTop(tex, posM);
154
- vec4 rgbaS = FxaaTexOff(tex, posM, vec2( 0.0, 1.0), fxaaQualityRcpFrame.xy);
155
- vec4 rgbaE = FxaaTexOff(tex, posM, vec2( 1.0, 0.0), fxaaQualityRcpFrame.xy);
156
- vec4 rgbaN = FxaaTexOff(tex, posM, vec2( 0.0,-1.0), fxaaQualityRcpFrame.xy);
157
- vec4 rgbaW = FxaaTexOff(tex, posM, vec2(-1.0, 0.0), fxaaQualityRcpFrame.xy);
158
- // . S .
159
- // W M E
160
- // . N .
161
-
162
- bool earlyExit = max( max( max(
163
- contrast( rgbaM, rgbaN ),
164
- contrast( rgbaM, rgbaS ) ),
165
- contrast( rgbaM, rgbaE ) ),
166
- contrast( rgbaM, rgbaW ) )
167
- < fxaaQualityEdgeThreshold;
168
- // . 0 .
169
- // 0 0 0
170
- // . 0 .
171
-
172
- #if (FXAA_DISCARD == 1)
173
- if(earlyExit) FxaaDiscard;
174
- #else
175
- if(earlyExit) return rgbaM;
176
- #endif
177
-
178
- float contrastN = contrast( rgbaM, rgbaN );
179
- float contrastS = contrast( rgbaM, rgbaS );
180
- float contrastE = contrast( rgbaM, rgbaE );
181
- float contrastW = contrast( rgbaM, rgbaW );
182
-
183
- float relativeVContrast = ( contrastN + contrastS ) - ( contrastE + contrastW );
184
- relativeVContrast *= fxaaQualityinvEdgeThreshold;
185
-
186
- bool horzSpan = relativeVContrast > 0.;
187
- // . 1 .
188
- // 0 0 0
189
- // . 1 .
190
-
191
- // 45 deg edge detection and corners of objects, aka V/H contrast is too similar
192
- if( abs( relativeVContrast ) < .3 ) {
193
- // locate the edge
194
- vec2 dirToEdge;
195
- dirToEdge.x = contrastE > contrastW ? 1. : -1.;
196
- dirToEdge.y = contrastS > contrastN ? 1. : -1.;
197
- // . 2 . . 1 .
198
- // 1 0 2 ~= 0 0 1
199
- // . 1 . . 0 .
200
-
201
- // tap 2 pixels and see which ones are "outside" the edge, to
202
- // determine if the edge is vertical or horizontal
203
-
204
- vec4 rgbaAlongH = FxaaTexOff(tex, posM, vec2( dirToEdge.x, -dirToEdge.y ), fxaaQualityRcpFrame.xy);
205
- float matchAlongH = contrast( rgbaM, rgbaAlongH );
206
- // . 1 .
207
- // 0 0 1
208
- // . 0 H
209
-
210
- vec4 rgbaAlongV = FxaaTexOff(tex, posM, vec2( -dirToEdge.x, dirToEdge.y ), fxaaQualityRcpFrame.xy);
211
- float matchAlongV = contrast( rgbaM, rgbaAlongV );
212
- // V 1 .
213
- // 0 0 1
214
- // . 0 .
215
-
216
- relativeVContrast = matchAlongV - matchAlongH;
217
- relativeVContrast *= fxaaQualityinvEdgeThreshold;
218
-
219
- if( abs( relativeVContrast ) < .3 ) { // 45 deg edge
220
- // 1 1 .
221
- // 0 0 1
222
- // . 0 1
223
-
224
- // do a simple blur
225
- return mix(
226
- rgbaM,
227
- (rgbaN + rgbaS + rgbaE + rgbaW) * .25,
228
- .4
229
- );
230
- }
231
-
232
- horzSpan = relativeVContrast > 0.;
233
- }
234
-
235
- if(!horzSpan) rgbaN = rgbaW;
236
- if(!horzSpan) rgbaS = rgbaE;
237
- // . 0 . 1
238
- // 1 0 1 -> 0
239
- // . 0 . 1
240
-
241
- bool pairN = contrast( rgbaM, rgbaN ) > contrast( rgbaM, rgbaS );
242
- if(!pairN) rgbaN = rgbaS;
243
-
244
- vec2 offNP;
245
- offNP.x = (!horzSpan) ? 0.0 : fxaaQualityRcpFrame.x;
246
- offNP.y = ( horzSpan) ? 0.0 : fxaaQualityRcpFrame.y;
247
-
248
- bool doneN = false;
249
- bool doneP = false;
250
-
251
- float nDist = 0.;
252
- float pDist = 0.;
253
-
254
- vec2 posN = posM;
255
- vec2 posP = posM;
256
-
257
- int iterationsUsed = 0;
258
- int iterationsUsedN = 0;
259
- int iterationsUsedP = 0;
260
- for( int i = 0; i < NUM_SAMPLES; i++ ) {
261
- iterationsUsed = i;
262
-
263
- float increment = float(i + 1);
264
-
265
- if(!doneN) {
266
- nDist += increment;
267
- posN = posM + offNP * nDist;
268
- vec4 rgbaEndN = FxaaTexTop(tex, posN.xy);
269
- doneN = contrast( rgbaEndN, rgbaM ) > contrast( rgbaEndN, rgbaN );
270
- iterationsUsedN = i;
271
- }
272
-
273
- if(!doneP) {
274
- pDist += increment;
275
- posP = posM - offNP * pDist;
276
- vec4 rgbaEndP = FxaaTexTop(tex, posP.xy);
277
- doneP = contrast( rgbaEndP, rgbaM ) > contrast( rgbaEndP, rgbaN );
278
- iterationsUsedP = i;
279
- }
280
-
281
- if(doneN || doneP) break;
282
- }
283
-
284
-
285
- if ( !doneP && !doneN ) return rgbaM; // failed to find end of edge
286
-
287
- float dist = min(
288
- doneN ? float( iterationsUsedN ) / float( NUM_SAMPLES - 1 ) : 1.,
289
- doneP ? float( iterationsUsedP ) / float( NUM_SAMPLES - 1 ) : 1.
290
- );
291
-
292
- // hacky way of reduces blurriness of mostly diagonal edges
293
- // but reduces AA quality
294
- dist = pow(dist, .5);
295
-
296
- dist = 1. - dist;
297
-
298
- return mix(
299
- rgbaM,
300
- rgbaN,
301
- dist * .5
302
- );
303
- }
304
-
305
- void main() {
306
- const float edgeDetectionQuality = .2;
307
- const float invEdgeDetectionQuality = 1. / edgeDetectionQuality;
308
-
309
- gl_FragColor = FxaaPixelShader(
310
- vUv,
311
- tDiffuse,
312
- resolution,
313
- edgeDetectionQuality, // [0,1] contrast needed, otherwise early discard
314
- invEdgeDetectionQuality
315
- );
316
- ${ShaderChunk.logdepthbuf_fragment}
317
- }
318
- `,
319
- blending: NoBlending, // 渲染时不与背景融合计算 直接替换
320
- depthTest: false,
321
- depthWrite: false,
322
- transparent: true
323
- });
324
-
325
- // 描边着色器
326
- const blurShader = new RawShaderMaterial({
327
- uniforms: {
328
- tDiffuse: { value: null },
329
- color: { value: new Color("#0f0") }, // 没有被挡住的地方的颜色绿色
330
- width: { value: 1.0 },
331
- opacity: { value: 1.0 },
332
- resolution: { value: new Vector2(1 / 512, 1 / 512) }, // 渲染器的分辨率
333
- offset: {
334
- value: [
335
- new Vector2(0.000, 1.000),
336
- new Vector2(0.259, 0.966),
337
- new Vector2(0.500, 0.866),
338
- new Vector2(0.707, 0.707),
339
- new Vector2(0.866, 0.500),
340
- new Vector2(0.966, 0.259),
341
- new Vector2(1.000, 0.000),
342
- new Vector2(0.966, -0.259),
343
- new Vector2(0.866, -0.500),
344
- new Vector2(0.707, -0.707),
345
- new Vector2(0.500, -0.866),
346
- new Vector2(0.259, -0.966),
347
- new Vector2(0.000, -1.000),
348
- new Vector2(-0.259, -0.966),
349
- new Vector2(-0.500, -0.866),
350
- new Vector2(-0.707, -0.707),
351
- new Vector2(-0.866, -0.500),
352
- new Vector2(-0.966, -0.259),
353
- new Vector2(-1.000, -0.000),
354
- new Vector2(-0.966, 0.259),
355
- new Vector2(-0.866, 0.500),
356
- new Vector2(-0.707, 0.707),
357
- new Vector2(-0.500, 0.866),
358
- new Vector2(-0.259, 0.966)
359
- ]
360
- }
361
- },
362
- vertexShader: `
363
- attribute vec3 position;
364
- attribute vec2 uv;
365
- varying vec2 vUv;
366
- void main() {
367
- vUv = uv;
368
- gl_Position = vec4(position, 1.0);
369
- }`,
370
- fragmentShader: `
371
- #ifdef GL_ES
372
- precision highp float;
373
- #endif
374
- uniform sampler2D tDiffuse;
375
- uniform vec3 color;
376
- uniform float width;
377
- uniform float opacity;
378
- uniform vec2 resolution;
379
- uniform vec2 offset[24];
380
- varying vec2 vUv;
381
- vec2 piexl = resolution * width; // 描边厚度
382
-
383
- vec4 stroke(){
384
- vec4 blurColor = vec4(0.0);
385
- vec4 Color = vec4(0.0);
386
- for (int i = 0; i < 24; i++ ) {
387
- Color = texture2D(tDiffuse, vUv + (offset[i] * piexl));
388
- if (Color.a > 0.0) {
389
- blurColor += Color;
390
- }
391
- }
392
- if (blurColor.a < 0.001) {
393
- return vec4(0.0);
394
- } else {
395
- return vec4(color, opacity);
396
- }
397
- }
398
- void main() {
399
- vec4 Color = texture2D(tDiffuse, vUv);
400
- if (Color.a > 0.0 || width == 0.0) {
401
- gl_FragColor = Color;
402
- } else {
403
- gl_FragColor = stroke();
404
- }
405
- }`,
406
- blending: NoBlending, // 渲染时不与背景融合计算 直接替换
407
- depthTest: false,
408
- depthWrite: false,
409
- transparent: true
410
- });
411
-
412
- // 过滤着色器
413
- const filterSelectShader = new RawShaderMaterial({
414
- uniforms: {
415
- selectTexture: { value: null },
416
- blurTexture: { value: null }
417
- },
418
- vertexShader: `
419
- attribute vec3 position;
420
- attribute vec2 uv;
421
- varying vec2 vUv;
422
- void main() {
423
- vUv = uv;
424
- gl_Position = vec4(position, 1.0);
425
- }
426
- `,
427
- fragmentShader: `
428
- #ifdef GL_ES
429
- precision highp float;
430
- #endif
431
- uniform sampler2D selectTexture;
432
- uniform sampler2D blurTexture;
433
- varying vec2 vUv;
434
-
435
- void main() {
436
- gl_FragColor = texture2D(blurTexture, vUv);
437
- gl_FragColor.a -= (texture2D(selectTexture, vUv).a);
438
- }
439
- `,
440
- blending: NoBlending, // 渲染时不与背景融合计算 直接替换
441
- depthTest: false,
442
- depthWrite: false,
443
- transparent: true
444
- });
445
-
446
- const copyShader = new ShaderMaterial({
447
- uniforms: {
448
- map: { value: null }, // 贴图纹理
449
- },
450
- vertexShader: `
451
- ${ShaderChunk.common}
452
- ${ShaderChunk.logdepthbuf_pars_vertex}
453
- varying vec2 vUv;
454
- void main() {
455
- vUv = uv;
456
- // gl_Position = vec4(position, 1.0);
457
- // gl_Position = projectionMatrix * modelViewMatrix * instanceMatrix * vec4(position, 1.0);
458
- gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
459
- ${ShaderChunk.logdepthbuf_vertex}
460
- }
461
- `,
462
- fragmentShader: `
463
- ${ShaderChunk.logdepthbuf_pars_fragment}
464
- uniform sampler2D map;
465
- varying vec2 vUv;
466
- void main() {
467
- gl_FragColor = texture2D(map, vUv);
468
- ${ShaderChunk.logdepthbuf_fragment}
469
- }
470
- `,
471
- depthTest: true,
472
- depthWrite: true,
473
- transparent: true
474
- });
475
-
476
- // 场景对象
477
- const scene = new Scene();
478
-
479
- // 对象描边
480
- export default function stroke_pass(renderer: WebGLRenderer, camera: Camera, object3d: Object3D, baseDepthTexture: DepthTexture) {
481
-
482
- const { stroke_enable = false, stroke_color = "#04fa12", stroke_width = 1 } = object3d.userData;
483
- if (!stroke_enable || stroke_width === 0) {
484
- return;
485
- }
486
-
487
- // 保存原帧缓冲区
488
- const originRenderTarget = renderer.getRenderTarget();
489
-
490
- // 设置选中目标的帧缓冲区
491
- renderer.getSize(size);
492
- size.multiplyScalar(window.devicePixelRatio);
493
- selectTextureTarget.setSize(size.x, size.y);
494
- selectDethpTestTextureTarget.setSize(size.x, size.y);
495
- blur1TextureTarget.setSize(size.x, size.y);
496
- blur2TextureTarget.setSize(size.x, size.y);
497
- renderer.setRenderTarget(selectTextureTarget);
498
- scene.children = [object3d];
499
- renderer.clear();
500
- renderer.render(scene, camera);
501
-
502
- // 设置描边着色器的分辨率
503
- blurShader.uniforms.resolution.value.set(1 / size.x, 1 / size.y);
504
- // 设置抗锯齿着色器的分辨率
505
- FXAAShaderMaterial.uniforms.resolution.value.set(1 / size.x, 1 / size.y);
506
- //描边颜色
507
- blurShader.uniforms.color.value.set(stroke_color);
508
- blurShader.uniforms.width.value = 1;
509
-
510
-
511
- //深度测试
512
- renderer.setRenderTarget(selectDethpTestTextureTarget);
513
- renderer.clear();
514
- depthTestShader.uniforms.map.value = selectTextureTarget.texture;
515
- depthTestShader.uniforms.baseDepth.value = baseDepthTexture;
516
- depthTestShader.uniforms.selectDepth.value = selectDepthTexture;
517
- fsQuad.render(renderer, depthTestShader);
518
-
519
- //一次描边
520
- renderer.setRenderTarget(blur1TextureTarget);
521
- blurShader.uniforms.tDiffuse.value = selectDethpTestTextureTarget.texture;
522
- fsQuad.render(renderer, blurShader);
523
-
524
- //二次描边
525
- renderer.setRenderTarget(blur2TextureTarget);
526
- blurShader.uniforms.tDiffuse.value = blur1TextureTarget.texture;
527
- fsQuad.render(renderer, blurShader);
528
-
529
-
530
- for (let i = 0; i < stroke_width - 2; i++) {
531
- //一次描边
532
- renderer.setRenderTarget(blur1TextureTarget);
533
- blurShader.uniforms.tDiffuse.value = blur2TextureTarget.texture;
534
- fsQuad.render(renderer, blurShader);
535
-
536
- //二次描边
537
- renderer.setRenderTarget(blur2TextureTarget);
538
- blurShader.uniforms.tDiffuse.value = blur1TextureTarget.texture;
539
- fsQuad.render(renderer, blurShader);
540
- }
541
-
542
- //最后抗锯齿
543
- renderer.setRenderTarget(blur1TextureTarget);
544
- FXAAShaderMaterial.uniforms.tDiffuse.value = blur2TextureTarget.texture;
545
- fsQuad.render(renderer, FXAAShaderMaterial);
546
-
547
- // 还原帧缓冲区 减去原始纹理保留描边
548
- renderer.setRenderTarget(originRenderTarget);
549
- filterSelectShader.uniforms.selectTexture.value = selectDethpTestTextureTarget.texture;
550
- filterSelectShader.uniforms.blurTexture.value = blur1TextureTarget.texture;
551
- filterSelectShader.blending = NormalBlending; // 与有的纹理融合计算 保留前面通道传递下来的纹理
552
- fsQuad.render(renderer, filterSelectShader);
553
-
554
-
555
- // 调试代码
556
- // renderer.setRenderTarget(null);
557
- // renderer.clearDepth();
558
- // copyShader.uniforms.tDiffuse.value = blur2TextureTarget.texture;
559
- // fsQuad.render(renderer, copyShader);
560
- // return;
561
- }