2013-05-25 5 views
0

큐브 맵을 사용하여 점 광원에 대한 그림자를 만들려고합니다.OpenGL 그림자 큐브 맵 - 조회 문제

나는 (Pointers on modern OpenGL shadow cubemapping?, https://www.opengl.org/discussion_boards/showthread.php/169743-cubemap-shadows-for-pointlights, http://www.cg.tuwien.ac.at/courses/Realtime/repetitorium/2011/OmnidirShadows.pdf, ...) 도움이되는 다양한 튜토리얼을 발견했지만 여전히 큐브 맵 조회에 문제가 있습니다. (: GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE 형식) :

이 쉐이더는 큐브 맵 생성

//vertex shader 
#version 330 

uniform mat4 Model; 
uniform mat4 View; 
uniform mat4 Projection; 

in vec3 vertex; 

out vec3 vertexModel; 

void main() 
{  
    gl_Position = Projection * View * Model * vec4(vertex, 1.0); 
    vertexModel = vec3(Model * vec4(vertex, 1.0)); 
} 

//fragment shader 
#version 330 

uniform vec3 lightPosition; 
uniform float lightRange; 

out float fragDepth; 
out vec4 fragColor; 

in vec3 vertexModel; 

void main() 
{ 
    gl_FragDepth = length(lightPosition - vertexModel)/lightRange; 
    fragColor = vec4(1.0); 
} 

lightPosition 세계 공간에서 빛의 위치입니다, lightRange 빛의 투영 행렬의 zFar은 기본적이다.

생성 된 큐브 맵은 gDEBugger를 사용하여 응용 프로그램을 디버깅 할 때 잘 나타납니다. 메인 셰이더

그림자 조회는 :

float shadowValue(int i) 
{ 
    vec3 lookup_vector = vertexModel - lightPosition; 
    float dist = texture(shadowMap, lookup_vector).r; 

    float curr_fragment_dist_to_light = length(lookup_vector)/lightRange; 

    float result = 1.0; 
    if (dist < curr_fragment_dist_to_light) 
     result = 0.0; 
    return result; 

} 

이 함수의 결과 값 frum 광 계산 곱해진다. 문제는 항상 1.0을 반환한다는 것입니다.

내가 뭘 잘못하고 있는지 알 수 있습니까?

+0

당신이 그 영향을 미치는지 만 볼'dist' 또는'curr_fragment_dist_to_light'을 반환 노력이 당신의 장면? – Grimmy

+0

예. 'curr_fragment_dist_to_light'는 좋았습니다 - 빛으로부터 멀어 질수록 커졌습니다. Thre 문제는'dist' - 큐브 맵 검색입니다. 항상 1.0 (또는 적어도 매우 높은 값)이며 항상 상수입니다. 생성 된 그림자지도는 다음과 같습니다. [http://oi40.tinypic.com/6gcwte.jpg](http://oi40.tinypic.com/6gcwte.jpg) (스크린 샷을 뒤에서 도려 내기로 전환했습니다. 일반적으로 그림자 맵을 앞면 컬링으로 렌더링합니다.) –

답변

0

lookup_vector의 y 좌표를 반전시켜야합니다. y- 좌표 점을 위쪽으로 렌더링하지만 OpenGL 텍스처를 렌더링 할 때는 y를 아래쪽으로 향하게합니다. 장면은 대칭, 그래서 당신의 질감은 처음에는 정확한 것 같다하지만 반영 할 필요가 - 아니면 그냥 돌아서 당신의 lookup_vector :

vec3 new_vec = vec3(lookup_vector .x, -lookup_vector .y, lookup_vector .z); 

그럼 그냥 당신이 이미했던 것처럼 당신의 그림자 맵에 렌더링 거리를 찾아 :

float dist = texture(shadowMap, new_vec); 

가 테스트 할 깊이 다음과 같이 계산한다 :

vec3 abs_vec = abs(new_vec); 
float local_z_comp = max(abs_vec .x, max(abs_vec .y, abs_vec .z)); 
float norm_z_comp = (z_far + z_near)/
    (z_far - z_near) - (2 * z_far * z_near)/(z_far - z_near)/local_z_comp; 
float curr_fragment_dist_to_light = (norm_z_comp + 1.0) * 0.5; 

z_farlightRange이며, z_near은 가까운 평면에 해당합니다.

float result = 1.0; 
if (dist < curr_fragment_dist_to_light) 
    result = 0.0; 
return result; 

나는이 질문에 대한 대답에서 이러한 계산을 기반으로 : 마지막으로, 당신의 결과를 반환 Cubemap shadow mapping not working

+0

편집 제안에 응답 할 수 없기 때문에 samplerCubeShadow 대신 samplerCube를 사용합니다. SamplerCube 조회는 3 요소 벡터 (float dist = texture (shadowMap, new_vec);)를 사용합니다. –