将一些基本的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);
...
}
什么是正确的“金属”方式?
vertexShader()
中的局部变量位于thread
地址空间,而不是device
地址空间。因此,您应该将getPositionAndNormal()
的参数声明为thread
地址空间。
device
地址空间用于设备共享的内容;也就是说,跨着着色器的所有“线程”或调用。这些变量特定于每个线程/调用。他们没有分享。
我怀疑完整的“无匹配函数”编译器错误会解释声明的参数与实际传递的参数之间的不匹配,尽管可能有些隐蔽。