2016-11-02 9 views
7

logarithmic depth buffer का उपयोग करने के लिए मेरे वर्तमान स्थगित रेंडरर को बदलने के बाद, मैं अपने जीवन के लिए, गहराई बफर मूल्यों से विश्व-अंतरिक्ष गहराई को पुनर्निर्माण कैसे कर सकता हूं, काम नहीं कर सकता।लॉगरिदमिक गहराई बफर से विश्व-स्थान की स्थिति

जब मेरे पास ओपनजीएल डिफ़ॉल्ट जेड/डब्ल्यू गहराई लिखी गई थी तो मैं आसानी से विंडो-स्पेस से एनडीसी-स्पेस में बदलकर इस मान की गणना कर सकता था और फिर विपरीत परिप्रेक्ष्य परिवर्तन कर सकता था।

मैं सभी दूसरा पास टुकड़ा शेडर में ऐसा किया:

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; 
} 

और एक परिणाम है कि बहुत सही देखा है:

Cube rendered with correct world-space position reconstruction

लेकिन अब एक सरल z मूल्य के लिए सड़क है इतना आसान नहीं है (ऐसा प्रतीत नहीं होता है कि यह इतना कठिन होना चाहिए)।

लॉग गहराई के साथ मेरी पहली पारित करने के लिए मेरे शिखर शेडर:

#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; 
} 

और मेरे टुकड़ा शेडर:

#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; 
} 

मैं सही ढंग से z-स्थिति वापस पाने के लिए कुछ अलग दृष्टिकोण की कोशिश की है, सभी असफल

अगर मैं फिर से परिभाषित मेरी reconstruct_pos दूसरा पास में होने के लिए:

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; 
} 

यह पुनर्निर्माण जेड पर मेरे वर्तमान प्रयास है:

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; 
} 

व्याख्या:

log2logz_FC_2: लिखित मूल्य गहराई बफर करने के लिए, log2(1.0 + gl_Position.w) * (FC/2)

logz: बस 1.0 + gl_Position.w

pos_z: परिप्रेक्ष्य विभाजित पहले gl_Position.z का मूल्य

वापसी मान: gl_Position.z

बेशक

, कि बस अपना काम कर रहे है। मुझे यकीन नहीं है कि ये मूल्य वास्तव में अंत में क्या धारण करते हैं, क्योंकि मुझे लगता है कि मैंने कुछ गणित को खराब कर दिया है या परिवर्तनों को सही तरीके से समझ नहीं लिया है।

इस लॉगरिदमिक गहराई बफर से मेरी विश्व-स्थान जेड स्थिति प्राप्त करने का सही तरीका क्या है?

उत्तर

0

अंत में मैं इस सब गलत के बारे में जा रहा था। जिस तरह से एक लॉग बफर का उपयोग कर विश्व अंतरिक्ष स्थिति वापस पाने के लिए है:

  1. बनावट
  2. फिर से संगठित gl_Position से गहराई प्राप्त करें।डब्ल्यू
  3. Linearize पुनर्निर्मित गहराई
  4. दुनिया अंतरिक्ष में अनुवाद

यहाँ GLSL में मेरी कार्यान्वयन है:

in vec2 uv_f; 

uniform float nearz; 
uniform float farz; 

uniform mat4 inv_view_proj_mat; 

float linearize_depth(in float depth){ 
    float a = farz/(farz - nearz); 
    float b = farz * nearz/(nearz - farz); 
    return a + b/depth; 
} 

float reconstruct_depth(){ 
    float depth = texture(depth_tex, uv_f).r; 
    return pow(2.0, depth * log2(farz + 1.0)) - 1.0; 
} 

vec3 reconstruct_world_pos(){ 
    vec4 wpos = 
     inv_view_proj_mat * 
     (vec4(uv_f, linearize_depth(reconstruct_depth()), 1.0) * 2.0 - 1.0); 

    return wpos.xyz/wpos.w; 
} 

कौन सा मुझे (लेकिन बेहतर परिशुद्धता के साथ) एक ही परिणाम देता है के रूप में जब मैं उपयोग कर रहा था डिफ़ॉल्ट ओपनजीएल गहराई बफर।

संबंधित मुद्दे