初めての2Dシェーダー
はじめに
シェーダーはGPUで実行される特殊なプログラムで、グラフィックスのレンダリングに使用されます。 最近のレンダリングはすべてシェーダーを使用して行われます。 シェーダーの詳細については、シェーダーとは を参照してください。
このチュートリアルでは、頂点関数とフラグメント関数の両方を使用してシェーダーを作成するプロセスを順を追って説明し、シェーダープログラムを作成する実用的な側面に焦点を当てます。 このチュートリアルは、シェーダーの初心者を対象にしています。
注釈
シェーダーの作成経験があり、Godotでのシェーダーの動作の概要を探しているだけの場合は、シェーディングリファレンス を参照してください。
セットアップ
CanvasItemシェーダー は Godot ですべての2Dオブジェクトを描画するために使用され、 :ref:`Spatialシェーダー <doc_spatial_shader>`はすべての3Dオブジェクトを描画するために使用されます。
シェーダーを使用するには、オブジェクトにアタッチする必要がある マテリアル 内にシェーダーをアタッチする必要があります。マテリアルは リソース の一種です。同じマテリアルで複数のオブジェクトを描画するには、各オブジェクトにマテリアルをアタッチする必要があります。
All objects derived from a CanvasItem have a material property. This includes all GUI elements, Sprite2Ds, TileMapLayers, MeshInstance2Ds etc. They also have an option to inherit their parent's material. This can be useful if you have a large number of nodes that you want to use the same material.
まずSprite2Dノードを作成します。 キャンバスに描画している限り、 任意のCanvasItem を使用できます。そのため、このチュートリアルでは、描画を開始するのに最も簡単なCanvasItemであるSprite2Dを使用します。
In the Inspector, click beside "Texture" where it says "[empty]" and select "Load", then select "icon.svg". For new projects, this is the Godot icon. You should now see the icon in the viewport.
次に、インスペクタのCanvasItemセクションの下を見て、「Material」の横をクリックし、「新規 ShaderMaterial」を選択します。 これにより、新しいマテリアルリソースが作成されます。 表示される球をクリックします。 Godotは現在、CanvasItemシェーダーとSpatialシェーダーのどちらを記述しているかを認識せず、Spatialシェーダーの出力をプレビューします。 したがって、表示されているのは、デフォルトのSpatialシェーダーの出力です。
注釈
Materials that inherit from the Material resource, such as StandardMaterial3D and ParticleProcessMaterial, can be converted to a ShaderMaterial and their existing properties will be converted to an accompanying text shader. To do so, right-click on the material in the FileSystem dock and choose Convert to ShaderMaterial. You can also do so by right-clicking on any property holding a reference to the material in the inspector.
Click beside "Shader" and select "New Shader". Finally, click on the shader you just created and the shader editor will open. You are now ready to begin writing your first shader.
初めてのCanvasItemシェーダー
Godotでは、すべてのシェーダーは、シェーダーのタイプを指定する行で始まります。 次の形式を使用します:
shader_type canvas_item;
CanvasItemシェーダーを記述しているため、最初の行で canvas_item を指定します。 すべてのコードは、この宣言の下に配置されます。
この行は、どのビルトイン変数と関数を提供するかをエンジンに伝えます。
Godotでは、3つの関数をオーバーライドして、シェーダーの動作を制御できます。vertex、fragment、および light。 このチュートリアルでは、頂点(vertex)関数とフラグメント(fragment)関数の両方を使用してシェーダーを作成する方法を説明します。 ライト(light)関数は、頂点関数やフラグメント関数よりもかなり複雑なので、ここでは説明しません。
初めてのフラグメント関数
フラグメント関数はSprite2D内のすべてのピクセルに対して実行され、そのピクセルが何色であるべきかを決定します。
これらはSprite2Dでカバーされるピクセルに制限されているため、Sprite2Dの周囲にアウトラインを作成する場合などは使用できません。
最も基本的なフラグメント関数は、すべてのピクセルに単一の色を割り当てること以外は何もしません。
そのためには、ビルトイン変数 COLOR に vec4 を書き込みます。vec4 は、4つの数値を含むベクトルを構築するための省略表現です。 ベクトルの詳細については、ベクトル演算チュートリアル <doc_vector_math>`を参照してください。``COLOR` はフラグメント関数への入力変数であり、フラグメント関数からの最終出力でもあります。
void fragment(){
COLOR = vec4(0.4, 0.6, 0.9, 1.0);
}
おめでとう! できました。 Godotで初めてのシェーダーの作成に成功しました。
それでは、もっと複雑にしましょう。
COLOR の計算に使用できるフラグメント関数には多くの入力があります。UV もその1つです。 UV座標は(知らないうちに)スプライトで指定され、メッシュの各部分のテクスチャからどこを読み取るかをシェーダーに指示します。
フラグメント関数では UV からしか読み取ることができませんが、他の関数で使用したり、値を COLOR に直接割り当てることができます。
UV は、左から右、上から下で0~1の間で変化します。
void fragment() {
COLOR = vec4(UV, 0.5, 1.0);
}
TEXTURE ビルトインを使用する
デフォルトのフラグメント関数は、設定されているSprite2Dテクスチャを読み込んで表示します。
Sprite2Dの色を調整したい場合は、以下のコードのようにテクスチャから手動で色を調整できます。
void fragment(){
// This shader will result in a blue-tinted icon
COLOR.b = 1.0;
}
Sprite2Dなどの特定のノードには、シェーダー内で TEXTURE を使用してアクセスできる専用のテクスチャ変数があります。 Sprite2Dテクスチャを他の色と組み合わせるために使用したい場合は、 UV と texture 関数を使用してこの変数にアクセスできます。これらを使用してSprite2Dをテクスチャで再描画します。
void fragment(){
COLOR = texture(TEXTURE, UV); // Read from texture again.
COLOR.b = 1.0; //set blue channel to 1.0
}
Uniform入力
Uniform入力は、シェーダー全体で同一のデータを、シェーダーに渡すために使用されます。
Uniformを使用するには、シェーダーの上部で次のように定義します:
uniform float size;
使用法の詳細については、シェーディング言語ドキュメント を参照してください。
uniformを追加して、Sprite2Dの青の量を変更します。
uniform float blue = 1.0; // you can assign a default value to uniforms
void fragment(){
COLOR = texture(TEXTURE, UV); // Read from texture
COLOR.b = blue;
}
これで、エディタからSprite2Dの青の量を変更できます。シェーダーを作成した場所のインスペクタを再確認すると、Shader Param というセクションが表示されるはずです。そのセクションを展開すると、宣言したuniformが表示されます。エディタで値を変更すると、シェーダーで指定したデフォルト値が上書きされます。
スクリプトからシェーダーを操作する
ノードのマテリアルリソースで呼び出される set_shader_param() 関数を使用して、コードからuniformを変更できます。 Sprite2Dノードでは、次のコードを使用して blue uniformを設定できます。
var blue_value = 1.0
material.set_shader_parameter("blue", blue_value)
var blueValue = 1.0;
((ShaderMaterial)Material).SetShaderParameter("blue", blueValue);
uniformの名前は文字列であることに注意してください。文字列は、スペルや大文字小文字を含め、シェーダーでの記述方法と正確に一致する必要があります。
初めての頂点関数
フラグメント関数ができたので、頂点関数を書きましょう。
頂点関数を使用して、各頂点が画面のどこに出現するかを計算します。
頂点関数の最も重要な変数は VERTEX です。最初はモデルの頂点座標を指定しますが、実際にそれらの頂点を描画する場所を決定するために書き込むこともできます。VERTEX は、ローカル空間で最初に表示される vec2 です(つまり、カメラ、ビューポート、または親ノードに関連しません)。
VERTEX に直接追加することにより、頂点をオフセットできます。
void vertex() {
VERTEX += vec2(10.0, 0.0);
}
TIME ビルトイン変数と組み合わせると、基本的なアニメーションを行うことができます。
void vertex() {
// Animate Sprite2D moving in big circle around its location
VERTEX += vec2(cos(TIME)*100.0, sin(TIME)*100.0);
}
結論
シェーダーとはこれまで見てきたことを実行し、VERTEX と COLOR を計算する仕組みです。これらの変数に値を割り当てるための、より複雑な数学的戦略を考え出すのはあなた次第です。
インスピレーションを得るには、Shadertoy や `The Book of Shaders <https://thebookofshaders.com>`_などのより高度なシェーダーチュートリアルをいくつか見てください。