~プログラミング~ DirectX 11でシェーダーをコンパイルしよう

C++言語でDirectX 11を使ったアプリケーションを開発してみよう。

 

DirectX 11ではシェーダーの利用が必須です。

簡単な図形を出すにもシェーダーを使わなければなりません。

 

シェーダーはHLSLという言語で記述する必要があり、さらにそれをコンパイルして使います。アプリ実行時に毎回コンパイルして使うという方法もありますが、事前にコンパイルしたものを使うのが一般的だと思います。

 

ここでは、HLSL言語で簡単なシェーダーを記述して、コンパイルする方法をまとめてみます。

頂点シェーダーを作る

すごく単純な頂点シェーダーを作ってみます。

入力された座標と色データをそのまま出力するだけのシェーダーです。

(本来ならここでワールド・ビュー・プロジェクションといった座標変換などを行なったりしますが、

 ここではシンプルに何もしません)

 

以下はHLSL言語で記述した頂点シェーダーです。

(ファイル名は「vs_test.vsh」としてみました)

vs_test.vsh

struct VS_IN
{
        float4 pos : POSITION0;
        float4 col : COLOR0;
};

struct VS_OUT
{
        float4 pos : SV_POSITION;
        float4 col : COLOR0;
};


VS_OUT vs_main( VS_IN input )
{
        VS_OUT output;

        output.pos = input.pos;
        output.col = input.col;
        return output;
}

「VS_IN」と「VS_OUT」という2つの構造体を定義しています。

それぞれ入力用のものと出力用のものです。

 

「vs_main」というのがシェーダーの実態となる関数です。

座標と色というデータを受け取り、それをそのまま吐き出しています。

ピクセルシェーダーを作る

すごく単純なピクセルシェーダーも作ってみます。

入力された座標と色データから色をそのまま出力するだけのシェーダーです。

(本来ならここでライトの当たり方によって色を変えたりなどの計算をしたりしますが、

 ここではシンプルに何もしません)

 

以下はHLSL言語で記述したピクセルシェーダーです。

(ファイル名は「ps_test.psh」としてみました)

ps_test.psh

struct PS_IN
{
        float4 pos : SV_POSITION;
        float4 col : COLOR0;
};


float4 ps_main( PS_IN input ) : SV_Target
{
        return input.col;
}

「PS_IN」という入力用の構造体を定義しています。

頂点シェーダーの出力と同じ構造です。

 

「ps_main」というのがシェーダーの実態となる関数です。

座標と色というデータを受け取り、その色データをそのまま吐き出しています。

fxc.exeでコンパイルする

まずはコンパイラの実行ファイル「fxc.exe」を見つけましょう。

Visual Studioを使っている人は [C:\Program Files (x86)\Windows Kits\8.1\bin\x86] 辺りにあると思います。

 

コマンドプロンプトなどから実行します。

使い方は [fxc.exe <options> <files>] のようになっています。

fxc.exeの代表的なオプション

/?

各オプションの説明など使い方を表示してくれます。

 

/T <profile>

ターゲットプロファイルを指定します。

指定できるプロファイルは「/?」オプションで確認できますが、シェーダーの種類とバージョンの組み合わせになっています。

例)vs_5_0  vs_4_1  vs_4_0  ps_5_0  ps_4_1  ps_4_0  など

 

/E <name>

シェーダーの関数名を指定します

 

/Fh <file>

出力ファイル名を指定します

コンパイル後のオブジェクトコードを含むヘッダーファイルが作成されます。

fxc.exeでコンパイルする

上記で作ったシェーダーのファイルを下記のような感じでコンパイルします。

 

>fxc.exe /T vs_5_0 /E vs_main /Fh vs_test.h vs_test.vsh

>fxc.exe /T ps_5_0 /E ps_main /Fh ps_test.h ps_test.psh

 

コンパイルが成功すると「vs_test.h」と「ps_test.h」ファイルが出来上がります。

コンパイル後のファイルをソースに組み込む

上記のように「/Fh」オプションを使うとヘッダーファイルが出来上がります。

中身を見てみると関数名の先頭に[g_]がついた変数が確認できます。

コンパイル後のオブジェクトコードがバイト配列で定義されています。

const BYTE g_vs_main[] =
{
     68,  88,  66,  67,  71, 193, 
     40, 109,  81,  69, 118, 230, 
    196, 192,  21,  90, 167, 179, 
    135,  40,   1,   0,   0,   0, 
     96,   2,   0,   0,   5,   0, 
      0,   0,  52,   0,   0,   0, 
    172,   0,   0,   0, 252,   0, 
      0,   0,  80,   1,   0,   0, 
    196,   1,   0,   0,  82,  68, 

          :
          :
  

出来上がったヘッダーファイルはインクルードして使います。

#include "vs_test.h"
#include "ps_test.h"