Как использовать трафареты с SCNTechnique?
По сути, я хотел бы нарисовать контур вокруг куба. Для этого, я думаю, я могу использовать SCNTechnique
который имеет следующие проходы рендеринга:
- Отобразите кубы как обычно, а также запишите их занятые пиксели в буфер трафарета.
- Визуализируйте немного большие кубы, если они не пересекаются с трафаретом в первом проходе.
Проблема в том, что документация на трафареты в SCNTechnique
очень редкий, и я не могу понять, как именно его использовать.
Я уже успешно рисовал контуры, сначала рисуя большие "кубы контура" с отключенным тестированием глубины, а затем рисуя нормальные кубы, и это работает довольно хорошо, однако вместо этого я хотел бы использовать трафареты из-за других сложностей этого метода.
В попытке заставить его работать, используя трафаретные буферы, мой первый проход stencilStates
выглядит (вместе с тем, почему я думаю, что мне нужны свойства):
clear = YES // To clear the buffer from last
enable = YES // To write to the buffer
behavior:
writeMask = 1 // Use bit 1
function = always // Always write to stencil regardless?
Второй проход stencilStates
похоже:
clear = NO // Keep the buffer from last step
enable = NO // Don't write to the buffer (only read?)
behavior:
readMask = 1 // Use bit 1
fail = keep // Not sure if these...
pass = zero // ...should be the other way round
Существует несколько других свойств поведения буфера трафарета, но я не уверен, что мне нужно и как их использовать. Я также не уверен, должен ли буфер трафарета быть указан как вход или выход для каждого прохода?
Изменить 1: Вот именно то , что я хочу реализовать, визуализируя сначала путем рисования синего, большего контура куба без записи в буфер глубины:
Если бы не было побочных эффектов при рисовании в этой усадьбе, я бы оставил реализацию такой, как эта, но вместо этого я думаю, что трафаретный подход позволит избежать этих побочных эффектов, и я думаю, что было бы полезно знать, как их использовать. тем не мение!
Редактировать 2: я играл, пытаясь создать аналогичный эффект, используя OpenGL (в C) напрямую. Я не претендую на то, что полностью понимаю, как работают трафареты (и я в основном позаимствовал код из учебника), но эти команды дают то, чего я пытаюсь достичь.
Прежде чем рисовать основной куб, пишем в буфер трафарета:
glStencilFunc(GL_ALWAYS, 1, 0xFF); // Set any stencil to 1
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glStencilMask(0xFF); // Write to stencil buffer
glClear(GL_STENCIL_BUFFER_BIT); // Clear stencil buffer (0 by default)
После отрисовки основного куба и перед отрисовкой большего контурного куба тестируем текущий буфер трафарета:
glStencilFunc(GL_EQUAL, 0, 0xFF); // Pass test if stencil value is 0
glStencilMask(0x00); // Don't write anything to stencil buffer
Поэтому вопрос заключается в том, как достичь вышеизложенного с помощью SCNTechnique
,
1 ответ
Вы можете использовать SCNTechnique, чтобы нарисовать контур. Идея состоит в том, чтобы нарисовать маски объектов в буфере, размыть один канал маски, а затем объединить его с исходным визуализированным кадром. Этот комбинационный шейдер проверяет размытый канал, а не размытый - и отображает только контур за пределами объекта.
Вот пример, который рисует свечение вокруг узлов: https://github.com/laanlabs/SCNTechniqueGlow Вы должны иметь возможность изменить его, чтобы получить желаемый эффект.