0

ポイント ライトのシャドウを作成するためにキューブ マップを使用しようとしています。

私に役立つさまざまなチュートリアルを見つけました ( Pointers on modern OpenGL shadow cubemapping?https://www.opengl.org/discussion_boards/showthread.php/169743-cubemap-shadows-for-pointlightshttp://www.cg. tuwien.ac.at/courses/Realtime/repetitorium/2011/OmnidirShadows.pdf、...) しかし、キューブ マップのルックアップにはまだ問題があります。

このシェーダーはキューブ マップを作成します (形式: GL_DEPTH_COMPONENT、GL_UNSIGNED_BYTE):

//vertex shader
#version 330

uniform mat4 Model;
uniform mat4 View;
uniform mat4 Projection;

in vec3 vertex;

out vec3 vertexModel;

void main()
{       
    gl_Position =  Projection * View * Model * vec4(vertex, 1.0);
    vertexModel = vec3(Model * vec4(vertex, 1.0));
}

//fragment shader
#version 330

uniform vec3 lightPosition;
uniform float lightRange;

out float fragDepth;
out vec4 fragColor;

in vec3 vertexModel;

void main()
{   
    gl_FragDepth = length(lightPosition - vertexModel) / lightRange;  
    fragColor = vec4(1.0);
}

lightPositionはワールド空間でのライトの位置で、lightRange基本的にはライトの射影行列の zFar です。

生成されたキューブ マップは、gDEBugger を使用してアプリケーションをデバッグするときに見栄えがします。

メイン シェーダーでのシャドウ ルックアップ:

float shadowValue(int i)
{
    vec3 lookup_vector = vertexModel - lightPosition;
    float dist = texture(shadowMap, lookup_vector).r; 

    float curr_fragment_dist_to_light = length(lookup_vector) / lightRange;

    float result = 1.0; 
    if (dist < curr_fragment_dist_to_light)
        result = 0.0;
    return result;

}

この関数の結果は、ライト計算の値で乗算されます。問題は、常に 1.0 を返すことです。

誰かが私が間違っていることを知っていますか?

4

1 に答える 1

0

lookup_vector の y 座標を反転する必要があります。レンダリング中 (私は推測します)、y 座標は上向きですが、OpenGL テクスチャの場合、y は下向きです。あなたのシーンは対称なので、最初はテクスチャが正しいように見えますが、反映する必要があります - または単にあなたのlookup_vector:

vec3 new_vec = vec3(lookup_vector .x, -lookup_vector .y, lookup_vector .z);

次に、すでに行ったように、シャドウ マップにレンダリングされた距離を調べます。

float dist = texture(shadowMap, new_vec);

テストする深度は、次のように計算する必要があります。

vec3 abs_vec = abs(new_vec);
float local_z_comp = max(abs_vec .x, max(abs_vec .y, abs_vec .z));
float norm_z_comp = (z_far + z_near) /
    (z_far - z_near) - (2 * z_far * z_near) / (z_far - z_near) / local_z_comp;
float curr_fragment_dist_to_light = (norm_z_comp + 1.0) * 0.5;

z_farはあなたのlightRangez_nearは近平面に相当するものです。最後になりましたが、結果を返します。

float result = 1.0; 
if (dist < curr_fragment_dist_to_light)
    result = 0.0;
return result;

これらの計算は、次の質問への回答に基づいています: Cubemap シャドウ マッピングが機能しない

于 2013-10-21T01:39:16.460 に答える