65.Three.js案例-使用 MeshNormalMaterial 和 MeshDepthMaterial 创建 3D 图形
实现效果
在该案例中,Three.js 被用来创建一个包含多个 3D 对象的场景。其中包括:
- 圆环结(TorusKnot)
- 立方体(Box)
- 球体(Sphere)
这些对象使用 MeshNormalMaterial
来渲染,并且整个场景背景为白色,所有对象位于一个居中的容器中。

知识点
WebGLRenderer (WebGL 渲染器)
构造器
THREE.WebGLRenderer(parameters)
参数 | 类型 | 描述 |
---|---|---|
parameters | Object | 包含渲染器选项的对象 |
常用参数:
antialias
:布尔值,启用抗锯齿以获得更平滑的渲染结果。alpha
:布尔值,是否支持透明背景(默认为黑色)。precision
:字符串,着色器精度 (highp
,mediump
,lowp
)。
方法
setSize(width, height, updateStyle)
设置渲染器的尺寸。
width
:渲染器的宽度(像素)。height
:渲染器的高度(像素)。updateStyle
:是否更新 canvas 的样式尺寸(可选,默认为true
)。
setClearColor(color, opacity)
设置渲染器的清除颜色。
color
:十六进制颜色值或 CSS 字符串表示的颜色。opacity
:透明度(0.0 到 1.0)。
PerspectiveCamera (透视相机)
构造器
THREE.PerspectiveCamera(fov, aspect, near, far)
参数 | 类型 | 描述 |
---|---|---|
fov | Number | 视野角度(单位是度),即垂直视角范围 |
aspect | Number | 渲染区域的宽高比(通常用窗口宽度除以高度) |
near | Number | 近裁剪面(相机视图可见范围的最近距离) |
far | Number | 远裁剪面(相机视图可见范围的最远距离) |
方法
position.set(x, y, z)
设置相机的位置坐标。
lookAt(vector)
让相机朝向指定的三维坐标点。
Scene (场景)
构造器
THREE.Scene()
用于创建一个空的场景对象,之后可以将相机、灯光、几何体等添加到场景中。
属性
overrideMaterial : Material
如果被赋值,则场景中的所有物体都会使用这个材质进行渲染,常用于调试。
translateX(value)
沿 X 轴移动整个场景。
MeshNormalMaterial (法线材质)
构造器
THREE.MeshNormalMaterial(options)
参数 | 类型 | 描述 |
---|---|---|
options | Object | 可选参数对象 |
常见参数:
wireframe
:布尔值,是否显示线框模式。flatShading
:布尔值,是否使用平面着色。visible
:布尔值,控制材质是否可见。
说明:此材质会根据物体表面的法线方向映射成 RGB 颜色,用于调试模型的表面方向。
TorusKnotGeometry (圆环结几何体)
构造器
THREE.TorusKnotGeometry(radius, tube, tubularSegments, radialSegments, p, q)
参数 | 类型 | 描述 |
---|---|---|
radius | Number | 圆环结的主半径 |
tube | Number | 管道的半径 |
tubularSegments | Number | 管道分段数(越高越光滑) |
radialSegments | Number | 径向分段数(越高越光滑) |
p | Number | 扭转因子(控制打结的方式) |
q | Number | 扭曲因子(控制打结的方式) |
BoxGeometry (立方体几何体)
构造器
THREE.BoxGeometry(width, height, depth, widthSegments, heightSegments, depthSegments)
参数 | 类型 | 描述 |
---|---|---|
width | Number | 立方体宽度 |
height | Number | 立方体高度 |
depth | Number | 立方体深度 |
widthSegments | Number | 宽度方向上的分段数 |
heightSegments | Number | 高度方向上的分段数 |
depthSegments | Number | 深度方向上的分段数 |
SphereGeometry (球体几何体)
构造器
THREE.SphereGeometry(radius, widthSegments, heightSegments, phiStart, phiLength, thetaStart, thetaLength)
参数 | 类型 | 描述 |
---|---|---|
radius | Number | 球体半径 |
widthSegments | Number | 经线数量(越高越光滑) |
heightSegments | Number | 纬线数量(越高越光滑) |
phiStart | Number | 起始经度角(弧度) |
phiLength | Number | 经度跨度(弧度) |
thetaStart | Number | 起始纬度角(弧度) |
thetaLength | Number | 纬度跨度(弧度) |
Mesh (网格模型)
构造器
THREE.Mesh(geometry, material)
参数 | 类型 | 描述 |
---|---|---|
geometry | Geometry | 几何体对象 |
material | Material | 材质对象 |
方法
translateX(value)
沿 X 轴方向移动模型。
代码
html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="ThreeJS/three.js"></script>
<script src="ThreeJS/jquery.js"></script>
</head>
<body>
<center id="myContainer"></center>
<script type="text/javascript">
// 创建渲染器并开启抗锯齿
var myRenderer = new THREE.WebGLRenderer({antialias: true});
myRenderer.setSize(window.innerWidth, window.innerHeight);
myRenderer.setClearColor('white', 1.0);
$('#myContainer')[0].appendChild(myRenderer.domElement);
// 创建透视相机
var myCamera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 30, 1000);
myCamera.position.set(-76.03, 30.40, -48.87);
myCamera.lookAt(new THREE.Vector3(0, 0, 0));
// 创建场景
var myScene = new THREE.Scene();
myScene.overrideMaterial = new THREE.MeshDepthMaterial();
myScene.translateX(30);
// 创建法向量材质
var myMaterial = new THREE.MeshNormalMaterial();
// 创建圆环结
var myTorusKnotGeometry = new THREE.TorusKnotGeometry(8, 3, 200, 60);
var myTorusKnotMesh = new THREE.Mesh(myTorusKnotGeometry, myMaterial);
myTorusKnotMesh.translateX(-62);
myScene.add(myTorusKnotMesh);
// 创建立方体
var myBoxGeometry = new THREE.BoxGeometry(20, 20, 20);
var myBoxMesh = new THREE.Mesh(myBoxGeometry, myMaterial);
myBoxMesh.translateX(-20);
myScene.add(myBoxMesh);
// 创建球体
var mySphereGeometry = new THREE.SphereGeometry(20, 60, 60);
var mySphereMesh = new THREE.Mesh(mySphereGeometry, myMaterial);
mySphereMesh.translateX(70);
myScene.add(mySphereMesh);
// 渲染场景
myRenderer.render(myScene, myCamera);
</script>
</body>
</html>