three-base 2.0.115 → 2.0.116

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.
package/ExtrudeMesh.d.ts CHANGED
@@ -34,6 +34,7 @@ export default class ExtrudeMesh extends Mesh<BufferGeometry, Material> {
34
34
  static temp2Matrix4: Matrix4;
35
35
  static temp3Matrix4: Matrix4;
36
36
  constructor(props: ExtrudeMeshProps, material?: Material);
37
+ shapePathWidth: number;
37
38
  pointerWidthRadius: Array<{
38
39
  vector3: [number, number, number];
39
40
  matrix: [
package/ExtrudeMesh.js CHANGED
@@ -2,7 +2,7 @@
2
2
  * @Author: xiaosihan
3
3
  * @Date: 2022-06-08 14:20:52
4
4
  * @Last Modified by: xiaosihan
5
- * @Last Modified time: 2022-09-30 00:12:19
5
+ * @Last Modified time: 2025-01-17 20:42:22
6
6
  */
7
7
  import { clamp, cloneDeep, filter, first, get, isNumber, last } from "lodash";
8
8
  import { BufferAttribute, BufferGeometry, Matrix4, Mesh, Vector2, Vector3 } from "three";
@@ -32,6 +32,8 @@ export default class ExtrudeMesh extends Mesh {
32
32
  super(undefined, material);
33
33
  this.updateGeometry(props);
34
34
  }
35
+ //宽度
36
+ shapePathWidth = 1;
35
37
  // 通过 props.paths 和圆角属性 计算出来的 最终路径
36
38
  pointerWidthRadius = [];
37
39
  // 通过2个顶点和缩放值计算矩阵
@@ -155,16 +157,16 @@ export default class ExtrudeMesh extends Mesh {
155
157
  .toArray()
156
158
  });
157
159
  }
158
- else if (segments === 0) { // 分段数为0时不分段
160
+ else if (segments === 0) { // 分段数为0时不分段 并在前后各加一个点
159
161
  let { x = 1, y = 1 } = scale;
160
162
  this.pointerWidthRadius.push({
161
163
  vector3,
162
- matrix: this.computerMatrix((v2Inv1Left ? circleCenter.toArray() : vector3), (v2Inv1Left ? vector3 : circleCenter.toArray()), [1, y, x])
164
+ matrix: this.computerMatrix((v2Inv1Left ? circleCenter.toArray() : vector3), (v2Inv1Left ? vector3 : circleCenter.toArray()), [1, y, x / Math.sin(innerAngle / 2)])
163
165
  });
164
166
  }
165
167
  else {
166
168
  for (let ii = 0; ii <= segments; ii++) {
167
- // 圆角计算的低n个点的角度
169
+ // 圆角计算的第n个点的角度
168
170
  let Aa = ii * ((Math.PI - innerAngle) / segments);
169
171
  //半径对角
170
172
  let Cc = Math.PI - Aa - (innerAngle / 2);
@@ -330,6 +332,7 @@ export default class ExtrudeMesh extends Mesh {
330
332
  //设置模型
331
333
  updateGeometry(props) {
332
334
  const { paths, shapePath, closed } = props;
335
+ this.shapePathWidth = Math.max(...shapePath.map(path => path[0])) - Math.min(...shapePath.map(path => path[0]));
333
336
  // 计算圆角路径
334
337
  this.computerPointerWidthRadius(paths, closed);
335
338
  //网格模型的每个顶点位置
package/ThreeBase.d.ts CHANGED
@@ -69,6 +69,7 @@ export default class ThreeBase extends EventDispatcher {
69
69
  autoRender: boolean;
70
70
  needRender: boolean;
71
71
  stopRender(): void;
72
+ hasPass(): boolean;
72
73
  render(): void;
73
74
  private renderBindThis;
74
75
  getThumbBlob(): Promise<Blob>;
package/ThreeBase.js CHANGED
@@ -2,7 +2,7 @@
2
2
  * @Author: xiaosihan
3
3
  * @Date: 2021-12-20 13:38:22
4
4
  * @Last Modified by: xiaosihan
5
- * @Last Modified time: 2025-01-17 06:49:44
5
+ * @Last Modified time: 2025-01-17 11:07:38
6
6
  */
7
7
  import { round } from "lodash";
8
8
  import { AxesHelper, Box3, DepthFormat, DepthTexture, EventDispatcher, GridHelper, LinearFilter, MOUSE, NoBlending, NormalBlending, OrthographicCamera, PerspectiveCamera, RGBAFormat, ReinhardToneMapping, SRGBColorSpace, Scene, TOUCH, UnsignedShortType, Vector2, Vector3, WebGLRenderTarget, WebGLRenderer, } from "three";
@@ -10,13 +10,14 @@ import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
10
10
  import { degToRad, generateUUID } from "three/src/math/MathUtils";
11
11
  import ThreeMouse from "./ThreeMouse";
12
12
  import Transition from "./Transition";
13
+ import bloom_pass from "./pass/bloom_pass";
14
+ import cover_pass from "./pass/cover_pass";
13
15
  import glow_pass from "./pass/glow_pass";
14
16
  import stroke_pass from "./pass/stroke_pass";
15
- import { baseTextureToRenderShader, copyShader, fullScreenMesh, } from "./shaders";
17
+ import { copyShader, fullScreenMesh } from "./shaders";
18
+ import { baseTextureToRenderShader } from "./shaders/baseTextureToRenderShader";
16
19
  import threeLoader from "./threeLoader";
17
20
  import threeUtils from "./threeUtils";
18
- import cover_pass from "./pass/cover_pass";
19
- import bloom_pass from "./pass/bloom_pass";
20
21
  // three.js 的基础对象
21
22
  export default class ThreeBase extends EventDispatcher {
22
23
  constructor() {
@@ -193,7 +194,7 @@ export default class ThreeBase extends EventDispatcher {
193
194
  this.renderer.setPixelRatio(window.devicePixelRatio);
194
195
  this.renderer.setSize(width, height);
195
196
  // 设置帧缓存区的尺寸
196
- this.baseRenderTarget.setSize(width * Math.max(2, window.devicePixelRatio), height * Math.max(2, window.devicePixelRatio));
197
+ this.baseRenderTarget.setSize(width * window.devicePixelRatio, height * window.devicePixelRatio);
197
198
  // 设置深度纹理的尺寸
198
199
  this.baseDepthTexture.image.width = width * window.devicePixelRatio;
199
200
  this.baseDepthTexture.image.height = height * window.devicePixelRatio;
@@ -427,6 +428,23 @@ export default class ThreeBase extends EventDispatcher {
427
428
  this.renderer.domElement.style.opacity = "0";
428
429
  }
429
430
  }
431
+ //判断是否有特效
432
+ hasPass() {
433
+ let hasPass = false;
434
+ this.scene.traverseVisible((obj) => {
435
+ const { stroke_enable = false, stroke_width = 1, glow_enable = false, glow_width = 1, cover_enable = false, cover_opacity = 1, } = obj.userData;
436
+ if (stroke_enable && stroke_width > 0) {
437
+ hasPass = true;
438
+ }
439
+ if (glow_enable && glow_width > 0) {
440
+ hasPass = true;
441
+ }
442
+ if (cover_enable && cover_opacity > 0) {
443
+ hasPass = true;
444
+ }
445
+ });
446
+ return hasPass;
447
+ }
430
448
  // 渲染场景
431
449
  render() {
432
450
  // canvas 没有在页面上面的话 就停止渲染
@@ -479,21 +497,31 @@ export default class ThreeBase extends EventDispatcher {
479
497
  }
480
498
  // 渲染场景
481
499
  this.dispatchEvent({ type: "beforeRender" });
500
+ const hasPass = this.hasPass();
482
501
  // 把基础场景渲染到 帧缓冲区 在后期通道中会用到
483
- this.renderer.setRenderTarget(this.baseRenderTarget);
484
- this.renderer.clear();
485
- this.renderer.render(this.scene, camera);
486
- this.renderer.setRenderTarget(null);
487
- this.renderer.clear();
488
- this.renderRendererTarget(this.baseRenderTarget);
489
- // 后处理特效渲染(描边,发光,颜色覆盖,磨砂玻璃,bloom)
490
- this.scene.traverseVisible((obj) => {
491
- stroke_pass(this.renderer, camera, obj, this.baseDepthTexture);
492
- glow_pass(this.renderer, camera, obj, this.baseDepthTexture);
493
- cover_pass(this.renderer, camera, obj, this.baseDepthTexture);
494
- });
495
- //后处理发光特效
496
- bloom_pass(this.renderer, camera, this.scene, this.baseDepthTexture);
502
+ if (hasPass) {
503
+ this.renderer.setRenderTarget(this.baseRenderTarget);
504
+ this.renderer.clear();
505
+ this.renderer.render(this.scene, camera);
506
+ // 后处理特效渲染(描边,发光,颜色覆盖,磨砂玻璃,bloom)
507
+ this.scene.traverseVisible((obj) => {
508
+ stroke_pass(this.renderer, camera, obj, this.baseDepthTexture);
509
+ glow_pass(this.renderer, camera, obj, this.baseDepthTexture);
510
+ });
511
+ this.renderer.setRenderTarget(null);
512
+ this.renderer.clear();
513
+ this.renderRendererTarget(this.baseRenderTarget);
514
+ this.scene.traverseVisible((obj) => {
515
+ cover_pass(this.renderer, camera, obj, this.baseDepthTexture);
516
+ });
517
+ //后处理发光特效
518
+ bloom_pass(this.renderer, camera, this.scene, this.baseDepthTexture);
519
+ }
520
+ else {
521
+ this.renderer.setRenderTarget(null);
522
+ this.renderer.clear();
523
+ this.renderer.render(this.scene, camera);
524
+ }
497
525
  this.dispatchEvent({ type: "afterRender" });
498
526
  }
499
527
  renderBindThis = this.render.bind(this);
@@ -540,8 +568,8 @@ export default class ThreeBase extends EventDispatcher {
540
568
  }
541
569
  //把渲染目标渲染到canvas上
542
570
  renderRendererTarget(renderTarget) {
543
- baseTextureToRenderShader.uniforms.map.value = renderTarget.texture;
544
- baseTextureToRenderShader.uniforms.opacity.value = 1.0;
571
+ baseTextureToRenderShader.uniforms.resolution.value.set(1 / this.size.x, 1 / this.size.y);
572
+ baseTextureToRenderShader.uniforms.tDiffuse.value = renderTarget.texture;
545
573
  fullScreenMesh.render(this.renderer, baseTextureToRenderShader);
546
574
  }
547
575
  // 渲染纹理
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "three-base",
3
- "version": "2.0.115",
3
+ "version": "2.0.116",
4
4
  "description": "three 3d three-base",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
package/pass/glow_pass.js CHANGED
@@ -556,14 +556,12 @@ export default function glow_pass(renderer, camera, object3d, baseDepthTexture)
556
556
  blurShader.uniforms.tDiffuse.value = blur1TextureTarget.texture;
557
557
  blurShader.uniforms.opacity.value = 0.1;
558
558
  fsQuad.render(renderer, blurShader);
559
- //最后抗锯齿
560
559
  renderer.setRenderTarget(blur1TextureTarget);
561
- FXAAShaderMaterial.uniforms.tDiffuse.value = blur2TextureTarget.texture;
562
- fsQuad.render(renderer, FXAAShaderMaterial);
560
+ copyShader.uniforms.map.value = blur2TextureTarget.texture;
561
+ fsQuad.render(renderer, copyShader);
563
562
  // 还原帧缓冲区 减去原始纹理保留描边
564
563
  renderer.setRenderTarget(originRenderTarget);
565
- filterSelectShader.uniforms.selectTexture.value =
566
- selectDethpTestTextureTarget.texture;
564
+ filterSelectShader.uniforms.selectTexture.value = selectDethpTestTextureTarget.texture;
567
565
  filterSelectShader.uniforms.blurTexture.value = blur1TextureTarget.texture;
568
566
  filterSelectShader.uniforms.opacity.value = glow_opacity;
569
567
  filterSelectShader.blending = NormalBlending; // 与有的纹理融合计算 保留前面通道传递下来的纹理
@@ -314,7 +314,7 @@ const FXAAShaderMaterial = new ShaderMaterial({
314
314
  transparent: true
315
315
  });
316
316
  // 描边着色器
317
- const blurShader = new RawShaderMaterial({
317
+ const strokeShader = new RawShaderMaterial({
318
318
  uniforms: {
319
319
  tDiffuse: { value: null },
320
320
  color: { value: new Color("#0f0") },
@@ -483,12 +483,12 @@ export default function stroke_pass(renderer, camera, object3d, baseDepthTexture
483
483
  renderer.clear();
484
484
  renderer.render(scene, camera);
485
485
  // 设置描边着色器的分辨率
486
- blurShader.uniforms.resolution.value.set(1 / size.x, 1 / size.y);
486
+ strokeShader.uniforms.resolution.value.set(1 / size.x, 1 / size.y);
487
487
  // 设置抗锯齿着色器的分辨率
488
488
  FXAAShaderMaterial.uniforms.resolution.value.set(1 / size.x, 1 / size.y);
489
489
  //描边颜色
490
- blurShader.uniforms.color.value.set(stroke_color);
491
- blurShader.uniforms.width.value = 1;
490
+ strokeShader.uniforms.color.value.set(stroke_color);
491
+ strokeShader.uniforms.width.value = 1;
492
492
  //深度测试
493
493
  renderer.setRenderTarget(selectDethpTestTextureTarget);
494
494
  renderer.clear();
@@ -498,26 +498,25 @@ export default function stroke_pass(renderer, camera, object3d, baseDepthTexture
498
498
  fsQuad.render(renderer, depthTestShader);
499
499
  //一次描边
500
500
  renderer.setRenderTarget(blur1TextureTarget);
501
- blurShader.uniforms.tDiffuse.value = selectDethpTestTextureTarget.texture;
502
- fsQuad.render(renderer, blurShader);
501
+ strokeShader.uniforms.tDiffuse.value = selectDethpTestTextureTarget.texture;
502
+ fsQuad.render(renderer, strokeShader);
503
503
  //二次描边
504
504
  renderer.setRenderTarget(blur2TextureTarget);
505
- blurShader.uniforms.tDiffuse.value = blur1TextureTarget.texture;
506
- fsQuad.render(renderer, blurShader);
505
+ strokeShader.uniforms.tDiffuse.value = blur1TextureTarget.texture;
506
+ fsQuad.render(renderer, strokeShader);
507
507
  for (let i = 0; i < stroke_width - 2; i++) {
508
508
  //一次描边
509
509
  renderer.setRenderTarget(blur1TextureTarget);
510
- blurShader.uniforms.tDiffuse.value = blur2TextureTarget.texture;
511
- fsQuad.render(renderer, blurShader);
510
+ strokeShader.uniforms.tDiffuse.value = blur2TextureTarget.texture;
511
+ fsQuad.render(renderer, strokeShader);
512
512
  //二次描边
513
513
  renderer.setRenderTarget(blur2TextureTarget);
514
- blurShader.uniforms.tDiffuse.value = blur1TextureTarget.texture;
515
- fsQuad.render(renderer, blurShader);
514
+ strokeShader.uniforms.tDiffuse.value = blur1TextureTarget.texture;
515
+ fsQuad.render(renderer, strokeShader);
516
516
  }
517
- //最后抗锯齿
518
517
  renderer.setRenderTarget(blur1TextureTarget);
519
- FXAAShaderMaterial.uniforms.tDiffuse.value = blur2TextureTarget.texture;
520
- fsQuad.render(renderer, FXAAShaderMaterial);
518
+ copyShader.uniforms.map.value = blur2TextureTarget.texture;
519
+ fsQuad.render(renderer, copyShader);
521
520
  // 还原帧缓冲区 减去原始纹理保留描边
522
521
  renderer.setRenderTarget(originRenderTarget);
523
522
  filterSelectShader.uniforms.selectTexture.value = selectDethpTestTextureTarget.texture;
@@ -0,0 +1,2 @@
1
+ import { ShaderMaterial } from "three";
2
+ export declare const baseTextureToRenderShader: ShaderMaterial;
@@ -0,0 +1,237 @@
1
+ import { ShaderMaterial, Vector2, ShaderChunk, NoBlending } from "three";
2
+ // 渲染目标绘制到渲染器着色器
3
+ export const baseTextureToRenderShader = new ShaderMaterial({
4
+ uniforms: {
5
+ tDiffuse: { value: null },
6
+ resolution: { value: new Vector2(1 / 1024, 1 / 1024) }
7
+ },
8
+ vertexShader: `
9
+ ${ShaderChunk.common}
10
+ ${ShaderChunk.logdepthbuf_pars_vertex}
11
+ varying vec2 vUv;
12
+ void main() {
13
+ vUv = uv;
14
+ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
15
+ ${ShaderChunk.logdepthbuf_vertex}
16
+ }
17
+ `,
18
+ fragmentShader: `
19
+ ${ShaderChunk.logdepthbuf_pars_fragment}
20
+ precision highp float;
21
+
22
+ uniform sampler2D tDiffuse;
23
+
24
+ uniform vec2 resolution;
25
+
26
+ varying vec2 vUv;
27
+
28
+ #ifndef FXAA_DISCARD
29
+ //
30
+ // Only valid for PC OpenGL currently.
31
+ // Probably will not work when FXAA_GREEN_AS_LUMA = 1.
32
+ //
33
+ // 1 = Use discard on pixels which don't need AA.
34
+ // For APIs which enable concurrent TEX+ROP from same surface.
35
+ // 0 = Return unchanged color on pixels which don't need AA.
36
+ //
37
+ #define FXAA_DISCARD 0
38
+ #endif
39
+
40
+ /*--------------------------------------------------------------------------*/
41
+ #define FxaaTexTop(t, p) texture2D(t, p, -100.0)
42
+ #define FxaaTexOff(t, p, o, r) texture2D(t, p + (o * r), -100.0)
43
+ /*--------------------------------------------------------------------------*/
44
+
45
+ #define NUM_SAMPLES 5
46
+
47
+ // assumes colors have premultipliedAlpha, so that the calculated color contrast is scaled by alpha
48
+ float contrast( vec4 a, vec4 b ) {
49
+ vec4 diff = abs( a - b );
50
+ return max( max( max( diff.r, diff.g ), diff.b ), diff.a );
51
+ }
52
+
53
+ /*============================================================================
54
+
55
+ FXAA3 QUALITY - PC
56
+
57
+ ============================================================================*/
58
+
59
+ /*--------------------------------------------------------------------------*/
60
+ vec4 FxaaPixelShader(
61
+ vec2 posM,
62
+ sampler2D tex,
63
+ vec2 fxaaQualityRcpFrame,
64
+ float fxaaQualityEdgeThreshold,
65
+ float fxaaQualityinvEdgeThreshold
66
+ ) {
67
+ vec4 rgbaM = FxaaTexTop(tex, posM);
68
+ vec4 rgbaS = FxaaTexOff(tex, posM, vec2( 0.0, 1.0), fxaaQualityRcpFrame.xy);
69
+ vec4 rgbaE = FxaaTexOff(tex, posM, vec2( 1.0, 0.0), fxaaQualityRcpFrame.xy);
70
+ vec4 rgbaN = FxaaTexOff(tex, posM, vec2( 0.0,-1.0), fxaaQualityRcpFrame.xy);
71
+ vec4 rgbaW = FxaaTexOff(tex, posM, vec2(-1.0, 0.0), fxaaQualityRcpFrame.xy);
72
+ // . S .
73
+ // W M E
74
+ // . N .
75
+
76
+ bool earlyExit = max( max( max(
77
+ contrast( rgbaM, rgbaN ),
78
+ contrast( rgbaM, rgbaS ) ),
79
+ contrast( rgbaM, rgbaE ) ),
80
+ contrast( rgbaM, rgbaW ) )
81
+ < fxaaQualityEdgeThreshold;
82
+ // . 0 .
83
+ // 0 0 0
84
+ // . 0 .
85
+
86
+ #if (FXAA_DISCARD == 1)
87
+ if(earlyExit) FxaaDiscard;
88
+ #else
89
+ if(earlyExit) return rgbaM;
90
+ #endif
91
+
92
+ float contrastN = contrast( rgbaM, rgbaN );
93
+ float contrastS = contrast( rgbaM, rgbaS );
94
+ float contrastE = contrast( rgbaM, rgbaE );
95
+ float contrastW = contrast( rgbaM, rgbaW );
96
+
97
+ float relativeVContrast = ( contrastN + contrastS ) - ( contrastE + contrastW );
98
+ relativeVContrast *= fxaaQualityinvEdgeThreshold;
99
+
100
+ bool horzSpan = relativeVContrast > 0.;
101
+ // . 1 .
102
+ // 0 0 0
103
+ // . 1 .
104
+
105
+ // 45 deg edge detection and corners of objects, aka V/H contrast is too similar
106
+ if( abs( relativeVContrast ) < .3 ) {
107
+ // locate the edge
108
+ vec2 dirToEdge;
109
+ dirToEdge.x = contrastE > contrastW ? 1. : -1.;
110
+ dirToEdge.y = contrastS > contrastN ? 1. : -1.;
111
+ // . 2 . . 1 .
112
+ // 1 0 2 ~= 0 0 1
113
+ // . 1 . . 0 .
114
+
115
+ // tap 2 pixels and see which ones are "outside" the edge, to
116
+ // determine if the edge is vertical or horizontal
117
+
118
+ vec4 rgbaAlongH = FxaaTexOff(tex, posM, vec2( dirToEdge.x, -dirToEdge.y ), fxaaQualityRcpFrame.xy);
119
+ float matchAlongH = contrast( rgbaM, rgbaAlongH );
120
+ // . 1 .
121
+ // 0 0 1
122
+ // . 0 H
123
+
124
+ vec4 rgbaAlongV = FxaaTexOff(tex, posM, vec2( -dirToEdge.x, dirToEdge.y ), fxaaQualityRcpFrame.xy);
125
+ float matchAlongV = contrast( rgbaM, rgbaAlongV );
126
+ // V 1 .
127
+ // 0 0 1
128
+ // . 0 .
129
+
130
+ relativeVContrast = matchAlongV - matchAlongH;
131
+ relativeVContrast *= fxaaQualityinvEdgeThreshold;
132
+
133
+ if( abs( relativeVContrast ) < .3 ) { // 45 deg edge
134
+ // 1 1 .
135
+ // 0 0 1
136
+ // . 0 1
137
+
138
+ // do a simple blur
139
+ return mix(
140
+ rgbaM,
141
+ (rgbaN + rgbaS + rgbaE + rgbaW) * .25,
142
+ .4
143
+ );
144
+ }
145
+
146
+ horzSpan = relativeVContrast > 0.;
147
+ }
148
+
149
+ if(!horzSpan) rgbaN = rgbaW;
150
+ if(!horzSpan) rgbaS = rgbaE;
151
+ // . 0 . 1
152
+ // 1 0 1 -> 0
153
+ // . 0 . 1
154
+
155
+ bool pairN = contrast( rgbaM, rgbaN ) > contrast( rgbaM, rgbaS );
156
+ if(!pairN) rgbaN = rgbaS;
157
+
158
+ vec2 offNP;
159
+ offNP.x = (!horzSpan) ? 0.0 : fxaaQualityRcpFrame.x;
160
+ offNP.y = ( horzSpan) ? 0.0 : fxaaQualityRcpFrame.y;
161
+
162
+ bool doneN = false;
163
+ bool doneP = false;
164
+
165
+ float nDist = 0.;
166
+ float pDist = 0.;
167
+
168
+ vec2 posN = posM;
169
+ vec2 posP = posM;
170
+
171
+ int iterationsUsed = 0;
172
+ int iterationsUsedN = 0;
173
+ int iterationsUsedP = 0;
174
+ for( int i = 0; i < NUM_SAMPLES; i++ ) {
175
+ iterationsUsed = i;
176
+
177
+ float increment = float(i + 1);
178
+
179
+ if(!doneN) {
180
+ nDist += increment;
181
+ posN = posM + offNP * nDist;
182
+ vec4 rgbaEndN = FxaaTexTop(tex, posN.xy);
183
+ doneN = contrast( rgbaEndN, rgbaM ) > contrast( rgbaEndN, rgbaN );
184
+ iterationsUsedN = i;
185
+ }
186
+
187
+ if(!doneP) {
188
+ pDist += increment;
189
+ posP = posM - offNP * pDist;
190
+ vec4 rgbaEndP = FxaaTexTop(tex, posP.xy);
191
+ doneP = contrast( rgbaEndP, rgbaM ) > contrast( rgbaEndP, rgbaN );
192
+ iterationsUsedP = i;
193
+ }
194
+
195
+ if(doneN || doneP) break;
196
+ }
197
+
198
+
199
+ if ( !doneP && !doneN ) return rgbaM; // failed to find end of edge
200
+
201
+ float dist = min(
202
+ doneN ? float( iterationsUsedN ) / float( NUM_SAMPLES - 1 ) : 1.,
203
+ doneP ? float( iterationsUsedP ) / float( NUM_SAMPLES - 1 ) : 1.
204
+ );
205
+
206
+ // hacky way of reduces blurriness of mostly diagonal edges
207
+ // but reduces AA quality
208
+ dist = pow(dist, .5);
209
+
210
+ dist = 1. - dist;
211
+
212
+ return mix(
213
+ rgbaM,
214
+ rgbaN,
215
+ dist * .5
216
+ );
217
+ }
218
+
219
+ void main() {
220
+ const float edgeDetectionQuality = .2;
221
+ const float invEdgeDetectionQuality = 1. / edgeDetectionQuality;
222
+
223
+ gl_FragColor = sRGBTransferOETF(FxaaPixelShader(
224
+ vUv,
225
+ tDiffuse,
226
+ resolution,
227
+ edgeDetectionQuality, // [0,1] contrast needed, otherwise early discard
228
+ invEdgeDetectionQuality
229
+ ));
230
+ ${ShaderChunk.logdepthbuf_fragment}
231
+ }
232
+ `,
233
+ blending: NoBlending,
234
+ depthTest: false,
235
+ depthWrite: false,
236
+ transparent: true
237
+ });
package/shaders.d.ts CHANGED
@@ -5,6 +5,3 @@ export declare const orthographicCamera: OrthographicCamera;
5
5
  export declare const clearShader: ShaderMaterial;
6
6
  export declare const intersectionShader: ShaderMaterial;
7
7
  export declare const copyShader: ShaderMaterial;
8
- export declare const baseTextureToRenderShader: ShaderMaterial;
9
- export declare const strokeShader: ShaderMaterial;
10
- export declare const gaussBlurShader: ShaderMaterial;
package/shaders.js CHANGED
@@ -4,7 +4,7 @@
4
4
  * @Last Modified by: xiaosihan
5
5
  * @Last Modified time: 2022-04-02 18:28:38
6
6
  */
7
- import { Color, NoBlending, OrthographicCamera, ShaderChunk, ShaderMaterial, Vector2 } from "three";
7
+ import { NoBlending, OrthographicCamera, ShaderChunk, ShaderMaterial } from "three";
8
8
  import FullScreenQuad from "./pass/FullScreenQuad";
9
9
  // 常用着色器及工具
10
10
  // 全屏渲染模型
@@ -95,163 +95,3 @@ export const copyShader = new ShaderMaterial({
95
95
  depthWrite: true,
96
96
  transparent: true,
97
97
  });
98
- // 渲染目标绘制到渲染器着色器
99
- export const baseTextureToRenderShader = new ShaderMaterial({
100
- uniforms: {
101
- map: { value: null },
102
- opacity: { value: 1.0 }, // 透明度
103
- },
104
- vertexShader: `
105
- ${ShaderChunk.common}
106
- ${ShaderChunk.logdepthbuf_pars_vertex}
107
- varying vec2 vUv;
108
- void main() {
109
- vUv = uv;
110
- gl_Position = vec4(position, 1.0);
111
- ${ShaderChunk.logdepthbuf_vertex}
112
- }
113
- `,
114
- fragmentShader: `
115
- ${ShaderChunk.logdepthbuf_pars_fragment}
116
- uniform sampler2D map;
117
- uniform float opacity;
118
- varying vec2 vUv;
119
- void main() {
120
- gl_FragColor = sRGBTransferOETF(texture(map, vUv));
121
- ${ShaderChunk.logdepthbuf_fragment}
122
- }
123
- `,
124
- depthTest: true,
125
- depthWrite: true,
126
- transparent: true,
127
- });
128
- // 描边着色器
129
- export const strokeShader = new ShaderMaterial({
130
- uniforms: {
131
- map: { value: null },
132
- resolution: { value: new Vector2(512, 512) },
133
- strokeWidth: { value: 1.0 },
134
- strokeColor: { value: new Color("#B2F2FF") },
135
- opacity: { value: 1.0 }, // 透明度
136
- },
137
- vertexShader: `
138
- varying vec2 vUv;
139
- void main() {
140
- vUv = uv;
141
- gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
142
- }
143
- `,
144
- fragmentShader: `
145
- uniform sampler2D map;
146
- uniform vec2 resolution;
147
- uniform vec3 strokeColor; // 描边颜色
148
- uniform float strokeWidth; // 描边厚度
149
- uniform float opacity; // 透明度
150
-
151
- varying vec2 vUv;
152
-
153
- // 获取当前叠加vu坐标偏移量的颜色值
154
- vec4 offsetColor(vec2 vu){
155
- return texture2D(map, vUv + (vu * (strokeWidth / resolution) ) );
156
- }
157
-
158
- vec4 fragColor(){
159
-
160
- vec4 currentColor = offsetColor(vec2(0.0, 0.0));
161
-
162
- if(
163
- currentColor.a < min(0.2, opacity) && (
164
- offsetColor(vec2(0.0, 1.0)).a > 0.0 ||
165
- offsetColor(vec2(0.0, -1.0)).a > 0.0 ||
166
- offsetColor(vec2(1.0, 0.0)).a > 0.0 ||
167
- offsetColor(vec2(-1.0, 0.0)).a > 0.0 ||
168
-
169
- offsetColor(vec2(1.0) * 0.7).a > 0.0 ||
170
- offsetColor(vec2(-1.0) * 0.7).a > 0.0 ||
171
- offsetColor(vec2(-1.0, 1.0) * 0.7).a > 0.0 ||
172
- offsetColor(vec2(1.0, -1.0) * 0.7).a > 0.0
173
- )
174
- ){
175
- return vec4( strokeColor, opacity);
176
- }else{
177
- // discard;
178
- return offsetColor(vec2(0.0, 0.0));
179
- }
180
-
181
- }
182
-
183
- void main() {
184
- gl_FragColor = fragColor();
185
- }
186
- `,
187
- blending: NoBlending,
188
- depthTest: true,
189
- depthWrite: true,
190
- transparent: true,
191
- });
192
- // 高斯模糊着色器 让颜色过渡更自然
193
- export const gaussBlurShader = new ShaderMaterial({
194
- uniforms: {
195
- map: { value: null },
196
- opacity: { value: 1.0 },
197
- radius: { value: 3.0 },
198
- resolution: { value: new Vector2(512, 512) }, // 渲染器的分辨率
199
- },
200
- vertexShader: `
201
- varying vec2 vUv;
202
- void main() {
203
- vUv = uv;
204
- gl_Position = vec4(position, 1.0);
205
- }
206
- `,
207
- fragmentShader: `
208
- uniform sampler2D map;
209
- uniform float opacity;
210
- uniform vec2 resolution;
211
- uniform float radius;
212
- varying vec2 vUv;
213
-
214
- vec4 offsetColor( vec2 uv){
215
- return texture2D(map, vUv + (uv / resolution * radius) );
216
- }
217
-
218
- vec4 blurColor(){
219
-
220
- vec4 leftColor = offsetColor( vec2(-1.0, 0.0) );
221
-
222
- vec4 rightColor = offsetColor( vec2(1.0, 0.0) );
223
-
224
- // 左右颜色混合
225
- vec4 leftRightColor = vec4(
226
- mix( leftColor.rgb ,rightColor.rgb, rightColor.a / (leftColor.a + rightColor.a)),
227
- (leftColor.a + rightColor.a) / 2.0
228
- );
229
-
230
- vec4 downColor = offsetColor( vec2(0.0, -1.0));
231
-
232
- vec4 upColor = offsetColor( vec2(0.0, 1.0));
233
-
234
- // 上下颜色混合
235
- vec4 upDownColor = vec4(
236
- mix( downColor.rgb, upColor.rgb, upColor.a / (downColor.a + upColor.a) ),
237
- (downColor.a + upColor.a) / 2.0
238
- );
239
-
240
- vec4 color = vec4(
241
- mix( leftRightColor.rgb, upDownColor.rgb, upDownColor.a / (leftRightColor.a + upDownColor.a) ),
242
- (leftRightColor.a + upDownColor.a) / 2.0
243
- );
244
-
245
- return color;
246
- }
247
-
248
- void main() {
249
- gl_FragColor = blurColor();
250
- gl_FragColor.a *= opacity;
251
- }
252
- `,
253
- blending: NoBlending,
254
- depthTest: false,
255
- depthWrite: false,
256
- transparent: true,
257
- });