Vulkan Cookbook 第七章 7 编写计算着色器

编写计算着色器

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

顾名思义,计算着色器用于一般的数学计算。 它们在定义的三维大小的(本地)组中执行,其可以访问公共数据集。 同时,可以执行许多本地组以更快地生成结果。

怎么做...

1.创建一个扩展名为comp的文本文件(例如,shader.comp)。
2.在文件的第一行插入#version 450。
3.使用输入布局(layout)限定符,定义本地工作组的大小:
    layout( local_size_x = <x size>, local_size_y = <y size>, local_size_z = <z size> ) in;
4.定义与应用程序中创建的描述符资源相对应的uniform变量:
    1.指定描述符集的数量和可以访问给定资源的绑定号:
        layout (set=<set index>, binding=<binding index>)
    2.提供uniform限定符
    3.指定变量的类型(例如image2D或buffer)
    4.定义变量的唯一名称
5.创建一个void main()函数,其中:
    1.执行所需的操作和计算
    2.将结果存储在选定的统一变量中

这个怎么运作...

计算着色器只能在专用计算管线中使用。 它们也不能在渲染过程中执行(调度)。

计算着色器没有从早期或后期管线阶段传递的任何输入或输出(用户定义)变量 - 它是计算管线中的唯一阶段。 必须使用uniform变量作为计算着色器数据的来源。 类似地,在计算着色器中执行的计算结果只能存储在uniform变量中。

有一些内置的输入变量提供有关本地工作组中给定着色器调用的索引的信息(通过uvec3 gl_LocalInvocationID变量),同时调度的工作组数(通过uvec3 gl_NumWorkGroups变量),或者当前工作组的编号(uvec3 gl_WorkGroupID变量)。 还有一个变量可以唯一标识所有工作组中所有调用中的当前着色器 -  uvec3 gl_GlobalInvocationID。 它的值计算如下:

gl_WorkGroupID * gl_WorkGroupSize + gl_LocalInvocationID

通过输入布局(layout)限定符定义本地工作组的大小。 在着色器内部,定义的大小也可通过uvec3 gl_WorkGroupSize内置变量获得。

在以下代码中,您可以找到使用gl_GlobalInvocationID变量生成简单静态分形图像的计算着色器示例:

#version 450 

layout( local_size_x = 32, local_size_y = 32 ) in; 

layout( set = 0, binding = 0, rgba8 ) uniform image2D StorageImage; 

void main() { 
  vec2 z = gl_GlobalInvocationID.xy * 0.001 - vec2( 0.0, 0.4 );
  vec2 c = z; 

  vec4 color = vec4( 0.0 ); 

  for( int i=0; i<50; ++I ) { 
    z.x = z.x * z.x-- z.y * z.y + c.x; 
    z.y = 2.0 * z.x * z.y + c.y; 
    if( dot( z, z ) > 10.0 ) { 
      color = i * vec4( 0.1, 0.15, 0.2, 0.0 ); 
      break; 
    } 
  } 
  imageStore( StorageImage, ivec2( gl_GlobalInvocationID.xy ), color ); 
}

前面的计算着色器在调度时生成以下结果:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值