我通過執行兩個拉伸添加陰影到在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