Использование шейдера Metal в SceneKit

Я хотел бы использовать шейдер Metal для применения затенения мультяшек / ячеек к материалам, используемым в сцене. Шейдер, который я пытаюсь реализовать, принадлежит Apple AAPLCelShader, который можно найти в MetalShaderShowcase. Я немного новичок в реализации шейдеров в SceneKit, поэтому могу делать все совершенно неправильно.

Насколько я понимаю из документации, шейдер Metal или GL может использоваться для изменения SceneKit рендеринга в iOS 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. Загрузка файла работает нормально, так что это не проблема.

Ошибка возникает из второй строки, где я пытаюсь найти путь, она дает мне «найдено ноль при разворачивании необязательного значения», которое можно было бы ожидать при принудительном разворачивании, за исключением того факта, что файл, который он пытается загрузить, больше всего обязательно в комплекте и тот же код отлично работает с другими типами файлов, только не .metal.

Я ошибаюсь? Я не могу понять, почему он не может получить доступ к файлу, кроме проблемы с неправильным использованием металлического файла.

Есть ли более простой или лучший способ реализовать затенение ячеек и, в конечном итоге, жирный контур по краям?


person Andy Heard    schedule 19.06.2015    source источник


Ответы (1)


AAPLCelShader.metal - это полная реализация вершины / rastex / фрагмента, которая не является что такое shaderModifiers: исходный код, который будет вставлен в уже готовые шейдеры.

Вместо этого вы можете создать SCNProgram, используя функции вершины и фрагмента в AAPLCelShader.metal. Что хорошего в Metal по сравнению с GLSL, так это то, что вы можете использовать имена функций Metal вместо строк исходного кода, с которыми легче работать, и в результате функции компилируются до времени выполнения, что GLSL не поддерживает. (Это все еще не так хорошо, как должно быть, поскольку Swift распознает функции Metal как правильно набранные, рефакторируемые замыкания с пространством имен.) Конечно, хотя программы GLSL SCN будут преобразованы в Metal, для совместимого оборудования программы Metal SCN не будут быть переведено на устаревшие устройства.

Что касается сопоставления SceneKit с членами rastex (неправильно названными ColorInOut):

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

… У меня, к сожалению, пока нет ответа.

person Jessy    schedule 20.06.2015
comment
Это отличная информация, спасибо. Это действительно проливает свет на все это, поскольку для меня это совершенно новая область. - person Andy Heard; 20.06.2015