Tôi đang thêm bóng vào một cảnh trong OpenGL bằng cách thực hiện hai đường vẽ, một đến bản đồ độ sâu và một đến bộ đệm khung bình thường.OpenGL shadow peter-panning
Không sử dụng sai lệch khi sử dụng bản đồ độ sâu, có rất nhiều mụn trứng cá.
này được cố định bằng cách thêm một sự thiên vị để kiểm tra bản đồ độ sâu.
Tuy nhiên, điều này gây ra bóng tối để 'Mở cửa sổ mới' từ đối tượng khi ánh sáng được chuyển đến một góc độ khác nhau.
tôi tin rằng hiệu ứng này được gọi là peter-panning và được gây ra bởi một sự thiên vị lớn hơn được sử dụng cho các góc khác nhau.
Việc sửa lỗi thông thường cho việc này có vẻ là hủy các hình tam giác khi vẽ bản đồ bóng, tuy nhiên khi mặt phẳng sàn là đối tượng 2D, tôi không tin điều này sẽ hoạt động đúng.
Địa hình thực tế tôi đang sử dụng được tạo theo cách thủ công và do đó, việc tạo phiên bản 3D của nó giống như trong ví dụ đơn giản này không hề đơn giản.
Làm cách nào để xoay khung hình được cố định trên một đối tượng 2D như thế này?
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);
}
Bạn có thể vẽ địa hình của bạn hai lần trong bóng tối lật các tam giác bình thường và bù đắp chúng bởi sự thiên vị trong hướng nhìn trong bóng đổ một lần - nó sẽ tăng gấp đôi hình tam giác rút ra nhưng nó sẽ cho phép bạn kích hoạt mặt sau culling (vì vậy nó nên ngay cả ở mức tối thiểu). Và vâng, trong kỹ thuật peter-panning này đang leo lên, luôn luôn. – BeyelerStudios
Độ lệch quy mô độ dốc thường được giới thiệu trong giai đoạn xây dựng shadowmap để khắc phục vấn đề này. Tra cứu 'glDepthOffset'. Biết rằng điều này sẽ phá vỡ một số loại tối ưu hóa bộ đệm độ sâu trong khi dựng hình, nhưng điều đó có thể không quan trọng vì bạn chỉ cần lấp đầy bộ đệm sâu và không chạy trình đổ bóng phân đoạn phức tạp. –
Cảm ơn, tôi sẽ thử những điều này. – Caw