c++ - Determining cascaded shadow map split ranges -


i'm doing cascaded shadow maps, , believe have problem concerning way split comparison select proper shadow map. stands, shadow mapping works overall in few cases @ angles not work.

currently lighting shader stage looks this:

"#version 420                                                                                                                     const float depth_bias = 0.00005;                                                                                                 layout(std140) uniform unifdirlight                                                                                                      {                                                                                                                                    mat4 mvpmatrix[4];                                                                                                               mat4 mcamviewmatrix;         vec4 msplitdistance;                                                                                                         vec4 mlightcolor;                                                                                                                vec4 mlightdir;                                                                                                                  vec4 mgamma;                                                                                                                     vec2 mscreensize;                                                                                                            } unifdirlightpass;                                                                                                               layout (binding = 2) uniform sampler2d unifpositiontexture;                                                                      layout (binding = 3) uniform sampler2d unifnormaltexture;                                                                        layout (binding = 4) uniform sampler2d unifdiffusetexture;                                                                       layout (binding = 6) uniform sampler2darrayshadow unifshadowtexture;                                                              out vec4 fragcolor;                                                                                                               void main()                                                                                                                      {                                                                                                                                    vec2 texcoord = gl_fragcoord.xy / unifdirlightpass.mscreensize;                                                                   vec3 worldpos = texture(unifpositiontexture, texcoord).xyz;                                                                      vec3 normal   = normalize(texture(unifnormaltexture, texcoord).xyz);                                                             vec3 diffuse  = texture(unifdiffusetexture, texcoord).xyz;                                                                        vec4 campos = unifdirlightpass.mcamviewmatrix * vec4(worldpos, 1.0);     // legit way of determining split?                                                  int index = 3;                                                                             if (campos .z > unifdirlightpass.msplitdistance.x)                                                                                   index = 0;                                                                                                                   else if (campos .z > unifdirlightpass.msplitdistance.y)                                                                              index = 1;                                                                                                                 else if (campos .z > unifdirlightpass.msplitdistance.z)                                                                              index = 2;                                                                                                                    vec4 projcoords = unifdirlightpass.mvpmatrix[index] * vec4(worldpos, 1.0);                                                       projcoords.w    = projcoords.z - depth_bias;                                                                                     projcoords.z    = float(index);                                                                                                  float visibilty = texture(unifshadowtexture, projcoords);                                                                         float anglenormal = clamp(dot(normal, unifdirlightpass.mlightdir.xyz), 0, 1);                                                     fragcolor = vec4(diffuse, 1.0) * visibilty * anglenormal * unifdirlightpass.mlightcolor;                                     } 

and "msplitdistance", each component center fardistance of frustrum split, multiplied main cameras view matrix

vec4 camfardistcenter; camerafrustrum camerafrustrum = calculatecamerafrustrum(neardistarr[cascadeindex], fardistarr[cascadeindex], lighting.mcameraposition, lighting.mcameradirection, camfardistcenter);  .....  camfardistcenter = lighting.mcameraviewmatrix * camfardistcenter; splitdistances[cascadeindex] = camfardistcenter.z; 

here's how create camera frustrum each split, if of interest, believe pretty common alghorithm:

camerafrustrum calculatecamerafrustrum(const float mindist, const float maxdist, const vec3& cameraposition, const vec3& cameradirection, vec4& camfarz) {     camerafrustrum ret = { vec4(-1.0f, -1.0f, 1.0f, 1.0f), vec4(-1.0f, -1.0f, -1.0f, 1.0f), vec4(-1.0f, 1.0f, 1.0f, 1.0f), vec4(-1.0f, 1.0f, -1.0f, 1.0f),                            vec4(1.0f, -1.0f, 1.0f, 1.0f), vec4(1.0f, -1.0f, -1.0f, 1.0f), vec4(1.0f, 1.0f, 1.0f, 1.0f), vec4(1.0f, 1.0f, -1.0f, 1.0f) };      const vec3 forwardvec = glm::normalize(cameradirection);     const vec3 rightvec   = glm::normalize(glm::cross(forwardvec, vec3(0.0f, 0.0f, 1.0f)));     const vec3 upvec      = glm::normalize(glm::cross(rightvec, forwardvec));      const vec3 nearcenter = cameraposition + forwardvec * mindist;     const vec3 farcenter  = cameraposition + forwardvec * maxdist;      camfarz = vec4(farcenter, 1.0);      const float nearheight = tan(glm::radians(70.0f) / 2.0f) * mindist;     const float nearwidth = nearheight * 1920.0f / 1080.0f;     const float farheight  = tan(glm::radians(70.0f) / 2.0f) * maxdist;     const float farwidth = farheight * 1920.0f / 1080.0f;      ret[0] = vec4(nearcenter - (upvec * nearheight) - (rightvec * nearwidth), 1.0);     ret[1] = vec4(nearcenter + (upvec * nearheight) - (rightvec * nearwidth), 1.0);     ret[2] = vec4(nearcenter + (upvec * nearheight) + (rightvec * nearwidth), 1.0);     ret[3] = vec4(nearcenter - (upvec * nearheight) + (rightvec * nearwidth), 1.0);      ret[4] = vec4(farcenter - upvec * farheight - rightvec * farwidth, 1.0);     ret[5] = vec4(farcenter + upvec * farheight - rightvec * farwidth, 1.0);     ret[6] = vec4(farcenter + upvec * farheight + rightvec * farwidth, 1.0);     ret[7] = vec4(farcenter - upvec * farheight + rightvec * farwidth, 1.0);      return ret; } 

is sound split comparison in camera space do? potential problem?

    void calculatecamerafrustrum(glm::mat4& projectionmatrix,                               glm::mat4  viewmatrix,       // viewmatrix = light pov                              glm::vec3  camera            // camera = eye position + eye direction                              float      znear,                               float      zfar,                               glm::vec4  point[4])         // point[4] = shadow map boundaries     glm::mat4 shadmvp =  projectionmatrix * (viewmatrix * glm::translate(camera));     glm::vec3 transf;     float     maxx = znear, minx = zfar,                maxy = znear, miny = zfar;      int = -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 scalex  =  2.0f / (maxx - minx),           scaley  =  2.0f / (maxy - miny),           offsetx = -0.5f * (maxx + minx) * scalex,           offsety = -0.5f * (maxy + miny) * scaley;      shadmvp = glm::mat4(1); // identity matrix      shadmvp[0][0] = scalex;     shadmvp[1][1] = scaley;     shadmvp[0][3] = offsetx;     shadmvp[1][3] = offsety;      projectionmatrix *= shadmvp; } // no need calculate view frustum splitting,    // boundaries of shadow maps levels needed (glm::ortho(...)).   // :) 

Comments

Popular posts from this blog

PHPMotion implementation - URL based videos (Hosted on separate location) -

c# - Unity IoC Lifetime per HttpRequest for UserStore -

I am trying to solve the error message 'incompatible ranks 0 and 1 in assignment' in a fortran 95 program. -