mieki256's diary



2024/11/22(金) [n年前の日記]

#1 [blender] blenderでobjエクスポートした際の色について調べてた。その2

_昨日 に引き続き、blender 4.2.3 LTS で svg をインポートして Wavefront (.obj) でエクスポートした際に、マテリアルカラー(.mtl) 内の値(Kd、Diffuse color)が svg のソレとは全然違う値になる/全体的に色が暗くなる件について調べてた。

svg をインポートした際に、scripts\addons\io_curve_svg\import_svg.py 内で、srgb_to_linearrgb() を経由してRGB値が変換されることは分かった。ということは、逆の計算をする関数を作れば、.mtl内のRGB値を、元々のsvgのRGB値に戻すことができるのではないかと。

関数の名前からして、逆の計算をする関数が ―― linearrgb_to_srgb() が既に書かれてそうだなと…。ググってみたら見つかった。

_color management - What's the exact gamma correction Blender uses? - Blender Stack Exchange
_blender/source/blender/blenlib/intern/math_color.c at master - dfelinto/blender
_#94202 - crash or error when using GPUFrameBuffer.read_color(... data=data) - blender - Blender Projects
_FBX SDK Python2020 の使用例2(マテリアル書き込み編 ブレンダーからクリップスタジオモデラーマテリアル画面へ)|ハイドロキャリス

C言語で書かれている事例は以下。
float linearrgb_to_srgb(float c)
{
  if (c < 0.0031308f) {
    return (c < 0.0f) ? 0.0f : c * 12.92f;
  }

  return 1.055f * powf(c, 1.0f / 2.4f) - 0.055f;
}

Pythonで書くなら以下になるのだろうか。
def linearrgb_to_srgb(c):
    if c < 0.0031308:
        if c < 0.0:
            return 0.0
        return c * 12.92
    return (1.055 * pow(c, (1.0 / 2.4)) - 0.055)

検証 :

手持ちのsvgファイル内では「#242424」と書かれていたRGB値が、blenderからエクスポートした .mtl内では以下の値になっていた。

newmtl Black01
Ns 96.078431
Ka 1.000000 1.000000 1.000000
Kd 0.017642 0.017642 0.017642
Ks 0.500000 0.500000 0.500000
Ke 0.000000 0.000000 0.000000
Ni 1.000000
d 1.000000
illum 0

PythonのIDLE上で計算してみる。
>>> hex(int(0.017642 * 255.0))
'0x4'
0x24 になってほしいのに、0x04 になってる。全然違う。

linearrgb_to_srgb() を定義して試してみた。
>>> def linearrgb_to_srgb(c):
...     if c < 0.0031308:
...         if c < 0.0:
...             return 0.0
...         return c * 12.92
...     return (1.055 * pow(c, (1.0 / 2.4)) - 0.055)
... 
>>> hex(int(linearrgb_to_srgb(0.017642) * 255.0))
'0x24'

0x24になった。合ってる気がする。

他の値も入れて確認してみたけれど、一部の値で誤差が出るのか全てがピッタリにはならなかったものの、ほとんど大体は合ってる値になった。

ということで、blender からエクスポートした Wavefront (.obj) の色が全体的に暗い場合は、この関数を通してRGB値を求め直してやれば本来のRGB値に近づいてくれる可能性が高い。

ただ、blender に .obj をインポートする際は、RGB値を変更しちゃうと二重に変換がかかってしまってマズイことになりそう。

実際に表示してみた :

しばらく前に、Wavefront形式(.obj .mtl)を読み込んで、C言語のヘッダファイルの形に変換するPythonスクリプトを書いたのだけど。

_mieki256's diary - OpenGLでモデルデータを読み込めそうか調べてる。その6

そのスクリプトに、前述の関数を追加して、.mtl内の Kd にガンマ補正をかけたRGB値を出力するように修正して、見た目がどう変わるか確認してみた。

せっかくだから github にアップロードしておいた。pyobj2c.py が、obj → c に変換するPythonスクリプト。

_mieki256/pyobj2c

OpenGLで描画するサンプルソース 01_drawobj.c をコンパイルして動かしてみた。スクリーンショットを以下の順番で並べてある。
  1. blender 4.2.3 LTSのマテリアルプレビュー
  2. pyobj2c.pyでガンマ補正した描画結果
  3. ガンマ補正無しの描画結果

blender423_ss02.png
01_drawobj_ss11_gamma.png
01_drawobj_ss11.png

blender423_ss01.png
01_drawobj_ss12_gamma.png
01_drawobj_ss12.png

blender423_ss03.png
01_drawobj_ss13_gamma.png
01_drawobj_ss13.png

ガンマ補正をかけたほうが、全体的に色が明るくなって、blender上での見た目に近い色になっていることが分かる。まあ、照明の当て方次第で色は変わってしまうものだけど…。それでも、今までの .obj .mtl より全然マシな見た目になってくれたかなと…。

以上です。

過去ログ表示

Prev - 2024/11 -
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project