threejs创建指定形状的几何体 - BufferGeometry | 青训营笔记

477 阅读2分钟

这是我参与「第四届青训营 」笔记创作活动的的第6天

image.png
eg.绘制指定位置的三角形
参考连接
郭隆邦技术博客
threejs官网

基础参数介绍

  • 创建缓冲类型的对象geometry
    var geometry = new THREE.BufferGeometry()
  • 定义存储点坐标的数组,pointsData存储三维空间中点的坐标,在这里开辟三倍的空间视为了后续BufferAttribute的参数使用
    let drawResult = new Float32Array(pointsData.length * 3);
  • ...一些列操作,获取drawResult数组
  • THREE.BufferAttribute(drawResult, 3) => 三个为一组,表示顶点坐标(每个定点都是一个三元组)
  • 设置几何体的顶点位置数据
    bgeometry.setAttribute('position', new THREE.BufferAttribute(drawResult, 3));
  • 定义几何形状需要渲染的材质
    color: 材质的颜色
    side: 渲染方式【前面THREE.FrontSide(默认)、后面THREE.BackSide、双面】
    opaicty: 材料的透明度,默认为1,范围为[0.0, 1.0]
    transparent: 定义物体是否透明,默认为false;只有该项为true时,opacity才生效
let material = new THREE.MeshPhongMaterial({
    color: "#919191",
    side: THREE.DoubleSide,
    opacity: 1,//高光部分的颜色
    transparent: true,
});
  • THREE.mesh(geometry: BufferGeometry, material: Material)
let mesh = new THREE.Mesh(bgeometry, material);
mesh.scale.set(1, 1, 1); //缩放
mesh.position.set(0, -240.0, 0); // 位置
scene.add(mesh);

若不采用脚手架,在本地进行直接测试的话,若使用npm安装的注意事项

目录结构

image.png

OrbitControl.js头部修改 => three.js 改为 ./three.module.js

image.png

image.png

开篇三角形实现的html部分

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="modelCanvas" style="height: 800px; width: 800px; position: relative; border: 2px solid black;"></div>
    <script src="./index.js" type="module"></script>
</body>
</html>

开篇三角形实现的js部分

import * as THREE from './three.module.js'
import {OrbitControls} from "./OrbitControls.js";
let scene, camera, renderer, pointLight, ambientLight, control
function initScene() {
    scene = new THREE.Scene()
}

function initCamera() {
    camera = new THREE.PerspectiveCamera(45, modelCanvas.clientWidth / modelCanvas.clientHeight, 0.1, 5000);
    camera.up.set(0, 1, 0);
    camera.position.set(0, 50, 900);
}

function initRenderer() {
    renderer = new THREE.WebGLRenderer({
        powerPreference: "high-performance",
        antialias: true,     //抗锯齿
    });
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(modelCanvas.clientWidth, modelCanvas.clientHeight);
    renderer.setClearColor(0xffffff, 1); //设置背景颜色
    // document.getElementById('modelCanvas').appendChild(renderer.value.domElement)
    modelCanvas.appendChild(renderer.domElement)
}

function initPointLight() {
    pointLight = new THREE.PointLight(0xffffff);
    pointLight.position.set(400, 240, 300); //点光源位置
    pointLight.castShadow = true;
    scene.add(pointLight); //点光源添加到场景中
}

function initAmbientLight() {
    ambientLight = new THREE.AmbientLight(0xa3781b);
    //ambient_light.castShadow = true;
    scene.add(ambientLight);
}

function initControl() {
    control = new OrbitControls(camera, renderer.domElement)
    control.addEventListener("change", () => {
        render()
    });
}

function initMesh() {
    const geometry = new THREE.BufferGeometry();
    // 创建一个简单的矩形. 在这里我们左上和右下顶点被复制了两次。
    // 因为在两个三角面片里,这两个顶点都需要被用到。
    const vertices = new Float32Array( [
        -100.0, -60.0,  100.0,
        100.0, -60.0,  100.0,
        100.0,  60.0,  100.0,

        110.0,  90.0,  100.0,
        -110.0,  50.0,  100.0,
        -110.0, -50.0,  100.0
    ] );

    // itemSize = 3 因为每个顶点都是一个三元组。
    geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
    const material = new THREE.MeshBasicMaterial( { color: 0xff0000, side: THREE.DoubleSide } );
    const mesh = new THREE.Mesh( geometry, material );
    scene.add(mesh)
}

function render() {
    pointLight.position.set(camera.position.x, camera.position.y, camera.position.z);
    renderer.render(scene, camera);
}

function initCanvas() {
    initScene()
    initCamera()
    initRenderer()
    initPointLight()
    initAmbientLight()
    initControl()
    initMesh();

    render()
}
initCanvas();