戒めのMitsuba2

レイトレベースのdifferentiable rendererとしてMitsuba2が広く知られています。

github.com

Mitsuba2の使い方に関しては、公式Installationの他、以下の記事が参考になります。

日本語のDocumentationも充実してきたので、自宅Windows PCにも導入しようとしたところコケたのでメモ。

  • Windowsで使いたい場合、ShellはGit BashかAnaconda script, Anaconda PowerShellを用いること
    • Powershellやmsys2, WSLでは動かないっぽい
    • Python側から呼びたい場合はGitBash上でも無理っぽい。人間はAnacondaから逃げられない。

github.com

  • Mitsuba2 Blenderと組み合わせたい場合は、Mitsuba2 build時に用いるPythonのVersionは3.7系にしておく

github.com

これくらいの短いコードでTextureの最適化ができるのは嬉しいですね!

import os
import cv2
import numpy as np
import enoki as ek
import mitsuba
mitsuba.set_variant('gpu_autodiff_rgb')


if __name__ == "__main__":
    import time
    from mitsuba.python.autodiff import render, write_bitmap, Adam
    from mitsuba.python.util import traverse
    from mitsuba.core import Thread
    from mitsuba.core.xml import load_file

    filename = './unchan/unchan.xml'
    Thread.thread().file_resolver().append(os.path.dirname(filename))
    scene = load_file(filename)

    # Initialize source texture
    params = traverse(scene)
    tex_res = params['OBJMesh.bsdf.reflectance.resolution']
    params.keep(['OBJMesh.bsdf.reflectance.data'])
    params.update()

    # Load a reference image
    image_ref = cv2.imread("./target_unchan.jpg")
    image_ref = cv2.cvtColor(image_ref, cv2.COLOR_BGR2RGB)
    image_ref = image_ref.flatten() / 255.0
    crop_size = scene.sensors()[0].film().crop_size()

    # Construct an Adam optimizer that will adjust the parameters 'params'
    opt = Adam(params, lr=.2)
    time_a = time.time()

    iterations = 100
    for it in range(iterations):
        image = render(scene, optimizer=opt, unbiased=True, spp=16)
        write_bitmap('./out/out_%03i.png' % it, image, crop_size)
        write_bitmap('./out/opttex_%03i.png' % it, params['OBJMesh.bsdf.reflectance.data'],
                     (tex_res[0], tex_res[1]))

        ob_val = ek.hsum(ek.sqr(image - image_ref)) / len(image)
        ek.backward(ob_val)
        opt.step()

    time_b = time.time()
    print('%f ms per iteration' % (((time_b - time_a) * 1000) / iterations))

source scene中のalbedo textureをtarget imageの見た目に合う様に最適化している様子*1

f:id:mocobt:20210113225359g:plain

Mitsuba2すごい!

なお、データはおめがシスターズさんからお借りしました。

*1:本当にalbedoなのかは謎