Search code examples
swiftshadermetalclip

Metal shader stage_in


I have a simple Metal shader downloaded from here: https://medium.com/@MalikAlayli/metal-with-scenekit-create-your-first-shader-2c4e4e983300. I have modified it by adding clip_distance to VertexOut. Everything works fine if clip_distance is a float. Since I need 6 clipping planes, I try to define it as a vector [[clip_distance]][6]. However, Xcode complains about the textureSamplerFragment routine, saying "Type 'VertexOut' is not valid for attribute 'stage_in'". I am new to Metal shader and have no idea about how to fix the error.

Can anyone give me a direction? Thank you in advance.

#include <metal_stdlib>
using namespace metal;
#include <SceneKit/scn_metal>

struct NodeBuffer {
    float4x4 modelTransform;
    float4x4 modelViewProjectionTransform;
    float4x4 modelViewTransform;
    float4x4 normalTransform;
    float2x3 boundingBox;
};

struct VertexInput {
    float3 position  [[attribute(SCNVertexSemanticPosition)]];
    float2 uv [[attribute(SCNVertexSemanticTexcoord0)]];
};


struct VertexOut {
    float4 position [[position]];
    float clip_distance [[clip_distance]][6];
    float2 uv;
};

vertex VertexOut textureSamplerVertex(VertexInput in [[ stage_in ]], constant NodeBuffer& scn_node [[buffer(1)]]) {
    VertexOut out;
    out.position = scn_node.modelViewProjectionTransform * float4(in.position, 1.0);
    out.clip_distance[0] = 1.5 - in.position.x;
    out.uv = in.uv;
    return out;
}

fragment float4 textureSamplerFragment(VertexOut out [[ stage_in ]], texture2d<float, access::sample> customTexture [[texture(0)]]) {
    constexpr sampler textureSampler(coord::normalized, filter::linear, address::repeat);
    return customTexture.sample(textureSampler, out.uv );
}

Solution

  • Based on this Metal Shading Language Specification:

    clip_distance attribute data types should be either float or float[n], n - must be known at compile time. You should change your shader logic to the corresponding requirements.