这里我用的版本是threejs 130,在学习某个东西的时候,我更倾向于在一个个简单的示例中来进行代码的解读,了解各个API方法的运转关联,最后根据自己的需求来进行自由组合。
import * as THREE from 'three'
export default class index extends Component {
componentDidMount(){
/**
* 创建场景对象Scene
*/
const scene = new THREE.Scene();
/**
* 创建网格模型
*/
//var geometry = new THREE.SphereGeometry(80, 80, 80); //创建一个球体几何对象
const geometry = new THREE.BoxGeometry(100, 100, 100); //创建一个立方体几何对象Geometry
const material = new THREE.MeshLambertMaterial({
color: 0x0000ff
}); //材质对象Material
const mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
scene.add(mesh); //网格模型添加到场景中
/**
* 光源设置
*/
//点光源
const point = new THREE.PointLight(0xffffff);
point.position.set(400, 200, 300); //点光源位置
scene.add(point); //点光源添加到场景中
//环境光
const ambient = new THREE.AmbientLight(0x444444);
scene.add(ambient);
// console.log(scene)
// console.log(scene.children)
/**
* 相机设置
*/
const width = window.innerWidth; //窗口宽度
const height = window.innerHeight; //窗口高度
const k = width / height; //窗口宽高比
const s = 200; //三维场景显示范围控制系数,系数越大,显示的范围越大
//创建相机对象
const camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
camera.position.set(200, 300, 200); //设置相机位置
camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
/**
* 创建渲染器对象
*/
const renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);//设置渲染区域尺寸
renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
document.getElementById("test").appendChild(renderer.domElement); //添加容器
//执行渲染操作 指定场景、相机作为参数
renderer.render(scene, camera);
}
render() {
return (
<div>
<div id="test"/>//添加div容器
</div>
)
}
}
此时,我们就完成了一个简单蓝色立方体的创建,效果如下图
我们做了什么?
首先,我们先分开梳理一下,我们声明了一个场景,一个相机,以及环境光。
代码对应如下
//场景初始化
const scene = new THREE.Scene();
//环境光
const ambient = new THREE.AmbientLight(0x444444);
scene.add(ambient);
//相机需要的参数
const width = window.innerWidth; //窗口宽度
const height = window.innerHeight; //窗口高度
const k = width / height; //窗口宽高比
const s = 200; //三维场景显示范围控制系数,系数越大,显示的范围越大
//创建相机对象
const camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
camera.position.set(200, 300, 200); //设置相机位置
camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
按照我个人的理解来解释就是,我们首先创建了一个空的世界(Scene),此外我们知道人类看见物品取决于光对于物品的光反射,所以我们创建了环境光(理解成太阳光),最后创建相机,你可以理解为我们观察这个三维世界的眼睛,然后我们将其放在我们满意的位置,但是此时这个世界空空如也,所以我们为其加上一些东西。
添加正方体的代码如下
const geometry = new THREE.BoxGeometry(100, 100, 100); //创建一个立方体几何对象Geometry
const material = new THREE.MeshLambertMaterial({
color: 0x0000ff
}); //材质对象Material
const mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
scene.add(mesh); //网格模型添加到场景中
在threejs中,这些三维物体我们称为网格对象,网格对象由材质和和几何体组成,通俗一点讲,就像是我们创建了一个正方体模具,然后用普通材料来制作它,你也可以使用金属材质或者别的材质,也可以用shaderMaterial来写着色器代码创造自定义的材质。当我们确定好形状和材料后,我们成功制作出这个正方体网格,最后将其添加到场景中。
最后,当我们准备好了这一切,我们来将其渲染到我们的dom节点中,对应的代码如下
/**
* 创建渲染器对象
*/
const renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);//设置渲染区域尺寸
renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
document.getElementById("test").appendChild(renderer.domElement); //添加容器
//执行渲染操作 指定场景、相机作为参数
renderer.render(scene, camera);
我们的三维世界之路,就此迈出第一步
在上面的基础上,我们进行一点小小的改进
//将上面的最后一段渲染函数
renderer.render(scene, camera);
//改为
function render() {
renderer.render(scene,camera);//执行渲染操作
mesh.rotateY(0.01);//每次绕y轴旋转0.01弧度
requestAnimationFrame(render);//请求再次执行渲染函数render,渲染下一帧
}
render();
此时我们可以观察到,网格模型在随着Y轴缓慢旋转,如果觉得不够清晰,我们可以添加坐标轴来观察
// AxesHelper( size : Number ) size为轴线的大小
const axesHelper = new THREE.AxesHelper(1000);
scene.add(axesHelper);
效果如下
此时,我们对这个场景依然只能在摄像头的固定角度进行观察,我们引入一个控件OrbitControls.js
具体代码如下
//第一行引入对应的包
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls'
///
//创建控件对象 相机对象camera作为参数 控件可以监听鼠标的变化,改变相机对象的属性
var controls = new THREE.OrbitControls(camera);
//监听鼠标事件,触发渲染函数,更新canvas画布渲染效果
controls.addEventListener('change', render);
此时,我们就可以对整个场景进行缩放和旋转了