У меня есть шейдер, который реализует отображение теней следующим образом:
#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
? Я знаю, что он может возвращать значения, отличные от нуля или единицы, если вы используете множественную выборку, и мне бы хотелось, чтобы поведение не прерывалось в какой-то момент.
Выходной вершинный шейдер:
#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;
}
Обратите внимание, что фрагментный шейдер предназначен для ландшафта, а вершинный шейдер — для пола, поэтому между ними могут быть небольшие несоответствия, но они не должны иметь значения.
shadow_matrix
— это униформа, переданная как bias_matrix * light_projection_matrix * light_view_matrix * light_model_matrix
.
textureProj (...)
? Нет такой вещи, какsampler2DShadowMS
. Единственное, что изменит ваш поиск текстур, возвращая 0.0 или 1.0, — это фильтрация текстур. Я объяснил это в своем ответе. - person Andon M. Coleman   schedule 06.02.2014