shader-programming-glsl について
GLSLでGPUシェーダーを作成する開発者向けのガイドです。シェーダー構造、変数、ベクトル演算、レンダリングの実践に加え、WebGLの例やコンパイル時のトラブル対処を扱います。
主な機能
- 01頂点シェーダーとフラグメントシェーダーの解説
- 02uniformとvaryingの説明
- 03ベクトル演算とスウィズリングの解説
- 04レイマーチングの例
- 05コンパイル対処と性能上のヒント
活用シーン
- 01WebGLやゲームエンジンでの視覚効果作成
- 02ぼかし、ブルーム、色補正の実装
- 03GPU上でのテクスチャやジオメトリ生成
- 04シェーダーのコンパイルや黒画面の問題調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ sickn33/ agentic-awesome-skills --skill shader-programming-glslインストール後、Claude Code で/shader-programming-glslを入力して読み込まれたか確認します。
詳細
シェーダープログラミング GLSL
概要
GLSL(OpenGL Shading Language)を使って GPU シェーダーを作成するための包括的なガイドです。構文、ユニフォーム、バリイング変数、スウィズリングやベクトル演算などの視覚効果に関わる重要な数学的概念を学びます。
このスキルを使用する場面
- WebGL、Three.js、ゲームエンジンでカスタム視覚効果を作成するときに使用します。
- グラフィックスのレンダリングパフォーマンスを最適化するときに使用します。
- ポストプロセス効果(ぼかし、ブルーム、色補正)を実装するときに使用します。
- GPU 上でテクスチャやジオメトリをプロシージャルに生成するときに使用します。
手順ガイド
1. 構造:頂点シェーダーとフラグメントシェーダー
以下の基本構文は GLSL ES 1.00/WebGL 1 を対象としています。ホストエンジンが行列や属性を挿入する場合がありますが、raw WebGL では明示的にバインドする必要があります。GLSL ES 3.00 では、attribute/varying/gl_FragColor の代わりに in/out と、宣言されたフラグメント出力を使用します。頂点シェーダーとフラグメントシェーダーを個別にコンパイルしてプログラムにリンクし、コンパイルおよびリンクのログを確認してください。
パイプラインを理解しましょう。
- 頂点シェーダー:3D 座標を 2D のスクリーン空間に変換します(
gl_Position)。 - フラグメントシェーダー:個々のピクセルに色を付けます(
gl_FragColor)。
// Vertex Shader (basic)
attribute vec3 position;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
void main() {
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
// Fragment Shader (basic)
precision mediump float;
uniform vec3 color;
void main() {
gl_FragColor = vec4(color, 1.0);
}
2. ユニフォームとバリイング
uniform:すべての頂点/フラグメントで一定のデータです(CPU から渡されます)。varying:頂点シェーダーからフラグメントシェーダーへ補間されるデータです。
// Separate vertex and fragment shader snippets; both declare varying vec2 vUv.
// Vertex shader also needs attribute vec2 uv and the matrices/position above.
// Raw WebGL fragment shader needs a float precision declaration.
varying vec2 vUv;
// In Vertex Shader
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
// In Fragment Shader
void main() {
// Gradient based on UV
gl_FragColor = vec4(vUv.x, vUv.y, 1.0, 1.0);
}
3. スウィズリングとベクトル演算
ベクトルの各成分には自由にアクセスできます:vec4 color = vec4(1.0, 0.5, 0.0, 1.0);
color.rgb->vec3(1.0, 0.5, 0.0)color.zyx->vec3(0.0, 0.5, 1.0)(並べ替え)
例
例 1:シンプルなレイマーチング(SDF 球体)
これは Shadertoy 形式のフラグメントエントリーポイントで、ホストから提供される iResolution を使用します。raw WebGL で使用するにはホストラッパーが必要です。
float sdSphere(vec3 p, float s) {
return length(p) - s;
}
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
vec2 uv = (fragCoord - 0.5 * iResolution.xy) / iResolution.y;
vec3 ro = vec3(0.0, 0.0, -3.0); // Ray Origin
vec3 rd = normalize(vec3(uv, 1.0)); // Ray Direction
float t = 0.0;
bool hit = false;
for(int i = 0; i < 64; i++) {
vec3 p = ro + rd * t;
float d = sdSphere(p, 1.0); // Sphere radius 1.0
if(d < 0.001) { hit = true; break; }
t += d;
if(t > 10.0) break;
}
vec3 col = vec3(0.0);
if(hit) {
vec3 p = ro + rd * t;
vec3 normal = normalize(p);
col = normal * 0.5 + 0.5; // Color by normal
}
fragColor = vec4(col, 1.0);
}
ベストプラクティス
- ✅ 推奨: 手動計算ではなく、線形補間に
mix()を使用します。 - ✅ 推奨: 閾値処理やソフトエッジには
step()とsmoothstep()を使用します(if分岐は避けてください)。 - ✅ 推奨: メモリアクセスを最小限にするため、データをベクトル(
vec4)にまとめます。 - ❌ 非推奨: 可能であれば、ループ内で重い分岐(
if-else)を使用しないでください。GPU の並列処理に悪影響を与えます。 - ❌ 非推奨: シェーダー内で定数値を計算しないでください。CPU 側で事前計算します(ユニフォーム)。
トラブルシューティング
問題: シェーダーはコンパイルされるものの、画面が黒いです。
解決策: クリップ空間変換全体と、同次座標 gl_Position.w を確認してください。透視投影で w = 1 になるとは限りません。ユニフォームがホストアプリケーションから実際に設定されているか確認してください。UV 座標が [0, 1] の範囲内にあることを確認してください。
GLSL ES のフラグメント精度の移植性については、Khronos のガイダンスを参照してください。分岐やベクトル化の最適化は、対象 GPU でプロファイリングしてください。これらのスタイル上の推奨事項は、速度向上を保証するものではありません。
制限事項
- このスキルは、タスクが上記の説明の範囲に明確に該当する場合にのみ使用してください。
- 出力を、環境固有の検証、テスト、または専門家によるレビューの代わりとして扱わないでください。
- 必要な入力、権限、安全上の境界、または成功基準が不足している場合は、作業を中断して確認を求めてください。