阴影映射着色器



我有一个着色器,可以实现这样的阴影映射:

#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(...)结果是否确实处于阴影状态

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 (...)不会返回归一化的浮点值。如果您在sampler<1D|2D|2DRect>Shadow上使用单个float,它确实会返回单个CC_7,但是此值代表了深度测试的结果。 1.0 = Pass, 0.0 =失败。

现在,这里要注意的有趣的事情,以及返回阴影采样器float的原因与滤波阴影映射完全有意义。如果您在影子地图上使用GL_LINEAR滤波器模式以及阴影采样器,则GL实际上将在影子映射中选择4个最接近的Texels,并执行4个独立的深度测试。

每个深度测试仍然具有二进制结果,但是GL将返回所有4个测试结果的加权平均值(基于距理想样本位置的距离)。因此,如果您将GL_LINEAR与影子采样器结合使用,则将具有一个位于 0.0 1.0 之间的值,代表4个最近的深度样本的平均闭合。

我应该指出,您对textureProj (...)的使用对我来说可能是错误的。它使用的坐标是一个4D向量,该向量由(str)[投影坐标]和(q)[测试深度值]组成。我看不到代码中的任何位置您分配了q深度值。如果您可以编辑问题以包括输出shadow_coord的顶点/几何着色器,那将有所帮助。

尝试以下内容:

从模型的每个顶点到光。

将此距离发送给您的碎片着色器。

将距离与存储在您的影子地图采样器中的值进行比较(我认为此纹理从相机的角度存储了场景的深度值?)

如果距离大于采样器,则点在阴影中。否则,不是。

如果这令人困惑,这里有一对应该有所帮助的教程:http://ogldev.atspace.co.uk/www/tutorial23/tutorial23.htmlhttp://ogldev.atspace.co.uk/www/tutorial24/tutorial24.html

相关内容

  • 没有找到相关文章

最新更新