如何使用金属着色器语言中的引用参数定义函数,除了顶点,片段和内核函数

问题描述 投票:0回答:1

将一些基本的OpenGL ES 2.0着色器移植到Metal着色器时,我不知道如何将glsl中的in /​​ inout / out限定符转换为金属着色器语言(MSL)。例如,

//OpenGL vertex shader

...

void getPositionAndNormal(out vec4 position, out vec3 normal, out vec3 tangent, out vec3 binormal)
{
    position = vec4(1.0, 0.0, 1.0, 1.0);
    normal = vec3(1.0, 0.0, 1.0);
    tangent = vec3(1.0, 0.0, 1.0);
    binormal = vec3(1.0, 0.0, 1.0);
}

void main()

{
    ...

    vec4 position;
    vec3 normal;
    vec3 tangent;
    vec3 binormal;
    getPositionAndNormal(position, normal, tangent, binormal);

    ...
}

尝试转换为MSL时,我尝试在getPositionAndNormal参数中使用引用:

void getPositionAndNormal(float4 & position, float3 & normal, float3 & tangent, float3 & binormal);

我得到以下编译错误信息:reference type must have explicit address space qualifier

根据Metal-Shading-Language-Specification.pdf的4.2节,我使用设备地址空间来引用以下形式的getPositionAndNormal参数:

void getPositionAndNormal(device float4 & position, device float3 & normal, device float3 & tangent, device float3 & binormal);

这一次,我得到的错误消息是没有匹配函数来调用'getPositionAndNormal'。

void getPositionAndNormal (
  device float4 & position,
  device float3 & normal,
  device float3 & tangent,
  device float3 & binormal)
{
  position = float4(1.0, 0.0, 1.0, 1.0);
  normal = float3(1.0, 0.0, 1.0);
  tangent = float3(1.0, 0.0, 1.0);
  binormal = float3(1.0, 0.0, 1.0);
}

vertex ShaderOutput vertexShader (ShaderInput inputMTL [[stage_in]], constant ShaderUniform& uniformMTL [[buffer(1)]])
{
  ...

  float3 binormal = 0;
  float3 tangent = 0;
  float3 normal = 0;
  float4 position = 0;
  getPositionAndNormal (position, normal, tangent, binormal);

  ...
}

什么是正确的“金属”方式?

metal
1个回答
1
投票

vertexShader()中的局部变量位于thread地址空间,而不是device地址空间。因此,您应该将getPositionAndNormal()的参数声明为thread地址空间。

device地址空间用于设备共享的内容;也就是说,跨着着色器的所有“线程”或调用。这些变量特定于每个线程/调用。他们没有分享。

我怀疑完整的“无匹配函数”编译器错误会解释声明的参数与实际传递的参数之间的不匹配,尽管可能有些隐蔽。

© www.soinside.com 2019 - 2024. All rights reserved.