Urho3D
GameDev.ru / Сообщества / Urho3D / Форум / Отсечение части объекта.

Отсечение части объекта.

Поделиться
Страницы: 1 2 Следующая »
AlexS32Пользовательwww24 ноя. 201717:23#0
Добрый день.
Прошу помощи в таком вопросе - как осуществить отрисовку только части объекта. Т.е. можно ли, например, разместить перед непрозрачным предметом какой-то невидимый объект, чтобы области им перекрываемые не отрисовывались?
Или такой способ в корне не верен и нужно смотреть в какую-то другую сторону? Если так, то прошу подсказать в какую.
GLoomПостоялецwww24 ноя. 201717:27#1
Теоретически (я не пробовал) можно прям как говоришь. Шаг 1 - рисуем то, что должно быть видно всегда. Шаг 2 рисуем материалом который только заполняет буфер глубины. Шаг 3 - рисуем объекты в которых могут быть "дырки".

То есть если брать fallout 1-2 например то дырок там нет в предметах, полу и персонажах. А вот в стенках есть.

smb_zПостоялецwww24 ноя. 201717:31#2
Можно так:
В render path добавляешь проход cull прямо перед проходом base:
<command type="scenepass" pass="cull" />

Тот объект, который будет "перекрывать" отрисовываешь вот таким материалом:

Materials/InvisibleOccluder.xml:

<material>
  <technique name="Techniques/InvisibleOccluder.xml" quality="0" loddistance="0" />
  <parameter name="UOffset" value="1 0 0 0" />
  <parameter name="VOffset" value="0 1 0 0" />
  <parameter name="MatDiffColor" value="1 1 1 0" />
  <parameter name="MatEmissiveColor" value="0 0 0" />
  <parameter name="MatEnvMapColor" value="1 1 1" />
  <parameter name="MatSpecColor" value="0 0 0 1" />
  <parameter name="Roughness" value="0.5" />
  <parameter name="Metallic" value="0" />
  <cull value="ccw" />
  <shadowcull value="ccw" />
  <fill value="solid" />
  <depthbias constant="0" slopescaled="0" />
  <renderorder value="128" />
</material>

Техника Techniques/InvisibleOccluder.xm:

<technique vs="Unlit" ps="Unlit" vsdefines="NOUV" >
    <pass name="cull" blend="alpha" />
</technique>


По сути - ты заполняешь z-buffer объектом-окклудером, при этом не рисуя на экран.
После чего остальные объекты не пройдут z-test.

Метод не самый оптимальный, но вроде работает.

AlexS32Пользовательwww24 ноя. 201721:12#3
Спасибо. Но пока что-то не получается. Окклюдер действительно не видим. Но никакого отсечения не получается((( Пробовал ему render order меньше поставить - без изменений.
Если что - окклюдером пытаюсь сделать  CustomGeometry.
GLoomПостоялецwww24 ноя. 201721:20#4
Попробуй кубик чтоб наверняка
smb_zПостоялецwww24 ноя. 201721:22#5
А точно render pass присутствует в выбранном render path?
Сделайте альфу ненулевой в материале, например
<parameter name="MatDiffColor" value="1 1 1 1" />

Вы должны увидеть окклудер

AlexS32Пользовательwww24 ноя. 201721:39#6
Кубик работает. Не совсем так как я ожидал, но работает
AlexS32Пользовательwww24 ноя. 201721:51#7
smb_z, я рендер pass для уверенности в Forward.xml добавил.
При не нулевой альфе:
  - кубик виден
  - CustomGeometry нет

CustomGeometry создается и меняется через BeginGeometry()/DefineVertex()/Commit()

smb_zПостоялецwww24 ноя. 201721:55#8
ну проблема, видимо, в CustomGeometry. тут не подскажу, смотреть надо.
Вроде в примера было как с ней работать. Надо добиться что бы она работала с обычными материалами, а потом уже назначать ей InvisibleOccluder.
Кстати посмотри в сторону параметра cull. Может у тебя треугольники не в том порядке обходятся?
AlexS32Пользовательwww24 ноя. 201722:12#9
"Где были мои глаза? Елки-палки"
Действительно про cull я и забыл. Все в первом приближении заработало. Спасибо огромное!!!
Правда сейчас окклюдер вырезает все до бесконечности. А мне хотелось бы, чтобы фоновые (те что находятся еще дальше чем прорезаемый объект) предметы не вырезались.
Я так понимаю это уже на render order смотреть надо?
smb_zПостоялецwww24 ноя. 201723:02#10
Нет, сейчас окклудер всегда рендерится первым, независимо от render order, т.к. он в отдельном пассе рисуется (render order влияет на сортировку в пределах одного пасса)
Поменяй
<pass name="cull" blend="alpha" />
на
<pass name="base" blend="alpha" />

и тогда да, можно регулировать порядок отрисовки с помощью render order.

AlexS32Пользовательwww27 ноя. 201718:40#11
После двух дней экспериментов вынужден признать, что, очевидно, я не понимаю чего-то фундаментального.
Цель моих экспериментов следующая - мне необходимо убирать часть объекта расположенного перед "экраном"
occluder_model | Отсечение части объекта.
На верхнем рисунке "нулевая" сцена - зеленым цветом обозначен обрезаемый объект, синим -окклюдер, красным - экран.
В этом состоянии окклюдер не должен ничего обрезать, т.е. объект располагается перед экраном и все хорошо -  как я понимаю, чтобы добиьтся этого, экран должен рисоваться первым.
На нижнем рисунке собственно ситуация с обрезкой - в результате поворота, часть зеленого объекта оказывается за окклюдером(выделена желтым, слева от пунктирной линии) и должна обрезаться.
Экран по прежнему не обрезается.
Для чего все это? Это мои эксперименты по дополненной реальности - экран действительно является  экраном, на него транслируется изображение с камеры.
Техники для экрана и объекта я использовал стандартные, DiffAlpha

Итоги экспериментов:
Для окклюдера я пытался адаптировать приведенную выше в ветке технику используя pass="base". Когда для окклюдера используется такая техника:

<technique vs="Unlit" ps="Unlit" vsdefines="NOUV" >
    <pass name="base" depthwrite="true" depthtest="less" blend="alpha" />
</technique>
Происходит и обрезка экрана и вырезка "экрана".
Я пытался заменить depthtest на greater, чтобы с одной стороны запись в буфер производилась, но с другой сам окклюдер не отображался - в результате окклюдер не отображается, но и обрезка объекта больше не производится.
Я так подозреваю, что именно здесь, я что-то важное и не понимаю - но вот что?

codingmonkeyПостоялецwww27 ноя. 201721:25#12
>В этом состоянии окклюдер не должен ничего обрезать
ну вот на верхнем рисунке тебе окклюдер по идее как раз должен середину у зеленого вырезать (если смотреть со стороны красной плоскости, вниз )
на нижнем должна остаться только треугольная часть от зеленого, что отсечена вертикальной линией. (мб еще чутку с другого края)

>Для чего все это? Это мои эксперименты по дополненной реальности - экран действительно является экраном, на него транслируется изображение с камеры.
Я не понял тебе нужно реальной геометрий с камеры обрезать оверлейную AR-графику ?
ну если ты построил и знаешь реальные объемы обьектов с камеры, то почему бы тебе их просто не нарисовать грубой геометрией в самом начале кадра без всяких окклюдеров
они заполнят Z буффер
далее ты очищаешь Viewport (color/albedo) (Сlear можно юзать для RT и в середине RenderPath'a)
и рисуешь свою AR - геометрию (как обычно) с уже формированным Z буфером.

или я задачу не так понял?

AlexS32Пользовательwww28 ноя. 201712:22#13
Забыл указать направление:( Смотреть нужно снизу - через зеленый объект на экран.
Работает это так - изображение с камеры без изменений транслируется на экран. Это изображение дополняется зеленым объектом (который кстати полупрозрачный).На основе анализа изображения создается окклюдер (именно поэтому я выбрал CustomGeometry - форма окклюдера постоянно меняется)
Задачей этого окклюдера является обрезка тех частей зеленого объекта, которые по логике дополнения изображения на экране в настоящий момент являются лишними.
codingmonkeyПостоялецwww28 ноя. 201714:53#14
как я уже писал выше пробуй рендерить таким образом:
сначала свои окклюдеры как обычную геометрию, только лишь для того чтобы заполнить Z буффер
после прорисовки всех окклюдеров очищаешь viewport
первым делом рисуешь свой экран (красную плоскость) без теста и без записи в Z
затем переключаешься в обычный режим и рисуешь "зеленые объекты", их должно отсечь по Z от пасса с окклюдерами

примерно так RP и техники должны выглядеть

+ Показать

можешь даже вместо пассов(cull и screen) заюзать просто 2-render-ивент'а. И в программе, при получении сообщений рисовать уже используя низкоуровневый graphics...

Правка: 28 ноя. 2017 15:07

Страницы: 1 2 Следующая »

/ Форум / Urho3D - игровой движок / ЗАДАВАЙТЕ ВОПРОСЫ

2001—2017 © GameDev.ru — Разработка игр