p5.Shader

シェーダープログラムを記述するためのクラスです。

p5.Shaderオブジェクトには、グラフィックス処理ユニット(GPU)上で 実行されるシェーダープログラムが含まれています。シェーダーは多くのピクセルや頂点を 同時に処理できるため、多くのグラフィックスタスクに対して高速です。シェーダーは GLSL という言語で書かれ、スケッチの他のコードと一緒に実行されます。

シェーダープログラムは、頂点シェーダーとフラグメントシェーダーの2つのファイルで 構成されています。頂点シェーダーは3Dジオメトリが画面上のどこに描画されるかに影響し、 フラグメントシェーダーは色に影響します。p5.Shaderオブジェクトが 作成されると、shader()関数で使用できます。 例えば、shader(myShader)のように使います。

シェーダーはオプションでフックを記述できます。フックはGLSLの 関数で、ユーザーがシェーダーの動作をカスタマイズするために提供することを選択できます。 頂点シェーダーまたはフラグメントシェーダーに対して、ユーザーはオブジェクトを渡すことが できます。各キーはフック関数の型と名前で、各値はパラメータリストとフックのデフォルト 実装を含む文字列です。例えば、ユーザーが頂点シェーダーの開始時にオプションでコードを 実行できるようにするには、オプションオブジェクトに以下を含めることができます:

{
  vertex: {
    'void beforeVertex': '() {}'
  }
}

そして、頂点シェーダーのソースで、HOOK_を前に付けた同じ名前の 関数を呼び出すことでフックを実行できます:

void main() {
  HOOK_beforeVertex();
  // ここに残りのシェーダーコードを追加します!
}

注意:createShader()createFilterShader()loadShader()が、 このクラスのインスタンスを作成する推奨される方法です。

実例

シンタックス

p5.Shader(renderer, vertSrc, fragSrc, [options])

パラメーター

renderer
p5.RendererGL:

このシェーダーのWebGLコンテキスト。

vertSrc
String:

頂点シェーダープログラムのソースコード。

fragSrc
String:

フラグメントシェーダープログラムのソースコード。

options
Object:

このシェーダーがフックで拡張される方法を記述するオプションのオブジェクト。 以下を含むことができます:

  • vertex:利用可能な頂点シェーダーフックを記述するオブジェクト。
  • fragment:利用可能なフラグメントシェーダーフックを記述するオブジェクト。

メソッド

inspectHooks

このシェーダーで利用可能なフックとその現在の実装をログに記録します。

各シェーダーは、その動作の一部をオーバーライドできます。各部分は フックと呼ばれます。フックは、頂点の位置に影響する場合は頂点 シェーダー用、ピクセルの色に影響する場合はフラグメントシェーダー用です。 このメソッドはそれらの値をコンソールに記録し、 modify()の呼び出しで 使用できるものを知ることができます。

例えば、このシェーダーは以下の出力を生成します:

myShader = baseMaterialShader().modify({
  declarations: 'uniform float time;',
  'vec3 getWorldPosition': `(vec3 pos) {
    pos.y += 20. * sin(time * 0.001 + pos.x * 0.05);
    return pos;
  }`
});
myShader.inspectHooks();
==== 頂点シェーダーフック: ====
void beforeVertex() {}
vec3 getLocalPosition(vec3 position) { return position; }
[MODIFIED] vec3 getWorldPosition(vec3 pos) {
      pos.y += 20. * sin(time * 0.001 + pos.x * 0.05);
      return pos;
    }
vec3 getLocalNormal(vec3 normal) { return normal; }
vec3 getWorldNormal(vec3 normal) { return normal; }
vec2 getUV(vec2 uv) { return uv; }
vec4 getVertexColor(vec4 color) { return color; }
void afterVertex() {}

==== フラグメントシェーダーフック: ====
void beforeFragment() {}
Inputs getPixelInputs(Inputs inputs) { return inputs; }
vec4 combineColors(ColorComponents components) {
                vec4 color = vec4(0.);
                color.rgb += components.diffuse * components.baseColor;
                color.rgb += components.ambient * components.ambientColor;
                color.rgb += components.specular * components.specularColor;
                color.rgb += components.emissive;
                color.a = components.opacity;
                return color;
              }
vec4 getFinalColor(vec4 color) { return color; }
void afterFragment() {}
modify

オリジナルのシェーダーに基づいて、カスタムのシェーダーコードスニペットで デフォルトの動作を置き換えた新しいシェーダーを返します。

各シェーダーは、その動作の一部をオーバーライドできます。各部分は フックと呼ばれます。フックは、頂点の位置に影響する場合は頂点 シェーダー用、ピクセルの色に影響する場合はフラグメントシェーダー用です。 利用可能な異なるフックを yourShader.inspectHooks() を呼び出すことで確認できます。また、デフォルトのマテリアル、ノーマルマテリアル、 カラー、ライン、ポイントシェーダーのリファレンスを読んで、それらが利用可能な フックを確認することもできます。

modify()は1つのパラメータhooksを取ります。これは オーバーライドしたいフックを含むオブジェクトです。hooksオブジェクトの 各キーはフックの名前で、値はそのフックのGLSLコードを含む文字列です。

既存のフックではない関数を提供した場合、それらはヘルパー関数としてシェーダーの 先頭に追加されるので、フック内で使用できます。

シェーダーに新しいuniformを 追加するには、uniformの型と名前をキーとし、デフォルト値またはデフォルト値を返す 関数を値とするuniformsオブジェクトを渡すことができます。これらは shader(yourShader)でシェーダーが設定されるときに自動的に設定されます。

また、declarationsキーを追加することもできます。その値は、 フック間で共有されるカスタムuniform変数、グローバル変数、関数を宣言するGLSL文字列 です。頂点シェーダーまたはフラグメントシェーダーにのみ宣言を追加するには、 vertexDeclarationsおよびfragmentDeclarationsキーを 追加します。

copyToContext

シェーダーをある描画コンテキストから別のコンテキストにコピーします。

p5.Shaderオブジェクトは、実行前に shader()を呼び出してコンパイルする必要が あります。コンパイルは通常メインキャンバスか p5.Graphicsのインスタンスである描画 コンテキストで行われます。シェーダーはコンパイルされたコンテキストでのみ使用 できます。copyToContext()メソッドはシェーダーを再度コンパイルし、 再利用できる別の描画コンテキストにコピーします。

パラメータcontextは、シェーダーが使用される描画コンテキストです。 シェーダーはp5.Graphicsのインスタンスに コピーできます。例えばmyShader.copyToContext(pg)のようにします。 シェーダーはp5.Graphicsオブジェクトから メインキャンバスにもwindow変数を使ってコピーできます。例えば myShader.copyToContext(window)のようにします。

注意:createShader()createFilterShader()、または loadShader()で作成された p5.Shaderオブジェクトは、 createFramebuffer()で作成された p5.Framebufferオブジェクトと 直接使用できます。両オブジェクトはメインキャンバスと同じコンテキストを持ちます。

setUniform

シェーダーのuniform(グローバル)変数を設定します。

シェーダープログラムはコンピューターのグラフィックス処理ユニット(GPU)上で 実行されます。シェーダーはコンピューターのメモリの、それを実行するスケッチとは 完全に分離された部分に存在します。uniformはシェーダープログラム内のグローバル 変数です。uniformはCPU上で実行されるスケッチからGPU上で実行されるシェーダー プログラムに値を渡す方法を提供します。

最初のパラメータuniformNameは、uniformの名前を含む文字列です。 上記のシェーダーの場合、uniformName'r'となります。

2番目のパラメータdataは、uniformを設定するために使用される値です。 例えば、myShader.setUniform('r', 0.5)を呼び出すと、上記のシェーダーの r uniformが0.5に設定されます。dataはuniformの型に 一致する必要があります。数値、文字列、ブール値、配列、多くの種類の画像はすべて setUniform()を使用してシェーダーに渡すことができます。

Notice any errors or typos? Please let us know. Please feel free to edit src/webgl/p5.Shader.js and open a pull request!

関連するリファレンス