Skip to content

第02回 HLSL の制御構文と反復計算

前回: 第01回 Shader Graph から HLSL へ

今回の授業内容

  • ifforbreak の役割を理解する
  • 上限回数を持つ安全なループを設計する
  • 反復で縞模様と近傍サンプリングを実装する
  • 分岐と steplerp の使い分けを比較する
  • 反復回数と描画負荷の関係を確認する

GPU の制御構文

GPU は多数のピクセルを並列に処理します。隣接するピクセルが異なる分岐へ進むと、両方の経路を計算する必要が生じる場合があります。分岐は禁止ではありませんが、画面全体で細かく切り替わる分岐は注意します。

hlsl
float mask;
if (value >= threshold)
{
    mask = 1.0;
}
else
{
    mask = 0.0;
}

このような2値化は step(threshold, value) でも記述できます。計算の意味が明確で、補間で置き換えられる場合は stepsmoothsteplerp を優先します。

上限付きループ

シェーダーのループは、終了条件と最大回数を明確にします。実行時の値だけを条件にした無制限の while は使いません。

hlsl
static const int MAX_ITERATIONS = 16;

float sum = 0.0;
for (int i = 0; i < MAX_ITERATIONS; i++)
{
    if (i >= iterationCount)
    {
        break;
    }
    sum += 1.0 / (i + 1.0);
}

MAX_ITERATIONS はシェーダーが実行する可能性のある上限です。iterationCount はマテリアルから変更する品質設定です。

反復で縞模様を作る

UV を回転しながら複数の波を重ねます。

hlsl
void IterativePattern_float(
    float2 UV,
    float Time,
    float Iterations,
    out float Out)
{
    float2 p = UV * 2.0 - 1.0;
    float value = 0.0;
    float2x2 rotation = float2x2(0.8, -0.6, 0.6, 0.8);

    [loop]
    for (int i = 0; i < 12; i++)
    {
        if (i >= (int)Iterations) break;
        p = mul(rotation, p) * 1.25;
        value += sin(p.x * 4.0 + Time + i) * 0.5 + 0.5;
    }

    Out = value / max(Iterations, 1.0);
}

反復ごとに UV の向きと大きさを変えることで、単一の正弦波より複雑な模様になります。

実習:近傍サンプリングでぼかす

テクスチャーの左右を複数回読み、平均を取ります。

hlsl
float3 color = 0.0;
float weight = 0.0;

for (int x = -4; x <= 4; x++)
{
    if (abs(x) > radius) continue;
    float2 offset = float2(x * texelSize.x, 0.0);
    color += SAMPLE_TEXTURE2D(textureName, samplerName, uv + offset).rgb;
    weight += 1.0;
}

color /= max(weight, 1.0);

Custom Function Node にテクスチャーを渡す方法は Shader Graph のバージョンによりラッパー型が使われます。この実習では教員が用意したテンプレートを使い、反復回数とサンプリングの意味に集中します。

授業内課題:品質設定を作る

  1. 反復回数を4、8、12に切り替える
  2. 各設定で模様またはぼかしの差を確認する
  3. Game View の Stats または Profiler でフレーム時間を比較する
  4. 低、中、高品質の推奨値を記録する

完成条件

  • for ループに固定の最大回数がある
  • プロパティで実際の反復回数を調整できる
  • 反復回数による品質と負荷の違いを説明できる

今回のまとめ

HLSL の分岐とループにより、Shader Graph のノードを大量に複製せず反復計算を記述できます。ループは常に最大回数を決め、品質と処理量をセットで設計します。

次回: 第03回 プロシージャルノイズと FBM