2. 혼합
9.1 혼합 공식
9.2 혼합 연산
9.3 혼합 계수
9.4 혼합 상태
9.5 예제
9.6 알파 채널
9.7 픽셀 자르기
9.8 안개
3. • 혼합 기법
• 현재 래스터화하는 픽셀을 후면 버퍼에 래스터화되어 있는 픽셀과 섞는 기법
• 반투명 물체 렌더링
• 오른쪽 그림은 우선 지형과 상자를 그리고, 수면을 후면 버퍼에 그리되
혼합을 이용해서 렌더링
• 물 픽셀들이 후면 버퍼에 이미 있는 지형, 나무 상자 픽셀들과 섞여 땅과
상자가 물을 통해 보인다
• 혼합 기법을 이용해 물이나 유리 같은 반투명 물체 렌더링 가능
혼합
4. • 혼합의 기본
• 𝐶𝑠𝑟𝑐: 원본(source) 픽셀, 즉 현재 래스터화 중인 ij 번째 픽셀에 대해 픽셀 셰이더가 출력한 색상
• 𝐶𝑑𝑠𝑡: 대상(destination) 픽셀, 즉 현재 후면 버퍼에 있는 ij번째 픽셀의 색상
• 혼합을 사용하지 않으면 𝐶𝑠𝑟𝑐 가 𝐶𝑑𝑠𝑡를 덮어써서 후면 버퍼의 ij 픽셀의 새로운 색상이 된다.
• 혼합을 사용하면 𝐶𝑠𝑟𝑐와 𝐶𝑑𝑠𝑡를 혼합 공식에 따라 얻은 색상 C가 𝐶𝑑𝑠𝑡를 덮어쓴다.
• 혼합 공식
• Direct3D는 아래 공식을 이용해 원본 픽셀과 대상 픽셀 색상을 섞는다.
혼합 기본
5. • 혼합 계수(blend factor)
• 𝐹𝑠𝑟𝑐: 원본 혼합 계수
• 𝐹𝑑𝑠𝑡: 대상 혼합 계수
• 계수 값을 적절히 설정해 원본 픽셀과 대상 픽셀을 다양한 방식으로 혼합. 효과 연출.
• ⊗ 연산자: 색상 벡터들의 성분별 곱셈 (5.3.1)
• ⊞ 연산자: 이항 연산자 (뒤에 정의)
9.1 RGB 성분 혼합 공식
6. • 공식은 RGB 성분의 혼합 공식과 동일
• RGB 혼합과 다른 혼합 계수와 이항 연산자 ⊞ 사용 가능
• RGB와 알파를 분리함으로써 둘을 서로 다르게 처리할 수 있다.
• 참고: 알파 성분의 혼합은 RGB 성분의 혼합에 비해 훨씬 덜 쓰인다.
알파 성분 혼합 공식
7. • D3D11_BLEND_OP
• 알파 혼합 공식에도 동일한 연산자 사용 (RGB 혼합과 따로 선택할 수 있다)
• 예) RGB 성분은 더하되 알파 성분은 빼는 경우
9.2 혼합 연산의 이항 ⊞ 연산자
8. • 원본 혼합 계수와 대상 혼합 계수 조합으로 다양한 혼합 효과 생성 가능
• D3D11_BELND의 혼합 계수
• 𝐹𝑠𝑟𝑐과 𝐹𝑑𝑠𝑡 따로 적용 가능
• 아래 혼합 계수들은 모두 RGB 혼합에 적용되지만 _COLOR로 끝나는 계수들은 알파 성분 혼합에 사용 불가
9.3 혼합 계수
9. • 혼합 계수 색상 직접 지정
• 아래 두 혼합 계수의 r,g,b,a 값은 ID3D11DeivceContext::OMSetBlendState 메서드에서 직접 지정 가능
• OMSetBlendState 메서드는 혼합 상태 객체를 출력 병합기 단계에 묶는 메서드.
혼합 계수
D3D11_BLEND_FACTOR: 𝐹 = 𝑟, 𝑔, 𝑏 , 𝐹 = 𝑎
D3D11_BLEND_INV_FACTOR: 𝐹 = 1 − 𝑟, 1 − 𝑔, 1 − 𝑏 , 𝐹 = 1 − 𝑎
10. • 응용 프로그램에서는 혼합 상태(blend state)를 나타내는 ID3D11BlendState 인터페이스로 혼합 설정 제어
• ID3D11BlendState 인터페이스 생성
• ID3D11Device::CreateBlendState 메서드에 D3D11_BLEND_DESC 구조체를 전달해 호출
• pBlendStateDesc: 생성할 BlendState에 대한 D3D11_BLEND_DESC 구조체 포인터
• ppBlendState: 생성된 BlendState 인터페이스 반환
9.4 혼합 상태(1)
11. • D3D11_BLEND_DESC 구조체
• AlphaToCoverageEnable:
다중표본화 기법인 알파-포괄도(alpha-to-coverage) 변환 활성화. 11장 예제 참고
• IndependentBlendEnable:
True로 설정하면 각 렌더 대상마다 혼합을 개별적으로 수행 가능 (Direct3D 11에서는 최대 8개까지의 렌더 대상
에 동시 렌더링 가능)
• RenderTarget:
D3D11_RENDER_TARGET_BLEND_DESC 원소 8개 배열. IndependentBlendEnaable==false이면 모든 렌더 대상은
RenderTarget[0]을 혼합에 사용
9.4 혼합 상태(2)
12. • BOOL BlendEnable: 혼합 활성화 여부. 활성화하려면 TRUE
• SrcBlend: RGB 성분 원본 혼합 계수 𝐹
𝑠𝑟𝑐. D3D11_BLEND 열거형
• DestBlend: RGB 성분 대상 혼합 계수 𝐹𝑑𝑠𝑡. D3D11_BLEND 열거형
• BlendOp: RGB 성분 혼합 연산자. D3D11_BLEND_OP 열거형
• SrcBlendAlpha: 알파 성분 원본 혼합 계수 𝐹
𝑠𝑟𝑐. D3D11_BLEND 열거형
• DestBlendAlpha: 알파 성분 원본 혼합 계수 𝐹𝑑𝑠𝑡. D3D11_BLEND 열거형
• BlendOpAlpha: 알파 성분 혼합 연산자. D3D11_BLEND_OP 열거형
• RenderTargetWriteMask: 렌더 대상 쓰기 마스크(write mask)
9.4 혼합 상태(3)
D3D11_BLEND_TARGET_BLEND_DESC 구조체
13. • 렌더 대상 쓰기 마스크(RenderTargetWriteMask)에 지정할 수 있는 플래그
• 플래그 조합으로 후면 버퍼의 어떤 색상 채널에 기록할 것인지 설정.
• 예) D3D11_COLOR_WRITE_ENABLE_ALPHA 지정하면 혼합 결과가 알파 채널에만 기록
• 기본값은 D3D11_COLOR_WRITE_ENABLE_ALL
9.4 혼합 상태(4)
14. • ID33D11DeviceContext::OMSetBlendState
• 생성한 혼합 상태 객체를 출력 병합기 단계에 묶는다
• pBlendState: 장치에 적용할 혼합 상태 객체 포인터
• BlendFactor: float 값 4개 배열로 하나의 RGBA 색상 벡터를 정의.
D3D11_BLEND_FACTOR나 D3D11_BLEND_INV_BLEND_FACTOR 지정했을 때의 혼합 계수
• SampleMask: 다중표본화의 32개 표본을 각 비트값으로 활성화/비활성화.
일반적으로 어떤 표본도 비활성화 하지 않는 기본값 0xffffffff 사용
• 첫 번째 매개변수에 NULL 값 전달해서 호출하면 기본 혼합 상태(혼합 비활성화) 적용
혼합 상태 바인딩
15. • RGB 성분 혼합
• 원본 Alpha 값을 RGB 혼합 계수로 사용
• 대상 1-Alpha 값을 RGB 혼합 계수로 사용
• 연산자는 합 연산
• 알파 혼합
• 원본 알파 혼합 계수 1
• 대상 알파 혼합 계수 0
• 연산자는 합 연산
• BlendState 생성
• BlendState를 output merge stage에 bind
혼합 상태 설정 예시
16. • 원본 픽셀이 대상 픽셀을 덮어쓰거나 섞이는 일 없이 유지하고자 할 때
• 예) 렌더링 결과를 깊이,스텐실 버퍼에만 기록하고 후면 버퍼에는 기록하지 않고자 할 때
• 원본 혼합 계수: D3D11_BLEND_ZERO (=(0,0,0))
• 대상 혼합 계수: D3D11_BLEND_ONE (=(1,1,1))
• 혼합 연산자: D3D11_BLEND_OP_ADD
• D3D_RENDER_TARGET_BLEND_DESC 구조체의 RenderTargetWriteMask를 0으로 설정해도 같은 결과
9.5 예제(1) – No Color Write
17. • 원본 픽셀을 대상 픽셀에 더하고자 할 때
• 원본 혼합 계수: D3D11_BLEND_ONE
• 대상 혼합 계수: D3D11_BLEND_ONE
• 혼합 연산자: D3D11_BLEND_OP_ADD
9.5 예제(2) – 가산/감산 혼합
색들이 더해져서 더 밝은 이미지 생성
18. • 원본 픽셀을 대상 픽셀에서 빼고자 할 때
• 원본 혼합 계수: D3D11_BLEND_ONE
• 대상 혼합 계수: D3D11_BLEND_ONE
• 혼합 연산자: D3D11_BLEND_OP_SUBTRACT
9.5 예제(2) – 가산/감산 혼합
색상 성분들의 값이 줄어든 부분이 어두워진다.
ㅡ
ㅡ
19. • 원본 픽셀을 대상 픽셀에 곱하는 혼합
• 원본 혼합 계수: D3D11_BLEND_ZERO
• 대상 혼합 계수: D3D11_BLEND_SRC_COLOR
• 혼합 연산자: D3D11_BLEND_OP_ADD
9.5 예제(3) – 승산 혼합
원본 색상과 대상 색상을 곱한다.
20. • 원본 알파 성분 𝑎𝑠는 원본 픽셀의 불투명도(opacity). 1 − 𝑎𝑠는 투명도
• 원본 픽셀과 대상 픽셀을 원본 픽셀의 불투명도(알파 값)에 비례해서 혼합
• 원본 혼합 계수: D3D11_BLEND_SRC_ALPHA
• 대상 혼합 계수: D3D11_BLEND_INV_SRC_ALPHA
• 혼합 연산자: D3D11_BLEND_OP_ADD
• 예) 𝑎𝑠 = 0.25일 때, 위 혼합을 적용한 최종 색상은 원본 픽셀 색상의 25%와 대상 픽셀 색상의 75%를 결합한 것
• 이러한 혼합 방법을 이용해 반투명 물체를 그릴 수 있다.
9.5.4 투명도(1)
21. • 불투명도에 비례한 혼합으로 (반)투명한 물체를 그릴 때에는 그리는 순서 중요
• 혼합을 사용하지 않는 물체를 먼저 그린다.
• 이후 혼합을 사용하는 물체들을 카메라와의 거리를 기준으로 정렬
• 물체들을 뒤에서 앞의 순서로 그린다.
• 각 물체가 부분적으로 뒤에 있는 물체들과 혼합되기 때문에 뒤에서부터(카메라에서 먼 것부터) 그린다.
• 투명한 물체 뒤에 있는 모든 픽셀이 후면 버퍼에 미리 기록되어 있어야 한다.
• 참고: 가산/감산, 승산 혼합은 교환법칙이 성립되기 때문에 순서는 중요하지 않다.
9.5.4 투명도(2)
22. • 가산/감산/승산 혼합 적용시 렌더링 하는 동안 깊이 판정이 일어나지 않도록 한다.
• 예) 물체의 집합 S를 물체들의 색상을 더해 더 밝은 모습으로 만들기 위해 가산 혼합할 때,
깊이 판정을 적용할 경우 (물체들을 뒤에서 앞으로 정렬해서 그리지 않으면)
어떤 물체가 이미 그려진 다른 물체에 가려질 수 있고, 해당 픽셀이 깊이 판정을 통과하지 못해
혼합 단계까지 가지 못하고 폐기될 수 있다.
• 깊이 판정 피하기 위해 깊이 쓰기(depth write; 깊이 버퍼에 값을 기록하는 것)을 비활성화 한다.
• 이를 포함한 깊이 판정의 여러 가지 설정들은 다음 장에서 다룬다.
9.5.5 혼합과 깊이 버퍼
23. • 앞에서와 같이 알파 성분을 RGB 성분 혼합에 사용해서 투명도를 제어할 때,
• 예제 프레임워크 기본 효과의 픽셀 셰이더는 분산광 재질의 알파 성분을 출력 알파 성분으로 사용
• 즉, 투명도를 제어하는 것은 분산광 텍스처 맵에 담긴 알파 채널
• 이를 위해 Photoshop 같은 이미지 편집 툴에서 알파 채널을 추가
• 알파 채널을 지원하는 파일 형식(32비트 BMP, DDS 등)으로 저장
9.6 알파 채널(1)
24. • DXTex를 이용한 알파 채널 추가
• RGB 채널들로 된 색상 이미지를 DXTex에서 열고 알파 채널을 지원하는 형식으로 변환한다.
• Format -> Change Surface Format 선택
• 예제에서는 알파 채널을 지원하는 압축 형식인 D3DFMT_DXT5을 선택
• 알파 채널을 가진 압축된 텍스처가 생성
9.6 알파 채널(2) – DirectX 텍스처 도구(DXTex)
25. • 생성된 압축 텍스처의 알파 채널에 자료 로드
• File -> Open Onto Alpha Channel Of This Texture
• 알파 채널에 로드할 회색조 이미지를 선택
9.6 알파 채널(3) – DirectX 텍스처 도구(DXTex)
텍스처 이미지에 알파 채널을 삽입한 모습
26. • 원본 픽셀을 더 이상 처리 없이 완전히 잘라내야(폐기)해야 할 때 HLSL의 내장 명령인 clip(x) 함수 이용
• x < 0이면 현재 픽셀을 완전 폐기
• 픽셀 셰이더에서만 호출 가능
• 완전 불투명 또는 투명한 픽셀을 렌더링할 때 사용
• 오른쪽 텍스처와 그 알파 채널에서 알파 채널이
검정색인 부분은 clip 함수에 의해 폐기.
철망한 그려진다.
• 알파 채널이 철망에 해당하지 않는 픽셀들을 제외
시키는 (masking out) 역할을 한다.
9.7 픽셀 자르기(1)
27. • 현재 픽셀의 알파 성분이 0에 가까운 작은 값이면 픽셀이 완전 투명한 것으로 간주하고 폐기하는 픽셀 셰이더
• Bool 매개 변수 gAlphaClip이 참인 경우에만 폐기 판정
• 텍스처 표본의 알파 성분이 0.1보다 작으면 픽셀을 폐기
• 이러한 판정을 일찍 수행해 셰이더를 일찍 벗어날 수 있다
• 혼합을 이용하는 방법보다 효율적
• 혼합 계산 불필요
• 그리기 순서에 영향 받지 않는다.
• 폐기 이후 픽셀 셰이더 나머지 명령 생략 가능
9.7 픽셀 자르기(2) – 픽셀 셰이더 예시
28. • 게임에서 특정 기상을 흉내내기 위해 사용하는 안개 효과
• 먼 거리의 렌더링 결함이나 파핑(popping) 현상 숨길 수 있다
• 절두체 밖 물체가 절두체 안으로 들어와 튀어나오는 현상
• 먼 거리의 물체가 흐릿하게 보이는 대기 원근 현상 표현
9.8 안개
29. • 필요 설정 값
• 안개의 색상
• 안개가 시작되는 (카메라와의) 거리
• 안개의 범위(시작 지점에서 안개에 완전히 가리는 지점까지)
안개의 구현
30. • 렌더링 시 삼각의 한 점의 색상을 원래 색상과 안개 색상의
가중 평균으로 구한다.
• 매개변수 s는 카메라 위치와 점 사이에 따른 0에서 1까지의 값
• 카메라와 표면 점 거리가 멀수록 1에 가깝고, 결과적으로 표면 점이 점점 안개에 가려진다.
• dist(p,E)는 표면 점 p와 카메라 E 사이의 거리
• Saturate 함수는 주어진 인수를 [0,1] 구간으로 한정
안개의 구현
31. • 𝑑𝑖𝑠𝑡(𝑝, 𝐸)(카메라와 표면 점 거리)에 따른 s 값
• 안개 색 가중치 s가 증가할수록 조명된 색상의 가중치 1-s는 감소
• 𝑓𝑜𝑔𝑆𝑡𝑎𝑟𝑡 < 𝐷𝑖𝑠𝑡 𝑝, 𝐸 < 𝑓𝑜𝑔𝐸𝑛𝑑일 때 안개 색 가중치가 점점 커지고,
표면 점이 점점 더 안개에 가려진다.
• 𝐷𝑖𝑠𝑡 𝑝, 𝐸 ≤ 𝑓𝑜𝑔𝑆𝑡𝑎𝑟𝑡면 𝑠 = 0이고,
𝑓𝑜𝑔𝑔𝑒𝑑𝐶𝑜𝑙𝑜𝑟 = 𝑙𝑖𝑡𝐶𝑜𝑙𝑜𝑟
• 카메라와 거리가 fogStart보다 가까운 표면 점은 변경되지 않는다
• 𝐷𝑖𝑠𝑡 𝑝, 𝐸 ≥ 𝑓𝑜𝑔𝐸𝑛𝑑면 𝑠 = 1이고,
𝑓𝑜𝑔𝑔𝑒𝑑𝐶𝑜𝑙𝑜𝑟 = 𝑓𝑜𝑔𝐶𝑜𝑙𝑜𝑟
• 카메라와 거리가 fogEnd보다 먼 표면 점은 안개 색상만 보인다.
안개의 구현(2)
32. • 픽셀 셰이더에서 조명 색상을 계산한 후 안개 거리에 따른 보간으로 최종 색상을 결정한다.
• 안개 색의 가중치를 구한다
• 안개 색상과 조명된 색상을 가중치로 선형 보간한다.
안개의 구현(3)