■今週のゲーム制作:描画エフェクトの実装



DirectX11で2Dスプライトに利用するためのHLSL言語の書き方について勉強を進めています。

ゼロ知識で始めたので、自分用にもう一度まとめていきたいと思います。(前回のHLSLに関する記事はこちら



後でパッと見返したいので、先に今回の記事の結論を書いておきます。


■ファイルフォーマット:拡張子「.hlsl」でLF(UNIX)、UTF-8(BOMなし)


■用意する必要があるシェーダー:頂点シェーダーとピクセルシェーダー両方必要((23/03/20追記)DirectXTKのSpriteBatchを利用している場合はピクセルシェーダーのみでOKでした!)


■セマンティクス:変数が何を意味するのかについて書くものがセマンティックで、シェーダーによってどのセマンティックが使えるのかは公式ドキュメントを見よう!


■命名規則:キャメルケースがよさそう


つづきで詳しく↓







■ファイルフォーマット

HLSL言語で書いたファイルのフォーマットは拡張子「.hlsl」でLF(UNIX)、UTF-8(BOMなし)で保存する。(文字コードとか改行コードはコンパイラが対応していれば何でもよさそうだけどBOMをつけるとエラーが出たよ!←出た人)
それと、拡張子「.fx」もあるらしいけど古いバージョンのものらしい。
検索すると頂点シェーダーを「.vsh」、ピクセルシェーダーを「.psh」の拡張子で作成している方もいらっしゃったので、どのシェーダーについて書かれたファイルかを明確にしたければこのパターンもありっぽい。この辺は好みかも?


■用意する必要があるシェーダー

シェーダーの種類は色々あるけど主な種類に頂点シェーダーとピクセルシェーダーがあって、ピクセルシェーダーだけ用意して使いたいときもピクセルシェーダーに値を渡す頂点シェーダーが必要になるみたい。要するに、頂点シェーダーとピクセルシェーダー両方必要ということ!(他のシェーダーの知識はないので必要になればまた勉強します(>_<;))

((23/03/20追記)DirectXTKのSpriteBatchを利用している場合はピクセルシェーダーのエントリポイント(main関数)の引数を(float4 color : COLOR0, float2 tex_coord : TEXCOORD0)にすると(おそらくデフォルトで設定されている頂点シェーダー?の)パラメータを受け取ることができました。なのでその場合は頂点シェーダーを用意するだけでOKです。)

  
  // イメージ( ^ω^)・・・
  float4 main(float4 color : COLOR0, float2 tex_coord : TEXCOORD0) : SV_Target0{
  
  	float4 result = color;
  
  	// ピクセルシェーダーでやりたい、なるべく簡単な処理
  
	return result;
  }
  

■セマンティクス

HLSL言語はC言語っぽく書けるけど、セマンティクスという要素がある。(専門用語ムズカシイけど「意味するもの」って感じっぽい)

    
    float4 color : COLOR0;
    

↑の「COLOR0」がセマンティックと呼ばれるもので、colorという変数が意味するものを決められる。
セマンティックは自分で勝手に名付けるわけではなく、もともと用意されたものから選ぶ。シェーダーの種類によって使えるものが決まっているみたい。↓公式ドキュメントを見よう!

Semantics - Win32 apps | Microsoft Learn

今回はcolor変数は色を表したいので「 : COLOR0」をつけてこれは色やで~と主張しておく。 セマンティックには数字を付けられるもの(POSITION、COLOR、TEXCOORDなど)があって、リソース番号っぽい。今のところとりあえず0を使えばよさそう。
公式ドキュメントによるとSV_PositionやSV_Targetなどの「SV_」から始まるものはDirect3D10以降で利用できるSystem-Valueセマンティクスとあるので、古いバージョンで利用できるように実装している場合は注意が必要そう。
コード例を検索するとピクセルシェーダーのmain関数には「COLOR」か「SV_Target」がついてるけど、「SV_Target」の方が新しい書き方ってことっぽい。(SV_Targetは出力する色を意味するっぽい)

      
    // イメージ( ^ω^)・・・
    float4 main(pixelShaderInputType input) : SV_Target0{
    	return input.color;
    }
    

セマンティクスについてまとめると、変数が何を意味するのかについて書くものがセマンティックで、シェーダーによってどのセマンティックが使えるのかは公式ドキュメントを見よう!ということです。


■命名規則

最近はC++でスネークケースを使っているんですが、HLSLでは型名やセマンティックに全部小文字のもの(float4とか)、全部大文字のもの(COLOR0とか)、スネークケースのもの(sampler_stateとか)があったりしてキャメルケースが使い分けやすいんじゃないかと思い始めました。命名規則なんて完全に好みだとは思いますが・・・( ˘ω˘)スヤァ(かんがえるのをやめた



とりあえずまだ実装したものを動かせてはいないので、動いたら続きもまとめていこうと思います。今週も頑張りますぞ~!