2
\$\begingroup\$

I've been rendering a scene (some objects over a large field of grass) to test shadow mapping which is working fine.

But when I use instancing to "gain" performance, I not only get a decrease in performance (by losing 2-4 ms per frame !), but my lighting also gets messed up.

Comparaison :

Scene without instancing : Normal scene

Scene with instancing : Messed up scene

The shadows are still rendered fine, but the grass lighting is completely off, alternating between dark and bright grass. The small "scene" above the grass is also very dark (I use the same shader as the one for the grass, for convenience purposes).

Even the debug text in the upper left corner isn't being rendered anymore...

I use the same shader for both scenes, except I use a uniform to let the shader know when I use instancing and when I'm not.

Here is the lighting shader:

//Vertex Shader
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec2 texCoords;
layout (location = 2) in vec3 normal;
layout (location = 3) in mat4 a_model;

out vec2 TexCoords;

out VS_OUT
{
    vec3 FragPos;
    vec3 Normal;
    vec2 TexCoords;
    vec4 FragPosLightSpace;
} vs_out;

uniform bool instanciate;

uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;
uniform mat4 lightSpaceMatrix;

uniform float u_time;

void main()
{   
    mat4 model1;
    if (instanciate)
        model1 = a_model;
    else 
        model1 = model;
    //Grass movement
    float time = u_time + 8.5f * gl_InstanceID;
    vec3 pos = position;
    float fact = 7/position.y;
    float sx = sin(pos.x*32.0+time*4.0)/fact*0.5+0.5;
    float cy = cos(pos.y*32.0+time*4.0)/fact*0.5+0.5;
    vec3 displacement = vec3(sx, cy, sx*cy);
    vec3 normalN = normal.xyz*2.0 - 1.0;

    pos = pos + normalN*displacement*vec3(0.06, 0.06, 0.06)*vec3(8.0, 3.0, 1.0);

    gl_Position = projection * view * model1 * vec4(pos, 1.0f);
    //Used for shadow mapping
    vs_out.FragPos = vec3(model1 * vec4(position, 1.0));
    vs_out.Normal = transpose(inverse(mat3(model1))) * normal;
    vs_out.TexCoords = texCoords;
    vs_out.FragPosLightSpace = lightSpaceMatrix * vec4(vs_out.FragPos, 1.0);
}

The fragment shader didn't change when I implemented instancing, so I don't think it's relevant to put it here.

Also, here is how I render the scene :

    glUniform1i(glGetUniformLocation(programMesh, "instanciate"), GL_TRUE);
    //The buffer is setup before with the matrices
    glEnableVertexAttribArray(3);
    glBindBuffer(GL_ARRAY_BUFFER, modelbuffer); // model matrices buffer
    glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (GLvoid*)0);
    glEnableVertexAttribArray(4);
    glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (GLvoid*)(vec4Size));
    glEnableVertexAttribArray(5);
    glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (GLvoid*)(2 * vec4Size));
    glEnableVertexAttribArray(6);
    glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, 4 * vec4Size, (GLvoid*)(3 * vec4Size));

    glVertexAttribDivisor(3, 1);
    glVertexAttribDivisor(4, 1);
    glVertexAttribDivisor(5, 1);
    glVertexAttribDivisor(6, 1);

    double instanceTime = elapsedTIme;
    glUniform1f(u_time, instanceTime);
    glDrawArraysInstanced(GL_TRIANGLES, 0, vertices.size(), 100);

    glUniform1i(glGetUniformLocation(programMesh, "instanciate"), GL_FALSE);

I don't really know where the problem could be.

I can give more code if needed.

Thanks in advance for any help.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.