Opengl 创建阴影体积时如何在GLSL中变换后向顶点

Opengl 创建阴影体积时如何在GLSL中变换后向顶点,opengl,glsl,shadow,Opengl,Glsl,Shadow,我正在使用OpenGL编写一个游戏,我正在尝试实现阴影体积 我想通过顶点着色器在GPU上构建模型的阴影体积。为此,我使用VBO表示模型,其中: 顶点被复制,这样每个三角形都有自己独特的三个顶点 每个顶点都有其三角形的法线 出于我不打算深入讨论的原因,我实际上是在做上述两点,所以我不太担心顶点复制 退化三角形被添加到每对“规则”三角形之间的边内形成四边形 使用此模型格式,在顶点着色器中,我能够找到作为三角形一部分的顶点,这些三角形朝向远离灯光的方向,并将它们移回以形成阴影体积 我要弄清楚的

我正在使用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();
    }
}
uniform vec3 lightDir;//平行光。
//在CPU上,这在world中表示
//空间。将相机设置为
//看,光矢量乘以
//要获取的modelview矩阵的逆矩阵
//它进入眼睛的空间(我想这就是我想要的
//在:P)中工作,然后通过
//这个着色器。
void main()
{
vec3眼法线=规格化(gl_法线矩阵*gl_法线);
vec3 realLightDir=标准化(lightDir);
float dotprod=点(眼法线、realLightDir);

如果(dotprodftTransform结果在剪辑空间中。因此,这不是您要应用realLightDir的空间。我不确定灯光在哪个空间中(您的评论让我困惑),但可以确定的是您要添加在同一空间中的向量

在CPU上,这在world中表示 空间。将相机设置为 看,光矢量乘以 要获取的modelview矩阵的逆矩阵 它进入眼睛的空间(我想这就是我想要的 在:P)中工作,然后通过 这个着色器

将一个向量乘以mv矩阵的倒数,将向量从视图空间带到模型空间。因此,你是说你的光向量(在世界空间中)应用了一个变换,该变换执行视图->模型。这对我来说没有什么意义

我们有4个空间:

  • 模型空间:定义gl_顶点的空间
  • 世界空间:德国劳埃德船级社通常不关心的空间,它代表了定位模型的任意空间。它通常是3d引擎工作的地方(它映射到我们对世界坐标的一般理解)
  • 视图空间:与查看器的引用相对应的空间。0,0,0是查看器所在的位置,向下看Z。通过将gl_顶点乘以modelview获得
  • 剪辑空间:矩阵投影带给我们的神奇空间。F变换的结果就在这个空间中(gl_ModelViewProjectionMatrix*gl_顶点也是如此)
你能明确你的光线方向在哪个空间吗

但是,您需要做的是在模型、世界或视图空间中进行光向量加法:将所有操作位放在同一空间中。例如,对于模型空间,只需在CPU上计算模型空间中的光方向,然后执行以下操作:

vec3 vertexTemp = gl_Vertex + lightDirInModelSpace * someConst
然后,可以在剪辑空间中使用

gl_Position = gl_ModelViewProjectionMatrix * vertexTemp

最后一点,不要尝试在剪辑空间中应用向量加法。它通常不会做您认为它应该做的事情,因为在这一点上,您必须处理非均匀w。

是“深度测试错误”仅仅因为你在没有Z缓冲的情况下渲染一批未排序的多边形?你能提供一个屏幕截图吗?我打开了深度测试。这很难描述,我需要在阴影体积着色器中应用明暗处理的颜色(我不传递颜色数据)很明显。基本上,我看到的是我不应该看到的多边形。我将添加一个屏幕截图来回应Bahbar的()回答。我更新了我的问题,试图解释我的灯光、着色器等所处的空间。我认为我的光向量位于模型空间中。至少,点积测试给出了我认为正确的结果。我尝试按照您的建议设置后向顶点的位置,如下所示:“gl_ModelViewProjectionMatrix*(gl_Vertex-vec4(lightDir,0.0));“但是,拉伸似乎遵循模型的旋转,并且似乎仍然存在一些瑕疵多边形,正如您在处看到的(与实际模型在处相比)。嗯,听起来好像您没有在模型空间中放置灯光方向。