首页IT科技three.js 地图底图(Three.js–》实现3d小岛模型搭建)

three.js 地图底图(Three.js–》实现3d小岛模型搭建)

时间2025-04-28 14:16:50分类IT科技浏览4028
导读:目录...

目录

项目搭建

初始化three.js基础代码

设置环境背景

设置水面样式

添加天空小岛

今天简单实现一个three.js的小Demo            ,加强自己对three知识的掌握与学习              ,只有在项目中才能灵活将所学知识运用起来      ,话不多说直接开始         。

项目搭建

本案例还是借助框架书写three项目         ,借用vite构建工具搭建react项目              ,vite这个构建工具如果有不了解的朋友        ,可以参考我之前对其讲解的文章:vite脚手架的搭建与使用                   。搭建完成之后      ,用编辑器打开该项目               ,在终端执行 npm i 安装一下依赖          ,安装完成之后终端在安装 npm i three 即可     。

因为react在每次页面发生变化时会出现执行整段代码   ,这样的话就会产生不必要的资源拥塞                ,所以我将three.js代码单独抽离成一个js文件      。具体如下:

import { render } from "./three/水天一色小岛.js" import ./App.css const App = () => { return ( <div> {render()} </div> ) } export default App

当然也是有比较设置一下css样式            ,重置一下浏览器原本的css样式,如下:

*{ margin: 0; padding: 0; } body{ background-color: #1e1a20; } ::-webkit-scrollbar { display: none; }

初始化three.js基础代码

three.js开启必须用到的基础代码如下:

导入three库

import * as THREE from three

初始化场景

const scene = new THREE.Scene()

初始化相机

const camera = new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,2000) camera.position.set(10,50,120) // 设置相机位置 camera.aspect = window.innerWidth / window.innerHeight // 更新摄像头宽高比例 camera.updateProjectionMatrix() // 更新摄像头矩阵 scene.add(camera)

初始化渲染器

const renderer = new THREE.WebGLRenderer({ antialias:true, // 设置抗锯齿 }) renderer.outputEncoding = THREE.sRGBEncoding // 告诉渲染器在输出颜色时采用sRGB空间的标准渲染格式 renderer.setSize(window.innerWidth,window.innerHeight) // 设置渲染器的宽高 document.body.appendChild(renderer.domElement) // 将渲染器添加到页面中

监听屏幕大小的改变              ,修改渲染器的宽高和相机的比例

window.addEventListener("resize",()=>{ camera.aspect = window.innerWidth / window.innerHeight camera.updateProjectionMatrix() renderer.setSize(window.innerWidth,window.innerHeight) })

导入控制器

import { OrbitControls } from "three/examples/jsm/controls/OrbitControls" // 实例化控制器 const controls = new OrbitControls(camera,renderer.domElement)

设置渲染函数

export function render(){ renderer.render(scene,camera) // 渲染场景 requestAnimationFrame(render) // 引擎自动更新渲染器 } render()

ok              ,设置完这些基础代码之后   ,我们可以添加一个物体进行检验一下            ,就添加个平面吧              ,如下:

// 添加平面 const planeGeometry = new THREE.PlaneGeometry(100,100) const planeMaterial = new THREE.MeshBasicMaterial({ color:0xffffff }) const plane = new THREE.Mesh(planeGeometry,planeMaterial) scene.add(plane)

ok      ,可见代码写的没有错误         ,接下来开始具体的Demo实操                 。

设置环境背景

在网上随便找一张全景图片              ,然后进行球体的纹理贴图        ,代码如下:

// 创建一个巨大的天空球体 const skyGeometry = new THREE.SphereGeometry(1000,60,60) const skyMaterial = new THREE.MeshBasicMaterial({ map: new THREE.TextureLoader().load(./src/public/starry-sky2.jpg) }) const sky = new THREE.Mesh(skyGeometry,skyMaterial) scene.add(sky)

一开始我们是置身在球体外部的      ,具体效果如下:

如果想我们一开始就置身在球体内部可以进行如下操作:

设置视频纹理:除了设置图片纹理外               ,我们也可以设置一下视频纹理          ,如下:

// 设置视频纹理 const video = document.createElement("video") video.src = "./src/public/sky.mp4" // 视频路径 video.loop = true // 循环播放 window,addEventListener("click",(e)=>{ // 判断视频是否处于播放状态 if(video.paused){ video.play() skyMaterial.map = new THREE.VideoTexture(video) skyMaterial.map.needsUpdate = true } })

设置水面样式

这里借助three库中Water来实现水面波纹的效果   ,如下:

// 导入水面 import { Water } from "three/examples/jsm/objects/Water2" // 创建平面 const waterGeometry = new THREE.CircleGeometry(300,64) const water = new Water(waterGeometry,{ textureWidth: 1024, textureHeight: 1024, color:0x0080ff, scale: 1, }) water.rotation.x = -Math.PI / 2 scene.add(water)

这里有个坑                ,如果想实现这种波纹效果的话            ,需要自行提供波纹的纹理贴图,并提供特定的路径              ,如果路径不对的话是否爆出如下错误的              ,如下:

添加天空小岛

导入gltf载入库

import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader" import { DRACOLoader } from three/examples/jsm/loaders/dracoloader

添加小岛模型

const loader = new GLTFLoader() // 实例化gltf载入库 const dracoLoader = new DRACOLoader() // 实例化draco载入库 dracoLoader.setDecoderPath("/draco/") // 添加draco载入库 loader.setDRACOLoader(dracoLoader) // 添加draco载入库 loader.load("./model/island2.glb",(gltf)=>{ scene.add(gltf.scene) })

这里需要设置一下环境纹理来显示具体样式

import { DRACOLoader } from three/examples/jsm/loaders/dracoloader import { RGBELoader } from three/examples/jsm/loaders/rgbeloader // 载入环境纹理 const hdrLoader = new RGBELoader() hdrLoader.loadAsync("./src/public/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)

最后实现的效果如下:

ok   ,今天的three.js小案例就讲到这            ,给出本文的代码笔记: (获取素材也可以私信博主)

/* eslint-disable no-unused-vars */ import * as THREE from three // 导入控制器 import { OrbitControls } from "three/examples/jsm/controls/OrbitControls" // 导入水面 import { Water } from "three/examples/jsm/objects/Water2" // 导入gltf载入库 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(10,50,120) // 设置相机位置 camera.aspect = window.innerWidth / window.innerHeight // 更新摄像头宽高比例 camera.updateProjectionMatrix() // 更新摄像头矩阵 scene.add(camera) // 初始化渲染器 const renderer = new THREE.WebGLRenderer({ antialias:true, // 设置抗锯齿 logarithmicDepthBuffer: true // 对数深度缓冲区 }) renderer.outputEncoding = THREE.sRGBEncoding // 告诉渲染器在输出颜色时采用sRGB空间的标准渲染格式 renderer.setSize(window.innerWidth,window.innerHeight) // 设置渲染器的宽高 document.body.appendChild(renderer.domElement) // 将渲染器添加到页面中 // 监听屏幕大小的改变              ,修改渲染器的宽高和相机的比例 window.addEventListener("resize",()=>{ camera.aspect = window.innerWidth / window.innerHeight camera.updateProjectionMatrix() renderer.setSize(window.innerWidth,window.innerHeight) }) // 实例化控制器 const controls = new OrbitControls(camera,renderer.domElement) // 设置渲染函数 export function render(){ renderer.render(scene,camera) // 渲染场景 requestAnimationFrame(render) // 引擎自动更新渲染器 } render() // 创建一个巨大的天空球体 let texture = new THREE.TextureLoader().load(./src/public/starry-sky2.jpg) const skyGeometry = new THREE.SphereGeometry(1000,30,30) const skyMaterial = new THREE.MeshBasicMaterial({ map: texture }) skyGeometry.scale(1,1,-1) const sky = new THREE.Mesh(skyGeometry,skyMaterial) scene.add(sky) // 设置视频纹理 const video = document.createElement("video") video.src = "./src/public/sky.mp4" // 视频路径 video.loop = true // 循环播放 window,addEventListener("click",(e)=>{ // 判断视频是否处于播放状态 if(video.paused){ video.play() let texture = new THREE.VideoTexture(video) skyMaterial.map = texture skyMaterial.map.needsUpdate = true scene.background = texture scene.environment = texture } }) // 载入环境纹理 const hdrLoader = new RGBELoader() hdrLoader.loadAsync("./src/public/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 waterGeometry = new THREE.CircleGeometry(300,64) const water = new Water(waterGeometry,{ textureWidth: 1024, textureHeight: 1024, color:0xeeeeff, scale: 1, }) water.position.y = 3 water.rotation.x = -Math.PI / 2 scene.add(water) // 添加小岛模型 const loader = new GLTFLoader() // 实例化gltf载入库 const dracoLoader = new DRACOLoader() // 实例化draco载入库 dracoLoader.setDecoderPath("/draco/") // 添加draco载入库 loader.setDRACOLoader(dracoLoader) // 添加draco载入库 loader.load("./model/island2.glb",(gltf)=>{ scene.add(gltf.scene) })

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
在线客服源码下载软件(在线客服系统源码编译Golang语言下go build命令构建二进制程序) 小旋风软件下载(小旋风X9站群系统:打造高效盈利的网站运营利器)