首页 > 其他分享 >MarsCode赋能Three.js:如何轻松实现3D模型点云效果

MarsCode赋能Three.js:如何轻松实现3D模型点云效果

时间:2024-12-23 10:31:08浏览次数:9  
标签:1.0 tempPosition THREE Three MarsCode 点云 new const

前言

点云技术正成为三维视觉开发的热门方向,而 MarsCode 作为强大的交互逻辑工具,与 Three.js 的采样器结合,为复杂点云效果的实现提供了高效解决方案。本文将重点展示如何借助 MarsCode 快速实现动物点云效果,解析其在数据处理与渲染中的核心作用,为开发者打开点云艺术的新思路。文章末尾会放源码地址

项目预览:

一. 项目初始化

使用html/css/js 模版

在这里插入图片描述

项目初始化详情(默认安装了vite),点击顶部运行按钮或使用命令行npm run start即可启动项目

在这里插入图片描述

安装项目依赖, package.json概览

{
  "name": "web-test",
  "version": "1.0.0",
  "description": "",
  "scripts": {
    "start": "vite --host --port=8000"
  },
  "devDependencies": {
    "vite": "^5.2.12",
    "vite-plugin-full-reload": "^1.1.0"
  },
  "dependencies": {
    "three": "0.163.0"
  }
}

二. 代码实现

1. threejs初始化配置

初始化场景、相机、渲染器和控制器,代码较为基础,不多赘述

import * as THREE from 'three';
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader.js';
import { MeshSurfaceSampler } from 'three/examples/jsm/math/MeshSurfaceSampler.js';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';

const scene = new THREE.Scene();

const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

const control = new OrbitControls(
    camera,
    renderer.domElement,
);

2. 模型加载

  • 本文使用模型为obj格式,所以使用OBJLoader加载模型资源
  • 使用MeshSurfaceSampler初始化模型采样器
  • 使用采样器的sample方法提取点坐标并存储,方便后续点云绘制
// 添加模型
function addModel() {
    new OBJLoader().load(
        '/models/Elephant.obj',
        (obj) => {
            const model = obj.children[0];
            model.material = new THREE.MeshBasicMaterial({
                wireframe: true,
                color: new THREE.Color('#7264B5'),
                transparent: true,
                opacity: 5,
            });
            sampler = new MeshSurfaceSampler(model).build();

            const tempPosition = new THREE.Vector3();
            // 采样点坐标存储
            for (let i = 0; i < particleNums; i++) {
                sampler.sample(tempPosition);
                vertices.push(tempPosition.x, tempPosition.y, tempPosition.z);
            }
            addParticle(vertices);
        }
    );
}

3. 点云绘制

通过上述采样器获取的点坐标利用BufferGeometry绘制点云。

// 点云绘制
function addParticle(vertices) {
    let colors = [];
    const palette = [
        new THREE.Color('#88C9B9'), // 青绿色
        new THREE.Color('#673AB7'), // 深紫色
        new THREE.Color('#009688'), // 深绿色
        new THREE.Color('#9C27B0'), // 深紫色
        new THREE.Color('#FFC107'), // 深橙色
        new THREE.Color('#03A9F4'), // 深蓝色
        new THREE.Color('#4CAF50'), // 深绿色
        new THREE.Color('#FF5722'), // 深橙色
    ];
    const pointGeometry = new THREE.BufferGeometry();
    for (let i = 0; i < particleNums; i++) {
        const color = palette[Math.floor(Math.random() * palette.length)];
        colors.push(color.r, color.g, color.b);
    }
    pointGeometry.setAttribute(
        'color',
        new THREE.Float32BufferAttribute(colors, 3),
    );
    pointGeometry.setAttribute(
        'position',
        new THREE.Float32BufferAttribute(vertices, 3),
    );
    const pointMaterial = new THREE.PointsMaterial({
        size: 0.1,
        alphaTest: 0.2,
        vertexColors: true,
    });
    const particles = new THREE.Points(pointGeometry, pointMaterial);
    scene.add(particles);
}
3.1 详解BufferGeometry

BufferGeometry的核心属性是attributes中的position,uv和color

在这里插入图片描述

  • position:存储三角面坐标,存储方式为Float32Array,相对于普通的数组读写效率会优秀很多

例如创建一个简单的矩形,我们需要俩个三角面,每个三角面需要三个点坐标,一个矩形由两个三角面构成所以需要六个点坐标。

const vertices= new Float32Array( [ 
    -1.0, -1.0, 1.0, 
    -1.0, 1.0, 1.0, 
    1.0, 1.0, 1.0, 

    1.0, 1.0, -1.0, 
    1.0, 1.0, -1.0,
    -1.0, 1.0,  1.0 
] ); 
// itemSize = 3 因为每个顶点都是一个三元组。 
geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );

ps:观察仔细的同学应该能发现其实有俩个点是重复共用的,这个时候可以通过设置索引缓冲区来共用顶点,从而降低顶点数量的生成,优化渲染效率。

geometry.setIndex(new THREE.BufferAttribute(indices, 1));
  • uv:定义纹理坐标,大致同上,不过纹理uv坐标是俩俩一组
  • color:颜色数组,注意点数量会和position保持一致,每三个一组,position中是xyz,而color中是rgb,和position一一对应关系

4. 绘制点云之间的连线

通过采样器选取一个初始点,随机选取和初始点距离不超过30的点绘制两点之间的连线,直至没有孤立点

// 添加线条
function addLines() {
    if (sampler) {
        const tempPosition = new THREE.Vector3();
        const first = previousPoint ? previousPoint.clone() : new THREE.Vector3();
        const lineGeometry = new THREE.BufferGeometry();
        const lineMaterial = new THREE.LineBasicMaterial({
            color: new THREE.Color("#808080"),
            opacity: 0.5,
        });
        let line = new THREE.Line(lineGeometry, lineMaterial);
        !previousPoint && sampler.sample(first);
        previousPoint = first.clone();
        let pointFound = false;
        while (!pointFound) {
            sampler.sample(tempPosition);
            if (tempPosition.distanceTo(previousPoint) < 30) {
                lineGeometry.setAttribute(
                    'position',
                    new THREE.Float32BufferAttribute(
                        [
                            first.x, first.y, first.z,
                            tempPosition.x, tempPosition.y, tempPosition.z
                        ],
                        3,
                    ),
                );
                previousPoint = tempPosition.clone();
                pointFound = true;
            }
        }
        scene.add(line);
    }
}

此时我发现我的代码好像缺少点注释, 于是就问了下豆包MarcodeAI

const particleNums = 15000; 
const vertices = []; 
let sampler = null; 
let previousPoint; 
let lineIndex = 0; 
let angle = 0; 

回答的很不错,对代码的理解很充分,专有名称也能很好的解释出来,很棒

标签:1.0,tempPosition,THREE,Three,MarsCode,点云,new,const
From: https://blog.csdn.net/jexplorex/article/details/144614139

相关文章

  • 三维测量与建模笔记 - 7.2 点云滤波
        逐点计算法向量,需要对每一个点拟合出它的切平面,一般使用邻域点信息来查找切平面。    选取要计算的点和它周围一定范围内的点可以拟合出一个平面,最基本的方法是通过最小二乘法取对这些点到平面的距离进行优化(计算量很大)。可以通过计算协方差矩阵来实现......
  • 豆包MarsCode:小U的数字插入问题
    问题描述问题分析问题的核心是找到将数字b插入到数字a的某个位置后,使形成的数字尽可能大。需要仔细分析以下几个要点:1.分析数字的特性输入的两个数字:a是一个正整数(例如76543)。b是一个非负整数(例如4)。目标:将b插入a的某个位置后,获得最大的数字。2.数......
  • Three.js资源-模型下载网站
    在使用Three.js进行3D开发时,拥有丰富的模型资源库可以大大提升开发效率和作品质量。以下是一些推荐的Three.js模型下载网站,它们提供了各种类型的3D模型,适合不同项目需求。无论你是需要逼真的建筑模型,还是简单的几何体,这些网站都能满足你的需求。1.Sketchfab简介:S......
  • ThreeJs-07操控物体实现家具编辑器
    本章节实现效果,通过gui快速添加场景,家具,并且可以快速设置家具实现一个编辑器效果一.基础设置与物体添加列表用之前做过的一个案例来改首先不要这个模型,然后换个背景颜色,并且添加一个网格辅助器1.1添加场景先往事件对象里面添加一个函数,到时候点击就会调用这个函数,而这个......
  • ThreeBody
    给时光以生命,给岁月以文明。你的无畏来源于无知。我们都是阴沟里的虫子,但总还是得有人仰望星空。弱小和无知不是生存的障碍,傲慢才是。碑是那么小,与其说是为了纪念,更像是为了忘却。记忆是一条早已干涸的河流,只在毫无生气的河床中剩下零落的砾石。我爱你,与你有何相干?毁灭你,又......
  • 【基于激光点云的目标检测】Ubuntu-Linux | 激光点云
    #本文是记录学习使用激光雷达相关的内容,其中是参考下面这篇博客无人驾驶汽车系统入门(二十四)——激光雷达的地面-非地面分割和pcl_ros实践_地面分割:无人驾驶汽车系统入门(二十四)-CSDN博客#一、激光雷达信号处理1、点云处理(1)点云预处理        由于点云的数据集......
  • Three.js案例-360全景房看
    在360°看房功能中,我们需要在浏览器中创建一个类似虚拟现实的场景,使得用户能够查看环境的每一个角落。这一功能的实现本质上是利用球体映射技术,即通过将全景图作为纹理贴图映射到一个反向的球体上,用户可以通过旋转视角来“环顾四周”。我们先来看一下效果![file](Maximumupl......
  • marscode | AI如何成为普通开发者的第一生产力
    前言白驹过隙,而立之年,毕业时扬言立于技术之巅的梦想觉得越来越远。以前的学习是针对于某一方向/语言不同知识点的学习,能想象到的就是,成为一个集前后端开发于一体的开发者。那时候我对AI的认知,仅仅是类似基于数据深度学习、回归预测以及NLP之类的概念,再加上后来的TensorFlo......
  • Threejs教程,2024全新系统threejs入门教程
    Threejs教程,2024全新系统threejs入门教程https://www.bilibili.com/video/BV1Zm421g7oi/?spm_id_from=333.999.0.02401-theejs三要素WebGL顶点数据顶点索引矩阵三要素场景Scene容器相机Camera观察渲染器Renderer组合透视相机(PerspectiveCamera)http://www.we......
  • 豆包 MarsCode 寒假青训营重磅来袭,与你共创技术未来!
    你是否正在寻找一个快速提升编程能力的机会?是否希望在AI时代中抓住新兴技术的核心技能?豆包MarsCode青训营为你提供一场从入门到实战的技术狂欢。青训营是什么?这是一个面向高校学生和初入职场技术人的AI编程训练营。在这里,你不仅能学习到Web前端开发的核心知识,还能接......