2

总之,我的全屏着色器没有输出任何东西,

我正在用 GLSL 编写一个延迟着色器,并且已经到了在屏幕空间中应用灯光的阶段。我有一个环境通道,我基本上将 GBuffer 中的漫反射强度写入默认 FBO,这工作正常。然后我应用另一个全屏四边形来计算场景中的定向光,这也是来自 GBUffer 的样本,应该与默认的 FBO 混合。

我遇到的问题是定向光着色器不输出任何东西。我使用与环境通道相同的矩阵和变换,但没有任何变化。

我尝试了以下方法;

  1. 在环境通道中的每个片段上输出相同的颜色,以确保它完全输出。(作品)
  2. 在定向光通道中的每个片段输出相同的颜色。(仍然一无所获)
  3. 将屏幕分辨率用于 XY 顶点坐标,而不是归一化坐标;
    • 这适用于环境通道,因为我可以看到结果按预期变化。
    • 它对定向光通过没有任何改变,我得到相同的输出。
  4. 将环境着色器更改为从法线或位置缓冲区中采样,以确保可以从(工作)中采样纹理

这是应用程序代码;

glBindFramebuffer(GL_READ_FRAMEBUFFER, m_GeometryBuffer->m_Name);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glDrawBuffers(1,draw_buffers);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

m_AmbientShader->Begin();
    m_AmbientShader->SetUniformInt1("Diffuse",m_DiffuseTexture->m_TextureUnit);
    // Draw full screen quad
    glBegin(GL_QUADS);
        glMultiTexCoord2i(GL_TEXTURE0,0,0);
        glVertex2i(-1,-1);
        glMultiTexCoord2i(GL_TEXTURE0,1,0);
        glVertex2i(1,-1);
        glMultiTexCoord2i(GL_TEXTURE0,1,1);
        glVertex2i(1,1);
        glMultiTexCoord2i(GL_TEXTURE0,0,1);
        glVertex2i(-1,1);
    glEnd();
m_AmbientShader->End();

const DirectionalLight& dl = scene.GetDirectionalLight();

glDrawBuffers(1, draw_buffers);
m_DirectionalLightShader->Begin();
m_DirectionalLightShader->SetUniformInt1("Diffuse",m_DiffuseTexture->m_TextureUnit);
m_DirectionalLightShader->SetUniformInt1("Position",m_PositionTexture->m_TextureUnit);
m_DirectionalLightShader->SetUniformInt1("Normal",m_NormalTexture->m_TextureUnit);
m_DirectionalLightShader->SetUniformFloat3("LightDir",dl.GetDirection());
m_DirectionalLightShader->SetUniformFloat3("LightAmb",dl.GetAmb());
m_DirectionalLightShader->SetUniformFloat3("LightDiff",dl.GetDiff());
m_DirectionalLightShader->SetUniformFloat3("LightSpec",dl.GetSpec());
m_DirectionalLightShader->SetUniformFloat3("LightAtt",dl.GetAtt());
m_DirectionalLightShader->SetUniformFloat1("LightIntensity",dl.GetIntensity());
    // Draw full screen quad
    glBegin(GL_QUADS);
        glMultiTexCoord2i(GL_TEXTURE0,0,0);
        glVertex2i(-1,-1);
        glMultiTexCoord2i(GL_TEXTURE0,1,0);
        glVertex2i(1,-1);
        glMultiTexCoord2i(GL_TEXTURE0,1,1);
        glVertex2i(1,1);
        glMultiTexCoord2i(GL_TEXTURE0,0,1);
        glVertex2i(-1,1);
    glEnd();
m_DirectionalLightShader->End();

如果我的数学错误,请原谅,我一直在搞乱着色器以尝试获得任何类型的输出,但这里是着色器源文件;

<-- 方向光.vert -->

varying out vec2 ScreenPos;

varying out vec3 VSLightDir;

uniform vec3 LightDir;
uniform vec3 LightAmb;
uniform vec3 LightDiff;
uniform vec3 LightSpec;
uniform float LightIntensity;

void main()
{
    gl_Position = gl_Vertex;
    ScreenPos = gl_MultiTexCoord0.st;
    VSLightDir = normalize((gl_ModelViewMatrix * vec4(LightDir,0.0)).xyz);
}

<-- 方向光.frag -->

// Gbuffer textures
uniform sampler2D Diffuse;
uniform sampler2D Position;
uniform sampler2D Normal;

in vec2 ScreenPos;
uniform vec3 LightDir;
uniform vec3 LightAmb;
uniform vec3 LightDiff;
uniform vec3 LightSpec;
uniform float LightIntensity;

in vec3 VSLightDir;
out vec4 OutColour;

void main()
{
    // Sample from the GBuffer
    vec4 Diffuse = texture2D(Diffuse, ScreenPos);
    vec4 VSPos = texture2D(Position, ScreenPos);
    vec4 MRT2 = texture2D(Normal, ScreenPos);
    vec3 VSNormal = normalize(MRT2.xyz);
    float Shininess = MRT2.w;

    float LDotN = dot(VSNormal, VSLightDir);

    vec3 View = -normalize(VSPos.xyz);

    // Compute ambient contribution
    vec3 ambient = LightIntensity * LightAmb * Diffuse.xyz;

    // Compute diffuse contribution
    vec3 diffuse = LightIntensity * LightDiff * Diffuse.xyz * max(0.0, LDotN);

    // Compute specular contribution
    vec3 HalfWay = normalize(LightDir + View);
    vec3 specular = (LDotN <= 0.0)
                ? vec3(0.0)
                : LightIntensity * LightSpec * Diffuse.xyz * pow(max(0.0, dot(VSNormal,HalfWay)), Shininess);

    OutColour = vec4(ambient + diffuse + specular, Diffuse.a);
    //OutColour = vec4(0.0,0.0,1.0,1.0); //Debug line
}

<-- 环境.vert -->

varying out vec2 ScreenPos;

void main()
{
    gl_Position = gl_Vertex;

    // Used for the position to sample from GBuffer
    ScreenPos = gl_MultiTexCoord0.st;
}

<-- 环境.frag -->

// Gbuffer textures
uniform sampler2D Diffuse;

in vec2 ScreenPos;

out vec4 OutColour;

void main()
{
    OutColour = texture2D(Diffuse, ScreenPos);
    //OutColour = vec4(0.0,0.0,1.0,1.0);
}
4

1 回答 1

3

您是否启用了深度测试?我看到您正在清除深度缓冲区,所以我怀疑也许,但是您正在以与第一个完全相同的深度绘制第二个纹理。glDepthFunc默认情况下会GL_LESS导致第二次抽奖被完全拒绝。

或者,您希望如何将这两个平局结合起来?是否应该涉及一些混合?

于 2012-04-15T19:28:38.223 回答