2016-09-02 5 views
1

가벼운 공간으로 변환하기 위해 화면 공간 픽셀 (지연 HLSL 셰이더에서 제공)을 얻으려고 노력하고 있습니다. 내 렌더링이 깊이 버퍼를 바둑판 식으로 배열하는 것처럼 보이는 결과는 놀랍습니다.DirectX 섀도우 맵 위치에 픽셀 위치를 변환하면 이상한 기와 결과가 생깁니다.

중요하게도 장면 카메라 (또는 눈)와 렌더링되는 빛이 같은 위치에서 시작됩니다. RGB 각각이 (명백하게 올바른) 결과를 얻을 수로

float3 eye = Eye; 
float4 position = { 
    IN.texCoord.x * 2 - 1, 
    (1 - IN.texCoord.y) * 2 - 1, 
    zbuffer.r, 
    1 
}; 
float4 hposition = mul(position, EyeViewProjectionInverse); 
position = float4(hposition.xyz/hposition.w, hposition.w); 
float3 eyeDirection = normalize(eye - position.xyz); 

결과는 XYZ 위치를 렌더링 올바른 것으로 보인다 : 첫째

는, I는 이하의 코드를 이용하여 화소의 세계 위치를 추출

Correctly rendered XYZ

빨간색 구성 요소는 X가 오른쪽으로 이동하면 올바르게 출력되고 파란색은 Z가 앞으로 이동하는 것으로 보입니다. 지면이 Y 축보다 약간 아래쪽에 있으므로 Y 인자도 정확합니다.

다음 (그리고 나는 확실히 미치지 않을 것이다), 나는 원래 깊이 버퍼를 출력하기로 결정했다. 일반적으로 이라는 Texture2D의 깊이 버퍼를 입력으로 쉐이더에 전달합니다. 그러나,이 경우, I는 적절한 위치로 다시 오프셋 및 눈의 뷰 프로젝션 행렬을 곱하여 화소 변환을 취소하려고하면 (이는 물론 정확한보고 결과를 산출

float4 cpos = mul(position, EyeViewProjection); 
cpos.xyz = cpos.xyz/cpos.w; 
cpos.x = cpos.x * 0.5f + 0.5f; 
cpos.y = 1 - (cpos.y * 0.5f + 0.5f); 
float camera_depth = pow(DepthMap.Sample(Sampler, cpos.xy).r, 100); // Power 100 just to visualize the map since scales are really tiny 
return float4(camera_depth, camera_depth, camera_depth, 1); 

I 비록 Z 값에 대해 100 % 확신하지 못함). 내가 픽셀의 세계를 변환하는 동일한 코드를 사용할 수 있습니다, 그래서 이론적으로

Reinterpreting XYZ back to ZBuffer space

: 또한 내가 더 깊이 정보를 (라이브 비교를 시도 할 때이 작업이 완료되지 않음) 시각화 결과가 지수했습니다 있습니다 빛의 시야 - 투영 행렬을 곱하여 빛의 위치로 이동합니다. 옳은?

float4 lpos = mul(position, ShadowLightViewProjection[0]); 
lpos.xyz = lpos.xyz/lpos.w; 
lpos.x = lpos.x * 0.5f + 0.5f; 
lpos.y = 1 - (lpos.y * 0.5f + 0.5f); 
float shadow_map_depth = pow(ShadowLightMap[0].Sample(Sampler, lpos.xy).r, 100); // Power 100 just to visualize the map since scales are really tiny 
return float4(shadow_map_depth, shadow_map_depth, shadow_map_depth, 1); 

을 그리고 여기 결과입니다 : 여기에 내가 시도 무엇

Broken light space

그리고 또 그것이 세계에 매핑 얼마나 더 잘 보여주기 위해 '

Broken light space #2

내가 돈 여기서 무슨 일이 벌어지고 있는지 이해해야합니다. 그것이 투영 행렬과 관련이 있을지 모르지만, 나는 무엇이 일어나고 있는지 확실히 알기 위해 수학에 능숙하지 않습니다. 여러 맵 크기를 시도 했으므로 라이트 맵의 너비/높이가 아니며 투영 행렬은 FOV와 종횡비를 사용하여 절대 너비/높이를 입력하지 않고 계산됩니다.

const auto ys = std::tan((T)1.57079632679f - (fov/(T)2.0)); 
    const auto xs = ys/aspect; 
    const auto& zf = view_far; 
    const auto& zn = view_near; 
    const auto zfn = zf - zn; 

    row1(xs, 0, 0, 0); 
    row2(0, ys, 0, 0); 
    row3(0, 0, zf/zfn, 1); 
    row4(0, 0, -zn * zf/zfn, 0); 
    return *this; 

여기 손실에 완전히 해요 :

마지막으로, 여기 (눈과 빛에 모두 사용) 내 관점 행렬이 계산되는 방법을 보여주는 몇 가지 C++ 코드입니다. 모든 지침이나 권장 사항은 크게 감사하겠습니다!

EDIT - 나는 또한 바둑판 식으로 배열 한 이미지가 거꾸로되어있는 것처럼 말했습니다. 눈 텍스처 공간으로 다시 가져와야하기 때문에 이상합니다.

답변

1

나는 여기 저기에 약간의 조정과 고정을했다. 궁극적으로, 가장 큰 문제는 예기치 않게 전 환된 매트릭스였습니다. 행렬이 어떻게 바뀌 었는지에 관해서는 약간 복잡합니다.하지만 그것이 왜 뒤집 혔을까요. 또한 D32 깊이 버퍼로 변경했는데 (W32를 포함하여) W로 분할 된 모든 위치가 W를 포함한 모든 구성 요소에 영향을 미치는지 확인했습니다.

그래서 같은 코드는 : 더 그림자 맵처럼 보이기 시작이야,이 모든 미세 조정 후 hposition = hposition/hposition.w

: hposition.xyz = hposition.xyz/hposition.w 이되었다.

Oh 및 전치 행렬은 빛의 ViewProjection입니다.