我正在使用 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)
,但这会导致某种深度测试错误(当我用颜色渲染体积时,某些面似乎在其他人后面可见)并且someConstant
似乎并没有影响背面延伸的距离.
更新 - 1 月 22 日
只是想弄清楚我可能在什么空间。我必须说,跟踪我在什么空间是我的着色器头痛的最大根源。
渲染场景时,我首先使用gluLookAt
. 相机可能是固定的,也可能是移动的;没关系。然后我使用翻译功能glTranslated
来定位我的模型。
在程序中(即在 CPU 上),我表示世界空间中的光矢量(三个浮点数)。我在开发过程中发现,要在我的着色器的正确空间中获得这个光矢量,我必须在设置相机和定位模型之前将它乘以模型视图矩阵的倒数。所以,我的程序代码是这样的:
- 定位相机 (
gluLookAt
) - 取世界空间中的光向量,将其乘以当前模型视图矩阵的逆矩阵并将其传递给着色器
- 定位模型的转换
- 模型绘制
这会让事情变得更清楚吗?