Vulkan Tutorial 19 Vertex input description
操作系统:Windows8.1
显卡:Nivida GTX965M
开发工具:Visual Studio 2017
Introduction
在接下来几个章节中,我们将会使用内存顶点缓冲区来替换之前硬编码到vertex shader中的顶点数据。我们将从最简单的方法开始创建一个CPU可见的缓冲区,并使用memcpy直接将顶点数据直接复制到缓冲区,之后将会使用暂存缓冲区将顶点数据赋值到高性能的内存。
Vertex shader
首先要修改的是顶点着色器,不再包含顶点数据。顶点着色器接受顶点缓冲区的输入使用in关键字。
#version
#extension GL_ARB_separate_shader_objects : enable layout(location = ) in vec2 inPosition;
layout(location = ) in vec3 inColor; layout(location = ) out vec3 fragColor; out gl_PerVertex {
vec4 gl_Position;
}; void main() {
gl_Position = vec4(inPosition, 0.0, 1.0);
fragColor = inColor;
}
inPosition和inColor变量是顶点属性。它们被顶点缓冲区中的每一个顶点指定,就像我们使用两个数组手动指定每个顶点的position和color一样。现在确保着色器被正确编译!
Vertex data
我们将顶点数组从着色器代码移到我们程序自定义的数组中。首先我们需要引入GLM库,它提供了像向量和矩阵之类的线性代数数据结构。我们使用这些类型指定position和颜色。
#include <glm/glm.hpp>
建立新的数据结构Vertex并定义两个属性,我们将会在顶点着色器内部使用:
struct Vertex {
glm::vec2 pos;
glm::vec3 color;
};
GLM很方便的提供了与C++类型匹配的可以在着色器中使用的矢量类型。
const std::vector<Vertex> vertices = {
{{0.0f, -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}}
};
现在使用Vertex结构体作为顶点数组的元素类型。我们使用与之前完全相同的position和color值,但是现在它们被组合成一个顶点数组。这被称为 interleaving 顶点属性。
Binding descriptions
一旦数据被提交到GPU的显存中,就需要告诉Vulkan传递到顶点着色器中数据的格式。有两个结构体用于描述这部分信息。
第一个结构体VkVertexInputBingdingDescription,Vertex结构体中新增一个成员函数,并使用正确的数值填充它。
struct Vertex {
glm::vec2 pos;
glm::vec3 color;
static VkVertexInputBindingDescription getBindingDescription() {
VkVertexInputBindingDescription bindingDescription = {};
return bindingDescription;
}
};
顶点绑定描述了在整个顶点数据从内存加载的速率。换句话说,它指定数据条目之间的间隔字节数以及是否每个顶点之后或者每个instance之后移动到下一个条目。
VkVertexInputBindingDescription bindingDescription = {};
bindingDescription.binding = ;
bindingDescription.stride = sizeof(Vertex);
bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
我们所有的顶点数据都被打包在一个数组中,所以我们需要一个绑定。binding的参数指定了数组中对应的绑定索引。stride参数指定一个条目到下一个条目的字节数,inputRate参数可以具备一下值之一:
- VK_VERTEX_INPUT_RATE_VERTEX: 移动到每个顶点后的下一个数据条目
- VK_VERTEX_INPUT_RATE_INSTANCE: 在每个instance之后移动到下一个数据条目
我们不会使用instancing渲染,所以坚持使用per-vertex data方式。
Attribute descriptions
第二个结构体描VkVertexInputAttributeDescription述如何处理顶点的输入。我们需要在Vertex中增加一个新的辅助函数。
#include <array>
...
static std::array<VkVertexInputAttributeDescription, > getAttributeDescriptions() {
std::array<VkVertexInputAttributeDescription, > attributeDescriptions = {};
return attributeDescriptions;
}
如函数圆形所示,该结构体为两个。一个属性描述结构体最终描述了顶点属性如何从对应的绑定描述过的顶点数据来解析数据。我们有两个属性,position和color,所以我们需要两个属性描述结构体。
attributeDescriptions[].binding = ;
attributeDescriptions[].location = ;
attributeDescriptions[].format = VK_FORMAT_R32G32_SFLOAT;
attributeDescriptions[].offset = offsetof(Vertex, pos);
binding参数告诉了Vulkan每个顶点数据的来源。location参数引用了vertex shader作为输入的location指令。顶点着色器中,location为0代表position,它是32bit单精度数据。
format参数描述了属性的类型。该格式使用与颜色格式一样的枚举,看起来有点乱。下列的着色器类型和格式是比较常用的搭配。
- float: VK_FORMAT_R32_SFLOAT
- vec2: VK_FORMAT_R32G32_SFLOAT
- vec3: VK_FORMAT_R32G32B32_SFLOAT
- vec4: V_FORMAT_R32G32B32A32_SFLOAT
如你所见,你应该使用颜色数量与着色器数据类型中的分量个数匹配的格式。允许使用比着色器中的分量个数更大的范围,但是它将会被默认丢弃。如果低于着色器分量的数量,则BGA组件将使用默认值(0, 0, 1)。颜色类型(SFLOAT, UINT, SINT) 和位宽度应该与着色器输入的类型对应匹配。如下示例:
- ivec2: VK_FORMAT_R32G32_SINT,由两个32位有符号整数分量组成的向量
- uvec4: VK_FORMAT_R32G32B32A32_UINT, 由四个32位无符号正式分量组成的向量
- double: VK_FORMAT_R64_SFLOAT, 双精度浮点数(64-bit)
format参数在属性数据中被隐式的定义为字节单位大小,并且offset参数指定了每个顶点数据读取的字节宽度偏移量。绑定一次加载一个Vertex,position属性(pos)的偏移量在字节数据中为0字节。这是使用offsetof macro宏自动计算的。
attributeDescriptions[].binding = ;
attributeDescriptions[].location = ;
attributeDescriptions[].format = VK_FORMAT_R32G32B32_SFLOAT;
attributeDescriptions[].offset = offsetof(Vertex, color);
color颜色属性与position位置属性的描述基本一致。
Pipeline vertex input
我们现在需要在createGraphicsPipeline函数中,配置图形管线可以接受重新定义的顶点数据的格式。找到vertexInputInfo结构体,修改引用之前定义的两个有关输入顶点的description结构体:
auto bindingDescription = Vertex::getBindingDescription();
auto attributeDescriptions = Vertex::getAttributeDescriptions(); vertexInputInfo.vertexBindingDescriptionCount = ;
vertexInputInfo.vertexAttributeDescriptionCount = static_cast<uint32_t>(attributeDescriptions.size());
vertexInputInfo.pVertexBindingDescriptions = &bindingDescription;
vertexInputInfo.pVertexAttributeDescriptions = attributeDescriptions.data();
图形管线现在准备接受vertices容器封装后的顶点数据,并将该格式的顶点数据传递到vertex shader。如果开启了validation layers运行程序,我们将会看到无顶点缓冲区绑定的提示。所以下一章节我们将会创建顶点缓冲区vertex buffer并把顶点数据存储在里面,最终GPU通过顶点缓冲区读取到顶点数据。
项目代码 GitHub 地址。
Vulkan Tutorial 19 Vertex input description的更多相关文章
- Vulkan Tutorial 20 Vertex buffer creation
操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Visual Studio 2017 Introduction 在Vulkan中,缓冲区是内存的一块区域,该区域用于向显卡 ...
- [译]Vulkan教程(21)顶点input描述
[译]Vulkan教程(21)顶点input描述 Vertex input description 顶点input描述 Introduction 入门 In the next few chapters ...
- [译]Vulkan教程(19)渲染和呈现
[译]Vulkan教程(19)渲染和呈现 Rendering and presentation 渲染和呈现 Setup 设置 This is the chapter where everything ...
- Vulkan Tutorial 12 Fixed functions
操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Visual Studio 2017 早起的图形API在图形渲染管线的许多阶段提供了默认的状态.在Vulkan中,从vie ...
- Vulkan Tutorial 10 图形管线
操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Visual Studio 2017 Introduction 通过接下来的章节,我们将会开启有关图形管线的话题,通过对图 ...
- Vulkan Tutorial 11 Shader modules
操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Visual Studio 2017 与之前的图像API不同,Vulkan中的着色器代码必须以二进制字节码的格式使用,而不 ...
- Vulkan Tutorial 13 Render passes
操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Visual Studio 2017 Setup 在我们完成管线的创建工作,我们接下来需要告诉Vulkan渲染时候使用的f ...
- Vulkan Tutorial 18 重构交换链
操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Visual Studio 2017 Introduction 现在我们已经成功的在屏幕上绘制出三角形,但是在某些情况下, ...
- Vulkan Tutorial 22 Index buffer
操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Visual Studio 2017 Introduction 在实际产品的运行环境中3D模型的数据往往共享多个三角形之间 ...
随机推荐
- Postmark介绍
一. 引言 Postmark是由著名的NAS提供商NetApp开发,用来测试其产品的后端存储性能. Postmark主要用于测试文件系统在邮件系统或电子商务系统中性能,这类应用的特点是:需要频繁.大量 ...
- python2与python3的不兼容_urllib2
网页下载器:将URL对应的网页以HTML下载到本地,用于后续分析 常见网页下载器:Python官方基础模块:urllib2 第三方功能包:requests python 3.x中urllib库和uri ...
- CSS3 02. 边框、边框圆角、边框阴影、边框图片、渐变、线性渐变、径向渐变、背景、过渡transition、2D转换
边框圆角 border-radius 每个角可以设置两个值,x值.y值 border-top-left-radius:水平半径 垂直半径 border-radius:水平半径/垂直半径 border- ...
- 安装hexo报错(npm WARN deprecated swig@1.4.2: This package is no longer maintained),已解决
问题:在使用npm安装hexo时报错 $ npm install -g hexo npm WARN deprecated swig@1.4.2: This package is no longer m ...
- logback配置文件详解
一:根节点<configuration>包含的属性: scan: 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true. scanPeriod: 设置监测配置文 ...
- 在Visual Studio中入门F#
写在前面的话 个人由某方面的兴趣需要学习 F#,网络上有关F#的中文资料很少,微软官方有很不错的文档,但是很可惜的是绝大部分的章节都是英文的.个人是一位.NET爱好者,想自己将 F# 的官方文档翻译出 ...
- Mysql数据库学习笔记之数据库索引(index)
什么是索引: SQL索引有两种,聚集索引和非聚集索引,索引主要目的是提高了SQL Server系统的性能,加快数据的查询速度与减少系统的响应时间. 聚集索引:该索引中键值的逻辑顺序决定了表中相应行的物 ...
- 时间序列预测之--ARIMA模型
什么是 ARIMA模型 ARIMA模型的全称叫做自回归移动平均模型,全称是(ARIMA, Autoregressive Integrated Moving Average Model).也记作ARIM ...
- 为程序猿正名,MM们,你们为什么要找一个程序猿男票?【原创】
前言 免责声明:这篇文章关于什么?六一儿童节马上就要到了,作为一个前端攻城师,自我感觉效率还可以,老早已把任务搞完,页面布局和前端编码高效按时交付,呵呵.趁有时间,写写文章娱乐一下.MM们,请不要拿起 ...
- Android 模块化探索与实践
首发于<程序员>杂志五月刊 一.前言 万维网发明人 Tim Berners-Lee 谈到设计原理时说过:"简单性和模块化是软件工程的基石:分布式和容错性是互联网的生命." ...