Vulkan-实践第一弹

2023-10-27

 上一篇文章中,我们浅析了Vulkan对传统图形API的优势,主要就是在其性能和精细化操控GPU上,具体可参考Vulkan-性能及精细化

今天我们就来用个简单的例子,亲身感受下Vulkan的开发“魅力”。

#include <iostream>
#include <chrono>
#include <cstring>
#include <glm/mat4x4.hpp>
#include <glm/gtx/transform.hpp>
#include "VK_UniformBuffer.h"
#include "VK_Context.h"
#include "VK_Pipeline.h"
#include "VK_DynamicState.h"

using namespace std;

const std::vector<uint32_t> indices = {
    0, 1, 2
};

const std::vector<float> vertices = {
    0.0f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.5f,
    0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.5f,
    -0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.5
};


VK_Context *context = nullptr;
VK_Pipeline *pipeline = nullptr;

// 窗口大小改变时通过onFrameSizeChanged更新窗口大小
void onFrameSizeChanged(int width, int height)
{
    pipeline->getDynamicState()->applyDynamicViewport({0, 0, (float)width, (float)height, 0, 1});
}

//实时更新uniform值
uint32_t updateUniformBufferData(char *&data, uint32_t size)
{
    static auto start = std::chrono::high_resolution_clock::now();
    auto current = std::chrono::high_resolution_clock::now();
    float time = std::chrono::duration<float, std::chrono::seconds::period>
                 (current - start).count();
    glm::mat4 model = glm::rotate(glm::mat4(1.0f), time * glm::radians(30.0f), glm::vec3(0.0f, 0.0f,
                                                                                         1.0f));
    memcpy(data, &model[0][0], size);
    return sizeof(model);
}


int main()
{
    VK_ContextConfig config;
    config.debug = true;
    config.name = "Uniform Demo";

    context = createVkContext(config);
    context->createWindow(640, 640, true);
    context->setOnFrameSizeChanged(onFrameSizeChanged);

    VK_Context::VK_Config vkConfig;
    context->initVulkanDevice(vkConfig);

    auto shaderSet = context->createShaderSet();
    shaderSet->addShader("../jianghuxiuxing/shader/mvp/vertex.spv", VK_SHADER_STAGE_VERTEX_BIT);
    shaderSet->addShader("../jianghuxiuxing/shader/mvp/fragmeng.spv", VK_SHADER_STAGE_FRAGMENT_BIT);

    shaderSet->appendAttributeDescription(0, sizeof (float) * 3, VK_FORMAT_R32G32B32_SFLOAT, 0);
    shaderSet->appendAttributeDescription(1, sizeof (float) * 4, VK_FORMAT_R32G32B32A32_SFLOAT,
                                          sizeof(float) * 3);

    shaderSet->appendVertexInputBindingDescription(7 * sizeof(float), 0, VK_VERTEX_INPUT_RATE_VERTEX);

    VkDescriptorSetLayoutBinding uniformBinding = VK_ShaderSet::createDescriptorSetLayoutBinding(0,
                                                                                                 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_VERTEX_BIT);
    shaderSet->addDescriptorSetLayoutBinding(uniformBinding);

    if (!shaderSet->isValid()) {
        std::cerr << "invalid shaderSet" << std::endl;
        shaderSet->release();
        context->release();
        return -1;
    }

    auto ubo = shaderSet->addUniformBuffer(0, sizeof(float) * 16);
    ubo->setWriteDataCallback(updateUniformBufferData);

    context->initVulkanContext();
    pipeline = context->createPipeline(shaderSet);
    pipeline->getDynamicState()->addDynamicState(VK_DYNAMIC_STATE_VIEWPORT);
    pipeline->create();
    pipeline->getDynamicState()->applyDynamicViewport({0, 0, 480, 480, 0, 1});

    auto buffer = context->createVertexBuffer(vertices, 3 + 4, indices);
    pipeline->addRenderBuffer(buffer);

    context->createCommandBuffers();

    context->run();
    context->release();

    return 0;
}

Vertex Shader

#version 450
layout(location = 0) in vec3 position;
layout(location = 1) in vec4 color;
layout(location = 0) out vec4 fragColor;

layout(binding = 0) uniform UniformBufferObject {
    mat4 model;
} mvp;

void main() {
    gl_Position = mvp.model * vec4(position, 1.0);
    fragColor = color;
}

Fragment Shader

#version 450
layout(location = 0) in vec4 fragColor;
layout(location = 0) out vec4 outColor;

void main() {
    outColor = fragColor;
}

效果:

 从上面的代码实现可以看出Vulkan在加载spv字节码,显示指定shader各属性方面都做了更繁琐的限制,开发者需要关注的程序控制和执行时机也变的更多了,这也印证了我们上一篇文章里说的Vulkan摒弃了传统图形API的大包大揽,而将更多的校验和权利下放给了程序设计者。

Vulkan的渲染流程

  • 创建程序窗口
  • 初始化Vulkan实例 - vulkan库的初始化
  • 初始化输出表面 - 指明渲染显示目的地
  • 选择满足要求的物理设备(通常多个,对于渲染程序,通常需要物理设备支持图形队列以及表面呈现队列)
  • 创建逻辑设备 - 根据指定物理设备即可创建逻辑设备(逻辑设备和物理设备相对应,但并不唯一)
  • 创建指令池对象 - vulkan中指令提交和传输需要通过指令缓冲来操作,对于指令缓冲需要构建指令池对象
  • 创建交换链 - vulkan中不存在默认帧缓冲的概念,需要一个缓存渲染缓冲的组件,这就是交换链。交换链本质上一个包含了若干等待呈现的图像的队列
  • 创建交换队列图像视图 - 有了交换链还不够,需要一组图形来保存渲染数据
  • 创建渲染通道 - 渲染通道用于表示帧缓冲,其是子通道以及子通道关系的集合。深度模板附件、颜色附件、帧附件都是在此阶段被创建的
  • 创建描述符布局 - 描述符是一个特殊的不透明的着色器变量,着色器使用它以间接的方式访问缓冲区和图像资源。描述符集合是描述一个管线使用到的描述符集合。描述符布局则用于刻画其布局。
  • 创建管线布局 - 管线布局包含一个描述符集合布局的列表
  • 创建帧缓冲 - 作为附件的图像依赖交换链用于呈现时返回的图像。这意味着我们必须为交换链中的所有图像创建一个帧缓冲区,并在绘制的时候使用对应的图像。其附件必须和渲染通道中使用的附件相匹配。
  • 创建描述符池 -描述符需要从池中分配,不能直接创建
  • 创建描述符集 - 描述符池是根据交换链帧个数以及Shader中描述符数量和数据来创建的,Shader属性类型和其中涉及的uninform、location等信息是在这个阶段被传入的
  • 分配和更行描述符集 - 交换链帧个数、uniform数据以及图形视图是在这个阶段被处理的
  • 创建管线 - 根据Shader、管线布局、渲染通道以及其他相关信息即可构造管线(需要设置各种属性关联的Shader,顶点输入格式 ,视口状态,光栅化,多重采样可选等)
  • 创建命令缓冲 - 根据命令池、渲染通道、交换链帧个数即可分配并使用命令缓冲,其中对管线的绑定、描述符集的绑定以及开始和结束渲染通道是在这个阶段完成的。
  • 渲染循环-从交换链中取图像(利用 vkAcquireNextImageKHR),更新uniform数据- vkMapMemory、vkUnmapMemory,提交指令缓冲 (利用vkQueueSubmit),图像回传交换链作呈现。(这个过程非常复杂,由于Vulkan的多线程需要保证同步等)
  • 管线重建-管线并不始终有效,如果渲染呈现丢失或者窗口大小发生变化或者管线配置发生变化时都需要重新构造交换链和管线。(相关的节点也需要重建,比如交换链,渲染通道,缓冲池等)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Vulkan-实践第一弹 的相关文章

  • 人像美妆效果实现(贴纸)——OpenGL实现

    一 贴纸美妆 人像美妆效果的实现方式有很多种 其中贴纸美妆是最常见也是应用最广泛的一种实现方式 它有实现简单 素材可移植和可复用性高等优点 是目前众多美颜美妆相关的App中应用最多的美妆实现方式 它有点像我们玩的贴在脸上或手臂上的的纹身贴纸
  • 3DCAT携手华为,打造XR虚拟仿真实训实时云渲染解决方案

    2023年5月8日 9日 以 因聚而生 众志有为 为主题的 华为中国合作伙伴大会2023 在深圳国际会展中心隆重举行 本次大会汇聚了ICT产业界的广大新老伙伴朋友 共同探讨数字化转型的新机遇 共享数字化未来的新成果 华为中国合作伙伴大会20
  • 光照 (5) 光照贴图

    物体在不同的部件上都有不同的材质属性 1 1 漫反射 允许我们对物体的漫反射分量 以及间接地对环境光分量 它们几乎总是一样的 和镜面光分量有着更精确的控制 漫反射贴图 Diffuse Map 使用一张覆盖物体的图像 让我们能够逐片段索引其独
  • Unity之使UI显示在最上层

    一 原理 Camera Depth 摄像机深度 深度值越小 越浅 越浮于表面 越近 前 Sorting Layer 排序层级 Order In Layer 在排序层中的层级 Render Queue 在Shader中对Tags的Queue进
  • Turbo跨平台开源渲染引擎

    Turbo跨平台开源渲染引擎 基于Vulkan开发的跨平台渲染引擎 欢迎来参观 使用 提意见 o o Turbo开源引擎地址 Turbo开源引擎开发记录视频
  • 【OpenGL】笔记五、纹理

    1 流程 1 1 单个纹理 纹理是一个2D图片 甚至也有1D和3D的纹理 它可以用来添加物体的细节 为了能够使用纹理图片 我们需要一个叫做stb image h的头文件库来加载不同格式的图片作为纹理 全部文件 得到该头文件后 加入项目 并且
  • 光照 (5) 法线矩阵(Normal Matrix)

    定义 模型矩阵左上角3x3部分的逆矩阵的转置矩阵 注意 大部分的资源都会将法线矩阵定义为应用到模型 观察矩阵 Model view Matrix 上的操作 但是由于我们只在世界空间中进行操作 不是在观察空间 我们只使用模型矩阵 1 1 法向
  • 光线追踪渲染实战(四):微平面理论与迪士尼 BRDF,严格遵循物理!

    项目代码仓库 GitHub https github com AKGWSB EzRT gitee https gitee com AKGWSB EzRT 目录 前言 0 前情回顾 1 微平面理论 2 BRDF 介绍 3 迪士尼原则的 BRD
  • 在vue中使用antV-G2展示柱状图

    介绍 G2 是一套基于图形语法理论的可视化底层引擎 以数据驱动 提供图形语法与交互语法 具有高度的易用性和扩展性 使用 G2 你可以无需关注图表各种繁琐的实现细节 一条语句即可使用 Canvas 或 SVG 构建出各种各样的可交互的统计图表
  • Android Display架构分析

    Fence https www jianshu com p 3c61375cc15b android12 display分析 https www cnblogs com roger yu p 15641545 html hwcomper h
  • 图形学/OpenGL/3D数学/Unity

    1 场景管理的数据结构 总结 游戏开发最常用的空间数据结构是四叉 八叉树和BVH树 而BSP树基本上只能应用于编辑器上 k d树则只能用在特殊问题应用场景 2 帧同步与状态同步 https gameinstitute qq com comm
  • 2021年 IEEE VIS 科学可视化与体渲染论文整理与分析

    因为最近工作的关系 需要研究一下IEEE VIS中2017年以后的与我之前主要方向 体渲染 医学可视化 有关的论文 我把这些年全部的论文进行了筛选和梳理 总共筛选出57篇论文 打算写一个文章来记录这些内容 这个栏目是2021年的九篇论文的介
  • 初识OpenGL (-)纹理过滤(Texture Filtering)

    1 OpenGL需要知道怎样将纹理像素 Texture Pixel 也叫Texel 映射到纹理坐标 纹理坐标 不依赖于分辨率 Resolution 它可以是任意浮点值 给模型顶点设置的那个数组 OpenGL以这个顶点的纹理坐标数据去查找纹理
  • Dx11--用dx11绘制棱台,并用键盘和鼠标进行旋转缩放操作

    目录 一 索引缓冲区 前言 创建缓冲区 缓冲区的描述 二 常量缓冲区 前言 准备工作 正式初始化 画面更新及其效果 画面更新 效果 三 键盘和鼠标的创建 1 鼠标的创建 2 键盘的创建 3 更新画面 4 消息回调函数 处理键盘鼠标信息 效果
  • OpenGL 7.测试框架,批渲染

    测试功能基类 本节搭建一个简单的测试框架 实现在窗口上显示一个菜单栏 点击不同的选项 进入不同的功能 附加目录中添加src 方便添加头文件 新建目录如下 测试基类 Test h 测试菜单TestMenu 用于管理所有的测试 pragma o
  • 计算机图形学GAMES101(十五)光线追踪(蒙特卡洛积分与路径追踪)

    本节涉及内容 蒙特卡罗积分 路径追踪 蒙特卡罗积分 蒙特卡罗积分的核心思想还是求一个不规则图形的面积 它的做法是 首先在a和b之间找一个值xi然后求f x 接着以f x 为高 ab为宽求矩形的面积 最后将所有的值求平均 当采样数量xi趋于无
  • 图形学基础1

    坐标系相关 uv可能会影响局部坐标系 如果light图和brdf图做卷积的时候 局部坐标系保持一致很重要 如下图 tangent是从外部模型文件进行加载的 切线空间采样并转世界坐标系 spherical to cartesian in ta
  • 游戏笔记本电脑可以进行 3D 建模和渲染吗?有哪些优势与缺点?

    3D 建模和渲染是创建令人惊叹的数字艺术 动画和游戏体验的最流行和最广泛使用的工具之一 随着技术的进步 对运行这些模型的强大计算机的需求呈指数级增长 对于那些寻求强大机器来处理 3D 建模任务的人来说 游戏笔记本电脑已成为一个可行的选择 游
  • 柏林噪声(Perlin Noise) 介绍及应用

    什么是噪声 信号处理中一般指原信号中不存在的无规则的额外信号 在处理过程中一般是我们不需要的 需要被处理掉的 噪声和信号本身无关 其频率和强弱变化无规律 噪声有什么用处 就如上面提到的那样 噪声是干扰原信号的存在 在信号处理中 我们一般都希
  • NeRF学习笔记(含公式、图解和过程)

    NeRF学习笔记 关注公众号 不定期分享NeRF相关文献 引言 NeRF Representing Scenes as Neural Radiance Fields for View Synthesis作为2020年ECCV的一篇论文 在用

随机推荐

  • 写出一个抽奖页面,有200个人参加抽奖

    写出一个抽奖页面 有200个人参加抽奖 每次抽出一个人 不能重复 必须每个人都要抽中奖 前面10次抽奖要选中固定的10个人 每次就从这10人中随机抽取一人 不能重复 从第11次开始就从剩余的190人当中抽奖 不能重复 直到抽奖结束 已经中过
  • Java实现输出 1000 - 2000 之间所有的闰年

    我之前写过一篇文章 输出1 100之内的素数 其实是差不多的 可以参考一下 https blog csdn net question mark article details 100627185 关于闰年我们知道 有三种情况 分别是普通闰年
  • 软件测试/测试开发丨学习笔记之接口自动化测试

    本文为霍格沃兹测试开发学社学员学习笔记分享 原文链接 https ceshiren com t topic 25120 一 接口自动化测试框架介绍 1 接口测试场景 2 自动化测试场景 3 接口自动化测试与 Web App 自动化测试区别
  • pands 表头字段自适应

    fields Unnamed 0 Unnamed 1 合计 人民币元 美元 合计 1 美元 1 沙特里亚尔 合计 2 人民币元 1 美元 2 沙特里亚尔 1 合计 3 美元 3 沙特里亚尔 2 cleaned sentence a 0 wh
  • 大模型时代,如何评估人工智能与人类智能?

    省时查报告 专业 及时 全面的行研报告库 省时查方案 专业 及时 全面的营销策划方案库 免费下载 2023年8月份全网热门报告合集 ChatGPT提词示例 让你的ChatGPT聪明100倍 超百页干货资料 AI应用的难点 痛点与未来 202
  • 软件测试最新项目合集【商城、外卖、银行、金融等等.......】

    项目一 ShopNC商城 项目概况 ShopNC商城是一个电子商务B2C电商平台系统 功能强大 安全便捷 适合企业及个人快速构建个性化网上商城 包含PC IOS客户端 Adroid客户端 微商城 系统PC 后台是基于ThinkPHP MVC
  • 同一个网站可以放2个服务器吗,两个网站放在同一个服务器 备案

    两个网站放在同一个服务器 备案 内容精选 换一换 介绍常见的安全组配置示例 如下示例中 出方向默认全通 仅介绍入方向规则配置方法 允许外部访问指定端口不同安全组内的弹性云服务器内网互通仅允许特定IP地址远程连接弹性云服务器SSH远程连接Li
  • python语法(高阶)-多线程编程

    演示多线程编程的使用 import time import threading def sing msg while True print msg time sleep 1 return None def dance msg while T
  • vue2+koa2+mongodb分页

    后端 const Koa require koa2 const Router require koa router const Monk require monk 链接mongodb数据库中间件 const app new Koa cons
  • 导入数据库

    导入数据库 数据库表 打开SQL Server数据库 选择数据库单击右键新建一个数据库表
  • Selenium爬虫实战丨Python爬虫实战系列(8)

    个人主页 互联网阿星 格言 选择有时候会大于努力 但你不努力就没得选 作者简介 大家好我是互联网阿星 和我一起合理使用Python 努力做时间的主人 如果觉得博主的文章还不错的话 请点赞 收藏 留言 支持一下博主哦 行业资料 PPT模板 简
  • 每天进步一点点-WPF-根据数据类型加载控件

    目的 根据数据类型的不同 动态的加载适用于不同数据类型的控件 布局 原理 为自定义的数据类型添加数据魔板 绑定的时候绑定这些数据类型的实例 例子 数据类型 数据模板
  • 达尔文商品管理

    什么是达尔文 达尔文是一套全新的商品管理体系 它不同于淘宝原来的分类法 基于类目属性体系 的管理思路 而是以最细粒度的产品节点 CSPU 为核心 使用系统 运营机制的方式维护一套丰富 准确的产品库 通过产品实现聚合 管控商品 以确保商品信息
  • Spring中typeAliasesPackage的作用

    typeAliasesPackage 是自动配置别名 也就是设置这个之后 在Mybatis的Mapper文件里就可以写对应的类名 而不用写全路径名了 例如 typeAliasesPackage xyz hashdog modules bea
  • UE4物体随着样条线(Spline)运动

    1 样条线原理 1 1 贝塞尔曲线 一定要经过起止点 若干个控制点用于控制曲线弯曲的方向 最终形成一条光滑的曲线 由于贝塞尔曲线点太多了不好控制 一般每四个点做一次贝塞尔曲线 得到的若干段相邻贝塞尔曲线的连接点需要共线且距离相同 即为C1连
  • Java 菜鸟入门

    前言 所谓进制转换 就是人们利用符号来计数的方法 进制转换由一组数码符号和两个基本因素 基数 和 位权 所构成 其中基数是指进位计数制中所采用的数码的个数 逢 n 进 1 中的 n 就是基数 而位权则指的是进位制中每一个固定位置所对应的单位
  • Vue PostCss插件——autoprefixer配置完成后无效,已解决

    在使用autoprefixer时 先前的配置能成功添加css浏览器前缀 但结合postcss pxtorem插件后 px可以转换为rem 但css前缀无效 经过几个小时的鼓捣 终于让我发现了蛛丝马迹 哈哈哈 好开心 好激动 一起来看一看博主
  • Vue.js面试题

    目录 1 如何再Vue的单文件组件里的样式定义全局CSS 2 vue router 3 1 0
  • C语言itoa函数实现-数字面值转字符串

    数字面值转字符串 思路 首先判断是否为负数若是则转为正数 将待转换的int类型值每次对10取余获得最低位的数字 将该数字转为字符面值 然后将int类型值除以10 直到等于0结束循环 此时由于是从int类型值的最低位开始取得 所以转换出来的字
  • Vulkan-实践第一弹

    上一篇文章中 我们浅析了Vulkan对传统图形API的优势 主要就是在其性能和精细化操控GPU上 具体可参考Vulkan 性能及精细化 今天我们就来用个简单的例子 亲身感受下Vulkan的开发 魅力 include