Results 1 to 5 of 5

Thread: Shadow mapping - theory and practice

  1. #1

    Shadow mapping - theory and practice

    My game still uses shadow volumes (think doom 3), it was easy to implement, to get something working but they are prone to various rendering faults and issues, use the obsolete stencil buffer, and generally look bad.

    I want to transition to shadow mapping, i got the shaders infrastructure in engine and got as far to render a scene depth buffer to a frame buffer object into texture - so the framebuffer part. I can also render a color buffer in order to test things.

    What i want right now is basic global illumination, so i've looked up some tutorials and what i need is a orthographic view projection of a rendering from light point of view.

    So.. i assume that this has to be rendered by taking center of my world where camera is currently, then creating 2 imaginary points (sun origin and sun lookat points ), this will result in 2 matrixes - modelview matrix (looking from sun towards world) and projection matrix (ortho matrix).

    But how does the vector for sun get calculated? do the relation between position even matter? does "orientation" during lookat for the light matter?

    This is the tutorial i use as a base:

    For the modelview they just use this, is this esentially going from 0.5, 2, 2 towards 0,0,0 ?

    glm::vec3 lightInvDir = glm::vec3(0.5f,2,2);
    glm::mat4 depthViewMatrix = glm::lookAt(lightInvDir, glm::vec3(0,0,0), glm::vec3(0,1,0));

    So.. the final depthMVP is then used in shader in both steps: light output render and shadow apply - nothing else needs to be done? s this complex only in my head?
    This is my game project - Top Down City:

    My OpenAL audio wrapper with Intelligent Source Manager to use unlimited:

  2. #2
    Well, i somehow managed to dig thru all the tutorials and use anger and stubbornness to figure out what i was doing wrong.

    So here it is:

    - It doesn't matter what area you render during the light-direction pass as matrixes will still know where the fragment fell into the shadowmap vbo texture, there is nothing to calculate regarding this at all, you can just render whatever area you want. i had some preconception that there is something special that has to be done to choose which area to render for shadow, but you can really just use any area, as long as it's big enough for your world. Some games also combine MULTIPLE shadow maps, they do so by rendering lower resolution long-distance pass, and high-resolution short-distance pass around / nearby player (i theorise that you could do this in 2 pass-es into one texture - just render to different mipmap levels).
    - The final pass has to include original projections used for light-pass and current pass - you need those in the shader. What the code does is, it needs for each vertex where it would been transformed in the light pass. This is then used as XY lookup on the shadow map texture, the math there is REALLY simple, i had some preconception that i need to calculate lookup using matrixes, but in reality this is really simple - it just uses original matrix, which is (BiasMatrix * ShadowProjMatrix * Shadowdepthmodelviewmatrix). Biasmatrix simply maps viewport render coordinates to texture coordinates ( [-1,1] to [0,1] )

    - It REALLY helps that you do not use opengl transform functions as you will have a bad time getting this to work with shaders cleanly.
    if you have to use glulookat and other matrix funcs then you can still use glGetFloatv(GL_PROJECTION_MATRIX, @projectionmatrix); + glGetFloatv(GL_MODELVIEW_MATRIX, @modelviewmatrix); and then put that into shader matrix.
    KEEP IN MIND that if you use gltranslatef, glrotatef, glscalef .. you NEED to update the modelview matrix into shader every time you render such a object.

    Perspective and orthogonal light projections are different, but still similar - orthogonal light (for outside shading) is simple to prepare and render, perspective shadows take more effort and are slightly different in implementation.
    A point light.. would however require multiple pass-es (6 for each direction basically).

    IF that still doesn't work and everything is shaded, then your BIAS is messed up and needs to have some adjusting.

    If you have multiple lights, just produce and combine multiple pass-es (and remember each original matrix)

    And now, i can show final result in my game:

    Last edited by JernejL; 07-04-2020 at 12:20 PM.
    This is my game project - Top Down City:

    My OpenAL audio wrapper with Intelligent Source Manager to use unlimited:

  3. #3
    Looks nice, not very distracting or confusing.
    No signature provided yet.

  4. #4
    Yep it just looks good, i'm surprised how well this combines with alpha transparency, i still have some weird problem that shadows don't work on nvidia cards (works on intel and amd tho) - i'll get that solved at one point too.

    Next step will be to combine this with a lighting system, i will probably need to start using two render targets and combine results, because currently car fake shadows don't combine well with map shadows, and ligting is still nonexistent in the engine
    This is my game project - Top Down City:

    My OpenAL audio wrapper with Intelligent Source Manager to use unlimited:

  5. #5
    Apparently i used GL_TEXTURE_COMPARE_MODE GL_COMPARE_R_TO_TEXTURE and GL_TEXTURE_COMPARE_FUNCset to GL_LEQUAL and that doesn't work on nvidia no matter what you try, it is not even needed if you use glsl - i'm not sure from what totorial i got that from..
    This is my game project - Top Down City:

    My OpenAL audio wrapper with Intelligent Source Manager to use unlimited:


Posting Permissions

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