three-base 2.0.98 → 2.0.100

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/ThreeBase.d.ts CHANGED
@@ -45,7 +45,7 @@ export default class ThreeBase extends EventDispatcher {
45
45
  position: Vector3;
46
46
  center: Vector3;
47
47
  }): void;
48
- setLookAt({ position, center, duration }: {
48
+ setLookAt({ position, center, duration, }: {
49
49
  position: Vector3;
50
50
  center: Vector3;
51
51
  duration?: number;
@@ -55,7 +55,7 @@ export default class ThreeBase extends EventDispatcher {
55
55
  position: Vector3;
56
56
  centerPosition: string;
57
57
  };
58
- lookatObjects({ objects, duration, direction, offset, distance }: {
58
+ lookatObjects({ objects, duration, direction, offset, distance, }: {
59
59
  objects: Array<Object3D>;
60
60
  duration?: number;
61
61
  direction?: Vector3;
package/ThreeBase.js CHANGED
@@ -2,20 +2,21 @@
2
2
  * @Author: xiaosihan
3
3
  * @Date: 2021-12-20 13:38:22
4
4
  * @Last Modified by: xiaosihan
5
- * @Last Modified time: 2024-08-10 04:23:41
5
+ * @Last Modified time: 2024-09-23 21:20:32
6
6
  */
7
7
  import { round } from "lodash";
8
- import { AxesHelper, Box3, DepthFormat, DepthTexture, EventDispatcher, GridHelper, LinearFilter, MOUSE, Mesh, NoBlending, NormalBlending, OrthographicCamera, PerspectiveCamera, RGBAFormat, Scene, TOUCH, UnsignedShortType, Vector2, Vector3, WebGLRenderTarget, WebGLRenderer } from "three";
8
+ import { AxesHelper, Box3, DepthFormat, DepthTexture, EventDispatcher, GridHelper, LinearFilter, MOUSE, Mesh, NoBlending, NormalBlending, OrthographicCamera, PerspectiveCamera, RGBAFormat, SRGBColorSpace, Scene, TOUCH, UnsignedShortType, Vector2, Vector3, WebGLRenderTarget, WebGLRenderer, } from "three";
9
9
  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
13
  import glow_pass from "./pass/glow_pass";
14
14
  import stroke_pass from "./pass/stroke_pass";
15
- import { clearShader, coptyShader, fullScreenMesh, gaussBlurShader, strokeShader } from "./shaders";
15
+ import { clearShader, coptyShader, fullScreenMesh, gaussBlurShader, strokeShader, } from "./shaders";
16
16
  import FXAAShaderMaterial from "./shaders/FXAAShaderMaterial";
17
17
  import threeLoader from "./threeLoader";
18
18
  import threeUtils from "./threeUtils";
19
+ import cover_pass from "./pass/cover_pass";
19
20
  // three.js 的基础对象
20
21
  export default class ThreeBase extends EventDispatcher {
21
22
  constructor() {
@@ -56,9 +57,17 @@ export default class ThreeBase extends EventDispatcher {
56
57
  return baseRenderTarget;
57
58
  })();
58
59
  // 公用渲染目标1
59
- renderTarget = new WebGLRenderTarget(128, 128, { minFilter: LinearFilter, magFilter: LinearFilter, format: RGBAFormat });
60
+ renderTarget = new WebGLRenderTarget(128, 128, {
61
+ minFilter: LinearFilter,
62
+ magFilter: LinearFilter,
63
+ format: RGBAFormat,
64
+ });
60
65
  // 渲染目标2
61
- renderTarget2 = new WebGLRenderTarget(128, 128, { minFilter: LinearFilter, magFilter: LinearFilter, format: RGBAFormat });
66
+ renderTarget2 = new WebGLRenderTarget(128, 128, {
67
+ minFilter: LinearFilter,
68
+ magFilter: LinearFilter,
69
+ format: RGBAFormat,
70
+ });
62
71
  // 公用二维向量
63
72
  tempVector2 = new Vector2();
64
73
  // 公用的三维向量
@@ -79,17 +88,18 @@ export default class ThreeBase extends EventDispatcher {
79
88
  });
80
89
  renderer.domElement.id = generateUUID();
81
90
  //监听上下文的销毁事件
82
- renderer.domElement.addEventListener('webglcontextlost', (event) => {
91
+ renderer.domElement.addEventListener("webglcontextlost", (event) => {
83
92
  this.rendererLost = true;
84
93
  }, false);
85
94
  // 监听上下文的恢复事件
86
- renderer.domElement.addEventListener('webglcontextrestored', (event) => {
95
+ renderer.domElement.addEventListener("webglcontextrestored", (event) => {
87
96
  this.rendererLost = false;
88
97
  }, false);
89
98
  renderer.localClippingEnabled = true;
90
99
  renderer.setPixelRatio(window.devicePixelRatio);
91
100
  renderer.autoClear = false;
92
101
  renderer.clear();
102
+ renderer.outputColorSpace = SRGBColorSpace;
93
103
  threeLoader.setAnisotropy(renderer.capabilities.getMaxAnisotropy());
94
104
  return renderer;
95
105
  })();
@@ -262,9 +272,8 @@ export default class ThreeBase extends EventDispatcher {
262
272
  return axesHelper;
263
273
  })();
264
274
  //TODO 设置帧频率 默认50帧
265
- frame = 50;
266
- init() {
267
- }
275
+ frame = 30;
276
+ init() { }
268
277
  // 重置控制器的位置
269
278
  resetLookAt({ position = this.perspectiveCamera.position, center = this.controls.target, }) {
270
279
  // 停止控制器的惯性
@@ -273,13 +282,21 @@ export default class ThreeBase extends EventDispatcher {
273
282
  this.controls.update();
274
283
  this.controls.reset();
275
284
  this.controls.enableDamping = originEnableDamping;
276
- this.controlsDistance.reset({ distance: new Vector3(position.x, position.y, position.z).distanceTo(new Vector3(center.x, center.y, center.z)) });
277
- position && this.controlsPosition.reset({ x: position.x, y: position.y, z: position.z });
278
- center && this.controlsCenter.reset({ x: center.x, y: center.y, z: center.z });
285
+ this.controlsDistance.reset({
286
+ distance: new Vector3(position.x, position.y, position.z).distanceTo(new Vector3(center.x, center.y, center.z)),
287
+ });
288
+ position &&
289
+ this.controlsPosition.reset({
290
+ x: position.x,
291
+ y: position.y,
292
+ z: position.z,
293
+ });
294
+ center &&
295
+ this.controlsCenter.reset({ x: center.x, y: center.y, z: center.z });
279
296
  this.needRender = true;
280
297
  }
281
298
  // 设置控制器的位置 以动画的方式移动控制器
282
- async setLookAt({ position = this.perspectiveCamera.position, center = this.controls.target, duration = 1000 }) {
299
+ async setLookAt({ position = this.perspectiveCamera.position, center = this.controls.target, duration = 1000, }) {
283
300
  // 停止控制器的惯性
284
301
  const originEnableDamping = this.controls.enableDamping;
285
302
  this.controls.saveState();
@@ -291,38 +308,60 @@ export default class ThreeBase extends EventDispatcher {
291
308
  // 等待动画执行完成
292
309
  await Promise.all([
293
310
  new Promise(async (resolve, reject) => {
294
- this.controlsDistance.setDuration(duration).reset({ distance: this.perspectiveCamera.position.distanceTo(this.controls.target) });
295
- await this.controlsDistance.set({ distance: new Vector3(position.x, position.y, position.z).distanceTo(new Vector3(center.x, center.y, center.z)) });
311
+ this.controlsDistance.setDuration(duration).reset({
312
+ distance: this.perspectiveCamera.position.distanceTo(this.controls.target),
313
+ });
314
+ await this.controlsDistance.set({
315
+ distance: new Vector3(position.x, position.y, position.z).distanceTo(new Vector3(center.x, center.y, center.z)),
316
+ });
296
317
  resolve();
297
318
  }),
298
319
  new Promise(async (resolve, reject) => {
299
- this.controlsPosition.setDuration(duration).reset({ x: currentPosition.x, y: currentPosition.y, z: currentPosition.z });
300
- await this.controlsPosition.set({ x: position.x, y: position.y, z: position.z });
320
+ this.controlsPosition.setDuration(duration).reset({
321
+ x: currentPosition.x,
322
+ y: currentPosition.y,
323
+ z: currentPosition.z,
324
+ });
325
+ await this.controlsPosition.set({
326
+ x: position.x,
327
+ y: position.y,
328
+ z: position.z,
329
+ });
301
330
  resolve();
302
331
  }),
303
332
  new Promise(async (resolve, reject) => {
304
- this.controlsCenter.setDuration(duration).reset({ x: currentCenter.x, y: currentCenter.y, z: currentCenter.z });
305
- await this.controlsCenter.set({ x: center.x, y: center.y, z: center.z });
333
+ this.controlsCenter.setDuration(duration).reset({
334
+ x: currentCenter.x,
335
+ y: currentCenter.y,
336
+ z: currentCenter.z,
337
+ });
338
+ await this.controlsCenter.set({
339
+ x: center.x,
340
+ y: center.y,
341
+ z: center.z,
342
+ });
306
343
  resolve();
307
- })
344
+ }),
308
345
  ]);
309
346
  }
310
347
  // 获取控制的位置和朝向 保留3位小数
311
348
  getLookAt() {
312
349
  //判断需要使用那个相机
313
- const position = this.perspectiveCamera.position.toArray().map(v => round(v, 3));
314
- const center = this.controls.target.toArray().map(v => round(v, 3));
350
+ const position = this.perspectiveCamera.position
351
+ .toArray()
352
+ .map((v) => round(v, 3));
353
+ const center = this.controls.target.toArray().map((v) => round(v, 3));
315
354
  return {
316
355
  center: new Vector3(...center),
317
356
  position: new Vector3(...position),
318
- centerPosition: `center: new Vector3(${center.join(",")}),position: new Vector3(${position.join(",")})`
357
+ centerPosition: `center: new Vector3(${center.join(",")}),position: new Vector3(${position.join(",")})`,
319
358
  };
320
359
  }
321
360
  // 查看对象
322
- lookatObjects({ objects, duration = 1000, direction = new Vector3(0.3, 0.3, 1), offset = new Vector3(0, 0, 0), distance = 1 }) {
361
+ lookatObjects({ objects, duration = 1000, direction = new Vector3(0.3, 0.3, 1), offset = new Vector3(0, 0, 0), distance = 1, }) {
323
362
  const box3 = new Box3();
324
- objects.map(o => {
325
- o.traverse(oo => {
363
+ objects.map((o) => {
364
+ o.traverseVisible((oo) => {
326
365
  box3.expandByObject(oo);
327
366
  });
328
367
  });
@@ -334,7 +373,7 @@ export default class ThreeBase extends EventDispatcher {
334
373
  const modelSize = size.length() * distance;
335
374
  if (this.cameraType === "perspectiveCamera") {
336
375
  const { fov } = this.getCamera();
337
- const cameraDistance = modelSize / (2 * Math.tan(fov * Math.PI / 360));
376
+ const cameraDistance = modelSize / (2 * Math.tan((fov * Math.PI) / 360));
338
377
  const position = direction.setLength(cameraDistance).add(center);
339
378
  this.setLookAt({ center, position, duration });
340
379
  }
@@ -355,7 +394,11 @@ export default class ThreeBase extends EventDispatcher {
355
394
  setControlType(controlType) {
356
395
  if (controlType === "OrbitControls") {
357
396
  this.controls.screenSpacePanning = this.originScreenSpacePanning;
358
- this.controls.mouseButtons = { LEFT: MOUSE.ROTATE, MIDDLE: MOUSE.DOLLY, RIGHT: MOUSE.PAN };
397
+ this.controls.mouseButtons = {
398
+ LEFT: MOUSE.ROTATE,
399
+ MIDDLE: MOUSE.DOLLY,
400
+ RIGHT: MOUSE.PAN,
401
+ };
359
402
  this.controls.touches = { ONE: TOUCH.ROTATE, TWO: TOUCH.DOLLY_PAN };
360
403
  }
361
404
  else if (controlType === "MapControls") {
@@ -383,14 +426,18 @@ export default class ThreeBase extends EventDispatcher {
383
426
  }
384
427
  // 判断是否有 发光和描边等对象 以便判断是否需要 渲染深度纹理
385
428
  hasPass() {
386
- let has_stroke_or_pass = false;
387
- this.scene.traverse(obj => {
388
- const { stroke_enable = false, stroke_width = 1, glow_enable = false, glow_width = 1 } = obj.userData;
389
- if ((stroke_enable && stroke_width > 0) || (glow_enable && glow_width > 0)) {
390
- has_stroke_or_pass = true;
429
+ let hasPass = false;
430
+ this.scene.traverse((obj) => {
431
+ const { stroke_enable = false, stroke_width = 1, glow_enable = false, glow_width = 1, cover_enable = false, //颜色覆盖
432
+ cover_opacity = 0, //透明度
433
+ } = obj.userData;
434
+ if ((stroke_enable && stroke_width > 0) ||
435
+ (glow_enable && glow_width > 0) ||
436
+ (cover_enable && cover_opacity > 0)) {
437
+ hasPass = true;
391
438
  }
392
439
  });
393
- return has_stroke_or_pass;
440
+ return hasPass;
394
441
  }
395
442
  // 渲染场景
396
443
  render() {
@@ -403,23 +450,33 @@ export default class ThreeBase extends EventDispatcher {
403
450
  if (this.cameraType === "perspectiveCamera") {
404
451
  const { center } = this.getLookAt();
405
452
  const { fov } = this.perspectiveCamera;
406
- const distaned = this.perspectiveCamera.position.clone().sub(center).length();
453
+ const distaned = this.perspectiveCamera.position
454
+ .clone()
455
+ .sub(center)
456
+ .length();
407
457
  const zoom = 1 / (Math.tan(degToRad(fov) / 2) * distaned);
408
458
  this.orthographicCamera.zoom = zoom;
409
- this.orthographicCamera.position.copy(this.perspectiveCamera.position.clone().sub(center)).setLength(2500).add(center);
459
+ this.orthographicCamera.position
460
+ .copy(this.perspectiveCamera.position.clone().sub(center))
461
+ .setLength(2500)
462
+ .add(center);
410
463
  }
411
464
  else if (this.cameraType === "orthographicCamera") {
412
465
  const { center } = this.getLookAt();
413
466
  const { fov } = this.perspectiveCamera;
414
467
  const { zoom } = this.orthographicCamera;
415
- const distaned = (1 / zoom) / Math.tan(degToRad(fov) / 2);
416
- this.perspectiveCamera.position.copy(this.orthographicCamera.position.clone().sub(center)).setLength(distaned).add(center);
468
+ const distaned = 1 / zoom / Math.tan(degToRad(fov) / 2);
469
+ this.perspectiveCamera.position
470
+ .copy(this.orthographicCamera.position.clone().sub(center))
471
+ .setLength(distaned)
472
+ .add(center);
417
473
  }
418
474
  //判断需要使用那个相机
419
475
  const camera = this.getCamera();
420
476
  //判断尺寸发生改变时重置尺寸
421
477
  const parentNode = this.renderer.domElement.parentNode;
422
- if (parentNode.clientWidth !== this.size.x || parentNode.clientHeight !== this.size.y) {
478
+ if (parentNode.clientWidth !== this.size.x ||
479
+ parentNode.clientHeight !== this.size.y) {
423
480
  this.setSize(parentNode.clientWidth, parentNode.clientHeight);
424
481
  }
425
482
  // 分发鼠标事件
@@ -447,9 +504,10 @@ export default class ThreeBase extends EventDispatcher {
447
504
  this.renderer.render(this.scene, camera);
448
505
  if (hasPass) {
449
506
  // 查找需要绘制描边的对象,并且绘制描边
450
- this.scene.traverseVisible(obj => {
507
+ this.scene.traverseVisible((obj) => {
451
508
  stroke_pass(this.renderer, camera, obj, this.baseDepthTexture);
452
509
  glow_pass(this.renderer, camera, obj, this.baseDepthTexture);
510
+ cover_pass(this.renderer, camera, obj, this.baseDepthTexture);
453
511
  });
454
512
  }
455
513
  this.dispatchEvent({ type: "afterRender" });
@@ -459,7 +517,7 @@ export default class ThreeBase extends EventDispatcher {
459
517
  async getThumbBlob() {
460
518
  this.render();
461
519
  const blob = await new Promise((resolve, reject) => {
462
- this.renderer.domElement.toBlob(blob => {
520
+ this.renderer.domElement.toBlob((blob) => {
463
521
  resolve(blob);
464
522
  }, "image/png", 1);
465
523
  });
@@ -468,20 +526,20 @@ export default class ThreeBase extends EventDispatcher {
468
526
  //获取渲染图base64
469
527
  getThumbBase64() {
470
528
  this.render();
471
- const base64 = this.renderer.domElement.toDataURL('image/png');
529
+ const base64 = this.renderer.domElement.toDataURL("image/png");
472
530
  return base64;
473
531
  }
474
532
  //获取渲染图文件对象
475
533
  async getThumbFile() {
476
534
  const blob = await this.getThumbBlob();
477
- const file = new File([blob], 'thumb.png', { type: blob.type });
535
+ const file = new File([blob], "thumb.png", { type: blob.type });
478
536
  return file;
479
537
  }
480
538
  // 下载渲染图
481
539
  async download(fileName = "download") {
482
540
  this.render();
483
541
  const blob = await this.getThumbBlob();
484
- const base64 = this.renderer.domElement.toDataURL('image/png');
542
+ const base64 = this.renderer.domElement.toDataURL("image/png");
485
543
  let saveLink = document.createElement("a");
486
544
  saveLink.download = `${fileName}.png`;
487
545
  saveLink.href = URL.createObjectURL(blob);
@@ -489,12 +547,17 @@ export default class ThreeBase extends EventDispatcher {
489
547
  saveLink.click();
490
548
  }
491
549
  _preMesh = new Mesh();
492
- _preRT = new WebGLRenderTarget(128, 128, { minFilter: LinearFilter, magFilter: LinearFilter, format: RGBAFormat });
550
+ _preRT = new WebGLRenderTarget(128, 128, {
551
+ minFilter: LinearFilter,
552
+ magFilter: LinearFilter,
553
+ format: RGBAFormat,
554
+ });
493
555
  //预加载纹理图片
494
556
  async preloadTexture(src) {
495
557
  const texture = threeLoader.getTexture(src);
496
- while (texture && !texture.image || !texture.image.complete) {
497
- await new Promise(resolve => setTimeout(resolve, 50));
558
+ while ((texture && !texture.image) ||
559
+ !texture.image.complete) {
560
+ await new Promise((resolve) => setTimeout(resolve, 50));
498
561
  }
499
562
  // 添加到计划任务中去
500
563
  threeUtils.addWork(() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "three-base",
3
- "version": "2.0.98",
3
+ "version": "2.0.100",
4
4
  "description": "three 3d three-base",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
File without changes
@@ -0,0 +1,7 @@
1
+ /*
2
+ * @Author: xiaosihan
3
+ * @Date: 2024-09-23 21:51:29
4
+ * @Last Modified by: xiaosihan
5
+ * @Last Modified time: 2024-09-23 21:51:29
6
+ */
7
+ // 发光后期通道
@@ -0,0 +1,2 @@
1
+ import { Camera, DepthTexture, Object3D, WebGLRenderer } from "three";
2
+ export default function cover_pass(renderer: WebGLRenderer, camera: Camera, object3d: Object3D, baseDepthTexture: DepthTexture): void;
@@ -0,0 +1,124 @@
1
+ /*
2
+ * @Author: xiaosihan
3
+ * @Date: 2024-09-23 21:07:06
4
+ * @Last Modified by: xiaosihan
5
+ * @Last Modified time: 2024-09-23 21:53:12
6
+ */
7
+ /*
8
+ * @Author: xiaosihan
9
+ * @Date: 2023-05-09 00:35:17
10
+ * @Last Modified by: xiaosihan
11
+ * @Last Modified time: 2023-05-09 02:33:28
12
+ */
13
+ import { Color, DepthFormat, DepthTexture, LinearFilter, NoBlending, RGBAFormat, Scene, ShaderChunk, ShaderMaterial, UnsignedShortType, Vector2, WebGLRenderTarget } from "three";
14
+ import copyShader from "../shaders/copyShader";
15
+ import FullScreenQuad from "./FullScreenQuad";
16
+ // 选中对象的深度纹理
17
+ const selectDepthTexture = (() => {
18
+ const baseDepthTexture = new DepthTexture(4096, 4096);
19
+ baseDepthTexture.format = DepthFormat;
20
+ baseDepthTexture.type = UnsignedShortType;
21
+ baseDepthTexture.anisotropy = 16;
22
+ return baseDepthTexture;
23
+ })();
24
+ // 选中对象的纹理
25
+ const selectTextureTarget = new WebGLRenderTarget(512, 512, {
26
+ minFilter: LinearFilter,
27
+ magFilter: LinearFilter,
28
+ format: RGBAFormat,
29
+ depthTexture: selectDepthTexture,
30
+ anisotropy: 16,
31
+ });
32
+ // 深度测试后的选中纹理
33
+ const selectDethpTestTextureTarget = new WebGLRenderTarget(512, 512, {
34
+ minFilter: LinearFilter,
35
+ magFilter: LinearFilter,
36
+ format: RGBAFormat,
37
+ anisotropy: 16,
38
+ });
39
+ const blur1TextureTarget = new WebGLRenderTarget(512, 512, {
40
+ minFilter: LinearFilter,
41
+ magFilter: LinearFilter,
42
+ format: RGBAFormat,
43
+ });
44
+ const size = new Vector2();
45
+ // 创建一个渲染工具 用于处理纹理
46
+ const fsQuad = new FullScreenQuad(); // 渲染辅助器
47
+ //深度比对纹理
48
+ const depthTestShader = new ShaderMaterial({
49
+ uniforms: {
50
+ color: { value: new Color("#000000") },
51
+ baseDepth: { value: null },
52
+ selectDepth: { value: null }, // 选中的对象深度纹理
53
+ },
54
+ vertexShader: `
55
+ ${ShaderChunk.common}
56
+ ${ShaderChunk.logdepthbuf_pars_vertex}
57
+ varying vec2 vUv;
58
+ void main() {
59
+ vUv = uv;
60
+ // gl_Position = vec4(position, 1.0);
61
+ // gl_Position = projectionMatrix * modelViewMatrix * instanceMatrix * vec4(position, 1.0);
62
+ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
63
+ ${ShaderChunk.logdepthbuf_vertex}
64
+ }
65
+ `,
66
+ fragmentShader: `
67
+ ${ShaderChunk.logdepthbuf_pars_fragment}
68
+ uniform vec3 color;
69
+ uniform sampler2D baseDepth;
70
+ uniform sampler2D selectDepth;
71
+ varying vec2 vUv;
72
+ void main() {
73
+ if(texture2D(baseDepth, vUv).r + 0.0001 < texture2D(selectDepth, vUv).r){
74
+ discard;
75
+ }
76
+ gl_FragColor = vec4(color, 1.0);
77
+ ${ShaderChunk.logdepthbuf_fragment}
78
+ }
79
+ `,
80
+ blending: NoBlending,
81
+ depthTest: true,
82
+ depthWrite: true,
83
+ transparent: true,
84
+ });
85
+ // 场景对象
86
+ const scene = new Scene();
87
+ // 给模型覆盖一层颜色 后处理通道
88
+ export default function cover_pass(renderer, camera, object3d, baseDepthTexture) {
89
+ const { cover_enable = false, cover_color = "#04fa12", cover_opacity = 1, } = object3d.userData;
90
+ if (!cover_enable || cover_opacity === 0) {
91
+ return;
92
+ }
93
+ // 保存原帧缓冲区
94
+ const originRenderTarget = renderer.getRenderTarget();
95
+ // 设置选中目标的帧缓冲区
96
+ renderer.getSize(size);
97
+ size.multiplyScalar(window.devicePixelRatio);
98
+ selectTextureTarget.setSize(size.x, size.y);
99
+ selectDethpTestTextureTarget.setSize(size.x, size.y);
100
+ blur1TextureTarget.setSize(size.x, size.y);
101
+ renderer.setRenderTarget(selectTextureTarget);
102
+ scene.children = [object3d];
103
+ renderer.clear();
104
+ renderer.render(scene, camera);
105
+ //深度测试
106
+ renderer.setRenderTarget(selectDethpTestTextureTarget);
107
+ renderer.clear();
108
+ depthTestShader.uniforms.color.value.set(cover_color);
109
+ depthTestShader.uniforms.baseDepth.value = baseDepthTexture;
110
+ depthTestShader.uniforms.selectDepth.value = selectDepthTexture;
111
+ fsQuad.render(renderer, depthTestShader);
112
+ // 颜色覆盖绘制到着色器
113
+ renderer.setRenderTarget(originRenderTarget);
114
+ renderer.clearDepth();
115
+ copyShader.uniforms.map.value = selectDethpTestTextureTarget.texture;
116
+ copyShader.uniforms.opacity.value = cover_opacity;
117
+ fsQuad.render(renderer, copyShader);
118
+ // 调试代码
119
+ // renderer.setRenderTarget(null);
120
+ // renderer.clearDepth();
121
+ // copyShader.uniforms.tDiffuse.value = blur2TextureTarget.texture;
122
+ // fsQuad.render(renderer, copyShader);
123
+ // return;
124
+ }
@@ -1,2 +1,2 @@
1
- import { Camera, Object3D, WebGLRenderer, DepthTexture } from "three";
1
+ import { Camera, DepthTexture, Object3D, WebGLRenderer } from "three";
2
2
  export default function glow_pass(renderer: WebGLRenderer, camera: Camera, object3d: Object3D, baseDepthTexture: DepthTexture): void;
package/pass/glow_pass.js CHANGED
@@ -2,9 +2,9 @@
2
2
  * @Author: xiaosihan
3
3
  * @Date: 2023-05-09 00:35:17
4
4
  * @Last Modified by: xiaosihan
5
- * @Last Modified time: 2023-05-09 02:33:28
5
+ * @Last Modified time: 2024-09-23 22:00:48
6
6
  */
7
- import { LinearFilter, RGBAFormat, Vector2, WebGLRenderTarget, ShaderMaterial, NoBlending, Scene, RawShaderMaterial, Color, NormalBlending, ShaderChunk, DepthTexture, DepthFormat, UnsignedShortType } from "three";
7
+ import { Color, DepthFormat, DepthTexture, LinearFilter, NoBlending, NormalBlending, RGBAFormat, RawShaderMaterial, Scene, ShaderChunk, ShaderMaterial, UnsignedShortType, Vector2, WebGLRenderTarget } from "three";
8
8
  import FullScreenQuad from "./FullScreenQuad";
9
9
  // 选中对象的深度纹理
10
10
  const selectDepthTexture = (() => {
@@ -1,2 +1,2 @@
1
- import { Camera, Object3D, WebGLRenderer, DepthTexture } from "three";
1
+ import { Camera, DepthTexture, Object3D, WebGLRenderer } from "three";
2
2
  export default function stroke_pass(renderer: WebGLRenderer, camera: Camera, object3d: Object3D, baseDepthTexture: DepthTexture): void;
@@ -2,9 +2,9 @@
2
2
  * @Author: xiaosihan
3
3
  * @Date: 2023-05-09 00:35:17
4
4
  * @Last Modified by: xiaosihan
5
- * @Last Modified time: 2023-05-09 02:33:28
5
+ * @Last Modified time: 2024-09-23 22:00:54
6
6
  */
7
- import { LinearFilter, RGBAFormat, Vector2, WebGLRenderTarget, ShaderMaterial, NoBlending, Scene, RawShaderMaterial, Color, NormalBlending, ShaderChunk, DepthTexture, DepthFormat, UnsignedShortType } from "three";
7
+ import { Color, DepthFormat, DepthTexture, LinearFilter, NoBlending, NormalBlending, RGBAFormat, RawShaderMaterial, Scene, ShaderChunk, ShaderMaterial, UnsignedShortType, Vector2, WebGLRenderTarget } from "three";
8
8
  import FullScreenQuad from "./FullScreenQuad";
9
9
  // 选中对象的深度纹理
10
10
  const selectDepthTexture = (() => {
@@ -0,0 +1,3 @@
1
+ import { ShaderMaterial } from "three";
2
+ declare const copyShader: ShaderMaterial;
3
+ export default copyShader;
@@ -0,0 +1,33 @@
1
+ import { ShaderChunk, ShaderMaterial } from "three";
2
+ // 拷贝着色器
3
+ const copyShader = new ShaderMaterial({
4
+ uniforms: {
5
+ map: { value: null },
6
+ opacity: { value: 1 }, // 透明度
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
+ uniform float opacity;
21
+ uniform sampler2D map;
22
+ varying vec2 vUv;
23
+ void main() {
24
+ gl_FragColor = texture2D(map, vUv);
25
+ gl_FragColor.a *= opacity;
26
+ ${ShaderChunk.logdepthbuf_fragment}
27
+ }
28
+ `,
29
+ depthTest: true,
30
+ depthWrite: true,
31
+ transparent: true,
32
+ });
33
+ export default copyShader;
package/threeLoader.js CHANGED
@@ -4,7 +4,7 @@
4
4
  * @Last Modified by: xiaosihan
5
5
  * @Last Modified time: 2024-09-11 11:43:31
6
6
  */
7
- import { CanvasTexture, DefaultLoadingManager, EventDispatcher, Mesh, MeshStandardMaterial, RepeatWrapping, TextureLoader, VideoTexture, } from "three";
7
+ import { CanvasTexture, DefaultLoadingManager, EventDispatcher, Mesh, MeshStandardMaterial, RepeatWrapping, SRGBColorSpace, TextureLoader, VideoTexture, } from "three";
8
8
  import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
9
9
  import { FBXLoader } from "three/examples/jsm/loaders/FBXLoader";
10
10
  import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
@@ -26,6 +26,8 @@ import { isArray, isEmpty, isNull, isString, isUndefined } from "lodash";
26
26
  import { generateUUID } from "three/src/math/MathUtils";
27
27
  import dracoDecoderWASM from "./lib/draco/draco_decoder.wasm?url";
28
28
  import threeUtils from "./threeUtils";
29
+ import { TGALoader } from "three/examples/jsm/Addons.js";
30
+ DefaultLoadingManager.addHandler(/tga$/, new TGALoader());
29
31
  // 加载器
30
32
  class ThreeLoader extends EventDispatcher {
31
33
  constructor() {
@@ -76,7 +78,7 @@ class ThreeLoader extends EventDispatcher {
76
78
  const canvasTexture = new CanvasTexture(src);
77
79
  canvasTexture.wrapS = canvasTexture.wrapT = RepeatWrapping;
78
80
  canvasTexture.anisotropy = this.anisotropy;
79
- // canvasTexture.colorSpace = SRGBColorSpace;
81
+ canvasTexture.colorSpace = SRGBColorSpace;
80
82
  return canvasTexture;
81
83
  }
82
84
  let texture = this.textureMap.get(src);
@@ -110,7 +112,7 @@ class ThreeLoader extends EventDispatcher {
110
112
  }
111
113
  texture.wrapS = texture.wrapT = RepeatWrapping;
112
114
  texture.anisotropy = this.anisotropy;
113
- // texture.colorSpace = SRGBColorSpace;
115
+ texture.colorSpace = SRGBColorSpace;
114
116
  return texture;
115
117
  }
116
118
  // 资源列表
@@ -344,6 +346,11 @@ class ThreeLoader extends EventDispatcher {
344
346
  if (stl) {
345
347
  return await this.loadModel(stl);
346
348
  }
349
+ //如果有zip文件就加载zip文件
350
+ let zipFile = Object.keys(zip.files).find((filename) => /\.stl$/.test(filename));
351
+ if (zipFile) {
352
+ return await this.loadModel(zipFile);
353
+ }
347
354
  if ([obj, gltf, dae, fbx, usdz, stl].every((v) => !v)) {
348
355
  throw new Error(`${url}压缩包里没有obj.glb.gltf.dae.fbx.usde.stl等模型文件`);
349
356
  }