three-base 2.0.49 → 2.0.51

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/Fire/Fire.d.ts ADDED
@@ -0,0 +1,28 @@
1
+ import { BufferGeometry, Camera, Clock, Group, Material, NormalBufferAttributes, Object3DEventMap, Points, Scene, Vector2, WebGLRenderer } from "three";
2
+ import FireGromtry from "./FireGromtry";
3
+ import FireMaterial from "./FireMaterial";
4
+ export default class Fire extends Points {
5
+ constructor();
6
+ geometry: FireGromtry;
7
+ material: FireMaterial;
8
+ fireColor: string;
9
+ fireScale: number;
10
+ fireRadius: number;
11
+ fireHeight: number;
12
+ particleCount: number;
13
+ isPerspectiveCamera: boolean;
14
+ size: Vector2;
15
+ cacheProps: {
16
+ fireColor: string;
17
+ fireScale: number;
18
+ fireRadius: number;
19
+ fireHeight: number;
20
+ particleCount: number;
21
+ width: number;
22
+ height: number;
23
+ isPerspectiveCamera: boolean;
24
+ };
25
+ updataFrame: number;
26
+ clock: Clock;
27
+ onBeforeRender(renderer: WebGLRenderer, scene: Scene, camera: Camera, geometry: BufferGeometry<NormalBufferAttributes>, material: Material, group: Group<Object3DEventMap>): void;
28
+ }
package/Fire/Fire.js ADDED
@@ -0,0 +1,79 @@
1
+ /*
2
+ * @Author: xiaosihan
3
+ * @Date: 2024-06-17 02:15:58
4
+ * @Last Modified by: xiaosihan
5
+ * @Last Modified time: 2024-06-18 20:34:38
6
+ */
7
+ import { Clock, Color, Points, Vector2 } from "three";
8
+ import FireGromtry from "./FireGromtry";
9
+ import FireMaterial from "./FireMaterial";
10
+ import { degToRad } from "three/src/math/MathUtils";
11
+ // 粒子火焰效果
12
+ export default class Fire extends Points {
13
+ constructor() {
14
+ super();
15
+ }
16
+ geometry = new FireGromtry(0, 0, 0);
17
+ material = new FireMaterial();
18
+ // 火焰的颜色
19
+ fireColor = "#ff2200";
20
+ // 火焰的整体缩放值
21
+ fireScale = 1;
22
+ // 火焰的燃烧半径
23
+ fireRadius = 0.5;
24
+ // 火焰的高度
25
+ fireHeight = 3;
26
+ // 火焰的粒子数量
27
+ particleCount = 500;
28
+ // 是否是透视相机
29
+ isPerspectiveCamera = true;
30
+ //渲染器的尺寸
31
+ size = new Vector2();
32
+ // 缓存的参数
33
+ cacheProps = {
34
+ fireColor: "#ff2200",
35
+ fireScale: 0,
36
+ fireRadius: 0.5,
37
+ fireHeight: 3,
38
+ particleCount: 500,
39
+ width: 0,
40
+ height: 0,
41
+ isPerspectiveCamera: true
42
+ };
43
+ // 当前渲染的帧数
44
+ updataFrame = 0;
45
+ // 时钟对象
46
+ clock = new Clock();
47
+ onBeforeRender(renderer, scene, camera, geometry, material, group) {
48
+ const delta = this.clock.getDelta();
49
+ renderer.getSize(this.size);
50
+ if (this.cacheProps.fireColor !== this.fireColor ||
51
+ this.cacheProps.fireScale !== this.fireScale ||
52
+ this.cacheProps.fireRadius !== this.fireRadius ||
53
+ this.cacheProps.fireHeight !== this.fireHeight ||
54
+ this.cacheProps.particleCount !== this.particleCount ||
55
+ this.cacheProps.isPerspectiveCamera !== this.isPerspectiveCamera ||
56
+ this.cacheProps.width !== this.size.x ||
57
+ this.cacheProps.height !== this.size.y) {
58
+ this.cacheProps.fireColor = this.fireColor;
59
+ this.cacheProps.fireScale = this.fireScale;
60
+ this.cacheProps.fireRadius = this.fireRadius;
61
+ this.cacheProps.fireHeight = this.fireHeight;
62
+ this.cacheProps.particleCount = this.particleCount;
63
+ this.cacheProps.isPerspectiveCamera = this.isPerspectiveCamera;
64
+ this.cacheProps.width = this.size.x;
65
+ this.cacheProps.height = this.size.y;
66
+ this.geometry = new FireGromtry(this.fireRadius * this.fireScale, this.fireHeight * this.fireScale, this.particleCount);
67
+ this.material.uniforms.color.value = new Color(this.fireColor);
68
+ this.material.uniforms.size.value = this.fireScale * 0.4;
69
+ if (camera.isPerspectiveCamera) {
70
+ this.material.uniforms.heightOfNearPlane.value = Math.abs(this.size.y / (2 * Math.tan(degToRad(camera.fov * 0.5))));
71
+ }
72
+ else {
73
+ this.material.uniforms.heightOfNearPlane.value = 0;
74
+ }
75
+ }
76
+ this.isPerspectiveCamera = camera.isPerspectiveCamera;
77
+ this.material.uniforms.time.value = (this.material.uniforms.time.value + delta) % 1;
78
+ }
79
+ }
package/Fire/Fire.ts ADDED
@@ -0,0 +1,99 @@
1
+ /*
2
+ * @Author: xiaosihan
3
+ * @Date: 2024-06-17 02:15:58
4
+ * @Last Modified by: xiaosihan
5
+ * @Last Modified time: 2024-06-18 20:34:38
6
+ */
7
+
8
+ import { BufferGeometry, Camera, Clock, Color, Group, Material, NormalBufferAttributes, Object3DEventMap, PerspectiveCamera, Points, Scene, Vector2, WebGLRenderer } from "three";
9
+ import FireGromtry from "./FireGromtry";
10
+ import FireMaterial from "./FireMaterial";
11
+ import { degToRad } from "three/src/math/MathUtils";
12
+
13
+ // 粒子火焰效果
14
+ export default class Fire extends Points {
15
+
16
+ constructor() {
17
+ super();
18
+ }
19
+
20
+ geometry = new FireGromtry(0, 0, 0);
21
+
22
+ material = new FireMaterial();
23
+
24
+ // 火焰的颜色
25
+ fireColor = "#ff2200";
26
+ // 火焰的整体缩放值
27
+ fireScale = 1;
28
+ // 火焰的燃烧半径
29
+ fireRadius = 0.5;
30
+ // 火焰的高度
31
+ fireHeight = 3;
32
+ // 火焰的粒子数量
33
+ particleCount = 500;
34
+ // 是否是透视相机
35
+ isPerspectiveCamera = true;
36
+ //渲染器的尺寸
37
+ size = new Vector2();
38
+
39
+ // 缓存的参数
40
+ cacheProps = {
41
+ fireColor: "#ff2200",
42
+ fireScale: 0,
43
+ fireRadius: 0.5,
44
+ fireHeight: 3,
45
+ particleCount: 500,
46
+ width: 0,
47
+ height: 0,
48
+ isPerspectiveCamera: true
49
+ }
50
+
51
+ // 当前渲染的帧数
52
+ updataFrame = 0;
53
+
54
+ // 时钟对象
55
+ clock = new Clock();
56
+
57
+ onBeforeRender(renderer: WebGLRenderer, scene: Scene, camera: Camera, geometry: BufferGeometry<NormalBufferAttributes>, material: Material, group: Group<Object3DEventMap>): void {
58
+
59
+ const delta = this.clock.getDelta();
60
+ renderer.getSize(this.size);
61
+
62
+ if (
63
+ this.cacheProps.fireColor !== this.fireColor ||
64
+ this.cacheProps.fireScale !== this.fireScale ||
65
+ this.cacheProps.fireRadius !== this.fireRadius ||
66
+ this.cacheProps.fireHeight !== this.fireHeight ||
67
+ this.cacheProps.particleCount !== this.particleCount ||
68
+ this.cacheProps.isPerspectiveCamera !== this.isPerspectiveCamera ||
69
+ this.cacheProps.width !== this.size.x ||
70
+ this.cacheProps.height !== this.size.y
71
+ ) {
72
+ this.cacheProps.fireColor = this.fireColor;
73
+ this.cacheProps.fireScale = this.fireScale;
74
+ this.cacheProps.fireRadius = this.fireRadius;
75
+ this.cacheProps.fireHeight = this.fireHeight;
76
+ this.cacheProps.particleCount = this.particleCount;
77
+ this.cacheProps.isPerspectiveCamera = this.isPerspectiveCamera;
78
+ this.cacheProps.width = this.size.x;
79
+ this.cacheProps.height = this.size.y;
80
+
81
+ this.geometry = new FireGromtry(this.fireRadius * this.fireScale, this.fireHeight * this.fireScale, this.particleCount);
82
+
83
+ this.material.uniforms.color.value = new Color(this.fireColor);
84
+ this.material.uniforms.size.value = this.fireScale * 0.4;
85
+ if ((camera as PerspectiveCamera).isPerspectiveCamera) {
86
+ this.material.uniforms.heightOfNearPlane.value = Math.abs(this.size.y / (2 * Math.tan(degToRad((camera as PerspectiveCamera).fov * 0.5))));
87
+ } else {
88
+ this.material.uniforms.heightOfNearPlane.value = 0;
89
+ }
90
+
91
+ }
92
+
93
+ this.isPerspectiveCamera = (camera as PerspectiveCamera).isPerspectiveCamera;
94
+
95
+ this.material.uniforms.time.value = (this.material.uniforms.time.value + delta) % 1;
96
+
97
+ }
98
+
99
+ }
@@ -0,0 +1,9 @@
1
+ export declare const SPRITE_ROW_LENGTH = 4;
2
+ export declare const ONE_SPRITE_ROW_LENGTH: number;
3
+ import { BufferGeometry } from "three";
4
+ export default class FireGromtry extends BufferGeometry {
5
+ radius: number;
6
+ height: number;
7
+ particleCount: number;
8
+ constructor(radius?: number, height?: number, particleCount?: number);
9
+ }
@@ -0,0 +1,40 @@
1
+ /*
2
+ * @Author: xiaosihan
3
+ * @Date: 2024-06-17 02:15:58
4
+ * @Last Modified by: xiaosihan
5
+ * @Last Modified time: 2024-06-18 18:12:37
6
+ */
7
+ export const SPRITE_ROW_LENGTH = 4; // 粒子图片中图片数量
8
+ export const ONE_SPRITE_ROW_LENGTH = 1 / SPRITE_ROW_LENGTH; // 每一行的宽度
9
+ import { BufferAttribute, BufferGeometry } from "three";
10
+ // 粒子火焰顶点对象
11
+ export default class FireGromtry extends BufferGeometry {
12
+ radius = 0.5;
13
+ height = 3;
14
+ particleCount = 200;
15
+ constructor(radius = 0.5, height = 3, particleCount = 200) {
16
+ super();
17
+ const halfHeight = height * 0.5;
18
+ const position = new Float32Array(particleCount * 3);
19
+ const random = new Float32Array(particleCount);
20
+ const sprite = new Float32Array(particleCount);
21
+ for (let i = 0; i < particleCount; i++) {
22
+ const r = Math.sqrt(Math.random()) * radius;
23
+ const angle = Math.random() * 2 * Math.PI;
24
+ position[i * 3 + 0] = Math.cos(angle) * r;
25
+ position[i * 3 + 1] = (radius - r) / radius * halfHeight + halfHeight;
26
+ position[i * 3 + 2] = Math.sin(angle) * r;
27
+ sprite[i] = ONE_SPRITE_ROW_LENGTH * ((Math.random() * 4) | 0);
28
+ random[i] = Math.random();
29
+ if (i === 0) {
30
+ // to avoid going out of Frustum
31
+ position[i * 3 + 0] = 0;
32
+ position[i * 3 + 1] = 0;
33
+ position[i * 3 + 2] = 0;
34
+ }
35
+ }
36
+ this.setAttribute('position', new BufferAttribute(position, 3));
37
+ this.setAttribute('random', new BufferAttribute(random, 1));
38
+ this.setAttribute('sprite', new BufferAttribute(sprite, 1));
39
+ }
40
+ }
@@ -0,0 +1,54 @@
1
+ /*
2
+ * @Author: xiaosihan
3
+ * @Date: 2024-06-17 02:15:58
4
+ * @Last Modified by: xiaosihan
5
+ * @Last Modified time: 2024-06-18 18:12:37
6
+ */
7
+
8
+ export const SPRITE_ROW_LENGTH = 4; // 粒子图片中图片数量
9
+ export const ONE_SPRITE_ROW_LENGTH = 1 / SPRITE_ROW_LENGTH; // 每一行的宽度
10
+ import { BufferAttribute, BufferGeometry } from "three";
11
+
12
+ // 粒子火焰顶点对象
13
+ export default class FireGromtry extends BufferGeometry {
14
+
15
+ radius = 0.5;
16
+ height = 3;
17
+ particleCount = 200;
18
+
19
+ constructor(radius: number = 0.5, height: number = 3, particleCount: number = 200) {
20
+ super();
21
+
22
+ const halfHeight = height * 0.5;
23
+ const position = new Float32Array(particleCount * 3);
24
+ const random = new Float32Array(particleCount);
25
+ const sprite = new Float32Array(particleCount);
26
+
27
+ for (let i = 0; i < particleCount; i++) {
28
+
29
+ const r = Math.sqrt(Math.random()) * radius;
30
+ const angle = Math.random() * 2 * Math.PI;
31
+ position[i * 3 + 0] = Math.cos(angle) * r;
32
+ position[i * 3 + 1] = (radius - r) / radius * halfHeight + halfHeight;
33
+ position[i * 3 + 2] = Math.sin(angle) * r;
34
+ sprite[i] = ONE_SPRITE_ROW_LENGTH * ((Math.random() * 4) | 0);
35
+ random[i] = Math.random();
36
+
37
+ if (i === 0) {
38
+
39
+ // to avoid going out of Frustum
40
+ position[i * 3 + 0] = 0;
41
+ position[i * 3 + 1] = 0;
42
+ position[i * 3 + 2] = 0;
43
+
44
+ }
45
+
46
+ }
47
+
48
+ this.setAttribute('position', new BufferAttribute(position, 3));
49
+ this.setAttribute('random', new BufferAttribute(random, 1));
50
+ this.setAttribute('sprite', new BufferAttribute(sprite, 1));
51
+ }
52
+
53
+
54
+ }
@@ -0,0 +1,28 @@
1
+ import { ShaderMaterial } from "three";
2
+ export default class FireMaterial extends ShaderMaterial {
3
+ constructor();
4
+ uniforms: {
5
+ color: {
6
+ value: any;
7
+ };
8
+ size: {
9
+ value: number;
10
+ };
11
+ map: {
12
+ value: import("three").Texture;
13
+ };
14
+ time: {
15
+ value: number;
16
+ };
17
+ heightOfNearPlane: {
18
+ value: number;
19
+ };
20
+ };
21
+ vertexShader: string;
22
+ fragmentShader: string;
23
+ blending: 2;
24
+ depthTest: boolean;
25
+ depthWrite: boolean;
26
+ transparent: boolean;
27
+ fog: boolean;
28
+ }
@@ -0,0 +1,83 @@
1
+ /*
2
+ * @Author: xiaosihan
3
+ * @Date: 2024-06-17 02:37:46
4
+ * @Last Modified by: xiaosihan
5
+ * @Last Modified time: 2024-06-18 20:23:31
6
+ */
7
+ import { AdditiveBlending, ShaderChunk, ShaderMaterial } from "three";
8
+ import threeLoader from "../threeLoader";
9
+ import { ONE_SPRITE_ROW_LENGTH } from "./FireGromtry";
10
+ // 火焰粒子材质
11
+ export default class FireMaterial extends ShaderMaterial {
12
+ constructor() {
13
+ super();
14
+ }
15
+ // 材质参数
16
+ uniforms = {
17
+ color: { value: null },
18
+ size: { value: 0.0 },
19
+ map: { value: threeLoader.getTexture("data:image/png;base64,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") },
20
+ time: { value: 0.0 },
21
+ heightOfNearPlane: { value: 0.0 }
22
+ };
23
+ // 顶点着色器
24
+ vertexShader = `
25
+ ${ShaderChunk.common}
26
+ ${ShaderChunk.logdepthbuf_pars_vertex}
27
+ attribute float random;
28
+ attribute float sprite;
29
+ uniform float time;
30
+ uniform float size;
31
+ uniform float heightOfNearPlane;
32
+
33
+ varying float vSprite;
34
+ varying float vOpacity;
35
+
36
+ float quadraticIn( float t ) {
37
+ float tt = t * t;
38
+ return tt * tt;
39
+ }
40
+
41
+ void main() {
42
+ float progress = fract( time + ( 2.0 * random - 1.0 ) );
43
+ float progressNeg = 1.0 - progress;
44
+ float ease = quadraticIn( progress );
45
+ float influence = sin( PI * ease );
46
+
47
+ vec3 newPosition = position * vec3( 1.0, ease, 1.0 );
48
+ gl_Position = projectionMatrix * modelViewMatrix * vec4( newPosition, 1.0 );
49
+ gl_PointSize = ( heightOfNearPlane * size ) / gl_Position.w;
50
+
51
+ vOpacity = min( influence * 4.0, 1.0 ) * progressNeg;
52
+ vSprite = sprite;
53
+ ${ShaderChunk.logdepthbuf_vertex}
54
+ }
55
+ `;
56
+ //片元着色器
57
+ fragmentShader = `
58
+ ${ShaderChunk.logdepthbuf_pars_fragment}
59
+ uniform vec3 color;
60
+ uniform sampler2D map;
61
+
62
+ varying float vSprite;
63
+ varying float vOpacity;
64
+
65
+ void main() {
66
+ vec2 texCoord = vec2(
67
+ gl_PointCoord.x * ${ONE_SPRITE_ROW_LENGTH} + vSprite,
68
+ gl_PointCoord.y
69
+ );
70
+ // gl_FragColor = vec4( texture2D( map, texCoord ).xyz * color * vOpacity, 1.0 );
71
+ vec4 textureColor = texture2D( map, texCoord );
72
+ float colorMax = max(max(textureColor.x, textureColor.y),textureColor.z);
73
+ vec4 newTextureColor = vec4( textureColor.xyz * (100.0) , colorMax);
74
+ gl_FragColor = newTextureColor * vec4(color,1.0) * vOpacity;
75
+ ${ShaderChunk.logdepthbuf_fragment}
76
+ }
77
+ `;
78
+ blending = AdditiveBlending;
79
+ depthTest = true;
80
+ depthWrite = false;
81
+ transparent = true;
82
+ fog = true;
83
+ }
@@ -0,0 +1,95 @@
1
+ /*
2
+ * @Author: xiaosihan
3
+ * @Date: 2024-06-17 02:37:46
4
+ * @Last Modified by: xiaosihan
5
+ * @Last Modified time: 2024-06-18 20:23:31
6
+ */
7
+
8
+ import { AdditiveBlending, LinearSRGBColorSpace, ShaderChunk, ShaderMaterial } from "three";
9
+ import threeLoader from "../threeLoader";
10
+ import { ONE_SPRITE_ROW_LENGTH } from "./FireGromtry";
11
+ import fireMapPNG from "./fireMap.png";
12
+ import fireMap2PNG from "./fireMap2.png";
13
+ import { map } from "lodash";
14
+
15
+ // 火焰粒子材质
16
+ export default class FireMaterial extends ShaderMaterial {
17
+
18
+ constructor() {
19
+ super();
20
+ }
21
+
22
+ // 材质参数
23
+ uniforms = {
24
+ color: { value: null },
25
+ size: { value: 0.0 },
26
+ map: { value: threeLoader.getTexture("data:image/png;base64,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") },
27
+ time: { value: 0.0 },
28
+ heightOfNearPlane: { value: 0.0 }
29
+ };
30
+
31
+ // 顶点着色器
32
+ vertexShader = `
33
+ ${ShaderChunk.common}
34
+ ${ShaderChunk.logdepthbuf_pars_vertex}
35
+ attribute float random;
36
+ attribute float sprite;
37
+ uniform float time;
38
+ uniform float size;
39
+ uniform float heightOfNearPlane;
40
+
41
+ varying float vSprite;
42
+ varying float vOpacity;
43
+
44
+ float quadraticIn( float t ) {
45
+ float tt = t * t;
46
+ return tt * tt;
47
+ }
48
+
49
+ void main() {
50
+ float progress = fract( time + ( 2.0 * random - 1.0 ) );
51
+ float progressNeg = 1.0 - progress;
52
+ float ease = quadraticIn( progress );
53
+ float influence = sin( PI * ease );
54
+
55
+ vec3 newPosition = position * vec3( 1.0, ease, 1.0 );
56
+ gl_Position = projectionMatrix * modelViewMatrix * vec4( newPosition, 1.0 );
57
+ gl_PointSize = ( heightOfNearPlane * size ) / gl_Position.w;
58
+
59
+ vOpacity = min( influence * 4.0, 1.0 ) * progressNeg;
60
+ vSprite = sprite;
61
+ ${ShaderChunk.logdepthbuf_vertex}
62
+ }
63
+ `;
64
+
65
+ //片元着色器
66
+ fragmentShader = `
67
+ ${ShaderChunk.logdepthbuf_pars_fragment}
68
+ uniform vec3 color;
69
+ uniform sampler2D map;
70
+
71
+ varying float vSprite;
72
+ varying float vOpacity;
73
+
74
+ void main() {
75
+ vec2 texCoord = vec2(
76
+ gl_PointCoord.x * ${ONE_SPRITE_ROW_LENGTH} + vSprite,
77
+ gl_PointCoord.y
78
+ );
79
+ // gl_FragColor = vec4( texture2D( map, texCoord ).xyz * color * vOpacity, 1.0 );
80
+ vec4 textureColor = texture2D( map, texCoord );
81
+ float colorMax = max(max(textureColor.x, textureColor.y),textureColor.z);
82
+ vec4 newTextureColor = vec4( textureColor.xyz * (100.0) , colorMax);
83
+ gl_FragColor = newTextureColor * vec4(color,1.0) * vOpacity;
84
+ ${ShaderChunk.logdepthbuf_fragment}
85
+ }
86
+ `
87
+
88
+ blending = AdditiveBlending
89
+ depthTest = true
90
+ depthWrite = false;
91
+ transparent = true
92
+ fog = true
93
+
94
+
95
+ }
package/README.md CHANGED
@@ -1,9 +1,11 @@
1
1
  ```tsx
2
+
2
3
  .创建一个 homeRender.ts 模块
3
4
  import { AmbientLight, BoxGeometry, Mesh, MeshLambertMaterial, PointLight } from "three";
4
5
  import ThreeBase from "three-base";
5
6
  import Transition from "three-base/Transition";
6
7
 
8
+ //qq389652405
7
9
  class HomeRender extends ThreeBase {
8
10
 
9
11
  constructor() {
@@ -35,6 +37,18 @@ class HomeRender extends ThreeBase {
35
37
 
36
38
  }
37
39
 
40
+ //火焰
41
+ fire = (() => {
42
+ const fire = new Fire();
43
+ fire.fireColor = "#ff2200";// 火焰的颜色
44
+ fire.fireScale = 1;// 火焰的整体缩放值
45
+ fire.fireRadius = 0.5;// 火焰的燃烧半径
46
+ fire.fireHeight = 3;// 火焰的高度
47
+ fire.position.set(0, 5, 0);
48
+ this.scene.add(fire);
49
+ return fire;
50
+ })();
51
+
38
52
  box = (() => {
39
53
  const geometry = new BoxGeometry(10, 10, 10);
40
54
  const matearil = new MeshLambertMaterial({ color: 0xfff });
package/ThreeBase.d.ts CHANGED
@@ -51,7 +51,7 @@ export default class ThreeBase extends EventDispatcher {
51
51
  autoRender: boolean;
52
52
  needRender: boolean;
53
53
  stopRender(): void;
54
- hasStrokeOrPass(): boolean;
54
+ hasPass(): boolean;
55
55
  render(): void;
56
56
  private renderBindThis;
57
57
  download(fileName?: string): void;
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: 2024-01-20 05:33:28
5
+ * @Last Modified time: 2024-06-18 21:03:02
6
6
  */
7
7
  import { round } from "lodash";
8
8
  import { AxesHelper, DepthFormat, DepthTexture, EventDispatcher, GridHelper, LinearFilter, MOUSE, Mesh, NoBlending, NormalBlending, OrthographicCamera, PerspectiveCamera, RGBAFormat, Scene, TOUCH, UnsignedShortType, Vector2, Vector3, WebGLRenderTarget, WebGLRenderer } from "three";
@@ -339,8 +339,8 @@ export default class ThreeBase extends EventDispatcher {
339
339
  this.renderer.domElement.style.opacity = "0";
340
340
  }
341
341
  }
342
- // 判断是否有 发光和描边的对象 以便判断是否需要 渲染深度纹理
343
- hasStrokeOrPass() {
342
+ // 判断是否有 发光和描边等对象 以便判断是否需要 渲染深度纹理
343
+ hasPass() {
344
344
  let has_stroke_or_pass = false;
345
345
  this.scene.traverse(obj => {
346
346
  const { stroke_enable = false, stroke_width = 1, glow_enable = false, glow_width = 1 } = obj.userData;
@@ -364,7 +364,7 @@ export default class ThreeBase extends EventDispatcher {
364
364
  const distaned = this.perspectiveCamera.position.clone().sub(center).length();
365
365
  const zoom = 1 / (Math.tan(degToRad(fov) / 2) * distaned);
366
366
  this.orthographicCamera.zoom = zoom;
367
- this.orthographicCamera.position.copy(this.perspectiveCamera.position.clone().sub(center)).setLength(5000).add(center);
367
+ this.orthographicCamera.position.copy(this.perspectiveCamera.position.clone().sub(center)).setLength(2500).add(center);
368
368
  }
369
369
  else if (this.cameraType === "orthographicCamera") {
370
370
  const { center } = this.getLookAt();
@@ -392,8 +392,8 @@ export default class ThreeBase extends EventDispatcher {
392
392
  }
393
393
  // 渲染场景
394
394
  this.dispatchEvent({ type: "beforeRender" });
395
- const has_stroke_or_pass = this.hasStrokeOrPass();
396
- if (has_stroke_or_pass) {
395
+ const hasPass = this.hasPass();
396
+ if (hasPass) {
397
397
  // 把基础场景渲染到 帧缓冲区 在后期通道中会用到
398
398
  this.renderer.setRenderTarget(this.baseRenderTarget);
399
399
  this.renderer.clear();
@@ -403,7 +403,7 @@ export default class ThreeBase extends EventDispatcher {
403
403
  // 清空主画布
404
404
  this.renderer.clear();
405
405
  this.renderer.render(this.scene, camera);
406
- if (has_stroke_or_pass) {
406
+ if (hasPass) {
407
407
  // 查找需要绘制描边的对象,并且绘制描边
408
408
  this.scene.traverseVisible(obj => {
409
409
  stroke_pass(this.renderer, camera, obj, this.baseDepthTexture);
package/ThreeBase.ts 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: 2024-01-20 05:33:28
5
+ * @Last Modified time: 2024-06-18 21:03:02
6
6
  */
7
7
 
8
8
  import { add, round } from "lodash";
@@ -409,8 +409,8 @@ export default class ThreeBase extends EventDispatcher {
409
409
  }
410
410
  }
411
411
 
412
- // 判断是否有 发光和描边的对象 以便判断是否需要 渲染深度纹理
413
- hasStrokeOrPass() {
412
+ // 判断是否有 发光和描边等对象 以便判断是否需要 渲染深度纹理
413
+ hasPass() {
414
414
  let has_stroke_or_pass = false;
415
415
 
416
416
  this.scene.traverse(obj => {
@@ -438,7 +438,7 @@ export default class ThreeBase extends EventDispatcher {
438
438
  const distaned = this.perspectiveCamera.position.clone().sub(center).length();
439
439
  const zoom = 1 / (Math.tan(degToRad(fov) / 2) * distaned);
440
440
  this.orthographicCamera.zoom = zoom;
441
- this.orthographicCamera.position.copy(this.perspectiveCamera.position.clone().sub(center)).setLength(5000).add(center);
441
+ this.orthographicCamera.position.copy(this.perspectiveCamera.position.clone().sub(center)).setLength(2500).add(center);
442
442
  } else if (this.cameraType === "orthographicCamera") {
443
443
  const { center } = this.getLookAt();
444
444
  const { fov } = this.perspectiveCamera;
@@ -472,9 +472,9 @@ export default class ThreeBase extends EventDispatcher {
472
472
  // 渲染场景
473
473
  this.dispatchEvent({ type: "beforeRender" } as never);
474
474
 
475
- const has_stroke_or_pass = this.hasStrokeOrPass();
475
+ const hasPass = this.hasPass();
476
476
 
477
- if (has_stroke_or_pass) {
477
+ if (hasPass) {
478
478
  // 把基础场景渲染到 帧缓冲区 在后期通道中会用到
479
479
  this.renderer.setRenderTarget(this.baseRenderTarget);
480
480
  this.renderer.clear();
@@ -486,7 +486,7 @@ export default class ThreeBase extends EventDispatcher {
486
486
  this.renderer.clear();
487
487
  this.renderer.render(this.scene, camera);
488
488
 
489
- if (has_stroke_or_pass) {
489
+ if (hasPass) {
490
490
  // 查找需要绘制描边的对象,并且绘制描边
491
491
  this.scene.traverseVisible(obj => {
492
492
  stroke_pass(this.renderer, camera, obj, this.baseDepthTexture);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "three-base",
3
- "version": "2.0.49",
3
+ "version": "2.0.51",
4
4
  "description": "three 3d three-base",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"