# The Industry's Foundation for High Performance Graphics

#### Hybrid View

Reposting, as the last topic is bugged and cant be edited.

I'm having issues where shadows vanish at certain angles and I want to ascertain I am using the correct values to determine the split index.

Code cpp:
```CameraFrustrum CalculateCameraFrustrum(const float minDist, const float maxDist, const Vec3& cameraPosition, const Vec3& cameraDirection, Vec4& splitDistance, const Mat4& camView)
{
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 Mat4 perspectiveMatrix = glm::perspective(70.0f, 1920.0f / (float)1080.0f, minDist, maxDist);
const Mat4 invMVP = glm::inverse(perspectiveMatrix * camView);

for (Vec4& v : ret)
{
v = invMVP * v;
v /= v.w;
}

splitDistance= ret[4];
splitDistance+= ret[5];
splitDistance+= ret[6];
splitDistance+= ret[7];
splitDistance /= 4;

return ret;
}```

The splitDistance.Z is what I use as each split maxdistance. It is multiplied by the main cameras view matrix before being sent to the shader (as the index determination is done in view space). Is this correct?

2. I don't understand what you're doing here and why. It doesn't mesh with what you say you're trying to do.

Why aren't you just computing your split distances in eye-space, for instance:

Code :
```      double d_uniform = mix( near, far, percent );  // Linear
double d_log     = near * pow( ( far / near ), percent );  // Log
d                = mix( d_uniform, d_log, blend_f ); // Practical split scheme```

3. I was talking about the split distances used for the comparison in the shader; I already have the computation of split distances working.

For example, here's the lighting fragment shader I use:

Code :
```#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;

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);

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 angleNormal = clamp(dot(normal, UnifDirLightPass.mLightDir.xyz), 0, 1);

fragColor = vec4(diffuse, 1.0) * visibilty * angleNormal * UnifDirLightPass.mLightColor;
}```

So my idea is that splitDistance.z for each splits frustrum (from 1st post) is what I use for mSplitDistance.x/y/z (depending on split). Is this the correct values to compare against?

4. Originally Posted by TheKaiser
I was talking about the split distances used for the comparison in the shader; I already have the computation of split distances working.
Ok, I'll take your word for that. The compute logic bothers me.

I'm having issues where shadows vanish at certain angles and I want to ascertain I am using the correct values to determine the split index.

Code glsl:
```...
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;
...```
Assuming the distances are correct, this looks reasonable. Have you printed the values to ensure that they are correct?

5. Originally Posted by Dark Photon
Ok, I'll take your word for that. The compute logic bothers me.
I know it's confusing, I'm using the term "split distances" in two places, the first one (which I assumed you were refering to in your first post and code) is this:

Code :
```void CalculateShadowmapCascades(std::array<float, gNumShadowmapCascades>& nearDistArr, std::array<float, gNumShadowmapCascades>& farDistArr, const float nearDist, const float farDist)
{
const float splitWeight = 0.75f;
const float ratio = nearDist / farDist;

nearDistArr[0] = nearDist;
{

nearDistArr[index] = splitWeight * (nearDist * powf(ratio, si)) + (1 - splitWeight) * (nearDist + (farDist - nearDist) * si);
farDistArr[index - 1] = nearDistArr[index] * 1.005f;
}
}```

which I borrowed from the nvidia cascaded shadow map sample, and it works fine, for example for near_z = 0.1f and far_z = 100.0f I get the splits {6, 12, 18, 100} which looks reasonable enough to me.

The second one is the uniform I send to the shader I posted, since I can't just use the unmodified values from CalculateShadowmapCascades() directly. I reason that for each split, while constructing that splits frustrum I sample the average Z of the far corners of the frustrum like this:

Code :
```splitDistance= ret[4];
splitDistance+= ret[5];
splitDistance+= ret[6];
splitDistance+= ret[7];
splitDistance /= 4;```

Code :
```splitDistance= lighting.mCameraViewMatrix * splitDistance;

And that is what I'm not sure if I'm doing correctly. The nvidia sample uses a different comparison for the splits, like this:

Code :
`far_bound[i] = 0.5f*(-f[i].fard*cam_proj[10]+cam_proj[14])/f[i].fard + 0.5f;`

But me doing deferred shading figured it would be much easier and less code to do the comparison in view space?

6. Originally Posted by TheKaiser
The second one is the uniform I send to the shader I posted, since I can't just use the unmodified values from CalculateShadowmapCascades() directly.
Why not? I do, for forward and deferred shading.

I reason that for each split, while constructing that splits frustrum I sample the average Z of the far corners of the frustrum like this:

Code :
```splitDistance= ret[4];
splitDistance+= ret[5];
splitDistance+= ret[6];
splitDistance+= ret[7];
splitDistance /= 4;```

Code :
```splitDistance= lighting.mCameraViewMatrix * splitDistance;