2015-03-01 2 views
4

Я использую SceneKit на iOS, и у меня есть геометрия, которую я хочу отобразить в качестве каркаса. Поэтому в основном я хочу рисовать только строки, поэтому нет текстур.Render SCNGeometry как wireframe

Я понял, что могу использовать свойство shaderModifiers используемого SCNMaterial для этого. Пример модификатора шейдера:

material.shaderModifiers = [ 
    SCNShaderModifierEntryPointFragment: "_output.color.rgb = vec3(1.0) - _output.color.rgb;" 
] 

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

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

Или, может быть, существует целый другой подход для визуализации геометрии в виде каркаса. Я хотел бы услышать это.

+0

Вы когда-нибудь разбирали это? В приложениях для 3D-дизайна одним из способов является «подделка» с помощью вершинных позиций для создания длинных тощих коробок или трубок/труб между вершинами, и они выглядят как каркасы. – Confused

ответ

1

Это не (вполне) ответ, потому что это вопрос без легкого ответа.

Выполнение рендеринга каркаса полностью в шейдерном коде намного сложнее, чем кажется, особенно на мобильном телефоне, где у вас нет геометрического шейдера. Проблема заключается в том, что вершинный шейдер (а затем и шейдер фрагмента) просто не имеет информации, необходимой для определения границ полигонов.

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

Если вы действительно хотите решить эту проблему, вам нужно узнать больше о GLSL (язык затенения OpenGL). Для этого есть множество книг и учебных пособий.

Как только у вас есть какой-то GLSL под вашим поясом, взгляните на некоторые из вопросов (например, this one pulled from the Related sidebar) и other stuff people have written о проблеме. (Обратите внимание, что, когда вы ищете ограничения для мобильных устройств, OpenGL ES имеет те же ограничения, что и WebGL на рабочем столе.)

С помощью SceneKit у вас есть дополнительная морщина, которая, вероятно, не имеет барицентрических координат атрибут вершины (aka SCNGeometrySource) для геометрии, с которой вы работаете, и, вероятно, вы не хотите выполнять тяжелую работу по ее созданию. В OS X вы можете использовать с geometryShader, чтобы добавить барицентрические координаты перед запуском вершинного/фрагментарного шейдера - но тогда вам нужно сделать свое собственное затенение (т. Е. Вы не можете комбинировать оттенки SceneKit, как вы можете, с шейдерными модификаторами). И это не доступно в iOS - там нет геометрических шейдеров. Возможно, вы сможете подделать его, используя текстурные координаты, если они будут выровнены прямо в вашей геометрии.


Это может быть проще просто сделать объект с помощью строки - попытаться сделать новый SCNGeometry из источников и элементов исходной (сплошная) геометрии, но при воссоздании SCNGeometryElement, использовать SCNPrimitiveTypeLine.

+0

Спасибо за ваш сложный ответ! –

+0

Да, ты прав. Лучшим подходом может стать воссоздание геометрии. Я уже видел этот совет где-то, но когда я его пробовал, я никуда не уходил. Я начал с простого извлечения источников и элементов из SCNSphere и создания с ним новой SCNGeometry. Но сфера просто исчезла, когда я это сделал. Поэтому я не уверен, что я сделал неправильно. Можете ли вы попытаться помочь мне с примером кода, как построить новую геометрию у тех же источников и элементов другой геометрии? –

+0

@TomvanZummeren - Вы когда-нибудь закончили писать этот код? Если да, можно ли в качестве ответа поделиться? – ndbroadbent

3

Теперь можно (по крайней мере, в какао) с:

gameView.debugOptions.insert(SCNDebugOptions.ShowWireframe) 

или вы можете сделать это в интерактивном режиме, если позволяет статистика с:

gameView.showsStatistics = true 

(Gameview является экземпляром SCNView)

+1

gameView.debugOptions = .ShowWireframe –

5

Попробуйте установить материал fillMode на .lines (iOS 11+ и macOS 10.13+):

sphereNode.geometry?.firstMaterial?.fillMode = .lines