07.three官方示例+编辑器+AI快速学习webgl_buffergeometry_attributes_integer

本实例主要讲解内容

这个Three.js示例展示了WebGL 2环境下的整数属性渲染技术。通过创建大量随机分布的三角形,并为每个三角形分配不同的整数索引,实现了基于索引动态选择纹理的效果。

核心技术包括:

  • WebGL 2环境下的整数属性支持
  • 顶点着色器与片段着色器中的整数变量传递
  • 多纹理动态切换
  • 几何体与材质的自定义着色器实现

在这里插入图片描述

完整代码注释

<!DOCTYPE html>
<html lang="en"><head><title>three.js WebGL 2 - buffergeometry - integer attributes</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 2 - buffergeometry - integer attributes</div><script type="importmap">{"imports": {"three": "../build/three.module.js","three/addons/": "./jsm/"}}</script><script type="module">import * as THREE from 'three';let camera, scene, renderer, mesh;init();function init() {// 初始化相机camera = new THREE.PerspectiveCamera( 27, window.innerWidth / window.innerHeight, 1, 3500 );camera.position.z = 2500;// 初始化场景scene = new THREE.Scene();scene.background = new THREE.Color( 0x050505 );scene.fog = new THREE.Fog( 0x050505, 2000, 3500 );// 创建几何体const triangles = 10000; // 三角形数量const geometry = new THREE.BufferGeometry();// 存储顶点位置、UV坐标和纹理索引const positions = [];const uvs = [];const textureIndices = [];// 三角形分布范围和大小const n = 800, n2 = n / 2; // 三角形分布的立方体范围const d = 50, d2 = d / 2; // 单个三角形的大小// 生成随机三角形for ( let i = 0; i < triangles; i ++ ) {// 随机位置const x = Math.random() * n - n2;const y = Math.random() * n - n2;const z = Math.random() * n - n2;// 三角形的三个顶点const ax = x + Math.random() * d - d2;const ay = y + Math.random() * d - d2;const az = z + Math.random() * d - d2;const bx = x + Math.random() * d - d2;const by = y + Math.random() * d - d2;const bz = z + Math.random() * d - d2;const cx = x + Math.random() * d - d2;const cy = y + Math.random() * d - d2;const cz = z + Math.random() * d - d2;// 添加顶点位置positions.push( ax, ay, az );positions.push( bx, by, bz );positions.push( cx, cy, cz );// 添加UV坐标uvs.push( 0, 0 );uvs.push( 0.5, 1 );uvs.push( 1, 0 );// 添加纹理索引(0,1,2 循环)const t = i % 3;textureIndices.push( t, t, t );}// 设置几何体属性geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) );geometry.setAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) );geometry.setAttribute( 'textureIndex', new THREE.Int16BufferAttribute( textureIndices, 1 ) );geometry.attributes.textureIndex.gpuType = THREE.IntType; // 指定GPU使用整数类型geometry.computeBoundingSphere(); // 计算边界球体// 加载纹理const loader = new THREE.TextureLoader();const map1 = loader.load( 'textures/crate.gif' );const map2 = loader.load( 'textures/floors/FloorsCheckerboard_S_Diffuse.jpg' );const map3 = loader.load( 'textures/terrain/grasslight-big.jpg' );// 创建自定义着色器材质const material = new THREE.ShaderMaterial( {uniforms: {uTextures: {value: [ map1, map2, map3 ] // 纹理数组}},vertexShader: /* glsl */`in int textureIndex; // 从几何体传入的纹理索引(整数)flat out int vIndex; // "flat" 表示不进行插值(整数属性必须)out vec2 vUv; // UV坐标void main()	{vIndex = textureIndex;vUv = uv;gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );}`,fragmentShader: /* glsl */`flat in int vIndex; // 从顶点着色器传入的纹理索引in vec2 vUv; // UV坐标uniform sampler2D uTextures[ 3 ]; // 纹理数组out vec4 outColor; // 输出颜色void main()	{// 根据索引选择不同的纹理if ( vIndex == 0 ) outColor = texture( uTextures[ 0 ], vUv );else if ( vIndex == 1 ) outColor = texture( uTextures[ 1 ], vUv );else if ( vIndex == 2 ) outColor = texture( uTextures[ 2 ], vUv );}`,side: THREE.DoubleSide, // 双面渲染glslVersion: THREE.GLSL3 // 使用GLSL 3.0} );// 创建网格并添加到场景mesh = new THREE.Mesh( geometry, material );scene.add( mesh );// 初始化渲染器(必须支持WebGL 2)renderer = new THREE.WebGLRenderer( { antialias: true } );renderer.setPixelRatio( window.devicePixelRatio );renderer.setSize( window.innerWidth, window.innerHeight );renderer.setAnimationLoop( animate );document.body.appendChild( renderer.domElement );}// 动画循环function animate() {const time = Date.now() * 0.001;// 旋转网格mesh.rotation.x = time * 0.25;mesh.rotation.y = time * 0.5;renderer.render( scene, camera );}</script></body>
</html>

WebGL 2整数属性技术解析

WebGL 2与整数属性

WebGL 2相比WebGL 1提供了更强大的功能,包括对整数数据类型的直接支持:

  1. 整数顶点属性:WebGL 2允许在顶点着色器中使用整数类型的属性,这在WebGL 1中是受限的
  2. 更高的精度:支持16位和32位整数,提供更精确的数据表示
  3. 更高效的数据传输:整数数据可以更高效地从CPU传输到GPU
  4. 简化的着色器逻辑:避免了在WebGL 1中需要将整数编码为浮点数的复杂操作

在本示例中,我们使用了Int16BufferAttributeTHREE.IntType来定义和指定整数属性。

顶点着色器与片段着色器通信

在着色器编程中,数据从顶点着色器传递到片段着色器需要特别注意:

  1. 插值行为:默认情况下,顶点着色器输出的变量会在光栅化阶段进行插值,这对于浮点数是合适的,但对于整数会导致错误
  2. flat限定符:使用flat限定符可以禁止插值,确保每个片段接收到的是顶点的原始整数值
  3. 数据类型匹配:顶点着色器和片段着色器中的变量类型必须严格匹配

在本示例中,我们使用了flat out int vIndexflat in int vIndex来确保整数数据正确传递。

多纹理动态选择

本示例展示了如何基于整数属性动态选择不同的纹理:

  1. 纹理数组:在着色器中定义uniform sampler2D uTextures[3]来存储多个纹理
  2. 条件判断:在片段着色器中使用if-else语句根据整数索引选择相应的纹理
  3. 高效切换:通过整数索引直接访问纹理数组,避免了使用多个材质的开销

这种技术在需要大量不同纹理的场景中非常有用,比如地形渲染、角色换装系统等。

性能优化考虑

使用整数属性和自定义着色器时,需要注意以下几点:

  1. 数据类型选择:根据实际需求选择合适的整数类型(Byte, Short, Int),避免浪费GPU内存
  2. 批处理:将多个具有相同材质的对象合并为一个,减少Draw Call
  3. 纹理管理:确保纹理尺寸合理,并考虑使用纹理图集(Texture Atlas)减少纹理切换
  4. 着色器复杂度:避免在片段着色器中使用复杂的条件判断,可能影响性能

这种技术适用于需要在单个几何体上应用多种纹理或材质属性的场景,通过减少材质和Draw Call数量来提高渲染性能。

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

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

相关文章

WebSocket:实时通信(如聊天应用)从零到一的深度解析

简介 在现代互联网应用中,实时通信已成为不可或缺的核心功能。从在线聊天到金融数据监控,从协同办公到在线游戏,实时性需求推动了WebSocket技术的广泛应用。本文将从底层协议原理出发,结合企业级开发场景,系统讲解WebSocket的实现机制、实战技巧与优化策略。通过完整的代…

【NLP 困惑度解析和python实现】

**困惑度&#xff08;Perplexity&#xff09;**是自然语言处理和机器学习中常用的评价指标&#xff0c;尤其在评估语言模型时广泛使用。它衡量的是一个概率模型对一个样本&#xff08;如一句话&#xff09;的预测能力。 一、困惑度的定义 对于一个语言模型 $ P $ 和一个测试语…

编程题 02-线性结构3 Reversing Linked List【PAT】

文章目录 题目输入格式输出格式输入样例输出样例 题解解题思路完整代码 编程练习题目集目录 题目 Given a constant K K K and a singly linked list L L L, you are supposed to reverse the links of every K K K elements on L L L. For example, given L being 1 → …

互联网大厂Java求职面试实战:Spring Boot到微服务全景解析

&#x1f4aa;&#x1f3fb; 1. Python基础专栏&#xff0c;基础知识一网打尽&#xff0c;9.9元买不了吃亏&#xff0c;买不了上当。 Python从入门到精通 2. 我的免费工具站&#xff1a; 欢迎访问 https://tools-6wi.pages.dev/ &#x1f601; 3. 毕业设计专栏&#xff0c;毕业…

课程11. 计算机视觉、自编码器和生成对抗网络 (GAN)

计算机视觉、自编码器和生成对抗网络&#xff08;GAN&#xff09; 自动编码器Vanilla自动编码器使用 AE 生成新对象. 变分 AE (VAE)AE 条件 GAN理论示例下载并准备数据GAN模型 额外知识 课程计划&#xff1a; 自动编码器&#xff1a; 自动编码器结构&#xff1b;使用自动编码器…

MarkitDown:AI时代的文档转换利器

在当今AI快速发展的时代,如何高效地将各种格式的文档转换为机器可读的格式,成为了一个迫切需要解决的问题。今天,我们来介绍一款由微软开发的强大工具——MarkitDown,它正是为解决这一问题而生的。 什么是MarkitDown? MarkitDown是一个用Python编写的轻量级工具,专门用…

Python实战案例:打造趣味猜拳小游戏

Python实战案例&#xff1a;猜拳小游戏 文章目录 Python实战案例&#xff1a;猜拳小游戏一、案例背景二、代码实现三、代码解析3.1 执行过程3.2 流程图 四、案例总结1. 核心知识点运用2. 编程思维提升 一、案例背景 猜拳游戏&#xff08;石头剪刀布&#xff09;是一款规则简单…

MCP:重塑AI交互的通用协议,成为智能应用的基础设施

目录: 为什么我们需要一个AI世界的USB-C?MCP的核心架构与工作原理MCP如何解决当前AI生态系统的碎片化问题从代码到实践:构建基于MCP的智能应用MCP的未来:从工具到生态为什么我们需要一个AI世界的USB-C? 还记得在USB-C标准普及之前,我们的数字生活是什么样子吗?抽屉里塞…

如何保证RabbitMQ消息的顺序性?

保证RabbitMQ消息的顺序性是一个常见的需求&#xff0c;尤其是在处理需要严格顺序的消息时。然而&#xff0c;默认情况下&#xff0c;RabbitMQ不保证消息的全局顺序&#xff0c;因为消息可能会通过不同的路径&#xff08;例如不同的网络连接或线程&#xff09;到达队列&#xf…

HTML-2.2 列表--无序列表、有序列表、定义列表

本系列可作为前端学习系列的笔记&#xff0c;代码的运行环境是在HBuilder中&#xff0c;小编会将代码复制下来&#xff0c;大家复制下来就可以练习了&#xff0c;方便大家学习。小编作为新晋码农一枚&#xff0c;会定期整理一些写的比较好的代码&#xff0c;作为自己的学习笔记…

Vuex和Vue的区别

Vue和Vuex有着不同的功能和定位&#xff0c;主要区别如下&#xff1a; 概念与功能 - Vue&#xff1a;是一个构建用户界面的JavaScript框架&#xff0c;专注于视图层的开发&#xff0c;采用组件化的方式构建应用程序&#xff0c;通过数据绑定和指令系统&#xff0c;能方便地…

数据可视化-----子图的绘制及坐标轴的共享

目录 绘制固定区域的子图 &#xff08;一&#xff09;、绘制单子图 subplot()函数 Jupyter Notebook的绘图模式 &#xff08;二&#xff09;、多子图 subplots()--可以在规划好的所有区域中一次绘制多个子图 &#xff08;三&#xff09;、跨行跨列 subplot2grid()---将整…

基于Qt6 + MuPDF在 Arm IMX6ULL运行的PDF浏览器——MuPDF Adapter文档

项目地址&#xff1a;总项目Charliechen114514/CCIMXDesktop: This is a Qt Written Desktop with base GUI Utilities 本子项目地址&#xff1a;CCIMXDesktop/extern_app/pdfReader at main Charliechen114514/CCIMXDesktop 前言 这个部分说的是Mupdf_adaper下的文档的工…

Linux 防火墙 firewalld 实战配置教程!

最近工作上处理了很多关系配置服务器防火墙的操作&#xff0c;于是想写一篇理论与实践并存的文章&#xff0c;在这里分享给大家&#xff0c;希望对您有所帮助&#xff01; 主要包括以下几部分内容&#xff1a; 防火墙概述 firewalld原理框架 与iptables的异同点 firewalld常…

C#发送文件到蓝牙设备

测试环境&#xff1a; visual studio 2022 win11笔记本电脑&#xff0c;具有蓝牙功能 .net6控制台 测试步骤如下&#xff1a; 1 新增名为BluetoothDemo控制台项目 2 通过nuget安装InTheHand.Net.Bluetooth&#xff0c;版本选择4.2.1和安装InTheHand.Net.Obex&#xff0c;版…

初识 Pandas:Python 数据分析的利器

在数据分析、数据清洗和可视化等领域&#xff0c;Python 无疑是最受欢迎的语言之一&#xff0c;而在 Python 的数据处理生态中&#xff0c;Pandas 是最核心、最基础的库之一。如果你接触数据分析、机器学习、金融建模&#xff0c;或者只是想处理一些 Excel 表格&#xff0c;那么…

SpringBoot项目使用POI-TL动态生成Word文档

近期项目工作需要动态生成Word文档的需求&#xff0c;特意调研了动态生成Word的技术方案。主要有以下两种&#xff1a; 第一种是FreeMarker模板来进行填充&#xff1b;第二种是POI-TL技术使用Word模板来进行填充&#xff1b; 以下是关于POI-TL的官方介绍 重点关注&#xff1…

fakeroot 在没有超级用户权限的情况下模拟文件系统的超级用户行为

fakeroot 是一个在 Linux 环境中使用的工具&#xff0c;它允许用户在没有超级用户权限的情况下模拟文件系统的超级用户行为。它是一个在 Linux 环境中广泛使用的工具&#xff0c;通常包含在大多数 Linux 发行版的软件仓库中。‌ 主要功能 ‌模拟 root 权限‌&#xff1a;fake…

Spring Spring Boot 常用注解整理

Spring & Spring Boot 常用注解整理 先理解核心概念&#xff1a;什么是注解&#xff08;Annotation&#xff09;&#xff1f;第一部分&#xff1a;IOC&#xff08;控制反转&#xff09;和 DI&#xff08;依赖注入&#xff09;1. Component2. Service, Repository, Controll…

AIGC与数字媒体实验室解决方案分享

第1部分 概述 1.1 建设目标 1.深度融合AIGC技术&#xff0c;培养能够驾驭新质生产力的数字媒体人才 通过引入前沿的AIGC技术&#xff0c;确保学生能够接触到最先进的人工智能应用。教学内容理论和实践结合&#xff0c;让学生在实际操作中熟练掌握AIGC工具&#xff0c;生成高…