メインコンテンツまでスキップ

カスタムシェーダー

PlayCanvas Engineでは、gsplatModifyVSシェーダーチャンクをオーバーライドすることで、Gaussian Splatsのレンダリング方法をカスタマイズできます。このチャンクはシーン全体のgsplatマテリアル(app.scene.gsplat.material)に設定されるため、1つのカスタムシェーダーがシーン内のすべてのスプラットに適用されます。

ライブサンプルを見る - アニメーションスプラットでシェーダーチャンクのカスタマイズを実際に見てください。

Multi Splat

オーバーライド可能な関数

gsplatModifyVSチャンクでは、スプラットの頂点ステージで3つの関数をオーバーライドできます:

関数目的
modifySplatCenterスプラットの中心位置を変換(モデル空間)
modifySplatRotationScaleスプラットの回転クォータニオンとスケールを調整
modifySplatColorスプラットの色と不透明度を変換
void modifySplatCenter(inout vec3 center);
void modifySplatRotationScale(vec3 originalCenter, vec3 modifiedCenter, inout vec4 rotation, inout vec3 scale);
void modifySplatColor(vec3 center, inout vec4 color);

変更したい関数だけを実装すれば十分です。

サンプルの仕組み

上記のライブサンプルは、サイン波による変位と金色のカラーパルスですべてのスプラットをアニメーションさせています。これは3つのステップで構成されます。

1. シェーダーチャンクを記述し、必要な関数をオーバーライドします。サンプルではuTimeユニフォームを使ってアニメーションさせています:

uniform float uTime;

void modifySplatCenter(inout vec3 center) {
float heightIntensity = center.y * 0.2;
center.x += sin(uTime * 5.0 + center.y) * 0.3 * heightIntensity;
}

void modifySplatRotationScale(vec3 originalCenter, vec3 modifiedCenter, inout vec4 rotation, inout vec3 scale) {
// 変更なし
}

void modifySplatColor(vec3 center, inout vec4 clr) {
float sineValue = abs(sin(uTime * 5.0 + center.y));
vec3 gold = vec3(1.0, 0.85, 0.0);
float blend = smoothstep(0.9, 1.0, sineValue);
clr.xyz = mix(clr.xyz, gold, blend);
}

2. チャンクをシーンのgsplatマテリアルに適用し、マテリアルを更新して再コンパイルします。GLSLとWGSLの両方のチャンクを設定すると、WebGLとWebGPUの両方のデバイスに対応できます:

const sceneMat = app.scene.gsplat.material;

sceneMat.getShaderChunks('glsl').set('gsplatModifyVS', glslVertShader);
sceneMat.getShaderChunks('wgsl').set('gsplatModifyVS', wgslVertShader);
sceneMat.update();

3. ユニフォームを毎フレーム更新します:

let currentTime = 0;
app.on('update', (dt) => {
currentTime += dt;
sceneMat.setParameter('uTime', currentTime);
sceneMat.update();
});

カスタムシェーダーの削除

デフォルトのレンダリングに戻すには、チャンクのオーバーライドを削除してマテリアルを更新します:

const sceneMat = app.scene.gsplat.material;
sceneMat.getShaderChunks('glsl').delete('gsplatModifyVS');
sceneMat.getShaderChunks('wgsl').delete('gsplatModifyVS');
sceneMat.update();

関連項目