[DirectX 11] Screen Space Ambient Occlusion

2021. 12. 14. 03:02·Graphics

SSAO

Screen Space에서 화면에 보이는 오브젝트만 Ambient Occlusion을 통해 특정 점을 기준으로 구를 그려 한번씩 체크하여

다른 점을 발견하면 그 점에 대해 차폐됬다고 판단하여 어둡게 처리하는 방식.

Camera View 공간에서 Depth 값과 Normal 값을 이용하여 처리.

 

// SSAO Pass전 Depth Buffer 생성..
vout.Depth = float4(normalV, pin.PosV.z);

 

float4 SSAO_PS(VertexIn pin) : SV_Target
{
	
    float4 normalDepth = gDepthMap.SampleLevel(gSamBorderLinearPoint, pin.Tex, 0.0f);
    // View Space Normal
    float3 n = normalDepth.xyz;
    // View Space Position Z
    float pz = normalDepth.w;
    // View Space Position
    float3 p = (pz / pin.ToFarPlane.z) * pin.ToFarPlane;
    
    // Random Vector를 통한 임의의 Normal Map 설정..
	float3 randVec = 2.0f * gRandomVecMap.SampleLevel(gSamWrapLinerPoint, 4.0f * pin.Tex, 0.0f).rgb - 1.0f;

    float occlusionSum = 0.0f;
    
    [unroll]
    for (int i = 0; i < 14; ++i)
    {
    	// Reflect(반사)를 이용해 랜덤성을 증가..
        float3 offset = reflect(gOffsetVectors[i].xyz, randVec);

		// Offset Vector 와 Noraml의 내적을 구해서 부호를 구한다..
        float flip = sign(dot(offset, n));

		// 현재 위치에서 부터 차폐를 검사할 Vector를 구한다..
        // flip을 곱하여 반구 방향으로만 계산..
        float3 q = p + flip * gOcclusionRadius * offset;

		// 위에서 구한 Vector에 Projection과 Texture Space 행렬을 곱하여 좌표 구한다..
        float4 projQ = mul(gViewToTexSpace, float4(q, 1.0f));
        projQ /= projQ.w;
		
        // 위에서 구한 좌표에 해당하는 깊이값을 구하고 깊이값에 매칭되는 View Space 좌표를 구한다..
        float rz = gDepthMap.SampleLevel(gSamBorderLinearPoint, projQ.xy, 0.0f).w;
		
        
        float3 r = (rz / q.z) * q;

        float distZ = p.z - r.z;
        float dp = max(dot(n, normalize(r - p)), 0.0f);
        float occlusion = dp * OcclusionFunction(distZ);

        occlusionSum += occlusion;
    }
	
    // 차폐를 계산한 만큼 정규화..
    occlusionSum /= 14;

    float access = 1.0f - occlusionSum;

	// 차폐된 최종 결과물 극대화 시키기 위해 변환..
    return saturate(pow(access, 4.0f));
}

위와같이 SSAO Map을 뽑으면 노이즈 현상이 심하기 때문에 Blur 처리가 필요하다.

 

변경사항

1. Normal Map기준 Normal View 변환 놓친 부분 수정.

2. 최종 출력에 생기는 노이즈가 Blur 과정에서 문제가 있어 수치 변경.

수정 전 World View (Normal & Pos) GBuffer
수정 후 World View (Normal & Pos) GBuffer
수정 전 Blur 이전 상태
수정 전 Blur 이후 상태
SSAO 변경전

 

SSAO 변경 후

 

'Graphics' 카테고리의 다른 글

[DirectX 11] Skinning Mesh  (0) 2021.12.18
[DirectX 11] Normal Mapping  (0) 2021.12.18
[DirectX 11] Gamma Correction  (0) 2021.12.18
[DirectX 11] Deferred Rendering GBuffer  (0) 2021.12.14
[DirectX 11] Shadow Map  (0) 2021.12.14
'Graphics' 카테고리의 다른 글
  • [DirectX 11] Normal Mapping
  • [DirectX 11] Gamma Correction
  • [DirectX 11] Deferred Rendering GBuffer
  • [DirectX 11] Shadow Map
KyuHwang
KyuHwang
  • KyuHwang
    DirectX Engine
    KyuHwang
  • 전체
    오늘
    어제
    • 분류 전체보기 (50)
      • C++ (4)
      • CS (0)
      • Graphics (32)
      • DLL (2)
      • Shader (7)
      • Project (4)
      • ETC (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • YouTube
  • 공지사항

  • 인기 글

  • 태그

    DirectX 2D
    Directx11
    bc format
    Shader Macro
    Define Function
    Implicit Linking
    Order Independent Transparency
    Shader Reflection
    Project
    Explicit Linking
    Return Type Operator
    animation constraint
    Hash Code
    rigging chain
    Define Macro
    C ++
    nvtt
    texture block compression
    DLL Interface
    std::is_base_of
    Alpha Blending
    animation retargeting
    mobile format
    std::enable_if
    hlsl
    Shader Resource 관리
    shader
    Win API
    RunTime Compile Shader
    dll
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
KyuHwang
[DirectX 11] Screen Space Ambient Occlusion
상단으로

티스토리툴바