Проблема с прозрачной текстурой в 3D примитиве, XNA 4.0 - PullRequest
4 голосов
/ 13 января 2011

Мне нужно нарисовать большой набор кубиков, все с (возможно) уникальными текстурами на каждой стороне.Некоторые из текстур также имеют части прозрачности.Кубы, которые находятся позади прозрачных текстур, должны показываться сквозь прозрачную текстуру.Тем не менее, кажется, что порядок, в котором я рисую кубы, решает, работает ли прозрачность или нет, чего я хочу избежать.Смотрите здесь:

cubeEffect.CurrentTechnique = cubeEffect.Techniques["Textured"];

Block[] cubes = new Block[4];
cubes[0] = new Block(BlockType.leaves, new Vector3(0, 0, 3));
cubes[1] = new Block(BlockType.dirt, new Vector3(0, 1, 3));
cubes[2] = new Block(BlockType.log, new Vector3(0, 0, 4));
cubes[3] = new Block(BlockType.gold, new Vector3(0, 1, 4));


foreach(Block b in cubes) {
    b.shape.RenderShape(GraphicsDevice, cubeEffect);
}

Это код в методе Draw.Он дает такой результат: первое изображение http://oi53.tinypic.com/av4tv7.jpg

Как видите, текстуры за кубом листа не видны с другой стороны.Когда я обращаю индекс 3 и 0 в массиве, я получаю это: correct image

Ясно, что порядок рисования влияет на кубы.Я подозреваю, что это может быть связано с режимом наложения, но я не знаю, с чего начать.

Ответы [ 4 ]

7 голосов
/ 14 января 2011

Вы полагаетесь на буферизацию глубины для достижения окклюзии.Этот метод работает только для непрозрачных объектов.

Чтобы добиться правильной окклюзии для сцены, содержащей прозрачные объекты:

  1. Установите для DepthBufferEnable и DepthBufferWriteEnable значение true

  2. Отрисовать всю непрозрачную геометрию

  3. Оставьте для DepthBufferEnable значение true, но для DepthBufferWriteEnable установите значение false

  4. Сортируйте альфа-смешанные объекты по расстояниюот камеры, затем нарисуйте их по порядку сзади вперед

Извлечение из Глубина сортировки альфа-смешанных объектов от Шона Харгривза

1 голос
/ 13 января 2011

Правильно нарисовать прозрачные объекты сложнее, чем обычные. Причина в том, что, когда лицо отображается по умолчанию, оно отмечает все пиксели как нарисованные на определенной глубине, и как результат пиксели, которые находятся позади, не будут нарисованы вообще. Я бы порекомендовал приобрести книгу по 3D-рендерингу и просмотреть более подробную информацию.

Самый простой подход, который вы уже нашли - рисовать прозрачные объекты ПОСЛЕ непрозрачных. Работает для прозрачных и полупрозрачных объектов. Обратите внимание, что прозрачные объекты должны быть отсортированы для правильного отображения (в отличие от непрозрачных).

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

0 голосов
/ 13 января 2011

Вы можете использовать это, если у вас нет полупрозрачных пикселей на объектах. Он будет либо полностью отображаться, либо не будет записывать в Z-буфер. Как в Riemers Alpha Testing .

0 голосов
/ 13 января 2011

XNA (и DirectX и все основные 3D-библиотеки) принимают во внимание то, что называется culling .Хотя по вашему коду я не могу точно сказать, по изображениям думаю, что это ваша проблема.Полигоны, которые вы не видите, имеют вершины в неправильном порядке.Если это проблема, у вас есть два решения:

  • либо отключите выборку (device.RenderState.CullMode = CullMode.None;, если я правильно помню)
  • примените вашу текстуру дважды, с точками многоугольникакак по часовой стрелке, так и против часовой стрелки
...