【Blender】IESデータを使う、ついでにCubemap化してUnityのLightのCookieで使いたい

Pocket
LinkedIn にシェア
LINEで送る

最近知ったんですが、Blender 2.8からIESファイルの読み込みに対応していたんですね。早く知りたかった。建築だと今も割と現役なIESデータですから、使わない手はないんです。

というのと最近、Unityでちゃかちゃかとまたビジュアライゼーションをやることになったこともあり、IESデータが欲しいんです。UnityだとIESファイル自体は使えなくて、Cookieと呼ばれていますが、配光データとしてモノクロのCubemapデータが必要となります。ちょっと面倒くさいんです。

ということで、まずはBlender 2.8でIESの適用方法を確認して、次にBlenderで画像を作成してUnityのCookieも作ってしまおうか。ということをしてみようと思います。

BlenderでIESファイルを使用する

1.Lightの設定

Point Lightを配置したら[Object Data Propaties]を開きます。
[use nodes]を選択。するとcolorとstrengthが出てきます。

[strength]の左側の[○]を選択しまして[IES Texture]を選択。パッと見みつからないように見えますが、選択肢の上の方にあります。

すると[source]というのが追加されます。
次に[External]を選択します。するとファイルを参照できるような表示に変わります。

フォルダアイコンを押して、IESファイルを選択して開きましょう。

これでPoint LightにIESデータが適用されます。光り方が変わったでしょう。

ちなみに単純なPoint Lightだけと、IESの2種類での光り方の比較をしてみました。全然変わりますね。

通常のPoint Light IESを適用したPoint Light

BlenderのIESからUnityのCookieを作ってみよう

さて本題。UnityのCookieを作ってみたいと思います。
注意:最初にことわっておきますが、この方法は光学的には全然正しくないです。配光特性は一致していて、強さは相対的に合っているらしい程度と割り切ってください。

1.Blender

Pythonスクリプトを使います。
次のようなMeshのSphere、Point Light、Cameraの3つを置いたシーンを用意します。

  ちなみにGithubにこちらの.blenderファイルを用意していますので、どうぞ。
  christinayan01/demo/Blender_Light_IES_to_Unity_Cookie – Github
  ies2equirec.blend

●MeshのSphere
座標は[X,Y,Z]=[0,0,0]にします。
半径は1m。
次に面を反転します。編集モード→全部の面を選択→Shift+Nキー→裏面Apply で、全部ひっくり返ります。プラネタリウムみたいな状態です。

●Point Light
座標は[X,Y,Z]=[0,0,0]にします。
IES Textureは先程の説明しています。

●Camera
座標は[X,Y,Z]=[0,0,0]にします。
[Camera]を選択してプロパティを開きます。
 [Field of View]を90 Degreeにします。
次にレンダリング設定へ。[Scene]を選択して、レンダリング解像度[Resolution X]と[Y]を決めます。
 [Resolution X]と[Y]は同じ値にしてください。数値はできるだけ2の階乗にします。
 [%]は100%で。

この状態でRotationのXYZを変更して、前、後、左、右、上、下の6枚をレンダリングします。

キューブマップ生成ツールを使う

6枚の画像をCubeMapに結合するツールを作ってみました。よければ使ってみてください。

  Githubにこちらにexeを用意していますので、どうぞ。
  christinayan01/demo/Blender_Light_IES_to_Unity_Cookie – Github
  ies2cookie.zip

 ies2cookie.exeの使い方:Blenderで作成した6枚の画像とIESファイルを特定のフォルダに置きます。
  起動引数に特定のフォルダを指定して起動します。
  (例)
   モジュールのパス:D:\ies2cookie\ies2cookie.exe
   画像を置いたフォルダ:D:\ies
   このときアプリは 「D:\ies2cookie\ies2cookie.exe D:\ies」 で起動します。     
 ルール:6枚のファイルのネーミングルールです。接尾語が必要です。
   左:{filename}_l.png
   右:{filename}_r.png
   前:{filename}_f.png
   後:{filename}_b.png
   上:{filename}_u.png
   下:{filename}_d.png
 フォーマット:jpg、png、tif

結合するとこんな風に1枚の画像になります。

2.Unity

出来上がったCookie用のCubeMapをUnity側にインポートします。

[Inspector]でCookieの設定をします。このとき次のように設定してください。
 Texture Type: Cookie
 Mapping: 6 Frames Layout
 Light Type: Point
 Alpha Source: From Gray Scale

最後に[Apply]します

Point Lightを置いて、Coooieにテクスチャをセットしてみてください。

完成

UnityでもIESと同じ配光になりました。
最初に言いましたが、光の向きと、光の相対的な強さがそれなりにIESから引き継げました。

スクリプト化

さていつものです。自動化しましょう。
IESファイルが5、6個だったら手作業でいいと思いますが、私は200個くらい変換したいので腱鞘炎必至です。ということでスクリプトで書きます。

BlenderのPythonスクリプトです。
・予めIESファイルをC:\Temp\IES\フォルダ以下に置いてください。
・「ここを設定してください」を自分の環境に合わせてください。

import glob
import os
import pathlib
import math

##ここを設定してください
RESOLUTION = 256
IES_DIR = 'D:/Temp/IES'
##

#カメラの向きをセットする
def set_camera(i):
  arg_x = [90, 90, 90, 90, 180, 0]
  arg_y = [0, 0, 0, 0, 0, 0]
  arg_z = [0, 180, 90, -90, 0, 0]
  # select camera
  bpy.ops.object.select_all(action='DESELECT')
  objectToSelect = bpy.data.objects["Camera"]
  objectToSelect.select_set(True)    
  bpy.context.view_layer.objects.active = objectToSelect
  # set camera rotation as euler
  bpy.context.active_object.rotation_euler[0] = math.radians(arg_x[i])
  bpy.context.active_object.rotation_euler[1] = math.radians(arg_y[i])
  bpy.context.active_object.rotation_euler[2] = math.radians(arg_z[i])

#レンダリング解像度を設定
scene = bpy.data.scenes["Scene"]
scene.render.resolution_x = RESOLUTION
scene.render.resolution_y = RESOLUTION

#メイン処理
files = glob.glob(IES_DIR + '/**/*.ies', recursive=True)
for file in files:
  #print(file)
  #文字列生成
  dir = os.path.dirname(file) 
  name = os.path.splitext(os.path.basename(file))[0]
  dir_path = str( pathlib.Path(file) )
  file_out = dir + '/' + name + '.png'
  print(file_out)
  #
  #IESファイルを変更
  #object = bpy.data.objects['Light']
  #ノードエディタのIES Textureノードを得る
  bpy.ops.object.select_all(action='DESELECT')
  objectToSelect = bpy.data.objects["Light"]
  objectToSelect.select_set(True)    
  bpy.context.view_layer.objects.active = objectToSelect
  ies_node = bpy.data.lights['Light'].node_tree.nodes["IES Texture"]
  ies_node.filepath = file
  #前後左右上下の順序で6回レンダリング
  for i in range(6):
    #
    #カメラの向きをセット
    set_camera(i)
    #
    #レンダリングして保存
    print('## Start rendering... ##')
    bpy.ops.render.render()
    postfix = ['_f', '_b', '_l', '_r', '_u', '_d']
    file_out = dir + '/' + name + postfix[i] + '.png'
    bpy.data.images['Render Result'].save_render(filepath=file_out)
    print('finish exporting file: file_out')

参考サイト

ShaderNodeTexIES(ShaderNode) – Blender Python API
概要 – IES 標準ファイル形式 – AutoCADサポート
Lightの明暗を調整するマスク処理 – Package「Light Cookies」 – 強火で進め

管理人が読んだおすすめの建築本

    

コメントを残す