Search code examples
swifttexturesmetal

How can I get rid of blurry textures in Metal?


I just created a Metal template and changed up the code a little. I switched out the default colormap with the Minecraft 16x16 lapis ore texture, but for some reason they are blurred out when they are low resolution. I am trying to achieve that pixelated, Minecraft look and so would like to know how to disable this blurring/filtering.

Is there a way to load/present assets without this blurring? Here is my load asset function:

class func loadTexture(device: MTLDevice, textureName: String) throws -> MTLTexture {
    /// Load texture data with optimal parameters for sampling
    return try MTKTextureLoader(device: device).newTexture(name: textureName, scaleFactor: 1.0, bundle: nil, options: [
        MTKTextureLoader.Option.textureUsage: NSNumber(value: MTLTextureUsage.shaderRead.rawValue),
        MTKTextureLoader.Option.textureStorageMode: NSNumber(value: MTLStorageMode.`private`.rawValue)
    ])
}

Here is a screenshot of the blurry cube I'm getting:

Blurry cube


Solution

  • In your texture sample call (in the shader), you need to set your magnification filter to 'nearest', instead of 'linear', like so (assuming your sampler is declared inline inside your shader):

    constexpr sampler textureSampler (mag_filter::nearest, // <-- Set this to 'nearest' if you don't want any filtering on magnification
                                      min_filter::nearest);
    
    // Sample the texture to obtain a color
    const half4 colorSample = colorTexture.sample(textureSampler, in.textureCoordinate);