2012-04-15 103 views
2

总之,我的全屏着色器不输出任何东西,为什么OpenGL + GLSL着色器不输出任何内容?

我正在GLSL写一个延期着色器,我已经到了我在屏幕空间应用灯光的阶段。我有一个环境通道,我基本上把GBuffer的diffuse强度写入默认的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(); 

请原谅我,如果我的数学是错误的,我一直在插科打诨与着色器,试图得到任何形式输出的,但这里有着色器源文件;

< - directional_light.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); 
} 

< - directional_light.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 
} 

< - ambient.vert - >

varying out vec2 ScreenPos; 

void main() 
{ 
    gl_Position = gl_Vertex; 

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

< - ambient.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); 
} 

回答

3

您是否启用了深度测试?我看到你正在清除深度缓冲区,所以我怀疑可能,但是你正在绘制第二个纹理,其深度与第一个纹理完全相同。与glDepthFunc默认GL_LESS,这将导致第二次被完全拒绝。

或者其他情况你如何将两次抽签合并?是否应该有一些混合?

+0

非常感谢你的答复,只是禁用深度测试,它绝对有效。我期待将它们混合为轻量级贡献,以便添加至饱和度。 glBlendFunc(GL_ONE,GL_ONE)会实现这个吗?我有一个固定的函数替代管道来测试我是否得到相同的结果,但它们略有不同。 – 2012-04-16 10:01:46

+0

@RDay:是的,那blendfunc应该做你想做的。不要忘记glEnable(GL_BLEND) – Tim 2012-04-16 17:23:04

+0

太棒了,再次感谢你! – 2012-04-16 19:15:37