Vulkan Cookbook 第七章 5 编写几何着色器

编写几何着色器

译者注:示例代码点击此处

3D场景由称为网格的对象组成。 网格是一组顶点,形成一个对象的外表面。 该表面通常由三角形表示。 当我们渲染一个对象时,我们提供顶点并指定它们构建的基元(点,线,三角形)的类型。 在顶点和可选曲面细分阶段处理顶点之后,它们被组装成指定类型的基元。 我们可以启用(也是可选的)几何阶段和写几何着色器来控制或改变从顶点形成基元的过程。 在几何着色器中,我们甚至可以创建新的基元或破坏现有的基元。

怎么做...

1.创建一个扩展名为geom文本文件(例如,shader.geom)。
2.在文件的第一行插入#version 450。
3.使用in layout限定符,定义在应用程序中绘制的基元(primitive)类型:points,lines,lines_adjacency,triangles或triangles_adjacency:
    layout( <primitive type> ) in;
4.使用out布局限定符,定义几何着色器(points,line_strip或triangle_strip)形成(输出)的基元(primitive)类型,以及着色器可能生成的最大顶点数:
    layout( <primitive type>, max_vertices = <count> ) out;
5.定义从顶点或曲面细分评估阶段提供的一组输入数组变量。 对于每个输入变量:
   1.使用位置布局(location layout)限定符和属性索引(index)定义其位置
        layout( location = <index> )
    2.提供in限定符
    3.指定输入变量的类型(例如ivec4,int或float)
    4.提供输入变量的唯一名称
    5.确保将变量定义为unsized array
6.如有必要,定义一个输出变量,该变量将被传递(并插入,除非另有说明)到片段着色器阶段。 要定义每个输出变量:
    1.使用位置布局(location layout)限定符和属性索引(index)定义其位置
        layout( location = <index> )
    2.指定out限定符
    3.定输出变量的类型(例如vec3或uint)
    4.选择输出变量的唯一名称
7.如有必要,定义与几何阶段可以访问的应用程序中创建的描述符资源相对应的uniform变量:
    1.指定描述符集的数量和可以访问给定资源的绑定号:
        layout (set=<set index>, binding=<binging index>)
    2.提供统一的uniform限定符
    3.定变量的类型(例如image2D,sampler1DArray)
    4.定义变量的唯一名称
8.创建一个void main()函数,其中:
    1.执行所需的操作
    2.对于每个生成或传递的顶点:
        ·将值写入输出变量
        ·将顶点(可能已转换)的位置存储在内置gl_Position变量中
        ·用EmitVertex()将一个顶点添加到基元
    3.通过调用EndPrimitive()函数完成基元的生成(隐式启动另一个基元)。

这个怎么运作...

几何是图形中的管线可选阶段。 没有它,当我们绘制几何图形时,将根据图形管道创建期间指定的类型自动生成图元。 几何着色器允许我们创建其他顶点和基元,销毁应用程序中绘制的顶点和基元,或更改从顶点形成的基元类型。

几何着色器对应用程序绘制的几何中的每个基元执行一次。 它可以访问构成基元的所有顶点,甚至可以访问相邻的顶点。 使用此数据,它可以传递相同的内容或创建新的顶点和基元。 我们必须记住,我们不应该在几何着色器中创建太多顶点。 如果我们想要创建许多新顶点,则曲面细分着色器更适合此任务(并且具有更好的性能)。 只是增加几何着色器可能创建的最大顶点数,即使我们并不总是形成它们,会降低我们的应用程序的性能。

提示:我们应该保持几何着色器发出的顶点数量尽可能低。

几何着色器始终生成条带基元。 如果我们想要创建不形成条带的单独基元(想要生成多个单独基元),只需要在适当的时刻结束基元(EndPrimitive) - 在基元结束后发出的顶点被添加到下一个条带,这样我们就可以创建尽可能多的单独条带 。 下面是在一个原始三角形的角中创建三个独立三角形的示例:

#version 450 

layout( triangles ) in; 

layout( triangle_strip, max_vertices = 9 ) out; 

void main() { 
  for( int vertex = 0; vertex < 3; ++vertex ) { 
    gl_Position = gl_in[vertex].gl_Position + vec4( 0.0, -0.2, 0.0, 0.0 ); 
    EmitVertex(); 
    gl_Position = gl_in[vertex].gl_Position + vec4( -0.2, 0.2, 0.0, 0.0 ); 
    EmitVertex(); 
    gl_Position = gl_in[vertex].gl_Position + vec4(  0.2, 0.2, 0.0, 0.0 ); 
    EmitVertex(); 
    EndPrimitive(); 
  }
} 

 使用简单的顶点和片段着色器绘制单个三角形时,用前面的几何着色器,结果应如下所示:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值