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 ); 

关于Vulkan关于Command Buffers的内容,我们会在本系列后续内容中继续与大家分享,Command Buffers也是Vulkan中很难理解,但却很重要的一部分内容。

敬请期待~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

虹图AI开放平台

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值