OpenGL学习笔记(十)-几何着色器-实例化

本文详细介绍了OpenGL中的几何着色器,包括其基本概念、使用方法,展示了如何通过几何着色器创建房屋模型、实现爆破效果以及法线可视化。此外,还探讨了实例化技术,解释了如何通过实例化提高渲染效率,以绘制大量相同物体,如四边形网格和小行星带,阐述了实例化数组的概念和应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考网址:LearnOpenGL 中文版

4.7 几何着色器

4.7.1 基本概念

1、顶点和片段着色器之间有一个可选的几何着色器,几何着色器的输入是一个图元(如点或三角形)的一组顶点,顶点发送到下一着色器之前可对它们随意变换,将顶点变换为完全不同的图元,并且还能生成比原来更多的顶点。

#version 330 core
layout (points) in;
layout (line_strip, max_vertices = 2) out;

void main() {
       
    gl_Position = gl_in[0].gl_Position + vec4(-0.1, 0.0, 0.0, 0.0); 
    EmitVertex();

    gl_Position = gl_in[0].gl_Position + vec4( 0.1, 0.0, 0.0, 0.0);
    EmitVertex();

    EndPrimitive();
}

2、在几何着色器的顶部,在in关键字前声明一个布局修饰符,声明从顶点着色器输入的图元类型,括号内的数字表示的是一个图元所包含的最小顶点数。

  • points:绘制GL_POINTS图元时(1)。
  • lines:绘制GL_LINES或GL_LINE_STRIP时(2)
  • lines_adjacency:GL_LINES_ADJACENCY或GL_LINE_STRIP_ADJACENCY(4)
  • triangles:GL_TRIANGLES、GL_TRIANGLE_STRIP或GL_TRIANGLE_FAN(3)
  • triangles_adjacency:GL_TRIANGLES_ADJACENCY或GL_TRIANGLE_STRIP_ADJACENCY(6)

3、在out关键字前面加一个布局修饰符,指定几何着色器输出的图元类型:

  • points
  • line_strip
  • triangle_strip

4、同时可以设置一个它最大能够输出的顶点数量(超过了这个值,OpenGL将不会绘制多出的顶点),使用上面定义的着色器输出一条线段,最大顶点数等于2:
在这里插入图片描述
5、几何着色器中有一个内建接口块变量gl_in[],包含了几个变量。其中,gl_Position与顶点着色器输出非常相似,它被声明为一个数组,因为几何着色器的输入是一个图元的所有顶点。

in gl_Vertex
{
   
    vec4  gl_Position;
    float gl_PointSize;
    float gl_ClipDistance[];
} gl_in[];

6、利用几何着色器函数EmitVertexEndPrimitive来生成新的数据了。调用EmitVertex时,gl_Position中的向量会被添加到图元中来。当EndPrimitive被调用时,所有发射出的顶点都会合成为指定的输出渲染图元。在一个或多个EmitVertex调用之后重复调用EndPrimitive能够生成多个图元。

void main() {
   
    gl_Position = gl_in[0].gl_Position + vec4(-0.1, 0.0, 0.0, 0.0); 
    EmitVertex();

    gl_Position = gl_in[0].gl_Position + vec4( 0.1, 0.0, 0.0, 0.0);
    EmitVertex();

    EndPrimitive();
}

7、在这个例子中,接受一个点图元作为输入,从原始顶点位置平移了0.1,发射了两个顶点。之后调用EndPrimitive,将这两个顶点合成为一个包含两个顶点的线条。即以这个点为中心,创建一条水平的线图元。

glDrawArrays(GL_POINTS, 0, 4);

在这里插入图片描述

4.7.2 使用几何着色器

1、在标准化设备坐标的z平面上绘制四个点,包含顶点信息和颜色信息

float points[] = {
   
    -0.5f,  0.5f, 1.0f, 0.0f, 0.0f, // 左上
     0.5f,  0.5f, 0.0f, 1.0f, 0.0f, // 右上
     0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // 右下
    -0.5f, -0.5f, 1.0f, 1.0f, 0.0f  // 左下
};

2、顶点着色器在z平面绘制点,使用一个接口块将颜色属性发送到几何着色器中。

#version 330 core
layout (location = 0) in vec2 aPos;
layout (location = 1) in vec3 aColor;

out VS_OUT{
   
	vec3 color;
}vs_out;

void main()
{
   
    gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0); 
    vs_out.color = aColor;
}

3、创建一个传递几何着色器,接收点图元,在每个点的位置上绘制一个房子。每个顶点都是原始点的位置加上一个偏移量,来组成一个大的三角形带。使用三角形带(Triangle Strip)绘制,使用的顶点更少。在第一个三角形绘制完之后,每个后续顶点将会在上一个三角形边上生成另一个三角形,每3个临近的顶点将会形成一个三角形,得到(1, 2, 3)、(2, 3, 4)、(3, 4, 5)3个三角形。一个三角形带有N个顶点,会生成N-2个三角形。
在这里插入图片描述

4、几何着色器的输出

  • 将几何着色器的输出设置为triangle_strip
  • 在几何着色器中声明相同的接口块(使用一个不同的接口名VS_OUT )接受颜色属性,因为几何着色器是作用于输入的一组顶点的,从顶点着色器发来输入数据总是会以数组的形式表示出来。
  • 为片段着色器阶段声明一个输出颜色向量fColor,因为片段着色器只需要一个插值的颜色,就是一个单独的向量。
#version 330 core
layout (points) in;
layout (triangle_strip, max_vertices = 5) out;

in VS_OUT {
   
    vec3 color;
} gs_in[];

out vec3 fColor;

void build_house(vec4 position)
{
       
	fColor = gs_in[0].color; // gs_in[0] 因为只有一个输入顶点
    gl_Position = position + vec4(-0.2, -0.2, 0.0, 0.0);    // 1:左下
    EmitVertex();   
    gl_Position = position + vec4( 0.2, -0.2, 0.0, 0.0);    // 2:右下
    EmitVertex();
    gl_Position = position + vec4(-0.2,  0.2, 0.0, 0.0);    // 3:左上
    EmitVertex();
    gl_Position = position + vec4( 0.2,  0.2, 0.0, 0.0);    // 4:右上
    EmitVertex();
    gl_Position = position +
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值