如何使用MTLSamplerState而不是在片段着色器代码中声明采样器? 如何创建SamplerState 使用方法

我在下面的着色器中定义了采样器(constexpr sampler textureSampler (mag_filter::linear,min_filter::linear);)。

    using namespace metal;

    struct ProjectedVertex {
      'float4 position [[position]];
      'float2 textureCoord;
    };

    fragment float4 fragmentShader(const ProjectedVertex in [[stage_in]],const texture2d<float> colorTexture [[texture(0)]],constant float4 &opacity [[buffer(1)]]){

      constexpr sampler textureSampler (mag_filter::linear,min_filter::linear);
      const float4 colorSample = colorTexture.sample(textureSampler,in.textureCoord);
      return colorSample*opacity[0];

    }

现在,我要避免在着色器代码中几乎不定义此采样器。我发现了MTLSamplerState,但我不知道如何使用它

ls_liusong 回答:如何使用MTLSamplerState而不是在片段着色器代码中声明采样器? 如何创建SamplerState 使用方法

如何创建SamplerState

首先,声明MTLSamplerDescriptor并配置一些属性,例如addressModes,magFilter,minFilter。 其次,从makeSamplerState调用MTLDevice方法。大多数情况下为默认设备。

您可以使用以下代码。希望对您有所帮助。

private static func buildSamplerState() -> MTLSamplerState? {
    let descriptor = MTLSamplerDescriptor()
    descriptor.sAddressMode = .repeat // .clampToEdge,.mirrorRepeat,.clampToZero
    descriptor.tAddressMode = .repeat // .clampToEdge,.clampToZero
    descriptor.magFilter = .linear // .nearest
    descriptor.minFilter = .linear // .nearest
    let samplerState = MTLCreateSystemDefaultDevice()?.makeSamplerState(descriptor: descriptor)
    return samplerState
}

使用方法

...

let samplerState = buildSamplerState()
...

// call `makeRenderCommandEncoder` to create commandEncoder from commandBuffer
let commandEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: renderPassDescriptor)
commandEncoder.setFragmentSamplerState(samplerState,index: 0)


在片段着色器中



fragment float4 exampleShader(VertexIO       inputFragment [[stage_in]],sampler textureSampler [[sampler(0)]],texture2d<float> inputTexture [[texture(0)]])
{
    float2 position = inputFragment.textureCoord;
    // ...
    return inputTexture.sample(textureSampler,position);
}

,

要创建采样器,请首先创建 MTLSamplerDescriptor 对象,然后配置描述符的属性。然后在将使用此采样器的 MTLDevice 对象上调用newSamplerStateWithDescriptor:方法。创建采样器后,您可以释放描述符或重新配置其属性以创建其他采样器。

// Create default sampler state
MTLSamplerDescriptor *samplerDesc = [MTLSamplerDescriptor new];
samplerDesc.rAddressMode = MTLSamplerAddressModeRepeat;
samplerDesc.sAddressMode = MTLSamplerAddressModeRepeat;
samplerDesc.tAddressMode = MTLSamplerAddressModeRepeat;
samplerDesc.minFilter = MTLSamplerMinMagFilterLinear;
samplerDesc.magFilter = MTLSamplerMinMagFilterLinear;
samplerDesc.mipFilter = MTLSamplerMipFilterNotMipmapped;
id<MTLSamplerState> ss = [device newSamplerStateWithDescriptor:samplerDesc];

设置片段功能的采样器状态:

    id<MTLRenderCommandEncoder> encoder = [commandBuffer renderCommandEncoderWithDescriptor: passDescriptor];
     ...
    [encoder setFragmentSamplerState: ss atIndex:0];

从着色器访问:

fragment float4 albedoMainFragment(ImageColor in [[stage_in]],texture2d<float> diffuseTexture [[texture(0)]],sampler smp [[sampler(0)]]) {

    float4 color = diffuseTexture.sample(smp,in.texCoord);
    return color;
}
本文链接:https://www.f2er.com/3047765.html

大家都在问