Я пытаюсь использовать металлический фрагментный шейдер с SCNTechnique, чтобы изменить цвет фрагмента в зависимости от положения в мире вершины Y.
Насколько я понимаю,
SCNTechnique можно настроить с помощью последовательности рендеринга проходит. Проход рендеринга позволяет внедрить вершину и фрагментный шейдер. Эти шейдеры написаны на металле. В спецификации Metal Shading Language указано, какие входы / выходы поддерживаются для этих двух. Вершинный шейдер вызывается для каждой отображаемой вершины. Мы можем передать дополнительную информацию из вершинного шейдера в фрагментный шейдер (например, положение в трехмерном пространстве, см. MSLS раздел 5.2 ). Фрагментный шейдер находится ближе всего к пикселю и может называться кратным временем для одного «пикселя», если есть несколько треугольников, которые «соответствуют» этому пикселю. (Обычно) после затенения фрагмента фрагмент может быть отброшен, если он не проходит проверку глубины или трафарета.
То, что я пытался
Это то, что я пытался. (Надеюсь, это проясняет, где не хватает моего понимания).
struct VertexOut {
float4 position [[position]];
};
vertex VertexOut innerVertexShader(VertexIn in [[stage_in]]) {
VertexOut out;
out.position = in.position;
return out;
};
fragment half4 innerFragmentShader(VertexOut in [[stage_in]],
half4 color [[color(0)]]) {
half4 output;
output = color; // test to see if getting rendered color works
output.g = in.position.y; // test to see if getting y works
return output;
}
На эти шейдеры есть ссылки в словаре SCNTechnique.
[
"passes": [
"innerPass: [
"draw": "DRAW_NODE",
"node": "inner",
"metalVertexShader": "innerVertexShader",
"metalFragmentShader": "innerFragmentShader"
]
],
"sequence": ["innerPass"],
"symbols": [:],
"targets": [:],
]
// ...
let technique = SCNTechnique(dictionary: techniqueDictionary)
Это позволяет сделать следующее: метод создан правильно и прикреплен к сцене (потому что это влияет на рендеринг). Но, похоже, что к вершинам не применяется преобразование камеры или преобразование положения узла. И вместо этого каждый узел отображается как просматриваемый из (0,0,1) в позиции (0,0,0). Цвета неправильные. Если я удаляю шейдеры из SCNTechnique, каждый рендеринг выполняется так, как я ожидал.
Как использовать обычное поведение SceneKit (преобразование камеры и т. Д. c.) И изменять только вывод цвета на основе фрагментов ' у мировой позиции? Я ожидаю, что это должно произойти на уровне фрагмента, используя положение мира, каким-либо образом полученное в вершинном шейдере. Я искал такие вещи, как «Вершинный шейдер Metal Basi c» и ничего не нашел. Я видел шейдеры , подобные этим , но я убежден, что смогу положиться на рендеринг SceneKit для таких вещей, как освещение, материалы PBR, преобразования камеры и т. Д. c. В этот момент я чувствую, что всякий раз, когда я ищу какой-нибудь Metal topi c, я оказываюсь на тех же сайтах, которые еще не достигли моего понимания на следующем уровне. Итак, любые новые / дополнительные ресурсы также приветствуются.
Фон
Последние два месяца я работаю над своим собственным игровым проектом, в котором SceneKit используется в качестве основной графической среды. Я обратился к SCNTechnique и Metal шейдерам для пользовательских эффектов. Последние два, в частности, вызвали у меня solid головных болей, оба из-за отсутствия примера кода / документации / обратной связи во время выполнения. Из-за этого я подумывал о переходе на Unity / Unreal или даже об отмене этого проекта. Но поскольку я упрям, а также потому, что я действительно не хочу переносить свой код Swift на C # / C ++, я еще не отказался от SceneKit.