PyrenderのPointLightの明るさメモ


はじめに

PyrenderでOpenGLを使ってレンダリングするのに明るさをどのくらいにすればいいかわからなかったのでメモです。

やったこと

OpenGL対応の環境で以下をインストール

pip install trimesh pyrender opencv-python matplotlib

このサイトを参考に、レンダリングしました。

import os
import numpy as np
import trimesh
import cv2
import math

from pyrender import PerspectiveCamera,\
                    DirectionalLight, SpotLight, PointLight,\
                    MetallicRoughnessMaterial,\
                    Primitive, Mesh, Node, Scene,\
                    OffscreenRenderer

# モデルのロード
model_gltf = trimesh.load('./dog.glb')
model_trimesh = model_gltf.geometry[list(model_gltf.geometry.keys())[0]]
model_mesh = Mesh.from_trimesh(model_trimesh)

# モデルのAABB(軸平行境界ボックス)の中心点と辺の長さ
centroid = bottle_mesh.centroid
extents = bottle_mesh.extents

# 最大の辺が大きさ1になるように縮小
r = max(extents)
model_pose = np.array([
    [1.0/r, 0.0,  0.0, -centroid[0]/r],
    [0.0, 1.0/r, 0.0, -centroid[1]/r],
    [0.0, 0.0,  1.0/r, -centroid[2]/r],
    [0.0, 0.0,  0.0, 1.0],
])

# カメラとポイントライト作成(intensityでライトの明るさを決める)
cam = PerspectiveCamera(yfov=(np.pi / 3.0))
cam_pose = np.array([
    [1.0,  0.0,  0.0,  0.0],
    [0.0,  1.0,  0.0,  0.0],
    [0.0,  0.0,  1.0,  1.5],
    [0.0,  0.0,  0.0,  1.0]
])
light = PointLight(intensity=10)
light_pose = np.array([
    [1.0, 0.0, 0.0, 0.0],
    [0.0, 1.0, 0.0, 0.0],
    [0.0, 0.0, 1.0, 1.5],
    [0.0, 0.0, 0.0, 1.0]
])

# Sceneの作成
scene = Scene()
# scene = Scene(ambient_light=np.array([1.0, 1.0, 1.0, 1.0])) # アンビエントライトを使う場合

# Sceneにカメラとモデルとライトを追加
model_node = scene.add(model_mesh, pose=model_pose)
cam_node = scene.add(cam, pose=cam_pose)
light_node = scene.add(light, pose=light_pose)

# レンダリング
r = OffscreenRenderer(viewport_width=width, viewport_height=height)
color, depth = r.render(scene)
r.delete()
cv2.COLOR_BGR2GRAY
color = cv2.cvtColor(color,cv2.COLOR_RGB2BGR)
result, color = cv2.imencode('.jpg', color)
thumbnail = base64.b64encode(color).decode('utf-8')
cv2.imwrite('./dog.png',color) # 保存

下の表は実行結果です。
ポイントライトの明るさをintensityで与えますが、どのくらいの明るさにすればいいかわかりづらいです。カメラとライトを同じ位置にしてライトの明るさを変えたときのモデルの見え方の違いを載せています。モデルとの距離にもよりますが参考までに...

アンビエントライトのみ アンビエントライトなし intensity=10 intensity=100 intensity=1000 intensity=10000

アンビエントライトを使うと3Dモデルの立体感がわかりづらいです。なので立体感を出したいときはアンビエントライトはなしがいいように思います。

おわりに

この条件だとintensityは10くらいがよさげです。

間違い等ありましたらご指摘いただければ幸いです。