Skip to content

Bake untranslatable worlds into an environment map - #157

Open
ishaanshah wants to merge 2 commits into
mitsuba-renderer:masterfrom
ishaanshah:bake-untranslatable-worlds
Open

ishaanshah wants to merge 2 commits into
mitsuba-renderer:masterfrom
ishaanshah:bake-untranslatable-worlds

Conversation

@ishaanshah

Copy link
Copy Markdown

A world that convert_world cannot translate is currently dropped with a warning, which leaves the scene without its main light. This affects common setups: a Sky Texture, a Mix or Add Shader surface (often used to separate the camera backdrop from the lighting), procedural chains, and Environment Textures that do not feed the Background directly (e.g. through a Gamma or Hue/Saturation node). On a set of about 1000 production scenes, this dropped the world in roughly 40% of them, mostly Sky Textures.

This PR bakes such a world into an envmap instead, and includes a couple of small fixes to the exporter.

Bake untranslatable worlds

When convert_world raises, export_world now renders the world once with Cycles through an equirectangular camera and exports the result as an envmap:

  • The bake runs on a copy of the world; the user's data is not modified.
  • The bake camera lays the map out like an environment-texture lookup, so the emitter gets the same to_world as a translated environment texture, and scale = 1 since the map already contains the strength.
  • The map is written with export_image, like any other texture.
  • The world's Cycles ray visibility is applied to the emitter, as for a translated world. (A world hidden from the camera is still baked, since the bake renders through a camera.)

Light Path. A world that switches on a Light Path output is baked with the values an indirect diffuse ray reports (Is Camera Ray = 0, Is Diffuse Ray = 1, depth 1, ...). The bake traces camera rays, so otherwise a world that shows the camera a backdrop and lights the scene with an HDRI would bake the backdrop. Node groups containing a Light Path node are copied before they are changed. This is a heuristic: one environment map cannot give a different answer per ray type, so for such worlds the camera backdrop or glossy reflections can differ from Cycles.

Options. bake_world (default on) and bake_world_resolution (map height, width is twice that; default 1024) on the export operator, in relaxed mode only. The bake is lossy: the map has a fixed resolution, so features smaller than a texel (such as a sun disk) are spread out, and a Light Path world keeps only one branch. Strict mode therefore still skips the world with a warning. The render engine never bakes: the bake runs a render operator, which is not available from the render job thread.

Export operator: honour the scene's exporting mode

The XML export operator now sets export_ctx.strict from scene.mitsuba.export_mode, as the render engine already does. Until now it always exported in strict mode, whatever the scene's setting.

Honouring relaxed mode exposed a bug in its colour fallback. When a colour input is driven by something the converter cannot handle, eval_color logs a warning and falls back to the socket's default colour. That fallback returned the bare _to_color(...) tuple, whereas every other branch returns a colour plugin (export_ctx.spectrum(...), or an unbounded srgb for values outside [0, 1]); Mitsuba rejects the tuple when the scene is loaded. The path was unreachable from the operator before, since strict mode replaces such a material with the error BSDF instead. The constant-colour conversion now lives in one helper, _color_constant, which both the resolved-constant branch and the fallback use, so the fallback also gets the out-of-range handling.

Examples

image image

Tests

  • tests/unit/test_world_export.py: Sky Texture and Mix Shader worlds are baked into an envmap whose file exists and loads in relaxed mode, while strict mode skips the world; an indirectly connected environment texture bakes back to its source image; the option turns baking off; translatable worlds are not baked; ray visibility is preserved; a Light Path world bakes its lighting branch.
  • tests/roundtrip/test_world_roundtrip.py: a world whose colour encodes the view direction is baked, then rendered in Mitsuba and in Cycles from six directions; they agree to within 0.001, which pins the orientation of the map.
  • tests/unit/test_export_warnings.py: the operator honours the exporting mode, and the relaxed colour fallback produces a valid spectrum.

…r fallback

The XML export operator now sets export_ctx.strict from
scene.mitsuba.export_mode, as the render engine does. Relaxed mode's
colour fallback goes through the constant-colour conversion instead of
returning a raw RGBA tuple Mitsuba's parser rejects.
A world that ``convert_world`` cannot translate (a Sky Texture, a Mix or Add
Shader surface, a procedural chain, an Environment Texture that does not feed
the Background directly) is currently dropped with a warning, which costs the
scene its main light. It is now rendered once with Cycles through an
equirectangular camera and exported as an ``envmap`` instead.

The bake runs on a copy of the world, so the user's data is untouched. Its
camera lays the map out in the parametrization of an environment texture
lookup, so the emitter takes the same ``to_world`` as a translated
environment texture, and ``scale`` 1 since the map already holds the
strength. The map is written through ``export_image`` like any other
texture. The world's ray visibility is put back on the emitter, as for a
translated world.

A world that switches on a Light Path output is baked with the values an
indirect diffuse ray reports. The bake traces camera rays, so a world that
shows the camera a backdrop and lights the scene with something else would
otherwise bake the backdrop. Node groups holding a Light Path node are
copied before they are changed. This is a heuristic: one environment map
cannot hold a different answer per ray type.

The ``bake_world`` export option (default on) and ``bake_world_resolution``
(map height, default 1024) control it, in relaxed mode only. The bake is
lossy: the map has a fixed resolution, so features smaller than a texel
(such as a sun disk) are spread out, and a Light Path world keeps only one
branch. Strict mode therefore still skips the world. The render engine never
bakes: the bake needs an operator, which the render job thread cannot run.

Tests: unit tests for Sky Texture and Mix Shader worlds, an indirect
environment texture whose bake must reproduce the source image, the option,
strict mode, untouched translatable worlds, ray visibility and a Light Path
world; and a roundtrip test rendering a direction-encoding world in Mitsuba
and in Cycles from six directions, which pins the orientation.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant