vue3使用three.js创建水天一色的小岛(全部代码)超详细

一、准备工作

创建项目、安装插件就不说了,准备好需要的模型,视频,照片放在主目录的public下,放在别的地方引不进来会报错

二、新建基础模块,代码在下方,引入需要用到的插件,gsap是一个新插件需要安装,其余的都是自带的

<template>

    <div>

      <div class="box" ref="screenDom"></div>

    </div>

  </template>

  <script setup>

  import * as THREE from "three";

  import { ref, onMounted } from "vue";

  import { gsap } from "gsap";

import { Water } from "three/examples/jsm/objects/Water";

  import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";

import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";

import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader";

  let screenDom = ref(null);

  onMounted(() => {

  });

  </script>

  <style scoped>

  .box {

    width: 100vw;

    height: 100vh;

    background-color: #000000;

  }

  </style>

三、所有的代码都在onMounted里,创建场景,创建相机,初始化渲染器

 // 创建一个场景

   const scene = new THREE.Scene();

    // 创建相机

    const camera = new THREE.PerspectiveCamera(

      75,

       screenDom.value.clientWidth /  screenDom.value.clientHeight,

      0.1,

      2000

    );

    camera.position.set(-50, 50, 130);

    // 初始化渲染器

    const renderer = new THREE.WebGLRenderer({

      // 设置抗锯齿

      antialias: true,

    });

    // 设置初始化渲染器的大小

    renderer.setSize( screenDom.value.clientWidth,  screenDom.value.clientHeight);

    // 监听画面变化,更新渲染画面

    window.addEventListener("resize", () => {

      // 更新摄像头

      camera.aspect =  screenDom.value.clientWidth /  screenDom.value.clientHeight;

      // 更新摄像机

      camera.updateProjectionMatrix();

      // 更新渲染器

      renderer.setSize( screenDom.value.clientWidth,  screenDom.value.clientHeight);

      // 设置 渲染器的像素比例

      renderer.setPixelRatio(window.devicePixelRatio);

    });

    scene.add(camera);

    // 将渲染的内容添加到body上

     screenDom.value.appendChild(renderer.domElement);

    // 浏览器自带的帧数方法保证每一帧都重新渲染页面

    function render() {

      // 不断地渲染

      renderer.render(scene, camera);

      // 下一帧的时候就调用函数

      requestAnimationFrame(render);

    }

    // 初始化渲染一次

    render();

 四、 创建一巨大的球

   

 // 创建一巨大的球

  const texture =  new THREE.TextureLoader().load("/ShuitianLsland/image/sky.jpg")

  const skytry = new THREE.SphereGeometry(1000, 60, 60);

  const skyial = new THREE.MeshBasicMaterial({

    map: texture

  });

  // z轴-1就可以吧场景设置为里面亮外面嘿

  skytry.scale(1, 1, -1);

  const sky = new THREE.Mesh(skytry, skyial);

  scene.add(sky); //添加完以后里面是黑色的外面是亮的需要吧他翻转过来

 scene.background = texture

  scene.environment = texture

  // 创建视频的纹理

  const video = document.createElement("video");

  video.src = "/ShuitianLsland/video/天空 (5).mp4";

  video.loop = true;

  window.addEventListener("mousemove", (e) => {

  // 当鼠标移动的时候播放视频

  //   判断视频是否处于播放状态

  if (video.paused) {

    video.play();

    let texture = new THREE.VideoTexture(video);

    skyial.map = texture;

    skyial.map.needsUpdate = true;

  }

});

五、实例化控制盘

     // 实例化控制器,控制元素的移动

    const controls = new OrbitControls(camera, renderer.domElement)

 六、创建水面,让他显示出波纹状态

    // 创建水面

    const watertry = new THREE.CircleGeometry(30, 64);

    const water = new Water(watertry, {

      textureWidth: 1024,

      textureHeight: 1024,

      color: 0xfffff,

      flowDirection: new THREE.Vector2(1, 1),

      scale: 1,

    });

    water.rotation.x = -Math.PI / 2;

    scene.add(water);

 七、添加模型

 // 添加小岛模型

// 实例化gltf载入库

const loader = new GLTFLoader();

// 实例化draco载入库

const dracoLoader = new DRACOLoader();

// 添加draco载入库

dracoLoader.setDecoderPath("/ShuitianLsland/draco/");

// 添加draco载入库

loader.setDRACOLoader(dracoLoader);

loader.load("/ShuitianLsland/model/island2.glb", (gltf) => {

  scene.add(gltf.scene);

});

八、添加环境纹理

 // 载入环境纹理

  const hdrLoader = new RGBELoader();

  hdrLoader.loadAsync("/ShuitianLsland/hdr/050.hdr").then((texture) => {

    texture.mapping = THREE.EquirectangularReflectionMapping;

    scene.background = texture;

    scene.environment = texture;

  });

 九、添加光源

  // 添加平行光

  const light = new THREE.DirectionalLight(0xffffff, 1);

  light.position.set(-100, 100, 10);

  scene.add(light);

这样一个可视化的3d小岛就完成了

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值