`THREE.BufferGeometry` 是 Three.js 中一个强大的类,用于表示几何体数据。

demo案例

在这里插入图片描述

THREE.BufferGeometry 是 Three.js 中一个强大的类,用于表示几何体数据。与传统的 THREE.Geometry 类相比,它使用缓冲区来存储顶点数据,从而在性能上有显著的提升。以下是 THREE.BufferGeometry 的详细说明,包括其输入参数、输出结果、属性和方法。

创建实例

const geometry = new THREE.BufferGeometry();

属性

BufferGeometry 的主要属性有:

  • attributes: 存储几何体顶点属性的对象。例如,顶点位置、法线、颜色等。
  • index: 用于定义顶点索引的属性,可以用于减少顶点重复。
  • groups: 一个数组,用于定义几何体的多个子集。
  • boundingBox: 几何体的轴对齐边界框(THREE.Box3 对象)。
  • boundingSphere: 几何体的边界球(THREE.Sphere 对象)。
  • drawRange: 一个对象,定义绘制的起始点和数量。
  • userData: 一个可用于存储任意数据的对象。

方法

BufferGeometry 提供了丰富的方法,用于操作几何体数据:

  • addAttribute: 添加或更新属性。自 Three.js r125 版本起已废弃,推荐使用 setAttribute

    geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3));
    
  • setIndex: 设置顶点索引。

    geometry.setIndex(indices);
    
  • setAttribute: 添加或更新属性。

    geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3));
    
  • getAttribute: 获取属性。

    const positions = geometry.getAttribute('position');
    
  • deleteAttribute: 删除属性。

    geometry.deleteAttribute('position');
    
  • applyMatrix4: 将几何体应用一个矩阵变换。

    geometry.applyMatrix4(matrix);
    
  • computeBoundingBox: 计算并更新 boundingBox 属性。

    geometry.computeBoundingBox();
    
  • computeBoundingSphere: 计算并更新 boundingSphere 属性。

    geometry.computeBoundingSphere();
    
  • computeVertexNormals: 计算并更新顶点法线。

    geometry.computeVertexNormals();
    
  • normalizeNormals: 规范化法线。

    geometry.normalizeNormals();
    
  • toNonIndexed: 将几何体转换为非索引形式。

    geometry.toNonIndexed();
    
  • clone: 克隆几何体。

    const clonedGeometry = geometry.clone();
    
  • copy: 从另一个几何体复制数据。

    const newGeometry = new THREE.BufferGeometry().copy(geometry);
    
  • dispose: 释放几何体相关的内存。

    geometry.dispose();
    
  • merge: 合并两个几何体。

    geometry.merge(geometry2);
    
  • setDrawRange: 设置绘制范围。

    geometry.setDrawRange(start, count);
    

示例

以下是一个完整示例,展示如何使用 THREE.BufferGeometry 创建一个简单的几何体并将其添加到场景中:

import * as THREE from 'three';

// 创建场景、相机和渲染器
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 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,
   1.0,  1.0, -1.0,
  -1.0,  1.0, -1.0
]);

// 定义顶点索引
const indices = [
  0, 1, 2, 0, 2, 3,
  4, 5, 6, 4, 6, 7,
  0, 1, 5, 0, 5, 4,
  1, 2, 6, 1, 6, 5,
  2, 3, 7, 2, 7, 6,
  3, 0, 4, 3, 4, 7
];

// 创建 BufferGeometry 并设置属性
const geometry = new THREE.BufferGeometry();
geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3));
geometry.setIndex(indices);

// 创建材质和网格
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00, wireframe: true });
const mesh = new THREE.Mesh(geometry, material);

// 将网格添加到场景中
scene.add(mesh);

// 设置相机位置
camera.position.z = 5;

// 渲染循环
function animate() {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
}
animate();

总结

THREE.BufferGeometry 是一个强大的类,允许高效地处理几何体数据。它通过使用缓冲区存储顶点数据,提供了高性能的几何体处理方式。通过其丰富的方法和属性,可以方便地操作和变换几何体数据。

<!DOCTYPE html>
<html lang="en">
	<head>
		<title>three.js webgl - buffer geometry custom attributes - particles</title>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
		<link type="text/css" rel="stylesheet" href="main.css">
	</head>
	<body>
		<div id="container"></div>
		<div id="info"><a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> webgl - buffergeometry custom attributes - particles</div>

		<!-- 顶点着色器 -->
		<script type="x-shader/x-vertex" id="vertexshader">

			attribute float size;

			varying vec3 vColor;

			void main() {

				vColor = color;

				vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );

				gl_PointSize = size * ( 300.0 / -mvPosition.z );

				gl_Position = projectionMatrix * mvPosition;

			}

		</script>

		<!-- 片段着色器 -->
		<script type="x-shader/x-fragment" id="fragmentshader">

			uniform sampler2D pointTexture;

			varying vec3 vColor;

			void main() {

				gl_FragColor = vec4( vColor, 1.0 );

				gl_FragColor = gl_FragColor * texture2D( pointTexture, gl_PointCoord );

			}

		</script>

		<script type="importmap">
			{
				"imports": {
					"three": "../build/three.module.js",
					"three/addons/": "./jsm/"
				}
			}
		</script>

		<script type="module">

			import * as THREE from 'three';
			import Stats from 'three/addons/libs/stats.module.js';

			let renderer, scene, camera, stats;
			let particleSystem, uniforms, geometry;
			const particles = 100000; // 粒子数量

			init(); // 初始化
			animate(); // 动画循环

			function init() {

				// 创建相机
				camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 10000 );
				camera.position.z = 300;

				// 创建场景
				scene = new THREE.Scene();

				// 定义 uniforms 变量
				uniforms = {
					pointTexture: { value: new THREE.TextureLoader().load( 'textures/sprites/spark1.png' ) }
				};

				// 创建着色器材质
				const shaderMaterial = new THREE.ShaderMaterial( {
					uniforms: uniforms,
					vertexShader: document.getElementById( 'vertexshader' ).textContent,
					fragmentShader: document.getElementById( 'fragmentshader' ).textContent,
					blending: THREE.AdditiveBlending,
					depthTest: false,
					transparent: true,
					vertexColors: true
				} );

				const radius = 200; // 粒子分布半径
				geometry = new THREE.BufferGeometry();
				const positions = [];
				const colors = [];
				const sizes = [];
				const color = new THREE.Color();

				for ( let i = 0; i < particles; i ++ ) {

					// 随机生成粒子的位置
					positions.push( ( Math.random() * 2 - 1 ) * radius );
					positions.push( ( Math.random() * 2 - 1 ) * radius );
					positions.push( ( Math.random() * 2 - 1 ) * radius );

					// 设置粒子的颜色
					color.setHSL( i / particles, 1.0, 0.5 );
					colors.push( color.r, color.g, color.b );

					// 设置粒子的初始大小
					sizes.push( 20 );

				}

				// 将属性添加到几何体中
				geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) );
				geometry.setAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) );
				geometry.setAttribute( 'size', new THREE.Float32BufferAttribute( sizes, 1 ).setUsage( THREE.DynamicDrawUsage ) );

				// 创建粒子系统
				particleSystem = new THREE.Points( geometry, shaderMaterial );
				scene.add( particleSystem );

				// 创建渲染器
				renderer = new THREE.WebGLRenderer();
				renderer.setPixelRatio( window.devicePixelRatio );
				renderer.setSize( window.innerWidth, window.innerHeight );

				const container = document.getElementById( 'container' );
				container.appendChild( renderer.domElement );

				// 添加统计信息
				stats = new Stats();
				container.appendChild( stats.dom );

				// 监听窗口大小变化
				window.addEventListener( 'resize', onWindowResize );

			}

			function onWindowResize() {

				// 更新相机和渲染器的尺寸
				camera.aspect = window.innerWidth / window.innerHeight;
				camera.updateProjectionMatrix();
				renderer.setSize( window.innerWidth, window.innerHeight );

			}

			function animate() {

				// 请求下一帧并渲染
				requestAnimationFrame( animate );
				render();
				stats.update();

			}

			function render() {

				const time = Date.now() * 0.005; // 获取当前时间

				particleSystem.rotation.z = 0.01 * time; // 旋转粒子系统

				const sizes = geometry.attributes.size.array;

				// 动态更新粒子大小
				for ( let i = 0; i < particles; i ++ ) {
					sizes[ i ] = 10 * ( 1 + Math.sin( 0.1 * i + time ) );
				}

				geometry.attributes.size.needsUpdate = true; // 标记属性需要更新
				renderer.render( scene, camera ); // 渲染场景

			}

		</script>

</body>
</html>

压图地址

image.png

一个功能强大的图片处理工具,它可以满足用户对于图片压缩、格式转换、质量调节以及长图片分割等多种需求。

【轻松压缩,一键搞定】您的图片处理神器来了!

压图地址

本内容来源于小豆包,想要更多内容请跳转小豆包 》

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-06 20:24:08       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-06 20:24:08       100 阅读
  3. 在Django里面运行非项目文件

    2024-06-06 20:24:08       82 阅读
  4. Python语言-面向对象

    2024-06-06 20:24:08       91 阅读

热门阅读

  1. Ubuntu中安装和配置SSH的完全指南

    2024-06-06 20:24:08       30 阅读
  2. linux实用命令

    2024-06-06 20:24:08       24 阅读
  3. uniapp vue input和textarea 的用法区别,一篇就懂

    2024-06-06 20:24:08       35 阅读
  4. vue2组件封装+elementUI

    2024-06-06 20:24:08       28 阅读
  5. 探索未来科技的前沿:从量子计算到人机融合

    2024-06-06 20:24:08       25 阅读
  6. 一些常用的 ADB(Android Debug Bridge)命令

    2024-06-06 20:24:08       23 阅读
  7. QT窗口类型以及非模态窗口如何显示在顶层

    2024-06-06 20:24:08       26 阅读
  8. Python 变量标签:深入解析其用法与影响

    2024-06-06 20:24:08       29 阅读
  9. AI绘图工具最全汇总--你适合哪一款

    2024-06-06 20:24:08       29 阅读
  10. Go 发送邮件的两种方式

    2024-06-06 20:24:08       28 阅读