2015-01-08 2 views
2

У меня есть вопрос и надеюсь, что вы можете мне помочь. Я был занят созданием игры с xna и недавно начал получать шейдеры (hlsl). Есть этот шейдер, который мне нравится, использует и хотел бы улучшить.HLSL Как правильно очертить плоскую затененную модель

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

Теперь возникает вопрос: существует ли способ вычисления (как в шейдере, так и в xna), как я должен переводить каждую вершину, или это единственный жизнеспособный вариант, просто создающий копию 3d-модели, но с гладкое затенение?

Заранее благодарим вас, надеюсь, вы сможете обучить меня!

EDIT: В качестве альтернативы, я мог бы загружать только модель с гладкой затенением и пытаться сгладить ее в шейдере. Это, однако, означало бы, что мне нужно найти нормали всех вершин соответствующей грани, добавить их нормали и нормализовать результат. Есть ли способ сделать это?

EDIT2: До сих пор я нашел несколько вариантов, которые, похоже, не работают в конце: установка «shademode» в hlsl теперь устарела. Установка режима fillmode на «каркас» будет аккуратной (при отбрасывании лицевых поверхностей), если бы я мог установить толщину линии.

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

ответ

0

Хорошо, я некоторое время работал над этой проблемой и нашел что-то, что работает очень хорошо.

Вместо того, чтобы делать сложную математику, чтобы нарисовать 2d строк на правой глубине, я просто сделал следующее: Установите состояние растеризатора, которое отбрасывает передние грани, рисует каркас и слегка отклоняется от глубины. Теперь нарисуйте модель во всех черных (я изменил свой шейдер для этого) Установите состояние растеризатора, которое отбирает обратные грани, рисует в fillmode.solid и имеет смещение глубины 0. Теперь нарисуйте модель в обычном режиме.

Поскольку мы не можем изменить толщину каркасных линий, у нас остался очень тонкий контур. Для моих целей это было не так уж плохо.

Я надеюсь, что эта информация полезна кому-то позже.