在我的SceneKit node 上,我希望应用磨砂玻璃效果,如下所示:
https://www.shadertoy.com/view/WdSGz1个
该着色器将纹理作为输入,并输出纹理的"模糊"版本.我想要的是创建一个SCNProgram(),并将其应用于我的一个 node 的material ,以便它具有磨砂玻璃纹理.
我试着用金属着色器重现这一点,但我不太熟悉它的工作原理.我是这样写的:
#include <metal_stdlib>
using namespace metal;
#include <SceneKit/scn_metal>
struct NodeBuffer {
float4x4 modelTransform;
float4x4 modelViewProjectionTransform;
float4x4 modelViewTransform;
float4x4 normalTransform;
float2x3 boundingBox;
};
struct MyNodeBuffer {
float4x4 modelTransform;
float4x4 inverseModelTransform;
float4x4 modelViewTransform;
float4x4 inverseModelViewTransform;
float4x4 normalTransform;
float4x4 modelViewProjectionTransform;
float4x4 inverseModelViewProjectionTransform;
};
struct VertexInput {
float3 position [[attribute(SCNVertexSemanticPosition)]];
float2 uv [[attribute(SCNVertexSemanticTexcoord0)]];
};
struct VertexOut {
float4 position [[position]];
float2 uv;
};
vertex VertexOut vertexFunction(VertexInput in [[ stage_in ]], constant NodeBuffer& scn_node [[buffer(1)]]) {
VertexOut out;
out.position = scn_node.modelViewProjectionTransform * float4(in.position, 1.0);
out.uv = in.uv;
return out;
};
float stepfun(float x) {
return (sign(x) + 1.0) / 2.0;
}
float square(float2 pos) {
return (stepfun(pos.x + 1.0) * stepfun(1.0 - pos.x)) *
(stepfun(pos.y + 1.0) * stepfun(1.0 - pos.y));
};
constexpr sampler textureSampler(coord::normalized, filter::linear, address::repeat);
float2 dist(float2 pos, texture2d<float,access::sample> texture [[ texture(0) ]])
{
float2 offset = pos;
return pos + square((offset - 0.5) * 3.0) * texture.sample(textureSampler, (offset - 0.5) * 5.0).xy * 0.05;
}
fragment float4 fragmentFunction(VertexOut out [[ stage_in ]],
texture2d<float, access::sample> texture [[ texture(0) ]],
device float3 *resolution [[ buffer(0) ]])
{
float2 uv = out.uv / resolution[0].xy;
float4 tex = texture.sample(textureSampler, dist(uv, texture));
tex.a = 0.5;
return tex;
}
但是,我需要将纹理作为我的FragmentFunction的输入,而我不知道这应该是什么.我希望它是我的 node 在没有着色器的情况下的纹理.