2015-06-19 79 views
3

我想使用一個Metal着色器來將場景/單元格着色應用於場景中使用的材質。我試圖實現的着色器是在MetalShaderShowcase中找到的Apple自己的AAPLCelShader。我在SceneKit中實現着色器有點新,所以我可能會做一切完全錯誤的。在SceneKit中使用金屬着色器

根據我在文檔中的瞭解,Metal或GL着色器可用於修改從iOS 9和Xcode 7開始的SceneKit渲染。文檔表明這與GL着色器以相同的方式完成。

我的方法是嘗試並獲得路徑,.metal文件,然後將其加載到要在SCNMaterialshaderModifiers財產的形式使用的字符串[字符串:字符串]字典,就像使用一個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文件中加載運行。文件加載工作正常,所以這不是一個問題。

錯誤來自我嘗試找到路徑的第二行,它給了我「解開可選值時發現的零」,這與解開力所期望的一樣,除了它正在嘗試的文件加載肯定是在捆綁和相同的代碼與其他文件類型正常工作,只是不是.metal之一。

我是否完全錯誤地回答這個問題?我不明白爲什麼它不會訪問文件,而不是我濫用金屬文件的問題。

是否有更簡單或更好的方法來實現單元格陰影並最終在邊緣上顯示粗體輪廓?

回答

3

AAPLCelShader.metal是一個完整的頂點/ rastex/fragment實現,它不是shaderModifiers的一部分:將被注入已完成着色器的源代碼。

取而代之,您可以使用AAPLCelShader.metal中的頂點和片段函數創建SCNProgram。 Metal與GLSL相比,不錯,您可以使用names of Metal functions而不是源代碼字符串,它更易於使用,並且導致GLSL不支持在運行時編譯函數。 (這還不夠理想,Swift認爲Metal函數是正確類型的,可重構的,命名空間的閉包。)當然,雖然GLSL SCNPrograms將轉換爲Metal,但對於兼容的硬件,Metal SCNPrograms不會被翻譯爲過時的設備。

至於從SceneKit到rastex的(不正確地命名ColorInOut)映射成員:

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

...可惜我沒有給你一個答案。

+0

這是一些很好的信息,謝謝。它確實說明了一切,因爲這對我來說是一個全新的領域。 –

相關問題