我通过执行两个拉伸添加阴影到在OpenGL场景通过,一个以一个深度图和一个到正常帧缓冲器。OpenGL的阴影彼得平摇
在使用深度图时不使用偏差,有很多阴影痤疮。
这是通过添加一个偏压施加到深度图检查固定的。
然而,这导致从对象的阴影,以“分离”当光被移动到不同的角度。
相信这种效果被称为彼得-平移和由较大偏压引起被用于不同的角度。
对于这个通常的解决方法似乎是在绘制阴影贴图时剔除背面三角形,但是由于地平面是2D对象,我不相信这会正常工作。
我使用的实际地形是程序生成的,所以创建它的3D版本并不像在这个简单的例子中那么简单。
如何将平移到像这样的二维物体上?
顶点着色器
#version 400
layout(location = 0) in vec3 position;
layout(location = 1) in vec3 normal;
layout(location = 2) in vec2 texture_coords;
out VS_OUT {
vec4 position;
vec3 normal;
vec2 texture_coords;
vec4 shadow_position;
} vs_out;
uniform mat4 model;
uniform mat4 model_view;
uniform mat4 model_view_perspective;
uniform mat3 normal_matrix;
uniform mat4 depth_matrix;
void main() {
vec4 position_v4 = vec4(position, 1.0);
vs_out.position = model_view * position_v4;
vs_out.normal = normal_matrix * normal;
vs_out.texture_coords = texture_coords;
vs_out.shadow_position = depth_matrix * model * position_v4;
gl_Position = model_view_perspective * position_v4;
}
片段着色器
#version 400
in VS_OUT {
vec4 position;
vec3 normal;
vec2 texture_coords;
vec4 shadow_position;
} fs_in;
out vec4 colour;
uniform mat4 view;
uniform mat4 model_view_perspective;
uniform vec3 light_position;
uniform vec3 emissive_light;
uniform float shininess;
uniform int textured;
uniform sampler2D tex;
uniform sampler2DShadow shadow_texture;
void main() {
const vec3 specular_albedo = vec3(1.0, 0.8, 0.6);
colour = vec4(0.8, 0.8, 0.8, 0.8);
if(textured != 0) {
colour = texture(tex, fs_in.texture_coords);
}
vec3 light_direction = normalize(light_position);
vec3 normal = normalize(fs_in.normal);
float visibility = 1.0;
if(fs_in.shadow_position.z <= 1.0) {
float bias = max(0.05 * (1.0 - dot(normal, light_direction)), 0.005);
if(fs_in.shadow_position.z > texture(shadow_texture, fs_in.shadow_position.xyz, 0.0) + bias){
visibility = 0.0;
}
}
/* Ambient */
vec3 ambient = colour.xyz * 0.1;
/* Diffuse */
vec3 diffuse = visibility * (clamp(dot(normal, light_direction), 0, 1) * colour.xyz);
/* Specular */
vec3 specular = vec3(0.0);
if(dot(normal, light_direction) > 0) {
vec3 V = normalize(-fs_in.position.xyz);
vec3 half_dir = normalize(light_direction + V);
specular = visibility * (pow(max(dot(normal, half_dir), 0.0), shininess) * specular_albedo.xyz);
}
colour = vec4(((ambient + diffuse) * colour.xyz) + specular + emissive_light, 1.0);
}
你可以在阴影过程中绘制地形两次,然后翻转三角法线并在着色器中沿着视线方向偏移一次 - 它将使所绘制的三角形加倍,但它可以让您启用背面剔除(所以它应该甚至在最低限度)。是的,在这种技术中,彼此一直在爬行。 – BeyelerStudios
通常在阴影贴图构建阶段引入坡度偏差以解决此问题。查找'glDepthOffset'。知道这将在渲染过程中破坏某些深度缓冲区优化,但这可能并不重要,因为您只是填充深度缓冲区而不运行复杂的片段着色器。 –
谢谢,我会试试这些。 – Caw