素材:
链接: https://pan.baidu.com/s/1HbT0SlFHwfQbrKH9tXlM5w
提取码: e98i
新引入:
import {
RGBELoader
} from "three/examples/jsm/loaders/RGBELoader"
import {
Water
} from "three/examples/jsm/objects/Water2";
import {
GLTFLoader
} from "three/examples/jsm/loaders/GLTFLoader"
import {
DRACOLoader
} from "three/examples/jsm/loaders/DRACOLoader"
关键代码:
片段1
const regbeLoader = new RGBELoader();
regbeLoader.loadAsync('three/050.hdr').then(loader => {
loader.mapping = THREE.EquirectangularReflectionMapping;
scene.background = loader;
scene.environment = loader;
})
片段2
let cloudLoader = new THREE.TextureLoader();
cloudLoader = cloudLoader.load('three/textures/sky.jpg');
const cloudMaterial = new THREE.MeshBasicMaterial({
map: cloudLoader
});
const mesh = new THREE.Mesh(boxBufferGeometry, cloudMaterial);
mesh.geometry.scale(1, -1, 1);
//将物体加入到场景
scene.add(mesh);
片段3
//创建水面
//创建圆
const circleGeometry = new THREE.CircleBufferGeometry(400, 100);
// circleGeometry.rotation.x =-Math.PI/2;
const textureLoader = new THREE.TextureLoader();
const waterMesh = new Water(circleGeometry, {
textureWidth: 1024,
textureHeight: 1024,
color: 0xeeeeff,
flowDirection: new THREE.Vector2(1, 1),
scale: 1,
flowMap:textureLoader.load("three/textures/water/Water_1_M_Flow.jpg"),
normalMap1: textureLoader.load("three/textures/water/Water_1_M_Normal.jpg"),
normalMap2: textureLoader.load("three/textures/water/Water_2_M_Normal.jpg"),
});
waterMesh.rotation.x = -Math.PI / 2;
scene.add(waterMesh);
片段4
//加载模型
const loader = new GLTFLoader().setPath('three/glb/');
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath('three/draco/')
// dracoLoader.setDecoderConfig({
// type: 'js'
// })
dracoLoader.preload();
loader.setDRACOLoader(dracoLoader);
loader.load('island.glb', gltf => {
scene.add(gltf.scene);
})
const videoELem = document.createElement("video");
videoELem.src = "three/textures/sky.mp4";
videoELem.loop = true;
//创建视频纹理
window.addEventListener("click", () => {
if(videoELem.paused){
videoELem.play();
cloudMaterial.map = new THREE.VideoTexture(videoELem);
cloudMaterial.map.needsUpdate = true;
//scene.background = textureLoader
}
})
片段5
/*设置场景渲染编码threejs将贴图的编码都默认设置为THREE.LinearEncoding,
*导致图片色彩失真(色彩不像正常那么鲜艳,会灰蒙蒙的),所以务必将场景中的所有贴图的编码都调整为THREE.sRGBEncoding
*/
render.outputEncoding =THREE.sRGBEncoding;
完整代码:
<template>
<div id="three_div"></div>
</template><script>
import * as THREE from "three";
import {
OrbitControls
} from "three/examples/jsm/controls/OrbitControls";
import {
RGBELoader
} from "three/examples/jsm/loaders/RGBELoader"
import {
Water
} from "three/examples/jsm/objects/Water2";
import {
GLTFLoader
} from "three/examples/jsm/loaders/GLTFLoader"
import {
DRACOLoader
} from "three/examples/jsm/loaders/DRACOLoader"
export default {
name: "HOME",
components: {
// vueQr,
// glHome,
},
data() {
return {};
},
mounted() {
//使用控制器控制3D拖动旋转OrbitControls
//控制3D物体移动//1.创建场景
const scene = new THREE.Scene();
console.log(scene);//2.创建相机
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
20000
);
//设置相机位置
camera.position.set(0, 0, 10);
//将相机添加到场景
scene.add(camera);
//添加物体
//创建一个半径为1,经纬度分段数位20的球
const boxBufferGeometry = new THREE.SphereBufferGeometry(500, 50, 50);
//纹理加载器
const regbeLoader = new RGBELoader();
regbeLoader.loadAsync('three/050.hdr').then(loader => {
loader.mapping = THREE.EquirectangularReflectionMapping;
scene.background = loader;
scene.environment = loader;
})
let cloudLoader = new THREE.TextureLoader();
cloudLoader = cloudLoader.load('three/textures/sky.jpg');
const cloudMaterial = new THREE.MeshBasicMaterial({
map: cloudLoader
});
const mesh = new THREE.Mesh(boxBufferGeometry, cloudMaterial);
mesh.geometry.scale(1, -1, 1);
//将物体加入到场景
scene.add(mesh);
//创建水面
//创建圆
const circleGeometry = new THREE.CircleBufferGeometry(400, 100);
// circleGeometry.rotation.x =-Math.PI/2;
const textureLoader = new THREE.TextureLoader();
const waterMesh = new Water(circleGeometry, {
textureWidth: 1024,
textureHeight: 1024,
color: 0xeeeeff,
flowDirection: new THREE.Vector2(1, 1),
scale: 1,
flowMap:textureLoader.load("three/textures/water/Water_1_M_Flow.jpg"),
normalMap1: textureLoader.load("three/textures/water/Water_1_M_Normal.jpg"),
normalMap2: textureLoader.load("three/textures/water/Water_2_M_Normal.jpg"),
});
waterMesh.rotation.x = -Math.PI / 2;
scene.add(waterMesh);
//给场景所有的物体添加默认的环境贴图
//添加坐标轴辅助器
// const axesHepler = new THREE.AxesHelper(5);
// scene.add(axesHepler);
//添加周围环境灯光(由物体发出的灯光)参数(灯色,强度0-1)
const light = new THREE.AmbientLight(0xFFFFFF, 1);
scene.add(light);
//加载模型
const loader = new GLTFLoader().setPath('three/glb/');
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath('three/draco/')
// dracoLoader.setDecoderConfig({
// type: 'js'
// })
dracoLoader.preload();
loader.setDRACOLoader(dracoLoader);
loader.load('island.glb', gltf => {
scene.add(gltf.scene);
})
const videoELem = document.createElement("video");
videoELem.src = "three/textures/sky.mp4";
videoELem.loop = true;
//创建视频纹理
window.addEventListener("click", () => {
if(videoELem.paused){
videoELem.play();
cloudMaterial.map = new THREE.VideoTexture(videoELem);
cloudMaterial.map.needsUpdate = true;
//scene.background = textureLoader
}
})
//初始化渲染器
const render = new THREE.WebGLRenderer();
/*设置场景渲染编码threejs将贴图的编码都默认设置为THREE.LinearEncoding,
*导致图片色彩失真(色彩不像正常那么鲜艳,会灰蒙蒙的),所以务必将场景中的所有贴图的编码都调整为THREE.sRGBEncoding
*/
render.outputEncoding = THREE.sRGBEncoding;
//设置渲染器的尺寸
render.setSize(window.innerWidth, window.innerHeight);
//使用渲染器,通过相机将场景渲染进来//创建轨道控制器,可以拖动,控制的是摄像头
const controls = new OrbitControls(camera, render.domElement);
//设置控制阻尼,让控制器有更真实的效果
controls.enableDamping = true;//将webgl渲染的canvas内容添加到body上
document.getElementById("three_div").appendChild(render.domElement);//渲染下一帧的时候就会调用回调函数
let renderFun = () => {
//更新阻尼数据
controls.update();
//需要重新绘制canvas画布
render.render(scene, camera);
//监听屏幕刷新(60HZ,120HZ),每次刷新触发一次requestAnimationFrame回调函数
//但是requestAnimationFrame的回调函数注册生命只有一次,因此需要循环注册,才能达到一直调用的效果
window.requestAnimationFrame(renderFun);
};
// window.requestAnimationFrame(renderFun);
renderFun();//画布全屏
window.addEventListener("dblclick", () => {
if (document.fullscreenElement) {
document.exitFullscreen();
} else {
//document.documentElement.requestFullscreen();
render.domElement.requestFullscreen();
}
});//监听画面变化,更新渲染画面,(自适应的大小)
window.addEventListener("resize", () => {
//更新摄像机的宽高比
camera.aspect = window.innerWidth / window.innerHeight;
//更新摄像机的投影矩阵
camera.updateProjectionMatrix();
//更新渲染器宽度和高度
render.setSize(window.innerWidth, window.innerHeight);
//设置渲染器的像素比
render.setPixelRatio(window.devicePixelRatio);
console.log("画面变化了");
});
},
methods: {
paush(animate) {
animate.pause();
},
},
};
</script><style scoped lang="scss">
</style>
效果图: