シェーダーの作成~解放
-DirectX11編-

最終更新日:2020/02/25

DirectX11のシェーダーの作成から解放までを書いた記事です。
この記事は以下の内容を知りたい方に向けて書いています。
  • DirectX11でシェーダーを作成したい
  • DirectX11でシェーダーをコンパイルしたい
  • DirectX11でシェーダーを設定したい
  • DirectX11でシェーダーを解放したい

サンプル

サンプルはここからダウンロードでき、環境については以下の内容となっています。

開発環境
DirectXのバージョン DirectX11
VSのバージョン VisualStudio 2019


ファイル作成

シェーダの読み込みを行う前に、まずはシェーダファイルを作成をします。
シェーダファイルの作成はcppやhファイルを追加する時と同じ方法で行えます。

directx_0134

追加ファイルの選択画面ではHLSL項目を選び、頂点シェーダと
ピクセルシェーダを作成してください。

directx_0133

作成したファイルは、頂点シェーダは頂点座標のみが渡され、
それをそのまま返しています。

float4 main( float4 pos : POSITION ) : SV_POSITION
{
	return pos;
}

ピクセルシェーダは何も受け取らず白色になるカラー値を返しています。

float4 main() : SV_TARGET
{
	return float4(1.0f, 1.0f, 1.0f, 1.0f);
}

コンパイルする

作成したシェーダファイルはそのままでは使用することはできないので、
以下の方法でコンパイルする必要があります。
  • VSに任せる
  • D3DCompileFromFileを使う

VSに任せる

ソリューションにシェーダファイルを追加して、きちんとした設定をすれば、
ビルド時にVSがコンパイルを行ってくれます。
まず、対象のシェーダーファイルを右クリックしてプロパティを開いてください。

directx_0135

プロパティ画面の構成プロパティの全般でビルドから除外が「いいえ」、
項目の種類が「HLSLコンパイラ」になっていることを確認してください。

directx_0136

次にHLSLコンパイラの全般のエントリポイント、シェーダの種類、シェーダモデルの
確認も合わせて行ってください。

directx_0137

確認が完了後、ビルドを行うとDebugフォルダに「.cso」ファイルが作成されます。
このファイルがコンパイルされたシェーダファイルです。

directx_0138

あとは、このファイルを実行時にfopen_sなどで読み込めば
コンパイル後のデータとしてシェーダー作成時などで使用することができます。

// シェーダファイル読み込み
FILE *fp = nullptr;
fopen_s(&fp, file_name, "rb");

if (fp == nullptr)
{
	return 0;
}
	
fseek(fp, 0, SEEK_END);
m_Size = ftell(fp);
fseek(fp, 0, SEEK_SET);
m_Data = new char[m_Size];
fread_s(m_Data, m_Size, m_Size, 1, fp);
fclose(fp);

シェーダーを作成する

ファイルの読み込みが完了したら、ID3D11Deviceの「CreateVertexShader」と
「CreatePixelShader」でシェーダの作成を行います。

directx_0140
// VertexShader作成
if (FAILED(device->CreateVertexShader(m_Data, m_Size, nullptr, &m_Interface)))
{
	return false;
}

directx_0139
// PixelShader作成
if (FAILED(device->CreatePixelShader(m_Data, m_Size, nullptr, &m_Interface)))
{
	return false;
}

設定する

作成したシェーダーはID3D11Deviceの設定関数である「VSSetShader」と
「PSSetShader」を使って、設定しないとレンダリングパイプラインで使われません。

directx_0141
// VertexShader設定
m_Context->VSSetShader( m_VertexShader->GetShaderInterface(), NULL, 0 );

directx_0142
// PixelShader設定
m_Context->PSSetShader( m_PixelShader->GetShaderInterface(), NULL, 0 );

解放する

シェーダを使い終わったらReleaseで解放します。
もし、シェーダーのファイルデータを動的確保しているようなら
こちらもきちんと解放してください。

// ファイルデータ解放
if (m_Data != nullptr)
{
	delete[] m_Data;
}


// シェーダの解放
if (m_Interface != nullptr)
{
	m_Interface->Release();	
}