본문 바로가기
DirectX11/정보정리

[DirectX11] 혼합

by 마두식 2023. 1. 5.
반응형

※  아래의 내용들은 DirectX 11을 이용한 3D 게임 프로그래밍 입문 책의 내용을 바탕으로 작성된 것입니다.

 

9장 혼합
  • 혼합공식(9.1절 393p)

-  현재 래스터화 하는 픽셀을 후면 버퍼에 이미 래스터화되어 있는 픽셀과 섞는(결합하는) 것을 혼합 기법이라고 한다.

-  알파 성분의 혼합은 RGB 성분들의 혼합에 비해 훨씬 덜 쓰인다.

=>  후면 버퍼의 알파 값들이 별로 중요하지 않기 때문.
=>  후면 버퍼의 알파 성분은 대상 알파 값을 필요로 하는 일부 알고리즘에서만 중요하다.

 

  • 혼합 연산(9.2절 394p)
  • 혼합 계수(9.3절 394p)

 

  • 혼합 상태(9.4절 396p)

-  앞에서 배운 혼합 연산자, 혼합 계수 등의 혼합 설정들은 렌터 상태의 하나인 혼합 상태를 나타내는 ID3D11BlendState 인터페이스로 제어한다.

=>  이 인터페이스를 얻으려면 D3D11_BLEND_DESC 구조체를 채우고 ID3D11Device::CreateBlendState 메서드를 호출해야 한다.


-  생성된 혼합 상태 객체는 OMSetBlendState 함수를 이용해 출력 병합기 단계에 묶어야 한다.

-  혼합을 위해서는 픽셀마다 추가 작업이 필요하므로, 오직 필요할 때에만 혼합을 활성화하고 필요하지 않을 때는 꺼야 한다.

=>  OMSetBlendState 함수의 첫 번째 매개변수를 널 값을 지정하면 기본 혼합 상태(혼합이 비활성화됨)가 적용된다.


-  다른 렌더 상태 인터페이스와 마찬가지로, 필요한 혼합 상태들을 응용 프로그램 초기화 시점에 모두 생성해두고 필요할 때마다 전환해서 사용하는 것이 바람직하다.

=>  혼합 상태 객체를 효과 파일에서 정의하고 설정하는 것도 가능하다.

 

  • 예제(9.5절) - 순백은 없다(9.5.1절 400p)

-  원본 픽셀이 대상 픽셀을 덮어쓰거나 섞이는 일 없이 대상 픽셀이 그대로 유지되게 하려면?

=>  이를테면 렌더링 결과를 깊이ㆍ스텐실 버퍼에만 기록하고 후면 버퍼에는 기록하지 않고자 할 때 유용한 방법이다.
==>  원본 픽셀의 혼합 계수를 D3D11_BLEND_ZERO, 대상 혼합 계수를 D3D11_BLEND_ONE으로 설정하고 혼합 연산자는 D3D11_BLEND_OP_ADD로 설정한다.
==>  D3D11_RENDER_TARGET_BLEND_DESC 구조체의 RenderTargetWriteMask 멤버를 0으로 설정해서 어떤 색상 채널에도 값이 기록되지 않게 해도 같은 효과를 얻을 수 있다.

 

  • 예제(9.5절) - 가산ㆍ감산 혼합(9.5.2절 401p)

-  원본 픽셀을 대상 픽셀에 더하는 혼합 방식

  • 예제(9.5절) - 승산 혼합(9.5.3절 402p)

-  대상 픽셀에 원본 픽셀을 성분별로 곱하는 혼합 방식

  • 예제(9.5절) -  투명도(9.5.4절 402p)

-  원본 픽셀과 대상 픽셀을 원본 픽셀의 불투명도에 비례해서 혼합하는 방식

 

-  물체들을 그리는 순서가 중요하다. 투명 물체가 있는 장면을 그릴 때 흔히 쓰이는 규칙은 아래와 같다.

1.  혼합을 사용하지 않는 물체를 먼저 그린다.
2.  그런 다음, 혼합을 사용하는 물체들을 카메라와의 거리를 기준으로 정렬한다
3.  물체들을 뒤에서 앞의 순서로 그린다.(카메라에서 먼 것부터 그리는 순서)

=>  3번의 이유는, 각 물체가 부분적으로 뒤에 있는 물체들과 혼합되기 때문이다.
=>  9.5.1절의 혼합 방법은 원본 픽셀이 후면 버퍼에 아예 그려지지 않으므로 그리기 순서가 중요하지 않다.


-  9.5.2, 9.5.3절 혼합 방법 모두 혼합을 사용하지 않는 물체들을 먼저 그리고, 혼합을 사용하는 물체를 나중에 그린다.

=>  혼합 없는 기하구조를 후면 버퍼에 모두 깔아둔 후에 혼합을 시작해야 하기 때문이다.
=>  단, 혼합 사용 물체들을 따로 정렬할 필요는 없다. 혼합 연산들이 교환법칙을 지원하기 때문이다.
==>  즉, 후면 버퍼에 있는 픽셀의 색상이 B인 상태에서 혼합을 시작해서 그 픽셀에 대해 가산이나 감산, 승산 혼합을 n회 수행한다고 할 때, 연산들을 어떤 순서로 수행하든 결과는 같다.

 

  • 예제(9.5절) - 혼합과 깊이 버퍼(9.5.5절 404p)

-  가산ㆍ감산ㆍ승산 혼합에서 발생하는 깊이 판정 관련 문제점

=>  물체들을 뒤에서 앞으로 정렬해서 그리지 않는 한 어떤 물체가 이미 그려진 다른 물체 뒤에 가려지며, 해당 픽셀 단편들이 깊이 판정을 통과하지 못해서 혼합 단계까지 가지 못하고 폐기된다.
==>  혼합의 의도가 무산된다.
==>  혼합 할 물체들을 렌더링 하는 동안에는 깊이 판정이 일어나지 않게 해야한다.


-  깊이 판정을 피하는 방법은 깊이 쓰기(depth write; 깊이 버퍼에 값을 기록하는 것)를 비활성화하는 것이다.

=>  혼합 할 물체에 대해서만 깊이 쓰기를 비활성화 해야한다.


-  깊이 읽기와 깊이 판정은 여전히 활성화 한다.

=>  그래야 비혼합 기하구조(혼합 사용 기하구조보다 먼저 그려진 것들)가 여전히 그 뒤에 있는 혼합된 기하구조를 가릴 것이기 때문이다.

 

  • 알파 채널(9.6절 405p)

-  원본의 알파 성분을 RGB 성분 혼합에 사용해서 투명도를 제어할 수 있음

=>  혼합 공식에 쓰이는 원본 픽셀 색상은 픽셀 셰이더가 출력한 것이다.

 

  • 픽셀 자르기(9.7절 407p)

-  원본 픽셀을 더 이상의 처리 없이 완전히 잘라내야(폐기) 할 때가 있다.

=>  HLSL의 내장 명령인 clip(x) 함수를 이용하면 된다.
==>  픽셀 셰이더에서만 호출 가능한 이 함수는 x<0 이면 현재 픽셀을 완전히 폐기해서 더 이상의 처리가 일어나지 않게 한다.
==>  clip() 함수를 최대한 일찍 수행하게 하면, 셰이더를 일찍 벗어남으로써 코드의 나머지 부분을 수행할 필요가 없으므로 성능 향상에 도움이 된다.
==>  완전히 불투명하거나 완전히 투명한 픽셀들을 렌더링할 때 유용하다.
ex)  철망 텍스처(그림 9.9)

=>  혼합을 이용해도 같은 효과를 얻을 수 있지만, 이 방법이 더 효율적이다.
=>  그리기 순서가 결과에 영향을 미치지 않는다.
=>  필터링 때문에 알파 채널이 약간 뭉개질 수 있으므로 알파 성분을 비교할 때 판정에 약간의 여유를 두어야 한다.
ex)  알파 값이 정확히 0인 픽셀들을 폐기할 것이 아니라, 0에 어느정도 가까운 픽셀들을 폐기해야 한다.

 

  • 안개(9.8절 410p)

-  파핑(popping) 현상

=>  절두체의 먼 평면 뒤에 있던 물체가 카메라의 이동에 따라 절두체 안으로 들어오면서 갑자기 화면으로 '튀어 나오는(popping)' 것을 말한다.
=>  먼 거리에 안개를 깔아 두면 파핑이 가려진다.
=>  게임 속 날씨가 맑다고 해도 먼 거리에 약간의 안개를 포함시키는 것이 좋다.
==>  맑은 날이라고 해도 지평선 부근의 산처럼 멀리 있는 물체는 흐릿해 보이기 때문이다.(깊이에 비례해서 선명함이 줄어든다)
===>  안개 효과는 이러한 대기 원근(atmospheric perspective) 현상을 흉내 내기에 적합하다.

 

  • HLSL의 unroll, loop

-  [Attribute] for(Initializer; 조건부; 반복기) {}   HLSL의 반복문에서 앞의 Attribute에 들어갈 수 있는 키워드


-  unroll

=>  반복을 지원하지 않는 모델에서는 반복할 내용을 반복 회수만큼 전개(unroll)해서 컴파일 하게 된다.

 

-  loop

=>  암시적으로 unroll 된 반복문을 명시적으로 반복문으로 실행되게 할 수 있다.
ex) for(int i = 0; i<5; ++i) 와 같은 반복문은 셰이더 컴파일러가 컴파일 시점에 최적화 한다. 즉 반복문이 아니라 그냥 반복문 내부 내용을 5번 풀어 써버리는 것[unroll]. loop 키워드를 추가하면 이러한 상황에 unroll 하지않고 반복문으로 동작하게 만들 수 있다.
=>  어떤 경우에 필요할지는 잘 모르겠음.

 

 


 

 

 

틀린 부분이나 이상한 부분이 있으면 댓글로 편하게 지적해주세요.

감사합니다!

반응형

'DirectX11 > 정보정리' 카테고리의 다른 글

[DirectX11] 기하 셰이더  (0) 2023.01.25
[DirectX11] 스텐실 적용  (0) 2023.01.07
[DirectX11] 텍스처 적용  (2) 2022.11.29
[DirectX11] 조명  (0) 2022.11.23
[DirectX11] 효과 프레임워크  (0) 2022.11.08

댓글