쉐이더를 잘 만드는 것은 클라이언트쪽에서 특수 스킬이다. (= 할 줄 알면 좋다.) 예쁘게 만들줄알면 좋다.
버텍스 쉐이더 꼴 아래와 같이 된다. WinAPI에서 소프트웨어 렌더링 해본 것들 생각해보면 됨.
다음 단계를 위한 리턴도 함.
FOutPut VertexShader(FEngineVertex Vertex)
{
Vertex.POSITION *= World;
Vertex.POSITION *= View;
Vertex.POSITION *= Projection;
FOutPut InputAsm2Return;
InputAsm2Return.ConvertPosition = Vertex.POSITION;
return InputAsm2Return;
}
점이 4개니까 4번 실행된다.
쉐이더 함수가 돌아가는 위치가 그래픽카드라는 게 중요하다.
일단 우리 엔진 URenderer::Render함수에 렌더링 파이프라인 순서대로 쭉 있음. OutputMerger는 순서 크게 상관없이 한 번만 해주면 되는 거라 따로 해줬다 함. (UEngineRenderTarget 클래스 Setting()인듯)
렌더링을 시작하기 위해서는 리소스를 만들고 세팅해줘야 함. 리소스를 만든다는 건 그래픽카드의 메모리를 할당한다는 거고 이렇게 만들어진 리소스들은 무조건 글카에 저장된다. 세팅을 해준다는 것은 글카에 렌더링 파이프라인을 기동시키기 위한 슬롯 개념에 내가 만든 리소스를 장착한다는 개념이다.
리소스를 만들려면 다이렉트가 제공한 인터페이스 : ID3D11Device* Device
리소스를 세팅해서 렌더링하기 위한 다이렉트가 제공한 인터페이스 : ID3D11DeviceContext* Context
→ 그래서 이 둘 디바이스와 컨텍스트를 관리하는 클래스인 UEngineGraphicDevice
를 만듦. 이 클래스의 Initialize함수에서 디바이스와 컨텍스트를 만들고 시작해야 한다.
만들어진 디바이스와 컨텍스트는 이제 렌더링 파이프라인의 리소스들을 만들고 렌더링 파이프라인의 리소스들을 세팅하는 데에 사용될 것이다.
일단 도형을 그리는 걸 목적으로 생각.
도형을 그리기 위해서는 점이 필요. 이 점에 해당하는 것은 인풋 어셈블러 1단계이다. 핵심 리소스 버텍스 버퍼와 인풋 레이아웃을 여기서 만들어야 한다.
X바이트의 자유로운 크기의 점 n개를 글카에 할당하는 것으로 만들어지고 우리 엔진에서는 UEngineGraphicDevice::EngineResourcesInit() 함수 내부의 MeshInit() 함수에서 만들어 진다.
점이 어떻게 구성되어 있는지에 대한 정보인 인풋 레이아웃을 만드는 코드가 보인다.
Info.AddInputLayOut 어쩌구 : 처음 넣는 게 0~16 바이트가 POSITION, 두 번째로 넣는 게 16~32 COLOR 인 것을 알려주는 거임. 순서를 알려줘야 함.
근데 POSITION, COLOR 순서를 쉐이더쪽에서 바꿔도 들어감!!
→ 그래픽 파이프라인 버텐스 쉐이더 단계에서 인풋에 컬러, 포지션 순서로 들어가도 포지션은 포지션에, 컬러는 컬러에 넣어주기 때문에 순서가 달라져도 실행이 잘 된다. 이거 때문에 인풋 레이아웃이 필요함. 시멘틱만 잘 설정해주면 인풋 레이아웃이 파악해서 쉐이더에 넣을 때 알아서 해준다.
심지어 인풋에 포지션만 넣어줘도 알아서 포지션만 넣어줌. 버텍스를 미리 100가지 변수 넣어줬어도 쉐이더에 따라 다르게 인풋 넣어줘도 인풋 레이아웃이 알아서 쓴다고 한 것만 넣어줌.
버텍스 버퍼에 있는 것보다 많이 인풋하면 그건 오류남.
CPU의 점 데이터가 디바이스를 통해서 글카 메모리로 넘어간거임 → 쉐이더에 점 넘어감 근데 뭔 연산을 안 해놔서 그대로 넘어감 → 그대로 인풋 어셈블러2로 넘어감.
쉐이더에서는 아무것도 안하고 그대로 내보냈는데, ULevel::Render함수에서 viewport 곱하기 때문에 화면 절반만큼의 사각형 나오는거임
(ImageShader_VS에서 x,y,z의 POSITION * 2씩 해주거나, 점 데이터 * 2씩해주면 화면 꽉채우는 사각형됨. (엔진에서 FullRect))
hlsl 언어에서 스위즐링(swizzling) 문법이 가능하다.
float4에서 float3만 빼서 쓰는 게 가능!
Out.POSITION.xyz = _Input.POSITION.xyz * 2.0f;
픽셀 쉐이더 아웃풋에 컬러 넣어주고 있음.
여기서 시멘틱(SV_Target0) 뜻 : 0번째 타켓에 빨간색 출력해라
레스터라이저 ~ OM
지금 월드변환, 뷰, 투영 행렬 안 곱한 상태.
이거를 쉐이더에서 해줘야 함. -> 상수버퍼 하다 끝남