Rendering quad

This example describes how to render a simple scene containing a quad represented by two triangles. The code starts again with lm::init() function.

[1]:
import lmenv
lmenv.load('.lmenv')
[1]:
Namespace(bin_path='/lightmetrica-v3/_build/bin', path='/lightmetrica-v3', scene_path='/lm3/scenes')
[2]:
import numpy as np
import imageio
%matplotlib inline
import matplotlib.pyplot as plt
import lightmetrica as lm
%load_ext lightmetrica_jupyter
[3]:
lm.init()
lm.log.init('jupyter')
lm.progress.init('jupyter')
lm.info()
[I|0.000] Lightmetrica -- Version 3.0.0 (rev. 70601db) Linux x64

Similarly we define the assets. In addition to film, we define camera, mesh, and material. Although the types of assets are different, we can use consistent interface to define the assets: lm::load_*() functions. Here we prepare for a pinhole camera (camera::pinhole), a raw mesh (mesh::raw), and a diffuse material (material::diffuse) with the corrsponding parameters. Please refer to Built-in component reference for the detailed description of the parameters.

[5]:
# Film for the rendered image
film = lm.load_film('film', 'bitmap', w=1920, h=1080)

# Pinhole camera
camera = lm.load_camera('camera', 'pinhole',
    position=[0,0,5],
    center=[0,0,0],
    up=[0,1,0],
    vfov=30,
    aspect=16/9)

# Load mesh with raw vertex data
mesh = lm.load_mesh('mesh', 'raw',
    ps=[-1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1],
    ns=[0,0,1],
    ts=[0,0,1,0,1,1,0,1],
    fs={
        'p': [0,1,2,0,2,3],
        'n': [0,0,0,0,0,0],
        't': [0,1,2,0,2,3]
    })

# Material
material = lm.load_material('material', 'diffuse', Kd=[1,1,1])
[I|0.016] Loading asset [name='film']
[I|0.094] Loading asset [name='camera']
[I|0.095] Loading asset [name='mesh']
[I|0.095] Loading asset [name='material']

Next we will create a scene asset. The scene asset can also be created load_scene() function. Here, we will create scene::default asset. A scene internally uses acceleration structure for ray-scene intersections, which can be specified by accel parameter.

[6]:
accel = lm.load_accel('accel', 'sahbvh')
scene = lm.load_scene('scene', 'default', accel=accel)
[I|0.102] Loading asset [name='accel']
[I|0.103] Loading asset [name='scene']

The scene of Lightmetrica is defined by a set of primitives. A primitive specifies an object inside the scene by associating geometries and materials. We can define a primitive by lm::Scene::add_primitive() function.

Note

If you need transformation applied to the geometry, you can use lm::Scene::add_transformed_primitive() function. The transformation is given by 4x4 matrix.

In this example we define two pritimives; one for camera and the other for quad mesh with diffuse material. We don’t apply any transformation to the geometry, so we use lm::Scene::add_primitive() function.

Note

Specifically, the scene is represented by a scene graph, a directed acyclic graph representing spatial structure and attributes of the scene. Each node of the scene graph describes either a primitive or a pritmive group. We provide a set of APIs to manipulate the structure of scene graph for advanced usage like instancing.

[7]:
scene.add_primitive(camera=camera)
scene.add_primitive(mesh=mesh, material=material)

After the configuration of the primitives, we must build the scene, which can be done by lm::Scene::build() function.

[8]:
scene.build()
[I|0.115] Building acceleration structure [name='accel']
[I|0.115] .. Flattening scene
[I|0.115] .. Building

Nowe we are ready for rendering. Here we will use renderer::raycast asset, which takes scene as a parameter. The rendered image will out written in the film asset specified by output parameter. We can also configure the background color with bg_color parameter.

[9]:
renderer = lm.load_renderer('renderer', 'raycast',
    scene=scene,
    output=film,
    bg_color=[0,0,0])
renderer.render()
[I|0.122] Loading asset [name='renderer']
[9]:
{'elapsed': 0.80884675}
[10]:
img = np.copy(film.buffer())
f = plt.figure(figsize=(15,15))
ax = f.add_subplot(111)
ax.imshow(np.clip(np.power(img,1/2.2),0,1), origin='lower')
plt.show()
../_images/executed_functest_example_quad_15_0.png