如何使用金属着色器语言中的引用参数定义函数,顶点、片段和内核函数除外
how to define functions with a referenced parameter in metal shader language except for vertex, fragment and kernel functions
将一些基本的 OpenGL ES 2.0 着色器移植到金属着色器时,我不知道如何将 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节,我使用设备地址space以下列形式引用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' 方法是什么?
vertexShader()
中的局部变量在thread
地址space,而不是device
地址space。因此,您也应该将 getPositionAndNormal()
的参数声明为 thread
地址 space。
device
地址 space 用于跨设备共享的内容;也就是说,在您的着色器的所有 "threads" 或调用中。这些变量特定于每个 thread/invocation。它们不共享。
我怀疑完整的 "no matching function" 编译器错误可以解释声明的参数和实际传递的参数之间的不匹配,尽管可能有点神秘。
将一些基本的 OpenGL ES 2.0 着色器移植到金属着色器时,我不知道如何将 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节,我使用设备地址space以下列形式引用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' 方法是什么?
vertexShader()
中的局部变量在thread
地址space,而不是device
地址space。因此,您也应该将 getPositionAndNormal()
的参数声明为 thread
地址 space。
device
地址 space 用于跨设备共享的内容;也就是说,在您的着色器的所有 "threads" 或调用中。这些变量特定于每个 thread/invocation。它们不共享。
我怀疑完整的 "no matching function" 编译器错误可以解释声明的参数和实际传递的参数之间的不匹配,尽管可能有点神秘。