@lijuhong1981/three.instancedsprite 1.0.0 → 1.1.0

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,134 +1,147 @@
1
- import { ShaderMaterial, Texture } from "three";
2
-
3
- const vertexShader = `
4
- // Three.js ShaderMaterial专用,自动注入uv、position、modelViewMatrix、projectionMatrix
5
- precision highp float;
6
- precision highp int;
7
-
8
- #include <common>
9
- #include <logdepthbuf_pars_vertex>
10
-
11
- // 基础属性
12
- attribute vec4 aPositionAndShow; // xyz: InstancedSprite位置(世界空间),w:显示标志(0/1)
13
- attribute vec4 aCenterAndSize; // xy: 锚点中心(0-1), zw: 图片宽高(像素/米)
14
- attribute vec3 aScaleAndRotationAndSizeAttenuation; // x: 缩放, y: 旋转(弧度), z: 大小跟随相机深度(0/1)
15
- attribute vec4 aColorAndOpacity; // RGBA颜色
16
-
17
- varying float vShow;
18
- varying vec2 vUv;
19
- varying vec4 vColorAndOpacity;
20
-
21
- void main() {
22
- // --- 1. 提前解包属性(GPU会自动优化,无性能损失)---
23
- float show = aPositionAndShow.w;
24
- float scale = aScaleAndRotationAndSizeAttenuation.x;
25
- float rotation = aScaleAndRotationAndSizeAttenuation.y;
26
- float sizeAttenuation = aScaleAndRotationAndSizeAttenuation.z;
27
- vec2 center = aCenterAndSize.xy;
28
- vec2 imageSize = aCenterAndSize.zw;
29
-
30
- // --- 2. 输出varying变量 ---
31
- vShow = show;
32
- vUv = uv;
33
- vColorAndOpacity = aColorAndOpacity;
34
-
35
- // --- 3. 提前隐藏不可见物体(顶点级丢弃,性能最优)---
36
- if (show < 0.5 || imageSize.x <= 0.0 || imageSize.y <= 0.0) {
37
- vShow = 0.0;
38
- gl_Position = vec4(0.0, 0.0, 2.0, 1.0);
39
- return;
40
- }
41
-
42
- // --- 4. 计算模型视图位置 ---
43
- vec4 mvPosition = modelViewMatrix * vec4(aPositionAndShow.xyz, 1.0);
44
-
45
- // --- 5. 深度检查:隐藏相机后面的物体,避免尺寸翻转 ---
46
- float depth = -mvPosition.z;
47
- if (depth <= 0.0) {
48
- vShow = 0.0;
49
- gl_Position = vec4(0.0, 0.0, 2.0, 1.0);
50
- return;
51
- }
52
-
53
- // --- 6. sizeAttenuation检查:大小跟随深度
54
- if (sizeAttenuation < 0.5) {
55
- bool isPerspective = isPerspectiveMatrix( projectionMatrix );
56
- if ( isPerspective ) scale *= depth;
57
- }
58
-
59
- // --- 7. 坐标对齐
60
- float aspectRatio = imageSize.x / imageSize.y;
61
- vec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * aspectRatio * scale;
62
-
63
- // --- 8. 计算旋转
64
- vec2 rotatedPosition;
65
- rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;
66
- rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;
67
- mvPosition.xy += rotatedPosition;
68
-
69
- // --- 9. 投影变换 ---
70
- gl_Position = projectionMatrix * mvPosition;
71
-
72
- #include <logdepthbuf_vertex>
73
- }
74
- `;
75
-
76
- const fragmentShader = `
77
- uniform sampler2D uTexture;
78
-
79
- #include <common>
80
- #include <logdepthbuf_pars_fragment>
81
-
82
- varying float vShow;
83
- varying vec2 vUv;
84
- varying vec4 vColorAndOpacity;
85
-
86
- void main() {
87
- vec4 texColor = texture2D(uTexture, vUv);
88
- vec4 diffuseColor = texColor * vColorAndOpacity;
89
-
90
- // 丢弃完全透明的像素
91
- if (diffuseColor.a < 0.005 || vShow < 0.5) {
92
- discard;
93
- }
94
-
95
- gl_FragColor = diffuseColor;
96
-
97
- #include <logdepthbuf_fragment>
98
- #include <tonemapping_fragment>
99
- #include <colorspace_fragment>
100
- }
101
- `;
102
-
103
- /**
104
- * InstancedSprite 材质类,以attribute形式传入InstancedSprite对象实例属性
105
- *
106
- * @extends ShaderMaterial
107
- */
108
- class InstancedSpriteMaterial extends ShaderMaterial {
109
- constructor() {
110
- super({
111
- vertexShader,
112
- fragmentShader,
113
- uniforms: {
114
- uTexture: { value: null },
115
- },
116
- transparent: true,
117
- depthTest: true,
118
- depthWrite: true,
119
- });
120
- }
121
- /**
122
- * 图片纹理
123
- * @type {Texture}
124
- */
125
- set texture(value) {
126
- this.uniforms.uTexture.value = value;
127
- }
128
- get texture() {
129
- return this.uniforms.uTexture.value;
130
- }
131
- };
132
-
133
- export default InstancedSpriteMaterial;
1
+ import { ShaderMaterial, Texture } from "three";
2
+
3
+ const vertexShader = `
4
+ // Three.js ShaderMaterial专用,自动注入uv、position、modelViewMatrix、projectionMatrix
5
+ precision highp float;
6
+ precision highp int;
7
+
8
+ #include <common>
9
+ #include <logdepthbuf_pars_vertex>
10
+
11
+ // 基础属性
12
+ attribute vec4 aPositionAndShow; // xyz: InstancedSprite位置(世界空间),w:显示标志(0/1)
13
+ attribute vec4 aCenterAndSize; // xy: 锚点中心(0-1), zw: 图片宽高(像素/米)
14
+ attribute vec3 aScaleAndRotationAndSizeAttenuation; // x: 缩放, y: 旋转(弧度), z: 大小跟随相机深度(0/1)
15
+ attribute vec4 aColorAndOpacity; // RGBA颜色
16
+ attribute vec4 aPickColorAndEnabled; // xyz:拾取颜色,w:是否启用拾取颜色(0/1)
17
+
18
+ varying float vShow;
19
+ varying vec2 vUv;
20
+ varying vec4 vColorAndOpacity;
21
+ varying vec4 vPickColorAndEnabled;
22
+
23
+ void main() {
24
+ // --- 1. 提前解包属性(GPU会自动优化,无性能损失)---
25
+ float show = aPositionAndShow.w;
26
+ float scale = aScaleAndRotationAndSizeAttenuation.x;
27
+ float rotation = aScaleAndRotationAndSizeAttenuation.y;
28
+ float sizeAttenuation = aScaleAndRotationAndSizeAttenuation.z;
29
+ vec2 center = aCenterAndSize.xy;
30
+ vec2 imageSize = aCenterAndSize.zw;
31
+
32
+ // --- 2. 输出varying变量 ---
33
+ vShow = show;
34
+ vUv = uv;
35
+ vColorAndOpacity = aColorAndOpacity;
36
+ vPickColorAndEnabled = aPickColorAndEnabled;
37
+
38
+ // --- 3. 提前隐藏不可见物体(顶点级丢弃,性能最优)---
39
+ if (show < 0.5 || imageSize.x <= 0.0 || imageSize.y <= 0.0) {
40
+ vShow = 0.0;
41
+ gl_Position = vec4(0.0, 0.0, 2.0, 1.0);
42
+ return;
43
+ }
44
+
45
+ // --- 4. 计算模型视图位置 ---
46
+ vec4 mvPosition = modelViewMatrix * vec4(aPositionAndShow.xyz, 1.0);
47
+
48
+ // --- 5. 深度检查:隐藏相机后面的物体,避免尺寸翻转 ---
49
+ float depth = -mvPosition.z;
50
+ if (depth <= 0.0) {
51
+ vShow = 0.0;
52
+ gl_Position = vec4(0.0, 0.0, 2.0, 1.0);
53
+ return;
54
+ }
55
+
56
+ // --- 6. sizeAttenuation检查:大小跟随深度
57
+ if (sizeAttenuation < 0.5) {
58
+ bool isPerspective = isPerspectiveMatrix( projectionMatrix );
59
+ if ( isPerspective ) scale *= depth;
60
+ }
61
+
62
+ // --- 7. 坐标对齐
63
+ float aspectRatio = imageSize.x / imageSize.y;
64
+ vec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * aspectRatio * scale;
65
+
66
+ // --- 8. 计算旋转
67
+ vec2 rotatedPosition;
68
+ rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;
69
+ rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;
70
+ mvPosition.xy += rotatedPosition;
71
+
72
+ // --- 9. 投影变换 ---
73
+ gl_Position = projectionMatrix * mvPosition;
74
+
75
+ #include <logdepthbuf_vertex>
76
+ }
77
+ `;
78
+
79
+ const fragmentShader = `
80
+ uniform sampler2D uTexture;
81
+
82
+ #include <common>
83
+ #include <logdepthbuf_pars_fragment>
84
+
85
+ varying float vShow;
86
+ varying vec2 vUv;
87
+ varying vec4 vColorAndOpacity;
88
+ varying vec4 vPickColorAndEnabled;
89
+
90
+ void main() {
91
+ if (vShow < 0.5) {
92
+ discard;
93
+ }
94
+
95
+ float enablePickColor = vPickColorAndEnabled.w;
96
+
97
+ if (enablePickColor > 0.5){
98
+ gl_FragColor = vec4(vPickColorAndEnabled.xyz, 1.0);
99
+ } else {
100
+ vec4 texColor = texture2D(uTexture, vUv);
101
+ vec4 diffuseColor = texColor * vColorAndOpacity;
102
+
103
+ // 丢弃完全透明的像素
104
+ if (diffuseColor.a < 0.005) {
105
+ discard;
106
+ }
107
+
108
+ gl_FragColor = diffuseColor;
109
+ #include <logdepthbuf_fragment>
110
+ #include <tonemapping_fragment>
111
+ #include <colorspace_fragment>
112
+ }
113
+ }
114
+ `;
115
+
116
+ /**
117
+ * InstancedSprite 材质类,以attribute形式传入InstancedSprite对象实例属性
118
+ *
119
+ * @extends ShaderMaterial
120
+ */
121
+ class InstancedSpriteMaterial extends ShaderMaterial {
122
+ constructor() {
123
+ super({
124
+ vertexShader,
125
+ fragmentShader,
126
+ uniforms: {
127
+ uTexture: { value: null },
128
+ },
129
+ transparent: true,
130
+ depthTest: true,
131
+ depthWrite: true,
132
+ });
133
+ }
134
+ /**
135
+ * 图片纹理
136
+ * @type {Texture}
137
+ */
138
+ set texture(value) {
139
+ this.uniforms.uTexture.value = value;
140
+ }
141
+ get texture() {
142
+ return this.uniforms.uTexture.value;
143
+ }
144
+ };
145
+
146
+ export default InstancedSpriteMaterial;
134
147
  export { InstancedSpriteMaterial };