2016-07-22 75 views
1

所以這是我第一次使用延期着色,它非常快速和簡單。直到我開始沒有得到預期的結果。光線以一種奇怪的方式表現,就像位置紋理不正確。 Deferred (從頂部順時針底部:(1)正常,(2)的位置,(3)反照率,(4)表面粗糙度/菲涅爾,(中心)最終)OpenGL延期着色照明無法正常工作

注意,光(在最後的渲染)表現得很怪異。

這裏是我的着色器代碼: GBuffer.vert

#version 330 core 

// I didn't have time to change this into layout (location = ...) ... 
attribute vec3 pos; 
attribute vec3 norm; 
attribute vec3 tangent; 
attribute vec2 uv; 

out DATA { 
    vec3 position; 
    vec3 normal; 
    vec2 texCoord; 
    mat3 tbn; 
} VS_OUT; 

void main() { 
    gl_Position = gl_ModelViewProjectionMatrix * vec4(pos, 1.0); 
    VS_OUT.position = (gl_ModelViewMatrix * vec4(pos, 1.0)).xyz; 
    VS_OUT.normal = gl_NormalMatrix * norm; 

    vec3 n = normalize(VS_OUT.normal); 
    vec3 t = normalize(gl_NormalMatrix * tangent); 
    t = normalize(t - dot(t, n) * n); 
    vec3 b = cross(t, n); 

    VS_OUT.tbn = mat3(t, b, n); 
    VS_OUT.texCoord = uv; 
} 

GBuffer.frag

#version 330 core 
layout (location = 0) out vec3 g_position; 
layout (location = 1) out vec3 g_normal; 
layout (location = 2) out vec4 g_diffuse; 
layout (location = 3) out vec4 g_material; 

struct TSlot { 
    int active; 
    int type; 
    vec2 scale; 
    float intensity; 
    int blendMode; 
}; 

struct TMaterial { 
    vec4 albedo; 
    float roughness; 
    float fresnel; 
}; 

struct TScene { 
    vec3 ambient; 
    vec3 viewPosition; 
}; 

// Textures 
uniform sampler2D textures[8]; 
uniform TSlot textureSlots[8]; 

// Scene 
uniform TScene scene; 

// Material 
uniform TMaterial material; 

// Object 
in DATA { 
    vec3 position; 
    vec3 normal; 
    vec2 texCoord; 
    mat3 tbn; 
} FS_IN; 

[... blending functions ...] 

void main() { 
    vec3 N = FS_IN.normal; 

    vec4 texs = vec4(1.0); 
    vec4 tex0 = vec4(0.0); 

    for (int i = 0; i < 8; i++) { 
     if (textureSlots[i].active == 0) { continue; } 
     vec2 uv = textureSlots[i].scale * FS_IN.texCoord; 
     int type = textureSlots[i].type; 
     if (type == 0) { // Diffuse 
      vec4 diff = texture2D(textures[i], uv); 
      texs = blend(texs, diff, textureSlots[i].intensity * diff.a, textureSlots[i].blendMode); 
     } if (type == 1) { // Normal 
      vec3 encNorm = texture2D(textures[i], uv).xyz; 
      vec3 localCoords = normalize(vec3(2.0, 2.0, 1.0) * encNorm - vec3(1.0, 1.0, 0.0)); 
      N *= normalize(FS_IN.tbn * localCoords); 
     } else if (type == 2) { // Sphere Reflection 
      vec3 E = normalize(scene.viewPosition - FS_IN.position); 
      vec3 R = normalize(reflect(E, N)); 
      float m = 2.0 * sqrt( 
       pow(R.x, 2.0) + 
       pow(R.y, 2.0) + 
       pow(R.z + 1.0, 2.0) 
      ); 
      vec2 tex = R.xy/m + 0.5; 
      vec4 diff = texture2D(textures[i], tex * textureSlots[i].scale); 
      texs = blend(texs, diff, textureSlots[i].intensity * diff.a, textureSlots[i].blendMode); 
     } else if (type == 3) { // Roughness Map 
      tex0.r = blendNormalFloat(tex0.r, texture2D(textures[i], uv).x, textureSlots[i].intensity); 
     } else if (type == 4) { // Fresnel Map 
      tex0.g = blendNormalFloat(tex0.g, texture2D(textures[i], uv).x, textureSlots[i].intensity); 
     } 
    } 

    // Outputs 
    g_position = FS_IN.position; 
    g_normal = N; 
    g_diffuse.rgb = texs.rgb * material.albedo.rgb; 
    g_diffuse.a = 1.0; 
    g_material = vec4(material.roughness + tex0.r, material.fresnel + tex0.g, 0.0, 0.0); 
} 

Lighting.vert

#version 330 core 

void main() { 
    gl_Position = ftransform(); 
    gl_TexCoord[0] = gl_MultiTexCoord0; 
    gl_FrontColor = vec4(1.0, 1.0, 1.0, 1.0); 
} 

Lighting.frag

#version 330 core 
layout (location = 0) out vec4 fragColor; 

struct TLight { 
    vec3 position; 
    float intensity; 
    vec3 color; 
    float radius; 
    float cutoff; 
    float spotCutoff; 
    vec3 direction; 
    int type; 
}; 

struct TScene { 
    vec3 ambient; 
    vec3 viewPosition; 
}; 

// Textures from GBuffer 
uniform sampler2D t_position; 
uniform sampler2D t_normal; 
uniform sampler2D t_diffuse; 
uniform sampler2D t_material; 

uniform TLight light; 
uniform TScene scene; 

void main() { 
    vec2 uv = gl_TexCoord[0].xy; 
    vec3 P = texture2D(t_position, uv).xyz; 
    vec3 N = normalize(texture2D(t_normal, uv).xyz); 
    vec4 D = texture2D(t_diffuse, uv); 
    vec4 M = texture2D(t_material, uv); 

    vec3 lighting = D.rgb * 0.1; 
    vec3 V = normalize(scene.viewPosition - P); 
    vec3 lightDir = normalize(light.position - P); 
    vec3 diffuse = max(dot(N, lightDir), 0.0) * D.rgb * light.color * light.intensity; 
    lighting += diffuse; 

    fragColor = vec4(lighting, 1.0); 
} 

我下面這些教程:http://www.codinglabs.net/tutorial_simple_def_rendering.aspx http://learnopengl.com/#!Advanced-Lighting/Deferred-Shading

編輯:原來我只是需要使用float紋理法線和位置

+0

看起來很奇怪的一件事是,您在着色器中使用'core'配置文件,但着色器仍然使用舊功能('gl_ModelViewProjectionMatrix等) – SurvivalMachine

+0

@SurvivalMachine這將在未來進行更改,我在學習現代OpenGL的過程中。我仍然使用舊功能,因爲它的設置和原型更快。 – dcubix

+0

嗯,我本可以發佈:「我想讓別人分析我的代碼」但是我沒有,所以如果有人真的回答了正確的答案,這將非常好。 – dcubix

回答

1

兩個想法:

,你必須使用浮點紋理,否則你的值被限制在[0; 1]的範圍內,或者在你的法線的情況下,你可以縮放並將它們偏移到該範圍內(並且使用比32F/16F更小的格式)

除非你是cha將光源在CPU端的位置調整到視圖座標中,您將在lighting.frag中同時計算視圖位置(從您的位置g緩衝區)和世界座標(您的光源位置),這將會一團糟與輸出。

我希望有幫助!

+0

非常感謝!我只需要使用浮動紋理 – dcubix