three.js利用点材质打造星空

news2024/9/23 5:24:19

最终效果如图:
在这里插入图片描述

一、THREE.BufferGeometry介绍

这里只是做个简单的介绍,详细的介绍大家可以看看THREE.BufferGeometry及其属性介绍

THREE.BufferGeometryThree.js中的一个重要的类,用于管理和操作几何图形数据。它是对THREE.Geometry的一种更新和改进,通过直接操作二进制数组来提高绘制性能。

在Three.js中,几何图形数据通常存储在顶点属性数组中。传统的THREE.Geometry使用JavaScript数组来存储这些数据,而THREE.BufferGeometry则使用更高效的TypedArray(如Float32Array、Uint16Array等)。

使用THREE.BufferGeometry可以获得更好的性能表现,特别是在处理大量几何数据时。它支持动态更新和批量渲染,可以通过改变数据的方式实现动画效果。此外,通过使用缓冲区对象,可以与WebGL的底层实现更好地集成,从而提高绘制性能。

THREE.BufferGeometry属性包括:位置(position)、法线(normal)、颜色(color)、UV坐标(uv)等。这些属性对应于顶点的各种属性,可以直接操作数据以改变几何图形的形状、颜色等。

在使用THREE.BufferGeometry创建几何图形

首先要创建一个新的THREE.BufferGeometry对象,并为各个属性创建TypedArray。然后,通过设置属性数组的值来定义顶点属性,并将这些属性分配到几何对象的对应属性中。最后,可以将几何对象传递给渲染器进行绘制。

var geometry = new THREE.BufferGeometry();

接下来,可以通过将数据存储在缓冲区中来定义几何体的属性,例如位置(位置矢量)、颜色、法线、纹理坐标等。数据存储在Float32Array、Uint16Array或Uint32Array等类型的缓冲区中,并绑定到BufferAttribute对象上,然后将这些BufferAttribute对象添加到BufferGeometry中。

例如,下面的示例展示了如何创建一个平面几何体:

var positions = new Float32Array([
   -1.0, -1.0,  0.0,
    1.0, -1.0,  0.0,
    1.0,  1.0,  0.0,

    1.0,  1.0,  0.0,
   -1.0,  1.0,  0.0,
   -1.0, -1.0,  0.0
]);

geometry.addAttribute('position', new THREE.BufferAttribute(positions, 3));

在这个例子中,我们创建了一个顶点位置矢量属性,并将其命名为’position’。这些位置数据存储在一个Float32Array类型的缓冲区中,每个矢量有三个分量。然后,我们通过调用addAttribute方法将这个属性添加到BufferGeometry中。

在创建完BufferGeometry后,我们可以将它应用于渲染器中的模型,例如使用THREE.Mesh创建一个网格对象:

var material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
var mesh = new THREE.Mesh(geometry, material);

这样,我们就创建了一个使用BufferGeometry的平面网格对象。

THREE.BufferGeometry是Three.js中用于管理和操作几何图形数据的强大工具,通过使用二进制数组和TypedArray来提供更高的绘制性能和灵活性。它在处理大规模几何数据和实现动画效果方面具有很大的优势

二、创建星云效果

如和使用three.js创建和渲染场景这里就不在详细介绍,下面就说一下实现星云效果的核心步骤

核心步骤如下:

1.使用BufferGeometry创建几何体

const particlesGeometry = new THREE.BufferGeometry();
const count = 5000;

// 设置缓冲区数组
const positions = new Float32Array(count * 3);
// 设置粒子顶点颜色
const colors = new Float32Array(count * 3);
// 设置顶点
for (let i = 0; i < count * 3; i++) {
  positions[i] = (Math.random() - 0.5) * 50; // 设置顶点的位置
  colors[i] = Math.random();
}
particlesGeometry.setAttribute(
  "position",
  new THREE.BufferAttribute(positions, 3)
);
particlesGeometry.setAttribute("color", new THREE.BufferAttribute(colors, 3));

2. 使用pointsMaterial 创建点材质

// 设置点材质
const pointsMaterial = new THREE.PointsMaterial();
// pointsMaterial.size = 0.9;
pointsMaterial.color.set(0xfff000);
// 相机深度而衰减
pointsMaterial.sizeAttenuation = true;

// 载入纹理
const textureLoader = new THREE.TextureLoader();
const texture = textureLoader.load("./textures/particles/4.png");
// 设置点材质纹理
pointsMaterial.map = texture;
pointsMaterial.alphaMap = texture;
pointsMaterial.transparent = true;
pointsMaterial.depthWrite = false;
pointsMaterial.blending = THREE.AdditiveBlending;
// 设置启动顶点颜色
pointsMaterial.vertexColors = true;

3. 使用Points创建点物体

const points = new THREE.Points(particlesGeometry, pointsMaterial);
scene.add(points);

4. 完整代码如下:

import * as THREE from "three";
// 导入轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
// 导入动画库
import gsap from "gsap";
// 导入dat.gui
import * as dat from "dat.gui";

// 目标:使用pointes设置随机顶点打造星河

const gui = new dat.GUI();
// 1、创建场景
const scene = new THREE.Scene();

// 2、创建相机
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
);

// 设置相机位置
camera.position.set(0, 0, 10);
scene.add(camera);

const particlesGeometry = new THREE.BufferGeometry();
const count = 5000;

// 设置缓冲区数组
const positions = new Float32Array(count * 3);
// 设置粒子顶点颜色
const colors = new Float32Array(count * 3);
// 设置顶点
for (let i = 0; i < count * 3; i++) {
  positions[i] = (Math.random() - 0.5) * 50; // 设置顶点的位置
  colors[i] = Math.random();
}
particlesGeometry.setAttribute(
  "position",
  new THREE.BufferAttribute(positions, 3)
);
particlesGeometry.setAttribute("color", new THREE.BufferAttribute(colors, 3));

// 设置点材质
const pointsMaterial = new THREE.PointsMaterial();
// pointsMaterial.size = 0.9;
pointsMaterial.color.set(0xfff000);
// 相机深度而衰减
pointsMaterial.sizeAttenuation = true;

// 载入纹理
const textureLoader = new THREE.TextureLoader();
const texture = textureLoader.load("./textures/particles/4.png");
// 设置点材质纹理
pointsMaterial.map = texture;
pointsMaterial.alphaMap = texture;
pointsMaterial.transparent = true;
pointsMaterial.depthWrite = false;
pointsMaterial.blending = THREE.AdditiveBlending;
// 设置启动顶点颜色
pointsMaterial.vertexColors = true;

const points = new THREE.Points(particlesGeometry, pointsMaterial);

scene.add(points);

// 初始化渲染器
const renderer = new THREE.WebGLRenderer();
// 设置渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight);
// 开启场景中的阴影贴图
renderer.shadowMap.enabled = true;
renderer.physicallyCorrectLights = true;

// 将webgl渲染的canvas内容添加到body
document.body.appendChild(renderer.domElement);

// 创建轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);
// 设置控制器阻尼,让控制器更有真实效果,必须在动画循环里调用.update()。
controls.enableDamping = true;

// 设置时钟
const clock = new THREE.Clock();

function render() {
  let time = clock.getElapsedTime();
  controls.update();
  renderer.render(scene, camera);
  //   渲染下一帧的时候就会调用render函数
  requestAnimationFrame(render);
}

render();

// 监听画面变化,更新渲染画面
window.addEventListener("resize", () => {
  // 更新摄像头
  camera.aspect = window.innerWidth / window.innerHeight;
  //   更新摄像机的投影矩阵
  camera.updateProjectionMatrix();

  //   更新渲染器
  renderer.setSize(window.innerWidth, window.innerHeight);
  //   设置渲染器的像素比
  renderer.setPixelRatio(window.devicePixelRatio);
});

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/708090.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

leetcode 226. 翻转二叉树

2023.7.1 这题依旧可以用层序遍历的思路来做。 在层序遍历的代码上将所有节点的左右节点进行互换即可实现二叉树的反转。 下面上代码&#xff1a; class Solution { public:TreeNode* invertTree(TreeNode* root) {queue<TreeNode*> que;if(root nullptr) return{};que…

gradio库中的Dropdown模块:创建交互式下拉菜单

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

2020年全国硕士研究生入学统一考试管理类专业学位联考逻辑试题——纯享题目版

&#x1f3e0;个人主页&#xff1a;fo安方的博客✨ &#x1f482;个人简历&#xff1a;大家好&#xff0c;我是fo安方&#xff0c;考取过HCIE Cloud Computing、CCIE Security、CISP等证书。&#x1f433; &#x1f495;兴趣爱好&#xff1a;b站天天刷&#xff0c;题目常常看&a…

编译原理期末复习简记(更新中~)

注意&#xff1a;该复习简记只是针对我校期末该课程复习纲要进行的&#xff0c;仅供参考 第一章 引论 编译程序是什么&#xff1f; 编译程序是一个涉及分析和综合的复杂系统 编译程序组成 编译程序通常由以下内容组成 词法分析器 输入 组成源程序的字符串输出 记号/单词序列语法…

Jenkins+Gitlab+Springboot项目部署Jar和image两种方式

Springboot环境准备 利用spring官网快速创建springboot项目。 添加一个controller package com.example.demo;import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;RestController public class…

新华三眼中的AI天路

ChatGPT的火爆&#xff0c;在全球范围内掀起了新一轮的AI风暴。如今&#xff0c;各行各业都在讨论AI&#xff0c;各个国家都在密集进行新一轮的AI基础设施建设与技术投入。 但眼前的盛景并非突然到来&#xff0c;就拿这一轮大模型热潮来说&#xff0c;谷歌早在2018年底就发布了…

协议速攻 IIC协议详解

介绍 IIC是一种 同步 半双工 串行 总线 同步 指的是同一根时钟线(SCL) 半双工 可以进行双向通信&#xff0c;但是收发不能同时进行&#xff0c;发的时候禁止接收&#xff0c;接的时候禁止发送 串行 数据是一位一位发送的 总线 两根线(SCL SDA)可以接多个IIC类型器件&#…

《统计学习方法》——逻辑斯蒂回归和最大熵模型

参考资料&#xff1a; 《统计学习方法》李航通俗理解信息熵 - 知乎 (zhihu.com)拉格朗日函数为什么要先最大化&#xff1f; - 知乎 (zhihu.com) 1 逻辑斯蒂回归 1.1 逻辑斯蒂回归 输入 x ( x ( 1 ) , x ( 2 ) , ⋯ , x ( n ) , 1 ) T x(x^{(1)},x^{(2)},\cdots,x^{(n)},1…

【动态规划算法练习】day11

文章目录 一、1312. 让字符串成为回文串的最少插入次数1.题目简介2.解题思路3.代码4.运行结果 二、1143. 最长公共子序列1.题目简介2.解题思路3.代码4.运行结果 三、1035. 不相交的线1.题目简介2.解题思路3.代码4.运行结果 总结 一、1312. 让字符串成为回文串的最少插入次数 1…

DevOps系列文章之 设计一个简单的DevOps系统

前置条件 gitlab gitlab-runner k8s docker 1. gitlab创建群组 创建群组的好处是,对项目进行分组,群组内的资源可以共享,这里创建了一个tibos的群组 2. 在群组创建一个项目 这里创建一个空白项目,项目名为Gourd.Test,将项目克隆到本地,然后在该目录下创建一个.net core3.1的w…

Spring Cloud Alibaba Seata源码分析

目录 一、Seata源码分析 1、Seata源码入口 1.1、2.0.0.RELEASE 1.2、2.2.6.RELEASE 2、Seata源码分析-2PC核心源码 3、Seata源码分析-数据源代理 3.1、数据源代理DataSourceProxy 4、Seata源码分析- Seata服务端&#xff08;TC&#xff09;源码 一、Seata源码分析 Sea…

P1dB、IIP3、OIP3、IMD定义及关系

P1dB 1分贝压缩输出功率。放大器有一个线性动态范围&#xff0c;在这个范围内&#xff0c;放大器的输出功率随输入功率线性增加。随着输入功率的继续增加&#xff0c;放大器进入非线性区&#xff0c;其输出功率不再随输入功率的增加而线性增加&#xff0c;也就是说&#xff0c;…

【新星计划·2023】Linux文件权限讲解

作者&#xff1a;Insist-- 个人主页&#xff1a;insist--个人主页 作者会持续更新网络知识和python基础知识&#xff0c;期待你的关注 前言 这篇文章&#xff0c;将带你详细的了解一下 Linux 系统里面有哪些重要的文件&#xff1f;。 不过&#xff0c;每个文件都有相当多的属性…

ROS学习篇之传感器(二)IMU(超核IMU HI266)

文章目录 一.确定IMU型号二.安装驱动1.找到驱动的包2.解压该压缩包3.安装步骤说明4.具体安装5.检查IMU的usb接口是否插到电脑 三.在RVIZ中的显示1.复制示例下的src里的文件复制到自己的src下2.自己的文件目录3.尝试编译一下4.示例的文件说明5.运行Demo6.配置Rviz 四.查看IMU的实…

【深入了解系统性能优化】「实战技术专题」全方面带你透彻探索服务优化技术方案(系统服务调优)

全方面带你透彻探索服务优化技术方案&#xff08;服务器系统性能调优&#xff09; 调优意义计划分析 流程相关分析优化分析Nginx请求服务日志将请求热度最高的接口进行优化异步调用优化方式注意要点 分析调用链路追踪体系建立切面操作分析性能和数据统计存储相关的调用以及耗时…

Pycharm中画图警告:MatplotlibDeprecationWarning

前言&#xff1a; \textcolor{Green}{前言&#xff1a;} 前言&#xff1a; &#x1f49e;这是由于在python中画图出现的问题&#xff0c;一般不会有错。因为它只是个警告&#xff0c;但是我们也可以知道解决这个问题的方法&#xff0c;防止后面出问题的时候知道怎么解决。 前因…

窗口函数 OVER(PARTITION BY ...)

开窗函数的语法结构&#xff1a;分析函数() over(partition by 分组列名 order by 排序列名 rows between 开始位置 and 结束位置) over()函数中包括三个函数&#xff1a;分区partition by 列名、排序order by 列名、指定窗口范围rows between 开始位置 and 结束位置 rows bet…

Win10共享文件|文件夹 电脑之间快速传输文件的方法

一、设置共享的文件或文件夹 1、A电脑上的文件要共享 进行如下设置&#xff1a; 右击要共享的就文件或文件夹->属性->"共享 "选项卡->"共享"按扭->选择共享的用户 下拉选择"Everyone"->单击"添加"按扭->根据需要设…

PVE8.0内核构建支持IOMMU拆分

PVE直通SATA控制器给群晖的时候&#xff0c;发现网卡、USB、SATA控制器都在一个IOMMU上。 直通完了&#xff0c;PVE直接失联了。这肯定不行。百度了一下说是要编译内核把IOMMU拆开。下面记录一下编译内核的过程。 准备编译环境 我直接用pve物理机编译&#xff0c;怕破坏环境的…

【Spring/Java项目】如何利用swagger-parser解析yaml中的api请求类型、注释、接口名等等(含示例代码)

手打不易&#xff0c;如果转摘&#xff0c;请注明出处&#xff01; 注明原文&#xff1a;https://zhangxiaofan.blog.csdn.net/article/details/129167371 目录 前言 官方文档 项目配置 示例代码 测试文件 解析代码 运行结果 前言 用到这个工具是因为项目需要&#xff0…