将 Metal Shader 纹理类型从 2D 转换为 2D Multisample

Converting Metal Shader texture type from 2D to 2D Multisample

我正在关注 2etime 在 YouTube 上关于 Apple Metal 图形 API 的教程。一切都按预期工作,但是当我尝试更改视图的样本数时,出现了很多错误。但是,这些错误很容易修复。到目前为止,我已经更改了每个文件中的样本计数,但我仍然停留在着色器上。要更改 view 的 样本计数,您必须更改 texture 样本计数(至少在我的情况下),并更改纹理样本计数,您必须将纹理类型更改为多重采样。这很容易做到。但是,在此更改之后,我从着色器中得到错误。看起来片段着色器使用 texture2d,我需要将其更改为 texture2d_ms,但是当我这样做时,我收到错误提示 'sample' 函数无效。我将 post 代码和错误。我试过在互联网上搜索,但似乎找不到任何东西。

FinalShaders.metal

#include <metal_stdlib>
#include "Shared.metal"
using namespace metal;

struct FinalRasterizerData {
    float4 position [[ position ]];
    float2 textureCoordinate;
};

vertex FinalRasterizerData final_vertex_shader(const VertexIn vIn [[ stage_in ]]) {
    FinalRasterizerData rd;
    
    rd.position = float4(vIn.position, 1.0);
    rd.textureCoordinate = vIn.textureCoordinate;
    
    return rd;
}

fragment half4 final_fragment_shader(const FinalRasterizerData rd [[ stage_in ]],
                                     texture2d_ms<float> baseTexture) {
    sampler s;
    
    float2 textureCoordinate = rd.textureCoordinate;
    textureCoordinate.y = 1 - textureCoordinate.y;
    
    float4 color = baseTexture.sample(s, textureCoordinate);
    
    return half4(color);
}

Shared.metal

#ifndef SHARED_METAL
#define SHARED_METAL

#include <metal_stdlib>
using namespace metal;

struct VertexIn {
    float3 position [[ attribute(0) ]];
    float4 color [[ attribute(1) ]];
    float2 textureCoordinate [[ attribute(2) ]];
    float3 normal [[ attribute(3) ]];
    float3 tangent [[ attribute(4) ]];
    float3 bitangent [[ attribute(5) ]];
};

struct RasterizerData{
    float4 position [[ position ]];
    float4 color;
    float2 textureCoordinate;
    float totalGameTime;
    
    float3 worldPosition;
    float3 toCameraVector;
    
    float3 surfaceNormal;
    float3 surfaceTangent;
    float3 surfaceBitangent;
};

struct ModelConstants{
    float4x4 modelMatrix;
};

struct SceneConstants{
    float totalGameTime;
    float4x4 viewMatrix;
    float4x4 skyViewMatrix;
    float4x4 projectionMatrix;
    float3 cameraPosition;
};

struct Material {
    float4 color;
    bool isLit;
    bool useBaseTexture;
    bool useNormalMapTexture;
    
    float3 ambient;
    float3 diffuse;
    float3 specular;
    float shininess;
};

struct LightData {
    float3 position;
    float3 color;
    float brightness;
    
    float ambientIntensity;
    float diffuseIntensity;
    float specularIntensity;
};

#endif

错误:

No member named 'sample' in 'metal::texture2d_ms<float, metal::access::read, void>'

我知道它清楚地表明 'sample' 不存在,但我找不到任何解决方案。当我删除它并用不同的值替换 return 时,我只看到很多 green/yellow 行,没有 3d 对象。感谢您的帮助!

(发生错误的着色器是最终 shaders.metal 中的第一个片段)

sample 函数意味着的方式进行采样对于多重采样纹理没有意义。您正在寻找的是在给定的 texcoord 处读取确切的样本值。

如果您查看 Metal Shader Language specification,在第 6.12.8 节中它描述了 2D 多重采样纹理存在哪些函数。

其中包括:

Tv read(uint2 coord, uint sample) const
Tv read(ushort2 coord, ushort sample) const 

uint get_width() const
uint get_height() const
uint get_num_samples() const

read函数中,coord表示像素坐标,所以它们在X轴上从0get_width(),从0get_height() 在 Y 轴上。 sample 是样本的索引,所以它会从 0get_num_samples()