Metal 示例之 Mipmap
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.
本文主要通过自己对 Metal By Example 理解编写,这一篇文章讲解 Metal 在纹理映射中使用 Mipmap。
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];
代码和效果
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK