Skip to content

Instantly share code, notes, and snippets.

@ardenpm

ardenpm/mi.md Secret

Created October 16, 2017 00:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ardenpm/973bb7747f8a5a68f7627019cf1a9ae0 to your computer and use it in GitHub Desktop.
Save ardenpm/973bb7747f8a5a68f7627019cf1a9ae0 to your computer and use it in GitHub Desktop.
mental ray Scene Description Format

mental images Scene Description Format

Introduction

The mental images Scene Description Format (here in referred to as the .mi format) was originally the native file format of the mental ray rendering engine. When RealityServer and Iray were created they adopted a modified version of this file format. While many aspects are compatible with the original format there are important differences to consider when creating tools that output .mi files for consumption by Iray or RealityServer. This document provides enough information to get you started with authoring .mi files for RealityServer or Iray.

Reference Documentation

Unfortunately there is not any definitive documentation for the RealityServer/Iray specific variant of the .mi format. The most complex elements however remain the same as the original mental ray version so the documentation for it is a good place to start for the general structure. The easiest place to find the majority of what is needed is the online mental ray documentation from Autodesk here.

Differences from mental ray

The general structure of the file is identical for RealityServer as it is for mental ray, so the options block, cameras, objects, lights, instances, groups and the final render statement are all used in the same way. Here are some of the key differences to consider.

In general, do not assume a feature of mental ray is supported by RealityServer/Iray. Many will not be, for example setting the exponent value on a light won't do anything since this would not be physically correct. Be sure to refer to Iray documentation for what is actually going to work.

  • Within the options block, very few of the standard mental ray options are used. It is recommended to ignore the documentation for the mental ray options completely with one exception, the filter statement. You can start with an options block something like this:
options "opt"
    shadow on
    filter gauss 3.0
end options

Iray only supports box, gauss or triangle filter types, if mitchell or lanczos are used they will be use the gauss filter instead. Note that the radius will be divided by two when the .mi file is parsed to match the way the radius is specified in Iray. Sensible defaults (in the .mi file) for box, triangle and gauss filter types are 1.0, 2.0 and 3.0 respectively.

  • RealityServer and Iray heavily utilise the concept of attributes which can be applied to any element in the scene, including options, objects, instances, cameras, lights and groups. When you see RealityServer or Iray documentation refer to an attribute you would set on the options it would be done as follows for example:
options "opt"
    attribute integer "progressive_rendering_max_samples" 100
    attribute scalar "progressive_rendering_converged_pixel_ratio" 0.9
    attribute boolean "progressive_rendering_quality_enabled" on
    attribute string "environment_function" "env_func"
end options

There are many options that can be set on the options block as well as various other elements. Refer to the Iray Programmers Guide for more details.

  • Attributes are defined using the following syntax:
attribute {type} "{name}" {value}

The types come from the mental ray world so need to be mapped to those used in RealityServer and Iray. Here are the mappings for some basic ones:

Float32 → scalar
Float64 → scalar
Sint32 → integer
Uint32 → integer
Boolean → boolean
String → string

There are other more complex ones but these are not frequently used. You can also set all options programmatically so you can just leave them out of the .mi file, you only need to have enough there to make it valid.

  • There is also some additional syntax for storing things not supported by mental ray, like light probes, camera backplates, projectors and several others. These are not documented however. The easiest way to work out how to deal with those is to import something into Iray Viewer and save it out as a .mi file.

  • Unless there is a need, we recommend sticking to polygon geometry or trilists which are both well supported by RealityServer from the .mi format. It is possible to use freeform surfaces (e.g., NURBS) but these are more complex.

  • Note that data statements on geometry elements are ignored. If you have a need to store additional data on geometry you should use attributes instead.

  • The main part that differs significantly from standard .mi syntax is how materials and MDL are handled. You need to use $include to include any MDL content you will reference, you then use only the shader directive to instantiate the materials, not the material directive that exists in .mi. Again, exporting from Iray Viewer will quickly show how this works.

  • There are two main choices to encode triangle/polygon data, the standard Polygon Geometry method or Primitive Lists (trilists). Which you choose will probably depend on how your source application encodes things. If you want to encode arbitrary polygons, including those with holes and any number of sides, then you need to use the former. If you are just doing triangles you can use either.

  • Start with a plain ASCII .mi file as they are much easier to debug while you are developing. Once you have that working you might want to add the optimisation of using binary vectors. Here is the description from the mental ray .mi documentation:

mental ray also accepts a compressed binary format for vectors. Instead of three floating-point numbers, a sequence of 12 bytes enclosed in backquotes is accepted. These 12 bytes are the memory image of three floats in IEEE 854 format, using big-endian byte order. This format is intended to increase translation and parsing speed when ray is connected to a native translator; it should not be used in files to be modified with text editors or filters, since they may refuse to accept files containing binary data, or corrupt them.

Many text editors do not correctly handle files with this data in them and will corrupt them so you need to take care handling them (Sublime text for example destroys those files. Textpad and tools like sed and vi handle them correctly). We recommend only looking at this later as a file size optimisation if you need it and always having it as an option to export either way for debugging if you do add it.

  • Catmull-Clark mesh geometry and Sub-division surface geometry only support triangles and quads in Iray. Polygons with more edges will be ignored.

  • Only parametric and length approximations are fully supported by Iray for tessellating free-form surfaces, subdivision surfaces, Catmull-Clark meshes and displacements. Distance ratio may be available for some geometry types but has not been tested by us.

  • Note that assemblies, user data, map data, hair geometry, particle geometry are not supported by Iray.

  • For a full understanding of how transformation matrices are handled by RealityServer/Iray please refer to this article on our blog. The matrix format used in .mi files is identical.

Example .mi File

Here is a simple example .mi file which demonstrates most of the features typically needed to construct a valid scene.

#
# Example .mi File
#

#
# MDL files needed for this scene
#
$include "base.mdl"
$include "::nvidia::core_definitions.mdl"

#
# Three simple materials from MDL definitions
#
shader "white" "mdl::nvidia::core_definitions::flex_material" (
        "base_color"    0.7 0.7 0.7,
        "reflectivity"  0.0
)
shader "green" "mdl::nvidia::core_definitions::flex_material" (
        "base_color"    0.15 0.7 0.15,
        "reflectivity"  0.0
)
shader "red" "mdl::nvidia::core_definitions::flex_material" (
        "base_color"    0.7 0.15 0.15,
        "reflectivity"  0.0
)

#
# Light Definition from MDL
#
shader "Light_def" "mdl::nvidia::core_definitions::light_omni" (
    "intensity" 42
)

#
# Rectangular light source
#
light "Light_lgt"
    = "Light_def"
    origin 0 0 0
    rectangle 130 0 0  0 105 0  1
end light

#
# Instance of the light source
#
instance "Light_inst" "Light_lgt"
    visible on
    transform
        1 0 0 0
        0 0 -1 0
        0 -1 0 0
        -278 279.5 548.8 1
end instance

#
# Camera with tonemapping parameters
#
camera "Camera"
    focal 0.035
    aperture 0.025
    aspect 1.0
    resolution 1024 1024
    attribute string "tm_tonemapper" "mia_exposure_photographic"
    attribute scalar "mip_cm2_factor" 1
    attribute color "mip_whitepoint" 1 1 1 1
    attribute scalar "mip_film_iso" 100
    attribute scalar "mip_camera_shutter" 0.1
    attribute scalar "mip_f_number" 2.0
    attribute scalar "mip_vignetting" 0
    attribute scalar "mip_burn_highlights" 0.7
    attribute scalar "mip_crush_blacks" 0.25
    attribute scalar "mip_saturation" 1.0
    attribute scalar "mip_gamma" 2.2
    attribute scalar "mip_lens_focus" 0
    attribute scalar "mip_lens_radius" 0
    attribute scalar "mip_lens_thickness" 0
end camera

#
# Instance of the camera moved into position
#
instance "Camera_inst" "Camera"
    transform 
        -1 0 0 0
        0 1 0 0
        0 0 -1 0
        278 -273 -800 1
end instance

#
# Polygon Geometry with multiple materials and holes
#
object "Room_obj"
    visible on
    tagged on
    group
        #
        ## Vectors
        #
        # Floor
        552.8 0.0 0.0   
        0.0 0.0 0.0
        0.0 0.0 559.2
        549.6 0.0 559.2
        # Floor Holes
        130.0 0.0 65.0
        82.0 0.0 225.0
        240.0 0.0 272.0
        290.0 0.0 114.0
        423.0 0.0 247.0
        265.0 0.0 296.0
        314.0 0.0 456.0
        472.0 0.0 406.0
        # Ceiling
        556.0 548.8 0.0   
        556.0 548.8 559.2
        0.0 548.8 559.2
        0.0 548.8 0.0
        # Ceiling Hole
        343.0 548.8 227.0
        343.0 548.8 332.0
        213.0 548.8 332.0
        213.0 548.8 227.0
        # Back Wall
        549.6 0.0 559.2 
        0.0 0.0 559.2
        0.0 548.8 559.2
        556.0 548.8 559.2
        # Right Wall
        0.0 0.0 559.2   
        0.0 0.0 0.0
        0.0 548.8 0.0
        0.0 548.8 559.2
        # Left Wall
        552.8 0.0 0.0 
        549.6 0.0 559.2
        556.0 548.8 559.2
        556.0 548.8 0.0

        #
        ## Vertices
        #
        # Floor
        v 0
        v 1
        v 2
        v 3
        # Floor Holes
        v 4
        v 5
        v 6
        v 7
        v 8
        v 9
        v 10
        v 11
        # Ceiling
        v 12
        v 13
        v 14
        v 15
        # Ceiling Hole
        v 16
        v 17
        v 18
        v 19
        # Back Wall
        v 20
        v 21
        v 22
        v 23
        # Right Wall
        v 24
        v 25
        v 26
        v 27
        # Left Wall
        v 28
        v 29
        v 30
        v 31

        #
        ## Polygons
        #
        # Floor with holes
        p 0 0 1 2 3 hole 4 5 6 7 hole 8 9 10 11
        # Ceiling with hole
        p 0 12 13 14 15 hole 16 17 18 19
        # Back Wall
        p 0 20 21 22 23
        # Right Wall
        p 1 24 25 26 27
        # Left Wall
        p 2 28 29 30 31
    end group
end object

#
# Instance of the room object
#
instance "Room_inst" "Room_obj"
    material [ "white", "green", "red" ]
    transform
        1 0 0 0
        0 1 0 0
        0 0 1 0
        0 0 0 1
end instance

#
# Primitive List geometry with a single material
#
object "Tall_block_obj"
    visible on
    trilist
        vertex 20 p
        triangle 10
        [
            423.0 330.0 247.0
            265.0 330.0 296.0
            314.0 330.0 456.0
            472.0 330.0 406.0
            423.0 0.0 247.0
            423.0 330.0 247.0
            472.0 330.0 406.0
            472.0 0.0 406.0
            472.0 0.0 406.0
            472.0 330.0 406.0
            314.0 330.0 456.0
            314.0 0.0 456.0
            314.0 0.0 456.0
            314.0 330.0 456.0
            265.0 330.0 296.0
            265.0 0.0 296.0
            265.0 0.0 296.0
            265.0 330.0 296.0
            423.0 330.0 247.0
            423.0 0.0 247.0
        ]
        [
            0 1 2
            2 3 0
            4 5 6
            6 7 4
            8 9 10
            10 11 8
            12 13 14
            14 15 12
            16 17 18
            18 19 16
        ]
    end trilist
end object

#
# Instance of the tall block
#
instance "Tall_block_inst" "Tall_block_obj"
    material [ "white" ]
    transform
        1 0 0 0
        0 1 0 0
        0 0 1 0
        0 0 0 1
end instance

#
# Primitive List geometry with a single material
#
object "Short_block_obj"
    visible on
    trilist
        vertex 20 p
        triangle 10
        [
            130.0 165.0  65.0 
            82.0 165.0 225.0
            240.0 165.0 272.0
            290.0 165.0 114.0
            290.0 0.0 114.0
            290.0 165.0 114.0
            240.0 165.0 272.0
            240.0 0.0 272.0
            130.0 0.0  65.0
            130.0 165.0  65.0
            290.0 165.0 114.0
            290.0 0.0 114.0
            82.0 0.0 225.0
            82.0 165.0 225.0
            130.0 165.0  65.0
            130.0 0.0  65.0
            240.0 0.0 272.0
            240.0 165.0 272.0
            82.0 165.0 225.0
            82.0 0.0 225.0
        ]
        [
            0 1 2
            2 3 0
            4 5 6
            6 7 4
            8 9 10
            10 11 8
            12 13 14
            14 15 12
            16 17 18
            18 19 16
        ]
    end trilist
end object

#
# Instance of the short block
#
instance "Short_block_inst" "Short_block_obj"
    material [ "white" ]
    transform
        1 0 0 0
        0 1 0 0
        0 0 1 0
        0 0 0 1
end instance

#
# Subdivision Surface geometry
#
object "Subdiv_obj"
    visible on
    group
        -10 -10 -10
         10 -10 -10
         10  10 -10
        -10  10 -10

        -10 -10  10
         10 -10  10
         10  10  10
        -10  10  10
         0   0   4

         v 0 v 1 v 2 v 3 v 4 v 5 v 6 v 7 v 8

         subdivision surface "surf1"

             p 0 1 5 4
             p 1 2 6 5
             p 2 3 7 6
             p 3 0 4 7
             p 4 5 6 7 {
                 detail 256 8
             }
             p 0 3 2 1 crease 15 1 1 1 1

         end subdivision surface
         approximate subdivision surface parametric 3 "surf1"
    end group
end object

#
# Instance of the Subdivision surface geometry
#
instance "Subdiv_inst" "Subdiv_obj"
    material [ "white" ]
    transform
        -1 0 0 0
        0 1 0 0
        0 0 1 0
        400 -60 -85 1
end instance

#
# Catmull-Clark mesh geometry
#
object "Catmull_clark_mesh_obj"
    visible on
    group
         20  0  0
         15 -20 0
        -15 -20 0
        -20  0  0
        -15  20 0
         15  20 0
         20  0  60
         15 -20 60
        -15 -20 60
        -20  0  60
        -15  20 60
         15  20 60

        v 0 v 1 v 2 v 3 v 4 v 5 v 6 v 7 v 8 v 9 v 10 v 11

        ccmesh "surf1"
            polygon 8 vertex 36
                p 0 1 2 3   crease 1 1 1 1 1 1
                p 6 11 10 9 crease 1 1 1 1 1 1
                p 2 1 7 8
                p 1 0 6 7
                p 0 5 11 6
                p 5 4 10 11
                p 4 3 9 10
                p 3 2 8 9
        end ccmesh
        approximate ccmesh parametric 4 "surf1"
    end group
end object

#
# Instance of the Catmull-Clark mesh
#
instance "Catmull_clark_mesh_inst" "Catmull_clark_mesh_obj"
    material [ "white" ]
    transform
        1 0 0 0
        0 1 0 0
        0 0 1 0
        -465 -60 -95 1
end instance

#
# The root group for the scene which contains all entities to use
#
instgroup "Root_grp"
    "Light_inst"
    "Camera_inst"
    "Room_inst"
    "Tall_block_inst"
    "Short_block_inst"
    "Catmull_clark_mesh_inst"
    "Subdiv_inst"
end instgroup

#
# Scene wide options
#
options "Options"
    shadow on
    filter gauss 3.0
    attribute integer "progressive_rendering_max_samples" 100
end options

#
# Render statement which tells us which root group, camera and options to use
#
render "Root_grp" "Camera_inst" "Options"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment