Ok I render metal shader from scenekit using scntechnique,
It's all of my setting
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>passes</key>
<dict>
<key>pass_backface</key>
<dict>
<key>metalVertexShader</key>
<string>backface_vertex</string>
<key>metalFragmentShader</key>
<string>backface_fragment</string>
<key>program</key>
<string>doesntexist</string>
<key>depthStates</key>
<dict>
<key>clear</key>
<true/>
</dict>
<key>colorStates</key>
<dict>
<key>clear</key>
<true/>
<key>clearColor</key>
<string>sceneBackground</string>
</dict>
<key>cullMode</key>
<string>front</string>
<key>includeCategoryMask</key>
<string>2</string>
<key>draw</key>
<string>DRAW_NODE</string>
<key>inputs</key>
<dict>
<key>aPos</key>
<string>vertex-symbol</string>
</dict>
<key>outputs</key>
<dict>
<key>color</key>
<string>backface</string>
</dict>
</dict>
<key>pass_mip</key>
<dict>
<key>colorStates</key>
<dict>
<key>clear</key>
<true/>
<key>clearColor</key>
<string>sceneBackground</string>
</dict>
<key>depthStates</key>
<dict>
<key>clear</key>
<true/>
</dict>
<key>metalVertexShader</key>
<string>mip_vertex</string>
<key>metalFragmentShader</key>
<string>mip_fragment</string>
<key>program</key>
<string>doesntexist</string>
<key>cullMode</key>
<string>back</string>
<key>includeCategoryMask</key>
<string>2</string>
<key>draw</key>
<string>DRAW_NODE</string>
<key>inputs</key>
<dict>
<key>aPos</key>
<string>vertex-symbol</string>
<key>viewport</key>
<string>screen_size</string>
<key>backface</key>
<string>backface</string>
<key>volume</key>
<string>volume</string>
</dict>
<key>outputs</key>
<dict>
<key>color</key>
<string>COLOR</string>
<key>depth</key>
<string>DEPTH</string>
</dict>
</dict>
</dict>
<key>sequence</key>
<array>
<string>pass_backface</string>
<string>pass_mip</string>
</array>
<key>targets</key>
<dict>
<key>backface</key>
<dict>
<key>type</key>
<string>color</string>
</dict>
</dict>
<key>symbols</key>
<dict>
<key>vertex-symbol</key>
<dict>
<key>semantic</key>
<string>vertex</string>
</dict>
<key>screen_size</key>
<dict>
<key>type</key>
<string>vec2</string>
</dict>
<key>volume</key>
<dict>
<key>type</key>
<string>sampler3D</string>
</dict>
</dict>
</dict>
</plist>
And, it's my metal shader code
#include <metal_stdlib>
using namespace metal;
#include <SceneKit/scn_metal>
struct VertexInput
{
float3 position [[ attribute(SCNVertexSemanticPosition) ]];
float2 uv [[attribute(SCNVertexSemanticTexcoord0)]];
};
struct NodeBuffer {
float4x4 modelTransform;
float4x4 modelViewTransform;
float4x4 normalTransform;
float4x4 modelViewProjectionTransform;
float2x3 boundingBox;
};
struct VertexOutput
{
float4 position [[position]];
float2 pixelCoord;
float3 color;
};
vertex VertexOutput backface_vertex(
VertexInput in [[ stage_in ]]
, constant SCNSceneBuffer& scn_frame [[buffer(0)]]
, constant NodeBuffer& scn_node [[buffer(1)]])
{
VertexOutput out;
out.position = scn_node.modelViewProjectionTransform
* float4(in.position, 1.0);
out.color = out.position.xyz;
return out;
}
fragment float4 backface_fragment(VertexOutput in [[stage_in]])
{
float4 color = float4(in.color, 1.0);
return color;
}
struct MipUniforms
{
float2 viewport;
};
vertex VertexOutput mip_vertex
(
VertexInput in [[ stage_in ]]
, constant SCNSceneBuffer& scn_frame [[buffer(0)]]
, constant NodeBuffer& scn_node [[buffer(1)]]
, constant MipUniforms& uniforms [[buffer(2)]]
)
{
VertexOutput out;
out.position = scn_node.modelViewProjectionTransform
* float4(in.position, 1.0);
out.color = out.position.xyz;
float2 viewport = uniforms.viewport;
out.pixelCoord = (in.position.xy - viewport * 0.5) / viewport;
return out;
}
fragment half4 mip_fragment ( VertexOutput in [[ stage_in ]],
texture2d<float> backface [[ texture(0) ]],
texture3d<float> volume [[ texture(1) ]]
)
{
constexpr sampler s(s_address::clamp_to_edge, t_address::clamp_to_edge, min_filter::linear, mag_filter::linear);
float3 rgb = backface.sample(s, in.pixelCoord).rgb;
float3 lookupColor = volume.sample(s, rgb, 0).rgb;
return half4(half3(lookupColor), 1.h);
}
And then I will set 3d texture at runtime.
So first time, 3d texture named volume is not set yet.