[DirectX] 렌더링 파이프라인 - 쉐이더 추가

라멘커비·2024년 4월 1일
0

DirectX 2D

목록 보기
8/24
post-custom-banner

쉐이더를 잘 만드는 것은 클라이언트쪽에서 특수 스킬이다. (= 할 줄 알면 좋다.) 예쁘게 만들줄알면 좋다.

  • 쉐이더
    렌더링 파이프라인 중간에 내가 넣어줄 수 있는 함수
    함수를 만들어서 그래픽카드에게 알려주는 것임.
    더 쉽게 얘기하면 콜백
    콜백 : 어떤 기능을 만든 사람이 중간에 UI관련 클래스 함수 포인터 넣어달라고 만들면 함수 넣어줘야함.
    ex) 라이브러리에서 UI => 버튼이라고 칠 때 함수 포인터 안 넣어주면 버튼 눌러도 뭘 실행해야하는지 UI에서는 몰루

버텍스 쉐이더 꼴 아래와 같이 된다. 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가지 변수 넣어줬어도 쉐이더에 따라 다르게 인풋 넣어줘도 인풋 레이아웃이 알아서 쓴다고 한 것만 넣어줌.

버텍스 버퍼에 있는 것보다 많이 인풋하면 그건 오류남.

인풋 어셈블러2

CPU의 점 데이터가 디바이스를 통해서 글카 메모리로 넘어간거임 → 쉐이더에 점 넘어감 근데 뭔 연산을 안 해놔서 그대로 넘어감 → 그대로 인풋 어셈블러2로 넘어감.

레스터라이저(뷰포트 변환 여기서)

쉐이더에서는 아무것도 안하고 그대로 내보냈는데, ULevel::Render함수에서 viewport 곱하기 때문에 화면 절반만큼의 사각형 나오는거임

(ImageShader_VS에서 x,y,z의 POSITION * 2씩 해주거나, 점 데이터 * 2씩해주면 화면 꽉채우는 사각형됨. (엔진에서 FullRect))

HLSL - Swizzling 문법

hlsl 언어에서 스위즐링(swizzling) 문법이 가능하다.
float4에서 float3만 빼서 쓰는 게 가능!

Out.POSITION.xyz = _Input.POSITION.xyz * 2.0f;

픽셀 쉐이더

픽셀 쉐이더 아웃풋에 컬러 넣어주고 있음.

여기서 시멘틱(SV_Target0) 뜻 : 0번째 타켓에 빨간색 출력해라

Output Merger

레스터라이저 ~ OM

Draw 계열 함수들

최종 정리

지금 월드변환, 뷰, 투영 행렬 안 곱한 상태.
이거를 쉐이더에서 해줘야 함. -> 상수버퍼 하다 끝남

profile
일단 시작해보자
post-custom-banner

0개의 댓글