14

Metal 示例之 Mipmap

 3 years ago
source link: http://blog.danthought.com/programming/2018/07/06/metal-by-example-mipmap/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

本文主要通过自己对 Metal By Example 理解编写,这一篇文章讲解 Metal 在纹理映射中使用 Mipmap。

Metal By Example Cover

Mipmap 理论

当纹理元素与屏幕像素不一致的时候,就需要过滤方式来处理两者之间的映射,纹理图像就可能会被拉升或缩小,Mipmap 先将纹理图像,按照每次比之前缩小 4/1 的方式处理,直到只有 1 个像素大小,每一次处理的图像称为 1 个等级,处理多少次就有多少个等级。

当 Mipmaped 的纹理图像在被 Sample 的时候,根据区域片段的大小来决定采用什么等级的纹理图像。

通过设置不同的 minFilter 和 mipFilter 可以产生 4 种组合:

选择最近的一个等级的纹理图像,Sample 的时候选择一个纹理元素:

MTLSamplerDescriptor *samplerDesc = [MTLSamplerDescriptor new];
samplerDesc.minFilter = MTLSamplerMinMagFilterNearest;
samplerDesc.mipFilter = MTLSamplerMipFilterNearest;

选择最近的两个等级的纹理图像,Sample 的时候从中各选一个纹理元素,再取平均得到最终结果:

MTLSamplerDescriptor *samplerDesc = [MTLSamplerDescriptor new];
samplerDesc.minFilter = MTLSamplerMinMagFilterNearest;
samplerDesc.mipFilter = MTLSamplerMipFilterLinear;

选择最近的一个等级的纹理图像,Sample 的时候从中各选四个纹理元素,再取平均得到最终结果:

MTLSamplerDescriptor *samplerDesc = [MTLSamplerDescriptor new];
samplerDesc.minFilter = MTLSamplerMinMagFilterLinear;
samplerDesc.mipFilter = MTLSamplerMipFilterNearest;

选择最近的两个等级的纹理图像,Sample 的时候从中各选四个纹理元素,再取平均得到最终结果:

MTLSamplerDescriptor *samplerDesc = [MTLSamplerDescriptor new];
samplerDesc.minFilter = MTLSamplerMinMagFilterLinear;
samplerDesc.mipFilter = MTLSamplerMipFilterLinear;

创建 Mipmap 各等级的纹理图像

mipmapped 为 YES

MTLTextureDescriptor *descriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatRGBA8Unorm
                                                                                      width:size.width
                                                                                     height:size.height
                                                                                  mipmapped:YES];
id<MTLTexture> texture = [device newTextureWithDescriptor:descriptor];

通过 CG 创建每一等级的纹理图像

MTLRegion region = MTLRegionMake2D(0, 0, mipWidth, mipHeight);
[texture replaceRegion:region mipmapLevel:level withBytes:[mipData bytes] bytesPerRow:mipBytesPerRow];

通过 Blit Command Encoder 创建每一等级的纹理图像

id<MTLBlitCommandEncoder> commandEncoder = [commandBuffer blitCommandEncoder];
[commandEncoder generateMipmapsForTexture:texture];
[commandEncoder endEncoding];
[commandBuffer addCompletedHandler:^(id<MTLCommandBuffer> buffer) {
    completionBlock(texture);
}];
[commandBuffer commit];

代码和效果

danjiang / mbe-sample-code / Mipmapping


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK