2014-09-27 7 views
3

나는 스포트라이트 그림자 맵핑을 관리하는 3D 어플리케이션을 코딩했다. 이렇게하려면 고전적인 그림자 매핑 기법을 사용합니다 (첫 번째 렌더링 패스에서 깊이 텍스처를 채 웁니다. 두 번째 렌더링 패스에서 빛으로부터 첫 번째 오 클 루더까지의 거리를 비교하고 빛에서 정점 위치까지의 거리를 비교하여 내 조각이 그림자에 있거나 없는지). 나는 기능 'textureProjOffset'를 사용 PCF 그림자 매핑 기법을 사용하여이 예에서큐브 맵 (OpenGL/GLSL)을 사용하여 점 광원으로 부드러운 그림자를 만들 수 있습니까?

enter image description here

:

여기에 스크린 샷 (스포트 라이트/2D 깊이 텍스처 그림자 매핑)입니다.

샘플러를 사용 : HARD 그림자

sampler2DShadow Shadow2DSampler[MAX_LIGHTS_COUNT]; 

: PCF 부드러운 그림자를 들어

shadowFactor = textureProj(Shadow2DSampler[idx], ShadowCoords[idx]); 

:

나는 또한이 여기 내 프레 그먼트 쉐이더의 코드 조각입니다 기본 큐브 맵 쉐도우 매핑을 관리하여 현재 점등에 적용된 무 지향성 쉐도우 매핑을 관리합니다. 첫 번째 렌더링 패스에서이 작업을 수행하려면 기하학 셰이더를 사용하여 6 개의 그림자 절두체가 제공하는 투영 및 뷰 행렬을 모두 전달합니다 (모두 한 번에 전달 함).이 시간과 6 개의 별도 텍스처를 채우기 위해 conciming하는 기법과 다릅니다. 렌더링 상태). 당신이 볼 수 있듯이

enter image description here

, 그것은 단지 HARD 매핑의 그림자 :

여기에 스크린 샷 (스포트 라이트/큐브 깊이 텍스처 그림자 매핑)입니다. 큐브 맵에 인코딩 된 심도 값을 복구하려면 이번에는 'texture'함수를 사용해야합니다 ('samplerCube'및 'samplerCubeShadow'에는 textureProj가 없습니다). 다음으로, 나는 빛의 위치와 월드 공간의 정점 위치 사이의 거리를 계산 한 다음 텍스처에 포함 된 깊이 값이 이미 클립 공간에 있으므로 클립 공간으로 변환해야합니다.

샘플러를 사용 :

float ConvertDistToClipSpace(vec3 lightDir_ws) 
{ 
    vec3 AbsVec = abs(lightDir_ws); 
    float LocalZcomp = max(AbsVec.x, max(AbsVec.y, AbsVec.z)); 

    float NormZComp = (NearFar.y + NearFar.x)/(NearFar.y - NearFar.x) 
     - (2.0f * NearFar.y * NearFar.x)/(LocalZcomp * NearFar.y - NearFar.x); 

    return ((NormZComp + 1) * 0.5f); 
} 

float GetBiased_Cube_Hard_ShadowFactor(vec3 vertexPosition_ws, int idx) 
{ 
    vec3 lightToVertexDir_ws = vertexPosition_ws - LightPos_ws.xyz; 
    float LightToVertexClipDist = ConvertDistToClipSpace(lightToVertexDir_ws); 

    float LightToOccluderClipDist = texture(
     ShadowCubeSampler[idx], vec4(lightToVertexDir_ws, LightToVertexClipDist)); 

    if (LightToOccluderClipDist < LightToVertexClipDist) 
     return (0.0f); 
    return (1.0f); 
} 

그리고 알고, 무엇을 PCF SOFT에 대해 : HARD 그림자

samplerCubeShadow ShadowCubeSampler[MAX_LIGHTS_COUNT]; 

여기

과정을 볼 수있는 프레 그먼트 쉐이더의 코드 조각을이다 큐브 맵을 사용하는 그림자? 나는 약간의 연구를하고 분명히 간단한 2D 텍스처를 사용하고 fragment shader에서 키워드 'sampler2DShadow'를 사용하는 것처럼 텍스처 오프셋을 복구하는 함수가 존재하지 않습니다. 내가 잘못 ? (나는 그렇게 바란다!). 나는 6 개 별도의 텍스처를 사용해야합니다 오프셋 질감 (그래서 '의 배열 sampler2DShadow를 복구하기 위해, 분명히

:

은 내가 (이 큐브 맵과 모든 솔루션을 존재하지 않는 경우 물론) 솔루션을 생각 '크기가 6이고'samplerCubeShadow '가 아님). 그래서 나는 똑같이 균일 한 matrix4x4 어레이를 사용하여 첫 번째 경우에서 스포트라이트 섀도우 매핑과 마찬가지로 밝은 공간에서의 세계 표현을 재현합니다.그리고 나서 6 텍스쳐에 'textureProjOffset'메쏘드를 사용할 것입니다.

그래서, 어떻게 생각하십니까? 큐브 맵을 사용하여 PCF 부드러운 그림자를 만들 수 있습니까? 그렇지 않은 경우 내 해결책이 맞습니까? 'samplerCube'또는 'samplerCubeShadow'를 사용하여 'textureProjOffset'과 같은 함수를 사용할 수 있습니까? 아니면 대안이 있습니까?

미리 도움 주셔서 감사합니다.

답변

2

큐브 맵의 PCF 부드러운 그림자를 얻으려면 작은 오프셋을 사용하여 텍스처를 여러 번 쿼리해야합니다. 이 방법은 예를 들어 GPU Gems article (12.4)에 설명되어 있습니다.

+0

답변 해 주셔서 감사합니다. 안녕. – user1364743

+3

최신 AMD 및 NV 드라이버에서 필터에'samplerCubeShadow'와'GL_LINEAR'을 사용하면 2x2 PCF가 자동으로 수행됩니다. 2x2 창은 꽤 작기 때문에 효과적인 창 크기를 늘리기 위해 하드웨어 PCF와 몇 가지 오프셋을 결합해야합니다. 이 기사는 나이 때문에 2x2 PCF를 수행하는 하드웨어 기능을 활용하지는 않지만 일반적으로 어떻게 문제에 접근해야 하는지를 설명합니다. 4x4 PCF는 16 개가 아닌 4 개 조회를 사용하여 구현할 수 있습니다. –