Я пытаюсь внедрить теневой каскад в свой проект, но все, что я получаю, это странная карта тени с бесконечным FOVC++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Я пытаюсь внедрить теневой каскад в свой проект, но все, что я получаю, это странная карта тени с бесконечным FOV

Сообщение Anonymous »

Я использую DirectX11 и пытаюсь получить каскадированную часть теневой карты и использовал статью LearnOpengl CSM, и свет прямо здесь < /p>
Это взгляд на функцию, которую я использую < /p>
template
inline CU::Matrix4x4 CU::Matrix4x4::LookAt(CU::Vector3f aEye, CU::Vector3f aCenter, CU::Vector3f aUp)
{
CU::Matrix4x4 mat;

auto Z = aCenter - aEye;
Z.Normalize();

auto X = Z.Cross(aUp);
X.Normalize();

if (!X.Length())
{
aUp = CU::Vector3f(0, 0, 1);

X = Z.Cross(aUp);
X.Normalize();
}

auto Y = X.Cross(Z);
Y.Normalize();

mat.SetRow(1, X.ToVector4(( - X.Dot(aEye))));
mat.SetRow(2, Y.ToVector4(( - Y.Dot(aEye))));
mat.SetRow(3, (-Z).ToVector4((Z.Dot(aEye))));
mat.SetRow(4, CU::Vector4f(0, 0, 0, 1));

return mat.GetTranspose();
}
< /code>
Вот где точки преобразуются в пространство просмотра камер Все точки правильно расположены с помощью Frustum < /p>
auto vec = MainSingleton::Get()->mySceneManager->GetCamera()->GetCameraData().GetFrustumCornersWorldSpace();

std::vector minMax;
std::vector views;
constexpr float zMult = 100.0f;
for (auto& v : vec)
{
CU::Vector3f center;
for (auto& vP : v)
{
center += vP;
}
center /= static_cast(v.size());

views.emplace_back(CU::Matrix4x4f::LookAt(center + myDirectionalLights.front()->GetData().direction, center, CU::Vector3f(0.f, 1.f, 0.f)));

//views.back().SetRow(4, myDirectionalLights.front()->gameObject->GetTransform().GetPosition().ToVector4(1));

minMax.emplace_back();

minMax.back().first.x = std::numeric_limits::max();
minMax.back().first.y = std::numeric_limits::max();
minMax.back().first.z = std::numeric_limits::max();

minMax.back().second.x = std::numeric_limits::lowest();
minMax.back().second.y = std::numeric_limits::lowest();
minMax.back().second.z = std::numeric_limits::lowest();

for (auto& vP : v)
{
const auto trf = vP * views.back();

minMax.back().first.x = std::min(minMax.back().first.x, trf.x);
minMax.back().first.y = std::min(minMax.back().first.y, trf.y);
minMax.back().first.z = std::min(minMax.back().first.z, trf.z);

minMax.back().second.x = std::max(minMax.back().second.x, trf.x);
minMax.back().second.y = std::max(minMax.back().second.y, trf.y);
minMax.back().second.z = std::max(minMax.back().second.z, trf.z);
}

if (minMax.back().first.z < 0)
minMax.back().first.z *= zMult;
else
minMax.back().first.z /= zMult;

if (minMax.back().second.z < 0)
minMax.back().second.z /= zMult;
else
minMax.back().second.z *= zMult;

}
< /code>
И конечно это то, где я делаю и рендеринг на карту тени с данным кадром < /p>
std::wstringstream stream;
stream GetContext()->ClearDepthStencilView(myShadowMaps[index]->GetDepthStencilView().Get(), D3D11_CLEAR_DEPTH, 1.0f, 0);

ID3D11ShaderResourceView* nullView = nullptr;
GraphicsEngine::GetRHI()->GetContext()->PSSetShaderResources(105 + index, 1, &nullView);

GraphicsEngine::GetRHI()->GetContext()->OMSetRenderTargets(0, nullptr, myShadowMaps[index]->GetDepthStencilView().Get());

CU::Camera camera;
auto val = miniMax[index];

//camera.GetSettings().myNearPlane = 10;
//camera.GetSettings().myFarPlane = 500000;

//float x = val.second.x - val.first.x;
//float y = val.second.y - val.first.y;

float left = val.first.x;
float right = val.second.x;
float bottom = val.first.y;
float top = val.second.y;
float nearPlane = val.first.z;
float farPlane = val.second.z;

camera.Init(left, right, bottom, top, nearPlane, farPlane);

auto& timer = CU::Time::Get();
myFrameBuffer.myCameraPosition = view[index].GetRowVector(4);
myFrameBuffer.myInverseViewMatrix = view[index].GetInverse();
myFrameBuffer.myProjectionMatrix = camera.GetClipSpace();
myFrameBuffer.myScreenResolution = GetResolution();
myFrameBuffer.myDeltaTime = timer.GetDeltaTime();
myFrameBuffer.myUnscaledDeltaTime = timer.GetDeltaTimeUnscaled();
myFrameBuffer.myTotalTime = timer.GetTotalTime();
myFrameBuffer.myForward = cam->GetData().direction;
UpdateAndSetConstantBuffer(ConstantBufferType::FrameBuffer, myFrameBuffer);

//this->SetFrameBuffer(cam->GetShadowCamera());

//auto& transform = cam->GetShadowCamera()->GetTransform();
//myFrameBuffer.myCameraPosition = transform.GetPosition().ToVector4(1.f);
//myFrameBuffer.myInverseViewMatrix = cam->GetShadowCamera()->GetView().GetInverse();
//myFrameBuffer.myForward = transform.Forward().GetNormalized();

D3D11_VIEWPORT viewport = {};
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = 4096;
viewport.Height = 4096;
viewport.MaxDepth = 1.0f;
myRHI->GetContext()->RSSetViewports(1, &viewport);

GraphicsEngine::GetRHI()->GetContext()->PSSetShader(nullptr, nullptr, 0);
< /code>
, а для разъяснения здесь - функция GetFrustum Corner < /p>
std::vector< std::vector> Camera::GetFrustumCornersWorldSpace()
{
std::vector< std::vector> frustumCorners;

const Vector3f up = myTransform.Up();
const Vector3f right = myTransform.Right();

const int nbSplits = 3;

std::vector splitpoints{10, 100, 300, 1000};

//for (int i = 0; i < nbSplits; i++)
//{
// float ratio = static_cast(i) / nbSplits;
// splitpoints = mySettings.myNearPlane + ratio * (mySettings.myFarPlane - mySettings.myNearPlane);
//}

for (int i = 1; i < nbSplits + 1; i++)
{
float fakeNearPlane = splitpoints;
float fakeFarPlane = splitpoints;

const float farHeight = std::tan(mySettings.myFov * Deg2Rad * 0.5f) * fakeFarPlane;
const float farWidth = farHeight * (16.f / 9.f);
const float nearHeight = std::tan(mySettings.myFov * Deg2Rad * 0.5f) * fakeNearPlane;
const float nearWidth = nearHeight * (16.f / 9.f);

const Vector3f farCentre = myTransform.GetPosition() + myTransform.Forward() * fakeFarPlane;
const Vector3f ftr = farCentre + up * farHeight + right * farWidth; //Far Top Right
const Vector3f ftl = farCentre + up * farHeight - right * farWidth; //Far Top Left
const Vector3f fbr = farCentre - up * farHeight + right * farWidth; //Far Bottom Right
const Vector3f fbl = farCentre - up * farHeight - right * farWidth; //Far Bottom Left

frustumCorners.emplace_back();

frustumCorners.back().emplace_back(ftr);
frustumCorners.back().emplace_back(ftl);
frustumCorners.back().emplace_back(fbr);
frustumCorners.back().emplace_back(fbl);

const Vector3f nearCentre = myTransform.GetPosition() + myTransform.Forward() * fakeNearPlane;
const Vector3f ntr = nearCentre + up * nearHeight + right * nearWidth;//Near Top Right
const Vector3f ntl = nearCentre + up * nearHeight - right * nearWidth;//Near Top Left
const Vector3f nbr = nearCentre - up * nearHeight + right * nearWidth;//Near Bottom Right
const Vector3f nbl = nearCentre - up * nearHeight - right * nearWidth;//Near Bottom Left

frustumCorners.back().emplace_back(ntr);
frustumCorners.back().emplace_back(ntl);
frustumCorners.back().emplace_back(nbr);
frustumCorners.back().emplace_back(nbl);
}

return frustumCorners;
}
< /code>
outputEt с изображением - это
Infinite fov < /p>
Я попытался изменить матрицу зажима
Умножение направления света, чтобы сделать Это дальше
я попытался получить обратный и получить транспонирование как на Clipspace, так и обратной матрице, но ничего не сработало

Подробнее здесь: https://stackoverflow.com/questions/794 ... t-is-a-wei
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C++»