2013-08-01 10 views
1

제 그래픽 엔진을위한 그림자 맵 쉐이더를 작성했습니다. 나는이 자습서를 따라 갔다 : Part 1 그리고 그 다음 부분.이상한 그림자 맵 동작은 좌표를 올바르게 계산합니까?

불행히도, 내가 얻은 결과는 꽤 떨어져 있습니다. 다음은 screenshots입니다. 그들은 내 장면이 정상적으로 보이는지, 그림자가있는 장면과 그림자 맵의 내용을 보여줍니다 (중심부에있는 흰 물건은 무시하십시오. 오리의 기하학적 의미입니다).

내 프래그먼트 쉐이더에 음영지도를 샘플링 좌표를 산출하는 방법이있다 다음 lightSpacePosition 벡터를 계산한다

float calcShadowFactor(vec4 lightSpacePosition) { 
    vec3 projCoords = lightSpacePosition.xyz/lightSpacePosition.w; 
    vec2 uvCoords; 
    uvCoords.x = 0.5 * projCoords.x + 0.5; 
    uvCoords.y = 0.5 * projCoords.y + 0.5; 
    float z = 0.5 * projCoords.z + 0.5; 
    float depth = texture2D(shadowMapSampler, uvCoords).x; 
    if (depth < (z + 0.00001f)) 
     return 0.0f; 
    else 
     return 1.0f; 
} 

:

projectionMatrix * inverseLightTransformationMatrix 
    * modelTransformationMatrix * vertexPosition 

투영 행렬이다 :

[1.0f/(tan(fieldOfView/2) * (width/height)), 0.0f, 0.0f, 0.0f] 
[0.0f, 1.0f/(tan(fieldOfView/2), 0.0f, 0.0f] 
[0.0f, 0.0f, (-zNear - zFar)/(zNear - zFar), 2.0f * zFar * zNear/(zNear - zFar)] 
[0.0f, 0.0f, 1.0f, 0.0f] 

내 그림자 맵이 괜찮은 것처럼 보이고 렌더링 패스가 내 그림자 맵 패스로 lightSpacePosition 벡터. 그러나 나는 무엇이 잘못되었는지 알 수 없다.

+0

[0.0f로, (-zNear - zFar)/zRange, 2.0f * zFar * zNear/zRange] 단 3 개의 변수 ??? – Quonux

+0

float z = 0.5 * projCoords.z + 0.5; float해야합니다. z = projCoords.z – Quonux

+0

오, 내 잘못 - 내가 편집 할 것입니다. 그게 작동하지 않습니다. 그런 다음 모든 픽셀이 그림자/조명 테스트에서 이기고 점등됩니다. 어쨌든, 조금 혼란스러워. 스택 교환에서 다른 튜토리얼과 질문에서 발견 한 바이어스 행렬은 z 값과 동일하지만, 이미 이러한 깊이 값이 [0; 1]에 있거나 실제로 [-1; 1]에 있지 않아야하며 음수 부분이 잘립니다? –

답변

0

전적으로 이것을 이해할 수는 없지만 버그를 발견했습니다. 좌표를 NDC 공간으로 변환해야하고 그 다음에 행렬을 곱합니다. 내 그림자 좌표 계산은 이제 다음과 같습니다

mat4 biasMatrix = mat4(
    0.5f, 0.0f, 0.0f, 0.0f, 
    0.0f, 0.5f, 0.0f, 0.0f, 
    0.0f, 0.0f, 0.5f, 0.0f, 
    0.5f, 0.5f, 0.5f, 1.0f 
); 
vec4 shadowCoord0 = biasMatrix * light * vec4(vertexPosition, 1.0f); 
shadowCoord = shadowCoord0.xyz/shadowCoord0.w; 

light = projectionMatrix * inverseLightTransformationMatrix 
* modelTransformationMatrix 

지금 프래그먼트 쉐이더의 그림자 인자 계산이 비교적 간단입니다 :

float shadowFactor = 1.0f; 
if (texture(shadowMapSampler, shadowCoord.xy).z < shadowCoord.z - 0.0001f) 
    shadowFactor = 0.0f; 
+0

흠, 아직도 조금 벗어난 것 같다 ... http://www.youtube.com/watch?v=9ikvak87s2E&feature=youtu.be –

+0

그래 ... 두 계산이 모두 정확했다. NVIDIA 그래픽 드라이버를 최신 WHQL 버전에서 최신 베타 드라이버로 업데이트했는데 이제는 매력처럼 작동합니다. –