4

我想使用Metal着色器将卡通/单元格着色应用于场景中使用的材质。我试图实现的着色器是 AppleAAPLCelShaderMetalShaderShowcase中找到的。我对实现着色器有点陌生,SceneKit所以我可能做的一切都完全错误。

根据我在文档中的理解,aMetal或 GL 着色器可用于修改SceneKitiOS 9 和 Xcode 7 的渲染。文档建议这与 GL 着色器的方式相同。

我的方法是尝试获取.metal文件的路径,然后将其加载到一个字符串中SCNMaterial shaderModifiers,以 [String: String] 字典的形式在属性中使用,就像使用 GL 着色器一样(尽管我还没有使其正常工作)。

我的代码是:

var shaders = [String: String]()
let path = NSBundle.mainBundle().pathForResource("AAPLCelShader", ofType: "metal")!

do{
  let celShader = try String(contentsOfFile: path, encoding: NSUTF8StringEncoding)
  shaders[SCNShaderModifierEntryPointLightingModel] = celShader
}catch let error as NSError{
  error.description
}
scene.rootNode.enumerateChildNodesUsingBlock({ (node, stop) -> Void in
  node.geometry?.firstMaterial?.shaderModifiers = shaders
})

这是在一个测试场景上运行的,其中有一个从.scn文件加载的盒子几何图形。文件加载工作正常,所以这不是问题。

错误来自我尝试查找路径的第二行,它给了我“在展开可选值时找到 nil”,这是强制展开时预期的,除了它尝试加载的文件是大多数当然在捆绑包中,相同的代码适用于其他文件类型,但不是.metal

我会以完全错误的方式解决这个问题吗?除了我滥用金属文件的问题外,我不明白为什么它不会访问该文件。

有没有更简单或更好的方法来实现单元格着色并最终在边缘上加粗轮廓?

4

1 回答 1

4

AAPLCelShader.metal is a complete vertex/rastex/fragment implementation, which is not what shaderModifiers are: source code that will be injected into already-complete shaders.

Instead, you can create an SCNProgram, using the vertex and fragment functions in AAPLCelShader.metal. What's nice about Metal, versus GLSL, is that you can use names of Metal functions, instead of source code strings, which is easier to work with, and results in having the functions compiled before runtime, which GLSL doesn't support. (This is still not as good as it should be, where Swift would recognize the Metal functions as correctly-typed, refactorable, namespaced closures.) Of course, while GLSL SCNPrograms will be converted to Metal, for compatible hardware, Metal SCNPrograms will not be translated for obsolete devices.

As for mapping from SceneKit to the rastex's (incorrectly-named ColorInOut) members:

float4 position [[position]];
float shine;
float3 normal_cameraspace;
float3 eye_direction_cameraspace;
float3 light_direction_cameraspace;

…I unfortunately do not have an answer for you yet.

于 2015-06-20T12:41:09.040 回答