我正在製作3D軟件渲染器,並且我已經完成了平移,旋轉和縮放矩陣。如何將投影點轉換爲屏幕座標(視口矩陣)
現在我已經有了一個透視投影矩陣,它將把深度透視應用於我所有的觀點。我不能做的是投影到屏幕座標上的最終透視投影矢量(視口變換)。
這是我現在使用透視投影矩陣: http://puu.sh/7XikH.jpg(抱歉,不能張貼圖片)
所以基本上我需要一個矩陣,將採取一個已經視角投射載體,把它變成屏幕座標。
好吧,這裏的一些代碼:
這是透視投影矩陣,我創建了其中的一個繁衍最後的矩陣我不得不通過它,所以這個乘以最終完全翻譯旋轉和縮放矩陣
public static Matrix4 CreateProjectionMatrix(double znear, double zfar, int width, int height, double fov)
{
double[,] ret = new double[4, 4];
double e = 1/Math.Tan(MathUtil.GetRadian(fov)/2.0);
double ar = width/height;
double zp = zfar + znear;
double zn = zfar - znear;
ret[0, 0] = e; ret[0, 1] = 0; ret[0, 2] = 0; ret[0, 3] = 0;
ret[1, 0] = 0; ret[1, 1] = e/ar; ret[1, 2] = 0; ret[1, 3] = 0;
ret[2, 0] = 0; ret[2, 1] = 0; ret[2, 2] = -(zp/zn); ret[2, 3] = -((2 * zfar * znear)/zn);
ret[3, 0] = 0; ret[3, 1] = 0; ret[3, 2] = -1; ret[3, 3] = 0;
return new Matrix4(ret);
}
另一矩陣相乘以該順序:
public Matrix4 GetTransformationMatrix()
{
Matrix4 translationm = Matrix4.CreateTranslationMatrix(Translation);
Matrix4 rotationm = Matrix4.CreateRotationMatrix(Rotation);
Matrix4 scalem = Matrix4.CreateScaleMatrix(Scale);
//scale -> rotate -> translate
return translationm * (rotationm * scalem);
}
,這是最後的矩陣,一個我獲得通過應用立體投影,然後我乘的所有頂點與結果:
public Matrix4 GetProjectedTransformationMatrix()
{
Matrix4 projectionm = Projection.GetProjectionMatrix();
Matrix4 tranformationm = GetTransformationMatrix();
Matrix4 ret = projectionm * tranformationm;
return ret;
}
我缺少一個視口矩陣,當我乘的最終載體與人會給我正確的X和Y屏幕座標。雖然我不使用OpenGL,但我認爲OpenGL或Direct3D設置視口矩陣的方式是可行的。
編輯
我已經解決了問題,雖然不是我想要的方式。
我在尋找一個能處理所有投影和座標變換的矩陣,這些矩陣可以將已經變換過的點與所有模型和視圖矩陣相乘並將其轉換爲屏幕座標。
我在做什麼,現在正在申請相同的透視投影矩陣我收到了,然後除以Z都X和Y,然後將屏幕尺寸的因素,如:
public Point GetProjectedPoint(Vector vec, Matrix4 mat)
{
Vector point = vec * mat;
double px = point.X/point.Z * Width;
double py = point.Y/point.Z * Height;
return new Point(px, py);
}
方式我認爲這會起作用的是透視投影(http://puu.sh/7XikH.jpg)會被Z分開,因爲這是「透視(更遠點=更小)」效應的來源,並且這會給我最終的世界座標(這使我困惑,因爲我在最終的視口投影中除以Z,所以透視投影是怎麼做的?)。
然後,將其轉換爲屏幕座標,視口矩陣首先將所有內容縮放到Normalized Device Coordinates,然後將其映射到屏幕座標。
如果有人可以澄清管道應該是什麼,我應該做什麼,或解釋一個更好的方法,使用適當的矩陣我會很感激。
您可以請張貼一些代碼/嘗試顯示您的進展到目前爲止?有時最好給出例子以獲得更有意義的答案。 – rdonatoiop