そのため、シャドウ マッピングにはさらに別の問題があります。キューブマップ シャドウを使用してポイント ライトを実装しようとしていますが、ほとんど機能しています。
影を DEPTH_COMPONENT16 タイプのキューブマップにレンダリングしています。ディレクショナル ライトとスポット ライトの場合とまったく同じシェーダーを使用して、6 つのパスを実行します。カラー出力はなく、深度バッファのみを使用します。キューブマップはスポットライトが 6 つしかないので、問題はないと思います。
ここで、ライティング シェーダーでシャドウ マップをサンプリングしようとすると、問題が発生します。私のレンダラーは延期されているので、深さからすべての位置を再構築する必要があります。
キューブマップからサンプリングするときは、次のようにします。
// world space fragment to light
vec3 cubeNorm = normalize(w_pos - LB.position);
vec3 absNorm = abs(cubeNorm);
bool xy = absNorm.x > absNorm.y;
bool yz = absNorm.y > absNorm.z;
bool zx = absNorm.z > absNorm.x;
// which cube face will be sampled from
int index = 0;
if (xy && !zx) index = 0 + int(cubeNorm.x < 0.f);
if (yz && !xy) index = 2 + int(cubeNorm.y < 0.f);
if (zx && !yz) index = 4 + int(cubeNorm.z < 0.f);
// point in light space with small normal offset
vec4 sc = LB.matArr[index] * vec4(w_pos+w_surf*0.06f, 1.f);
vec4 shadcrd = vec4(cubeNorm, sc.z / sc.w * 0.5f + 0.5f);
// normals in view space
float bias = get_bias(v_surf, dirToPoint);
float vis = sample_shadow(shadcrd, bias, texShad);
get_bias 関数:
float get_bias(vec3 _normal, vec3 _lightDir) {
float lightDot = dot(_normal, -_lightDir);
float magicTan = sqrt(1.f - lightDot * lightDot) / lightDot;
return clamp(0.006f * magicTan, 0.f, 0.03f);
}
sample_shadow 関数:
float sample_shadow(vec4 _sc, float _bias, samplerCubeShadow _tex) {
return texture(_tex, vec4(_sc.xyz, _sc.w-_bias));
}
そして、これが私が得たものです。問題を簡単に確認できるように、ディスタンス ロール オフを無効にしています。
そのため、バイアスが適切に機能しません。より大きな値を返すように get_bias 関数を調整しても効果がないようです。にきびを取り除く唯一のことは、巨大な一定の偏りを加えることのようですが、これは明らかにオプションではありません.
比較のために、90 度の視野で同じ場所にレンダリングされたスポットライトを次に示します。シェーダーは同じ get_bias 関数を使用し、ニア プレーンとファー プレーンは同じ (0.2/5.0) です。
バイアスの問題はありません。6 つのスポットライト (丸みを帯びたエッジなし) を使用することもできますが、キューブマップを使用したいと思います。私は何を間違っていますか?