我想在SCNView上的 Swift Playgrounds中使用带有Metal着色器的SCNTechnique.因此,我尝试使用以下代码编译着色器: guard let metalDevice = sceneView.device else { return}if let path = Bundle.main.path(forResource: "di
guard let metalDevice = sceneView.device else { return } if let path = Bundle.main.path(forResource: "distortTechnique", ofType: "metal") { do { let contents = try String(contentsOf: URL(fileURLWithPath: path)) do { try metalDevice.makeLibrary(source: contents, options: nil) } catch { error print(error) } } catch { // contents could not be loaded } }
文件已加载但我收到以下编译器错误:
Error Domain=MTLLibraryErrorDomain Code=3 "Compilation failed: program_source:11:10: fatal error: 'SceneKit/scn_metal' file not found #include <SceneKit/scn_metal> ^ " UserInfo={NSLocalizedDescription=Compilation failed: program_source:11:10: fatal error: 'SceneKit/scn_metal' file not found #include <SceneKit/scn_metal> ^ }
所以似乎无法找到»scn_metal«库.
知道如何解决这个问题吗?
相同的设置在iOS App项目中运行得非常好.
这是着色器代码:
#include <metal_stdlib> using namespace metal; #include <SceneKit/scn_metal> struct custom_vertex_t { float4 position [[attribute(SCNVertexSemanticPosition)]]; }; constexpr sampler s = sampler(coord::normalized, address::repeat, filter::linear); struct out_vertex_t { float4 position [[position]]; float2 uv; float time; float random; }; vertex out_vertex_t pass_through_vertex(custom_vertex_t in [[stage_in]], constant SCNSceneBuffer& scn_frame [[buffer(0)]]) { out_vertex_t out; out.position = in.position; out.uv = float2((in.position.x + 1.0) * 0.5 , (in.position.y + 1.0) * -0.5); out.time = scn_frame.time; return out; }; fragment half4 pass_through_fragment(out_vertex_t vert [[stage_in]], texture2d<float, access::sample> colorSampler [[texture(0)]]) { float4 fragment_color = colorSampler.sample( s, vert.uv); return half4(fragment_color); }; fragment half4 distort_fragment(out_vertex_t vert [[stage_in]], texture2d<float, access::sample> colorSampler [[texture(0)]]) { float multiplier = sin(vert.time * 0.5); float effectRadius = 0.75; float effectAmount = 360. * 2.; float effectAngle = multiplier * effectAmount; effectAngle = effectAngle * M_PI_F / 180; float2 resolution = float2(colorSampler.get_width(), colorSampler.get_height()); float2 center = float2(0.5, 0.5);//iMouse.xy / iResolution.xy; float2 uv = vert.position.xy / resolution - center; float len = length(uv * float2(resolution.x / resolution.y, 1.)); float angle = atan2(uv.y, uv.x) + effectAngle * smoothstep(effectRadius, 0., len); float radius = length(uv); float4 fragment_color = colorSampler.sample(s, float2(radius * cos(angle), radius * sin(angle)) + center); return half4(fragment_color); };
附件是操场的图像.
谢谢!
我最终通过预编译实际应用程序项目的金属库来使用它,然后将结果default.metallib与操作中包含的着色器函数一起使用.这似乎是必要的,因为顶点和碎片的SCNTechnique文档,这些函数必须存在于应用程序的默认金属库中.«
有点hacky但是为我的目的工作.
具体步骤:
– 为选定平台创建新的应用项目
– 使用所有定义设置SCNTechnique plist
– 使用着色器代码添加.metal文件
– 实现项目
– 打开archieved包并将default.metallib文件复制到您的游乐场资源文件夹中
– 现在只需在SCNView上设置您的技术
– 利润.
再次感谢Oliver的帮助!