簡體   English   中英

嘗試繪制模型時黑屏[閱讀編輯]

[英]Black screen when trying to draw model [read edit]

我正在嘗試制作一個可以使用相機的世界對象,並一次繪制多個模型,每個模型都有自己的位置(以及將來的旋轉方式等)。 除了它帶有黑屏,我不知道為什么。

我嘗試過更改矩陣的創建方式,調整位置,但沒有任何改變。

世界:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Microsoft.Xna.Framework;

using Simple3DWorld.Objects;

namespace Simple3DWorld
{
    public class World
    {
        public Camera Camera;
        public ModelObject[] Objects;

        public World()
        {
            Camera = new Camera(new Vector3(0, 0, 1), Vector3.Zero);
            Objects = new ModelObject[100];
            AddObject(new Landscape(new Vector3(0, 0, -1)));
        }

        public void AddObject(ModelObject obj)
        {
            bool added = false;

            for (int i = 0; i < Objects.Length && !added; i++)
            {
                if (Objects[i] == null)
                {
                    Objects[i] = obj;
                    added = true;
                }
            }
        }

        public void Update(GameTime gt)
        {
            for (int i = 0; i < Objects.Length; i++)
            {
                if (Objects[i] != null)
                {
                    Objects[i].Update(gt);
                }
            }
        }

        public void Draw()
        {
            for (int i = 0; i < Objects.Length; i++)
            {
                if (Objects[i] != null)
                {
                    Objects[i].Draw(Camera);
                }
            }
        }
    }
}

相機:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Simple3DWorld
{
    public class Camera
    {
        public Vector3 Position;
        public Vector3 LookingAt;
        public float FieldOfView;
        public float AspectRatio;

        public Camera(Vector3 pos, Vector3 lookAt)
        {
            Position = pos;
            LookingAt = lookAt;
            FieldOfView = MathHelper.PiOver4;
            AspectRatio = STDW.Width / STDW.Height;
        }
    }
}

ModelObject:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Simple3DWorld
{
    public class ModelObject
    {
        public Model Model;
        public Vector3 Position;

        public ModelObject(Model model, Vector3 pos)
        {
            Model = model;
            Position = pos;
        }

        public virtual void Update(GameTime gt)
        {

        }

        public virtual void Draw(Camera camera)
        {
            foreach (ModelMesh mesh in Model.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.EnableDefaultLighting();
                    effect.PreferPerPixelLighting = true;
                    effect.World = Matrix.CreateTranslation(Position);
                    effect.View = Matrix.CreateLookAt(camera.Position, camera.LookingAt, Vector3.UnitZ);
                    effect.Projection = Matrix.CreatePerspectiveFieldOfView(camera.FieldOfView, camera.AspectRatio, 1f, 100f);
                }

                mesh.Draw();
            }
        }
    }
}

是的,我確保所有方法都可以正確調用。 屏幕上應該顯示的是我的風景模型。

編輯:解決。 出於某些愚蠢而令人沮喪的原因,如果攝像機的X和Y(不是向上矢量)都為0,MonoGame將不會渲染您的模型。如果有人能以某種方式解釋這一點,我將非常感激。

相機的PositionLookAt向量在垂直於Up向量的兩個軸上不能相等。 結果為NaN(不是數字)。

這種情況也可以稱為Gimbol Lock ,因為繞X(Roll)Y(Pitch)軸的旋轉是對齊的,因此無法從提供的信息中確定Z(Yaw)

在下面的行中創建View矩陣時會出現問題:

effect.View = Matrix.CreateLookAt(camera.Position, camera.LookingAt, Vector3.UnitZ);

替換參數值:

effect.View = Matrix.CreateLookAt(new Vector3(0,0,1), new Vector3(0,0,0), new Vector3(0,0,1));

在實現時帶有CreateLookAt的帶注釋的部分源代碼(有關通過調用的信息,請參見此處

 public static void CreateLookAt(ref Vector3 cameraPosition, ref Vector3 cameraTarget, ref Vector3 cameraUpVector, out Matrix result)
 {
    var vector = Vector3.Normalize(cameraPosition - cameraTarget);

Normalize((0,0,1) - (0,0,0)) -> (x,y,z)/Length

Length = (0 - 0)² + (0 - 0)² + (0 - 1)² > 1

(0/Length,0/Length,1/Length) -> (0/1,0/1,1/1) -> (0,0,1) *確定

    var vector2 = Vector3.Normalize(Vector3.Cross(cameraUpVector, vector));

由內而外:

Cross((0,0,1),(0,0,1)) -> (y1 * z2 - z1 * y2, z1 * x2 - x1 *z2, x1 * y2 - y1 *x2) ->

(0 * 1 - 1 * 0, 1 * 0 - 0 * 1, 0 * 0 - 0 * 0) (0,0,0) * (0 * 1 - 1 * 0, 1 * 0 - 0 * 1, 0 * 0 - 0 * 0) (0,0,0) (0 * 1 - 1 * 0, 1 * 0 - 0 * 1, 0 * 0 - 0 * 0) -> (0,0,0) *數學上正確,幾何上未定義(未定義垂直於輸入的平面分)

Normalize(Cross((0,0,1),(0,0,1))) -> Normalize(0,0,0)

Length = (0 - 0)² + (0 - 0)² + (0 - 0)² -> 0

(0/Length,0/Length,0/Length) -> (0/0,0/0,0/0) -> (NaN,NaN,NaN) * UH-OH

NaN由除以零得到,其中0表示IEEE 754定義的無符號。

由於對NaN任何操作都會導致NaN NaN傳播到“ World和“ Projection矩陣,從而導致黑屏。

換一種方式:

如果您站着看( Camera.Position = (0,0,6) ),則忽略了您的頭部必須傾斜才能看到它們的事實( Camera.LookAt = (0,0,0) )是是否有可能確定羅盤方向,即Up矢量等於Vector3.UnitZ所面對的方向? 不可以。您可能會面對飛機上的任何方向。

如果我要求世界坐標在你腳前(1,0,0)前面一個單位,那么我可以說出您所面對的方向。

固定。 我要做的就是將相機移開0,0,0。 0,1,0 1,0,0和1,1,0似乎都可以工作,這意味着相機的其他兩個坐標(而不是確定它是向上還是向下的坐標)不能位於原點。 不太確定為什么會這樣,但至少現在已解決。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM