OpenGL学习日记-2015.3.13——多实例渲染

实例渲染Instanced Rendering 在此之前红宝书已经介绍了不少关于缓存和绘制的命令,并给出了用同样的顶点绘制几个三角形的例程,但是此前的例程实现起来非常麻烦,每个三角形要指定一次变换矩阵,假如还要更换颜色的话还要增加相应语句。如果想绘制的物体成千上万,这么一一指定管理起来比较混乱,因此,OpenGL给出了一个新的命令类型:实例渲染——Instanced Rendering。 阅读详情
    实例化(instancing)或者多实例渲染(instancd rendering)是一种连续执行多条相同渲染命令的方法。并且每个命令的所产生的渲染结果都会有轻微的差异。是一种非常有效的,实用少量api调用来渲染大量几何体的方法。OpenGL提供多种机制,允许着色器对不同渲染实例赋予不同的顶点属性。

几个简单的多实例渲染命令:

    1、void glDrawArraysInstanced( GLenum mode, GLint first, GLsizei count, GLsizei primCount )
            该函数是glDrawArrays()的多实例版本,参数完全等价,只是多了个primCount,该参数用于设置渲染实例个数。
    2、void glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, void* indices, GLsizei primcount )
            该函数是glDrawElements()的多实例版本,同样只是多了个primCount参数而已,同样是用于设置渲染实例个数。
    3、void glDrawElementsInstancedBaseVertex( GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei instanceCount, GLuint baseVertex )
            该函数是glDrawElementsBaseVertex()的多实例版本,instanceCount表示渲染的实例数目。

多实例渲染顶点属性控制:
    1、void glVertexAttribDivisor( GLenum index, GLuint divisor )
            index对应于着色器中输入变量的location。divisor:表示顶点属性的更新频率,每隔多少个实例将重新设置实例的该属性,例如设置为1,那么每个实例的属性都不一样,设置为2则每两个实例相同,3则每三个实例改变属性。而该属性的属性数组大小将为(instance/divisor),instance为之前设置的渲染实例数(primCount),假设在多实例渲染中改变实例的颜色,设divisor为2,instance为100,颜色数组至少为100/2 = 50组rgba数据,才能保证每个实例都有自己的颜色值,不然将是黑漆漆的。最后如果divisor设置为0,将代表是非实例化,渲染的结果是,所有实例都是黑漆漆的,可能这个黑漆漆的结果也不是必然的,我猜想的是这时候着色器的输入变量vec4 color为默认的(0.0,0.0,0.0,1.0)并没有设置它的值,所以是黑色的。

顶点着色器分析:
#version 410

    //输入变量position,顶点坐标
  layout (location = 0) in vec4 position;
//normal顶点法线计算
  layout (location = 1) in vec3 normal;
//顶点颜色
  layout (location = 2) in vec4 color;

//特别注意,这里设置的mat4类型的输入变量,location为3,但是一个mat4类型会占据连续的4个位置
//因此model_matrix占据了3,4,5,6四个索引位置。
  layout (location = 3) in mat4 model_matrix;

    //在程序渲染过程是常量的视图矩阵,和投影矩阵(just这个程序是常量)
  uniform mat4 view_matrix;
  uniform mat4 projection_matrix;
  
//输入变量,一个简单的结构体,法线,和颜色。
  out VERTEX
  {
      vec3    normal;
      vec4    color;
  } vertex;

  void main(void)
  {
        //计算模型视图矩阵
      mat4 model_view_matrix = view_matrix * model_matrix;
    
        //计算顶点坐标
      gl_Position = projection_matrix * (model_view_matrix * position);
    
    //计算法线和颜色,并输出
      vertex.normal = mat3(model_view_matrix) * normal;
      vertex.color = color;
  }

片元着色器分析:
#version 410

//片元着色器的输出
  layout (location = 0) out vec4 color;

//和顶点着色器几乎一样的片元着色器输入,in/out必须是匹配的。
  in VERTEX
  {
      vec3    normal;
      vec4    color;
  } vertex;

  void main(void)
  {
    //结合法线计算最终的颜色
      color = vertex.color * (0.1 + abs(vertex.normal.z)) + vec4(0.8, 0.9, 0.7, 1.0) * pow(abs(vertex.normal.z), 40.0);
  }

应用程序代码:
代码并没有太多的分析,主要是用了前面几个函数,进行多实例渲染的设置,代码在关键的地方都有或多或少的注释。在这里把尽可能把代码贴全。代码中用到了vbm格式的模型数据,大概是书者自己定义的一种格式,在源代码中vbm管理类历经变迁,新版本还不能读旧版本的数据。
在这里顺便提供第八版源代码的下载地址: http://www.opengl-redbook.com/ 应该可以轻易下到。感谢作者们的辛勤劳动
#include "instancing_1.h"
#include "vutils.h"
#include "vmath.h"
#include "vbm_ch3_intancing1.h"

namespace instancing1
{
	float shade_aspect = 800 / 600;
	GLuint color_buffer;
	GLuint model_matrix_buffer;
	GLuint render_prog;
	GLuint model_matrix_loc;
	GLuint view_matrix_loc;
	GLuint projection_matrix_loc;

	VBObject object;
	#define INSTANCE_COUNT 100

	GLenum gl_err = 0;
	static const GLubyte* errorStr = NULL;
};


using namespace instancing1;

void instancing1Init()
{
	int n;
	
	//创建着色器程序
	render_prog = glCreateProgram();

	//着色器字符串
	static const char render_vs[] =
		"#version 410\n"
		"\n"
		"// 'position' and 'normal' are regular vertex attributes\n"
		"layout (location = 0) in vec4 position;\n"
		"layout (location = 1) in vec3 normal;\n"
		"\n"
		"// Color is a per-instance attribute\n"
		"layout (location = 2) in vec4 color;\n"
		"\n"
		"// model_matrix will be used as a per-instance transformation\n"
		"// matrix. Note that a mat4 consumes 4 consecutive locations, so\n"
		"// this will actually sit in locations, 3, 4, 5, and 6.\n"
		"layout (location = 3) in mat4 model_matrix;\n"
		"\n"
		"// The view matrix and the projection matrix are constant across a draw\n"
		"uniform mat4 view_matrix;\n"
		"uniform mat4 projection_matrix;\n"
		"\n"
		"// The output of the vertex shader (matched to the fragment shader)\n"
		"out VERTEX\n"
		"{\n"
		"    vec3    normal;\n"
		"    vec4    color;\n"
		"} vertex;\n"
		"\n"
		"// Ok, go!\n"
		"void main(void)\n"
		"{\n"
		"    // Construct a model-view matrix from the uniform view matrix\n"
		"    // and the per-instance model matrix.\n"
		"    mat4 model_view_matrix = view_matrix * model_matrix;\n"
		"\n"
		"    // Transform position by the model-view matrix, then by the\n"
		"    // projection matrix.\n"
		"    gl_Position = projection_matrix * (model_view_matrix * position);\n"
		"    // Transform the normal by the upper-left-3x3-submatrix of the\n"
		"    // model-view matrix\n"
		"    vertex.normal = mat3(model_view_matrix) * normal;\n"
		"    // Pass the per-instance color through to the fragment shader.\n"
		"    vertex.color = color;\n"
		"}\n";

	static const char render_fs[] =
		"#version 410\n"
		"\n"
		"layout (location = 0) out vec4 color;\n"
		"\n"
		"in VERTEX\n"
		"{\n"
		"    vec3    normal;\n"
		"    vec4    color;\n"
		"} vertex;\n"
		"\n"
		"void main(void)\n"
		"{\n"
		"    color = vertex.color * (0.1 + abs(vertex.normal.z)) + vec4(0.8, 0.9, 0.7, 1.0) * pow(abs(vertex.normal.z), 40.0);\n"
		"}\n";

	//shader创建,编译,装载
	vglAttachShaderSource( render_prog, GL_VERTEX_SHADER, render_vs );
	vglAttachShaderSource( render_prog, GL_FRAGMENT_SHADER, render_fs );

	//连接着色器成为可用程序
	glLinkProgram(render_prog);
	//激活着色器
	glUseProgram(render_prog);

	//获取视图矩阵位置
	view_matrix_loc = glGetUniformLocation(render_prog, "view_matrix");
	//获取投影矩阵位置
	projection_matrix_loc = glGetUniformLocation(render_prog, "projection_matrix");

	//加载vbm模型文件
	//@pram 1路径、2顶点location 3法线location、4纹理location(颜色)
	object.LoadFromVBM("../8edlib/media/armadillo_low.vbm", 0, 1, 2);

	//绑定顶点数组
	object.BindVertexArray();

	//获取顶点着色器in变量location
	int position_loc = glGetAttribLocation( render_prog, "position" );
	int normal_loc = glGetAttribLocation( render_prog, "normal" );
	int color_loc = glGetAttribLocation( render_prog, "color" );
	int matrix_loc = glGetAttribLocation( render_prog, "model_matrix");

	//每个实例的颜色数组
	vmath::vec4 colors[INSTANCE_COUNT];
	for (n = 0; n < INSTANCE_COUNT; n++ )
	{
		float a = float(n) / 4.0f;
		float b = float(n) / 5.0f;
		float c = float(n) / 6.0f;

		colors[n][0] = 0.5f + 0.25f * (sinf(a + 1.0f) + 1.0f );
		colors[n][1] = 0.5f + 0.25f * (sinf(b + 2.0f) + 1.0f );
		colors[n][2] = 0.5f + 0.25f * (sinf(c + 3.0f) + 1.0f );
		colors[n][3] = 1.0f;
	}

	//缓存对象
	glGenBuffers(1, &color_buffer);
	glBindBuffer(GL_ARRAY_BUFFER, color_buffer);//3个工作。
	glBufferData( GL_ARRAY_BUFFER, sizeof(colors), colors, GL_DYNAMIC_DRAW );//动态改变用于绘制的数据

	glVertexAttribPointer( color_loc, 4, GL_FLOAT, GL_FALSE, 0, NULL );
	glEnableVertexAttribArray( color_loc );

	//!!!启用顶点属性多实例属性,每个实例读取一次颜色值
	glVertexAttribDivisor( color_loc, 1);

	//模型矩阵数据
	glGenBuffers(1, &model_matrix_buffer );
	glBindBuffer( GL_ARRAY_BUFFER, model_matrix_buffer );
	//NULL保留内存
	glBufferData( GL_ARRAY_BUFFER, INSTANCE_COUNT * sizeof(vmath::mat4), NULL, GL_DYNAMIC_DRAW );
	for (int i = 0; i < 4; i++ )
	{
		glVertexAttribPointer(matrix_loc + i, 4, GL_FLOAT, GL_FALSE, sizeof(vmath::mat4), (void *)(sizeof(vmath::vec4)* i));
		glEnableVertexAttribArray( matrix_loc + i );
		glVertexAttribDivisor( matrix_loc + i, 1 );
	}

	//解除vao绑定,至于为什么要这句呢,我的理解是:这是个好习惯,用完之后吧OpenGL还原默认状态。
	glBindVertexArray(0);
}
static inline int min( int a, int b )
{
	return a < b ? a : b;
}

void instancing1Display()
{
	float t = float(GetTickCount() & 0x3FFF) / float(0x3FFF);
	int n;

	//清屏
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

	//
	glEnable( GL_CULL_FACE );
	glEnable( GL_DEPTH_TEST );
	glDepthFunc( GL_LEQUAL );

	//绑定vbo,修改数据
	glBindBuffer( GL_ARRAY_BUFFER, model_matrix_buffer );

	//获取当前vbo的OpenGL指针
	vmath::mat4* matrices = (vmath::mat4*)glMapBuffer( GL_ARRAY_BUFFER, GL_WRITE_ONLY );
	for (n = 0; n < INSTANCE_COUNT; n++ )
	{
		float a = 50.0f * float(n) / 4.0f;
		float b = 50.0f * float(n) / 5.0f;
		float c = 50.0f * float(n) / 6.0f;

		matrices[n] = vmath::rotate(a + t * 360.0f, 1.0f, 0.0f, 0.0f) *
					  vmath::rotate(a + t * 360.0f, 0.0f, 1.0f, 0.0f) *
					  vmath::rotate(a + t * 360.0f, 0.0f, 0.0f, 1.0f) *
					  vmath::translate(10.0f + a, 40.0f + b, 50.0f + c);//平移,再旋转
	}

	//数据操作完毕,解除映射!必须
	glUnmapBuffer( GL_ARRAY_BUFFER );

	//确认激活需要的着色器程序
	glUseProgram( render_prog );

	//生成视图矩阵和投影矩阵
	vmath::mat4 view_matrix(vmath::translate(0.0f, 0.0f, -1500.0f) * vmath::rotate(t * 360.0f * 2.0f, 0.0f, 1.0f, 0.0f));
	vmath::mat4 projection_matrix(vmath::frustum(-1.0f, 1.0f, -shade_aspect, shade_aspect, 1.0f, 5000.0f));

	//设置视图矩阵和投影矩阵
	glUniformMatrix4fv( view_matrix_loc, 1, GL_FALSE, view_matrix );//这次你就没写错参数,能不能不坑爹,之前我都以为自己智商出问题了。
	glUniformMatrix4fv( projection_matrix_loc, 1, GL_FALSE, projection_matrix );

	//渲染多个实例
	object.Render( 0, INSTANCE_COUNT ); //能不能不坑爹。。后面的vbm居然不兼容前面的vbm.....
	GLenum  error = glGetError();//
	const GLubyte* errorStr = gluErrorString(error);
	//这个几个意思。。。lookat只是生成了一个矩阵而已。。。
	//vmath::lookat( vmath::vec3(0.0f, 0.0f, 0.0f), vmath::vec3(1.0f, 0.0f, 0.0f), vmath::vec3(0.0f, 1.0f, 0.0f) ); //摄像机?????????/
}

void instancing1Update(float)
{

}


另一个多实例渲染实例,纹理打包,着色器内置变量gl_InstanceID使用:
实例计数器gl_InstanceID:
当前实例的索引值可以再顶点着色器中通过内置变量gl_InstanceID变量获得。该变量被声明为一个整数,初始为0,每个实例被渲染之后,他会加1.他总是存在于顶点着色器中,即使当前没有启用多实例特性,此时他的值保持0.gl_InstanceID可以作为uniform数组的索引使用,也可以作为纹理查找的参数,或者作为某个分析函数的输入,等等。
新实例分析:
新示例实现了上一个实例的相同画面,只是程序的实现方式不一样。在这里用到了纹理缓存对象,对于我又是一个未使用过的特性,在接受新东西的时候总不会觉得乏味。
...................虽然不觉得乏味,但还是会困,明天还得上班QAQ,To Be Continue~~~~~

看了代码之后,发现这个示例并没有什么好总结,或者是记录的东西,唯一就是让我对于应用程序和着色器程序之间的数据传递的灵活性有了进一步的了解,示例使用了两个tbo对象,以纹理缓存作为媒介,把颜色值和模型变换矩阵,传递到模型着色器中使用。最不明白的地方还是在于对于glsl着色器内置函数和sampler的陌生,之后详细学习sampler之后应该疑惑自然就可以解决。
WEBGL Shader零基础教程(九):实例化渲染 摘要:本文系统介绍了WebGL中的实例化渲染技术,通过Three.js框架实现高效大规模重复物体渲染。文章首先对比传统渲染与实例化渲染的性能差异,指出实例化渲染通过单次DrawCall渲染多个实例,显著降低CPU负载。核心内容包括:实例化属性传递机制、Shader差异化处理、Three.js的InstancedMesh API使用,以及静态/动态实例化实现方法。通过1000个立方体渲染、粒子系统等案例,演示了位置、颜色、大小、旋转等属性的实例化控制。文章还提供了性能优化技巧和常见问题排查方法,帮助开发者掌握 阅读详情

相关推荐

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

Catog的博客 1754

【奇境】OpenGL计算机图形学编程—从小白到精通

1 课程简介:本课程详细讲解了OpenGL从入门到精通的理论+实践知识,对于每一个知识点都会带领学员通过代码来实现功能。其中涵盖了基础图元绘制,基础光照,高级过程,高级光照等内容;当前图形引擎的应用已经越来越广泛,春晚以及各大综艺节目已经开始使用XR作为主流的内容制作技术,房地产漫游及Web渲染技术已经开始茁壮发展,VR也即将突破硬件瓶颈;普遍的游戏引擎在独特的领域已经无法完全实用,且我们国家要发展自主科技技术,图形引擎以及CAD等卡脖子技术一定会蓬勃发展,所以同学们要抓住机会,趁势而上,熟悉底层,博取更大发展,学习OpenGL底层接口的应用以及图形学算法,将是您向纵深发展的第一步!2 课程解决优势:很多同学学习OpenGL最难的是找到路径,并且其中牵扯到的理论知识点无法完全理解透彻(比如VAO与VBO的区别,MVP矩阵变换的推导及原理,光照系统的设计及算法推导,帧缓存的灵活应用等),我们的课程可以带领大家从原理+实践的角度进行学习,每一个知识点都会:a 推导基础公式及原理 b 一行一行进行代码实践从而能够保证每位同学都学有所得,能够看得懂,学得会,用得上,并且能够培养自主研究的能力。学习课程所得:学习本课程完毕之后,学员可以全方位的完全了解OpenGL当中的必要接口,并且可以对图形学的基础知识融会贯通,可以制作中级的特效。并且对于UnrealEngine以及Unity3D的学习更加轻松,对于各类商业引擎当中的算法以及内容制作手法更加深刻理解把控。学员也可以自行进行图形引擎的设计以及研究,并且将本课程的知识点进行代码模块化编写;能够自主推导图形学管线以及应用当中的各类公式,并且理解其几何含义。 代码与PPT资源,已随课程附赠,请同学们对应课程下载 

【OpenGL手册14】实例化

实例化渲染,是用少数数据做模板,实现海量物体渲染的手段方法。用实例化渲染,需要对每个实例产生一定描述数据。如何实现?请看本文下文。

gongdiwudu的专栏 3315

实例渲染(Instanced Rendering)

)​Qt Quick 3D支持模型对象的实例化。实例化是指使用一个绘制调用多次渲染一个对象的技术。(例如,OpenGL函数glDrawElementsInstanced。)​实例化允许复制具有变量的模型。与使用Repeater3D不同,模型及其图形资源只分配一次。重复实例的渲染由GPU在低级别完成。根据模型的复杂性,这可以使性能提高几个数量级。实际上,实例化是通过定义一个表来完成的,该表指定每个实例相对于基础模型的修改方式。

aggs1990的专栏 1220

NDK OpenGL ES 3.0 开发(十三):实例化(Instancing)

该原创文章首发于微信公众号:字节流动 OpenGL ES 实例化(Instancing) OpenGL ES 实例化(Instancing)是一种只调用一次渲染函数就能绘制出很多物体的技术,可以实现将数据一次性发送给 GPU ,告诉 OpenGL ES 使用一个绘制函数,将这些数据绘制成多个物体。 实例化(Instancing)避免了 CPU 多次向 GPU 下达渲染命令(避免多次调用 gl...

字节流动 7725

「大模型学习」(14)Long Context之线性插值、NTK-aware、Yarn、LongRoPE

大语言模型长上下文扩展中的位置插值技术 摘要:为解决大语言模型(LLMs)在推理阶段扩展上下文窗口时的位置编码限制,研究人员开发了一系列位置插值技术。这些方法主要针对旋转位置编码(RoPE)机制,通过不同策略调整位置索引以适应超出训练长度的上下文。典型方法包括:基础位置插值(PI)均匀缩放位置索引;NTK-aware插值对不同频率维度差异化处理;NTK-by-parts插值根据波长分段调整;Yarn插值结合温度调节;以及LongRoPE采用非均匀插值策略。这些技术在不修改模型结构的前提下,通过调整位置编码的

qq_43044037的博客 1643

opengl之实例化(Instance)

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

wqdqwass的博客 1957

Linux -- 图形界面配置Samba;system-config-samba工具

图形界面配置Samba6.6.1 system-config-sambasystem-config-samba是Red Hat公司专门为Samba服务器管理编写的图形界面的管理工具,通过system-config-samba几乎可以完成对Samba服务器的所有配置,所以在只希望通过Samba服务器实现一些简单的资源共享时,system-config-samba是一个不错的选...

weixin_33695450的博客 2200

实例化渲染

定义:实例化渲染是一种通过调用特殊渲染接口,由GPU完成的批处理技术。它允许在单个绘制调用中多次渲染相同的模型,从而提高渲染效率。工作原理:与传统渲染方式相比,实例化渲染在调用渲染命令时需要告知GPU这次渲染的次数。GPU接到命令后,会连续绘制多个物体到屏幕上,效率远高于连续调用多次传统渲染命令。

本博客聚焦游戏开发技巧、创业实战心得及大学热门课程干货。这里既有技术深度,也有思维广度,无论你是开发者、创业者还是高校学子,都能在这里找到适合自己的成长之路! 840

别光看教程了!手把手带你用STM32F103C8T6最小系统板点亮第一个LED(附完整电路图)

本文详细介绍了如何使用STM32F103C8T6最小系统板点亮第一个LED,从硬件连接到软件开发环境搭建,再到编写和下载程序,手把手教你完成STM32入门的第一步。适合初学者快速上手STM32开发,附完整电路图和代码示例。

weixin_28678831的博客 193

手把手教你用LTspice仿真BUCK-BOOST电路(附波形分析)

本文详细介绍了如何使用LTspice进行BUCK-BOOST电路的仿真与波形分析,涵盖电路原理、CCM与DCM模式特性、效率优化及常见问题解决方案。通过实战案例,帮助工程师快速掌握升降压转换电路的设计与调试技巧,提升电力电子设计能力。

julia4scientist的博客 1044

合批/批量渲染 (Batch)、实例化Instancing

可以简单的理解为:批量渲染是通过减少CPU向GPU发送渲染命令(DrawCall)的次数,以及减少GPU切换渲染状态的次数,尽量让GPU一次多做一些事情,来提升逻辑线和渲染线的整体效率。但这是建立在GPU相对空闲,而CPU把更多的时间都耗费在渲染命令的提交上时,才有意义。 合批最重要的前提:材质必须相同!!! 合批是节省了CPU的相关准备工作的工作量。 合批后,经过VS,PS,尝试测试,模板测试后,此时已没有了纹理,顶点,索引的概念,只剩下一个个孤立的像素,各像素间没有任何关系了。像素送到GPU后进行批

微小的鱼的博客 9312

win11怎么安装dosbox和masm来运行汇编程序(小白,萌新篇)

一文教会你如何部署dosbox和masm环境

m0_73279193的博客 4699

php 字符串涨肚,PHP中字符串补齐为定长

App Today Extension开发注意事项从iOS 8起,就有了App Extension.Extension的种类至今也扩充到了19种,应用也很广泛,值得重点关注起来. Extension几乎可以看做一个内嵌的独立App,拥有独立的Bund ...C&plus;&plus;学习准则C++学习准则 1.把C++当成一门新的语言学习(和C没啥关系!真的): 2.看,不要看(...

weixin_28738021的博客 150

避开这5个坑!Tushare金融数据获取与分析的常见错误排查指南

本文详细解析了使用Tushare进行金融数据获取与分析时常见的5个问题,包括Token失效、数据缺失、频率限制、数据一致性和性能瓶颈,并提供了实用的解决方案和优化策略。通过Python代码示例和最佳实践,帮助金融数据分析师和量化开发者高效避开这些陷阱,提升工作效率。

x2y3z4a5b的博客 1036

【理解机器学习算法】之Clustering算法(Agglomerative Clustering)

是一种层次聚类算法,通过逐步合并或“聚集”它们来构建嵌套聚类。这种方法采用自底向上的方式构建聚类层次:它从将每个数据点作为单个聚类开始,然后迭代合并最接近的聚类对,直到所有数据点合并为一个聚类,或直到达到指定的聚类数量。优点:- 聚合聚类在距离和连接准则的选择上具有多样性,使其适用于各种数据集。- 它产生了一个层次结构,这对于不同规模的聚类数据结构是有信息量的。-缺点:- 对于大数据集来说,它可能计算成本高,因为它需要在每次迭代中计算和更新所有聚类对之间的距离。

Hyman Qiu 2687

OpenGL学习日记——多实例渲染

OpenGL学习日记——多实例渲染 glVertexAttribDivisor

whl0071的专栏 1855

Week 9 10 Neural Networks

Week 9 10 Neural Networks

金州饿霸吃不饱的博客 402

OpenGL学习-高级OpenGL-实例化

简述: 如果我们想以前一样渲染几千个物体,调用几千个渲染函数会极大的影响性能。 与绘制顶点本身相比,使用glDrawArrays或glDrawElements函数告诉GPU去绘制你的顶点数据会消耗更多的性能,因为OpenGL在绘制顶点数据之前需要做很多准备工作(比如告诉GPU该从哪个缓冲读取数据,从哪寻找顶点属性,而且这些都是在相对缓慢的CPU到GPU总线(CPU to GPU Bus)上进行的)。所以,即便渲染顶点非常快,命令GPU去渲染却未必。 如果我们能够将数据一次性发送给GPU,然后使用一个绘

m0_56399931的博客 1671

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

OpenGL高级-实例化

假如你有一个有许多模型的场景,而这些模型的顶点数据都一样,只是进行了不同的世界空间的变换。想象一下,有一个场景中充满了草叶:每根草都是几个三角形组成的。你可能需要绘制很多的草叶,最终一次渲染循环中就肯能有成千上万个草需要绘制了。因为每个草叶只是由几个三角形组成,绘制一个几乎是即刻完成,但是数量巨大以后,执行起来就很慢了。像这样绘制出你模型的其他实例,多次绘制之后,很快将达到一个瓶颈,这是因为你glDrawArrays或glDrawElements这样的函数(Draw call)过多。

少年的博客 1253

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

关于QOpenGLWidget的多线程渲染

QOpenGLWidget是Qt中继承自QWidget的一个类,对OpenGL的渲染环境进行了很好的封装。用户在使用时只用继承并重写几个关键的虚函数即可完成OpenGL资源的准备和每帧画面的绘制。

WHEgqing的专栏 4153

efm32 入门.pdf

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

PyOpenGL-06.实例化渲染

本系列教程主要讲解利用Python和OpenGL开发三维图形程序。这里主要用到的工具库是glfw开源图形库。本系列内容较难。要求学生对几何和编程有一定的了解。建议初三以上同学学习。当我们在一个场景中绘制多个相同物体时。比如绘制多棵树、草。大家想到的肯定是用一个for语句来重复绘制命令来实现。这种方法效率是非常低的。小场景还好,在大场景采用这种方法效率会非常低下。效率低下原因是,for语句是在cpu下执行的。我要绘制100棵树,CPU就要提交100次数据给GPU,效率可想而知。

Sun zi chao的博客 423

OPenGL实例化绘制、普通绘制说明

OpenGL 实例化(Instancing)是一种只调用一次渲染函数就能绘制出不少物体的技术,能够实现将数据一次性而不是多次发送给 GPU ,告诉 OpenGL使用一个绘制函数,将这些数据绘制成多个物体。数组实例化(Instancing)避免了 CPU 屡次向 GPU 下达渲染命令(避免屡次调用 glDrawArrays 或 glDrawElements 等绘制函数),节省了绘制多个物体时 CPU 与 GPU 之间的通讯时间,提高了渲染性能。 //普通渲染 glDrawArrays (GLenum m.

danshiming的博客 2487

OpenGL入门学习笔记(三)——glDrawElementsInstanced多实例绘制

glDrawElementsInstanced多实例绘制

qq_45523399的博客 1183
上一篇: OpenGL学习日记-2015.3.5——Hello glsl(着色器)
下一篇: OpenGL学习笔记-2015.3.24——transform feedback缓存&粒子系统示例分析
CoderLing
博客等级 码龄15年 40粉丝 38原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值