Hello Vulkan(五)| 图形渲染新技术Vulkan纹理


回顾
上一期技术分享中,我们讲述了如何关于Vulkan的Data Buffers使用及VMA内存管理器使用,自己创建或使用VMA在显存里创建Buffers,并在CPU进行读取或写入。
本期将继续分享关于Vulkan的技术,内容是非常有趣的部分,即「纹理绘制」,我们会介绍如何在Vulkan中如何进行纹理映射,所见即所得。很有趣的是,我们虹图的英文即“TexelJoy”,其中“Texel”就是纹理的最小单元 – 纹素,熟悉图形渲染的同学肯定不陌生,如果你感觉陌生也没关系,像素“Pixel”总听过吧,接下来本期讲述的内容也会涉及纹素和像素的关系。
基础概念
纹理映射:图形渲染中的一种将单独的图片映射覆盖到3D模型上,并且跟随模型移动、变换,映射到屏幕空间的图形渲染操作。
纹理:进行纹理映射的图片,部分硬件要求必须是2的整数幂,当然也并不是所有硬件的要求,确保安全最好是2的整数幂。
像素(Pixel):屏幕上的每个小点。
纹素(Texel):纹理上的每个小点。使用纹素这个术语,而不是像素来表示纹理对象中的显示元素,主要是为了强调纹理对象的应用方式。
纹理坐标:我们使用S,T来表示纹理对象中的纹素位置。S,T也可以用U,V来表示,纹理坐标有时也称UV坐标。

映射原理:带有纹理坐标的3D模型会在每个顶点都有ST纹理坐标,由纹理坐标找到对应应该在屏幕显示的纹理中纹素位置,如下图:

那么如何给每个顶点指定合适ST坐标呢?
平面比较容易,做个比例缩小即可:
 

球体那就要做一些运算:


 换做经纬度:

这样的模型呢?貌似有些复杂了。

这个可以放心,都是现成的自动化算法可以直接使用进行计算ST坐标。
存储类型
让我们回到Vulkan,先说内存类型,首先分为CPU内存和GPU显存,GPU显存则分为主机内存(Host Visible Memory)和设备内存(Device Local Memory)。CPU可以向主机内存进行读写操作。设备内存是一种设备可见的内存,常见的缓冲内存和图像内存,可以被设备本地快速使用,而设备内存最大的用处就是储存纹理,因为纹理读取是需要快速完成的。

在Vulkan里应该如何设置纹理映射的参数呢?我们先看下之前OpenGL如何进行参数设置的:
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
但在Vulkan里则是有一定区别的,但是类似于创建Buffer的操作。
MyTexture MyPuppyTexture;...VkSamplerCreateInfo vsci;vsci.magFilter = VK_FILTER_LINEAR;vsci.minFilter = VK_FILTER_LINEAR;vsci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;vsci.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;vsci.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;vsci.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;...result = vkCreateSampler( LogicalDevice, IN &vsci, PALLOCATOR, OUT &MyPuppyTexture->texSampler);
对比下Vulkan和OpenGL,其实可以发现在设置Mode为LINEAR(线性滤波法)时Vulkan是mipmapMode,而OpenGL只是Mode。那么这个Mipmap是什么意思呢?Mipmap是缩小版本的image,每个新image是前一张图的宽度和高度的一半。Mipmap用于作为细节级别(即Level of Detail)的一种方式。远离相机的物体将从较小的mip图像中采样纹理。使用较小的图像可以提高渲染速度,避免锯齿,具体做法就是平均4个像素,生成1个新的像素,依次循环。

最后放一个我觉得对大家有帮助的文件,就是如何把一个bmp、png、jpg图片读取成纹理。
typedef struct MyTexture{uint32_t width;uint32_t height;VkImage texImage;VkImageView texImageView;VkSampler texSampler;VkDeviceMemory vdm;} MyTexture;…MyTexture MyPuppyTexture;result = Init06TextureBufferAndFillFromBmpFile ( “puppy1.bmp”, &MyPuppyTexture); Init06TextureSampler( &MyPuppyTexture.texSampler );

具体读取代码的CPP文件已经放至公众号后台,回复“sample.cpp”即可获取。到这儿所有的Vulkan 纹理的内容就结束了。欢迎大家关注虹图AI开放平台公众号,后台留言交流,也欢迎大家移步至我们刚上线的开发者社区中交流和分享。
关于Vulkan关于Command Buffers的内容,我们会在本系列后续内容中继续与大家分享,Command Buffers也是Vulkan中很难理解,但却很重要的一部分内容。(虹图人像人体中美颜SDK部分是基于Vulkan进行开发封装的,性能极致,对开发者更加友好,十行之内完成一个简单的demo,点击【阅读原文】可查看详情。)
敬请期待~
到顶部