쉐이더마다 특징이 있는데, 특징에 맞는 그룹군을 모아서 랜더링 순서를 정할 것이다.
*도메인 쉐이더할 때의 도메인이 아님!
*비트연산할게 아니니까 enum class
*도메인 -> 자신의 주영역, 메인 영역
enum class SHADER_DOMAIN -> 쉐이더마다의 영역!
투명도가 없는 애들이 제일 먼저 그려져야한다.
반투명하다 -> 기존에 그려져 있는 거랑 색상이 반쯤 섞이는 것이다.
불투명한 애들이 먼저 그려져 있어야 반투명한 애들이 그려질 때 이미 그려진 애랑 본인이 출력할 색상을 섞은 색상으로 값을 계산할 수 있다.
불투명한 애들이 먼저 다 그려지고 나면 반투명한 애들과 영역이 겹치는게 있을 시 사이사이에 껴들어간다.
물체들의 실체 위치와 상관없이 불투명하냐 반투명하냐에 따라 랜더링 시점을 다르게 정렬해서
누굴 먼저 그리면서 해야 장면이 제대로 완성될 것인지 고려해야한다.
1. DOMAIN_OPAQUE -> 불투명
쉐이더 중에서 투명처리를 하지 않는 물체들은 여기서 랜더링
2. DOMAIN_TRANSPARENT -> 반투명
반투명한 애들이 덧그려져야함..
3. DOMAIN_MASK -> 1과 2의 중간에 있는 것
반투명도 아니고 그렇다고 다 불투명도 아니다.
출력/비출력으로 나뉘는것
불투명 아니면 완전 투명
가려진 부분은 출력하지 않고 가려지지 않는 부분은 출력을 한다.
각 쉐이더 별로 자기가 어느 쉐이더 도메인에 속하는지 그래픽스 쉐이더에 명시를 해놔야한다.
test 쉐이더
blend state가 정해지지 않으면 알파를 0으로 출력해도 반응이 없다.
blend state를 정하지 않으면 default blend state 로 돼서 알파값이 다 1로 된다.
blend state를 사용하는 물체는 그려질 때 실제 본인이 샘플링을 해서
자기가 추출한 색상이 알파값에 들어있어도 출력하면 본인의 색상 RGB가 그대로 출력 된다.
default blend state는 본인계수가 1이고 목적지계수가 0이기 때문이다.
이렇게 작성된 쉐이더는 쉐이더 도메인을 OPAGUE(불투명)으로 지정해야한다.
std2D 쉐이더
blend state를 알파블랜드를 사용하고 있다.
알파값이 몇이 되든 그거에 맞게 계수가 본인의 출력 색상에 적용이 된다.
출력할 때 목적지 색이랑 블랜딩에 걸리는 알파블랜딩을 사용하기 때문이다.
그래서 이 쉐이더는 반투명 타입이라고 봐야한다 (MASK)
알파블랜드용 쉐이더는 따로 만든다.
std2DAlphaBlendShader라는 이름으로. (TRANSPARENT)
알파블랜드를 쓴다 안쓴다는 픽셀쉐이더에서만 달라지니까 버텍스쉐이더는 공유해도 상관없다.
버텍스 쉐이더랑 같은걸 쓰는데 픽셀 쉐이더를 두 종류를 줄 것이다.
둘은 나누는 차이는 쉐이더 코드에서 나올 것이다.
hlsl에서, 픽셀쉐이더에서 discard 라는 구문을 만나면, 픽셀쉐이더가 버려진다.
-> 즉, 아웃풋머지단계(OM)까지 갈수가없다는 의미이다.
-> 픽셀쉐이더를 중간에 분기처리해서 폐기처분할 수 있다.
똑같은 기능을 가능하게 하는걸로 clip(-1) 이라는 함수가 있다.
만약 내가 출력하려는 최종 컬러에 알파가 0면 픽셀 쉐이더를 없는 취급을 할 것이다.
어차피 알파블랜딩을 하면 알파가 0라는건 본인의 출력 색상 x 0가 될 것이고
목적지(원래그려져 있던 색상) x 1 이니까 출력해도 원래 없는 색상으로 보이지 않는다.
0으로 블랜딩을 하거나 버리는거나 사실상 보는 사람 입장에서는 똑같다.
그런데, 달라질 수가 있다. 어떤 경우에 ??
원점에서 테투리로 갈수록 알파값이 0에 가까워져 점점 옅어지는 것처럼 보인다.
알파값이 0이어도 뭔가를 출력했기 때문에 알파값이 반영되어 이렇게 나오게 된다.
블랜딩 계수?가 본인이 출력하는 색상에 x 0
+
원래 이 자리에 그려져 있던 색상 x ( 1 - 0)
=> 원래 이자리에 그려져 있던 색상
이기 때문에 투명하다라고 보여지는 것이다.
* 투명하게 보이더라도 본인의 깊이 값이 저장이 되어 있는 상태이다.
깊이 텍스처는 랜더 타겟과 똑같은 해상도로 만들어져 있는데, 랜더타겟에 물체를 그리면
깊이 택스쳐에도 같은 위치에 그 물체의 깊이값이 저장되게 된다.
우리 눈에는 단순하게 투명하게 보여서 출력이 안 된 것처럼 보이지만,
사실은 그 자리에 깊이 텍스쳐의 깊이가 남은 상태인 것이다.
그래서 불투명 쉐이더를 사용할 때는 깊이 값을 남기면 안된다.
* 불투명한 쉐이더는 자신의 색을 그대로 출력하기 때문에 랜더링 순서를
반투명보다 불투명이 먼저 해야한다.
랜더링 순서 잡기
랜더링이 되어야하는 물체들을 모아 본인이 어떤 쉐이더를 사용할 것인지에 따라 그룹화를 시킨다.
쉐이더 도메인이 OPAQUE or MASK 일 경우 먼저 출력하고, TRANSPARENT 와 다른 것은 나중에 출력한다.
랜더링 순서를 잡기 위해서 '쉐이더 도메인'이 필요하다.
물체들이 재질을 참조하고, 재질은 쉐이더를 참조하고 있기 때문에
본인이 어떤 시점에 그려져야 정상적으로 화면에 잘 완성될것인지에 따라 우리가 분류작업을 해야한다.
Depth Stensil State
1. Less
깊이 값이 가까운게 우선 출력 -> 깊이 값 기록
2. Greater
깊이 값이 멀수록 우선 출력 -> 깊이 값 기록
3. Depth
설정된 깊이 값이 가까울수록 우선 출력 -> 깊이 값 기록 X
4. No Test No Write
깊이 값 판정 안 하고 무조건 출력 -> 깊이 값 기록 X
랜더 매니저
랜더링의 기준을 카메라에 잡히는 것들로 한정한다.
월드에 있는 모든 것을 랜더링 하는건 메모리 낭비이기 때문이다.
카메라는 여러 대가 있을 수 있다는 가정하에 작업한다.
카메라마다 레이어를 갖게하고, 카메라는 특정 레이어를 배제하고 출력할 수 있다.
* 특정 레이어 배제 함수 : SetLayerMask
* 레이어 번호를 주거나 이름을 주면 된다.
카메라는 메인 카메라와 ui 카메라로 나뉜다.
메인 카메라는 플레이어와 같이 월드 상에 보여주는 것들을 보여주는 것이고,
ui는 ui 와 인벤토리창들만 비추는 카메라이다.
*다이렉트X 에서는 transform component를 사용하기 때문에
메인 카메라가 ui도 같이 비추게 되면 캐릭터가 회전할 시 ui도 같이 회전을 하기 때문에
카메라를 따로 두는 것이다.
카메라 클래스의 final tick에서 랜더 매니저를 가져와서 백터에 카메라를 등록한다.
랜더매니저에 있는 카메라 벡터에 현재 레벨에 존재하는 모든 카메라 정보가 들어가게 된다.
여기에 들어가는 카메라 내용은 매 프레임마다 자동으로 갱신되게끔 한다.