Search K
Appearance
Appearance
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body,
html {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
overflow: hidden;
}
.container{
height: 100vh;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
#c2d {
/* width: 100%;
height: 100vh; */
margin: 0 auto;
}
</style>
</head>
<body>
<div class="container">
<canvas id="c2d" class="c2d" width="2000" height="1000"></canvas>
</div>
<script type="module">
/**
* 本章节内容
* 学习threejs中的常用几何体以及常用材质
**/
// 引入官网提供的地址
import * as THREE from "../libs/three.module.js"
import { OrbitControls } from 'https://threejsfundamentals.org/threejs/resources/threejs/r132/examples/jsm/controls/OrbitControls.js'
let renderer = null;
let camera = null;
let scene = null;
let sunMesh = null;
let controls = null;
let canvas = null;
let loader = null;
// 初始化渲染器
const initRenderer = () => {
canvas = document.querySelector("#c2d")
renderer = new THREE.WebGLRenderer({ canvas, antialias: true })
renderer.setClearColor(0xf5f5f5, 1)
}
// 初始化相机
const initCamera = () => {
// 视野范围
const fov = 40
// 相机的宽高比,画布的宽高比
const aspect = document.body.clientWidth / document.body.clientHeight
// 近平面
const near = 0.1
// 远平面
const far = 1000
// 透视投影相机
camera = new THREE.PerspectiveCamera(fov, aspect, near, far)
// 相机位置
camera.position.set(0, 0, 50)
camera.lookAt(0, 0, 0) // 相机朝向
}
// 初始化场景
const initScene = () => {
scene = new THREE.Scene()
}
// 初始化灯光
const initLight = () => {
const color = 0xffffff
const intensity = 1
// 创建光源
const light = new THREE.PointLight(color, intensity)
// 光源 加入场景
scene.add(light)
}
// 初始化OrbitControls相机控件
const initOrbitControls = () => {
controls = new OrbitControls(camera, canvas)
controls.update()
}
// 初始化网格线和物体
const initMesh = () => {
// 纹理加载器
loader = new THREE.TextureLoader()
}
// 初始化场景中的背景颜色
const initSceneBackground = () => {
const bgTexture = loader.load("../imgs/4.jpg")
scene.background = bgTexture
}
// 场景和相机放入渲染器中
const render = (time = 1) => {
time *= 0.001
// 加载渲染器
renderer.render(scene, camera)
// 开始动画
requestAnimationFrame(render)
}
initScene()
initRenderer()
initCamera()
initOrbitControls()
initLight()
initMesh()
initSceneBackground()
// 开始渲染
requestAnimationFrame(render)
</script>
</body>
</html>
添加星空背景,通过TextureLoader
将图片转化为纹理
// 初始化场景中的背景颜色
const initSceneBackground = () => {
const bgTexture = loader.load("../imgs/4.jpg")
scene.background = bgTexture
}
// 初始化网格线和物体
const initMesh = () => {
// 纹理加载器
loader = new THREE.TextureLoader()
// 添加太阳
const radius = 2 // 半径
const widthSegments = 32 // 宽度分段数
const heightSegments = 32 // 宽度分段数
// 创建球体
const sphereGeometry = new THREE.SphereGeometry(radius, widthSegments, heightSegments)
// 加载太阳贴图
const sunTexture = loader.load("../imgs/1.jpg", textture => {
// 创建太阳材质
const sunMaterial = new THREE.MeshBasicMaterial({ map: textture })
// 创建太阳网格对象
sunMesh = new THREE.Mesh(sphereGeometry, sunMaterial)
// 网格分别在x,y,z轴上面放大的倍数
sunMesh.scale.set(3, 3, 3)
obejects.push(sunMesh)
scene.add(sunMesh)
// 添加地球
const earthTexture = loader.load("../imgs/3.jpg", textture2 => {
// 创建地球材质
const earthMaterial = new THREE.MeshPhongMaterial({ map: textture2 })
// 创建地球网格
earthMesh = new THREE.Mesh(sphereGeometry, earthMaterial)
earthMesh.position.x = 20
scene.add(earthMesh)
obejects.push(earthMesh)
})
})
}
// 场景和相机放入渲染器中
const render = (time = 1) => {
time *= 0.001
// 加载渲染器
renderer.render(scene, camera)
obejects.forEach(k => {
k.rotation.y = time
})
// 开始动画
requestAnimationFrame(render)
}
此时已经添加了地球和太阳,并且它们都已实现了自转,下一步需要实现地球绕太阳转动
要实现地球绕太阳运动,可以将太阳和地球都添加作为一个网格组,此时太阳在网格组的正中心,设置地球x
轴定位在网格组20
个单位
// 初始化网格线和物体
const initMesh = () => {
// 纹理加载器
loader = new THREE.TextureLoader()
// 添加太阳
const radius = 2 // 半径
const widthSegments = 32 // 宽度分段数
const heightSegments = 32 // 宽度分段数
// 创建球体
const sphereGeometry = new THREE.SphereGeometry(radius, widthSegments, heightSegments)
// 加载太阳贴图
const sunTexture = loader.load("../imgs/1.jpg", textture => {
// 创建太阳材质
const sunMaterial = new THREE.MeshBasicMaterial({ map: textture })
// 创建太阳网格对象
sunMesh = new THREE.Mesh(sphereGeometry, sunMaterial)
// 网格分别在x,y,z轴上面放大的倍数
sunMesh.scale.set(3, 3, 3)
// obejects.push(sunMesh)
// scene.add(sunMesh)
// 添加地球
const earthTexture = loader.load("../imgs/3.jpg", textture2 => {
// 创建地球材质
const earthMaterial = new THREE.MeshPhongMaterial({ map: textture2 })
// 创建地球网格
earthMesh = new THREE.Mesh(sphereGeometry, earthMaterial)
earthMesh.position.x = 20
// scene.add(earthMesh)
obejects.push(earthMesh)
const solarSystemGroup = new THREE.Group()
solarSystemGroup.add(sunMesh)
solarSystemGroup.add(earthMesh)
scene.add(solarSystemGroup)
obejects.push(solarSystemGroup)
})
})
}
这样既可实现地球绕太阳公转,也可以实现地球自转,月亮是以地球为中心点,所以实现方式是跟太阳系的实现方式类似的
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body,
html {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
overflow: hidden;
}
.container {
height: 100vh;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
#c2d {
/* width: 100%;
height: 100vh; */
margin: 0 auto;
}
</style>
</head>
<body>
<div class="container">
<canvas id="c2d" class="c2d" width="2000" height="1000"></canvas>
</div>
<script type="module">
/**
* 本章节内容
* 学习threejs中的常用几何体以及常用材质
**/
// 引入官网提供的地址
import * as THREE from "../libs/three.module.js"
import { OrbitControls } from 'https://threejsfundamentals.org/threejs/resources/threejs/r132/examples/jsm/controls/OrbitControls.js'
let renderer = null;
let camera = null;
let scene = null;
let sunMesh = null;
let controls = null;
let canvas = null;
let loader = null;
let earthMesh = null;
// 添加到该数组中的3D对象渲染的时候遍历循环
const obejects = []
// 初始化渲染器
const initRenderer = () => {
canvas = document.querySelector("#c2d")
renderer = new THREE.WebGLRenderer({ canvas, antialias: true })
renderer.setClearColor(0xf5f5f5, 1)
}
// 初始化相机
const initCamera = () => {
// 视野范围
const fov = 40
// 相机的宽高比,画布的宽高比
const aspect = document.body.clientWidth / document.body.clientHeight
// 近平面
const near = 0.1
// 远平面
const far = 1000
// 透视投影相机
camera = new THREE.PerspectiveCamera(fov, aspect, near, far)
// 相机位置
camera.position.set(0, 0, 50)
camera.lookAt(0, 0, 0) // 相机朝向
}
// 初始化场景
const initScene = () => {
scene = new THREE.Scene()
}
// 初始化灯光
const initLight = () => {
const color = 0xffffff
const intensity = 1
// 创建光源
const light = new THREE.PointLight(color, intensity)
// 光源 加入场景
scene.add(light)
}
// 初始化OrbitControls相机控件
const initOrbitControls = () => {
controls = new OrbitControls(camera, canvas)
controls.update()
}
// 初始化网格线和物体
const initMesh = () => {
// 纹理加载器
loader = new THREE.TextureLoader()
// 添加太阳
const radius = 2 // 半径
const widthSegments = 32 // 宽度分段数
const heightSegments = 32 // 宽度分段数
// 创建球体
const sphereGeometry = new THREE.SphereGeometry(radius, widthSegments, heightSegments)
// 加载太阳贴图
const sunTexture = loader.load("../imgs/1.jpg", textture => {
// 创建太阳材质
const sunMaterial = new THREE.MeshBasicMaterial({ map: textture })
// 创建太阳网格对象
sunMesh = new THREE.Mesh(sphereGeometry, sunMaterial)
// 网格分别在x,y,z轴上面放大的倍数
sunMesh.scale.set(3, 3, 3)
// 加载地球贴图
const earthTexture = loader.load("../imgs/3.jpg", textture2 => {
// 加载月球贴图
const monthTexture = loader.load("../imgs/2.jpg", textture3 => {
// 创建地球材质
const earthMaterial = new THREE.MeshPhongMaterial({ map: textture2 })
// 创建地球网格
earthMesh = new THREE.Mesh(sphereGeometry, earthMaterial)
// 添加地月系
const landOrbit = new THREE.Group()
// 地月系相对太阳x设置20个单位
landOrbit.position.x = 20
// 将地球设置为地月系的中心点
landOrbit.add(earthMesh)
// 地球自转
obejects.push(earthMesh)
// 创建月球材质
const monthMaterial = new THREE.MeshPhongMaterial({ map:textture3 })
// 创建月球网格
const monthMesh = new THREE.Mesh(sphereGeometry,monthMaterial)
// 设置月球相对地月系中心点也就是地球x偏移10个单位
monthMesh.position.x = 3
// 月球比地球小,缩小体积
monthMesh.scale.set(0.5,0.5,0.5)
// 添加月球网格到地月系网格组中
landOrbit.add(monthMesh)
// 地月系自身开始自转,以地球为中心点
obejects.push(landOrbit)
// 创建太阳系网格
const solarSystemGroup = new THREE.Group()
// 添加太阳网格,以太阳网格为中心
solarSystemGroup.add(sunMesh)
// 添加地月系,地月系距离太阳x设置20个单位
solarSystemGroup.add(landOrbit)
scene.add(solarSystemGroup)
// 太阳系自转,以太阳为中心点
obejects.push(solarSystemGroup)
})
})
})
}
// 初始化场景中的背景颜色
const initSceneBackground = () => {
const bgTexture = loader.load("../imgs/4.jpg")
scene.background = bgTexture
}
// 场景和相机放入渲染器中
const render = (time = 1) => {
time *= 0.001
// 加载渲染器
renderer.render(scene, camera)
obejects.forEach(k => {
k.rotation.y = time
})
// 开始动画
requestAnimationFrame(render)
}
initScene()
initRenderer()
initCamera()
initOrbitControls()
initLight()
initMesh()
initSceneBackground()
// 开始渲染
requestAnimationFrame(render)
</script>
</body>
</html>
TIP