Skip to main content

A fancy shiny python renderer

Project description

Splendor Render

Shiny!!

Purpose

This package is designed to be a lightweight but nice looking 3D renderer in python. It has primarily been designed to generate online training data for computer vision, reinforcement learning and robotics applications.

There are a few other packages that do similar things that you may also want to check out:

  • PyRender is a really solid renderer and does a lot of what Splendor Render can do. It is also supports more common formats, and has more robust documentation than you will find here. Unlike PyRender, Splendor supports image-based lighting, which adds a very high level of realism if you are willing to spend the time to build good light maps.

  • PyBullet is focused more on physics simulation, but some people use it for generating images as well.

Features

  • Splendor Render is shiny! Splendor Render uses various approximations of physically based rendering (PBR) for image-based lighting (IBL). This is the lighting model used in a lot of game engines, and basically means that the lighting/material model uses environment maps for lighting and provides relatively simple material controls (base reflectance, metal, roughness) that are designed to approximate physics.

  • Splendor Render is fast! For simple scenes you can easily generate images using image-based lighting at faster than 1000hz (including copying images back from the graphics card) with a good GPU.

  • Splendor Render can run on servers! Splendor Render can use EGL to run on headless servers that have no physical display.

  • Splendor Render is easy to use! I think. If not, let me know and I'll try to make it better.

Unsupported Features

  • Splendor Render does not support shadows!

  • Splendor Render does not support transparent objects!

Getting Started

Install this package:

pip install splendor-render

Run a script to install some default assets:

splendor_asset_installer

This downloads about 15MB worth of images and textures that are used in various examples. The install location defaults to ~/.cache/splendor but can be changed by setting the SPLENDOR_HOME environment variable. Some images come from external sources with Creative Commons licenses, see ~/.cache/splendor/default_assets/panoramas/LICENSE.txt for details.

Run the interactive viewer:

splendor_viewer cereal

Render a single image to a file:

splendor_render cereal ./my_render.jpg

Example

In the examples above cereal refers to ~/.cache/splendor/default_assets/scenes/cereal.json using the asset library structure found in ~/.cache/splendor/default_assets.cfg. Let's take a look to get a sense of how scenes are stored in splendor-render:

"cubemaps":{
    "diffuse": {
        "cubemap_asset": "dresden_dif",
        "mipmaps": null
    },
    "reflect": {
        "cubemap_asset": "dresden_ref",
        "mipmaps": null
    }
},

The first section "cubemaps" defines two cube maps that will be used for the image-based lighting in the scene. The first is named "diffuse" and will be used later to represent the non-shiny component of the lighting. The second is named "reflect" and will be used later for the reflections (the shiny component of the lighting) and the background. The "cubemap_asset" tells splendor-render to load the "dresden_dif" and "dresden_ref" assets accordingly, which live in assets/cubemaps. These cubemaps don't do anything until we actually use them for something though, which leads us to...

"image_lights":{
    "background_1": {
        "diffuse_cubemap": "diffuse",
        "reflect_cubemap": "reflect",
        "blur":0,
        "render_background":1
    }
},
"active_image_light" : "background_1",

The next section defines the image-light that will illuminate the scene. You can see it references the "diffuse" and "reflect" cubemaps that we defined earlier. The "render_background"=1 attribute tells the system to render the reflection map as the scene background, and the "blur" attribute defines how blurry the background will be when rendered.

"meshes": {
    "cereal_box": {
        "mesh_primitive":{
            "shape":"cube",
            "x_extents":[-3.5,3.5],
            "y_extents":[-5.5,5.5],
            "z_extents":[-1,1],
            "bezel":0.05
        },
        "scale":1.0,
        "color_mode":"textured"
    }
},

Here we define a single mesh named "cereal_box". You can see it is constructed using a primitive cube with some preset extents and a small bezel. Arbitrary meshes are supported using .obj files.

"textures": {
    "splendor" : {
        "texture_asset":"splendor_texture"
    },
    "splendor_matprop" : {
        "texture_asset":"splendor_matprop"
    }
},

Next we load two textures. This is similar to the cubemaps we saw at the beginning where both are referred to using their asset name. These also don't do anything util we use them for something.

"materials": {
    "varying": {
        "texture_name":"splendor",
        "material_properties_texture":"splendor_matprop"
    },
    "fixed": {
        "texture_name":"splendor",
        "ambient":1.0,
        "metal":0.75,
        "rough":0.75,
        "base_reflect":0.04
    }
},

Here we build two materials that can be used in the scene. The first is "varying" which uses the second texture ("splendor_matprop") to define the material properties of the surface. The second sets each of these values explicitly for the entire surface. The "ambient" parameter affects how much the surface is affected by the ambient light (uniform lighting bias) in the scene. The other three ("metal", "rough" and "base_reflect") control the interaction between the lighting and the surface. Briefly, "base_reflect" makes the surface more shiny. When "base_reflect=1" the surface will become a pure mirror and will ignore the albedo (surface color/texture) entirely. The "rough" parameter makes these reflections more blurry, while "metal" is another kind of shiny that incorporates the albedo and makes the surface look like colored refelctive foil instead of a pure mirror.

"instances": {
    "cube_1": {
        "mesh_name": "cereal_box",
        "material_name": "varying",
        "transform": [
            [-1,0,0,0],
            [0,1,0,0],
            [0,0,-1,0],
            [0,0,0,1]],
        "mask_color": [1,1,1]
    }
},

Finally we add an instance to the scene. In splendor-render no meshes are displayed until we create an instance of them. This allows us to have many copies of a mesh in the scene while only loading it once. Each instance is essentially a combination of a mesh, a material and a 3D transform that places it somewhere in the scene. Here you can see we refer to the "cereal_box" mesh and "varying" material that we created earlier.

"ambient_color": [0,0,0],
"point_lights": {},
"direction_lights": {},
"camera":{
    "view_matrix":[0.0, 0.0, 0, 12.0, 0, 0],
    "projection":[
        [ 1.73205081,  0.0       ,  0.0       ,  0.0       ],
        [ 0.0       ,  1.73205081,  0.0       ,  0.0       ],
        [ 0.0       ,  0.0       , -1.002002  , -0.1001001 ],
        [ 0.0       ,  0.0       , -1.0       ,  0.0       ]]
}

This last section defines the ambient color (in this case [0,0,0] which means no contribution), an empty list of "point_lights" and "direction_lights" (we are using the image light above instead of these simpler lights), as well as camera information.

Asset Paths

Splendor Render supports asset paths for easy asset loading. To make an asset library, simply make a .cfg structured like this:

[paths]
assets = /path/to/assets/folder
image_lights = %(assets)s/image_lights
meshes = %(assets)s/meshes
materials = %(assets)s/materials
textures = %(assets)s/textures
panoramas = %(assets)s/panoramas
scenes = %(assets)s/scenes

Paths do not necessarily need to be relative to a single assets directory but it does make it more convenient. Also, any path can use {HERE} to specify a path relative to the location of the .cfg file. Using the asset library in this way lets you refer to scene components without specifying their full path. The scene entry for a mesh can then look something like:

"meshes": {
  "my_mesh":{
    "mesh_asset":"mesh_name",
    "scale":1.0,
    "color_mode":"flat_color"
}

As long as a file named mesh_name.obj exists in the mesh path specified by the .cfg file, then everything will be loaded correctly. In order to specify what asset file to use when loading a scene, you can pass it into SplendorRender:

renderer = SplendorRender(assets='/path/to/assets.cfg')

If nothing is passed in, the default asset file default_assets.cfg is used. The command line utilities should all have --assets flags that let you specify an assets file when loading a scene for viewing/rendering/etc.

Finally, multiple asset files can be used by specifying a comma-separated list. When looking for assets, the paths are searched in order until something is found. The keyword DEFAULT can be used to refer to the default assets path found in default_assets.cfg.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

splendor-render-0.3.4.tar.gz (54.8 kB view details)

Uploaded Source

File details

Details for the file splendor-render-0.3.4.tar.gz.

File metadata

  • Download URL: splendor-render-0.3.4.tar.gz
  • Upload date:
  • Size: 54.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.16

File hashes

Hashes for splendor-render-0.3.4.tar.gz
Algorithm Hash digest
SHA256 39f8f830bf106f6ecc512d7740ad6480fe96f01ce7ab612bbbee1e142fa8b763
MD5 a8918b907babc81813b502ae5ec2057b
BLAKE2b-256 97384dd4282bda54b9eaab12fb3ab46a6aa2a96c2891af91ec2ddac1289549ec

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page