我正在使用OpenGL编写游戏,我正在尝试实现阴影卷。
我想通过顶点着色器在GPU上构建模型的阴影体积。为此,我用VBO代表模型,其中:
使用此模型格式,在顶点着色器中,我能够找到顶点,这些顶点是远离光线的三角形的一部分,然后将它们移回以形成阴影体。
我还要弄清楚究竟应该将哪种转换应用于背面顶点。
我能够检测到顶点背离光线的时间,但我不确定应该应用哪种变换。这是我的顶点着色器到目前为止的样子:
uniform vec3 lightDir; // Parallel light.
// On the CPU this is represented in world
// space. After setting the camera with
// gluLookAt, the light vector is multiplied by
// the inverse of the modelview matrix to get
// it into eye space (I think that's what I'm
// working in :P ) before getting passed to
// this shader.
void main()
{
vec3 eyeNormal = normalize(gl_NormalMatrix * gl_Normal);
vec3 realLightDir = normalize(lightDir);
float dotprod = dot(eyeNormal, realLightDir);
if (dotprod <= 0.0)
{
// Facing away from the light
// Need to translate the vertex along the light vector to
// stretch the model into a shadow volume
//---------------------------------//
// This is where I'm getting stuck //
//---------------------------------//
// All I know is that I'll probably turn realLightDir into a
// vec4
gl_Position = ???;
}
else
{
gl_Position = ftransform();
}
}
我尝试过简单地将gl_position
设置为ftransform() - (vec4(realLightDir, 1.0) * someConstant)
,但这会导致某种深度测试错误(当我用颜色渲染音量时,某些面孔似乎在其他面后可见)和{ {1}}似乎没有影响背面延伸的距离。
更新 - 1月22日
只是想澄清一下我可能在哪个空间的问题。我必须说,跟踪我所处的空间是我的着色器头痛的最大来源。
渲染场景时,我首先使用someConstant
设置相机。相机可以是固定的,也可以四处移动;没关系。然后我使用gluLookAt
之类的翻译函数来定位我的模型。
在程序中(即在CPU上),我代表世界空间中的光矢量(三个浮点数)。我在开发过程中发现,为了在我的着色器的正确空间中获得这个光矢量,我必须在设置相机之后和定位模型之前将它乘以模型视图矩阵的倒数。所以,我的程序代码是这样的:
glTranslated
)这会让事情更清楚吗?
答案 0 :(得分:1)
ftransform结果位于剪辑空间中。所以这不是你想要应用realLightDir的空间。我不确定你的光源在哪个空间(你的评论让我困惑),但可以肯定的是你想要添加在同一空间中的矢量。 / p>
在CPU上,这是世界上的代表 空间。用相机设置后 gluLookAt,光矢量乘以 得到的模型视图矩阵的逆 进入眼睛空间(我认为这就是我的意思 在工作之前:P)在被传递之前 这个着色器。
将矢量乘以mv矩阵的逆矩阵,将矢量从视图空间带到模型空间。所以你说你的光矢量(在世界空间中)应用了一个视图 - &gt;模型的变换。这对我来说没什么意义。
我们有4个空格:
你能准确说明你的光照方向是哪个空间吗?
然而,您需要做的是在模型,世界或视图空间中添加光矢量:将操作的所有位置放在同一空间中。例如。对于模型空间,只需计算CPU上模型空间中的光照方向,然后执行:
vec3 vertexTemp = gl_Vertex + lightDirInModelSpace * someConst
然后您可以使用
将新的顶点位置放在剪辑空间中gl_Position = gl_ModelViewProjectionMatrix * vertexTemp
最后一点,不要尝试在剪辑空间中应用向量添加。它通常不会做你认为应该做的事情,因为那时你必须用不统一的w来处理homogeneous coordinates。