Как нарисовать только модели передней части камеры полностью или частично - XNA

Разрабатываю небольшую игру в стиле XNA «MinecraftGame».

Поскольку нужно рисовать много кубиков. Я создал функцию, которая позволяет рисовать только кубики перед камерой! Но проблема в том, что если куб не полностью заполнен в моем поле зрения, он не будет нарисован. Как вы можете видеть на «скриншоте» ниже. Кубики, расположенные по краям, не прорисовываются. Как нарисовать кубики полностью или частично отображенными перед камерой? и не только целиком.

Большое спасибо

Вот мой код, чтобы проверить, содержит ли Frustum модель:

//Initialize frustum
private void GenerateFrustum()
{
    Matrix viewProjection = View * Projection;
    Frustum = new BoundingFrustum(viewProjection);
}

//private void UpdateFrustum
{
    Matrix viewProjection = View * Projection;
    Frustum.Matrix = viewProjection;
}

//Function that will add models instantiated in the transformation matrix only if the    model is in the field of view !
private udpateTransformModelInstancied()
{
     for (int i = 0; i < ListInstance.Count; i++)
     {
         if(camera.Frustum.Contains(ListInstance[i].Transform.Translation) != ContainmentType.Disjoint)
         {
               instanceTransforms.Add(ListInstance[i].Transform);
         }

      }
 .......
}

SreenShot: введите описание изображения здесь


person Mehdi Bugnard    schedule 13.03.2013    source источник


Ответы (3)


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

person anaximander    schedule 13.03.2013
comment
Но теперь у меня другая проблема ^ ^ Если я быстро перемещаю камеру, земля по краям прорисовывается недостаточно быстро. - person Mehdi Bugnard; 13.03.2013
comment
Добавьте немного буфера безопасности; сделайте усеченную пирамиду немного больше, чем фактическое поле зрения. - person anaximander; 13.03.2013
comment
Окей, большое спасибо. Если я правильно понимаю, мне нужно создать вид и проекцию, особенно для моего большого усеченного конуса. - person Mehdi Bugnard; 13.03.2013

Тестирование ограничивающих структур для ваших кубов, а не только положения куба, будет работать, но это усложняет вашу игру, поскольку вам нужно управлять кучей ограничивающих структур плюс математика тестирования ограничивающей структуры, а не точки. Если вам нужны ограничивающие структуры для других вещей, тогда идите по этому пути. Но если нет, то я бы просто взял положение куба, определил точку ширины куба слева или справа от него и протестировал бы эти точки. Если один из них находится «внутри», нарисуйте куб.

Vector3 leftRightVector = Matrix.Transpose(view).Right;//calc once for each frame(or only when camera rotates)

Vestor3 testPoint1 = cubePosition + (leftRightVector * maxCubeWidth);//calc for each cube
Vestor3 testPoint2 = cubePosition + (leftRightVector * -maxCubeWidth);
if(frustum.Contains(testPoint1 || testPoint2)
{
  //draw
}
person Steve H    schedule 13.03.2013
comment
Спасибо. Я не использовал эту возможность, тоже думал ^^. Этот код кажется таким же чистым, но может потребоваться больше вычислений. - person Mehdi Bugnard; 13.03.2013

Насколько я понимаю, вы просто проверяете положение каждого куба. Самым эффективным решением было бы создать BoundingSphere, который бы полностью охватывал один из ваших кубов, переводил его в местоположение кубов и выполнял Frustum.Contains с этой сферой вместо позиции :)

Также; Сделайте сферу чуть больше, чем нужно, чтобы учесть края усеченной вершины. И запомни; Если вы хотите создать клон minecraft, вам нужно будет использовать какую-то технику пакетного рендеринга. Я рекомендую использовать буфер экземпляра, так как будет меньше данных для отправки на GPU, а также проще реализовать.

person Stig-Rune Skansgård    schedule 13.03.2013