Render Depth to Cube Map

I am attempting to render depth information into a cube map for use with shadows from a point light.
I have been using this site as a guide:
http://sunandblackcat.com/tipFullView.php?l=eng&topicid=36

I am unsure how to display the textures that are being created in the fbo so that I can visualize the depths written from the depth shaders. Or if they are being created correctly within the fbo. I have also looked at ofxCubeMap, but can’t seem to get it working for this purpose.

I am using the programmable renderer and openGL 3.3 on OSX 10.9.

Below is the code I am using to generate the cube map and fbo. Sorry for the long post. :slight_smile:

void Init( int asize ) {
        mSize = asize;
        
        
        // Create the FBO
        glGenFramebuffers(1, &m_fbo);
        glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
        
        // Create the depth buffer
        glGenTextures(1, &m_depth);
        glBindTexture(GL_TEXTURE_2D, m_depth);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, mSize, mSize, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depth, 0);
        
        glBindTexture(GL_TEXTURE_2D, 0);
        
        // Create the cube map
        glGenTextures(1, &m_shadowMap);
        glBindTexture(GL_TEXTURE_CUBE_MAP, m_shadowMap);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
//        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
        
//        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
        
        for (uint i = 0 ; i < 6 ; i++) {
            glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_R32F, mSize, mSize, 0, GL_RED, GL_FLOAT, NULL);
//            glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT32F, mSize, mSize, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
        }
        
        // Disable writes to the color buffer
//        glDrawBuffer(GL_NONE);
        
        // Disable reads from the color buffer
//        glReadBuffer(GL_NONE);
        
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X, m_shadowMap, 0 );
          
        GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
        switch(status) {
            case GL_FRAMEBUFFER_COMPLETE:
                ofLogVerbose("ofFbo") << "FRAMEBUFFER_COMPLETE - OK";
                return true;
            case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
                ofLogError("ofFbo") << "FRAMEBUFFER_INCOMPLETE_ATTACHMENT";
                break;
            case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
                ofLogError("ofFbo") << "FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";
                break;
            case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
                ofLogError("ofFbo") << "FRAMEBUFFER_INCOMPLETE_DIMENSIONS";
                break;
#ifndef TARGET_PROGRAMMABLE_GL
            case GL_FRAMEBUFFER_INCOMPLETE_FORMATS:
                ofLogError("ofFbo") << "FRAMEBUFFER_INCOMPLETE_FORMATS";
                break;
#endif
            case GL_FRAMEBUFFER_UNSUPPORTED:
                ofLogError("ofFbo") << "FRAMEBUFFER_UNSUPPORTED";
                break;
#ifndef TARGET_OPENGLES
            case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
                ofLogWarning("ofFbo") << "FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER";
                break;
            case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
                ofLogError("ofFbo") << "FRAMEBUFFER_INCOMPLETE_READ_BUFFER";
                break;
            case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
                ofLogError("ofFbo") << "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE";
                break;
#endif
            default:
                ofLogError("ofFbo") << "UNKNOWN ERROR " << status;
                break;
                
        }
        
// disable
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        glBindTexture(GL_TEXTURE_CUBE_MAP, 0);       

    }

and the bind for writing into the textures:
void BindForWriting( int CubeFace) {

        ofPushView();
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + CubeFace, m_shadowMap, 0 );
        glDrawBuffer(GL_COLOR_ATTACHMENT0);
//        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + CubeFace, m_shadowMap, 0 );
        glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
        
        cam.setFov( 90 );
        cam.setNearClip( 1 );
        cam.setFarClip( 1000 );
        
        if( CubeFace == 0 ) {
            cam.lookAt( ofVec3f(1,0,0), ofVec3f(0,1,0) );
        } else if( CubeFace == 1 ) {
            cam.lookAt( ofVec3f(-1,0,0), ofVec3f(0,1,0) );
        } else if( CubeFace == 2 ) {
            cam.lookAt( ofVec3f(0,1,0), ofVec3f(0,0,-1) );
        } else if( CubeFace == 3 ) {
            cam.lookAt( ofVec3f(0,-1,0), ofVec3f(0,0,1) );
        } else if( CubeFace == 4 ) {
            cam.lookAt( ofVec3f(0,0,1), ofVec3f(0,-1,0) );
        } else if( CubeFace == 5 ) {
            cam.lookAt( ofVec3f(0,0,-1), ofVec3f(0,-1,0) );
        }
        //        glLoadMatrixf( tcam.getProjectionMatrix()  );
        cam.begin( ofRectangle( 0, 0, mSize, mSize ));
    }

// vert shader for writing depth //
#version 330
// set automatically by OF //
in vec4 position;

// these are passed in from OF programmable renderer
uniform mat4 viewMatrix;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
uniform mat4 modelViewProjectionMatrix;

uniform mat4 u_modelMat;
// world space position of the vertex to the fragment shader
out vec4	o_worldSpacePosition;

void main( void ) {
     o_worldSpacePosition = position;
        gl_Position     = modelViewProjectionMatrix * position;
}

// frag shader for writing depth
#version 330

// world space position of the fragment
in vec4	o_worldSpacePosition;

// distance that will be saved to framebuffer
out float resultingColor;

void main( void ) {  
    vec3 u_lightPos = vec3( 0.0, 0.0, 0.0 );
    // distance from light to near and far cliping planes
    vec2 u_nearFarPlane = vec2( 0.0, 1000.0 );
    // additional offset from the light
    float u_depthOffset = 0.0001;
    
    // distance to light
    float distanceToLight = distance( u_lightPos, o_worldSpacePosition.xyz);
//     normalize distance taking into account near and far clipping planes
//     so valid distances should be in [0, 1] range
    resultingColor = (distanceToLight - u_nearFarPlane.x) / (u_nearFarPlane.y - u_nearFarPlane.x);// + u_depthOffset;
//     clamp distances to [0, 1] range
    resultingColor = clamp(resultingColor, 0.0, 1.0);
}

Hi @NickHardeman

Here is my pointlight shadow example(oF) I’ve implemented.
I’m sorry that some code may be messy. but i hope It will help you.

Thanks @yuma_taesu! To a quick glance at it and it looks very helpful. Going to dig more into it later. :slight_smile: