从零开始的 Vulkan(八):计算管线
假如离开了图形渲染,GPU 还能干什么?GPU 通用计算(General-purpose computing on GPU,GPGPU)向我们展现了一个美好的图景,使用 GPU 强大的并行处理能力,能够将 CPU 从的大量的重复运算中解放出来,实现远超传统 CPU 处理的运算速度。
在 GPGPU 的道路上,有诸如 OpenGL 的计算着色器,微软的 Direct Compute,NVIDIA 的 CUDA 这些前辈,Vulkan 同样也有其自己的用于 GPGPU 的 API,也就是我们这节所要了解的计算管线。
存储资源对象
创建存储资源对象
在光栅化渲染中,我们通过将帧缓冲绑定到渲染通道上,来向渲染目标中写入像素数据。但在计算管线中,既没有渲染通道也没有帧缓冲的概念,我们要做的事情更加简单,创建一个用于读写数据的存储资源对象,并通过描述符将其绑定到着色器阶段上,直接在着色器中对其进行原子操作(atomic operations)。
存储资源对象有以下几种:
Storage Buffer:以缓冲的形式存储数据。
Storage Buffer Dynamic:除了指定偏移的方式以外,和 ...
离散数学(二):图论、数论与代数结构
本文承接自《离散数学(一)》,主要讲述基础图论、数论、群环域以及格的相关内容。
数学分析初步(四):多元函数
在本文中,我们进入多元函数的世界,了解多元函数微分学,方向导数、梯度与多元函数分析的相关内容。
高等数学:空间解析几何基础
在本文中,我们简单了解在高等数学中所应用到的空间解析几何知识,包括直线、平面、曲面的方程,以及它们的关系。
从零开始的 Vulkan(七):光线追踪
光线追踪支持
硬件光线追踪图形API是由 DXR(DirectX Ray Tracing)首先提出并实现的,随后 Vulkan 也引入了光线追踪并作为扩展功能由 NVIDIA 完成实现。在 Vulkan 1.2 后,光线追踪正式进入了 Vulkan 核心部分并成为了 KHR 扩展功能。
既然是扩展功能,那么就代表并不是所有平台上都可以使用,以 NVIDIA RTX 为首的显卡自然是能够使用硬件光追,部分 GTX 显卡也可以籍由驱动实现伪硬件光追,同时 AMD 显卡也在努力完善对硬件光追的支持。
为了使 Vulkan 支持光线追踪,需要开启以下相关 KHR 扩展:
1234567891011121314151617181920212223242526272829deviceExtensions.emplace_back(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME);deviceExtensions.emplace_back(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME);deviceExtensions ...
离散数学(一):数理逻辑与集合论
由于计算机中的数据都以离散量的形式存储,处于对研究数据结构和算法的需要,离散数学成为了计算机科学必备的前置科目。离散数学是一门证明较多,实用性较强的学科,因此概念和定理也非常繁杂。
离散量:逻辑量,图,树,整数,布尔代数等
连续量:温度,压力,体积,电压等
命题逻辑
命题逻辑与联结词
所谓命题(proposition),是指一句有真假意义的话。我们用大写的英文字母 P,Q,R,⋯P,Q,R,\cdotsP,Q,R,⋯,代表一个抽象的命题,称为命题符号。
如果一个命题为真,则称其真值为1,也用“1”代表一个抽象的真命题;如果一个命题为假,则称其真值为0,也用“0”代表一个抽象的假命题。
命题“PPP 是不对的”称为 PPP 的否定,记作 ¬P\neg P¬P,读作非 PPP.
真值规定:¬P\neg P¬P 为真 ⟺ \iff⟺ PPP 为假。
命题“PPP 或者 QQQ”称为 P,QP,QP,Q 的析取(disjunctive),记作 P∨QP\vee QP∨Q,读作 PPP 或 QQQ.
真值规定:P∨QP\vee QP∨Q 为真 ⟺ \iff⟺ P,QP,QP,Q 中至 ...
一篇文章学完 Effective C++:条款 & 实践
虽然笔者和 C++ 结识已经很长时间了,但一直没有阅读过这本久负盛名的著作 Effective C++,在此,我将结合自己对 Modern C++ 的理解,记录自己的阅读笔记,并且将内容以条款 & 实践的方式呈现,以求更加清晰的理解。
第一章:让自己习惯 C++
条款 1:视 C++ 为一个语言联邦
C++ 拥有多种不同的编程范式,而这些范式集成在一个语言中,使得 C++ 是一门即灵活又复杂的语言:
传统的面向过程 C:区块,语句,预处理器,内置数据类型,数组,指针。
面向对象的 C with Classes:类,封装,继承,多态,动态绑定。
模板编程 Template C++ 和堪称黑魔法的模板元编程(TMP)。
C++ 标准库 STL。
C++ 高效编程守则视情况而变化,程序设计没有银弹。
条款 2:尽量以 const, enum, inline 替换 #define
在原书写成时 C++11 中的constexpr还未诞生,现在一般认为应当用constexpr定义编译期常量来替代大部分的#define宏常量定义:
1#define ASPECT_RATIO 1.653 ...
现代实时渲染技术笔记(一):阴影
最近一直在写大量的工程代码,解决工程上的问题,颇有些令人疲惫,所以在此之际想开一个新的专栏,以理论为主,每篇文章讨论一个实时渲染的技术话题,以激励自己继续理论知识的学习。同样的,这些文章也是在前人研究的基础上归纳总结出的,参考资料有GAMES101/202,RTR以及各路大佬的技术文章,希望能帮助到更多想要学习的人。
投射平面阴影
阴影映射基础
在光栅化中,之所以阴影的绘制是一个比较麻烦的事,是因为在只考虑局部光照的情况下,我们无法知道完整的环境信息,自然也无法知道哪些地方光线会被遮挡,哪些地方处于光照之下,为了在一定程度上补全环境信息,我们通常会采用阴影映射(Shadow mapping)。阴影映射的概念最初由 Lance Williams 于1978年在论文中提出,通过额外的开销预渲染一张阴影贴图,来做到在真正渲染时判断哪些地方处于阴影当中。
传统的做法需要过两遍Pass,在第一遍Pass中从光源的角度进行场景的渲染,并且将深度测试得到的结果存储在一张深度贴图中,在第二遍Pass中使用。一般在投射方向光阴影时使用正交投影,投射点光源/聚光灯阴影时使用透视投影。
如何使用阴影贴图? ...
使用模板技巧和LibClang实现简易C++静态反射系统
在游戏引擎的设计中,我们经常会需要从外部去修改在程序代码中定义的变量,例如在代码中定义一个角色的速度,将其曝露在编辑器中,使我们在调试的时候只需要在编辑器中修改对应的值,而不需要每次都修改对应的代码,这种使数据和实现分离的思想是游戏引擎设计中的核心一环。
为了实现这个功能,我们就需要引入反射(Reflection) 的概念。所谓反射,就是指程序可以访问,检测和修改它本身状态或行为的一种能力,而在C++里,就是可以通过字符串表示的类名找到程序中对应的类,以及访问和修改类中的成员变量/成员函数的功能。
反射的实现主要有以下两个方法:
运行时反射:在运行时创建反射的注册表,将所有要反射的类写入注册表中。
编译期反射:给所有要反射的类指定宏,并在编译期自动生成反射类的代码。
这里我选择以运行时反射为基础,先成功获取所有的反射信息,之后要进行代码生成或者静态反射就十分容易了。
运行时反射
以下代码部分参考RTTR库以及 https://github.com/taichi-dev/cpp-training-season1 实现。
创建全局注册表
我们需要一个基本的数据结构来描述反射出的类是 ...
矩阵代数(三):特征值与二次型
在本文中,我们主要研究特征矩阵和特征值的求法和性质,了解合同变换的概念,以及解决基本的二次型问题。