|
@@ -17,6 +17,19 @@
|
|
|
<div v-if="showLightControl" class="light-control-panel">
|
|
<div v-if="showLightControl" class="light-control-panel">
|
|
|
<h4>光照控制</h4>
|
|
<h4>光照控制</h4>
|
|
|
|
|
|
|
|
|
|
+ <!-- 材质透明度调整 -->
|
|
|
|
|
+ <div class="control-item">
|
|
|
|
|
+ <label>材质不透明度</label>
|
|
|
|
|
+ <el-slider
|
|
|
|
|
+ v-model="materialOpacity"
|
|
|
|
|
+ :min="0.1"
|
|
|
|
|
+ :max="1"
|
|
|
|
|
+ :step="0.05"
|
|
|
|
|
+ @change="updateMaterialOpacity"
|
|
|
|
|
+ />
|
|
|
|
|
+ <span class="value">{{ materialOpacity.toFixed(2) }}</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
<!-- 环境光强度 -->
|
|
<!-- 环境光强度 -->
|
|
|
<div class="control-item">
|
|
<div class="control-item">
|
|
|
<label>环境光强度</label>
|
|
<label>环境光强度</label>
|
|
@@ -165,6 +178,8 @@ const lightSettings = ref({
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
|
|
+const materialOpacity = ref(1.0)
|
|
|
|
|
+
|
|
|
// 获取类型显示名称
|
|
// 获取类型显示名称
|
|
|
const getTypeDisplayName = (type) => {
|
|
const getTypeDisplayName = (type) => {
|
|
|
const typeMapping = {
|
|
const typeMapping = {
|
|
@@ -693,6 +708,8 @@ const loadGLTFModel = (url) => {
|
|
|
// 调整相机位置,使模型在视角中心且完整可见
|
|
// 调整相机位置,使模型在视角中心且完整可见
|
|
|
adjustCameraForModel()
|
|
adjustCameraForModel()
|
|
|
console.log('相机位置调整完成')
|
|
console.log('相机位置调整完成')
|
|
|
|
|
+ // 修复半透明材质太透的问题
|
|
|
|
|
+ fixTransparentMaterials(model)
|
|
|
// 释放Blob URL
|
|
// 释放Blob URL
|
|
|
URL.revokeObjectURL(blobUrl)
|
|
URL.revokeObjectURL(blobUrl)
|
|
|
},
|
|
},
|
|
@@ -764,6 +781,8 @@ const loadOBJModel = (url) => {
|
|
|
// 调整相机位置,使模型在视角中心且完整可见
|
|
// 调整相机位置,使模型在视角中心且完整可见
|
|
|
adjustCameraForModel()
|
|
adjustCameraForModel()
|
|
|
console.log('相机位置调整完成')
|
|
console.log('相机位置调整完成')
|
|
|
|
|
+ // 修复半透明材质太透的问题
|
|
|
|
|
+ fixTransparentMaterials(model)
|
|
|
// 释放Blob URL
|
|
// 释放Blob URL
|
|
|
URL.revokeObjectURL(blobUrl)
|
|
URL.revokeObjectURL(blobUrl)
|
|
|
},
|
|
},
|
|
@@ -948,6 +967,8 @@ const loadFBXModel = (url) => {
|
|
|
console.log('调整相机位置...')
|
|
console.log('调整相机位置...')
|
|
|
adjustCameraForModel()
|
|
adjustCameraForModel()
|
|
|
console.log('相机位置调整完成')
|
|
console.log('相机位置调整完成')
|
|
|
|
|
+ // 修复半透明材质太透的问题
|
|
|
|
|
+ fixTransparentMaterials(model)
|
|
|
|
|
|
|
|
// 释放Blob URL
|
|
// 释放Blob URL
|
|
|
URL.revokeObjectURL(blobUrl)
|
|
URL.revokeObjectURL(blobUrl)
|
|
@@ -1016,6 +1037,8 @@ const loadSTLModel = (url) => {
|
|
|
// 调整相机位置,使模型在视角中心且完整可见
|
|
// 调整相机位置,使模型在视角中心且完整可见
|
|
|
adjustCameraForModel()
|
|
adjustCameraForModel()
|
|
|
console.log('相机位置调整完成')
|
|
console.log('相机位置调整完成')
|
|
|
|
|
+ // 修复半透明材质太透的问题
|
|
|
|
|
+ fixTransparentMaterials(model)
|
|
|
// 释放Blob URL
|
|
// 释放Blob URL
|
|
|
URL.revokeObjectURL(blobUrl)
|
|
URL.revokeObjectURL(blobUrl)
|
|
|
},
|
|
},
|
|
@@ -1387,6 +1410,67 @@ const updateLights = () => {
|
|
|
camera.updateProjectionMatrix()
|
|
camera.updateProjectionMatrix()
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+// 修复半透明材质太透的问题
|
|
|
|
|
+const fixTransparentMaterials = (modelObject) => {
|
|
|
|
|
+ if (!modelObject) return
|
|
|
|
|
+
|
|
|
|
|
+ let fixedCount = 0
|
|
|
|
|
+
|
|
|
|
|
+ modelObject.traverse((child) => {
|
|
|
|
|
+ if (child.isMesh && child.material) {
|
|
|
|
|
+ const materials = Array.isArray(child.material) ? child.material : [child.material]
|
|
|
|
|
+
|
|
|
|
|
+ materials.forEach((material) => {
|
|
|
|
|
+ // 检查是否使用了透明度贴图
|
|
|
|
|
+ const hasAlphaMap = material.alphaMap && material.alphaMap !== null
|
|
|
|
|
+ const isTransparent = material.transparent === true
|
|
|
|
|
+ const opacity = material.opacity
|
|
|
|
|
+
|
|
|
|
|
+ // 如果有透明度贴图或设置了transparent
|
|
|
|
|
+ if (hasAlphaMap || isTransparent) {
|
|
|
|
|
+ // 确保透明模式开启
|
|
|
|
|
+ material.transparent = true
|
|
|
|
|
+
|
|
|
|
|
+ // 启用双面渲染,确保半透明效果正确显示
|
|
|
|
|
+ material.side = THREE.DoubleSide
|
|
|
|
|
+
|
|
|
|
|
+ // 如果opacity太低或等于1(全透/全不透),设置为一个合适的值
|
|
|
|
|
+ if (opacity === undefined || opacity >= 1 || opacity < 0.1) {
|
|
|
|
|
+ material.opacity = 0.8
|
|
|
|
|
+ fixedCount++
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 修复depthWrite问题 - 对于半透明材质,depthWrite通常应为false
|
|
|
|
|
+ material.depthWrite = false
|
|
|
|
|
+ material.needsUpdate = true
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ console.log('修复了', fixedCount, '个半透明材质的透明度')
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 更新模型材质的不透明度
|
|
|
|
|
+const updateMaterialOpacity = () => {
|
|
|
|
|
+ if (!model) return
|
|
|
|
|
+
|
|
|
|
|
+ const opacity = materialOpacity.value
|
|
|
|
|
+
|
|
|
|
|
+ model.traverse((child) => {
|
|
|
|
|
+ if (child.isMesh && child.material) {
|
|
|
|
|
+ const materials = Array.isArray(child.material) ? child.material : [child.material]
|
|
|
|
|
+
|
|
|
|
|
+ materials.forEach((material) => {
|
|
|
|
|
+ if (material.transparent === true || material.opacity < 1) {
|
|
|
|
|
+ material.opacity = opacity
|
|
|
|
|
+ material.needsUpdate = true
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+}
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped>
|
|
<style scoped>
|