03.Three.js的入门教程(二)如何创建一个3D地球?

前言:通过上节课 02.Three.js的入门课程(一),我们了解了Three.js的最小案例DEMO,熟悉了几个重要组成部分。这节课带领大家编写一个3D地球。

一、通过纹理图渲染一个地球

1.1.创建一个纹理加载器对象TextureLoader,可以加载图片作为纹理贴图;

// 引入three.js
import * as THREE from '../../../three.js-r123/build/three.module.js';

// 创建地球mesh网格对象
// 地球半径
var R = 100;

var earth = createSphereMesh(R);

// R:地球半径
function createSphereMesh(R) {

    // 创建纹理加载器对象
    var textureLoader = new THREE.TextureLoader();

    // 加载纹理贴图
    var texture = textureLoader.load('earth.jpg');

    // 创建一个球体几何对象
    var geometry = new THREE.SphereBufferGeometry(R, 40, 40); 
  
    // 材质对象Material
    var material = new THREE.MeshLambertMaterial({
        // color: 0x00ffff,
        map: texture,//设置地球颜色贴图map
    });

    // 网格模型对象Mesh
    var mesh = new THREE.Mesh(geometry, material); 

    return mesh;
}

export { earth }

1.2.完整代码结构

二、小球标注球面上一点

2.1.创建一个小球的网格模型

// 引入Three.js
import * as THREE from '../../../three.js-r123/build/three.module.js';

// 创建一个小球用于测试
function createSphereMesh(R,x,y,z) {
  // 创建一个球体几何对象  
  var geometry = new THREE.SphereGeometry(R, 25, 25); 
  
  // 材质对象Material
  var material = new THREE.MeshLambertMaterial({
      color: 0xff0000
  });

  // 网格模型对象Mesh
  var mesh = new THREE.Mesh(geometry, material);

  mesh.position.set(x,y,z);

  return mesh
}

export { createSphereMesh }

2.2.完整代码

html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title></title>
  <style>
    body {
      margin: 0;
      overflow: hidden;
    }
  </style>
</head>

<body>
  <script type="module">
        
    /**
     * 01.创建地球
     */
    import { scene, renderer } from './scene.js'
    // Three.js渲染结果Canvas画布插入到body元素中
    document.body.appendChild(renderer.domElement); 
    
    /**
     * 02.创建小球mesh
     */
    // 地球半径
    var R = 100;
    import { createSphereMesh } from './help.js'
    // 北极球面上绘制一个小球标注
    scene.add(createSphereMesh(10,0,R,0));

  </script>
</body>

</html>

scene.js

/**
 * 01.引入第三方依赖
 */
// 引入Three.js
import * as THREE from '../../../three.js-r123/build/three.module.js';

// 引入Three.js扩展库
import { OrbitControls } from '../../../three.js-r123/examples/jsm/controls/OrbitControls.js';

// 引入地球
import { earth } from './earth.js'


/**
 * 02.创建场景对象Scene
 */
var scene = new THREE.Scene();
scene.add(earth);

/**
 * 03.光源设置
 */
// 平行光1
var directionalLight = new THREE.DirectionalLight(0xffffff, 0.6);
directionalLight.position.set(400, 200, 300);
scene.add(directionalLight);

// 平行光2
var directionalLight2 = new THREE.DirectionalLight(0xffffff, 0.6);
directionalLight2.position.set(-400, -200, -300);
scene.add(directionalLight2);

//环境光
var ambient = new THREE.AmbientLight(0xffffff, 0.6);
scene.add(ambient);

/**
 * 04.相机设置
 */
// width和height用来设置Three.js输出Canvas画布尺寸,同时用来辅助设置相机渲染范围
// 窗口文档显示区的宽度
var width = window.innerWidth; 
// 窗口文档显示区的高度
var height = window.innerHeight; 

// Three.js输出的Cnavas画布宽高比
var k = width / height; 
// 控制相机渲染空间左右上下渲染范围,s越大,相机渲染范围越大
var s = 200; 
// THREE.OrthographicCamera()创建一个正投影相机对象
// -s * k, s * k, s, -s, 1, 1000定义了一个长方体渲染空间,渲染空间外的模型不会被渲染
var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);

// 相机在Three.js坐标系中的位置
camera.position.set(200, 300, 200); 
// 相机指向Three.js坐标系原点
camera.lookAt(0, 0, 0); 

/**
 * 05.创建渲染器对象
 */
var renderer = new THREE.WebGLRenderer({
  antialias: true, //开启锯齿
});

// 设置设备像素比率,防止Canvas画布输出模糊
renderer.setPixelRatio(window.devicePixelRatio);
// 设置渲染区域尺寸
renderer.setSize(width, height); 

// 设置背景颜色
// renderer.setClearColor(0xb9d3ff, 1); 
// renderer.domElement表示Three.js渲染结果,也就是一个HTML元素(Canvas画布)
// body元素中插入canvas对象
// document.body.appendChild(renderer.domElement); 

/**
 * 06.渲染循环
 */ 
function render() {
  // 地球绕y轴旋转动画
  // earth.rotateY(0.01);
  // 执行渲染操作
  renderer.render(scene, camera); 
  // 请求再次执行渲染函数render,渲染下一帧
  requestAnimationFrame(render); 
}
render();

/**
 * 07.Three.js三维坐标轴 三个坐标轴颜色RGB分别对应xyz轴
 */
var axesHelper = new THREE.AxesHelper(250);
scene.add(axesHelper);


/**
 * 08.创建控件对象  控件可以监听鼠标的变化,改变相机对象的属性
 */
// 旋转:拖动鼠标左键
// 缩放:滚动鼠标中键
// 平移:拖动鼠标右键
var controls = new OrbitControls(camera, renderer.domElement);

export { scene, renderer}

earth.js

// 引入three.js
import * as THREE from '../../../three.js-r123/build/three.module.js';

// 地球半径
var R = 100;
// 创建地球mesh
var earth = createSphereMesh(R);

function createSphereMesh(r) {
  // TextureLoader创建一个纹理加载器对象,可以加载图片作为纹理贴图
  var textureLoader = new THREE.TextureLoader();

  // 加载纹理贴图
  var texture = textureLoader.load('earth.jpg');

  // 创建一个球体几何对象
  var geometry = new THREE.SphereBufferGeometry(r, 40, 40); 

  // 材质对象Material
  var material = new THREE.MeshLambertMaterial({
    // color: 0x00ffff,
    // 设置地球颜色贴图map
    map: texture,
  });

  // 网格模型对象Mesh
  var mesh = new THREE.Mesh(geometry, material); 

  return mesh
}

export { earth }

help.js

// 引入Three.js
import * as THREE from '../../../three.js-r123/build/three.module.js';

// 创建一个小球用于测试
function createSphereMesh(R,x,y,z) {
  // 创建一个球体几何对象
  var geometry = new THREE.SphereGeometry(R, 25, 25); 

  // 材质对象Material
  var material = new THREE.MeshLambertMaterial({
    color: 0xff0000
  }); 

  // 网格模型对象Mesh
  var mesh = new THREE.Mesh(geometry, material);

  mesh.position.set(x,y,z);
  return mesh
}

export { createSphereMesh }

earth.png

2.3.运行效果图

说明:本文代码参考技术博客:www.yanhuangxueyuan.com,如有侵权,请私信作者,删除博文处理。 

猜你喜欢

转载自blog.csdn.net/weixin_44121341/article/details/131539322