自文艺复兴以来,人类掌握了基于透视法原理准确描绘三维世界的绘画技法。这一突破的核心在于将三维空间关系系统地投影到二维平面上。绘画的基础训练强调对几何体(如静物、建筑构件乃至鸡蛋)的结构、比例、光影的观察与表现,并延伸至物体表面属性(材质)和色彩的把握。
计算机图形学(Computer Graphics)正是借鉴了这套源于现实世界观察和艺术实践的高度抽象方法,在虚拟空间中构建了对应的核心概念体系:
- 几何体(Geometry) :定义物体的形状。
- 材质(Material) :描述物体表面的光学特性(如颜色、光泽度、粗糙度,对应绘画中的固有色、质感),决定其如何与光交互。
- 光源(Light) :模拟光照条件(类型、强度、颜色、位置/方向)。
- 场景(Scene) :作为容器,组织和管理所有需要在三维空间中呈现的对象(物体、光源等)的层级关系(通常通过类似
Group的结构实现)。 - 相机(Camera) :精确控制观察视角和投影方式(即虚拟的“透视法”或其他投影),定义了从哪个角度、以何种规则将三维场景映射到二维画面。
在Three.js中的实现流程清晰地体现了这一抽象体系:
-
定义场景(Scene) :创建场景容器。
-
创建对象:
- 组合 几何体(Geometry) (定义形状)和 材质(Material) (定义表面属性)形成 网格(Mesh) 对象。
- 设置网格对象的空间位置(位置、旋转、缩放)。
-
添加光源(Light) :创建并设置光源(如点光源、平行光、环境光等),添加到场景中。
-
设置相机(Camera) :创建相机(如透视相机
PerspectiveCamera),设定其位置、朝向和投影参数(如视野FOV、宽高比)。 -
渲染:使用 WebGL渲染器(WebGLRenderer) ,调用其
render(scene, camera)方法。渲染器执行核心流程:依据相机设定的视角和投影规则,计算场景中所有对象(受几何体、材质、光源共同作用)最终在二维屏幕上的呈现,生成符合视觉规律的图像。通常将此渲染调用置于动画循环中,以实现动态场景。
代码示例:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>文艺复兴透视法到3D计算机图形学</title>
<style>
body { margin: 0; overflow: hidden; }
canvas { display: block; }
</style>
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/three@0.132.2/build/three.min.js"></script>
<script>
// ============= 1. 定义场景(Scene)容器 =============
const scene = new THREE.Scene();
scene.background = new THREE.Color(0xaaaaaa); // 设置场景背景色
// ============= 2. 创建网格对象(Geometry + Material = Mesh) =============
// 几何体(Geometry) - 定义物体形状(立方体)
const geometry = new THREE.BoxGeometry(1, 1, 1);
// 材质(Material) - 定义表面光学特性(红色漫反射材质)
const material = new THREE.MeshLambertMaterial({
color: 0xff3300, // 固有色(对应绘画中的色彩)
roughness: 0.5 // 粗糙度(对应绘画中的质感)
});
// 组合几何体和材质创建网格对象
const cube = new THREE.Mesh(geometry, material);
// 设置空间位置(透视法中的空间关系)
cube.position.set(0, 0.5, 0); // 位置(X,Y,Z)
cube.rotation.y = Math.PI / 4; // 旋转
scene.add(cube); // 将对象添加到场景
// ============= 3. 添加光源(Light) =============
// 环境光(全局照明)
const ambientLight = new THREE.AmbientLight(0xffffff, 0.4);
scene.add(ambientLight);
// 方向光(模拟太阳光)
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
directionalLight.position.set(3, 5, 2); // 光源位置
directionalLight.castShadow = true; // 启用阴影
scene.add(directionalLight);
// ============= 4. 设置相机(Camera) =============
// 创建透视相机(模拟人眼视角)
const camera = new THREE.PerspectiveCamera(
45, // 视野FOV(Field of View)
window.innerWidth / window.innerHeight, // 宽高比
0.1, // 近裁剪面
100 // 远裁剪面
);
camera.position.set(3, 2, 4); // 相机空间位置
camera.lookAt(0, 0, 0); // 注视场景中心
// ============= 5. 渲染器配置与渲染循环 =============
// 创建WebGL渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true; // 启用阴影映射
document.body.appendChild(renderer.domElement);
// 响应窗口变化
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
// 渲染循环(动画帧回调)
function animate() {
requestAnimationFrame(animate);
// 动态效果:旋转立方体(展示三维空间关系)
cube.rotation.x += 0.01;
cube.rotation.y += 0.005;
// 核心渲染操作(将3D场景投影到2D画布)
renderer.render(scene, camera); // 执行透视投影
}
animate();
</script>
<!-- 理论说明标签 -->
<div style="position:absolute; top:20px; left:20px; background:rgba(0,0,0,0.7); color:white; padding:15px; max-width:500px; border-radius:8px;">
<h3>从文艺复兴到计算机图形学</h3>
<p>1. <b>场景(Scene)</b>: 三维世界容器 | 2. <b>几何体(Geometry)</b>: 立方体形状</p>
<p>3. <b>材质(Material)</b>: 红色粗糙表面 | 4. <b>光源(Light)</b>: 方向光+环境光</p>
<p>5. <b>相机(Camera)</b>: 透视投影(FOV:45°) | 6. <b>渲染器</b>: 执行投影计算</p>
</div>
</body>
</html>