threejs 创建纹理贴图 学习笔记

threejs yekong

纹理贴图就是通过threejs将图片贴在threejs创建的几何模型上面。创建纹理贴图模型需要大概以下几步
1.纹理加载器加载纹理
2.创建球形几何体
3.创建材质将纹理加入进去
4.创建网格模型将几何体和材质加入进去
5.创建场景将模型加入到场景中

球形贴图

demo地址

纹理贴图3d地球

纹理加载器

在进行贴图前首先需要将图片加载进来,加载图片是使用纹理加载器textureLoader进行图片加载。

创建加载器对象

加载前需要创建加载器对象

var textureLoader = new THREE.TextureLoader();

加载纹理贴图

通过textureLoader.load将图片加载进来,load里是图片的路径。

var texture = textureLoader.load('static/earth1.jpg');

至此图片便加载完成,接下来创建模型

创建球体

创建球体几何对象是用SphereBufferGeometry进行创建,但是SphereBufferGeometry在新版本里面已经没有了,
这里使用的版本是r123 根据r123版本文档里的说明,我们可以快速创建一个球体.
创建球体我们只需要创建前三个参数分别是
球体半径
水平分段数
垂直分段数

球体半径不必多说,这里的水平分段数和垂直分段数越多越接近圆,太多的话会消耗显存资源,所这里我们只设置32个。

const geometry = new THREE.SphereBufferGeometry( 5, 32, 32 );

球缓冲几何体

参数说明

radius — 球体半径,默认为1。
widthSegments — 水平分段数(沿着经线分段),最小值为3,默认值为8。
heightSegments — 垂直分段数(沿着纬线分段),最小值为2,默认值为6。
phiStart — 指定水平(经线)起始角度,默认值为0。。
phiLength — 指定水平(经线)扫描角度的大小,默认值为 Math.PI * 2。
thetaStart — 指定垂直(纬线)起始角度,默认值为0。
thetaLength — 指定垂直(纬线)扫描角度大小,默认值为 Math.PI。
该几何体是通过扫描并计算围绕着Y轴(水平扫描)和X轴(垂直扫描)的顶点来创建的。 因此,不完整的球体(类似球形切片)可以通过为phiStart,phiLength,thetaStart和thetaLength设置不同的值来创建, 以定义我们开始(或结束)计算这些顶点的起点(或终点)。

创建材质对象

几何体和纹理都创建好了,接下来创建材质对象,通过MeshLambertMaterial创建材质将纹理通过map参数传到材质对象中。这样材质便创建完成了。

var material = new THREE.MeshLambertMaterial({
    // color: 0x00ffff,
    map: texture,
});

创建网格模型

通过Mesh我们创建出一个模型对象,然后将我们前面创建的模型和材质传进去,整个模型就创建好了。

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

导出模型

创建完模型后将模型导出以便于我们复用

// 引入three.js
import * as THREE from 'three/build/three.module.js';
import {modelUrl} from "@/config/config.js";
// R:地球半径
function createSphereMesh(R) {
  // TextureLoader创建一个纹理加载器对象,可以加载图片作为纹理贴图
  var textureLoader = new THREE.TextureLoader();
  var texture = textureLoader.load(modelUrl + 'static/earth1.jpg');//加载纹理贴图
  var geometry = new THREE.SphereBufferGeometry(R, 40, 40); //创建一个球体几何对象
  //材质对象Material
  var material = new THREE.MeshLambertMaterial({
    // color: 0x00ffff,
    map: texture,//设置地球颜色贴图map
  });
  var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
  return mesh
}

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

export { earth }

加入到场景

引入我们前面创建的模型,添加到threejs创建的场景中

import { earth } from './earth.js'//绘制地球
// 创建场景
var scene = new THREE.Scene();
将我们绘制的地球加入进去搞定了
scene.add(earth);

场景

当然场景里只有我们的地球还不行,还需要灯光 摄像机这些不是今天的重点我只把代码贴出来,供大家参考

// 引入Three.js
import * as THREE from 'three/build/three.module.js';
// 引入Three.js扩展库
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { earth } from './earth.js'//绘制地球
/**
 * 创建场景对象Scene
 */
var scene = new THREE.Scene();
scene.add(earth);
/**
* 光源设置
*/
// 平行光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);

// width和height用来设置Three.js输出Canvas画布尺寸,同时用来辅助设置相机渲染范围
var width = window.innerWidth; //窗口文档显示区的宽度
var height = window.innerHeight; //窗口文档显示区的高度
/**
* 相机设置
*/
var k = width / height; //Three.js输出的Cnavas画布宽高比
var s = 200; //控制相机渲染空间左右上下渲染范围,s越大,相机渲染范围越大
//THREE.OrthographicCamera()创建一个正投影相机对象
// -s * k, s * k, s, -s, 1, 1000定义了一个长方体渲染空间,渲染空间外的模型不会被渲染
var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
camera.position.set(200, 300, 200); //相机在Three.js坐标系中的位置
camera.lookAt(0, 0, 0); //相机指向Three.js坐标系原点
/**
 * 创建渲染器对象
 */
var renderer = new THREE.WebGLRenderer({
  antialias: true, //开启锯齿
});
renderer.setPixelRatio(window.devicePixelRatio);//设置设备像素比率,防止Canvas画布输出模糊。
renderer.setSize(width, height); //设置渲染区域尺寸
// renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
// renderer.domElement表示Three.js渲染结果,也就是一个HTML元素(Canvas画布)
// document.body.appendChild(renderer.domElement); //body元素中插入canvas对象

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

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


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

export { scene, renderer,camera}

将创建好的3d模型加入到场景中便大功告成了。

喜欢