Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 4 of 4

Thread: Point lights shadows via GL_TEXTURE_CUBE_MAP_ARRAY: mess with cube faces

  1. #1
    Junior Member Newbie
    Join Date
    Nov 2017
    Posts
    14

    Point lights shadows via GL_TEXTURE_CUBE_MAP_ARRAY: mess with cube faces

    Hi, All.

    After success reworking CSM from separated textures to texture array, I want to do similar refactoring with shadow cube of point lights.
    So, I try to use GL_TEXTURE_CUBE_MAP_ARRAY instead several GL_TEXTURE_CUBE_MAP.


    When I use one point light it is looks fine, but when I try to it with two there is some mess with cube faces:

    one:
    Click image for larger version. 

Name:	one-cube-map.jpg 
Views:	14 
Size:	17.2 KB 
ID:	2562


    two:
    Click image for larger version. 

Name:	two-cube-maps.jpg 
Views:	14 
Size:	20.1 KB 
ID:	2563


    I,m using OpenGl 4.0, lwjgl (java opengl library)

    CubeShadowBuffer:
    Code :
        depthMapFBO = glGenFramebuffers();
     
        depthMap = new CubeTexture(shadowMapWidth, shadowMapHeight, GL_DEPTH_COMPONENT, lightsNumber);
     
        glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
        glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthMap.getId(), 0, 0);
     
        glDrawBuffer(GL_NONE);
        glReadBuffer(GL_NONE);
     
        int status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
        if (status != GL_FRAMEBUFFER_COMPLETE) {
          // number of problem from enum
          throw new IllegalStateException("Could not create FrameBuffer: " + (status - GL_FRAMEBUFFER_COMPLETE));
        }
     
        glBindFramebuffer(GL_FRAMEBUFFER, 0);


    CubeTexture:
    Code :
        id = glGenTextures();
     
        glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, id);
        glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
     
        glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_DEPTH_COMPONENT, width, height, 6 * lightsNumber, 0, GL_DEPTH_COMPONENT, GL_FLOAT, (ByteBuffer) null);
     
        glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, 0);



    Cycle of rendering:
    Code :
      public void render(Display display, Camera camera, Scene scene, Transformation transformation, IHud hud) {
     
     
        glViewport(0, 0, SHADOW_MAP_WIDTH, SHADOW_MAP_HEIGHT);
     
        for (int cnt = 0; cnt < MAX_POINT_LIGHTS; cnt++) {
          Matrix4f viewMatrix = camera.updateViewMatrix();
          update(display, viewMatrix, scene, cnt);
     
          depthShaderProgram.bind();
     
     
          glDrawBuffer(GL_NONE);
          glReadBuffer(GL_NONE);
          glCullFace(GL_BACK);
     
          glClearColor(Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE);
     
          renderCubeFace(shadowBuffer, pointLightShadowBox.getRightMap(), 0 + cnt, scene, transformation);
          renderCubeFace(shadowBuffer, pointLightShadowBox.getLeftMap(), 1 + cnt, scene, transformation);
          renderCubeFace(shadowBuffer, pointLightShadowBox.getTopMap(), 2 + cnt, scene, transformation);
          renderCubeFace(shadowBuffer, pointLightShadowBox.getBottomMap(), 3 + cnt, scene, transformation);
          renderCubeFace(shadowBuffer, pointLightShadowBox.getRearMap(), 4 + cnt, scene, transformation);
          renderCubeFace(shadowBuffer, pointLightShadowBox.getFrontMap(), 5 + cnt, scene, transformation);
     
          depthShaderProgram.unbind();
          glBindFramebuffer(GL_FRAMEBUFFER, 0);
          glDrawBuffer(GL_BACK);
          glReadBuffer(GL_BACK);
        }
     
      }
     
      private void renderCubeFace(CubeShadowBuffer shadowBuffer, ShadowMap shadowMap, int face, Scene scene, Transformation transformation) {
        depthShaderProgram.setUniform("projectionMatrix", shadowMap.getProjectionMatrix());
        depthShaderProgram.setUniform("lightViewMatrix", shadowMap.getLightViewMatrix());
     
        glBindFramebuffer(GL_FRAMEBUFFER, shadowBuffer.getDepthMapFBO());
        glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, shadowBuffer.getDepthMapTexture().getId(), 0, face);
        glDrawBuffer(GL_DEPTH_ATTACHMENT);
        glClear(GL_DEPTH_BUFFER_BIT);
     
        renderMeshes(scene, transformation);
      }


    Thank you for help!

  2. #2
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    4,170
    I would try checking for GL errors. For instance, glDrawBuffer() specifies the color buffer to write to. GL_DEPTH_ATTACHMENT is not a color buffer.

    Also, where's your shader that reads from the cubemap array?

  3. #3
    Junior Member Newbie
    Join Date
    Nov 2017
    Posts
    14
    Quote Originally Posted by Dark Photon View Post
    I would try checking for GL errors. For instance, glDrawBuffer() specifies the color buffer to write to. GL_DEPTH_ATTACHMENT is not a color buffer.
    Added validation, and there is no any errors:
    Code :
        glBindFramebuffer(GL_FRAMEBUFFER, shadowBuffer.getDepthMapFBO());
        glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, shadowBuffer.getDepthMapTexture().getId(), 0, face);
        glDrawBuffer(GL_DEPTH_ATTACHMENT);
        glClear(GL_DEPTH_BUFFER_BIT);
     
        int status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
        if (status != GL_FRAMEBUFFER_COMPLETE) {
          // number of problem from enum
          throw new IllegalStateException("Could not create FrameBuffer: " + (status - GL_FRAMEBUFFER_COMPLETE));
        }

    Quote Originally Posted by Dark Photon View Post
    Also, where's your shader that reads from the cubemap array?
    There is the shader:
    Code :
    #version 400
    ...
    uniform samplerCubeArray plShadowMap;
    uniform int plNumber;
    ...
     
    float calcPlShadow(vec3 position, PointLight light, int idx) {
     
     
      mat4 plLightViewMatrix = mat4(1,0,0,0,
                        0,1,0,0,
                        0,0,1,0,
                        -light.position.x,-light.position.y,-light.position.z,1);
     
      vec4 position_ls = plLightViewMatrix * wPosition;
      vec4 abs_position = abs(position_ls);
      float fs_z = -max(abs_position.x, max(abs_position.y, abs_position.z));
      vec4 clip = plProjectionMatrix * vec4(0.0, 0.0, fs_z, 1.0);
      float depth = (clip.z / clip.w) * 0.5 + 0.5;
      float result = 0.0;
      result = texture(plShadowMap, vec4(position_ls.xyz, idx)).r;
      if (result >= depth - 0.0002) {
        return 1.0;
      } else {
        return 0.0;
      }
    }
     
    void main() {
      ...
      vec4 aroundLight = vec4(0,0,0,0);
     
      for (int i=0; i < plNumber; i++) {
        if ( pointLights[i].intensity > 0 ) {
     
          float shadow = 1;
          vec4 currPointLight = calcPointLight(pointLights[i], mvVertexPos, currNomal);
          shadow = calcPlShadow(mvVertexPos, pointLights[i], i);
          aroundLight += (currPointLight * shadow);
        }
      }
    ...
    }

  4. #4
    Junior Member Newbie
    Join Date
    Nov 2017
    Posts
    14
    I have found the problem.

    It was so stupid bug!
    was:
    Code :
        for (int cnt = 0; cnt < MAX_POINT_LIGHTS; cnt++) {
          ......
          renderCubeFace(shadowBuffer, pointLightShadowBox.getRightMap(), 0 + cnt, scene, transformation);
          renderCubeFace(shadowBuffer, pointLightShadowBox.getLeftMap(), 1 + cnt, scene, transformation);
          renderCubeFace(shadowBuffer, pointLightShadowBox.getTopMap(), 2 + cnt, scene, transformation);
          renderCubeFace(shadowBuffer, pointLightShadowBox.getBottomMap(), 3 + cnt, scene, transformation);
          renderCubeFace(shadowBuffer, pointLightShadowBox.getRearMap(), 4 + cnt, scene, transformation);
          renderCubeFace(shadowBuffer, pointLightShadowBox.getFrontMap(), 5 + cnt, scene, transformation);
          ......
        }

    fixed as:
    Code :
        for (int cnt = 0; cnt < MAX_POINT_LIGHTS; cnt++) {
          ......
          int idx = cnt * 6;
          renderCubeFace(shadowBuffer, pointLightShadowBox.getRightMap(), 0 + idx, scene, transformation);
          renderCubeFace(shadowBuffer, pointLightShadowBox.getLeftMap(), 1 + idx, scene, transformation);
          renderCubeFace(shadowBuffer, pointLightShadowBox.getTopMap(), 2 + idx, scene, transformation);
          renderCubeFace(shadowBuffer, pointLightShadowBox.getBottomMap(), 3 + idx, scene, transformation);
          renderCubeFace(shadowBuffer, pointLightShadowBox.getRearMap(), 4 + idx, scene, transformation);
          renderCubeFace(shadowBuffer, pointLightShadowBox.getFrontMap(), 5 + idx, scene, transformation);
          ......
        }

    Also i removed string "glDrawBuffer(GL_DEPTH_ATTACHMENT);".
    It was redundant there.
    Now it working fine!

    Thank you, Photon!

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •