자체엔진

[Dx11] hlsl을 헤더파일로 컴파일 하는법

doyyy_0 2025. 6. 18. 12:41

DX11에서는 런타임시 hlsl파일을 컴파일 하는 방식이 존재한다.

D3DCompileFromFile과 같은 함수를 사용하는 것이다. 하지만 코드 길이가 길어지고, 배포시에는 보안상 사용될 수 없다. 

 

이외의 방식에는 .cso로해서 빌드 시 객체 파일로 컴파일 하는 방식이 있고, 빌드 시 헤더 파일로 컴파일 하는 방식이 있다.

 

여기서는 빌드 시 헤더파일로 컴파일 하는 방식에 대해 알아 볼 것이다. visual studio내부에서 hlsl을 바이트 배열로 변환하고 그 값들을 헤더파일에 저장한다. 그리고 사용하면 된다. 

 

D3DCompileFromFile에서는 코드가 다음과 같은데,

HRESULT hr = S_OK;
  
// 컴파일된 셰이더 코드가 들어갈 blob
ID3DBlob* pPSBlob = nullptr;
ID3DBlob* pErrorBlob = nullptr;

// HLSL 파일을 컴파일
hr = D3DCompileFromFile(
	L"PixelShader.hlsl",
	nullptr,                // 매크로 정의 (없음)
	nullptr,                // 포함자 인터페이스 (없음)
	"PSMain",               // 셰이더 진입 함수 이름
	"ps_5_0",               // 셰이더 모델 (픽셀 셰이더 5.0)
	0,                      // 컴파일 플래그 (예: D3DCOMPILE_DEBUG)
	0,
	&pPSBlob,
	&pErrorBlob
);

if (FAILED(hr))
{
	if (pErrorBlob)
	{
		HandleHRFailure(m_hwnd, hr, "CompilePixelShader");
	}
	if (pPSBlob)
		SafeRelease(&pPSBlob);
	return;
}

hr = m_Device->CreatePixelShader(
	pPSBlob->GetBufferPointer(),
	pPSBlob->GetBufferSize(),
	nullptr,
	&m_PixelShader
);

SafeRelease(&pPSBlob);

if (FAILED(hr))
{
	HandleHRFailure(m_hwnd, hr, "CreatePixelShader");
}

 

헤더파일의 바이트를 이용하면, pPsBlob이나  pErrorBlob같은 걸 사용할 필요없이 바로 다음과 같이 끝낼 수 있다.

HRESULT hr = S_OK;

// pPSBlob 필요 없음 → 대신 g_psshader 배열 사용
hr = m_Device->CreatePixelShader(
	g_psshader,                  // 바이트 코드 데이터
	sizeof(g_psshader),          // 바이트 코드 크기
	nullptr,
	&m_PixelShader
);

if (FAILED(hr))
{
	HandleHRFailure(m_hwnd, hr, "CreatePixelShader");
}

 

하지만 헤더파일은 선언해줘야한다.

include "PixelShader.h"

...
        ComPtr<ID3D11PixelShader> m_pPixelShader;
        hr = pDevice->CreatePixelShader(g_psshader, sizeof(g_psshader), nullptr, &m_pPixelShader);

 

여기서 

hr = D3DCompileFromFile(
	L"PixelShader.hlsl",
	nullptr,                // 매크로 정의 (없음)
	nullptr,                // 포함자 인터페이스 (없음)
	"PSMain",               // 셰이더 진입 함수 이름
	"ps_5_0",               // 셰이더 모델 (픽셀 셰이더 5.0)
	0,                      // 컴파일 플래그 (예: D3DCOMPILE_DEBUG)
	0,
	&pPSBlob,
	&pErrorBlob

이 내부에 있는 것들은 .hlsl의 property에 들어가서 알아서 조정해주면 된다. 

 

 

HeaderVariableName이 바이트배열의 이름이 된다. 다음과 같다.

//PixelShader.h안의 내용
..
const BYTE g_psshader[] =
{
     68,  88...
}

HeaderFileName은 PixelShader.h로 해줘야 이름이 그렇게 형성된다

 

Reference:

https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-part1