制作3D聚光灯锥形矩阵

时间:2010-03-29 11:15:29

标签: math 3d matrix

如何创建将圆柱体(高度1和直径1)转换为代表我的聚光灯(位置,方向和截止角度)的圆柱体的变换矩阵(4x4)?

- 的修改 -
换句话说:如何通过在适当的变换矩阵中绘制圆柱来绘制代表我的聚光灯的圆锥。

- 的 EDIT2 -
以下(伪)代码给出了预期的结果:

PushMatrix();
LoadIdentity();
Perspective(lightCutoffAngle * 2, 1, 0.001, 10000); // fov, aspect, near, far
LookAt(lightPos.x,lightPos.y,lightPos.z, lightDir.x,lightDir.y,lightDir.z, 0,0,1);
Matrix44 mat = GetModelViewMatrix();
mat.Invert();
PopMatrix();
MultMatrix(mat);
DrawCone(1,1); // diameter, height

HIH

2 个答案:

答案 0 :(得分:1)

您通常不会使用矩阵将柱面转换为圆锥。这是因为它涉及缩放2个组件,其中比例因子取决于第3个组件。

我认为你可以通过构建“look at”矩阵(gluLookAt或D3DXMatrxiLookAtLH)并将其与透视矩阵(gluPerspective或D3DXMatrixPerspectiveFovLH)相乘来构建这样的矩阵,但我很怀疑你能用OpenGL渲染那个圆柱体或D3D。这是因为为了投影工作,3D渲染使用第四矢量分量-W,其通过将矢量与投影矩阵相乘来计算。 W组件通常是隐藏的,只能通过着色器使用。使用此组件时,通常会拧紧任何几何体,如果不使用w组件,则无法将圆柱体转换为圆锥体。即如果你将圆柱体变换为圆锥体,你将不得不使用W,这将搞乱投影变换。

我建议正常构建圆柱体 - 从顶点开始。这在D3D和OpenGL中并不难。

如果确实想要将圆柱体变换为圆锥体,那么编写用于变换圆柱体的顶点着色器将更容易,但确保所有法线都可以正常可能是一个问题。

如果您想知道哪些物体击中光锥,请使用数学和碰撞检测。这并不难。

如果要渲染在光锥内可见的对象,请创建其他渲染目标(或帧缓冲区),视口或其他内容,并从光源的角度渲染对象。

关于光线截止角度。

给定点P,光线位置L和光线方向LDir,以及截止角度,您可以轻松检查P是否在光锥内。要做到这一点,你需要余弦全部或一半的截止角(取决于是否相对于光方向计算截止角,或确定锥的宽度)。使矢量PDir = P-L,归一化PDir,并计算归一化PDir和归一化LDir之间的点积,这将给出点P处光方向之间的角度的余弦.IF余弦(在PDir和Ldir之间)是光锥的较大余弦,然后点在光锥内。

答案 1 :(得分:-1)

我确实想要一个类似

的矩阵
x/y 0   0  0
 0  y   0  0
 0  0  z/y 0
 0  0   0  1

或可能

x(1-y) 0   0    0
  0    1   0    0
  0    0 z(1-y) 0
  0    0   0    1

如果圆锥是一个以原点为中心的圆,则位于沿y轴挤出1个单位的z-x轴上。其中一个矩阵应该可以工作,因为锥体的点越向y轴移动,你想要它们向y轴移动的越多。

希望这会让你感到厌烦,或者至少给你一个良好的开端......现在让我安息吧。

<强>更新

正如评论中所指出的,这需要工作。我想我跳了一半枪。如果将x ans z替换为1,则将矩阵乘以向量。你会得到像

这样的东西
x = x/y  or x(1-y)
y =  y
z = z/y  or z(1-y)

<强>更新

考虑到光的角度,我们将缩放圆锥的半径但保持单位长度。如果我们有光的角度L(这是从它的中心点,而不是边缘到边缘),我们可以说我们的锥体需要的半径是tan ^ -1(L)

所以,如果我们考虑到这一点,我们的最终数学应该是

x = tan^-1(L) * [ x/y  or x(1-y) ]
y =  y
z = tan^-1(L) * [ z/y  or z(1-y) ]