Ok。それで、私は先週、自分のゲーム エンジンで影をいじっていました。私は主にカスケード シャドウ マップ (CSM) を実装しましたが、解決できないように見えるシャドウイングに少し問題があります。
このシーンの唯一のライトはディレクショナル ライト (太陽) で、{-0.1 -0.25 -0.65} を指しています。次のコードを使用して、CSM の 4 つの分割に対して 4 セットの錐台境界を計算します。
// each projection matrix calculated with same near plane, different far
Frustum make_worldFrustum(const glm::mat4& _invProjView) {
Frustum fr; glm::vec4 temp;
temp = _invProjView * glm::vec4(-1, -1, -1, 1);
fr.xyz = glm::vec3(temp) / temp.w;
temp = _invProjView * glm::vec4(-1, -1, 1, 1);
fr.xyZ = glm::vec3(temp) / temp.w;
...etc 6 more times for ndc cube
return fr;
}
ライトの場合、次のようなビュー マトリックスを取得します。
glm::mat4 viewMat = glm::lookAt(cam.pos, cam.pos + lightDir, {0,0,1});
次に、各錐台の境界から各オルソ マトリックスを作成します。
lightMatVec.clear();
for (auto& frus : cam.frusVec) {
glm::vec3 arr[8] {
glm::vec3(viewMat * glm::vec4(frus.xyz, 1)),
glm::vec3(viewMat * glm::vec4(frus.xyZ, 1)),
etc...
};
glm::vec3 minO = {INFINITY, INFINITY, INFINITY};
glm::vec3 maxO = {-INFINITY, -INFINITY, -INFINITY};
for (auto& vec : arr) {
minO = glm::min(minO, vec);
maxO = glm::max(maxO, vec);
}
glm::mat4 projMat = glm::ortho(minO.x, maxO.x, minO.y, maxO.y, minO.z, maxO.z);
lightMatVec.push_back(projMat * viewMat);
}
非常に単純な頂点シェーダー (フラグ無効またはパンチスルー アルファ) を使用してシーンを描画する 4 つのフレームバッファーにバインドされた 4 レイヤーの TEXTURE_2D_ARRAY があります。
その後、最後のシーンを描きます。頂点シェーダーは、4 つのシャドウ texcoords を出力します。
out vec3 slShadcrd[4];
// stuff
for (int i = 0; i < 4; i++) {
vec4 sc = WorldBlock.skylMatArr[i] * vec4(world_pos, 1);
slShadcrd[i] = sc.xyz / sc.w * 0.5f + 0.5f;
}
そして、使用する分割を決定するフラグメント シェーダー:
int csmIndex = 0;
for (uint i = 0u; i < CameraBlock.csmCnt; i++) {
if (-view_pos.z > CameraBlock.csmSplits[i]) index++;
else break;
}
そして、この関数でシャドウ マップ配列をサンプリングします。
float sample_shadow(vec3 _sc, int _csmIndex, sampler2DArrayShadow _tex) {
return texture(_tex, vec4(_sc.xy, _csmIndex, _sc.z)).r;
}
そして、これが私が得たシーンです (各分割がわずかに着色され、4 つの深度レイヤーがオーバーレイされています)
。いいね。
しかし、カメラを少し右に向けると、
影が消え始めます (角度によっては、影があるべきでない場所に現れます)。
GL_DEPTH_CLAMP を有効にしているので、それは問題ではありません。私は前面をカリングしていますが、それをオフにしてもこの問題に違いはありません。
私は何が欠けていますか?私の予測の 1 つに問題があるように感じますが、それらはすべて私には正しく見えます。ありがとう!
編集: 描画されたライトの錐台の 4 つすべて。それらはすべてそこにありますが、カメラに対して相対的に変化しているのは z だけです (以下のコメントを参照)。
編集: おそらくもっと便利です。これは、カメラが (0,0,0) にあり、前方 (0,1,0) を指しているときに、一度だけ更新したときに視錐台がどのように見えるかです。今回もデプステストで描きました。
重要な編集: この問題は、現在、ライトのビュー マトリックスに直接関連しているようです。
glm::mat4 viewMat = glm::lookAt(cam.pos, cam.pos + lightDir, {0,0,1});
目とターゲットの値を変更すると、バグのある影に影響するようです。しかし、実際にこれを何に設定すればよいかわかりませんか?私よりも理解している人にとっては簡単なはずです:D