级联阴影贴图无法正常工作

穆罕默德·哈希姆(Mohamed Hashem)

我正在尝试使用opengl实现级联阴影映射,但遇到了一些问题。

我开始通过将我的视锥体3个分割并为每个分割它具有

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

当我运行程序时,我的阴影可以正常工作

在此处输入图片说明

但是当我将摄像机移回直到地板进入第二个拆分的范围而不是使用第二个拆分阴影时,它消失了,但是当我开始上下移动摄像机时,阴影又出现了,所以我认为问题在于计算光视图矩阵,但我不知道。

在此处输入图片说明

这些是我的拆分范围->

0.1-> 30.0
0.1-> 50.0
0.1-> 1000.0

穆罕默德·哈希姆(Mohamed Hashem)

好吧,我发现我没有正确放置灯光,所以这个片段

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

应该

glm::vec3 lightDir = glm::normalize(mRenderer->GetLightDirection()); 
glm::vec3 lightPos = mFrustumCenter + lightDir * (mFar - mNear); 
mLightView = glm::lookAt(lightPos, mFrustumCenter , glm::vec3(0.0f, 1.0f, 0.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);

应该

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, near, maxZ - minZ);

正交投影矩阵的近点和远点应等于平截锥体的近点,远点应等于最近角和最远角(z轴)之间的距离

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

OpenGL阴影贴图几乎可以正常工作

来自分类Dev

laravel级联无法正常工作?

来自分类Dev

级联删除无法正常工作

来自分类Dev

使用OpenGL纹理贴图无法正常工作

来自分类Dev

级联阴影贴图不太正确

来自分类Dev

Android Room onDelete级联无法正常工作

来自分类Dev

OpenGL延迟阴影照明无法正常工作

来自分类Dev

GLSL 中阴影光线的平滑阴影无法正常工作

来自分类Dev

使用GLSL,多光源阴影映射无法正常工作

来自分类Dev

3d法线贴图在Three.js中无法正常工作

来自分类Dev

无法让Sprite贴图在三个js中正常工作

来自分类Dev

升级后,Redmine从剪贴板粘贴图像无法正常工作

来自分类Dev

为什么阴影贴图着色器向后工作?

来自分类Dev

带有DeleteBehavior.Restrict的EF核心级联参照完整性无法正常工作

来自分类Dev

阴影贴图工件

来自分类Dev

OpenGL中的阴影贴图

来自分类Dev

GLSL 1.20阴影贴图,使阴影变形

来自分类Dev

OpenGL阴影贴图-阴影位置错误

来自分类Dev

@BeforeSuite无法正常工作

来自分类Dev

BringIntoView无法正常工作

来自分类Dev

Selendroid无法正常工作?

来自分类Dev

无法使URLrewritng正常工作

来自分类Dev

substr()无法正常工作

来自分类Dev

slidetoggle无法正常工作

来自分类Dev

onkeypress无法正常工作

来自分类Dev

Bash IF无法正常工作

来自分类Dev

@AfterThrowing无法正常工作

来自分类Dev

httpPost无法正常工作

来自分类Dev

getrusage无法正常工作