Using the metal shader in SceneKit

I would like to use a shader Metal

to apply the toon / cell tint to the materials used in the scene. The shader I'm trying to implement is proprietary to Apple AAPLCelShader

, found in MetalShaderShowcase . I'm a bit new to implementing shaders in SceneKit

, so I might be doing it completely wrong.

From what I understand in the documentation it is possible to use Metal

either the GL shader to change the SceneKit

rendering since iOS 9 and Xcode 7. The documentation assumes this is done in the same way as the GL shaders.

My method is to try to get the path to the file .metal

and then load it into a string to be used in the SCNMaterial

shaderModifiers

dictionary property [String: String], as you would with a GL shader (although I haven't gotten it working right yet).

My code:

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
})

      

This is done on a test scene with one window geometry loaded from a file .scn

. The file upload works fine, so the problem does not occur.

The error comes from the second line where I am trying to find the path, it gives me a "found zero when expanding an optional value" which one would expect when deploying a force, other than that the file it is trying to download is definitely included. and the same code works fine with other file types, not .metal

.

Am I completely wrong about this? I can't figure out why it won't access the file, other than the metal file misuse issue.

Is there an easier or better way to implement cell shading and eventually a bold outline around the edges?

+3


source to share


1 answer


AAPLCelShader.metal is a full vertex / rastex / implementation of a fragment, which is not what shader modulators are: the source code to be injected into the already-complete shaders.

Instead, you can create an SCNProgram using the vertex and fragment functions in AAPLCelShader.metal. What's different from both Metal and GLSL is that you can use Metal function names instead of source lines that are easier to work with and causes functions to be compiled before execution that GLSL does not support. (This is still not as good as it should be when Swift recognizes Metal functions as properly typed, refactorable private names.) Of course, while GLSL SCNPrograms will be converted to Metal for compatible hardware, Metal SCNPrograms will not be deprecated. devices.

Regarding mapping from SceneKit to Rastex members (incorrectly named ColorInOut):



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

      

... Unfortunately, I don't have an answer yet.

+3


source







All Articles