オプション
家家 Skill その他 pixijs-custom-rendering

pixijs-custom-rendering

pixijs/pixijs pixijs/pixijs

PixiJS v8でカスタムシェーダー、ユニフォーム、フィルター、またはバッチャーを作成する際に、このスキルを活用してください。Shader.from({gl, gpu, resources})、GlProgram/GpuProgram、型付きユニフォーム(f32、vec2、mat4x4)を使用したUniformGroup、 UBOモード、リソースとしてのテクスチャ、Filter.fromによるカスタムフィルター、GLSL ES 3.0の規約(in/out、finalColor、texture())、uBackTextureのサンプリング、厳格なCSPのためのpixi.js/unsafe-eval、拡張機能によるカスタムバッチャー。 トリガー対象:Shader、GlProgram、GpuProgram、UniformGroup、Batcher、Filter、Filter.from、GLSL、WGSL、UBO、uniform、カスタムシェーダー、finalColor、uBackTexture、blendRequired、unsafe-eval。

...すべて拡張します
177
更新された時間 2026年8月11日

カスタムシェーダーでは、Shader.from({ gl, gpu, resources }) を通じて、GLSL および WGSL プログラムをシーンオブジェクトにバインドします。ユニフォームは型付きUniformGroupsに格納され、テクスチャは個別のリソースとして渡されます。また、同じシェーダーで WebGL と WebGPU の両方をターゲットに設定できます。

クイックスタート

constuniforms =new UniformGroup({
  uTime: {value:0,type:"f32"},
});constshader =Shader.from({
  gl: {vertex: vertexSrc,fragment: fragmentSrc },
 resources: { uniforms },
});constgeometry =new MeshGeometry({
  positions:new Float32Array([0,0,100,0,100,100,0,100]),
 uvs:new Float32Array([0,0,1,0,1,1,0,1]),
 indices:new Uint32Array([0,1,2,0,2,3]),
});constmesh =new Mesh({ geometry, shader });
app.stage.addChild(mesh);app.ticker.add(() =>{
  shader.resources.uniforms.uniforms.uTime= performance.now() /1000;
});

関連スキル: pixijs-filters(組み込みフィルター)、pixijs-scene-mesh(カスタムジオメトリ)、pixijs-performance(バッチ最適化)、pixijs-migration-v8(v7からのシェーダーAPI移行)。

主要なパターン

デュアルレンダラーシェーダー (WebGL + WebGPU)

import{Shader,GlProgram,GpuProgram,UniformGroup}from "pixi.js";constglVertex =`...`;// GLSL 頂点(WebGL2/GLSL ES 3.0 を使用する場合は、`#version 300 es` を自分で記述してください)
constglFragment =`...`;// GLSLフラグメント
constwgslSource =`...`;//WGSLコンバインドconstshader =Shader.from({
  gl: {vertex: glVertex,fragment: glFragment },
 gpu: {
    // entryPoint の名前は任意ですが、 WGSL ソース内の @vertex / @fragment
    // 関数名と 一致している必要があります 。PixiJS には
    // 'mainVert' / 'mainFrag'  を使用した例 が含まれていますが、`main` でも同様に有効です。
   vertex: {entryPoint:"mainVert",source: wgslSource },
    fragment: {entryPoint:"mainFrag",source: wgslSource },
  },
 resources: {
    myUniforms:new UniformGroup({
      uColor: {value:new Float32Array([1,0,0,1]),type:"vec4"},
     uMatrix: {value:new Float32Array(16),type:"mat4x4"},
    }),
  },
});

glのみが指定された場合、シェーダーは WebGL でのみ動作します。gpuのみが指定された場合、WebGPU でのみ動作します。compatibleRenderersビットマスクは自動的に設定されます。

GlProgram は#version 300 esを自動挿入しません。#version 300 esを手動で記述した場合、PixiJS はそれを保持し、シェーダーを GLSL ES 3.0 として扱います。そうでない場合は、WebGL1 互換マクロ(varying 内の #define、texture2D 内の #define texture)を挿入し、シェーダーを WebGL1 スタイルの GLSL として実行します。GlProgramは常に、デフォルトの精度(頂点:highp、フラグメント:mediump)とプログラム名を挿入します。GLSL ES 3.0を使用する場合は、attribute/varyingの代わりにin/out、texture2D()の代わりにtexture( )、gl_FragColorの代わりにout vec4を使用してください。

リソースとしてのテクスチャ

テクスチャはユニフォームではなくリソースです。テクスチャのソースと スタイルを別々に渡します:

import{Shader,UniformGroup,Texture,Assets}from "pixi.js";consttexture =await Assets.load("myImage.png");constshader =Shader.from({
  gl: {vertex: vertSrc,fragment: fragSrc },
 resources: {
    uTexture: texture.source,
    uSampler: texture.source.style,
    myUniforms:new UniformGroup({
      uAlpha: {value:1.0,type:"f32"},
    }),
  },
});// 実行時にテクスチャを差し替える
shader.resources.uTexture= otherTexture.source;

リソースはフラットなキー・値のマップです。キーは、シェーダーソース内のユニフォーム名またはバインディング名と一致している必要があります。

リソースは単純なオブジェクトとしても指定可能です(自動的にUniformGroupにラップされます):

constshader =Shader.from({
  gl: {vertex: vertSrc,fragment: fragSrc },
 resources: {
    myUniforms: {
      uTime: {value:0,type:"f32"},
    },
  },
});

UBOモード(Uniform Buffer Objects)

UBOモードでは、ユニフォームを単一のGPUバッファにまとめます。WebGPUでは必須ですが、WebGLではオプション(WebGL2+)です。

import{UniformGroup}from "pixi.js";constubo =new UniformGroup(
  {
    uProjection: {value:new Float32Array(16),type:"mat4x4"},
   uAlpha: {value:1.0,type:"f32"},
  },
  {ubo:true,isStatic:true},
);// isStatic が true の場合は、update() を手動で呼び出す必要があります
ubo.uniforms.uAlpha=0.5;
ubo.update();

UBOのルール:

  • f32およびi32ベースの型のみがサポートされます(u32 は不可)。行列は float のみです。
  • サンプラーやテクスチャをUBOに入れることはできません。
  • リソース内のUniformGroup名は、シェーダー内のUBOブロック名と完全に一致する必要があります。
  • 構造と順序は、シェーダーのレイアウトと完全に一致する必要があります。
  • UBOの同期処理は、内部で新しいFunctionを使用しています。strict-CSP環境(unsafe-evalなし)では、起動時にpixi.js/unsafe-evalを1回インポートして、フォールバックの同期パスに切り替えてください。これを行わない場合、UBOを利用したシェーダー(ひいてはWebGPU)は、初回使用時に例外をスローします。

カスタムフィルタ

Filter.from({ gl, resources })は省略形です。フラグメントシェーダーのみを渡してください。PixiJS は、出力フレームの位置決めを処理するデフォルトの頂点シェーダーを提供します。

import{Filter}from "pixi.js";constfilter =Filter.from({
  gl: {
    fragment:`
            in vec2 vTextureCoord;
            out vec4 finalColor;
            uniform sampler2D uTexture;
            uniform float uStrength;            void main(void) {
                vec4 color = texture(uTexture, vTextureCoord);
                finalColor = mix(color, vec4(1.0 - color.rgb, color.a), uStrength);
            }
        `,
  },
  resources: {
    filterUniforms: {
      uStrength: {value:0.5,type:"f32"},
    },
  },
});filter.resources.filterUniforms.uniforms.uStrength=1.0;

カスタム頂点シェーダーを使用する場合は、new Filter({ glProgram: new GlProgram({ vertex, fragment }), resources }) を使用します。

Filter シェーダーの規約 (GLSL ES 3.0)
  • varyingvec2 vTextureCoord;の代わりにvec2 vTextureCoord;
  • gl_FragColorの代わりにout vec4 finalColor;
  • texture2D(uTexture, uv)の代わりにtexture (uTexture, uv)
  • デフォルトの頂点シェーダーでは、uInputSize、uOutputFrame、uOutputTexture、およびヘルパー関数filterVertexPosition()/filterTextureCoord()が公開されています。
フィルタの背後にあるレンダリングターゲットのサンプリング

blendRequired: trueを設定し、フラグメントシェーダーでuBackTexture をサンプリングします。PixiJS は、フィルタを実行する前に、宛先ピクセルをそのユニフォームにコピーします:

constblendFilter =Filter.from({
  gl: {fragment: blendFragSrc },
  resources: {uniforms: {uAmount: {value:0.5,type:"f32"} } },
  blendRequired:true,
});

blendRequired は必要な場合にのみ有効にしてください。これを有効にすると、毎フレーム、GPU での余分なコピーが強制されます。

実行時のユニフォームの更新

// resources 経由で UniformGroup にアクセス
shader.resources.myUniforms.uniforms.uTime= performance.now() /1000;// isStatic UBO の場合、値を変更した後に update() を呼び出します
shader.resources.myUniforms.update();

ユニフォーム型のリファレンス

サポートされている型の完全な一覧、対応する WGSL/GLSL 表記、および値の形式については、references/uniform-types.md を参照してください。

カスタムバッチャー(拡張機能ベース)

Batcher抽象クラスは、特殊なレンダリングのためのカスタムバッチ処理を可能にします。このクラスをサブクラス化し、拡張機能を通じて登録してください:

import{Batcher, extensions,ExtensionType}from "pixi.js";
import type{
  BatcherOptions,
  BatchableMeshElement,
  BatchableQuadElement,
  Geometry,
  Shader,
}from "pixi.js";class MyBatcher extends Batcher{
 public staticextension = {
    type: [ExtensionType.Batcher],
    name:"my-batcher",
  };  publicname ="my-batcher";
 protectedvertexSize =6;// 頂点あたりの浮動小数点数
  public geometry:Geometry;
  public shader:Shader;  constructor(options:BatcherOptions) {
    super(options);
    // ジオメトリとシェーダーを初期化
  }  public packAttributes(
    element:BatchableMeshElement,
    float32View:Float32Array,
    uint32View:Uint32Array,
    index:number,
    textureId:number,
  ):void{
   // メッシュの頂点属性をバッチバッファにパックする
  }  public packQuadAttributes(
    element:BatchableQuadElement,
    float32View:Float32Array,
    uint32View:Uint32Array,
    index:number,
    textureId:number,
  ):void{
   // クワッドの頂点属性をバッチバッファにパックする
  }
}extensions.add(MyBatcher);

要素は、batcherName によってバッチャーを参照します。BatchableElementインターフェースには、batcherName、texture、blendMode、indexSize、attributeSize、topology、およびpackAsQuad の指定が必須です。

よくある間違い

[重大] 旧式の Shader.from(vertex, fragment, uniforms) コンストラクタ

誤った例:

constshader =Shader.from(vertex, fragment, {uTime:1});

正しい例:

constshader =Shader.from({
  gl: { vertex, fragment },
  resources: {
    uniforms:new UniformGroup({
      uTime: {value:1,type:"f32"},
    }),
  },
});

v8 では、gl/gpuプログラムおよびリソースに対してオプションオブジェクトが必要です。位置指定 API は削除されました。

[重大] 型注釈のない UniformGroup

誤り:

new UniformGroup({uTime:1});

正しい記述:

new UniformGroup({uTime: {value:1,type:"f32"} });

すべてのユニフォームには、明示的な{ value, type }のペアが必要です。型を省略すると、実行時エラー「未定義のユニフォーム型はサポートされていません」が発生します。

[HIGH] サポートされていない型または不正な構造を持つ UBO

UBOモードでは、f32 およびi32ベースの型(スカラーおよびベクトル)がサポートされています。u32はサポートされているUniformGroupの型リストに含まれていないため、例外が発生します。行列はfloatのみです(mat* )。サンプラーをUBOに配置することはできません。

構造体の名前とフィールドの順序は、シェーダーのUBO宣言と完全に一致している必要があります。一致しない場合、エラーは発生しませんが、レンダリングが乱れます。

[HIGH] UniformGroupへのテクスチャの配置

誤った例:

new UniformGroup({
  uTexture: {value: texture,type:"f32"},
});

正しい例:

constshader =Shader.from({
  gl: { vertex, fragment },
  resources: {
   uTexture: texture.source,
    uSampler: texture.source.style,
    myUniforms:new UniformGroup({
      uAlpha: {value:1.0,type:"f32"},
    }),
  },
});

テクスチャはリソースであり、ユニフォームではありません。texture.source(TextureSource) およびtexture.source.style(TextureStyle) を、最上位のリソースエントリとして渡してください。

APIリファレンス

GitHubで見る

Custom shaders bind GLSL and WGSL programs to scene objects via Shader.from({ gl, gpu, resources }). Uniforms live in typed UniformGroups, textures are passed as separate resources, and the same shader can target both WebGL and WebGPU.

Quick Start

const uniforms = new UniformGroup({
  uTime: { value: 0, type: "f32" },
});const shader = Shader.from({
  gl: { vertex: vertexSrc, fragment: fragmentSrc },
  resources: { uniforms },
});const geometry = new MeshGeometry({
  positions: new Float32Array([0, 0, 100, 0, 100, 100, 0, 100]),
  uvs: new Float32Array([0, 0, 1, 0, 1, 1, 0, 1]),
  indices: new Uint32Array([0, 1, 2, 0, 2, 3]),
});const mesh = new Mesh({ geometry, shader });
app.stage.addChild(mesh);app.ticker.add(() => {
  shader.resources.uniforms.uniforms.uTime = performance.now() / 1000;
});

Related skills: pixijs-filters (built-in filters), pixijs-scene-mesh (custom geometry), pixijs-performance (batch optimization), pixijs-migration-v8 (shader API migration from v7).

Core Patterns

Dual-renderer shader (WebGL + WebGPU)

import { Shader, GlProgram, GpuProgram, UniformGroup } from "pixi.js";const glVertex = `...`; // GLSL vertex (write `#version 300 es` yourself if you want WebGL2/GLSL ES 3.0)
const glFragment = `...`; // GLSL fragment
const wgslSource = `...`; // WGSL combinedconst shader = Shader.from({
  gl: { vertex: glVertex, fragment: glFragment },
  gpu: {
    // entryPoint names are arbitrary; they must match the @vertex / @fragment
    // function names in your WGSL source. PixiJS ships examples using
    // 'mainVert' / 'mainFrag' but `main` is equally valid.
    vertex: { entryPoint: "mainVert", source: wgslSource },
    fragment: { entryPoint: "mainFrag", source: wgslSource },
  },
  resources: {
    myUniforms: new UniformGroup({
      uColor: { value: new Float32Array([1, 0, 0, 1]), type: "vec4<f32>" },
      uMatrix: { value: new Float32Array(16), type: "mat4x4<f32>" },
    }),
  },
});

If only gl is provided, the shader works with WebGL only. If only gpu is provided, it works with WebGPU only. The compatibleRenderers bitmask is set automatically.

GlProgram does not auto-inject #version 300 es. If you write #version 300 es yourself, PixiJS preserves it and treats the shader as GLSL ES 3.0; otherwise it injects WebGL1 compat macros (#define in varying, #define texture texture2D) and runs the shader as WebGL1-style GLSL. GlProgram always injects a default precision (highp vertex, mediump fragment) and the program name. For GLSL ES 3.0, use in/out instead of attribute/varying, texture() instead of texture2D(), and an out vec4 instead of gl_FragColor.

Textures as resources

Textures are resources, not uniforms. Pass the texture's source and style separately:

import { Shader, UniformGroup, Texture, Assets } from "pixi.js";const texture = await Assets.load("myImage.png");const shader = Shader.from({
  gl: { vertex: vertSrc, fragment: fragSrc },
  resources: {
    uTexture: texture.source,
    uSampler: texture.source.style,
    myUniforms: new UniformGroup({
      uAlpha: { value: 1.0, type: "f32" },
    }),
  },
});// Swap texture at runtime
shader.resources.uTexture = otherTexture.source;

Resources are a flat key-value map. The key must match the uniform/binding name in the shader source.

Resources can also be plain objects (auto-wrapped into UniformGroup):

const shader = Shader.from({
  gl: { vertex: vertSrc, fragment: fragSrc },
  resources: {
    myUniforms: {
      uTime: { value: 0, type: "f32" },
    },
  },
});

UBO mode (Uniform Buffer Objects)

UBO mode packs uniforms into a single GPU buffer. Required for WebGPU; optional (WebGL2+) for WebGL.

import { UniformGroup } from "pixi.js";const ubo = new UniformGroup(
  {
    uProjection: { value: new Float32Array(16), type: "mat4x4<f32>" },
    uAlpha: { value: 1.0, type: "f32" },
  },
  { ubo: true, isStatic: true },
);// Must call update() manually when isStatic is true
ubo.uniforms.uAlpha = 0.5;
ubo.update();

UBO rules:

  • Only f32 and i32 based types are supported (no u32). Matrices are float-only.
  • Samplers/textures cannot go in a UBO.
  • The UniformGroup name in resources must exactly match the UBO block name in the shader.
  • Structure and order must exactly match the shader layout.
  • UBO sync uses new Function under the hood. In strict-CSP environments (no unsafe-eval), import pixi.js/unsafe-eval once at startup to swap in the fallback sync path; without it, UBO-backed shaders (and therefore WebGPU) will throw on first use.

Custom filter

Filter.from({ gl, resources }) is the shorthand. Pass only a fragment shader; PixiJS supplies a default vertex shader that handles output frame positioning.

import { Filter } from "pixi.js";const filter = Filter.from({
  gl: {
    fragment: `
            in vec2 vTextureCoord;
            out vec4 finalColor;
            uniform sampler2D uTexture;
            uniform float uStrength;            void main(void) {
                vec4 color = texture(uTexture, vTextureCoord);
                finalColor = mix(color, vec4(1.0 - color.rgb, color.a), uStrength);
            }
        `,
  },
  resources: {
    filterUniforms: {
      uStrength: { value: 0.5, type: "f32" },
    },
  },
});filter.resources.filterUniforms.uniforms.uStrength = 1.0;

For a custom vertex shader, use new Filter({ glProgram: new GlProgram({ vertex, fragment }), resources }).

Filter shader conventions (GLSL ES 3.0)
  • in vec2 vTextureCoord; instead of varying vec2 vTextureCoord;
  • out vec4 finalColor; instead of gl_FragColor
  • texture(uTexture, uv) instead of texture2D(uTexture, uv)
  • The default vertex shader exposes uInputSize, uOutputFrame, uOutputTexture and helpers filterVertexPosition() / filterTextureCoord()
Sampling the render target behind the filter

Set blendRequired: true and sample uBackTexture in the fragment shader. PixiJS copies the destination pixels into that uniform before running the filter:

const blendFilter = Filter.from({
  gl: { fragment: blendFragSrc },
  resources: { uniforms: { uAmount: { value: 0.5, type: "f32" } } },
  blendRequired: true,
});

Only enable blendRequired when you need it; it forces an extra GPU copy every frame.

Updating uniforms at runtime

// Access the UniformGroup via resources
shader.resources.myUniforms.uniforms.uTime = performance.now() / 1000;// For isStatic UBOs, call update() after changing values
shader.resources.myUniforms.update();

Uniform type reference

See references/uniform-types.md for the complete table of supported types, their WGSL/GLSL equivalents, and value formats.

Custom Batcher (extension-based)

The Batcher abstract class enables custom batching for specialized rendering. Subclass it and register via extensions:

import { Batcher, extensions, ExtensionType } from "pixi.js";
import type {
  BatcherOptions,
  BatchableMeshElement,
  BatchableQuadElement,
  Geometry,
  Shader,
} from "pixi.js";class MyBatcher extends Batcher {
  public static extension = {
    type: [ExtensionType.Batcher],
    name: "my-batcher",
  };  public name = "my-batcher";
  protected vertexSize = 6; // floats per vertex
  public geometry: Geometry;
  public shader: Shader;  constructor(options: BatcherOptions) {
    super(options);
    // Initialize geometry and shader
  }  public packAttributes(
    element: BatchableMeshElement,
    float32View: Float32Array,
    uint32View: Uint32Array,
    index: number,
    textureId: number,
  ): void {
    // Pack mesh vertex attributes into the batch buffer
  }  public packQuadAttributes(
    element: BatchableQuadElement,
    float32View: Float32Array,
    uint32View: Uint32Array,
    index: number,
    textureId: number,
  ): void {
    // Pack quad vertex attributes into the batch buffer
  }
}extensions.add(MyBatcher);

Elements reference the batcher by batcherName. The BatchableElement interface requires: batcherName, texture, blendMode, indexSize, attributeSize, topology, and packAsQuad.

Common Mistakes

[CRITICAL] Old Shader.from(vertex, fragment, uniforms) constructor

Wrong:

const shader = Shader.from(vertex, fragment, { uTime: 1 });

Correct:

const shader = Shader.from({
  gl: { vertex, fragment },
  resources: {
    uniforms: new UniformGroup({
      uTime: { value: 1, type: "f32" },
    }),
  },
});

v8 requires an options object with gl/gpu programs and resources. The positional API was removed.

[CRITICAL] UniformGroup without type annotation

Wrong:

new UniformGroup({ uTime: 1 });

Correct:

new UniformGroup({ uTime: { value: 1, type: "f32" } });

Every uniform requires an explicit { value, type } pair. Omitting the type causes a runtime error: "Uniform type undefined is not supported."

[HIGH] UBO with unsupported types or wrong structure

UBO mode supports f32 and i32 based types (scalars and vectors). u32 is not in the supported UniformGroup type list and will throw. Matrices are float-only (mat*<f32>). Samplers cannot be placed in UBOs.

The struct name and field order must exactly match the shader's UBO declaration. Mismatches produce garbled rendering with no error.

[HIGH] Putting textures in UniformGroup

Wrong:

new UniformGroup({
  uTexture: { value: texture, type: "f32" },
});

Correct:

const shader = Shader.from({
  gl: { vertex, fragment },
  resources: {
    uTexture: texture.source,
    uSampler: texture.source.style,
    myUniforms: new UniformGroup({
      uAlpha: { value: 1.0, type: "f32" },
    }),
  },
});

Textures are resources, not uniforms. Pass texture.source (TextureSource) and texture.source.style (TextureStyle) as top-level resource entries.

API Reference

すべてのファイル

2件のファイル

pixijs-custom-renderingをインストール

スキルファイルをダウンロードし、.claude/skills/ ディレクトリに解凍してください。

ZIPをダウンロード

リポジトリをクローンし、スキルファイルをプロジェクトにコピーしてください。

git clone https://github.com/pixijs/pixijs/tree/dev/skills/pixijs-custom-rendering # Copy the skill folder to .claude/skills/ or .codex/skills/

コピー コピー
クイックセットアップ: skill フォルダを .claude/skills/ にコピーしてください。Claude が自動的にスキルを検出して使用します。
リポジトリ pixijs/pixijs

関連スキル

v4-new-features
更新された時間 2026年8月4日
pixijs-application
更新された時間 2026年8月4日
multica-creating-agents
更新された時間 2026年8月12日
agent-project-board-sync
更新された時間 2026年8月3日
OR