Sau khi thay đổi bộ hiển thị trả lại hiện tại của tôi để sử dụng logarithmic depth buffer Tôi không thể làm việc được, trong cuộc đời của tôi, cách tái tạo chiều sâu không gian thế giới từ các giá trị bộ đệm độ sâu.Vị trí không gian thế giới từ bộ đệm độ sâu logarit
Khi tôi có độ sâu z/w mặc định OpenGL được viết, tôi có thể dễ dàng tính toán giá trị này bằng cách chuyển từ không gian cửa sổ sang không gian NDC rồi thực hiện phép biến đổi phối cảnh nghịch đảo.
tôi đã làm tất cả điều này trong lần thứ hai vượt qua đoạn đổ bóng:
uniform sampler2D depth_tex;
uniform mat4 inv_view_proj_mat;
in vec2 uv_f;
vec3 reconstruct_pos(){
float z = texture(depth_tex, uv_f).r;
vec4 pos = vec4(uv_f, z, 1.0) * 2.0 - 1.0;
pos = inv_view_proj_mat * pos;
return pos.xyz/pos.w;
}
và nhận một kết quả trông khá chính xác:
Nhưng bây giờ con đường dẫn đến một giá trị đơn giản z
là không dễ dàng như vậy (dường như không quá khó).
shader My đỉnh cho pass đầu tiên của tôi với độ sâu log:
#version 330 core
#extension GL_ARB_shading_language_420pack : require
layout(location = 0) in vec3 pos;
layout(location = 1) in vec2 uv;
uniform mat4 mvp_mat;
uniform float FC;
out vec2 uv_f;
out float logz_f;
out float FC_2_f;
void main(){
gl_Position = mvp_mat * vec4(pos, 1.0);
logz_f = 1.0 + gl_Position.w;
gl_Position.z = (log2(max(1e-6, logz_f)) * FC - 1.0) * gl_Position.w;
FC_2_f = FC * 0.5;
}
Và shader mảnh của tôi:
#version 330 core
#extension GL_ARB_shading_language_420pack : require
// other uniforms and output variables
in vec2 uv_f;
in float FC_2_f;
void main(){
gl_FragDepth = log2(logz_f) * FC_2_f;
}
Tôi đã thử một vài phương pháp khác nhau để lấy lại z-position một cách chính xác, tất cả đều thất bại.
Nếu tôi xác định lại tôi reconstruct_pos
ở đèo thứ hai là:
vec3 reconstruct_pos(){
vec4 pos = vec4(uv_f, get_depth(), 1.0) * 2.0 - 1.0;
pos = inv_view_proj_mat * pos;
return pos.xyz/pos.w;
}
Đây là nỗ lực hiện tại của tôi ở xây dựng lại Z:
uniform float FC;
float get_depth(){
float log2logz_FC_2 = texture(depth_tex, uv_f).r;
float logz = pow(2, log2logz_FC_2/(FC * 0.5));
float pos_z = log2(max(1e-6, logz)) * FC - 1.0; // pos.z
return pos_z;
}
Giải thích:
log2logz_FC_2
: giá trị bằng văn bản vào bộ đệm độ sâu, do đó, log2(1.0 + gl_Position.w) * (FC/2)
logz
: chỉ cần 1.0 + gl_Position.w
pos_z
: giá trị của gl_Position.z
trước viễn cảnh chia
giá trị trả về: gl_Position.z
Tất nhiên, đó chỉ là làm việc của tôi. Tôi không chắc chắn những gì các giá trị này thực sự giữ cuối cùng, bởi vì tôi nghĩ rằng tôi đã screwed lên một số các toán học hoặc không chính xác hiểu các biến đổi đang xảy ra.
Cách chính xác để có được vị trí Z không gian thế giới của tôi từ bộ đệm độ sâu logarit này là gì?