Three.js 学习1: 从文艺复兴到计算机图形学

112 阅读4分钟

自文艺复兴以来,人类掌握了基于透视法原理准确描绘三维世界的绘画技法。这一突破的核心在于将三维空间关系系统地投影到二维平面上。绘画的基础训练强调对几何体(如静物、建筑构件乃至鸡蛋)的结构、比例、光影的观察与表现,并延伸至物体表面属性(材质)和色彩的把握。

计算机图形学(Computer Graphics)正是借鉴了这套源于现实世界观察和艺术实践的高度抽象方法,在虚拟空间中构建了对应的核心概念体系:

  1. 几何体(Geometry) :定义物体的形状。
  2. 材质(Material) :描述物体表面的光学特性(如颜色、光泽度、粗糙度,对应绘画中的固有色、质感),决定其如何与光交互。
  3. 光源(Light) :模拟光照条件(类型、强度、颜色、位置/方向)。
  4. 场景(Scene) :作为容器,组织和管理所有需要在三维空间中呈现的对象(物体、光源等)的层级关系(通常通过类似 Group 的结构实现)。
  5. 相机(Camera) :精确控制观察视角和投影方式(即虚拟的“透视法”或其他投影),定义了从哪个角度、以何种规则将三维场景映射到二维画面。

在Three.js中的实现流程清晰地体现了这一抽象体系:

  1. 定义场景(Scene) :创建场景容器。

  2. 创建对象

    • 组合 几何体(Geometry) (定义形状)和 材质(Material) (定义表面属性)形成 网格(Mesh)  对象。
    • 设置网格对象的空间位置(位置、旋转、缩放)。
  3. 添加光源(Light) :创建并设置光源(如点光源、平行光、环境光等),添加到场景中。

  4. 设置相机(Camera) :创建相机(如透视相机 PerspectiveCamera),设定其位置、朝向和投影参数(如视野FOV、宽高比)。

  5. 渲染:使用 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>