在SceneKit中使用金属着色器 [英] Using a Metal shader in SceneKit

查看:123
本文介绍了在SceneKit中使用金属着色器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用Metal着色器将卡通/单元格阴影应用于场景中使用的材质.我要实现的着色器是在

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

该错误来自我尝试查找路径的第二行,它为我提供了在展开可选值时找到nil",这将在强制展开时得到预期,而事实并非是文件正在尝试执行该操作捆绑中肯定有负载,并且相同的代码可以与其他文件类型(而不是.metal文件)一起正常工作.

我是完全以错误的方式来做这件事吗?除了我滥用金属文件的问题外,我不明白为什么它无法访问该文件.

是否有一种更简单或更佳的方法来实现单元着色并最终在边缘上使用粗体轮廓?

解决方案

AAPLCelShader.metal是完整的顶点/ rastex /fragment实现,这不是shaderModifiers的含义:将被注入到已经完成的着色器中的源代码.

相反,您可以创建 SCNProgram ,使用APLCLCShaSha.metal中的顶点和片段函数.与GLSL相比,Metal的优点在于,您可以使用MetalShaderShowcase. I'm a little new to implementing shaders in SceneKit so I could be doing everything completely wrong.

From what I understand in the documentation a Metal or GL shader can be used to modify SceneKit rendering as of iOS 9 and Xcode 7. The documentation suggests that this is done in the same way as GL shaders.

My method is to try and get the path for the .metal file and then load it into a string to be used in the SCNMaterial shaderModifiers property in the form of a [String: String] dictionary, as you would with a GL shader (though I've yet to get that working properly).

My code is:

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 being run on a test scene with a single box geometry in it that is being loaded from a .scn file. The file loading works fine so that's not an issue.

The error comes from the second line where I try and find the path, it gives me the "found nil while unwrapping optional value" which would be expected with the force unwrapping, other than the fact that the file it is trying to load is most certainly in the bundle and the same code works fine with other file types, just not .metal ones.

Am I going about this completely the wrong way? I can't understand why it won't access the file other than an issue with me misusing the metal file.

Is there a simpler or better way to implement cell shading and eventually a bold outline on edges?

解决方案

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.

这篇关于在SceneKit中使用金属着色器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆