编写纹理顶点和片段着色器
译者注:示例代码点击此处
纹理是一种常用技术,可显着提高渲染图像的质量。 它允许我们加载图像并将其包裹在对象周围,如壁纸。 它增加了内存使用量,但节省了处理更复杂几何体时会浪费的性能。
怎么做...
1.在名为shader.vert的文本文件中创建顶点着色器(请参阅编写编写顶点着色器内容)。
2.除顶点位置外,在顶点着色器中定义一个附加输入变量(属性),通过该变量从应用程序提供纹理坐标:
layout( location = 1 ) in vec2 app_tex_coordinates;
3.在顶点着色器中,定义一个输出变量,纹理坐标将通过该变量从顶点着色器传递到片段着色器:
layout( location = 0 ) out vec2 vert_tex_coordinates;
4.在顶点着色器的void main()函数中,将app_tex_coordinates变量分配给vert_tex_coordinates变量:
vert_tex_coordinates = app_tex_coordinates;
5.创建片段着色器(请参阅编写片段着色器内容)。
6.在片段着色器中,定义一个输入变量,其中将传递从顶点着色器提供的纹理坐标:
layout( location = 0 ) in vec2 vert_tex_coordinates;
7.创建一个统一的sampler2D变量,该变量将表示应该应用于几何的纹理:
layout( set=0, binding=0 ) uniform sampler2D TextureImage;
8.定义一个输出变量,其中将存储片段的最终颜色(从纹理中读取):
layout( location = 0 ) out vec4 frag_color;
9.片段着色器的void main()函数中,对纹理进行采样并将结果存储在frag_color变量中:
frag_color = texture( TextureImage, vert_tex_coordinates );
这个怎么运作...
要绘制一个对象,我们需要它的所有顶点。 为了能够使用纹理并将其应用于模型,除了顶点位置之外,我们还需要为每个顶点指定纹理坐标。 这些属性(位置和纹理坐标)将传递给顶点着色器。 它获取位置并将其转换为裁剪空间(如果需要),并将纹理坐标传递给片段着色器:
#version 450
layout( location = 0 ) in vec4 app_position;
layout( location = 1 ) in vec2 app_tex_coordinates;
layout( location = 0 ) out vec2 vert_tex_coordinates;
void main() {
gl_Position = app_position;
vert_tex_coordinates = app_tex_coordinates;
}
纹理操作在片段着色器中执行。 来自形成多边形的所有顶点的纹理坐标被内插并提供给片段着色器。 它使用这些坐标从纹理中读取(采样)颜色。 此颜色存储在输出和(可能)附件中:
#version 450
layout( location = 0 ) in vec2 vert_tex_coordinates;
layout( set=0, binding=0 ) uniform sampler2D TextureImage;
layout( location = 0 ) out vec4 frag_color;
void main() {
frag_color = texture( TextureImage, vert_tex_coordinates );
}
除了为着色器提供纹理坐标外,应用程序还需要准备纹理本身。 通常,这是通过创建组合图像采样器(请参阅第5章,描述符集中的创建组合图像采样器内容)并将其提供给设置为第0个绑定的描述符(在此示例中)来完成的。 描述符集必须绑定到第0个集合索引。