three.js之Geometry顶点、颜色数据与三角面

专栏目录请点击

简介

  1. Geometry与BufferGeometry表达的含义相同,只是对象的结构不同
  2. three.js渲染的时候会先把Geometry转化为BufferGeometry在解析几何体顶点数据进行渲染

顶点

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>源码对应电子书:百度"three.js 郭隆邦"</title>
    <style>
        body {
            margin: 0;
            overflow: hidden;
            /* 隐藏body窗口区域滚动条 */
        }
    </style>
    <!--引入three.js三维引擎-->
    <script src="http://www.yanhuangxueyuan.com/versions/threejsR92/build/three.js"></script>
    <!-- 引入threejs扩展控件OrbitControls.js -->
    <script src="http://www.yanhuangxueyuan.com/versions/threejsR92/examples/js/controls/OrbitControls.js"></script>
</head>

<body>
    <script>
        /**
         * 创建场景对象Scene
         */
        var scene = new THREE.Scene();
        /**
         * 创建网格模型
         */
        var geometry = new THREE.Geometry(); //声明一个几何体对象Geometry

        var p1 = new THREE.Vector3(50, 0, 0); //顶点1坐标
        var p2 = new THREE.Vector3(0, 70, 0); //顶点2坐标
        var p3 = new THREE.Vector3(80, 70, 0); //顶点3坐标
        //顶点坐标添加到geometry对象
        geometry.vertices.push(p1, p2, p3);

        //材质对象
        var material = new THREE.LineBasicMaterial({
            color: 0xffff00
        });
        //线条模型对象
        var line = new THREE.Line(geometry, material);
        scene.add(line); //线条对象添加到场景中


        // 辅助坐标系
        var AxesHelper = new THREE.AxesHelper(250);
        scene.add(AxesHelper);
        /**
         * 光源设置
         */
        //点光源
        var point = new THREE.PointLight(0xffffff);
        point.position.set(400, 200, 300); //点光源位置
        scene.add(point); //点光源添加到场景中
        //环境光
        var ambient = new THREE.AmbientLight(0x444444);
        scene.add(ambient);
        /**
         * 相机设置
         */
        var width = window.innerWidth; //窗口宽度
        var height = window.innerHeight; //窗口高度
        var k = width / height; //窗口宽高比
        var s = 150; //三维场景显示范围控制系数,系数越大,显示的范围越大
        //创建相机对象
        var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
        camera.position.set(200, 300, 200); //设置相机位置
        camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
        /**
         * 创建渲染器对象
         */
        var renderer = new THREE.WebGLRenderer();
        renderer.setSize(width, height); //设置渲染区域尺寸
        renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
        document.body.appendChild(renderer.domElement); //body元素中插入canvas对象

        // 渲染函数
        function render() {
            renderer.render(scene, camera); //执行渲染操作
        }
        render();
        //创建控件对象  相机对象camera作为参数   控件可以监听鼠标的变化,改变相机对象的属性
        var controls = new THREE.OrbitControls(camera, renderer.domElement);
        //监听鼠标事件,触发渲染函数,更新canvas画布渲染效果
        controls.addEventListener('change', render);
    </script>
</body>

</html>

他渲染出来的是这个样子

在这里插入图片描述

对于代码的解释

  1. 我们定义了一个集合体
var geometry = new THREE.Geometry();
  1. 然后,我们设置了顶点,使用Vector3,定义了顶点
    1. Vector3对象表示一个顶点的xyz坐标,顶点的法线向量
    2. 几何体Geometry的顶点属性geometry.vertices和缓冲几何体属性BufferGeometry.attributes.position是对应的
var p1 = new THREE.Vector3(50, 0, 0); //顶点1坐标
var p2 = new THREE.Vector3(0, 70, 0); //顶点2坐标
var p3 = new THREE.Vector3(80, 70, 0); //顶点3坐标
//顶点坐标添加到geometry对象
geometry.vertices.push(p1, p2, p3);

颜色

我们以上面的代码为基础,加上以下代码

// Color对象表示顶点颜色数据
var color1 = new THREE.Color(0x00ff00); //顶点1颜色——绿色
var color2 = new THREE.Color(0xff0000); //顶点2颜色——红色
var color3 = new THREE.Color(0x0000ff); //顶点3颜色——蓝色
//顶点颜色数据添加到geometry对象
geometry.colors.push(color1, color2, color3);

//材质对象
var material = new THREE.LineBasicMaterial({
    // color: 0xffff00
    vertexColors: THREE.VertexColors, //以顶点颜色为准
});

渲染结果

在这里插入图片描述

对于代码的解释

  1. 我们通过Color可以定义几何体顶点颜色数据,Geometry的颜色属性为geometry.colors
    • 这与缓冲几何体BufferGeometry.attributes.color是等价的
  2. 需要注意的是几何体Geometry顶点颜色属性geometry.colors,对于网格模型Mesh是无效的,对于点、线模型有效

三角面

几何体Geometry的三角面属性geometry.faces和缓冲类型几何体BufferGeometry顶点索引属性BufferGeometry.index相同,用来组织网络模型三角形的绘制

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>源码对应电子书:百度"three.js 郭隆邦"</title>
    <style>
        body {
            margin: 0;
            overflow: hidden;
            /* 隐藏body窗口区域滚动条 */
        }
    </style>
    <!--引入three.js三维引擎-->
    <script src="http://www.yanhuangxueyuan.com/versions/threejsR92/build/three.js"></script>
    <!-- 引入threejs扩展控件OrbitControls.js -->
    <script src="http://www.yanhuangxueyuan.com/versions/threejsR92/examples/js/controls/OrbitControls.js"></script>
</head>

<body>
    <script>
        /**
         * 创建场景对象Scene
         */
        var scene = new THREE.Scene();
        /**
         * 创建网格模型
         */
        var geometry = new THREE.Geometry(); //声明一个几何体对象Geometry

        var p1 = new THREE.Vector3(0, 0, 0); //顶点1坐标
        var p2 = new THREE.Vector3(0, 100, 0); //顶点2坐标
        var p3 = new THREE.Vector3(50, 0, 0); //顶点3坐标
        var p4 = new THREE.Vector3(0, 0, 100); //顶点4坐标
        //顶点坐标添加到geometry对象
        geometry.vertices.push(p1, p2, p3, p4);

        // Face3构造函数创建一个三角面
        var face1 = new THREE.Face3(0, 1, 2);
        //三角面每个顶点的法向量
        var n1 = new THREE.Vector3(0, 0, -1); //三角面Face1顶点1的法向量
        var n2 = new THREE.Vector3(0, 0, -1); //三角面2Face2顶点2的法向量
        var n3 = new THREE.Vector3(0, 0, -1); //三角面3Face3顶点3的法向量
        // 设置三角面Face3三个顶点的法向量
        face1.vertexNormals.push(n1, n2, n3);

        // 三角面2
        var face2 = new THREE.Face3(0, 2, 3);
        // 设置三角面法向量
        face2.normal = new THREE.Vector3(0, -1, 0);

        //三角面face1、face2添加到几何体中
        geometry.faces.push(face1, face2);

        //材质对象
        var material = new THREE.MeshLambertMaterial({
            color: 0xffff00,
            side: THREE.DoubleSide//两面可见
        });
        //网格模型对象
        var mesh = new THREE.Mesh(geometry, material);
        scene.add(mesh); //网格模型对象添加到场景中

        // 辅助坐标系
        var AxesHelper = new THREE.AxesHelper(250);
        scene.add(AxesHelper);
        /**
         * 光源设置
         */
        //点光源
        var point = new THREE.PointLight(0xffffff);
        point.position.set(400, 200, 300); //点光源位置
        scene.add(point); //点光源添加到场景中
        //环境光
        var ambient = new THREE.AmbientLight(0x444444);
        scene.add(ambient);
        /**
         * 相机设置
         */
        var width = window.innerWidth; //窗口宽度
        var height = window.innerHeight; //窗口高度
        var k = width / height; //窗口宽高比
        var s = 150; //三维场景显示范围控制系数,系数越大,显示的范围越大
        //创建相机对象
        var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
        camera.position.set(200, 300, 200); //设置相机位置
        camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
        /**
         * 创建渲染器对象
         */
        var renderer = new THREE.WebGLRenderer();
        renderer.setSize(width, height); //设置渲染区域尺寸
        renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
        document.body.appendChild(renderer.domElement); //body元素中插入canvas对象

        // 渲染函数
        function render() {
            renderer.render(scene, camera); //执行渲染操作
        }
        render();
        //创建控件对象  相机对象camera作为参数   控件可以监听鼠标的变化,改变相机对象的属性
        var controls = new THREE.OrbitControls(camera, renderer.domElement);
        //监听鼠标事件,触发渲染函数,更新canvas画布渲染效果
        controls.addEventListener('change', render);
    </script>
</body>

</html>

上面代码的展示效果如下
在这里插入图片描述

  1. 结合我们上面讲的复用顶点数据,我们会发现,设置两个三角形,我们用了四个顶点
var p1 = new THREE.Vector3(0, 0, 0); //顶点1坐标
var p2 = new THREE.Vector3(0, 100, 0); //顶点2坐标
var p3 = new THREE.Vector3(50, 0, 0); //顶点3坐标
var p4 = new THREE.Vector3(0, 0, 100); //顶点4坐标
geometry.vertices.push(p1, p2, p3,p4);
  1. 然后我们使用这四个顶点来绘制三角形的面,他所表示的是数组中下标0,1,2组成一个三角形,索引0,2,3构成一个三角形
var face1 = new THREE.Face3(0, 1, 2);
var face2 = new THREE.Face3(0, 2, 3);
  1. 法线设置,无论网络模型还是几何体模型本质上都是由一个个的三角形组成,所以我们可以通过设置三角形的法线方向向量来表示几何体表面各个位置的法线方向向量,一般设置法线方向向量有两种方式
    1. 一种是直接定义三角面的法线向量
// 三角面2
var face2 = new THREE.Face3(0, 2, 3);
// 设置三角面法向量
face2.normal=new THREE.Vector3(0, -1, 0);
2. 一种是定义三角形三个顶点的法线方向数据来表示法线方向
// Face3构造函数创建一个三角面
var face1 = new THREE.Face3(0, 1, 2);
//三角面每个顶点的法向量
var n1 = new THREE.Vector3(0, 0, -1); //三角面Face1顶点1的法向量
var n2 = new THREE.Vector3(0, 0, -1); //三角面2Face2顶点2的法向量
var n3 = new THREE.Vector3(0, 0, -1); //三角面3Face3顶点3的法向量
// 设置三角面Face3三个顶点的法向量
face1.vertexNormals.push(n1,n2,n3);
  1. 进行三角形颜色设置,这里我们没有设置这个属性
// 三角形1颜色
face1.color = new THREE.Color(0xffff00);
// 设置三角面face1三个顶点的颜色
face1.color = new THREE.Color(0xff00ff);

或者,我们可以设置三个顶点的颜色

face1.vertexColors = [
  new THREE.Color(0xffff00),
  new THREE.Color(0xff00ff),
  new THREE.Color(0x00ffff),
]

使用顶点数据的时候,注意设置材质的属性vertexColors属性值为THREE.VertexColors

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
three.js是一个用于创建和显示3D图形的JavaScript库。要显示三角网格,你可以按照以下步骤进行操作: 1. 首先,确保你已经引入了three.js库文件,并创建一个场景(scene)、相机(camera)和渲染器(renderer)。 2. 创建一个几何体(geometry)来定义三角网格的形状。你可以使用`THREE.Geometry()`来创建一个空的几何体,然后使用`geometry.vertices.push()`方法添加顶点坐标,使用`geometry.faces.push()`方法添加三角的索引。 3. 创建一个材质(material)来定义三角网格的外观。你可以使用`THREE.MeshBasicMaterial`或者其他类型的材质来设置颜色、纹理等属性。 4. 使用几何体和材质创建一个网格(mesh)对象。你可以使用`THREE.Mesh(geometry, material)`来创建一个网格对象。 5. 将网格对象添加到场景中,使用`scene.add(mesh)`方法。 6. 设置相机的位置和方向,以便正确观察场景中的三角网格。 7. 渲染场景,使用`renderer.render(scene, camera)`方法将场景渲染到屏幕上。 下是一个简单的示例代码,展示了如何使用three.js显示一个三角网格: ```javascript // 创建场景、相机和渲染器 var scene = new THREE.Scene(); var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); var renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // 创建几何体 var geometry = new THREE.Geometry(); geometry.vertices.push( new THREE.Vector3(-1, -1, 0), new THREE.Vector3(1, -1, 0), new THREE.Vector3(0, 1, 0) ); geometry.faces.push(new THREE.Face3(0, 1, 2)); // 创建材质 var material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); // 创建网格对象 var mesh = new THREE.Mesh(geometry, material); // 将网格对象添加到场景中 scene.add(mesh); // 设置相机位置和方向 camera.position.z = 5; // 渲染场景 function animate() { requestAnimationFrame(animate); renderer.render(scene, camera); } animate(); ``` 这是一个简单的示例,你可以根据自己的需求进行修改和扩展。希望对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值