Help with basic deferred lighting please - Solved

Started by
18 comments, last by hannesp 9 years, 2 months ago

Hi

I'm working on a little project to learn about deferred lighting in GLSL. So far I can render to textures, and display them as can be seen in the screenshot. But I am stuck at the lighting part - I can display the scene by just referencing the 'Diffuse' image texture, but that ignores any lighting I am attempting. I have looked at lots of examples but can't work it out. Any help would be great please.

Screenshot - the black square in the middle will display the final image: I am trying to display a light above the scene.

vghijr.png

This is the lightPass fragment shader:


#version 330

uniform sampler2D   tDiffuse;
uniform sampler2D   tPosition;
uniform sampler2D   tNormals;

uniform vec3        cameraPosition;
uniform vec4        lightPosition;

in vec2 fragTexCoord0;

out vec4 outColor;

void main( void )
{
	vec4 image =    texture2D( tDiffuse, fragTexCoord0 );
	vec4 position = texture2D( tPosition, fragTexCoord0 );
	vec4 normal =   texture2D( tNormals, fragTexCoord0 );

    vec3 light = vec3(0,50,0);

    vec3 lightDir = light.xyz - position.xyz;

    normal = normalize(normal);
    lightDir = normalize(lightDir);

    vec3 eyeDir = normalize(cameraPosition-position.xyz);
    vec3 vHalfVector = normalize(lightDir.xyz+eyeDir);

    float diffuse = max(dot(vec3(normal),lightDir),0);
    float specular = pow(max(dot(vec3(normal),vHalfVector),0.0), 100) * 1.5;

    outColor =  diffuse * image + specular;

// This displays the Diffuse texture 
// outColor = image;

}
Advertisement

your position and normal are vec4, what values do the w components have? this can affect the normalization of the normal maybe

use vec3 n = normalize(normal.xyz) or change the texture lookup

your calculations of diffuse and specular terms seem to be correct

i also think you dont transform your normals correctly

on the tanks blue is up, on the floor green is up

transform normals in the geometry pass by the inverse transpose of modelview matrix

your position and normal are vec4, what values do the w components have? this can affect the normalization of the normal maybe

use vec3 n = normalize(normal.xyz) or change the texture lookup

your calculations of diffuse and specular terms seem to be correct

i also think you dont transform your normals correctly

on the tanks blue is up, on the floor green is up

transform normals in the geometry pass by the inverse transpose of modelview matrix

Changed texture lookups to vec3 types - no difference.


#version 330

uniform sampler2D   tDiffuse;
uniform sampler2D   tPosition;
uniform sampler2D   tNormals;

uniform vec3        cameraPosition;
uniform vec4        lightPosition;

in vec2 fragTexCoord0;

out vec4 outColor;

void main( void )
{
	vec4 image =    texture2D( tDiffuse, fragTexCoord0 );
	vec3 position = texture2D( tPosition, fragTexCoord0 ).xyz;
	vec3 normal =   texture2D( tNormals, fragTexCoord0 ).xyz;

    vec3 light = vec3(0,50,0);

    vec3 lightDir = light.xyz - position.xyz;

    normal = normalize(normal);
    lightDir = normalize(lightDir);

    vec3 eyeDir = normalize(cameraPosition-position.xyz);
    vec3 vHalfVector = normalize(lightDir.xyz+eyeDir);

    float diffuse = max(dot(vec3(normal),lightDir),0);
    float specular = pow(max(dot(vec3(normal),vHalfVector),0.0), 100) * 1.5;

    outColor =  diffuse * image + specular;
}

This is the geometry pass shader where the normals are transformed - I think I'm doing a inverse transpose of the modelView matrix.


#version 330

uniform mat4 u_viewProjectionMat;
uniform mat4 u_modelMat;

in vec3 inPosition;
in vec2 inTextureCoords;
in vec3 inNormal;

out vec2 TexCoord0;
out vec3 Normal0;
out vec3 WorldPos0;

void main()
{
    mat3 normalMatrix = transpose(inverse(mat3(u_modelMat)));

    TexCoord0      = inTextureCoords;
    Normal0        = normalize(normalMatrix * inNormal).xyz;
    WorldPos0      = (u_modelMat * vec4(inPosition, 1.0)).xyz;

    gl_Position    = u_viewProjectionMat * u_modelMat * vec4(inPosition, 1.0);
}

Thanks for the suggestions.

normal transformation looks correct, if you do no scaling on the modelMat even the modelMat itself would be a proper transformation for normals

but since you transformed them to worldspace colors should be consistent for surfaces which equal orientation, which is clearly not the case for your rendering of worldspace normal vectors - so as soon as you get some lighting expect it to be wrong on the tanks tongue.png

try to render the lightDirs next, pls post the result :)

What's the format of the render target where you're storing the normals? Is it a signed format? (Since you don't seem to be doing any [0-1] -> [-1,1] mapping when using the value from the normal texture).

as phil_t said ... i recommend to use RGB32F which means 32bit for each vector component

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, width, height, 0, GL_RGB, GL_FLOAT, 0);

usually color textures have a RGB or RGBA format, which provides only unsigned 8 bit per component

You could try to test with a static normal, instead of the normalmap lookup and see what happens (thinking about what phil_t mentioned).

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

try to render the lightDirs next, pls post the result smile.png

Rendering with


    outColor = vec4(lightDir, 1.0);

25i7jwm.png

and rendering with:


gl_createGBufTex(GL_TEXTURE2, GL_RGB32F, id_textures[GBUFFER_TEXTURE_TYPE_NORMAL], GL_RGB, screenWidth, screenHeight);  // Normal

Creation of the Buffer fails with:


case GL_FRAMEBUFFER_UNSUPPORTED:
                    printf("The combination of internal formats of the attached images violates an implementation-dependent set of restrictions.\n");
                    break;

OpenGL driver details:


Vendor: [ Intel Open Source Technology Center ]
Renderer: [ Mesa DRI Intel(R) Haswell Mobile  ]
Version: [ 3.3 (Core Profile) Mesa 10.3.2 ]

15hbuxs.png

I changed the way the models are loaded using Assimp to discard the normals and regenerate them - they are looking better now.

2ezic7m.png

Still no lighting however.

that's no opengl command ...

gl_createGBufTex(GL_TEXTURE2, GL_RGB32F, id_textures[GBUFFER_TEXTURE_TYPE_NORMAL], GL_RGB, screenWidth, screenHeight); // Normal

could you provide sourcecode for this?

since you don't specifiy it in gl_createGBufTex the GL_FLOAT part may be missing

that's no opengl command ...

gl_createGBufTex(GL_TEXTURE2, GL_RGB32F, id_textures[GBUFFER_TEXTURE_TYPE_NORMAL], GL_RGB, screenWidth, screenHeight); // Normal

could you provide sourcecode for this?

since you don't specifiy it in gl_createGBufTex the GL_FLOAT part may be missing


//-----------------------------------------------------------------------------
//
// Create the GBuffer
void gl_createGBufTex( GLenum texUnit, GLenum format1, GLuint &texid, GLenum format2, GLuint width, GLuint height )
//-----------------------------------------------------------------------------
{
    GL_ASSERT(glActiveTexture(texUnit));
    GL_ASSERT(glGenTextures(1, &texid));
    GL_ASSERT(glBindTexture(GL_TEXTURE_2D, texid));
    GL_ASSERT(glTexImage2D(GL_TEXTURE_2D, 0, format1, width, height, 0, format2, GL_FLOAT, NULL));

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}

Called this way:


    //
    // Create the textures for position, normal and color
    gl_createGBufTex(GL_TEXTURE0, GL_RGBA, id_textures[GBUFFER_TEXTURE_TYPE_DIFFUSE],  GL_RGBA, screenWidth, screenHeight);  // Color
    gl_createGBufTex(GL_TEXTURE1, GL_RGBA, id_textures[GBUFFER_TEXTURE_TYPE_POSITION], GL_RGBA, screenWidth, screenHeight);  // Position
    gl_createGBufTex(GL_TEXTURE2, GL_RGB, id_textures[GBUFFER_TEXTURE_TYPE_NORMAL], GL_RGB, screenWidth, screenHeight);  // Normal
    //

This is the same scene using a forward rendering shader with one light and shadowmap.

2j2z6ef.png

This topic is closed to new replies.

Advertisement