5

次のようなシャドウ マッピングを実装するシェーダーがあります。

#version 430 core

out vec4 color;

in VS_OUT {
    vec3 N;
    vec3 L;
    vec3 V;
    vec4 shadow_coord;
} fs_in;

layout(binding = 0) uniform sampler2DShadow shadow_tex;

uniform vec3 light_ambient_albedo = vec3(1.0);
uniform vec3 light_diffuse_albedo = vec3(1.0);
uniform vec3 light_specular_albedo = vec3(1.0);

uniform vec3 ambient_albedo = vec3(0.1, 0.1, 0.2);
uniform vec3 diffuse_albedo = vec3(0.4, 0.4, 0.8);
uniform vec3 specular_albedo = vec3(0.0, 0.0, 0.0);
uniform float specular_power = 128.0;

void main(void) {
    //color = vec4(0.4, 0.4, 0.8, 1.0);

    //normalize
    vec3 N = normalize(fs_in.N);
    vec3 L = normalize(fs_in.L);
    vec3 V = normalize(fs_in.V);

    //calculate R
    vec3 R = reflect(-L, N);

    //calcualte ambient
    vec3 ambient = ambient_albedo * light_ambient_albedo;

    //calculate diffuse
    vec3 diffuse = max(dot(N, L), 0.0) * diffuse_albedo * light_diffuse_albedo;

    //calcualte spcular
    vec3 specular = pow(max(dot(R, V), 0.0), specular_power) * specular_albedo * light_specular_albedo;

    //write color
    color = textureProj(shadow_tex, fs_in.shadow_coord) * vec4(ambient + diffuse + specular, 0.5);
    //if in shadow, then multiply color by 0.5 ^^, except alpha
}

私がやりたいことは、フラグメントが実際に影にあるかどうかを最初に確認してから、色変更することです(完全な黒と元の色の中間になるように半分にします)。

textureProj(...)ただし、正規化された値を返すことがわかっている限り、結果が実際に影にあるかどうかを確認する方法float

textureProj(...) > 0.9999すでに十分でしょうか?マルチサンプリングを使用している場合、0 または 1 以外の値を返す可能性があることはわかっています。また、ある時点で壊れない動作が必要です。

出力頂点シェーダー:

#version 430 core

layout(location = 0) in vec4 position;

layout(location = 0) uniform mat4 model_matrix;
layout(location = 1) uniform mat4 view_matrix;
layout(location = 2) uniform mat4 proj_matrix;
layout(location = 3) uniform mat4 shadow_matrix;

out VS_OUT {
    vec3 N;
    vec3 L;
    vec3 V;
    vec4 shadow_coord;
} vs_out;

uniform vec4 light_pos = vec4(-20.0, 7.5, -20.0, 1.0);

void main(void) {
    vec4 local_light_pos = view_matrix * light_pos;
    vec4 p = view_matrix * model_matrix * position;

    //normal
    vs_out.N = vec3(0.0, 1.0, 0.0);

    //light vector
    vs_out.L = local_light_pos.xyz - p.xyz;

    //view vector
    vs_out.V = -p.xyz;

    //light space coordinates
    vs_out.shadow_coord = shadow_matrix * position;

    gl_Position = proj_matrix * p;
}

フラグメント シェーダーは地形用であり、頂点シェーダーは床用であるため、この 2 つの間には多少の不一致がある可能性がありますが、関連性はありません。

shadow_matrixとして渡されるユニフォームbias_matrix * light_projection_matrix * light_view_matrix * light_model_matrixです。

4

2 に答える 2

1

次のことを試してください。

モデルの各頂点からライトまでの距離を取得します。

この距離をフラグメント シェーダーに送信します。

距離をシャドウ マップ サンプラーに格納されている値と比較します (このテクスチャには、カメラの視点から見たシーンの深度値が格納されていると思いますか?)

距離がサンプラーよりも大きい場合、そのポイントは影になります。そうでなければ、そうではありません。

これが紛らわしい場合は、次のチュートリアルが役立ちます。 http://ogldev.atspace.co.uk/www/tutorial23/tutorial23.html http://ogldev.atspace.co.uk/www/tutorial24/tutorial24 .html

于 2014-02-06T16:37:35.143 に答える