vue3+ts写3D铁塔

目标:

写一个3D铁塔,随意切换角度观察

背景:

vue3+ts,使用贴图的方式

准备工作:

创建一个文件夹,我这里是叫tbTieta,里面创建一个文件夹(mx2)和一个文件(index.vue)

在你的文件夹mx2中复制粘贴进你的scene.bin文件和scene.gltf文件(scene.bin和scene.gilt文件均来自于此文件)

同时在public中也引入

OK,准备工作咱们已经做好了

代码:

在tbtieta中的index.vue 中写代码:

<template>
  <div class="about">
    <div id="container"></div>
  </div>
</template>
<script lang="ts" setup>
import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { ref, shallowRef, onMounted } from 'vue';


let logosrc = ref('')
let objContainer = shallowRef(); // 箱子
let objScence = shallowRef(); // 场景
let objCamera = shallowRef(); // 相机(透视相机)
let objRenderer = shallowRef(); // 渲染器
let objLight = shallowRef(); // 光源
let objPointLight = shallowRef(); // 点光源
let objpxLight = shallowRef(); // 平行光

let objGeometry = shallowRef(); // 物体
let objMaterial = shallowRef(); // 纹理
let objCube = shallowRef(); // 物体对象

let objGeometry2 = shallowRef(); // 物体
let objMaterial2 = shallowRef(); // 纹理
let objCube2 = shallowRef(); // 物体对象

let objZb = shallowRef(); // 坐标轴
let objControl = shallowRef(); // 控制器
const props = defineProps({
  x: {
    type: String,
    default: ''
  },
  y: {
    type: String,
    default: ''
  },
  z: {
    type: String,
    default: ''
  }
});
console.log(props.x, props.y, props.z, 555666);

onMounted(() => {
  objContainer.value = document.getElementById("container");
  funInit();
})

const funInit = () => {
  // nextTick(() => {
  objScence.value = new THREE.Scene(); // 场景

  objCamera.value = new THREE.PerspectiveCamera(75, objContainer.value.clientWidth / objContainer.value.clientHeight, 0.1, 1000); // 相机(透视相机)
  objCamera.value.position.z = 5;
  objCamera.value.position.y = 0.5;

  objRenderer.value = new THREE.WebGLRenderer({ antialias: true }); // 渲染器
  objRenderer.value.setSize(objContainer.value.clientWidth, objContainer.value.clientHeight);
  objRenderer.value.setClearColor("#222222", 0);
  objContainer.value.appendChild(objRenderer.value.domElement);


  objZb.value = new THREE.AxesHelper(160); // 坐标轴
  // objScence.value.add(objZb.value);

  objGeometry.value = new THREE.BoxGeometry(1, 1, 1); // 物体\纹理\物体对象
  objMaterial.value = new THREE.MeshStandardMaterial({
    color: 0xff0051,
    flatShading: true,
    metalness: 0,
    roughness: 1,
  });
  objCube.value = new THREE.Mesh(objGeometry.value, objMaterial.value);

  objLight.value = new THREE.AmbientLight(0xffffff, 0.2); // 环境光源
  objScence.value.add(objLight.value);

  objPointLight.value = new THREE.PointLight(0xffffff, 2); // 点光源
  objPointLight.value.position.set(1, 0, 1);
  objScence.value.add(objPointLight.value);

  objpxLight.value = new THREE.DirectionalLight(0xffffff, 1);
  objpxLight.value.position.set(80, 100, 50);
  objpxLight.value.target = objCube.value;
  objScence.value.add(objpxLight.value);
  objControl.value = new OrbitControls(objCamera.value, objRenderer.value.domElement);
  // 创建GLTF加载器对象
  const gltfloaderA = new GLTFLoader();
  // 创建插入模型
  const modelA = new THREE.Group();
  //加载模型文件,返回gltf对象
  gltfloaderA.load(
    './mx2/scene.gltf',
    // 添加模型
    function (gltf: any) {
      gltf.scene.scale.set(0.05, 0.05, 0.05);
      modelA.add(gltf.scene);
      objScence.value.add(modelA);
   
      // 设置中心点的颜色
      const centerPointGeometry = new THREE.SphereGeometry(0.05); // 创建一个小球体代表中心点
      const centerPointMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 }); // 设置中心点颜色
      const centerPoint = new THREE.Mesh(centerPointGeometry, centerPointMaterial);
      // 将中心点放置在铁塔模型的中心
      centerPoint.position.copy(modelA.position);
      // 添加中心点到场景
      objScence.value.add(centerPoint);

    },


    // // 加载模型进度
    // function (xhr) {
    //   console.log(`已加载:${(xhr.loaded / xhr.total) * 100}%`);


    // },
    // // 回调函数
    // function (error) {
    //   console.log(error, "错误显示");
    // }
  )

  // 底座部分

  // 创建底座
  const baseGeometry = new THREE.CircleGeometry(1, 50);
  const baseMaterial = new THREE.MeshBasicMaterial({
    color: 0x654321,
    side: THREE.DoubleSide
  });
  const baseMesh = new THREE.Mesh(baseGeometry, baseMaterial);
  baseMesh.rotation.x = -Math.PI / 2.0;
  baseMesh.position.set(0, 0, 0);
  objScence.value.add(baseMesh);
  // resize 事件
  // window.addEventListener("resize", () => {
  //     let width = window.innerWidth;
  //     let height = window.innerHeight;
  //     renderer.setSize(width, height);
  //     camera.aspect = width / height;
  //     camera.updateProjectionMatrix();
  // });

  funAnimate();
  // })
}
const funAnimate = () => {
  requestAnimationFrame(funAnimate);
  objCube.value.rotation.x = objCube.value.rotation.x + 0.04;
  objCube.value.rotation.y = objCube.value.rotation.y + 0.04;
  // objCube2.value.rotation.x = objCube2.value.rotation.x  - 0.01;
  // objCube2.value.rotation.y = objCube2.value.rotation.y  - 0.01;
  objRenderer.value.render(objScence.value, objCamera.value);
  // objControl.value.update();
}
</script>
<style lang="less" scoped>
.about {
  display: flex;
  align-items: center;
  justify-content: center;

  #container {
    width: 100%;
    height: 700px;
    overflow: hidden;
  }
}
</style>

这个运行出来是这样的:

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值