2021-05-10

Can't I just make a picture of this 3D model?

It sounds like a simple request: take this set of object models and make a set of pictures so we can vdiff them. No problem, right?

On one level that is right: there are a lot of tools out there than can draw you a picture of a 3D model.

But there are some unstated requirements:

  • These represent the same object at different points in the evolution of a physical effect, so we want to image them all from the same point using the same viewport and the same lighting. Maybe even generate a movie, but that's a bonus.
  • There are a lot of these objects because they are are generated by a scripted process, so we'd like to be able to initiate and control the rendering from the command line.
  • If our renderer uses a light model more sophisticated than pure ambient light (and it probably should, even if we don't need it to be particularly sophisticated), we want to control the lighting.
  • We'd actually like to add a simple legend to the scene, though this a "may" item that can be dispensed with.

And now the problem is actually pretty hard, and there are many fewer tools that offer the facilities we need.

Let's take a closer look at the requirements.

Scene description

The first thing to know is that a plain object model (in wavefront (.obj) or stl format) isn't enough to define a picture. What direction do you see it from? How much of the frame does it fill? Which way is "up" in the frame? How is it lit (and for that matter, how do we model lighting)? In what color? And so on ad nauseum.

So we need some kind of additional information. We call the combination of the object model(s) and all that ancillary information a "scene description", and it is written in a scene description language or format.

There are a lot of scene description languages out there (in many cases used by a single tool), though a small number are reasonable common. From today's web browing it looks like COLLADA, the RenderMan format (.rbi), and blender's proprietary and undocumented .blend files are the big players.

Command-line interface

This operation is part of a fairly complex workflow that I expect execute a few score to a few hundred times. It really should be scripted, but doesn't justify writing a custom tool unless I can just plumb together some existing bits. For that to be practical we need a renderer with a command-line interface (because this means that someone else has already done the bulk of the work).

In an ideal world I could write something like:

 renderer -i thingy_2.5s.obj \
        -c camera.txt -l lights.txt \
        --quality=3 --resolution=1920x1080

and get thingy_2.5s.png out. Then I could just loop over the available input files (re-using the scene description elements) and get my perfectly aligned set of images.

Where that leaves us

In a lot of ways the obvious choice is blender (not withstanding that this is a hugely heavy tool for the job), but it wants the scene description in an undocumented format which I can't generate outside of the program. Strike the obvious solution.

Now both COLLADA and RenderMan are documented, but as far as I've learned so far neither one is modular in the sense that I can define the camera and lights in a separate file from the 3D model and neither one lets me say "Use this wavefront file with rotation matrix M and translation T." in the singular file. In principle I could rework my code that is generating .obj files to produce .rbi instead but that would mean the producing code would need to know about my choice of camera and lights which is simply in the wrong domain for that code. Argh!

So, at least in my context, the answer to the title question seems to be "No, you can't.", which seems to be a bit of free real estate in the software utility market. Another task to add to my queue of projects that are not getting done due to the demands of my home life. Sigh.

Update 11-May: It turns out that RenderMan format does support separate inclusion in the form a "Entity files" and a ##Include directive. This represents a path forward, though it means supporting mesh output in a new format.

Update 14-May: The specification says:

Note that the Include keyword itself does not cause the inclusion of the specified file. Aswith all structural hints, theIncludekeyword serves only as a special hint for rendermanagement systems. As such, the Include keyword should only be used if render management facilities are known to exist.

Though it appears that I can provide the adequate level of "render management facilities" with a simple tool that identifies the keyword. Better still the renderer I'm looking at (aqsis) is willing to accept the standard input so it becomes possible to write something like includer lights_and_camers.rib | aqsis .

No comments:

Post a Comment