LearnOpenGL学习笔记——实例化

OpenGL 入门 21:实例化 OpenGL 实例化 阅读详情

实例化

假设你有一个绘制了很多模型的场景,而大部分的模型包含的是同一组顶点数据,只不过进行的是不同的世界空间变换。想象一个充满草的场景:每根草都是一个包含几个三角形的小模型。你可能会需要绘制很多根草,最终在每帧中你可能会需要渲染上千或者上万根草。因为每一根草仅仅是由几个三角形构成,渲染几乎是瞬间完成的,但上千个渲染函数调用却会极大地影响性能。如果我们需要渲染大量物体时,代码看起来会像这样:

	for(unsigned int i = 0; i < amount_of_models_to_draw; i++)
	{
    	DoSomePreparations(); // 绑定VAO,绑定纹理,设置uniform等
    	glDrawArrays(GL_TRIANGLES, 0, amount_of_vertices);
	}

如果像这样绘制模型的大量实例(Instance),你很快就会因为绘制调用过多而达到性能瓶颈。与绘制顶点本身相比,使用glDrawArrays或glDrawElements函数告诉GPU去绘制你的顶点数据会消耗更多的性能,因为OpenGL在绘制顶点数据之前需要做很多准备工作(比如告诉GPU该从哪个缓冲读取数据,从哪寻找顶点属性,而且这些都是在相对缓慢的CPU到GPU总线(CPU to GPU Bus)上进行的)。所以,即便渲染顶点非常快,命令GPU去渲染却未必。如果我们能够将数据一次性发送给GPU,然后使用一个绘制函数让OpenGL利用这些数据绘制多个物体,就会更方便了。这就是实例化(Instancing)。实例化这项技术能够让我们使用一个渲染调用来绘制多个物体,来节省每次绘制物体时CPU -> GPU的通信,它只需要一次即可。如果想使用实例化渲染,我们只需要将glDrawArrays和glDrawElements的渲染调用分别改为glDrawArraysInstanced和glDrawElementsInstanced就可以了。这些渲染函数的实例化版本需要一个额外的参数,叫做实例数量(Instance Count),它能够设置我们需要渲染的实例个数。这样我们只需要将必须的数据发送到GPU一次,然后使用一次函数调用告诉GPU它应该如何绘制这些实例。GPU将会直接渲染这些实例,而不用不断地与CPU进行通信。

实例化数组

我们要渲染远超过100个实例的时候(这其实非常普遍),我们最终会超过最大能够发送至着色器的uniform数据大小上限。它的一个代替方案是实例化数组(Instanced Array),它被定义为一个顶点属性(能够让我们储存更多的数据),仅在顶点着色器渲染一个新的实例时才会更新。

	#version 330 core
	layout (location = 0) in vec2 aPos;
	layout (location = 1) in vec3 aColor;
	layout (location = 2) in vec2 aOffset;
	out vec3 fColor;
	void main()
	{
    	gl_Position = vec4(aPos + aOffset, 0.0, 1.0);
    	fColor = aColor;
	}

因为实例化数组和position与color变量一样,都是顶点属性,我们还需要将它的内容存在顶点缓冲对象中,并且配置它的属性指针。我们首先将(上一部分的)translations数组存到一个新的缓冲对象中:

	unsigned int instanceVBO;
	glGenBuffers(1, &instanceVBO);
	glBindBuffer(GL_ARRAY_BUFFER, instanceVBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec2) * 100, &translations[0], GL_STATIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER, 0);

之后我们还需要设置它的顶点属性指针,并启用顶点属性:

	glEnableVertexAttribArray(2);
	glBindBuffer(GL_ARRAY_BUFFER, instanceVBO);
	glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);
	glBindBuffer(GL_ARRAY_BUFFER, 0);   
	glVertexAttribDivisor(2, 1);

这段代码很有意思的地方在于最后一行,我们调用了glVertexAttribDivisor。这个函数告诉了OpenGL该什么时候更新顶点属性的内容至新一组数据。它的第一个参数是需要的顶点属性,第二个参数是属性除数(Attribute Divisor)。默认情况下,属性除数是0,告诉OpenGL我们需要在顶点着色器的每次迭代时更新顶点属性。将它设置为1时,我们告诉OpenGL我们希望在渲染一个新实例的时候更新顶点属性。而设置为2时,我们希望每2个实例更新一次属性,以此类推。我们将属性除数设置为1,是在告诉OpenGL,处于位置值2的顶点属性是一个实例化数组。

知识点总结:

  • 实例化的意义其实是为了减少CPU和GPU的通信,我们一次性将所有的数据发送给GPU
  • 使用glEnableVertexAttribArray绑定实例化数组
  • 使用glVertexAttribDivisor告诉GPU这个是实例化数据

https://learnopengl-cn.github.io/04%20Advanced%20OpenGL/10%20Instancing/#_1

OpenGL学习笔记(十)-几何着色器-实例化 参考网址:LearnOpenGL 中文版 4.7 几何着色器 4.7.1 基本概念 1、顶点和片段着色器之间有一个可选的几何着色器,几何着色器的输入是一个图元(如点或三角形)的一组顶点,顶点发送到下一着色器之前可对它们随意变换,将顶点变换为完全不同的图元,并且还能生成比原来更多的顶点。 #version 330 core layout (points) in; layout (line_strip, max_vertices = 2) out; void main() { gl_Posit 阅读详情

相关推荐

【LearnOpenGL 学习笔记】高级OpenGL

LearnOpenGL 学习笔记 高级OpenGL

weixin_42489848的博客 557

LearnOpenGL学习笔记—高级OpenGL 10:实例化

LearnOpenGL学习笔记—高级OpenGL 10:实例化1 知识:实例化1.1 小练习2 小行星带 本节对应官网学习内容:实例化 1 知识:实例化 假设有一个绘制了很多模型的场景,而大部分的模型包含的是同一组顶点数据,只不过进行的是不同的世界空间变换(比如之前的十个立方体模型)。 也比如是充满草的场景:每根草都是一个包含几个三角形的小模型。 如果需要绘制很多根草,最终在每帧中可能会需要渲染上千或者上万根草。 因为每一根草仅仅是由几个三角形构成,渲染几乎是瞬间完成的,但上千个渲染函数调用却会极大地影响性

清清!的博客 1391

LearnOpenGL——几何着色器、实例化

在顶点着色器和片元着色器之间还有一个可选的几何着色器,几何着色器输入的是一个图元(点或者三角形)的一组顶点,几何着色器可以在片元着色器之前对它们进行随意变化,可以变换为不同的图元,也可以生成更多的顶点。我们需要声明从顶点着色器输入的图元类型——在in前面加一个布局修饰符(如下),如果我们要绘制三角形,就将修饰符修改为triangles,括号内的数字表示的是一个图元所包含的最小顶点数。几何着色器,会接收每一个顶点(包括一个位置向量和一个法向量),并在每个位置向量处绘制一个法线向量。

weixin_70073176的博客 1311

十五、实例化

opengles实现实例化+粒子化实践

zw1996的博客 797

LearnOpenGL CN学习笔记(一)

懒得弄 学习笔记而已

weixin_43839880的博客 1205

OpenGL实例

OpenGL,一个球形,用经度和纬度的形式表示,可以随意改动纹理,看到顶点

OpenGL 实例化

实例化是一种用于一次性渲染多个相同物体(网格)但具有不同属性(如位置、颜色、大小、纹理偏移等)的技术。它是一种极其重要的性能优化手段i < 1000;i++)// 1. 为每个草设置各自的 MVP 矩阵(通过 Uniform)// 2. 绑定纹理、VAO 等// 3. 发起绘制调用 (glDrawArrays/glDrawElements)过多的绘制调用 (Draw Call):每次glDraw*都是一个绘制调用。CPU 需要准备大量数据并发送给 GPU,这个过程本身就有开销。

w2064004678的博客 1062

OpenGL实例代码30例

很适合学习的资料,以及对OPENGL有一些了解的人

【OpenGL】LearnOpenGL学习笔记20 - 实例化 Instancing

LearnOpenGL学习笔记 - 实例化 Instancing

Duo1J的随笔 1260

OpenGL实例化绘制行星带_VS2015.rar

OpenGL实例化绘制行星带_VS2015.rar http://blog.youkuaiyun.com/yulinxx/article/details/53943948

FT601Q芯片深度解析:从USB3.0引脚定义到FPGA FIFO协议实战选型

本文深入解析FT601Q芯片在USB3.0接口设计与FPGA协议栈开发中的应用,详细介绍了USB3.0引脚定义、FT601Q芯片架构、245同步FIFO模式及硬件设计要点,帮助工程师实现高速数据传输系统。

weixin_30607659的博客 447

LearnOpenGL学习(高级OpenGL - - 实例化,抗锯齿)

借助该变量,我们可以改变其位置,渲染方式等。从0开始,当渲染第43个实例时,该变量为42。索引一个包含100个偏移向量的uniform数组,将偏移值加到每个实例化的四边形上。)技术,用一个绘制函数让OpenGL绘制多个物体,而非循环(Drawcall: N->1)。,来节省每次绘制物体时CPU -> GPU的通信,它只需要一次即可。(Instance Count),它能够设置我们需要渲染的实例个数。对于在同一场景中使用相同顶点数据的对象(如草地中的草),可以使用。版本需要一个额外的参数,叫做。

zaizai1007的博客 855

硬件开发实践:高速 PCB 差分信号与时钟同步优化

由两条互补信号线组成(正负极)接收端只关注两线之间电压差共模噪声对两线同时作用,可被抵消。

2501_93174775的博客 394

LearnOpenGL学习笔记2-Shaders

这一节介绍了基本的GLSL语法;着色器的输入与输出;全局变量在着色器的使用;颜色属性的添加;着色器类的封装。

LLLawrenceQ的博客 1875

SAP 第三方销售

第三方销售

yanzibing99的博客 3514

PCA9548实战:从硬件连接到Linux驱动的I2C扩展全解析

本文详细解析了PCA9548 I2C多路复用器从硬件连接到Linux驱动配置的全过程。涵盖硬件引脚连接、电源去耦、地址选择等关键设计要点,以及Linux驱动加载、设备树配置和应用层编程技巧,帮助开发者高效实现I2C总线扩展。

weixin_28726391的博客 410

LearnOpenGL学习笔记—PBR:理论

LearnOpenGL学习笔记—PBR1 理论1.1 引入1.2 微表面模型1.3 能量守恒1.4 反射方程1.4.1 辐射度量学1.4.2 辐射通量(Radiant Flux)1.4.3 立体角(Solid Angle)1.4.4 辐射强度(Radiant Intensity)1.4.5 入射辐照度(Irradiance)1.4.6 出射辐射度(Radiance)1.4.6 概念:双向反射分布函数(Bidirectional ReflectanceDistribution Function,BRDF)1.

清清!的博客 2880

使用MiniExcel.SaveAsByTemplate快速地保存百万数据

该代码展示了如何使用MiniExcel快速生成并导出百万级销售数据。核心方法GenerateLargeData()可生成指定数量的随机销售记录,包含客户名、日期、VIP状态、积分等20个字段。通过随机函数模拟真实数据分布,并支持自定义数据量(默认100万条)。配合Excel模板使用MiniExcel.SaveAsByTemplate()方法,能高效地将大数据量导出为Excel文件,且处理速度极快。代码结构清晰,包含数据生成、随机日期辅助方法和数据模型类,适合需要批量生成测试数据或导出大型报表的场景。

大坡3D软件开发 253

【实践LearnOpenGL项目】高级篇

本文介绍了OpenGL中的四项高级渲染技术:1. 实例化渲染技术,通过glDraw*Instanced实现3万个陨石的高效渲染,避免了循环绘制的性能损耗;2. 离屏抗锯齿技术,通过多重采样帧缓冲和后处理帧缓冲消除图形边缘锯齿;3. 统一缓冲对象(UBO)技术,用于在多个着色器间共享矩阵和光源参数;4. 几何着色器应用,演示了通过几何着色器实现三角形爆炸效果。每种技术都配有核心代码片段和实际效果图,展示了从基础渲染到高级优化的完整解决方案。

qq_37378423的博客 2218

使用MATLAB和Simulink来设计并仿真一个智能家居多传感器数据融合系统

智能家居多传感器数据融合系统旨在通过集成来自多种不同类型的传感器的数据,以提供更精确和可靠的环境信息或用户状态监测。例如,将温度、湿度、光照强度、运动检测等多种传感器的数据结合起来,可以更好地了解家庭内部的状态,并做出相应的调整或响应。在这个教程中,我们将使用MATLAB和Simulink来设计并仿真一个智能家居多传感器数据融合系统。

amy_mhd的博客 189

Agentic AI应用架构师如何提升AI应用的灵活性

可扩展性(Scalability):快速添加新功能或扩展任务范围(如Agent从“客服”扩展到“供应链管理”);可修改性(Modifiability):调整Agent的决策逻辑或动作策略,无需重构整个系统;鲁棒性(Robustness):在环境异常或数据噪声下保持性能稳定;自适应(Self-Adaptation):自主学习新场景,无需人工干预。状态空间(S):Agent能感知的所有内部/外部状态(如用户需求、环境数据);动作空间(A):Agent能执行的所有动作(如调用工具、发送消息);

项目管理的博客 582

LearnOpenGL学习笔记—入门05:Texture

小学期终于结束了,可以回来更新了Orz,总是拖拖拉拉的(瘫 0 前言 本节笔记对应的内容 纹理 在入门01中我们配置好了环境 在入门02中我们可以检测输入并出现一个有颜色的窗口 在入门03中我们初步学习了图形渲染管线,尝试用不同方法画出了三角形和四边形 在入门04(上)中我们学习了shader和GLSL的相关知识,并给图形加上了变换的颜色以及彩色。 在入门04(下)中我们建立自己的shader类,并能够从外部读取shader的内容。 在这一节,我们将会了解有关材质的内容 1 纹理简介 在之前的学习中,我们可

清清!的博客 1867

网络速度的极致:800G & 1.6T 以太网的突破!

你好,这里是网络技术联盟站。在我们进入数据驱动的世界时,以太网的重要性日益突出。从根本上说,以太网是一种连接计算机的技术,旨在形成一个本地网,通过它,设备可以与其他设备进行通信。然而,随着时间的推移,以太网已经发展成为一种全球的数据通信系统,其速度从初始的10Mbit/s发展到现在的800G,甚至1.6T。这种巨大的进步并不是没有挑战的,但每一次的突破都代表了技术的巨大飞跃。本文将探讨800G和1.6T以太网的创新与挑战。

网络技术联盟站 1771

LearnOpenGL学习笔记—入门07:Coordinate Systems

LearnOpenGL学习笔记—入门07:Coordinate Systems0 前言1 坐标系统概述1.1 局部空间1.2 世界空间/模型矩阵1.3 观察空间/观察矩阵1.4 裁剪空间/投影矩阵1.4.1 正射投影1.4.2 透视投影1.5 总结2 代码实现 0 前言 本节笔记对应的内容 坐标系统 在入门01中我们配置好了环境 在入门02中我们可以检测输入并出现一个有颜色的窗口 在入门03中我们初步学习了图形渲染管线,尝试用不同方法画出了三角形和四边形 在入门04(上)中我们学习了shader和GLSL的

清清!的博客 3244

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

[learnOpenGL学习笔记_1] Macbook Pro下搭建learnOpenGL环境

Macbook Pro下搭建learnOpenGL环境 文章目录Macbook Pro下搭建learnOpenGL环境1. 创建一个新的XCode工程2. 搭建learnOpenGL环境2.1 获取GLFW2.2 配置GLAD3. 验证环境,生成一个窗口 learnOpenGL网站是学习openGL非常有用的网站,作为一个小白,为了方便后续回顾同时给大家提供借鉴,在此记录学习的过程。 learn...

同学小张的博客 856

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

LearnOpenGL学习笔记—模型加载02: Mesh

LearnOpenGL学习笔记—模型加载02: Mesh0 前言1 Mesh类1.1 Mesh.h1.2 Mesh.cpp1.2.1 构造函数1.2.2 初始化 0 前言 本节笔记对应官网学习内容:网格 在模型加载01中我们导入了assimp库。 通过使用Assimp,我们可以加载不同的模型到程序中,但是载入后它们都被储存为Assimp的数据结构。 我们最终仍要将这些数据转换为OpenGL能够理解的格式,这样才能渲染这个物体。 我们从上一节中学到,网格(Mesh)代表的是单个的可绘制实体,我们现在先来定义一

清清!的博客 1393

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

上一篇: LearnOpenGL学习笔记——几何着色器
下一篇: LearnOpenGL学习笔记——抗锯齿
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值