kumak1’s blog

kumak1のイラストや技術ログ

Unity Shader で 0~ 1 の値を扱う際の雑メモ

shader というか、ベクトル 演算する際には 0 ~ 1 の Normalize された値をよく使う。 Unity でこういった値を扱う際、「Mac (Radeon Pro 460) だと大丈夫だけど、Windows (Geforce GTX 1060) だと意図した表示にならない!」みたいな事が頻発する(特にlerpの第三引数)。 両者には、API が Metal か DirectX か、ハードウェアが OpenGL 最適化か DirectX 最適化か、といった違いがあるためどちらが原因になっているかはわからないが、 float の演算精度が異なるのは確実だ。 特に、「乗算いっぱいしてるけど、どう計算しても 0 ~ 1 になるから大丈夫だよね!」というケースで泣きを見る事が多い。 「どちらでも(ある程度)同一の表示をしたいなら、プログラム側で補正する」のが安全のようだ。 拙いながらも同一表示にできた経験をメモしておく。

0 あるいは 1 を使う場合

step() を必ず通す

0 ~ 1 を使う場合

saturate() clamp() を必ず通す

色を扱う場合

inline half3 clip_color(half3 color)
{
    color.x = clamp(color.x, 0.001h, 0.999h);
    color.y = clamp(color.y, 0.001h, 0.999h);
    color.z = clamp(color.z, 0.001h, 0.999h);
    return color;
}

上記のようなフィルタを通して 完全な白 完全な黒 にならないようにする。