diff --git a/src/assets/images/three/hdri.hdr b/src/assets/images/three/hdri.hdr new file mode 100644 index 0000000..4a4a4dd Binary files /dev/null and b/src/assets/images/three/hdri.hdr differ diff --git a/src/assets/images/three/sample.glb b/src/assets/images/three/sample.glb index a8eae0c..f6c551f 100644 Binary files a/src/assets/images/three/sample.glb and b/src/assets/images/three/sample.glb differ diff --git a/src/components/Canvas/FlowCanvas/components/tools/threeModel/index.vue b/src/components/Canvas/FlowCanvas/components/tools/threeModel/index.vue index dee681c..577187c 100644 --- a/src/components/Canvas/FlowCanvas/components/tools/threeModel/index.vue +++ b/src/components/Canvas/FlowCanvas/components/tools/threeModel/index.vue @@ -18,6 +18,7 @@ let data = reactive({ const modelRef = ref(null) onMounted(()=>{ + // modelRef.value.open(threeGlb) if(props?.currentData?.glbPath)modelRef.value.open(props?.currentData?.glbPath) }) onUnmounted(()=>{ diff --git a/src/components/Canvas/FlowCanvas/components/tools/threeModel/model.vue b/src/components/Canvas/FlowCanvas/components/tools/threeModel/model.vue index 568d1dd..a146e10 100644 --- a/src/components/Canvas/FlowCanvas/components/tools/threeModel/model.vue +++ b/src/components/Canvas/FlowCanvas/components/tools/threeModel/model.vue @@ -18,7 +18,6 @@ let group = shallowRef()//组 let camera = shallowRef()//相机 let renderer = shallowRef()//渲染器 let pointLight = shallowRef();//光 -let ambient = shallowRef()//环境光 let controls = shallowRef()//监听鼠标、键盘事件 const animationId = ref(null); @@ -28,17 +27,17 @@ const load = ref({ progress:0 }) // const textureLoader = ref(new THREE.TextureLoader())//材质 -const init = () => { +const init = async () => { //初始化threejs if (scene.value) return - const initResult = initThree(threeDom.value) + const initResult = await initThree(threeDom.value) scene.value = initResult.scene group.value = initResult.group camera.value = initResult.camera renderer.value = initResult.renderer - ambient.value = initResult.ambient - controls.value = initResult.controls pointLight.value = initResult.pointLight + controls.value = initResult.controls + // pointLight.value = initResult.pointLight threeDom.value.ondblclick = (event:any)=>{ let intersects = openModel(event); @@ -133,26 +132,27 @@ const setModel = async (url:any)=>{ await addModel(url,controls,camera,pointLight,group,load) // addMaterial() } -const open = async (url)=>{ +const open = (url)=>{ load.value.state = true - await nextTick(()=>{ - init() + nextTick(async ()=>{ + await init() + controls.value.enableDamping = true; + let animate = ()=>{ + animationId.value = requestAnimationFrame(animate); + // renderer.value.render(scene.value, camera.value); + // model.rotation.x += 0.01; //旋转物体 + var vector = camera.value.position.clone() + controls.value.update(); + renderer.value.render(scene.value, camera.value); + // point.position.set(vector.x,vector.y,vector.z); + // group.rotation.y += 0.01; + // composer.render(); + }; + animate(); + await setModel(url) + load.value.state = false }) - controls.value.enableDamping = true; - let animate = ()=>{ - animationId.value = requestAnimationFrame(animate); - // renderer.value.render(scene.value, camera.value); - // model.rotation.x += 0.01; //旋转物体 - var vector = camera.value.position.clone() - controls.value.update(); - renderer.value.render(scene.value, camera.value); - // point.position.set(vector.x,vector.y,vector.z); - // group.rotation.y += 0.01; - // composer.render(); - }; - animate(); - await setModel(url) - load.value.state = false + } onMounted(()=>{ diff --git a/src/components/Canvas/FlowCanvas/components/tools/threeModel/threeTool.ts b/src/components/Canvas/FlowCanvas/components/tools/threeModel/threeTool.ts index e289a61..bef12eb 100644 --- a/src/components/Canvas/FlowCanvas/components/tools/threeModel/threeTool.ts +++ b/src/components/Canvas/FlowCanvas/components/tools/threeModel/threeTool.ts @@ -2,8 +2,10 @@ import * as THREE from 'three'; import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'; import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js"; import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js' +import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js' +import hdri from '@/assets/images/three/hdri.hdr' -export const initThree = (threeDom)=>{ +export const initThree = async (threeDom)=>{ const scene = new THREE.Scene(); const group = new THREE.Group() scene.add(group) @@ -16,6 +18,8 @@ export const initThree = (threeDom)=>{ /** * 创建渲染器对象 */ + + const width = threeDom.offsetWidth; //窗口宽度 const height = threeDom.offsetHeight; //窗口高度 const renderer = new THREE.WebGLRenderer({ @@ -34,9 +38,8 @@ export const initThree = (threeDom)=>{ threeDom.appendChild(renderer.domElement); // 设置渲染器大小 - //环境光 - const ambient = new THREE.AmbientLight(0xffffff,.8); - scene.add(ambient); + + const controls = new OrbitControls(camera,renderer.domElement)//监听鼠标、键盘事件; // controls.minDistance = 500; // 设置相机与焦点的最小距离 // controls.maxDistance = 4000; // 设置相机与焦点的最大距离 @@ -47,6 +50,23 @@ export const initThree = (threeDom)=>{ RIGHT:THREE.MOUSE.PAN // 右键 旋转(默认拖动:PAN) // RIGHT:THREE.MOUSE.ROTAafTE // 右键 旋转(默认拖动:PAN) } + try { + const rgbeLoader = new RGBELoader() + const hdrTexture = await rgbeLoader.loadAsync(hdri) + hdrTexture.mapping = THREE.EquirectangularMapping + + // 设置环境贴图(影响材质反射) + scene.environment = hdrTexture + // 可选:同时设置为背景 + scene.background = hdrTexture + + console.log('HDR 环境贴图加载成功:', hdri) + } catch (error) { + console.error('HDR 加载失败:', error) + // 降级方案:使用环境光 + const ambientLight = new THREE.AmbientLight(0xffffff, 0.8) + scene.add(ambientLight) + } /** * 光源设置 */ @@ -57,8 +77,16 @@ export const initThree = (threeDom)=>{ DirectionalLight 平行光,比如太阳光 SpotLight 聚光源 */ + + // 2. 定向光(主光源) + const directionalLight = new THREE.DirectionalLight(0xffffff, 1); + // 设置定向光的目标点(指向原点) + directionalLight.target.position.set(0, 0, 0); + scene.add(directionalLight); + //设置环境光全亮 - const pointLight = new THREE.AmbientLight(0xffffff,.2); + //环境光 + const pointLight = new THREE.AmbientLight(0xffffff,.8); scene.add(pointLight); // const pointLight = new THREE.AmbientLight(0xffffff,1.0); // pointLight.intensity = 1.2//光源强度 @@ -80,7 +108,7 @@ export const initThree = (threeDom)=>{ const textureLoader = new THREE.TextureLoader(); // const texture = textureLoader.load('/3dModel/sketch-thick.jpg'); scene.background = new THREE.Color("#fff"); - return {scene,group,camera,renderer,ambient,controls,pointLight} + return {scene,group,camera,renderer,controls,pointLight} } export const clearModel = (group,scene)=>{ const oldGroup:any = group.value; diff --git a/vite.config.ts b/vite.config.ts index 1c71515..87aab9b 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -36,7 +36,7 @@ export default defineConfig(({ mode }) => { inject: 'body-last' // 注入位置优化 }) ], - assetsInclude: ['**/*.glb'], + assetsInclude: ['**/*.glb','**/*.hdr'], define: { __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: false, },