Я пытаюсь реализовать отображение каскадных теней с помощью opengl, но у меня есть некоторые проблемы.
я начинаю с разделения моей пирамиды обзора на три разделения, и для каждого разделения у него есть
1- рядом
2- далеко
3 - углы (углы усеченной пирамиды данного раскола в мировом пространстве)
4- карта глубины (2D-текстура с размерами 1024 * 1024)
и для каждого разделения я начинаю с вычисления его углов следующим образом, и с помощью этих углов в мировом пространстве я вычисляю центр усеченной вершины, который я буду использовать для рассчитать матрицу светового обзора.
float width = float(mRenderer->GetGame()->GetWidth());
float height = float(mRenderer->GetGame()->GetHeight());
mProjMatrix = glm::perspective(glm::radians(90.0f), (float)width / (float)height, mNear, mFar);
mViewMatrix = mRenderer->GetView();
glm::mat4 viewProj = mProjMatrix * mViewMatrix;
glm::vec3 frustumCorners[8] =
{
glm::vec3(-1.0f, 1.0f, -1.0f),
glm::vec3(1.0f, 1.0f, -1.0f),
glm::vec3(1.0f, -1.0f, -1.0f),
glm::vec3(-1.0f, -1.0f, -1.0f),
glm::vec3(-1.0f, 1.0f, 1.0f),
glm::vec3(1.0f, 1.0f, 1.0f),
glm::vec3(1.0f, -1.0f, 1.0f),
glm::vec3(-1.0f, -1.0f, 1.0f),
};
for (int i = 0; i < 8; ++i)
{
glm::vec4 inversePoint = glm::inverse(viewProj) * glm::vec4(frustumCorners[i], 1.0f);
mCorners[i] = glm::vec3(inversePoint / inversePoint.w);
}
for (int i = 0; i < 8; ++i)
{
mFrustumCenter += mCorners[i];
}
mFrustumCenter /= 8.0f;
после того, как у меня будет центр усеченной вершины этого конкретного разделения, мне нужно выяснить матрицу просмотра света, которую я буду использовать для рендеринга сцены (между ближним и дальним участком разделения ), и я делаю это следующим образом.
mRenderer- ›GetLightDirection () = {0.0f, 20.0f, -1.0f}
glm::vec3 lightDir = glm::normalize(mRenderer->GetLightDirection());
glm::vec3 lightPos = mFrustumCenter + lightDir;
mLightView = glm::lookAt(lightPos, mFrustumCenter , glm::vec3(0.0f, 1.0f, 0.0f));
и, наконец, последнее, что я делаю, - это вычисляю ортогональную матрицу света с использованием разделенных углов усеченной вершины после того, как я преобразовал их в пространство света с помощью Матрица светового просмотра я рассчитала на предыдущем шаге.
for (int i = 0; i < 8; ++i)
{
mCorners[i] = glm::vec3(mLightView * glm::vec4(mCorners[i], 1.0f));
}
float minX = std::numeric_limits<float>::max();
float maxX = std::numeric_limits<float>::min();
float minY = std::numeric_limits<float>::max();
float maxY = std::numeric_limits<float>::min();
float minZ = std::numeric_limits<float>::max();
float maxZ = std::numeric_limits<float>::min();
for (int i = 0; i < 8; ++i)
{
minX = std::min(minX, mCorners[i].x);
maxX = std::max(maxX, mCorners[i].x);
minY = std::min(minY, mCorners[i].y);
maxY = std::max(maxY, mCorners[i].y);
minZ = std::min(minZ, mCorners[i].z);
maxZ = std::max(maxZ, mCorners[i].z);
}
mLightProj = glm::ortho(minX, maxX, minY, maxY, minZ, maxZ);
когда я запускаю свою программу, моя тень работает правильно
но когда я перемещаю камеру назад, пока пол не войдет в диапазон второго разделения вместо использования второй разделенной тени, он исчезает, но когда я начинаю перемещать камеру вверх и вниз, тень снова появляется, поэтому я думаю, что проблема в вычислении света просмотреть матрицу, но я не мог этого понять.
это диапазоны моих разбиений
near- ›far
0,1 -› 30,0
0,1 - ›50,0
0,1 -› 1000,0