【问题标题】:DirectX, scaling orthgraphic vertices to world space verticesDirectX,将正交顶点缩放到世界空间顶点
【发布时间】:2014-01-22 09:52:08
【问题描述】:

简介


假设我有以下顶点:

const VERTEX World::vertices[ 4 ] = {
    { -960.0f, -600.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f },    // side 1 screen coordinates centred
    { 960.0f, -600.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f },
    { -960.0f, 600.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f },
    { 960.0f, 960.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f }
};

你可能已经猜到 960 * 2 是 1920.. 这是我屏幕的宽度,同样 600 * 2 是 1200。

这些顶点代表一个矩形,它将填满我的整个屏幕,原点位于我的屏幕中心。


问题


所以到目前为止,我一直在使用没有投影的正交视图:

matView = XMMatrixOrthographicLH( Window::width, Window::height, -1.0, 1.0 );

任何被发送到屏幕的矩阵都乘以 matView,它似乎工作得很好。更具体地说,我的形象;使用上面的 vertices 数组,紧贴在我的屏幕上,并且与原始形式的像素为 1:1。

不幸的是,我现在需要 3D...我刚刚意识到我需要一些投影...所以我准备了这只小狗:

XMVECTOR vecCamPosition = XMVectorSet( 0.0f, 0.0f, -1.0f, 0 ); // I did try setting z to -100.0f but that didn't work well as I can't scale it back any more... and it's not accurate to the 1:1 pixel I want
XMVECTOR vecCamLookAt = XMVectorSet( 0.0f, 0.0f, 0.0f, 0.0f );
XMVECTOR vecCamUp = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f );
matView = XMMatrixLookAtLH( vecCamPosition, vecCamLookAt, vecCamUp ); 

matProjection = XMMatrixPerspectiveFovLH(
    XMConvertToRadians( 45 ),        // the field of view
    Window::width / Window::height,  // aspect ratio
    1.0f,                            // the near view-plane
    100.0f );                        // the far view-plan

您可能已经知道问题出在哪里......但如果没有,我刚刚将我的视野设置为 45 度......这将是一个很好的视角并且可以很好地完成 3d 的东西,但我的顶点数组不是切芥末的时间更长... 因为 fov 和屏幕纵横比已大大减少(或增加),因此对于我正在查看的当前视图而言,顶点将太大(见图)强>

我在想我需要对输出矩阵进行一些缩放,以将巨大的坐标缩放回我的 fov 和屏幕方面现在要求的相应大小。

我必须做些什么才能按原样使用 vertices 数组(与原始图像大小的像素比为 1:1),同时仍然允许 3d 的东西发生,比如在屏幕上飞来飞去并旋转并靠近并进一步进入截锥体等......


目标


我试图避免将每个对象顶点数组更改为原始图像在世界空间中的外观的粗略缩放预测。



一些额外信息


我只是想澄清一下我目前正在对世界进行什么样的矩阵运算,然后我如何使用这些更改进行渲染......所以这是我对我的大旧背景图像进行一些翻译:

// flipY just turns the textures back around
// worldTranslation is actually the position for the background, so always 0,0,0... as you can see 0.5 was there to make sure I ordered things that were drawn correctly when using orthographic

XMMATRIX worldTranslation = XMMatrixTranslation( 0.0f, 0.0f, 0.5f );
world->constantBuffer.Final = flipY * worldTranslation * matView;

// My thoughts are on this that somehow I need to add a scaling to this matrix... 
// but if I add scaling here... it's going to mean every other game object 
// (players, enemies, pickups) are going to need to be scaled... and really I just want to 
// have to scale the whole lot the once.. right?

最后这是它被绘制到屏幕上的地方:

// Background

    d3dDeviceContext->PSSetShaderResources( 0, 1, world->textures[ 0 ].GetAddressOf( ) ); // Set up texture of background
    d3dDeviceContext->IASetVertexBuffers( 0, 1, world->vertexbuffer.GetAddressOf( ), &stride, &offset ); // Set up vertex buffer (do I need the scaling here?)
    d3dDeviceContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); // How the vertices be drawn
    d3dDeviceContext->IASetIndexBuffer( world->indexbuffer.Get( ), DXGI_FORMAT_R16_UINT, 0 ); // Set up index buffer

    d3dDeviceContext->UpdateSubresource( constantbuffer.Get( ), 0, 0, &world->constantBuffer, 0, 0 ); // set the new values for the constant buffer
    d3dDeviceContext->OMSetBlendState( blendstate.Get( ), 0, 0xffffffff ); // DONT FORGET IF YOU DISABLE THIS AND YOU WANT COLOUR, * BY Color.a!!!
    d3dDeviceContext->DrawIndexed( ARRAYSIZE( world->indices ), 0, 0 ); // draw

然后我做了什么来应用我的 matProjection,它已经超大了我的所有顶点

world->constantBuffer.Final = flipY * worldTranslation * matView * matProjection; // My new lovely projection and view that make everything hugeeeee... I literally see like 1 pixel of the background brah!

请随意复制我的游戏并按原样运行它(Windows 8 应用程序 Visual Studio 2013 Express 项目),希望您能帮助我将这一切变成 3D: https://github.com/jimmyt1988/FlyGame/tree/LeanerFramework/Game

【问题讨论】:

  • 能贴出渲染矩形的代码吗?解决方案可能很简单,但在我把它扔出去之前我需要代码,当这不是问题时看起来像个白痴。我正在寻找如何在没有透视矩阵的情况下渲染矩形,以及如何更改以使用透视矩阵渲染它。
  • 我希望这是你需要的(添加到 OP)

标签: c++ matrix directx


【解决方案1】:

又是我。让我试着澄清一些事情

1

这是我的一个编辑的小截图:

我在小黑框内进行了编辑以说明某些内容。您在对象周围看到的轴圈以完全相同相同的大小呈现。但是,它们是通过透视投影渲染的。如您所见,最左边的那个大约是中间那个的两倍。这纯粹是由于这样的投影的性质。如果这是不可接受的,则必须使用非透视投影。

2 保持屏幕空间与 uv 空间的1:1 比率的唯一方法是让对象在屏幕上每 1 个像素在纹理上渲染 1 个像素。没有什么比这更重要的了。但是,您可以做的是更改纹理过滤器选项。过滤器选项是专门用于呈现非1:1 比率的设计。例如代码:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

告诉opengl:“如果你被告知要采样一个像素,不要插入任何东西。只需在纹理上取最接近的值并将其粘贴到屏幕上。

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

然而,这段代码做得更好:它在像素之间进行插值。我认为这可能是你想要的,如果你还没有这样做的话。

这些图片(取自http://www.opengl-tutorial.org/beginners-tutorials/tutorial-5-a-textured-cube/)展示了这一点:

最近的:

线性:

归根结底就是这样。您要求:

我必须做些什么才能按原样使用顶点数组(与原始图像大小的像素比为 1:1),同时仍然允许 3d 的东西发生,就像一只苍蝇在屏幕上飞来飞去并旋转并越来越近地进入截头体等...

根据定义,您的要求是不可能的,因此您必须寻找替代解决方案。我希望这会有所帮助。

【讨论】:

  • 你在上面或这里所说的对我有点帮助......我意识到我想问的真正问题是如何添加投影而不破坏 1:1 像素比例我设置的正交视图。 matView = XMMatrixOrthographicLH(Window::width, Window::height, -1.0, 100.0f);
  • 这就是我想说的!没有办法做你所要求的。您真正需要做的是获取像素过滤器设置来掩盖它不是 1:1 比率的事实。查看任何 3D 程序,您会发现比例不是 1:1。关键是让这个比例看起来不错。
  • 酷,在那种情况下...我可能只是对我的对象顶点应用一个巨大的负比例以将它们设置回来一点
  • 感谢您的时间伙伴。我学到了很多东西,你也帮了大忙。我认为这不应该标记为已完成
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多