Рисование 3D спереди / сзади спрайтов в XNA / WP7? - PullRequest
0 голосов
/ 15 декабря 2010

Это немного расстраивает меня, так как я уже несколько часов сижу в нем.

По сути, я рисую 2D-спрайты с помощью spritebatch и трехмерной ортогонально проецируемой геометрии, используя класс BasicEffect.

Моя проблема заключается в контроле того, что визуализируется поверх чего.Сначала я подумал, что это будет просто управление порядком рендеринга, т.е. если я сделаю:

Draw3DStuff()

SpriteBatch.Begin(...)
Draw2DStuff();
SpriteBatch.End();

Это будет означать, что 2D-вещи будут рендериться поверх 3D-объектов, однако, поскольку я не контролирую, когда устройствоРендеринг начинается / заканчивается, это не результат.3D всегда визуализируется поверх 2D-элементов, независимо от настроек проекции, трансляции мира, z-компонентов определений вершин 3D-геометрии и глубины слоя 2D-элементов.

Есть ли что-то, что яне глядя сюда?Какой правильный способ обработки глубины здесь?

Ответы [ 3 ]

4 голосов
/ 15 декабря 2010

ОК, я понял это через 2 секунды после публикации этого вопроса. Я не знаю, было ли это совпадением или в StackOverflow появилась новая функция, позволяющая видеть будущие ответы.

Положение Z элементов spritebatch находится в диапазоне от 0 до 1, поэтому они не сопоставимы напрямую с позициями z отображаемой ортогональной геометрии.

Когда вы создаете орфографическую матрицу, вы определяете ближнюю и дальнюю плоскости отсечения. Заданная вами позиция Z должна быть в этой плоскости отсечения. У меня было предчувствие, что класс spritebatch эффективно рисует квадратики орфографически, так что расширение от 0 до 1 означало бы, что 0 представляет ближний клип, а 1 - дальний клип, и глубина, вероятно, отображается в том же месте, где глубина трехмерной геометрии равна переводится в.

Тааак, чтобы это сработало, я просто подумал, что клипы ближнего / дальнего расстояния, которые я определил для орфографической визуализации, будут измеряться по отношению к клипам ближнего / дальнего расстояния рендеринга спрайтов, так что это просто вопрос установки правильного значение z, например:

Если у меня есть ближний клип 0 и дальний клип 10000, и я хотел нарисовать его так, чтобы он соответствовал глубине слоя 0,5f и рендерился перед спрайтами, нарисованными на 0,6, и позади спрайтов, нарисованными на 0,4 Я делаю:

   float zpos = 0.5f;
   float orthoGraphicZPos = LinearInterpolate(0, 10000, zpos);

Или просто zpos * 10000: D

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

Надеюсь, мои рассуждения об этом решении были правильными (более или менее).

2 голосов
/ 15 декабря 2010

В качестве отступления, поскольку вы упомянули, что у вас есть догадка о том, как спрайтовая партия рисует квады. Вы можете просмотреть исходный код для всех включенных по умолчанию шейдеров и класса spritebatch, если вам интересно, или вам нужна помощь в решении такой проблемы:
http://create.msdn.com/en-US/education/catalog/sample/stock_effects

1 голос
/ 16 декабря 2010

Проблема в том, что spritebatch портит некоторые рендеры, которые используются при рисовании ваших трехмерных объектов.Чтобы это исправить, вам просто нужно сбросить их перед рендерингом ваших трехмерных объектов следующим образом.

GraphicsDevice.BlendState = BlendState.Opaque;
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap; 

Draw3DStuff()

SpriteBatch.Begin(...)
Draw2DStuff();
SpriteBatch.End();

Обратите внимание, что это для xna 4.0, который, я уверен, вы все равно используете.Более подробную информацию можно найти в блоге Шон Харгривз здесь .Это нарисует сброс состояний рендеринга, нарисует 3d объекты, а затем 2d объекты над ними.Без сброса состояний рендера вы получите странные эффекты, такие как ваше зрение.

...