{ "cells": [ { "cell_type": "raw", "id": "a52b8945", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ ".. _example_quad:\n", "\n", "Rendering quad\n", "==========================\n", "\n", "This example describes how to render a simple scene containing a quad represented by two triangles. The code starts again with :cpp:func:`lm::init` function." ] }, { "cell_type": "code", "execution_count": 1, "id": "32c3ea95", "metadata": { "execution": { "iopub.execute_input": "2021-10-22T11:24:07.192420Z", "iopub.status.busy": "2021-10-22T11:24:07.191763Z", "iopub.status.idle": "2021-10-22T11:24:07.294153Z", "shell.execute_reply": "2021-10-22T11:24:07.294697Z" } }, "outputs": [ { "data": { "text/plain": [ "Namespace(bin_path='/lightmetrica-v3/_build/bin', path='/lightmetrica-v3', scene_path='/lm3/scenes')" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import lmenv\n", "lmenv.load('.lmenv')" ] }, { "cell_type": "code", "execution_count": 2, "id": "65d580e0", "metadata": { "execution": { "iopub.execute_input": "2021-10-22T11:24:07.300621Z", "iopub.status.busy": "2021-10-22T11:24:07.297081Z", "iopub.status.idle": "2021-10-22T11:24:07.504269Z", "shell.execute_reply": "2021-10-22T11:24:07.503831Z" } }, "outputs": [], "source": [ "import numpy as np\n", "import imageio\n", "%matplotlib inline\n", "import matplotlib.pyplot as plt\n", "import lightmetrica as lm\n", "%load_ext lightmetrica_jupyter" ] }, { "cell_type": "code", "execution_count": 3, "id": "d017e681", "metadata": { "execution": { "iopub.execute_input": "2021-10-22T11:24:07.510140Z", "iopub.status.busy": "2021-10-22T11:24:07.508828Z", "iopub.status.idle": "2021-10-22T11:24:07.512036Z", "shell.execute_reply": "2021-10-22T11:24:07.511625Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[I|0.000] Lightmetrica -- Version 3.0.0 (rev. 70601db) Linux x64\n" ] } ], "source": [ "lm.init()\n", "lm.log.init('jupyter')\n", "lm.progress.init('jupyter')\n", "lm.info()" ] }, { "cell_type": "code", "execution_count": 4, "id": "10ef35a9", "metadata": { "execution": { "iopub.execute_input": "2021-10-22T11:24:07.516778Z", "iopub.status.busy": "2021-10-22T11:24:07.515548Z", "iopub.status.idle": "2021-10-22T11:24:07.517326Z", "shell.execute_reply": "2021-10-22T11:24:07.517706Z" }, "nbsphinx": "hidden" }, "outputs": [], "source": [ "if not lm.Release:\n", " lm.debug.attach_to_debugger()\n", " lm.parallel.init('openmp', num_thread=1)" ] }, { "cell_type": "raw", "id": "12398c11", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "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 :ref:`component_ref` for the detailed description of the parameters." ] }, { "cell_type": "code", "execution_count": 5, "id": "00554171", "metadata": { "execution": { "iopub.execute_input": "2021-10-22T11:24:07.602185Z", "iopub.status.busy": "2021-10-22T11:24:07.601382Z", "iopub.status.idle": "2021-10-22T11:24:07.606330Z", "shell.execute_reply": "2021-10-22T11:24:07.606683Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[I|0.016] Loading asset [name='film']\n", "[I|0.094] Loading asset [name='camera']\n", "[I|0.095] Loading asset [name='mesh']\n", "[I|0.095] Loading asset [name='material']\n" ] } ], "source": [ "# Film for the rendered image\n", "film = lm.load_film('film', 'bitmap', w=1920, h=1080)\n", "\n", "# Pinhole camera\n", "camera = lm.load_camera('camera', 'pinhole',\n", " position=[0,0,5],\n", " center=[0,0,0],\n", " up=[0,1,0],\n", " vfov=30,\n", " aspect=16/9)\n", "\n", "# Load mesh with raw vertex data\n", "mesh = lm.load_mesh('mesh', 'raw',\n", " ps=[-1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1],\n", " ns=[0,0,1],\n", " ts=[0,0,1,0,1,1,0,1],\n", " fs={\n", " 'p': [0,1,2,0,2,3],\n", " 'n': [0,0,0,0,0,0],\n", " 't': [0,1,2,0,2,3]\n", " })\n", "\n", "# Material\n", "material = lm.load_material('material', 'diffuse', Kd=[1,1,1])" ] }, { "cell_type": "raw", "id": "e37054c0", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "Next we will create a `scene` asset. The scene asset can also be created :cpp:func:`load_scene` function. Here, we will create ``scene::default`` asset.\n", "A scene internally `uses acceleration structure` for ray-scene intersections, which can be specified by ``accel`` parameter." ] }, { "cell_type": "code", "execution_count": 6, "id": "a8f1dc5e", "metadata": { "execution": { "iopub.execute_input": "2021-10-22T11:24:07.611159Z", "iopub.status.busy": "2021-10-22T11:24:07.610620Z", "iopub.status.idle": "2021-10-22T11:24:07.612992Z", "shell.execute_reply": "2021-10-22T11:24:07.613376Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[I|0.102] Loading asset [name='accel']\n", "[I|0.103] Loading asset [name='scene']\n" ] } ], "source": [ "accel = lm.load_accel('accel', 'sahbvh')\n", "scene = lm.load_scene('scene', 'default', accel=accel)" ] }, { "cell_type": "raw", "id": "c5d96bcd", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "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 :cpp:func:`lm::Scene::add_primitive` function.\n", "\n", ".. note::\n", " If you need transformation applied to the geometry, you can use :cpp:func:`lm::Scene::add_transformed_primitive` function. The transformation is given by 4x4 matrix. \n", "\n", "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 :cpp:func:`lm::Scene::add_primitive` function.\n", "\n", ".. note::\n", " 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." ] }, { "cell_type": "code", "execution_count": 7, "id": "c1d71941", "metadata": { "execution": { "iopub.execute_input": "2021-10-22T11:24:07.617262Z", "iopub.status.busy": "2021-10-22T11:24:07.615496Z", "iopub.status.idle": "2021-10-22T11:24:07.618859Z", "shell.execute_reply": "2021-10-22T11:24:07.619235Z" } }, "outputs": [], "source": [ "scene.add_primitive(camera=camera)\n", "scene.add_primitive(mesh=mesh, material=material)" ] }, { "cell_type": "raw", "id": "4e6b9572", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "After the configuration of the primitives, we must `build` the scene, which can be done by :cpp:func:`lm::Scene::build` function." ] }, { "cell_type": "code", "execution_count": 8, "id": "6ed4f0e5", "metadata": { "execution": { "iopub.execute_input": "2021-10-22T11:24:07.623670Z", "iopub.status.busy": "2021-10-22T11:24:07.622305Z", "iopub.status.idle": "2021-10-22T11:24:07.626529Z", "shell.execute_reply": "2021-10-22T11:24:07.626872Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[I|0.115] Building acceleration structure [name='accel']\n", "[I|0.115] .. Flattening scene\n", "[I|0.115] .. Building\n" ] } ], "source": [ "scene.build()" ] }, { "cell_type": "raw", "id": "3d878c2f", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ "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." ] }, { "cell_type": "code", "execution_count": 9, "id": "de324e9f", "metadata": { "execution": { "iopub.execute_input": "2021-10-22T11:24:07.630986Z", "iopub.status.busy": "2021-10-22T11:24:07.630411Z", "iopub.status.idle": "2021-10-22T11:24:08.566829Z", "shell.execute_reply": "2021-10-22T11:24:08.567201Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[I|0.122] Loading asset [name='renderer']\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "4419b9b897064f49a587d8fff7f35f44", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/2073600 [00:00" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "img = np.copy(film.buffer())\n", "f = plt.figure(figsize=(15,15))\n", "ax = f.add_subplot(111)\n", "ax.imshow(np.clip(np.power(img,1/2.2),0,1), origin='lower')\n", "plt.show()" ] } ], "metadata": { "jupytext": { "cell_metadata_json": true, "formats": "ipynb,py:light", "text_representation": { "extension": ".py", "format_name": "light", "format_version": "1.5", "jupytext_version": "1.3.3" } }, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.10" }, "widgets": { "application/vnd.jupyter.widget-state+json": { "state": { "212bd6e484304be3a9a1c3f72450437c": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "3b75cba75282483db18a5f4f1f026560": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "DescriptionStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "DescriptionStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "description_width": "" } }, "4419b9b897064f49a587d8fff7f35f44": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HBoxModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HBoxModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HBoxView", "box_style": "", "children": [ "IPY_MODEL_589b8cddf2db426ba72068234e032d15", "IPY_MODEL_8e4cbe8c358a410789b2b994f136beec", "IPY_MODEL_92d8143a5ae240a1b5c1d5cc389cf6bd" ], "layout": "IPY_MODEL_e2cec351d1864875b3572796d5133e16" } }, "589b8cddf2db426ba72068234e032d15": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_c6223533be8b48fd8eb89e11dfd20b7d", "placeholder": "​", "style": "IPY_MODEL_3b75cba75282483db18a5f4f1f026560", "value": "100%" } }, "5acc202982564ee689caa003c472d997": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "ProgressStyleModel", "state": { "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "ProgressStyleModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "StyleView", "bar_color": null, "description_width": "" } }, "8e4cbe8c358a410789b2b994f136beec": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "FloatProgressModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "FloatProgressModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "ProgressView", "bar_style": "success", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_feef3874725b4f4a8840ef21b2ebec3e", "max": 2073600.0, "min": 0.0, "orientation": "horizontal", "style": "IPY_MODEL_5acc202982564ee689caa003c472d997", "value": 2073600.0 } }, "92d8143a5ae240a1b5c1d5cc389cf6bd": { "model_module": "@jupyter-widgets/controls", "model_module_version": "1.5.0", "model_name": "HTMLModel", "state": { "_dom_classes": [], "_model_module": "@jupyter-widgets/controls", "_model_module_version": "1.5.0", "_model_name": "HTMLModel", "_view_count": null, "_view_module": "@jupyter-widgets/controls", "_view_module_version": "1.5.0", "_view_name": "HTMLView", "description": "", "description_tooltip": null, "layout": "IPY_MODEL_f5e1939c6cba4780b72ac9176f25821b", "placeholder": "​", "style": "IPY_MODEL_212bd6e484304be3a9a1c3f72450437c", "value": " 2073600/2073600 [00:00<00:00, 2716232.53it/s]" } }, "c6223533be8b48fd8eb89e11dfd20b7d": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "e2cec351d1864875b3572796d5133e16": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "f5e1939c6cba4780b72ac9176f25821b": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } }, "feef3874725b4f4a8840ef21b2ebec3e": { "model_module": "@jupyter-widgets/base", "model_module_version": "1.2.0", "model_name": "LayoutModel", "state": { "_model_module": "@jupyter-widgets/base", "_model_module_version": "1.2.0", "_model_name": "LayoutModel", "_view_count": null, "_view_module": "@jupyter-widgets/base", "_view_module_version": "1.2.0", "_view_name": "LayoutView", "align_content": null, "align_items": null, "align_self": null, "border": null, "bottom": null, "display": null, "flex": null, "flex_flow": null, "grid_area": null, "grid_auto_columns": null, "grid_auto_flow": null, "grid_auto_rows": null, "grid_column": null, "grid_gap": null, "grid_row": null, "grid_template_areas": null, "grid_template_columns": null, "grid_template_rows": null, "height": null, "justify_content": null, "justify_items": null, "left": null, "margin": null, "max_height": null, "max_width": null, "min_height": null, "min_width": null, "object_fit": null, "object_position": null, "order": null, "overflow": null, "overflow_x": null, "overflow_y": null, "padding": null, "right": null, "top": null, "visibility": null, "width": null } } }, "version_major": 2, "version_minor": 0 } } }, "nbformat": 4, "nbformat_minor": 5 }