3

nvidia SDK (http://developer.download.nvidia.com/SDK/10.5/Samples/cascaded_shadow_maps.zip) のようにカスケード シャドウ マッピングを実装しました。しかし、私のルックアップはうまくいかないようです。

これが私の現在の状態を表す写真です: http://i.imgur.com/SCHDO.png

問題は、私が最初のスプリットから遠く離れているにもかかわらず、すぐに最初のスプリットになってしまうことです。ご覧のとおり、他の分割は考慮されていません。

この理由は、メイン エンジンが使用している別のプロジェクション マトリックスにあるのではないかと考えました。これは私がアルゴリズムに提供したものとは異なりますが、同じマトリックスをシェーダーに渡して次のように計算しようとしました: 私はまだ1つの分割だけで終わった。

ここに私のシェーダーがあります:

[バーテックス]

varying vec3 vecLight;
varying vec3 vecEye;
varying vec3 vecNormal;
varying vec4 vecPos;
varying vec4 fragCoord;
void main(void)
{
    vecPos = gl_Vertex;
    vecNormal = normalize(gl_NormalMatrix * gl_Normal);
    vecLight = normalize(gl_LightSource[0].position.xyz);
    vecEye = normalize(-vecPos.xyz);

    gl_TexCoord[0] = gl_MultiTexCoord0;
    gl_Position = ftransform();
}

[フラグメント] (影の部分のみ)

vec4 getShadow()
{
    vec4 sm_coord_c = texmat_3*vecPos;
    float shadow = texture2D(smap_3, sm_coord_c.xy).x;
    float s = (shadow < sm_coord_c.z) ? 0.0 : 1.0;

    vec4 shadow_c = vec4(1.0, 1.0, 1.0, 1.0) * s;

    if(gl_FragCoord.z < vecFarbound.x)
    {
      vec4 sm_coord_c = texmat_0*vecPos;
      float shadow = texture2D(smap_0, sm_coord_c.xy).x;
      float s = (shadow < sm_coord_c.z) ? 0.0 : 1.0;

      shadow_c = vec4(0.7, 0.7, 1.0, 1.0) * s;
    }
    else if(gl_FragCoord.z < vecFarbound.y)
    {
      vec4 sm_coord_c = texmat_1*vecPos;
      float shadow = texture2D(smap_1, sm_coord_c.xy).x;
      float s = (shadow < sm_coord_c.z) ? 0.0 : 1.0;

      shadow_c = vec4(0.7, 1.0, 0.7, 1.0) * s;
    }
    else if(gl_FragCoord.z < vecFarbound.z)
    {
      vec4 sm_coord_c = texmat_2*vecPos;
      float shadow = texture2D(smap_2, sm_coord_c.xy).x;
      float s = (shadow < sm_coord_c.z) ? 0.0 : 1.0;

      shadow_c = vec4(1.0, 0.7, 0.7, 1.0) * s;
    }

    return shadow_c;
}

したがって、何らかの理由で、シーンのどこにいても、gl_FragCoord.z は vecFarbound.x よりも小さくなります。(また、左端の影の領域に注意してください。これは、カメラを上に移動するほど増加し、すぐにすべてのシーンを占有します..)

vecFarbound の値を確認しましたが、nvidia のコードの値と似ているので、正しく計算したと思います。

gl_FragCoord.z の値を確認する方法はありますか?

4

1 に答える 1

1

私の古い csm 実装では、単にカメラ空間で距離を使用しました

float tempDist = 0.0;
tempDist = dot(EyePos.xyz, EyePos.xyz);
if (tempDist < split.x) ...
else if (tempDist < split.y) ...
...

このソリューションは、理解するのが少し簡単で、分割をより適切に制御できました。Z 値を (クリップ スペースで) 使用する場合、z 値が線形でないことに起因する問題が発生する可能性があります。

viewSpace で分割テストを行うことをお勧めします。その後、(機能する場合) gl_FragCoord.z を使用します。

于 2012-05-12T11:34:56.177 に答える