我的定向灯让我的阴影正常工作,但是当谈到点光源时,我有点难过。我的想法是使用立方体贴图来渲染光线周围所有六个边的深度。到目前为止,这一切都很有效。我已经通过将我的立方体的每个面渲染为2D图像来验证此步骤,并且它看起来是正确的。
现在我试图让阴影出现在世界上。为此,我使用的是GLSL的samplerCubeShadow数据类型。有了它,我做:
$thumb_ass = $this->MProperty->sel_asset_by_list($val_id_assets,$par = "PAR_1");
$slide_ass = $this->MProperty->sel_asset_by_list($val_id_assets,$par = "PAR_2");
$data = array ('thumb_ass' => $thumb_ass, 'slide_ass' =>$slide_ass);
我尝试了很多配置,这总是让我的场景变成黑色。有任何想法吗?我的fragPos只是模型矩阵乘以顶点位置。我应该将光的模型视图矩阵应用于它吗?或者,同样地,我应该将世界的模型视图矩阵应用于光吗?任何反馈都非常感谢!
答案 0 :(得分:1)
假设您要在立方体贴图中存储深度值;
AFAIK立方体贴图是世界空间中的AABB,因此需要在世界空间中进行计算。在您的情况下,light.position
和fragPos
必须位于世界空间中,或者如果您在其他位置的视图空间中使用这些名称,则提供其他变量/成员,例如每片段光计算
此外,您需要在传递给texture
之前将lightToFrag转换为深度值。
此答案显示如何将lightToFrag转换为深度值:Omnidirectional shadow mapping with depth cubemap
这里是我的实现(我删除了#ifdef SHAD_CUBE,因为其他人使用相同的名称):
uniform samplerCubeShadow uShadMap;
uniform vec2 uFarNear;
float depthValue(const in vec3 v) {
vec3 absv = abs(v);
float z = max(absv.x, max(absv.y, absv.z));
return uFarNear.x + uFarNear.y / z;
}
float shadowCoef() {
vec3 L;
float d;
L = vPosWS - light.position_ws;
d = depthValue(L);
return texture(uShadMap, vec4(L, d));
}
如果您只有ModelViewProjection(MVP)
,这可能需要统一的模型矩阵这里如何在客户端计算uNearFar:
float n, f, nfsub, nf[2];
n = sm->near;
f = sm->far;
nfsub = f - n;
nf[0] = (f + n) / nfsub * 0.5f + 0.5f;
nf[1] =-(f * n) / nfsub;
glUniform2f(gkUniformLoc(prog, "uFarNear"), nf[0], nf[1]);
这只是优化,但你不必使用它并按照我之前提到的链接。
您可能需要偏差值,相关答案使用偏差,但我不确定如何正确地将其应用于立方体贴图。我不确定d - + 0.0001是否正确。
如果你想在立方体贴图中存储世界距离,那么本教程似乎是上帝之一:https://learnopengl.com/Advanced-Lighting/Shadows/Point-Shadows