Tôi đã triển khai ánh xạ bóng cơ bản lần đầu tiên trong OpenGL bằng cách sử dụng trình đổ bóng và tôi đang gặp một số vấn đề. Dưới đây bạn có thể thấy một ví dụ về cảnh hiển thị của tôi:
Quá trình ánh xạ bóng tôi đang theo dõi là tôi kết xuất cảnh cho bộ đệm khung bằng cách sử dụng Ma trận xem từ điểm nhìn sáng và ma trận chiếu và mô hình được sử dụng để hiển thị bình thường.
Trong lần chuyển thứ hai, tôi gửi ma trận MVP ở trên từ điểm nhìn ánh sáng đến bộ đổ bóng đỉnh để biến đổi vị trí thành không gian ánh sáng. Trình tạo bóng mảnh phân chia phối cảnh và thay đổi vị trí thành tọa độ kết cấu.
Đây là shader đỉnh của tôi,
#version 150 core
uniform mat4 ModelViewMatrix;
uniform mat3 NormalMatrix;
uniform mat4 MVPMatrix;
uniform mat4 lightMVP;
uniform float scale;
in vec3 in_Position;
in vec3 in_Normal;
in vec2 in_TexCoord;
smooth out vec3 pass_Normal;
smooth out vec3 pass_Position;
smooth out vec2 TexCoord;
smooth out vec4 lightspace_Position;
void main(void){
pass_Normal = NormalMatrix * in_Normal;
pass_Position = (ModelViewMatrix * vec4(scale * in_Position, 1.0)).xyz;
lightspace_Position = lightMVP * vec4(scale * in_Position, 1.0);
TexCoord = in_TexCoord;
gl_Position = MVPMatrix * vec4(scale * in_Position, 1.0);
}
Và mảnh vỡ của tôi,
#version 150 core
struct Light{
vec3 direction;
};
uniform Light light;
uniform sampler2D inSampler;
uniform sampler2D inShadowMap;
smooth in vec3 pass_Normal;
smooth in vec3 pass_Position;
smooth in vec2 TexCoord;
smooth in vec4 lightspace_Position;
out vec4 out_Color;
float CalcShadowFactor(vec4 lightspace_Position){
vec3 ProjectionCoords = lightspace_Position.xyz / lightspace_Position.w;
vec2 UVCoords;
UVCoords.x = 0.5 * ProjectionCoords.x + 0.5;
UVCoords.y = 0.5 * ProjectionCoords.y + 0.5;
float Depth = texture(inShadowMap, UVCoords).x;
if(Depth < (ProjectionCoords.z + 0.001)) return 0.5;
else return 1.0;
}
void main(void){
vec3 Normal = normalize(pass_Normal);
vec3 light_Direction = -normalize(light.direction);
vec3 camera_Direction = normalize(-pass_Position);
vec3 half_vector = normalize(camera_Direction + light_Direction);
float diffuse = max(0.2, dot(Normal, light_Direction));
vec3 temp_Color = diffuse * vec3(1.0);
float specular = max( 0.0, dot( Normal, half_vector) );
float shadowFactor = CalcShadowFactor(lightspace_Position);
if(diffuse != 0 && shadowFactor > 0.5){
float fspecular = pow(specular, 128.0);
temp_Color += fspecular;
}
out_Color = vec4(shadowFactor * texture(inSampler, TexCoord).xyz * temp_Color, 1.0);
}
Một trong những vấn đề là tự đổ bóng như bạn có thể thấy trong hình, thùng có bóng của chính nó. Những gì tôi đã thử là cho phép bù đa giác (tức là glEnable (POLYGON_OFFSET_FILL), glPolygon Offerset (GLfloat, GLfloat)) nhưng nó không thay đổi nhiều. Như bạn thấy trong shader mảnh, tôi đã đặt giá trị offset tĩnh là 0,001 nhưng tôi phải thay đổi giá trị tùy thuộc vào khoảng cách của ánh sáng để có được hiệu ứng mong muốn hơn, không tiện dụng lắm. Tôi cũng đã thử sử dụng loại bỏ mặt trước khi kết xuất với bộ đệm khung, điều đó cũng không thay đổi nhiều.
Vấn đề khác là các pixel bên ngoài chế độ xem của Light bị mờ. Đối tượng duy nhất được cho là có thể tạo bóng là cái thùng. Tôi đoán tôi nên chọn phép chiếu và xem ma trận phù hợp hơn, nhưng tôi không chắc làm thế nào để làm điều đó. Một số thực tiễn phổ biến, tôi nên chọn một hình chiếu chính tả là gì?
Từ việc loay hoay một chút, tôi hiểu rằng những vấn đề này không phải là chuyện nhỏ. Có ai có bất kỳ dễ dàng để thực hiện các giải pháp cho những vấn đề này. Bạn có thể cho tôi một số lời khuyên bổ sung?
Xin hỏi tôi nếu bạn cần thêm thông tin về mã của tôi.
Dưới đây là một so sánh có và không có bản đồ bóng của cận cảnh thùng. Các bóng tự nhìn thấy rõ hơn.