我正在使用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
)
- 取出光向量,它在世界空间中,并将其乘以当前模型视图矩阵的逆矩阵,并将其传递给着色器。
- 定位模型
- 绘制模型这样清楚些吗?