WEB 3D技术 three.js 线框几何体

2024-01-09 23:40:51

本文 我们说一下 线框几何体

想将一个几何体 以线框形式展现 threeJS中 有两种类可以实现
第一种 WireframeGeometry
在这里插入图片描述
这种几何体 其实就类似于 将材质中的 wireframe 开启 这种方法 之前我们也用过

还有一种 就是 EdgesGeometry 边缘几何体
在这里插入图片描述
我们先将代码写成这样

import './style.css'
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";

//创建相机
const camera = new THREE.PerspectiveCamera(
    45, //视角 视角越大  能看到的范围就越大
    window.innerWidth / window.innerHeight,//相机的宽高比  一般和画布一样大最好
    0.1,
    1000
);
const scene = new THREE.Scene();
const gltfLoader = new GLTFLoader();
gltfLoader.load(
  "/gltf/scene.gltf",
  (gltf) => {
    gltf.scene.traverse((child) => {
      if (child.isMesh) {
        child.frustumCulled = false;
        child.castShadow = true;
        child.material.emissive = child.material.color;
        child.material.emissiveMap = child.material.map;
      }
    });
    scene.add(gltf.scene);
  }
);

//c创建一个canvas容器  并追加到 body上
const renderer = new THREE.WebGLRenderer(0);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

//设置相机位置   这里 我们设置Z轴  大家可以试试  S Y 和 Z  都是可以的
camera.position.z = 5;
//设置相机默认看向哪里   三个 0  代表 默认看向原点
camera.lookAt(0, 0, 0);
//将内容渲染到元素上
renderer.render(scene, camera);
const controls = new OrbitControls(camera, renderer.domElement);

function animate() {
    controls.update();
    requestAnimationFrame(animate);
    /*cube.rotation.x += 0.01;
    cube.rotation.y += 0.01;*/
    renderer.render(scene, camera);
}
animate();

gltf/scene.gltf 是我项目中的一个 gltf 3D资源文件
在这里插入图片描述
现在 我希望用边缘几何体 将这个3D元素 拆解显示
那么 先这样改一下

const gltfLoader = new GLTFLoader();
gltfLoader.load(
  "/gltf/scene.gltf",
  (gltf) => {
    gltf.scene.traverse((child) => {
      if (child.isMesh) {
        child.frustumCulled = false;
        child.castShadow = true;
        child.material.emissive = child.material.color;
        child.material.emissiveMap = child.material.map;
        let geometry = child.geometry;
        let edgesGeometry = new THREE.EdgesGeometry(geometry);
        
      }
    });
    scene.add(gltf.scene);
  }
);

threeJS中 LineSegments 可以生成线段
在这里插入图片描述
但是 现在 我们需要先用 LineBasicMaterial 创建一个线段的材质
在这里插入图片描述
整个复制 然后 我们只需要里面的 color 颜色属性
在这里插入图片描述
都弄好之后 我们就可以通过 LineSegments 生成一个线框几何体 然后将他add到场景中了
整体代码如下

const gltfLoader = new GLTFLoader();
gltfLoader.load(
  "/gltf/scene.gltf",
  (gltf) => {
    gltf.scene.traverse((child) => {
      if (child.isMesh) {
        child.frustumCulled = false;
        child.castShadow = true;
        child.material.emissive = child.material.color;
        child.material.emissiveMap = child.material.map;
        let geometry = child.geometry;
        let edgesGeometry = new THREE.EdgesGeometry(geometry);
        const material = new THREE.LineBasicMaterial( {
            color: 0xffffff
        } );
        let edges = new THREE.LineSegments(edgesGeometry, material);// 添加倒场录
        scene.add(edges);
      }
    });
    scene.add(gltf.scene);
  }
);

但是运行之后 你会发现 两个几何体重合了
在这里插入图片描述
我们这里 可以将这个线框几何体 移动一下
在这里插入图片描述
然后 我们线框几何体就前面去了
在这里插入图片描述
但是 这里 我们明显发现 我们原来的3D元素 是有旋转的 但是线框几何体没有
这边 我们可以通过世界举证 解决这个问题

我们这样写

const gltfLoader = new GLTFLoader();
gltfLoader.load(
  "/gltf/scene.gltf",
  (gltf) => {
    gltf.scene.traverse((child) => {
      if (child.isMesh) {
        child.frustumCulled = false;
        child.castShadow = true;
        child.material.emissive = child.material.color;
        child.material.emissiveMap = child.material.map;
        let geometry = child.geometry;
        let edgesGeometry = new THREE.EdgesGeometry(geometry);
        const material = new THREE.LineBasicMaterial( {
            color: 0xffffff
        } );
        let edges = new THREE.LineSegments(edgesGeometry, material);// 添加倒场录
        child.updateMatrixWorld(true, true);
        edges.matrix.copy(child.matrixWorld);
        edges.matrix.decompose(edges.position, edges.quaternion, edges.scale, edges.rotation);
        scene.add(edges);
      }
    });
    scene.add(gltf.scene);
  }
);

decompose 会同步他们的旋转 位置等属性
但是 我们这里 好像是用顶点旋转做的
在这里插入图片描述
那直接简单粗暴 我们直接也旋转它

在这里插入图片描述
直接改 rotation 属性
在这里插入图片描述
然后 前面也说了 还有一种 WireframeGeometry 线框几何体的方式
直接将

let edgesGeometry = new THREE.EdgesGeometry(geometry);

换成

let edgesGeometry = new THREE.WireframeGeometry(geometry);

因为他也是 可以直接传入原几何体对象 然后生成几何体内容 通过材质 LineSegments
就可以用了的

const gltfLoader = new GLTFLoader();
gltfLoader.load(
  "/gltf/scene.gltf",
  (gltf) => {
    gltf.scene.traverse((child) => {
      if (child.isMesh) {
        child.frustumCulled = false;
        child.castShadow = true;
        child.material.emissive = child.material.color;
        child.material.emissiveMap = child.material.map;
        let geometry = child.geometry;
        const material = new THREE.LineBasicMaterial( {
            color: 0xffffff
        } );
        let edgesGeometry = new THREE.WireframeGeometry(geometry);
        let edges = new THREE.LineSegments(edgesGeometry, material);// 添加倒场录
        child.updateMatrixWorld(true, true);
        edges.matrix.copy(child.matrixWorld);
        edges.matrix.decompose(edges.position, edges.quaternion, edges.scale, edges.rotation);
        scene.add(edges);
      }
    });
    //scene.add(gltf.scene);
  }
);

在这里插入图片描述
这种 看着就会乱很多 因为整体都是 三角形构成的

文章来源:https://blog.csdn.net/weixin_45966674/article/details/135489780
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。