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 9 of 9

Thread: Cascaded Shadow Mapping in OpenGL

  1. #1
    Junior Member Newbie
    Join Date
    Oct 2014
    Posts
    5

    Cascaded Shadow Mapping in OpenGL

    Hello, I'm new on this forum.
    I'm trying to implement cascaded shadow maps in OpenGL, but it's very hard! Can I implement it without frustum splitting? is there any method of cascaded shadow maps implementation that does not involve frustum splitting?

  2. #2
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    4,569
    Without frustum splitting? That's the "cascaded" part of cascaded shadow mapping.

    You might want to do more reading on how basic shadow mapping works, what problems it has, which leads into when you'd use cascaded shadow mapping. Then you can decide if you can drop the "cascaded" part. If you're not comfortable with all of OpenGL's coordinate spaces, how coordinate frame transformations work, and how the depth buffer works, you need to study up on that first.

  3. #3
    Junior Member Newbie
    Join Date
    Oct 2014
    Posts
    5
    Quote Originally Posted by Dark Photon View Post
    Without frustum splitting? That's the "cascaded" part of cascaded shadow mapping.

    You might want to do more reading on how basic shadow mapping works, what problems it has, which leads into when you'd use cascaded shadow mapping. Then you can decide if you can drop the "cascaded" part. If you're not comfortable with all of OpenGL's coordinate spaces, how coordinate frame transformations work, and how the depth buffer works, you need to study up on that first.
    Hey, thank you very much for your reply.

    But, today I got it!!! I implemented a "cascaded shadow map" in OpenGL!... Or, like you say, maybe not! Because it has no frustum splitting! If this is not a cascaded shadow map, then what is it? I'm new in shadow mapping. Happy Haloween.

    There is the source code:

    Code :
    C++ code:
     
    void MakeShadowMaps(MD5Model* modelPtr, int model, MD5Model* weaponPtr)
    {
    	float  units;
    	int    i = -1, j;
    	double boundX, boundZ;
     
        // Light's point of view
    	viewMatrix = Mat4::LookAt(Vec::Vec3(light.position), 
    		                      Vec::Vec3(0, 0, 0), 
    							  Vec::Vec3(0, 1, 0));
     
    	// Render on the whole framebuffer, 
    	// complete from the lower left corner to the upper right
    	glViewport(0, 0, WIDTH, HEIGHT); // WIDTH = 1024, HEIGHT = 1024
     
    	while (++i < 4)
    	{
    		// Render to our framebuffer
    		glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName[i]);
     
    		if (i == 0)
    		{
    			units  = 2.0f;     // units of glPolygonOffset()
    			boundX = boundZ = BOUND0; // 300
    		}
    		else if (i == 1)
    		{
    			units  = 4.0f;
    			boundX = boundZ = BOUND1; // 600
    		}
    		else if (i == 2)
    		{
    			units  = 8.0f;
    			boundX = boundZ = BOUND2; // 1200
    		}
    		else
    		{
    			glViewport(0, 0, WIDTH2, HEIGHT2); // WIDTH = 2048, HEIGHT = 2048
    			units  = 10.0f;
    			boundX = boundZ = BOUND3; // 3000
    		}
     
    		// Clear the screen
    		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     
    		point[0].x = (float)-boundX;
    		point[0].y = (float)-boundZ;
    		point[0].z = 0;
    		point[0].w = 1;
     
    		point[1].x = (float)-boundX;
    		point[1].y = (float)boundZ;
    		point[1].z = 0;
    		point[1].w = 1;
     
    		point[2].x = (float)boundX;
    		point[2].y = (float)-boundZ;
    		point[2].z = 0;
    		point[2].w = 1;
     
    		point[3].x = (float)boundX;
    		point[3].y = (float)boundZ;
    		point[3].z = 0;
    		point[3].w = 1;
     
    		// Compute the MVP matrix from the light's point of view
    		projectionMatrix = Mat4::Ortho(-1, 1,-1, 1, Z_NEAR, Z_FAR); // ZNEAR = -3000, ZFAR = 6000
    	    camera = eyePosition + eyeDirection * (float)boundX;
    	    ApplyCropMatrix((float)boundX);
     
    		matrix.LoadIdentity();
    		CalculateTerrainDepthMatrix(i);
     
    		if (abs(light.position.x) < 100.0f || 
    			abs(light.position.z) < 100.0f)
    			glPolygonOffset(1.0f, units * 100);
    		else
    			glPolygonOffset(1.0f, units * 5);
     
    		animation = false;
    		matrix.LoadIdentity();
    		UpdateShadersUniforms(WALLS, -1, i);
    		walls.NoAnimation();
    		walls.DrawShadow();
     
    		glPolygonOffset(1.0f, units);
    		matrix.LoadIdentity();
    		UpdateShadersUniforms(GRAVES, -1, i);
    		graves.NoAnimation();
    		graves.DrawShadow();
    		animation = true;
     
    		matrix.LoadIdentity();
    		matrix.Translatev(modelTranslatev = Vec::Vec3(mx, 0, mz));
    		UpdateShadersUniforms(model, -1, i);
    		modelPtr->DrawShadow();
    		if (model == DARK_KNIGHT)
    			weaponPtr->DrawShadow();
     
    		j = -1;
    		while(++j < NUM_OF_TREES)
    		{
    			matrix.LoadIdentity();
    			matrix.Translatev(treesCoord[j]);
    			UpdateShadersUniforms(TREE, j, i);
    			treev[j].NoAnimation();
    			treev[j].DrawShadow();
    		}
     
    		glPolygonOffset(1.0f, units * 2);
    		matrix.LoadIdentity();
    		matrix.Translatev(churchCoord);
    		UpdateShadersUniforms(CHURCH, -1, i);
    		church.NoAnimation();
    		church.DrawShadow();
    		animation = true;
    	}
    }
     
    .
    .
    .
     
    void ApplyCropMatrix(float bound)
    {	
    	matrix4x4_t shadMvp = projectionMatrix * 
    		                  (viewMatrix * Mat4::Translatev3(camera));
    	float       maxX = Z_NEAR, minX = Z_FAR, 
    		        maxY = Z_NEAR, minY = Z_FAR;
     
    	int i = -1;
    	while (++i < 4)
    	{
    		transf = shadMvp * point[i];
     
    		transf.x /= transf.w;
    		transf.y /= transf.w;
     
    		if(transf.x > maxX) 
    			maxX = transf.x;
    		if(transf.x < minX) 
    			minX = transf.x;
    		if(transf.y > maxY) 
    			maxY = transf.y;
    		if(transf.y < minY) 
    			minY = transf.y;
    	}
     
    	float absMaxXminX         = abs(maxX - minX),
    		  absMaxYminY         = abs(maxY - minY),
    		  absBoundAbsMaxXminX = abs((bound *= 2) - absMaxXminX) * 0.5f,
    		  absBoundAbsMaxYminY = abs(bound        - absMaxYminY) * 0.5f;
     
    	if (absMaxXminX < bound)
    	{
    		maxX += absBoundAbsMaxXminX;
    		minX -= absBoundAbsMaxXminX;
    	}
    	else if (absMaxXminX > bound)
    	{
    		maxX -= absBoundAbsMaxXminX;
    		minX += absBoundAbsMaxXminX;
    	}
    	if (absMaxYminY < bound)
    	{
    		maxY += absBoundAbsMaxYminY;
    		minY -= absBoundAbsMaxYminY;
    	}
    	else if (absMaxYminY > bound)
    	{
    		maxY -= absBoundAbsMaxYminY;
    		minY += absBoundAbsMaxYminY;
    	}
     
    	float scaleX  =  2.0f / (maxX - minX),
    	      scaleY  =  2.0f / (maxY - minY),
    	      offsetX = -0.5f * (maxX + minX) * scaleX,
    	      offsetY = -0.5f * (maxY + minY) * scaleY;
     
    	shadMvp = Mat4::Identity();
     
    	shadMvp.m(0, 0) = scaleX;
    	shadMvp.m(1, 1) = scaleY;
    	shadMvp.m(0, 3) = offsetX;
    	shadMvp.m(1, 3) = offsetY;
     
    	projectionMatrix *= shadMvp;
    }
     
    .
    .
    .
     
    GLSL code:
     
    Vertex shader:
     
    #version 120
     
    .
    .
    .
     
    // Input vertex data, different for all executions of this shader.
    attribute vec3 vertexPosition_modelspace;
    .
    .
    .
     
    // Output data ; will be interpolated for each fragment.
     
    .
    .
    .
     
    varying vec4 fragCoord;
    varying vec4 ShadowCoord[4];
     
    // Values that stay constant for the whole mesh.
     
    .
    .
    .
     
    uniform mat4 MVP;
    uniform mat4 DepthBiasMVP[4];
     
    .
    .
    .
     
    void main()
    {
    	vec4  vertexPosition = vec4(vertexPosition_modelspace, 1);
     
            .
            .
            .
     
    	// Output position of the vertex, in clip space : MVP * position	
    	fragCoord = gl_Position = MVP * vertexPosition;
     
    	ShadowCoord[0] = DepthBiasMVP[0] * vertexPosition;
    	ShadowCoord[1] = DepthBiasMVP[1] * vertexPosition;
    	ShadowCoord[2] = DepthBiasMVP[2] * vertexPosition;
    	ShadowCoord[3] = DepthBiasMVP[3] * vertexPosition;
     
            .
            .
            .
    }
     
    Fragment shader:
     
    #version 120
    #extension GL_EXT_gpu_shader4 : enable
     
    .
    .
    .
     
    // Interpolated values from the vertex shaders
     
    .
    .
    .
     
    varying vec4 fragCoord;
    varying vec4 ShadowCoord[4];
     
    // Values that stay constant for the whole mesh.
     
    .
    .
    .
     
    uniform sampler2DShadow shadowMap[4];
    uniform vec3            farBound;
     
    .
    .
    .
     
    uniform bool  shadow;
    uniform bool  showSplit;
     
    float Shadow(sampler2DShadow sMap, vec4 sCoord)
    {
    	// Use PCF to improve shadow quality at the shadow edges.
    	// Gaussian 3x3 filter
    	float coeff = shadow2D(sMap, vec3(sCoord)).x * 0.25;
    	coeff += shadow2DOffset(sMap, vec3(sCoord), ivec2(-1,-1)).x * 0.0625;
    	coeff += shadow2DOffset(sMap, vec3(sCoord), ivec2(-1, 0)).x * 0.125;
    	coeff += shadow2DOffset(sMap, vec3(sCoord), ivec2(-1, 1)).x * 0.0625;
    	coeff += shadow2DOffset(sMap, vec3(sCoord), ivec2( 0,-1)).x * 0.125;
    	coeff += shadow2DOffset(sMap, vec3(sCoord), ivec2( 0, 1)).x * 0.125;
    	coeff += shadow2DOffset(sMap, vec3(sCoord), ivec2( 1,-1)).x * 0.0625;
    	coeff += shadow2DOffset(sMap, vec3(sCoord), ivec2( 1, 0)).x * 0.125;
    	return coeff += 
    		   shadow2DOffset(sMap, vec3(sCoord), ivec2(1, 1)).x * 0.0625;
    }
     
    void main()
    {
     
            .
            .
            .
     
    	if (shadow)
    	{
    		if (showSplit)
    		{
    			if (fragCoord.z < farBound.x)
    			{
    				shadowCoeff = shadow2D(shadowMap[0], vec3(ShadowCoord[0])).x;
    				splitColor  = vec3(0.5, 0.5, 1.0);
    			}
    			else if (fragCoord.z < farBound.y)
    			{
    				shadowCoeff = shadow2D(shadowMap[1], vec3(ShadowCoord[1])).x;
    				splitColor  = vec3(0.5, 1.0, 0.5);
    			}
    			else if (fragCoord.z < farBound.z)
    			{
    				shadowCoeff = shadow2D(shadowMap[2], vec3(ShadowCoord[2])).x;
    				splitColor  = vec3(1.0, 0.5, 0.5);
    			}
    			else
    			{
    				shadowCoeff = shadow2D(shadowMap[3], vec3(ShadowCoord[3])).x;
    				splitColor  = vec3(1.0, 1.0, 1.0);
    			}
    		}
    		else
    		{
    			if (fragCoord.z < farBound.x)
    				shadowCoeff = Shadow(shadowMap[0], ShadowCoord[0]);
    			else if (fragCoord.z < farBound.y)
    				shadowCoeff = Shadow(shadowMap[1], ShadowCoord[1]);
    			else if (fragCoord.z < farBound.z)
    				shadowCoeff = Shadow(shadowMap[2], ShadowCoord[2]);
    			else
    				shadowCoeff = Shadow(shadowMap[3], ShadowCoord[3]);
    		}
    	}
     
            .
            .
            .
     
    }
    Last edited by OpenGL_man; 10-31-2014 at 05:12 PM.

  4. #4
    Junior Member Newbie
    Join Date
    Jun 2014
    Posts
    28
    Can I implement it without frustum splitting?

    your question is strange looks like you need to read about shado map

    1-read about FBO (Frame Buffer Object) or render to texture

    2-read about Render Depth Buffer


    ok i will explane to in short

    what is FBO (frame Buffer Object)

    when you call draw function in opengl opengl dosn't draw it on your screen or window
    but it's store it as FBO in Graphic Card's memory then if you need to show it you have to call function to draw it like glutSwapBuffers (if you are using glut)

    you can render to another target(another frame buffer) without effect on your orginal buffer


    the shadow is render to texture but it is rendering the depth of your pixel

    you need to learn longer about them

    take a look

    render to texture :http://www.opengl-tutorial.org/inter...er-to-texture/

    shadow map :http://www.opengl-tutorial.org/inter...hadow-mapping/

  5. #5
    Junior Member Newbie
    Join Date
    Oct 2014
    Posts
    5
    Thank you for your reply.

    Yes, I'm new in shadow mapping, but I know the basis on this mather. The code above (by the way, how can I modify it?) is from one implementation made by myself, It's not regular cascade shadow mapping (there are no frustum splitting), but it does exactly the same thing! Take a look: http://www.youtube.com/watch?v=ofm_LwR5RDI

  6. #6
    Junior Member Newbie
    Join Date
    Oct 2014
    Posts
    5
    Sorry, but I have to change some lines:

    Code :
    C++ code:
     
    void MakeShadowMaps(MD5Model* modelPtr, int model, MD5Model* weaponPtr)
    {
        float  units;
        int    i = -1, j;
        double boundX, boundZ, fovRatio = FRUSTUM_FOV / 45.0;
     
        // Light's point of view
        viewMatrix = Mat4::LookAt(Vec::Vec3(light.position), 
                                  Vec::Vec3(0, 0, 0), 
                                  Vec::Vec3(0, 1, 0));
     
        // Render on the whole framebuffer, 
        // complete from the lower left corner to the upper right
        glViewport(0, 0, WIDTH, HEIGHT); // WIDTH = 1024, HEIGHT = 1024
     
        while (++i < 4)
        {
            // Render to our framebuffer
            glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName[i]);
     
            if (i == 0)
            {
                units  = 2.0f;     // units of glPolygonOffset()
                boundX = boundZ = BOUND0 * fovRatio; // 300
            }
            else if (i == 1)
            {
                units  = 4.0f;
                boundX = boundZ = BOUND1 * fovRatio; // 600
            }
            else if (i == 2)
            {
                units  = 8.0f;
                boundX = boundZ = BOUND2 * fovRatio; // 1200
            }
            else
            {
                glViewport(0, 0, WIDTH2, HEIGHT2); // WIDTH = 2048, HEIGHT = 2048
                units  = 10.0f;
                boundX = boundZ = BOUND3 * fovRatio; // 3000
            }
     
            // Clear the screen
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     
            point[0].x = (float)-boundX;
            point[0].y = (float)-boundZ;
            point[0].z = 0;
            point[0].w = 1;
     
            point[1].x = (float)-boundX;
            point[1].y = (float)boundZ;
            point[1].z = 0;
            point[1].w = 1;
     
            point[2].x = (float)boundX;
            point[2].y = (float)-boundZ;
            point[2].z = 0;
            point[2].w = 1;
     
            point[3].x = (float)boundX;
            point[3].y = (float)boundZ;
            point[3].z = 0;
            point[3].w = 1;
     
            // Compute the MVP matrix from the light's point of view
            projectionMatrix = Mat4::Ortho(-1, 1,-1, 1, Z_NEAR, Z_FAR); // ZNEAR = -3000, ZFAR = 6000
            camera = eyePosition + eyeDirection * (float)boundX;
            ApplyCropMatrix((float)boundX);
     
            matrix.LoadIdentity();
            CalculateTerrainDepthMatrix(i);
     
            if (abs(light.position.x) < 100.0f || 
                abs(light.position.z) < 100.0f)
                glPolygonOffset(1.0f, units * 100);
            else
                glPolygonOffset(1.0f, units * 5);
     
            animation = false;
            matrix.LoadIdentity();
            UpdateShadersUniforms(WALLS, -1, i);
            walls.NoAnimation();
            walls.DrawShadow();
     
            glPolygonOffset(1.0f, units);
            matrix.LoadIdentity();
            UpdateShadersUniforms(GRAVES, -1, i);
            graves.NoAnimation();
            graves.DrawShadow();
            animation = true;
     
            matrix.LoadIdentity();
            matrix.Translatev(modelTranslatev = Vec::Vec3(mx, 0, mz));
            UpdateShadersUniforms(model, -1, i);
            modelPtr->DrawShadow();
            if (model == DARK_KNIGHT)
                weaponPtr->DrawShadow();
     
            j = -1;
            while(++j < NUM_OF_TREES)
            {
                matrix.LoadIdentity();
                matrix.Translatev(treesCoord[j]);
                UpdateShadersUniforms(TREE, j, i);
                treev[j].NoAnimation();
                treev[j].DrawShadow();
            }
     
            glPolygonOffset(1.0f, units * 2);
            matrix.LoadIdentity();
            matrix.Translatev(churchCoord);
            UpdateShadersUniforms(CHURCH, -1, i);
            church.NoAnimation();
            church.DrawShadow();
            animation = true;
        }
    }
     
    .
    .
    .
     
    void ApplyCropMatrix(float bound)
    {    
        matrix4x4_t shadMvp = projectionMatrix * 
                              (viewMatrix * Mat4::Translatev3(camera));
        float       maxX = Z_NEAR, minX = Z_FAR, 
                    maxY = Z_NEAR, minY = Z_FAR;
     
        int i = -1;
        while (++i < 4)
        {
            transf = shadMvp * point[i];
     
            transf.x /= transf.w;
            transf.y /= transf.w;
     
            if(transf.x > maxX) 
                maxX = transf.x;
            if(transf.x < minX) 
                minX = transf.x;
            if(transf.y > maxY) 
                maxY = transf.y;
            if(transf.y < minY) 
                minY = transf.y;
        }
     
        float absMaxXminX         = abs(maxX - minX),
              absMaxYminY         = abs(maxY - minY),
              absBoundAbsMaxXminX = abs((bound *= 2) - absMaxXminX) * 0.5f,
              absBoundAbsMaxYminY = abs(bound        - absMaxYminY) * 0.5f;
     
        if (absMaxXminX < bound)
        {
            maxX += absBoundAbsMaxXminX;
            minX -= absBoundAbsMaxXminX;
        }
        else if (absMaxXminX > bound)
        {
            maxX -= absBoundAbsMaxXminX;
            minX += absBoundAbsMaxXminX;
        }
        if (absMaxYminY < bound)
        {
            maxY += absBoundAbsMaxYminY;
            minY -= absBoundAbsMaxYminY;
        }
        else if (absMaxYminY > bound)
        {
            maxY -= absBoundAbsMaxYminY;
            minY += absBoundAbsMaxYminY;
        }
     
        float scaleX  =  2.0f / (maxX - minX),
              scaleY  =  2.0f / (maxY - minY),
              offsetX = -0.5f * (maxX + minX) * scaleX,
              offsetY = -0.5f * (maxY + minY) * scaleY;
     
        shadMvp = Mat4::Identity();
     
        shadMvp.m(0, 0) = scaleX;
        shadMvp.m(1, 1) = scaleY;
        shadMvp.m(0, 3) = offsetX;
        shadMvp.m(1, 3) = offsetY;
     
        projectionMatrix *= shadMvp;
    }
     
    .
    .
    .
     
    GLSL code:
     
    Vertex shader:
     
    #version 120
     
    .
    .
    .
     
    // Input vertex data, different for all executions of this shader.
    attribute vec3 vertexPosition_modelspace;
    .
    .
    .
     
    // Output data ; will be interpolated for each fragment.
     
    .
    .
    .
     
    varying vec4 fragCoord;
    varying vec4 ShadowCoord[4];
     
    // Values that stay constant for the whole mesh.
     
    .
    .
    .
     
    uniform mat4 MVP;
    uniform mat4 DepthBiasMVP[4];
     
    .
    .
    .
     
    void main()
    {
        vec4  vertexPosition = vec4(vertexPosition_modelspace, 1);
     
            .
            .
            .
     
        // Output position of the vertex, in clip space : MVP * position    
        fragCoord = gl_Position = MVP * vertexPosition;
     
        ShadowCoord[0] = DepthBiasMVP[0] * vertexPosition;
        ShadowCoord[1] = DepthBiasMVP[1] * vertexPosition;
        ShadowCoord[2] = DepthBiasMVP[2] * vertexPosition;
        ShadowCoord[3] = DepthBiasMVP[3] * vertexPosition;
     
            .
            .
            .
    }
     
    Fragment shader:
     
    #version 120
    #extension GL_EXT_gpu_shader4 : enable
     
    .
    .
    .
     
    // Interpolated values from the vertex shaders
     
    .
    .
    .
     
    varying vec4 fragCoord;
    varying vec4 ShadowCoord[4];
     
    // Values that stay constant for the whole mesh.
     
    .
    .
    .
     
    uniform sampler2DShadow shadowMap[4];
    uniform vec3            farBound;
     
    .
    .
    .
     
    uniform bool  shadow;
    uniform bool  showSplit;
     
    float Shadow(sampler2DShadow sMap, vec4 sCoord)
    {
        // Use PCF to improve shadow quality at the shadow edges.
        // Gaussian 3x3 filter
        float coeff = shadow2D(sMap, vec3(sCoord)).x * 0.25;
        coeff += shadow2DOffset(sMap, vec3(sCoord), ivec2(-1,-1)).x * 0.0625;
        coeff += shadow2DOffset(sMap, vec3(sCoord), ivec2(-1, 0)).x * 0.125;
        coeff += shadow2DOffset(sMap, vec3(sCoord), ivec2(-1, 1)).x * 0.0625;
        coeff += shadow2DOffset(sMap, vec3(sCoord), ivec2( 0,-1)).x * 0.125;
        coeff += shadow2DOffset(sMap, vec3(sCoord), ivec2( 0, 1)).x * 0.125;
        coeff += shadow2DOffset(sMap, vec3(sCoord), ivec2( 1,-1)).x * 0.0625;
        coeff += shadow2DOffset(sMap, vec3(sCoord), ivec2( 1, 0)).x * 0.125;
        return coeff += 
               shadow2DOffset(sMap, vec3(sCoord), ivec2(1, 1)).x * 0.0625;
    }
     
    void main()
    {
     
            .
            .
            .
     
        if (shadow)
        {
            if (showSplit)
            {
                if (fragCoord.z < farBound.x)
                {
                    shadowCoeff = shadow2D(shadowMap[0], vec3(ShadowCoord[0])).x;
                    splitColor  = vec3(0.5, 0.5, 1.0);
                }
                else if (fragCoord.z < farBound.y)
                {
                    shadowCoeff = shadow2D(shadowMap[1], vec3(ShadowCoord[1])).x;
                    splitColor  = vec3(0.5, 1.0, 0.5);
                }
                else if (fragCoord.z < farBound.z)
                {
                    shadowCoeff = shadow2D(shadowMap[2], vec3(ShadowCoord[2])).x;
                    splitColor  = vec3(1.0, 0.5, 0.5);
                }
                else
                {
                    shadowCoeff = shadow2D(shadowMap[3], vec3(ShadowCoord[3])).x;
                    splitColor  = vec3(1.0, 1.0, 1.0);
                }
            }
            else
            {
                if (fragCoord.z < farBound.x)
                    shadowCoeff = Shadow(shadowMap[0], ShadowCoord[0]);
                else if (fragCoord.z < farBound.y)
                    shadowCoeff = Shadow(shadowMap[1], ShadowCoord[1]);
                else if (fragCoord.z < farBound.z)
                    shadowCoeff = Shadow(shadowMap[2], ShadowCoord[2]);
                else
                    shadowCoeff = Shadow(shadowMap[3], ShadowCoord[3]);
            }
        }
     
            .
            .
            .
     
    }
    Last edited by OpenGL_man; 11-04-2014 at 02:03 PM.

  7. #7
    Junior Member Newbie
    Join Date
    Jun 2014
    Posts
    28
    frustum splitting is confusing to me i dont knw what dose it mean

  8. #8
    Junior Member Newbie
    Join Date
    Jun 2014
    Posts
    28
    i see i understand what you are talking about you can finde my anser above
    in your code you are using shadow map
    you only need one shadow

  9. #9
    Junior Member Newbie
    Join Date
    Jun 2014
    Posts
    28
    learn FBO render to texture vary well


    make shader program to calculat your shadow

    gl_FragColor = vec4(distance(LightPosition,Vertex)/MaxLightDistance,0,0,Alpha);

    and you get depth result texture each pixel contents the distance betwwen vertex and light position (range [0-1])

    to calculate shadow use this programe while rendering depth case and swith to your orginal programe and compare the distance betwwn light distance
    the pixel in your texture

    if you distance between light and vertex = pixel is value means there is no shadow here
    else vertex's color = black

    this is basics about shadow but you need to learn how to render to texture to understand these lines

Posting Permissions

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