【问题标题】:OpenGL Deferred Shading lighting not working properlyOpenGL延迟着色照明无法正常工作
【发布时间】:2016-07-24 01:14:27
【问题描述】:

所以这是我第一次使用延迟着色,它非常快速和简单。直到我开始没有得到预期的结果。光线的行为方式很奇怪,就好像位置纹理不正确。 (从上到下顺时针:(1)法线,(2)位置,(3)反照率,(4)粗糙度/菲涅尔,(中心)最终)

请注意,灯光(在最终渲染中)的行为方式很奇怪。

这是我的着色器代码: 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

编辑:原来我只需要为法线和位置使用浮动纹理

【问题讨论】:

  • 一件看起来很奇怪的事情是您在着色器中使用core 配置文件,但您的着色器仍然使用旧功能(`gl_ModelViewProjectionMatrix 等)
  • @SurvivalMachine 这将在未来改变,我正在学习现代 OpenGL。我仍然使用旧功能,因为它的设置和原型制作速度更快。
  • 好吧,我本可以发布:“我希望有人分析我的代码”但我没有,所以如果有人真的回复了正确的答案,那就太好了。
  • 这也是重点:代码无效,因此可以做任何事情。核心配置文件中没有内置矩阵、ftransformgl_TexCoord 等。

标签: java opengl lwjgl lighting deferred-rendering


【解决方案1】:

两个想法:

您必须使用浮点纹理,否则您的值会被限制在 [0;1] 范围内,或者如果是法线,您可以将它们缩放并偏置到该范围(并使用比 32F/16F 更小的格式)

除非您将 CPU 侧的灯光位置更改为视图坐标,否则您在光照中同时计算视图位置(来自您的位置 g 缓冲区)和世界坐标(您的灯光位置)。 frag,这肯定会影响输出。

希望对你有帮助!

【讨论】:

  • 非常感谢!我只需要使用浮动纹理
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-02
  • 1970-01-01
  • 2015-07-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多