2016-11-02 1 views
7

logarithmic depth buffer을 사용하기 위해 현재 지연 렌더러를 변경 한 후, 내 인생에서 깊이 버퍼 값에서 월드 - 스페이스 깊이를 재구성하는 방법을 사용할 수 없습니다.로그 깊이 버퍼에서 월드 - 스페이스 위치

OpenGL의 기본 z/w 깊이를 썼을 때 윈도우 공간에서 NDC 공간으로 변환하여이 값을 쉽게 계산할 수 있었으며 역 투영 변환을 수행했습니다.

나는 모든 2 패스 프래그먼트 쉐이더에서 이런 짓을 :

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

그리고 내 조각 쉐이더 : I 올바르게 Z 위치를 다시 얻을 수있는 몇 가지 방법을 시도

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

, 모두 실패했습니다.

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

이 재구성 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; 
} 

는 설명 :

log2logz_FC_2 : 기록 된 값 깊이 버퍼로, 그래서 log2(1.0 + gl_Position.w) * (FC/2)

logz은 : 단순히

pos_z1.0 + gl_Position.w는 : 관점으로 나눔 전 gl_Position.z의 값은

반환 값 : 물론 gl_Position.z

, 그건 그냥 내 작업입니다. 나는 수학의 일부를 망쳐 놨거나 제대로 된 변환을 제대로 이해하지 못했기 때문에이 값들이 실제로 결국 무엇을 유지하는지 확신 할 수 없습니다.

이 로그 깊이 버퍼에서 월드 와이드 Z 위치를 얻는 올바른 방법은 무엇입니까?

답변

0

결국 나는이 모든 잘못에 대해 생각하고있었습니다. 로그 버퍼를 사용하여 세계 공간 위치를 다시 얻을 수있는 방법은 다음과 같습니다

  1. 텍스처
  2. 재구성 gl_Position에서 깊이를 검색합니다.

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

    내가 사용하던 때와 같이 (그러나 더 나은 정밀도) 나에게 동일한 결과를 제공합니다 :

  3. 선형화 재구성 깊이 승

여기 GLSL 내 구현의 세계 공간으로 변환 디폴트의 ​​OpenGL 깊이 버퍼