创建一个地球模型通常涉及到使用纹理贴图来给球体添加地球表面的图像。在 Three.js 中,你可以通过加载一张地球的图片作为纹理,并将其应用到一个 SphereGeometry 上来实现这一点。以下是如何完成这个过程的一个基本示例:
步骤 1: 设置场景、相机和渲染器
这部分与前面创建基础球体时相同。
import * as THREE from 'three';
// 创建场景
const scene = new THREE.Scene();
// 创建相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 8; // 将相机后移,以便看到整个地球
// 创建渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
步骤 2: 加载地球纹理
我们需要从某个 URL 加载地球的纹理图片。Three.js 提供了 TextureLoader 来处理这一任务。
const textureLoader = new THREE.TextureLoader();
const earthTexture = textureLoader.load('path/to/earth_texture.jpg'); // 确保你有正确的路径指向地球纹理图片
步骤 3: 创建地球材质并应用纹理
我们将使用 MeshPhongMaterial 来创建一个可以反射光线的材质,并将纹理应用到它上面。
// 创建地球材质
const material = new THREE.MeshPhongMaterial({
map: earthTexture,
shininess: 10
});
步骤 4: 创建地球几何体
接下来,我们创建一个球体几何体,并用之前定义的材质来包裹它。
// 创建球体几何体
const geometry = new THREE.SphereGeometry(1, 64, 64); // 半径为1,细分度为64x64,以获得更平滑的球面
// 创建地球网格
const earth = new THREE.Mesh(geometry, material);
// 将地球添加到场景中
scene.add(earth);
步骤 5: 添加光源
为了让地球看起来更真实,我们需要添加光源。这里我们添加一个环境光和一个定向光。
// 添加环境光
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(ambientLight);
// 添加定向光
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
directionalLight.position.set(5, 5, 3); // 调整位置以达到理想的光照效果
scene.add(directionalLight);
步骤 6: 渲染循环及窗口大小调整
最后,我们需要设置渲染循环以及监听窗口大小变化的事件处理器。
function animate() {
requestAnimationFrame(animate);
// 可选:旋转地球
earth.rotation.y += 0.005;
renderer.render(scene, camera);
}
animate();
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
完整代码
这是所有代码段合并后的完整示例:
import * as THREE from 'three';
// 场景、相机、渲染器
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 8;
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// 纹理加载
const textureLoader = new THREE.TextureLoader();
const earthTexture = textureLoader.load('path/to/earth_texture.jpg');
// 材质与几何体
const material = new THREE.MeshPhongMaterial({ map: earthTexture, shininess: 10 });
const geometry = new THREE.SphereGeometry(1, 64, 64);
const earth = new THREE.Mesh(geometry, material);
scene.add(earth);
// 光源
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
directionalLight.position.set(5, 5, 3);
scene.add(directionalLight);
// 渲染循环
function animate() {
requestAnimationFrame(animate);
earth.rotation.y += 0.005;
renderer.render(scene, camera);
}
animate();
// 窗口调整
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
确保你有一个可用的地球纹理图片,并且正确设置了其路径。这样,当你运行这段代码时,你应该能看到一个带有纹理的地球模型在页面上旋转。
融合到vue3创建地球模型实现及效果
示例代码
<template><div id="three" ref="three"></div>
</template><script lang="ts">
import type {AmbientLight,AxesHelper,Clock,DirectionalLight,Mesh,OrthographicCamera,Scene,Texture,WebGLRenderer
} from 'three'
import * as THREE from 'three'
import { defineComponent, onBeforeUnmount, onMounted, ref } from 'vue'
import Stats from 'stats.js'
import CameraControls from 'camera-controls'
import { useThree } from '@/hooks'let scene: Scene,camera: OrthographicCamera,renderer: WebGLRenderer,point: DirectionalLight,ambient: AmbientLight,axesHelper: AxesHelper,mesh: Mesh,stats: Stats,cameraControls: CameraControls,clock: Clock,animation: number,texture: Textureexport default defineComponent({name: 'gallery4',setup () {const three = ref<HTMLElement>(document.createElement('div'))const {initScene,initCamera,initRenderer,initLight,initHelpers,initStats,windowResize,initControls,initClock} = useThree(scene, camera, renderer, point, ambient, axesHelper, stats, cameraControls, clock)// 初始化模型function initModel () {const geometry = new THREE.SphereGeometry(100, 100, 100) // 球体const textureLoader = new THREE.TextureLoader()// 加载纹理贴图const texture = textureLoader.load('/img/earth.png')// 加载法线贴图const textureNormal = textureLoader.load('/img/earth_normal.png')// 加载高光贴图const textureSpecular = textureLoader.load('/img/earth_spec.png')const material = new THREE.MeshPhongMaterial({map: texture,normalMap: textureNormal, // 法线贴图normalScale: new THREE.Vector2(1.5, 1.5), // 设置深浅程度,默认值(1,1)。shininess: 40, // 高光部分的亮度,默认30specularMap: textureSpecular // 高光贴图})mesh = new THREE.Mesh(geometry, material)scene.add(mesh)}// 渲染function render () {scene && renderer.render(scene, camera)stats && stats.update()cameraControls && cameraControls.update(clock.getDelta())animation = requestAnimationFrame(render)mesh.rotateY(0.005)}// 初始化function init (el: HTMLElement) {scene = initScene()camera = initCamera()renderer = initRenderer(el)stats = initStats(el)cameraControls = initControls()clock = initClock()initLight()initHelpers()initModel()render()}onMounted(() => {const el = three.valueinit(el)window.addEventListener('resize', windowResize)})onBeforeUnmount(() => {cancelAnimationFrame(animation)cameraControls && cameraControls.dispose()window.removeEventListener('resize', windowResize)})return {three}}
})
</script>
如果对您有所帮助,请点赞打赏支持!
技术合作交流qq:2401315930
最后分享一下地图下载器设计及下载地址:
链接:https://pan.baidu.com/s/1RZX7JpTpxES-G7GiaVUxOw
提取码:61cn
地图下载器代码结构设计及功能实现_地图下载管理器解析-CSDN博客