fl-web-component 2.0.2 → 2.0.3
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/README.md +4 -0
- package/dist/fl-web-component.common.js +333 -309
- package/dist/fl-web-component.common.js.map +1 -1
- package/package.json +1 -1
- package/src/utils/instance-parser.js +45 -7
package/package.json
CHANGED
|
@@ -91,6 +91,11 @@ function requestInstancedMapping(instances, drawObjs) {
|
|
|
91
91
|
});
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
function getInstanceNormalSign(matrix) {
|
|
95
|
+
if (!matrix || typeof matrix.determinant !== 'function') return 1;
|
|
96
|
+
return matrix.determinant() < 0 ? -1 : 1;
|
|
97
|
+
}
|
|
98
|
+
|
|
94
99
|
/**
|
|
95
100
|
* 重置处理状态,用于新的批量加载会话
|
|
96
101
|
*/
|
|
@@ -448,6 +453,11 @@ function setInstanceMatricesAndColors(model, drawObj, mesh, meshName, customColo
|
|
|
448
453
|
m4.multiplyMatrices(meshMatrix, geomMatrix);
|
|
449
454
|
model.setMatrixAt(index, m4);
|
|
450
455
|
|
|
456
|
+
const normalSignAttr = model.geometry && model.geometry.getAttribute('instanceNormalSign');
|
|
457
|
+
if (normalSignAttr && normalSignAttr.array && index < normalSignAttr.array.length) {
|
|
458
|
+
normalSignAttr.array[index] = getInstanceNormalSign(m4);
|
|
459
|
+
}
|
|
460
|
+
|
|
451
461
|
const copyMatrix = new THREE.Matrix4().copy(m4);
|
|
452
462
|
model.userData.copyMatrix = copyMatrix;
|
|
453
463
|
|
|
@@ -466,6 +476,10 @@ function setInstanceMatricesAndColors(model, drawObj, mesh, meshName, customColo
|
|
|
466
476
|
if (model.instanceColor) {
|
|
467
477
|
model.instanceColor.needsUpdate = true;
|
|
468
478
|
}
|
|
479
|
+
const normalSignAttr = model.geometry && model.geometry.getAttribute('instanceNormalSign');
|
|
480
|
+
if (normalSignAttr) {
|
|
481
|
+
normalSignAttr.needsUpdate = true;
|
|
482
|
+
}
|
|
469
483
|
|
|
470
484
|
if (Array.isArray(instances)) {
|
|
471
485
|
const capacity =
|
|
@@ -546,6 +560,12 @@ function appendInstanceToInstancedMesh(model, drawObj, mesh, instance, customCol
|
|
|
546
560
|
model.setMatrixAt(currentCount, m4);
|
|
547
561
|
if (model.instanceMatrix) model.instanceMatrix.needsUpdate = true;
|
|
548
562
|
|
|
563
|
+
const normalSignAttr = model.geometry && model.geometry.getAttribute('instanceNormalSign');
|
|
564
|
+
if (normalSignAttr && normalSignAttr.array && currentCount < normalSignAttr.array.length) {
|
|
565
|
+
normalSignAttr.array[currentCount] = getInstanceNormalSign(m4);
|
|
566
|
+
normalSignAttr.needsUpdate = true;
|
|
567
|
+
}
|
|
568
|
+
|
|
549
569
|
const copyMatrix = new THREE.Matrix4().copy(m4);
|
|
550
570
|
model.userData.copyMatrix = copyMatrix;
|
|
551
571
|
const instanceProps = {
|
|
@@ -948,35 +968,53 @@ function draw3Dmodel(
|
|
|
948
968
|
);
|
|
949
969
|
|
|
950
970
|
const opacities = new Float32Array(instanceCount);
|
|
971
|
+
const instanceNormalSigns = new Float32Array(instanceCount);
|
|
951
972
|
for (let i = 0; i < instanceCount; i++) {
|
|
952
973
|
opacities[i] = opacity;
|
|
974
|
+
instanceNormalSigns[i] = 1;
|
|
953
975
|
}
|
|
954
976
|
geometry.setAttribute('opacity', new THREE.InstancedBufferAttribute(opacities, 1));
|
|
977
|
+
geometry.setAttribute(
|
|
978
|
+
'instanceNormalSign',
|
|
979
|
+
new THREE.InstancedBufferAttribute(instanceNormalSigns, 1)
|
|
980
|
+
);
|
|
955
981
|
|
|
956
982
|
if (!customMaterial) {
|
|
957
983
|
material.onBeforeCompile = shader => {
|
|
984
|
+
const normalFragmentBegin = THREE.ShaderChunk.normal_fragment_begin.replace(
|
|
985
|
+
'float faceDirection = gl_FrontFacing ? 1.0 : - 1.0;',
|
|
986
|
+
'float faceDirection = (gl_FrontFacing ? 1.0 : - 1.0) * vInstanceNormalSign;'
|
|
987
|
+
);
|
|
988
|
+
|
|
958
989
|
shader.vertexShader = `
|
|
959
|
-
|
|
960
|
-
|
|
990
|
+
attribute float opacity; // 实例透明度属性
|
|
991
|
+
attribute float instanceNormalSign; // 镜像矩阵法线修正
|
|
992
|
+
varying float vAlpha;
|
|
993
|
+
varying float vInstanceNormalSign;
|
|
961
994
|
${shader.vertexShader}
|
|
962
995
|
`.replace(
|
|
963
996
|
'#include <begin_vertex>',
|
|
964
997
|
`
|
|
965
998
|
#include <begin_vertex>
|
|
966
999
|
vAlpha = opacity; // 传递透明度到片段着色器
|
|
1000
|
+
vInstanceNormalSign = instanceNormalSign;
|
|
967
1001
|
`
|
|
968
1002
|
);
|
|
969
1003
|
shader.fragmentShader = `
|
|
970
|
-
|
|
1004
|
+
varying float vAlpha;
|
|
1005
|
+
varying float vInstanceNormalSign;
|
|
971
1006
|
${shader.fragmentShader}
|
|
972
|
-
|
|
973
|
-
'#include <
|
|
974
|
-
|
|
1007
|
+
`
|
|
1008
|
+
.replace('#include <normal_fragment_begin>', normalFragmentBegin)
|
|
1009
|
+
.replace(
|
|
1010
|
+
'#include <alphatest_fragment>',
|
|
1011
|
+
`
|
|
975
1012
|
#include <alphatest_fragment>
|
|
976
1013
|
diffuseColor.a *= vAlpha; // 应用实例透明度
|
|
977
1014
|
`
|
|
978
|
-
|
|
1015
|
+
);
|
|
979
1016
|
};
|
|
1017
|
+
material.customProgramCacheKey = () => 'instance-opacity-normal-sign-v2';
|
|
980
1018
|
}
|
|
981
1019
|
|
|
982
1020
|
// 针对 MeshLineMaterial 开启实例化支持
|