シェーダー
シェーダー(英語:shader)とは、本来は3DCGで「陰影処理を」行うことをいう。現在では主にGPUで行う様々な処理の総称となっている。
概要
シェーダーは大きくわけてGPUが固定機能として持つ「固定シェーダー」と、プログラマが独自の処理を記述できる「プログラマブルシェーダー」に分けられる。
現在ではプログラマブルシェーダーが主流であるため「シェーダー=プログラマブルシェーダー」となっていることが多い。2018年時点で固定シェーダーを採用している現役製品はニンテンドー3DSくらいである。
また、ほとんどのゲームフレームワークやゲームエンジンでは無駄にプログラミングしなくても定番のレンダリング処理はあらかじめ固定シェーダーとして用意されている。これらでは内部的にはプログラマブルシェーダーを叩いているがソフトウェア的に固定シェーダーに見せている。
DXライブラリのシェーダー
DXライブラリにおいては、シェーダーをC言語っぽい言語で書き、付属のツールでコンパイルすることができる。
頂点シェーダー
未稿
ピクセルシェーダー
テクスチャ(プログラムで指定した画像)上の位置(左上を(0.0,0.0)、右下を(1.0,1.0)とする)などのパラメータが渡され、 その位置に書き込みたい色のデータを返す。色のデータは、RGBAの各要素をそれぞれ0.0~1.0の実数で表す形式で入出力する。
例:グレースケール化
//おまじない
struct PS_INPUT {
float4 DiffuseColor : COLOR0;
float4 SpecularColor : COLOR1;
float2 TextureCoord0 : TEXCOORD0;
float2 TextureCoord1 : TEXCOORD1;
};
struct PS_OUTPUT {
float4 Output : COLOR0;
};
sampler DiffuseMapTexture : register(s0);
//メインのプログラムを書く
PS_OUTPUT main(PS_INPUT PSInput) {
PS_OUTPUT PSOutput;
float4 nowColor;
//指定された場所のテクスチャの色を取得するおまじない
nowColor=tex2D(DiffuseMapTexture,PSInput.TextureCoord0);
//グレースケールにする計算
PSOutput.Output.r=0.298912f*nowColor.r+0.586611f*nowColor.g+0.114478f*nowColor.b;
PSOutput.Output.g=PSOutput.Output.r;
PSOutput.Output.b=PSOutput.Output.r;
PSOutput.Output.a=nowColor.a;
//計算結果を返す
return PSOutput;
}
一応行列の積などの計算もできそうだが、普通に計算したほうが速いし正確。
DirectXのシェーダー
DirectXでは上位シェーダーモデルとしてHLSL(High-Level Shader Language:上位レベルシェーダ言語)が採用されている。
HLSLはDirectX9から実装された高級シェーダー言語でありC言語風な書き方ができるようになっている。
現在、シェーダーモデル1~5までが存在しており、それぞれでの使える機能・対応するDirectX自体のバージョンが違うため、注意が必要となる
Direct3D 9の場合(シェーダーモデル1.x~3.0)は、頂点シェーダーとピクセルシェーダーの二つが提供されていた。
Direct3D 10.xの場合(シェーダーモデル4.x)は、そこにジオメトリシェーダーが追加。
Direct3D 11.xの場合(シェーダーモデル5.0)では、ハルシェーダー、ドメインシェーダー、コンピュートシェーダー(計算シェーダー、演算シェーダー)が追加となった。
ただし、コンピュートシェーダーに関してはグラフィックパイプラインの機能ではなく、物理演算やアニメーション計算などの計算時にGPUを使用するための機能として提供されている。
例:HLSLによる単純な3Dポリゴンの描画(バージョンはvs2.0,ps2.0)
//グローバル変数
float4x4 worldViewProjMat; //射影変換用行列
//テクスチャ
texture modelTexture; // テクスチャ情報の格納
// サンプラー(テクスチャの状態を規定する構造体)
sampler texSampler = sampler_state
{
Texture =<modelTexture>;
MinFilter =LINEAR;
MagFilter =LINEAR;
MipFilter =NONE;
AddressU =Clamp;
AddressV =Clamp;
};
//頂点シェーダからピクセルシェーダーに渡す構造体
struct VertexShaderResult
{
float4 Position : POSITION;
float2 TexCoord : TEXCOORD0;
};
//頂点シェーダ
VertexShaderResult VS( float4 _pos:POSITION, float2 _texCoord:TEXCOORD)
{
VertexShaderResult Out = (VertexShaderResult )0;//出力データ
Out.Position = mul(_pos, worldViewProjMat);//位置座標
Out.TexCoord = _texCoord;//テクスチャ座標
return Out;
}
//ピクセルシェーダ
float4 PS( VertexShaderResult _vertexResult ):COLOR
{
// テクスチャの貼り付け
return tex2D( texSampler , _vertexResult.TexCoord );
}
// テクニック
// DirectX側でこのテクニックを指定することで
// このテクニックで指定した頂点シェーダーとピクセルシェーダーで描画を行う
technique SampleShader
{
pass P0
{
VertexShader = compile vs_2_0 VS(); // 頂点シェーダーを2.0のシェーダーモデルで描画
PixelShader = compile ps_2_0 PS(); // ピクセルシェーダーを2.0のシェーダーモデルで描画
}
}
Unityのシェーダー
未稿
OpenGLのシェーダー
未稿