0
\$\begingroup\$

I am adding shadow mapping to a game engine I am working on.

For this effect, each light source needs it's own associated shadow map cube texture.

I am going to be exaggerated and say there can be up to 1000 lights in the world at a given time (this would most likely lag the entire thing, but that's not the issue).

This means I need up to 1000 depth maps loaded into the shaders at any one time.

According to:

GLint temp; 
glGetIntegerv(GL_MAX_TEXTURE_UNITS, &temp);
cout << temp << endl;

I have up to 4 texture units available. And the way I am currently passing my shadow maps is:

void Shadow_Map::load_to_GPU(GLuint program, GLuint index)
{   
    glUseProgram(program);
    glActiveTexture(GL_TEXTURE0+index+1);
    glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);

    string name = "depth_maps[" + to_string(index) + "]";

    GLint loc = glGetUniformLocation(program, name.c_str());
    if(loc == GL_INVALID_VALUE || loc==GL_INVALID_OPERATION)
    {
        cerr << "Error returned when trying to find depth_map uniform."
             << endl;
        return;
    }

    glUniform1i(loc,1+index);
}

So under my current methods I am very far away from the amount of depth map cube textures I need to use. Is there a better way to pass a large amount of cubicTextures, or what other techinique could I use to be able to handle large amounts of point lights?

\$\endgroup\$
  • 2
    \$\begingroup\$ "Many point lights" sounds like you're right in the wheelhouse of deferred rendering. \$\endgroup\$ – DMGregory Feb 18 '18 at 22:03
  • \$\begingroup\$ "I have up to 4 texture units available." That's compatibility OpenGL. A core profile would have given you an error. The maximum number of texture image units for a fragment shader is GL_MAX_TEXTURE_IMAGE_UNITS. \$\endgroup\$ – Nicol Bolas Feb 19 '18 at 1:40
  • \$\begingroup\$ Also, note that a 512x512 depth cubemap, even at 16-bit precision, requires 3 MB. Therefore, storing 1000 of them would require 3 GB. Good luck with that. \$\endgroup\$ – Nicol Bolas Feb 19 '18 at 1:44
2
\$\begingroup\$

I would use a Cube Map Texture Array for this. You can query the maximum array texture layers with:

GLuint max_layers;
glGetIntegerv (GL_MAX_ARRAY_TEXTURE_LAYERS, &max_layers);

E.g. my implementation (NVIDIA) returns 2048. Your mileage may vary with others.

I am raising my eyebrow slightly at the need for so many light sources. It seems a little excessive.

As DMGregory mentions, deferred shading is a preferred solution for many light sources, however even there you aren't going to generate a unique shadow map for each. It's not trivial to implement well either.

\$\endgroup\$
  • 1
    \$\begingroup\$ "my implementation (NVIDIA) returns 2048. Your mileage may vary with others." Note that for cubemap arrays, the maximum number of array texture layers is actually the number of layer faces. So the maximum number of cubemap array layers would be 2048 / 6 = 341. \$\endgroup\$ – Nicol Bolas Feb 19 '18 at 1:39
  • \$\begingroup\$ Ah, good point Nicol. \$\endgroup\$ – Robinson Feb 19 '18 at 18:34

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.