J'ajoute des ombres à une scène dans OpenGL en effectuant deux passes, une pour une carte de profondeur et une autre pour le frame frame normal.OpenGL shadow peter-panning
Sans utiliser de biais lors de l'utilisation de la carte de profondeur, il y a beaucoup d'acné cachée.
Ceci est corrigé en ajoutant une polarisation à la vérification de la carte de profondeur.
Cependant, cela provoque l'ombre à « détacher » de l'objet lorsque la lumière est déplacé vers un autre angle.
Je crois que cet effet est appelé Pierre-mouvement horizontal et est causé par un biais plus utilisé pour des angles différents. La solution habituelle pour cela semble être de reculer les triangles en vis-à-vis lorsque vous dessinez la carte d'ombre, cependant comme le plan du sol est un objet 2D, je ne crois pas que cela fonctionnerait correctement. Le terrain réel que j'utilise est généré de manière procédurale et il n'est donc pas aussi simple de créer une version 3D que dans cet exemple simple.
Comment le peter-panning peut-il être fixé sur un objet 2D tel que celui-ci?
Vertex shader
#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;
}
Fragment shader
#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);
}
Vous pouvez dessinez votre terrain deux fois dans le passage d'ombre en renversant les normales du triangle et en les décalant par le biais dans le sens du regard dans le shader une fois - cela va doubler les triangles tracés mais cela vous permettra d'activer l'abattage égaliser au minimum). Et oui, dans cette technique, peter-panning se faufile, toujours. – BeyelerStudios
La distorsion d'échelle de pente est généralement introduite pendant la phase de construction de la carte d'ombre pour résoudre ce problème. Recherche 'glDepthOffset'. Sachez que cela va casser certains types d'optimisations de tampons de profondeur pendant le rendu, mais cela peut ne pas être si important puisque vous ne faites que remplir le tampon de profondeur et ne pas exécuter un fragment de shader compliqué. –
Merci, je vais essayer ceux-ci. – Caw