我的视锥体中有一个256x256的纹理,我需要移动到一个z位置,在这个位置,纹理在ACTUAL大小的屏幕上复制。
到目前为止我所拥有的是:
const float zForTrueScale = -((itemSize/2) / tanf(DEGREES_TO_RADIANS(fieldOfView/2)) ) * 2;
其中itemSize是世界空间中纹理的大小(2.0单位)。这是为了计算itemSize / 2(相反)为1.0时的Z(相邻)。我认为这会奏效。
无论我使用何种FOV,这个公式都显示纹理一直太小了约10%。
由于
编辑:我在3D空间中移动图像,需要无缝过渡到正确的z距离。我不能使用orthagonal投影,它必须在视锥体中。答案 0 :(得分:6)
由于您需要的信息直接保存在投影矩阵中,因此您可以比使用视野更轻松地做到这一点。
因此,您的投影矩阵将如下所示:
xScale 0 0 0
0 yScale 0 0
0 0 -(zf + zn)/(zf - zn) -(2 * zf) / (zf-zn)
0 0 -1 0
其中z-Far(zf)和z-Near(zn),xScale和yScale是已知的。
要选择正确的Z-Depth,我们将首先确保w最终为1.这样当我们除以w时,它不会改变任何东西。
幸运的是,很容易搞定。它只是输入z的负数。因此,输入-1到z将返回w为1。
我们假设您使用的分辨率为1024x768,并且您想要的纹理尺寸正确为256x256。
我们还将进一步假设您的矩形设置为左上角位于-1,1和右下角1,-1。
所以让我们插入这些并计算出z。
如果我们使用以下内容:
-1, 1, -1, 1
1, -1, -1, 1
我们会得到如下内容。
1 / xScale, -1 / yScale, someZThatIsn'tImportant, 1
-1 / xScale, 1 / yScale, someZThatIsn'tImportant, 1
视口变换转换这些值,使-1,1为0,0和1,-1为1024,768
所以我们可以看到这样做((x + 1)/ 2)* 1024和((1 - y)/ 2)* 768
因此,如果我们假设xScale为3/4且yScale为1,我们可以看到通过插入,我们将获得以下内容:
左上角:
x = -3/4
=> ((-3/4 + 1) / 2) * 1024
=> 128
y = 1
=> ((1 - 1) / 2) * 768
=> 0
右下角:
x = 3/4
=> ((3/4 + 1) / 2) * 1024
=> 896
y = -1
=> ((1 + 1) / 2) * 768
=> 768
您可以看到我们在屏幕中居中有一个768x768像素的图像。显然要获得256x256我们需要得到w为3以便w w divide我们将那些坐标设置为大小的第3个((xScale * 1024)/ 256应该等于(yScale * 768)/ 256以获得正方形投影。
所以如果我们的最终坐标如下:
-1, 1, -3, 1
and
1, -1, -3, 1
我们将得到以下内容(在w-divide之后):
-0.25, 0.333, unimportantZ, 1
and
0.25, -0.333, unimportantZ, 1
通过上面的屏幕方程运行那些,我们得到
左上角:
x = -0.25
=> ((-0.25 + 1) / 2) * 1024
=> 384
y = 0.3333
=> ((1 - 0.3333) / 2) * 768
=> 256
右下角:
x = 0.25
=> ((0.25 + 1) / 2) * 1024
=> 640
y = -0.333
=> ((1 + 0.33333) / 2) * 768
=> 512
640 - 384 = 256
512 - 256 = 256
因此我们现在有正确像素大小的最终矩形......
答案 1 :(得分:2)
在不了解您的情况的情况下,将正交投影推到投影矩阵堆栈上,绘制纹理然后再将其弹出几乎肯定更容易。
答案 2 :(得分:0)
虽然速度很慢,但您可以使用glDrawPixels()
并完成它。
......不过,如果它的性能至关重要,那就不行了!
答案 3 :(得分:0)
你的帧缓冲区是否正方形?
如果没有,那么你有一个水平视野和一个垂直视野。你使用的是正确的吗?另外,你怎么知道你希望它在世界坐标中是2.0单位?如果您的最终目标是将其映射到像素,那么您需要考虑视口,然后从中进行操作。
我同意Pike65的说法,我没有得到* 2的来源。