一、准备工作
创建项目、安装插件就不说了,准备好需要的模型,视频,照片放在主目录的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小岛就完成了