Three.js--》实现3d地月模型展示

这篇具有很好参考价值的文章主要介绍了Three.js--》实现3d地月模型展示。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

项目搭建

初始化three.js基础代码

创建月球模型

添加地球模型

添加模型标签


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

项目搭建

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

<template>
  <!-- 地月模型 -->
  <EarthMoonSurrounding></EarthMoonSurrounding>
</template>

<script setup>
import EarthMoonSurrounding from './components/EarthMoonSurrounding.vue';
</script>

<style lang="less">
  *{
    margin: 0;
    padding: 0;
  }
</style>

初始化three.js基础代码

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

导入three库

import * as THREE from 'three'

初始化场景

const scene = new THREE.Scene()

初始化相机

const camera = new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,200)
camera.position.set(10,5,20)

初始化渲染器

const renderer = new THREE.WebGLRenderer({ antialias: true })
renderer.setSize(window.innerWidth,window.innerHeight)

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

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

设置渲染函数

const render = () =>{ 
  requestAnimationFrame(render);
  renderer.render(scene, camera);
}

进行挂载

onMounted(()=>{
  render()
})

ok,写完基础代码之后,接下来开始具体的Demo实操。

创建月球模型

首先这里通过直接给画布的canvas标签添加css样式,给其一个背景图片作为背景:

canvas{
  background-image: url('../../public/images/star.jpg');
  background-size: cover;
}

然后使用TextureLoader用于加载图片纹理的工具,将图片文件加载为 Three.js 中的纹理对象,并且可以将纹理应用到场景中的任何物体上,从而实现更加生动的渲染效果。

// 创建月球
const moonGeometry = new THREE.SphereGeometry(MOON_RADIUS,16,16)
const moonMaterial = new THREE.MeshPhongMaterial({
  map: textureLoader.load('/public/textures/planets/moon_1024.jpg')
})
const moon = new THREE.Mesh(moonGeometry, moonMaterial)
moon.receiveShadow = true
moon.castShadow = true;
scene.add(moon)

创建好模型之后给场景中添加光源:

// 创建添加聚光灯光源
const dirLight = new THREE.SpotLight(0xffffff)
dirLight.position.set(0,0,10)
dirLight.intensity = 1
dirLight.castShadow = true
scene.add(dirLight)
// 添加环境光
const aLight = new THREE.AmbientLight(0xffffff)
aLight.intensity = 0.03
scene.add(aLight)

在渲染函数中通过getElapsedTime方法计算动画经过的时间或者控制动画的播放速度,来动态改变月球位置,让其绕圆周开始运动。

let clock = new THREE.Clock();
// 设置渲染函数
const render = () =>{ 
  const elapsed = clock.getElapsedTime()
  // 月球旋转
  moon.position.set(Math.sin(elapsed)*5,0,Math.cos(elapsed)*5)
  renderer.render(scene,camera)
  requestAnimationFrame(render)
}

Three.js--》实现3d地月模型展示

添加地球模型

这里也采用TextureLoader用于加载图片纹理的工具,将图片文件加载为 Three.js 中的纹理对象,并且可以将纹理应用到场景中的任何物体上,从而实现更加生动的渲染效果。

// 创建地球
const earthGeometry = new THREE.SphereGeometry(EARTH_RADIUS,16,16)
const earthMaterial = new THREE.MeshPhongMaterial({
  map: textureLoader.load('/public/textures/planets/earth_atmos_2048.jpg'),
  specularMap: textureLoader.load('/public/textures/planets/earth_specular_2048.jpg'),
  normalMap: textureLoader.load('/public/textures/planets/earth_normal_2048.jpg'),
})
const earth = new THREE.Mesh(earthGeometry,earthMaterial)
earth.receiveShadow = true
earth.castShadow = true
scene.add(earth)

这里依然在render渲染函数处通过getElapsedTime方法计算动画经过的时间或者控制动画的播放速度,来动态改变地球自转速度,让自转运动。

let clock = new THREE.Clock();
let oldtime = 0
// 设置渲染函数
const render = () =>{ 
  const elapsed = clock.getElapsedTime()
  // 月球旋转
  moon.position.set(Math.sin(elapsed)*5,0,Math.cos(elapsed)*5)
  // 地球自转
  let axis = new THREE.Vector3(0,1,0)
  earth.rotateOnAxis(axis, (elapsed - oldtime) * Math.PI / 10)
  oldtime = elapsed
  requestAnimationFrame(render)
}

Three.js--》实现3d地月模型展示

添加模型标签

在 Three.js 中,CSS2DRenderer 是一个用于将 HTML 元素渲染成 2D 贴图,并将其添加到 Three.js 场景中的工具类。它可以帮助我们更方便地在 Three.js 场景中添加 HTML 元素,比如显示标签、文字等。CSS2DRenderer 类似于 Three.js 中的 WebGLRenderer,但是它渲染的不是 Three.js 的 3D 对象,而是 HTML 元素。

import { CSS2DRenderer} from 'three/examples/jsm/renderers/CSS2DRenderer'

// 创建标签选择器
const labelRenderer = new CSS2DRenderer();
labelRenderer.setSize(window.innerWidth, window.innerHeight)
labelRenderer.domElement.style.position = 'absolute';
labelRenderer.domElement.style.top = '0px';
document.body.appendChild(labelRenderer.domElement)
// 给CSS2DRenderer添加控制器
const controls1 = new OrbitControls(camera,labelRenderer.domElement)
controls1.enableDamping = true

CSS2DObject 则是可以在 Three.js 场景中创建的一个 CSS2D 元素。它类似于 Three.js 中的 Mesh,但是它表示的不是三维物体,而是一个 CSS 元素。你可以通过创建 CSS2DObject 实例,将其添加到 Three.js 的场景中,并设置其内部的 HTML 元素,从而在 Three.js 场景中显示 HTML 内容。

import { CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer'

// 创建月球标签
const moonDiv = document.createElement('div');
moonDiv.className = 'label';
moonDiv.textContent = 'Moon';
const moonLabel = new CSS2DObject(moonDiv)
moonLabel.position.set(0, MOON_RADIUS + 0.5, 0);
moon.add(moonLabel)

// 创建地球标签
const earthDiv = document.createElement('div');
earthDiv.className = 'label';
earthDiv.textContent = 'Earch';
const eartchLabel = new CSS2DObject(earthDiv)
eartchLabel.position.set(0, EARTH_RADIUS + 0.5, 0);
earth.add(eartchLabel)

然后给出直接设置类名的样式:

Three.js--》实现3d地月模型展示

最后在渲染函数中加载渲染标签函数 :

Three.js--》实现3d地月模型展示

Three.js--》实现3d地月模型展示

demo做完,给出本案例的完整代码:(获取素材也可以私信博主)文章来源地址https://www.toymoban.com/news/detail-466986.html

<script setup>
import * as THREE from 'three'
import { onMounted } from 'vue';
// 控制器
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
// 文字2D渲染器
import { CSS2DRenderer,CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer'

const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.1,200)
camera.position.set(10,5,20)

// 创建渲染器
const renderer = new THREE.WebGLRenderer({ 
  alpha: true
})
renderer.setPixelRatio(window.devicePixelRatio) // 根据屏幕显示像素比
renderer.setSize(window.innerWidth,window.innerHeight)
renderer.shadowMap.enabled = true // 渲染阴影
document.body.appendChild(renderer.domElement)

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

// 设置控制器
const controls = new OrbitControls(camera,renderer.domElement)
controls.enableDamping = true

let clock = new THREE.Clock();
let oldtime = 0
// 设置渲染函数
const render = () =>{ 
  const elapsed = clock.getElapsedTime()
  // 月球旋转
  moon.position.set(Math.sin(elapsed)*5,0,Math.cos(elapsed)*5)
  // 地球自转
  let axis = new THREE.Vector3(0,1,0)
  earth.rotateOnAxis(axis, (elapsed - oldtime) * Math.PI / 10)
  oldtime = elapsed
  renderer.render(scene,camera)
  labelRenderer.render(scene, camera)
  requestAnimationFrame(render)
}

// 设置地球和月球的半径大小
const EARTH_RADIUS = 2.5
const MOON_RADIUS = 0.27
// 实例化纹理加载器
const textureLoader = new THREE.TextureLoader()
// 创建标签选择器
const labelRenderer = new CSS2DRenderer();
labelRenderer.setSize(window.innerWidth, window.innerHeight)
labelRenderer.domElement.style.position = 'absolute';
labelRenderer.domElement.style.top = '0px';
document.body.appendChild(labelRenderer.domElement)
// 给CSS2DRenderer添加控制器
const controls1 = new OrbitControls(camera,labelRenderer.domElement)
controls1.enableDamping = true

// 创建月球
const moonGeometry = new THREE.SphereGeometry(MOON_RADIUS,16,16)
const moonMaterial = new THREE.MeshPhongMaterial({
  map: textureLoader.load('/public/textures/planets/moon_1024.jpg')
})
const moon = new THREE.Mesh(moonGeometry, moonMaterial)
moon.receiveShadow = true
moon.castShadow = true;
scene.add(moon)
// 创建月球标签
const moonDiv = document.createElement('div');
moonDiv.className = 'label';
moonDiv.textContent = 'Moon';
const moonLabel = new CSS2DObject(moonDiv)
moonLabel.position.set(0, MOON_RADIUS + 0.5, 0);
moon.add(moonLabel)

// 创建地球
const earthGeometry = new THREE.SphereGeometry(EARTH_RADIUS,16,16)
const earthMaterial = new THREE.MeshPhongMaterial({
  map: textureLoader.load('/public/textures/planets/earth_atmos_2048.jpg'),
  specularMap: textureLoader.load('/public/textures/planets/earth_specular_2048.jpg'),
  normalMap: textureLoader.load('/public/textures/planets/earth_normal_2048.jpg'),
})
const earth = new THREE.Mesh(earthGeometry,earthMaterial)
earth.receiveShadow = true
earth.castShadow = true
scene.add(earth)
// 创建地球标签
const earthDiv = document.createElement('div');
earthDiv.className = 'label';
earthDiv.textContent = 'Earch';
const eartchLabel = new CSS2DObject(earthDiv)
eartchLabel.position.set(0, EARTH_RADIUS + 0.5, 0);
earth.add(eartchLabel)

// 创建添加聚光灯光源
const dirLight = new THREE.SpotLight(0xffffff)
dirLight.position.set(0,0,10)
dirLight.intensity = 1
dirLight.castShadow = true
scene.add(dirLight)
// 添加环境光
const aLight = new THREE.AmbientLight(0xffffff)
aLight.intensity = 0.03
scene.add(aLight)

onMounted(()=>{
  render()
})
</script>
<style lang="less">
canvas{
  background-image: url('../../public/images/star.jpg');
  background-size: cover;
}
.label {
  color: #fff;
  font-size: 16px;
}
</style>

到了这里,关于Three.js--》实现3d地月模型展示的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Three.js--》实现3d圣诞贺卡展示模型

    目录 项目搭建 初始化three.js基础代码 加载环境模型 设置环境纹理 添加水面并设置阴影效果 实现幽灵小球的运动 实现相机切换和文字切屏 实现漫天星星和爱心样式 今天简单实现一个three.js的小Demo,加强自己对three知识的掌握与学习,只有在项目中才能灵活将所学知识运用起

    2024年02月06日
    浏览(54)
  • Three.js--》实现3d球形机器人模型展示

    目录 项目搭建 初始化three.js基础代码 设置环境纹理 加载机器人模型 添加光阵 今天简单实现一个three.js的小Demo,加强自己对three知识的掌握与学习,只有在项目中才能灵活将所学知识运用起来,话不多说直接开始。 项目搭建 本案例还是借助框架书写three项目,借用vite构建工

    2024年02月07日
    浏览(88)
  • Three.js--》实现3d小岛模型搭建

    目录 项目搭建 初始化three.js基础代码 设置环境背景 设置水面样式 添加天空小岛 今天简单实现一个three.js的小Demo,加强自己对three知识的掌握与学习,只有在项目中才能灵活将所学知识运用起来,话不多说直接开始。 项目搭建 本案例还是借助框架书写three项目,借用vite构建

    2024年02月05日
    浏览(87)
  • Three.js--》实现3d汽车模型展览搭建

    目录 项目搭建 初始化three.js基础代码 添加汽车模型展示 动态修改汽车模型 今天简单实现一个three.js的小Demo,加强自己对three知识的掌握与学习,只有在项目中才能灵活将所学知识运用起来,话不多说直接开始。 项目搭建 本案例还是借助框架书写three项目,借用vite构建工具

    2024年02月06日
    浏览(84)
  • Three.js--》实现3d水晶小熊模型搭建

    目录 项目搭建 初始化three.js基础代码 加载背景纹理 加载小熊模型 今天简单实现一个three.js的小Demo,加强自己对three知识的掌握与学习,只有在项目中才能灵活将所学知识运用起来,话不多说直接开始。 项目搭建 本案例还是借助框架书写three项目,借用vite构建工具搭建vue项

    2024年02月06日
    浏览(51)
  • 微信小程序利用three.js展示3D模型部分问题

    由于小程序的内存限制比较多,稍不注意就容易溢出,所以经过测试后我选择gltf模型。不用加载贴图,而且这个格式较为通用,最关键的是真的很小。OBJ+PNG怎么转GLTF格式在我上篇帖子内有。 three.js有一个小程序专用插件threex,移植效果还不错,但渲染出来的效果会差一点,

    2024年02月08日
    浏览(51)
  • three.js加载3D模型,在网页上展示3D模型(.glb.gltf.fbx格式)

    Three.js是一款开源的主流3D绘图JS引擎,简单点,可以将它理解为three+js就可以了,three表示3D,js表示JavaScript的意思。 结构  .glb.gltf文件最好放在服务器上 放在本地容易报找不到的错 .fbx格式文件可以在本地用3d看图(win10自带)打开另存为.glb格式 index.html代码 js代码 项目案例

    2024年02月11日
    浏览(53)
  • Three.js--》实现3D汽车展厅效果展示

    目录 项目搭建 初始化three.js基础代码 加载汽车模型 设置展厅效果 设置GUI面板动态控制车身操作 车门操作与车身视角展示 设置手动点击打开关闭车门 设置图片背景 今天简单实现一个three.js的小Demo,加强自己对three知识的掌握与学习,只有在项目中才能灵活将所学知识运用起

    2024年02月09日
    浏览(53)
  • Three.js--》实现图片转3D效果展示

    目录 项目搭建 初始化three.js基础代码 加载图片纹理 设置着色器 今天简单实现一个three.js的小Demo,加强自己对three知识的掌握与学习,只有在项目中才能灵活将所学知识运用起来,话不多说直接开始。 项目搭建 本案例还是借助框架书写three项目,借用vite构建工具搭建vue项目

    2024年02月08日
    浏览(55)
  • 微信小程序3D,使用Three.js在微信小程序中展示gltf模型,使用VisionKit展示AR能力

    本仓库只开源gltf模型展示技术,技术好的朋友有这些代码就能帮助你解决很多问题了 如需要完整项目(基于若依框架开发的后端,AR能力前端)需另外付费赞助, 联系方式:QQ 790002517 微信公众号:时不待我 https://github.com/zzy-life/Wechat3D Three.js Three.js is a JavaScript 3D library. thr

    2024年02月09日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包