three.js入门篇9 之 水天一色的小岛
code App.vue
<template>
<div class="container" ref="container"></div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import * as THREE from "three"
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"
import { Water } from "three/examples/jsm/objects/Water2";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader";
const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(75,window.innerWidth / window.innerHeight,0.1,2000)
camera.position.set(-50,50,130)
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
scene.add( camera );
const renderer = new THREE.WebGL1Renderer({
antialias:true,
logarithmicDepthBuffer: true,
})
renderer.outputEncoding = THREE.sRGBEncoding;
renderer.setSize(window.innerWidth,window.innerHeight)
const controls = new OrbitControls(camera,renderer.domElement)
window.addEventListener('resize',()=>{
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
renderer.setSize(window.innerWidth, window.innerHeight)
})
document.body.appendChild(renderer.domElement)
function animate() {
requestAnimationFrame( animate );
controls.update();
renderer.render( scene, camera );
}
animate()
const skyGeometry = new THREE.SphereGeometry(1000,60,60)
const skyMaterials = new THREE.MeshBasicMaterial({
map: new THREE.TextureLoader().load("./img/water/sky.jpg"),
})
skyGeometry.scale(1,1,-1)
const sky = new THREE.Mesh(skyGeometry,skyMaterials)
scene.add(sky)
const video = document.createElement("video")
video.src = './img/water/sky.mp4'
video.loop = true
window.addEventListener("click",()=>{
if ( video.paused ) {
video.play()
skyMaterials.map = new THREE.VideoTexture(video)
skyMaterials.map.needsUpdate = true
}
})
const waterGeometry = new THREE.CircleBufferGeometry(300,64)
const water = new Water(waterGeometry,{
textureWidth:1024,
textureHeight:1024,
color:0xeeeeff,
flowDirection:new THREE.Vector2(1,1),
scale:1,
})
water.position.y = 3;
water.rotation.x = -Math.PI / 2;
scene.add(water)
const hdrLoader = new RGBELoader();
hdrLoader.loadAsync("./assets/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);
const loader = new GLTFLoader();
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath("./draco/");
loader.setDRACOLoader(dracoLoader);
loader.load("./model/island2.glb", (gltf) => {
scene.add(gltf.scene)
});
function render() {
requestAnimationFrame( render );
renderer.render( scene, camera );
}
const container = ref(null)
onMounted(()=>{
container.value.appendChild(renderer.domElement)
render()
})
</script>
<style lang="scss" scoped>
* {
padding:0;
margin: 0;
}
.container {
height:100;
width:100%;
background:'#f0f0f0'
}
</style>
效果
