C++ ときどき ごはん、わりとてぃーぶれいく☆

USAGI.NETWORKのなかのひとのブログ。主にC++。

UE4 の Material における Sampler の Sampler Type の Color と Linear Color の違い、対応する Texture と使い所について

Quiz: どんな描画結果が得られるでしょう?😃

  • ↓のX軸方向にR値が 0 から 255 へ線形に変化するだけの 8 bit/channel の PNG 画像を

f:id:USAGI-WRP:20190214143144p:plain

  • UE4 へテクスチャーとしてインポートし、
  • マテリアルを作成して↓のノードを組み2値化を実装した
    • サンプラーノードの Parameter Name を t へ変更した
    • サンプラーノードの Texture の default をインポートしたテクスチャーへ変更した
    • サンプラーノードの他のパラメーターは初期値のまま変更せず、図のように他のノードを組んで完成とした

f:id:USAGI-WRP:20190215052544p:plain

このマテリアルの描画結果はどのようになるか、マテリアルのプレビューをプレーン・プリミティブとしてZY平面をX軸+側(正面)から表示した場合の特徴がわかるように回答せよ。(3点)

ヒント

画像を UE4 ではなく、一般的なラスター画像の編集アプリで R=0 ... 127 を黒、 R=128 ... 255 を2値化すると↓のようになる。

f:id:USAGI-WRP:20190214144453p:plain

つまりこの問題では↑のようにはならない。

さてどうなるでしょう?

どうしてでしょう??

こたえ

↓こうなる💀

f:id:USAGI-WRP:20190214144835p:plain

知らないと UE4 がバグってるとしか思えない…かもしれない😂

どうしてそうなるのか?

UE4 のマテリアルのサンプラーノードの Samplpe Type パラメーターの初期値は Color になっている。この Color は sRGB 色空間に展開された色なので UNORM の値 [0 ... 1] に対して 0.5 を中心に想定した2値化は「こたえ」のような結果になる。ちなみにおよそ 0.21 を中心に2値化するとこの例ではプレビューのプレーンのちょうど真ん中くらいで黒と白に分かれた結果になる。それくらい sRGB 色空間の R 値は "ずれ" ている。

ユーザーの心理としては「 sRGB になんて設定してないよ😂」なのだけど、 UE4 はインポートした PNG 画像のテクスチャーは初期値として sRGB のテクスチャーにしてしまう。意匠設計担当さんにはイイハナシダナーってなるかもしれないけど、プログラマー的にはちょっとしたホラー😱

sRGB ではなく、数値的に単純な UNORM 値としてテクスチャーを扱いたい場合は、

すると、 0.5 で2値化しても

f:id:USAGI-WRP:20190214151026p:plain

↑こうなる😃

でっていう?

GPGPUGPGPU とわざわざ呼ばれていた太古の昔の時代は、もちろん Compute Shader や Stream Out みたいな便利な仕組みは整理されていなくて、 GPGPU の先人たちは半ば狂人扱いされながら GPU の計算、つまるところ頂点と色の計算に四苦八苦しながら値の意味論(セマンティクス)を無理やり本来の GPU の用途を引っ剥がしてどうにかこうにか使う道を…

*ながくなりそうなので自主規制*

現在でも、 UE4 を扱う場合でも、 GPU での頂点や色の計算中に参照するためのデータテーブルをテクスチャー画像に乗せて扱いたいって、そういう事もあったりする。そんな時、この事を忘れてしまっていると、なにかおかしい計算結果を生成してしまう。

なお、私は今日も本件でヒヤリハットしたのでブログに愉快なクイズ形式で書き留め、自戒としたのでした🐰 あぶないあぶない。