Skip to content

Commit 834983f

Browse files
yuvaltassacopybara-github
authored andcommitted
Add sample/render.cc
PiperOrigin-RevId: 969891418 Change-Id: I3e81d152e0dda42e6a263ebf8c8e2eca04d3ea8f
1 parent f384834 commit 834983f

8 files changed

Lines changed: 929 additions & 10 deletions

File tree

‎doc/changelog.rst‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@
22
Changelog
33
=========
44

5+
Upcoming version (not yet released)
6+
-----------------------------------
7+
8+
Samples
9+
^^^^^^^
10+
11+
- Added :ref:`render.cc<saRender>`: a headless offscreen rendering sample that saves an image to a PNG image.
12+
Supports both the Filament and classic OpenGL backends, with command-line options for camera, resolution, keyframe,
13+
geom/site groups, visualization and rendering flags, labels, and frames.
14+
15+
516
Version 3.12.0 (August 20, 2026)
617
--------------------------------
718

‎doc/programming/samples.rst‎

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,3 +496,102 @@ proliferation of overlapping technologies, which differ not only between platfor
496496
case of Linux. The addition of a couple of extra functions (such as those provided by OSMesa for example) could have
497497
avoided a lot of confusion. EGL is a newer standard from Khronos which aims to do this, and it is gaining popularity.
498498
But we cannot yet assume that all users have it installed.
499+
500+
.. _saRender:
501+
502+
`render <https://github.com/google-deepmind/mujoco/blob/main/sample/render.cc>`_
503+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
504+
505+
This code sample renders a model configuration offscreen and saves the result directly to a PNG image file. It supports
506+
both the modern Filament rendering backend (:ref:`mjrf <FilamentRenderingApi>`) with physically-based rendering (PBR),
507+
and the classic OpenGL renderer (:ref:`mjrContext`). The rendering runs headless without creating an interactive window.
508+
509+
.. code-block:: Shell
510+
511+
render model [output] [options]
512+
513+
Where the command-line arguments and options are
514+
515+
.. list-table::
516+
:width: 95%
517+
:align: left
518+
:widths: 2 1 4
519+
:header-rows: 1
520+
521+
* - Option
522+
- Default
523+
- Meaning
524+
* - ``model``
525+
- (required)
526+
- path to model (positional argument)
527+
* - ``output``
528+
- (default)
529+
- path to output image file (positional argument, default: ``<model>.png``)
530+
* - ``--backend=B``
531+
- ``filament``
532+
- rendering backend (``filament``, ``classic``)
533+
* - ``--width=N``
534+
- 640
535+
- image width in pixels
536+
* - ``--height=N``
537+
- 480
538+
- image height in pixels
539+
* - ``--camera=C``
540+
- (free)
541+
- camera name or integer index (default: free camera)
542+
* - ``--lookat=X,Y,Z``
543+
- (center)
544+
- free camera lookat position
545+
* - ``--distance=D``
546+
- (fit)
547+
- free camera distance
548+
* - ``--azimuth=A``
549+
- ``90``
550+
- free camera azimuth in degrees
551+
* - ``--elevation=E``
552+
- ``-45``
553+
- free camera elevation in degrees
554+
* - ``--key=K``
555+
- (none)
556+
- keyframe name or integer index to load prior to rendering
557+
* - ``--geomgroup=G``
558+
- ``111000``
559+
- 6-character string enabling/disabling geom groups 0-5 (e.g. ``111111``)
560+
* - ``--sitegroup=S``
561+
- ``111000``
562+
- 6-character string enabling/disabling site groups 0-5
563+
* - ``--label=L``
564+
- (none)
565+
- type of label (e.g. ``--label=geom``, ``--label=body``, ``--label=site``)
566+
* - ``--frame=F``
567+
- (none)
568+
- type of coordinate frame (e.g. ``--frame=geom``, ``--frame=body``, ``--frame=site``)
569+
* - ``--<visflag>=0|1``
570+
- (default)
571+
- toggle visualization flag declared in :ref:`mjVISSTRING` (e.g. ``--joint=1``, ``--contactpoint=1``)
572+
* - ``--<rndflag>=0|1``
573+
- (default)
574+
- toggle rendering flag declared in :ref:`mjRNDSTRING` (e.g. ``--shadow=0``, ``--wireframe=1``)
575+
576+
**Notes:**
577+
578+
- Running ``render`` with no arguments (or with ``--help`` / ``-h``) prints the help message.
579+
- The non-optional ``model`` path and optional ``output`` path are positional arguments. If ``output`` is
580+
omitted, the output filename is derived from the model filename with the ``.png`` extension (e.g.
581+
``humanoid.xml`` becomes ``humanoid.png``).
582+
- ``--backend=filament`` uses MuJoCo's Filament C API to configure a scene from the model, setting up lighting,
583+
materials, and textures, and rendering via Filament's offscreen pipeline. ``--backend=classic`` uses standard OpenGL
584+
offscreen rendering with an EGL context.
585+
- The default camera is the model's free camera looking at the center of the scene. Specifying ``--camera=name`` selects
586+
a named camera defined in the model XML, while integer indices ``0, 1, ...`` select fixed cameras in order of definition.
587+
When using the free camera, its viewpoint can be adjusted via ``--lookat=x,y,z``, ``--distance=d``, ``--azimuth=a``,
588+
and ``--elevation=e``.
589+
- If a keyframe is specified via ``--key``, the model state is reset to that keyframe before evaluating kinematics and
590+
rendering. If no keyframe is specified and a keyframe named ``test`` exists in the model, it is used by default.
591+
- Visualization and rendering flags can be individually toggled using normalized flag names from :ref:`mjVISSTRING`
592+
and :ref:`mjRNDSTRING`.
593+
- Labels can be enabled using ``--label=L`` where ``L`` is a label type name from :ref:`mjLABELSTRING` (e.g. ``geom``,
594+
``body``, ``joint``) or an integer index.
595+
- Coordinate frames can be rendered using ``--frame=F`` where ``F`` is a frame type name from :ref:`mjFRAMESTRING` (e.g.
596+
``geom``, ``body``, ``site``, ``world``) or an integer index.
597+

‎sample/CMakeLists.txt‎

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,31 @@ target_link_libraries(
113113
)
114114
target_link_options(record PRIVATE ${MUJOCO_SAMPLE_LINK_OPTIONS})
115115

116+
if(MUJOCO_USE_FILAMENT)
117+
add_executable(render render.cc)
118+
target_compile_options(render PUBLIC ${MUJOCO_SAMPLE_COMPILE_OPTIONS})
119+
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
120+
target_compile_options(render PRIVATE -Wno-gnu-anonymous-struct -Wno-nested-anon-types)
121+
endif()
122+
target_link_libraries(
123+
render
124+
mujoco::mujoco
125+
mujoco::filament
126+
lodepng
127+
Threads::Threads
128+
)
129+
target_link_options(render PRIVATE ${MUJOCO_SAMPLE_LINK_OPTIONS})
130+
endif()
131+
116132
if(APPLE AND MUJOCO_BUILD_MACOS_FRAMEWORKS)
117133
embed_in_bundle(basic simulate)
118134
embed_in_bundle(compile simulate)
119135
embed_in_bundle(dependencies simulate)
120136
embed_in_bundle(record simulate)
121137
embed_in_bundle(testspeed simulate)
138+
if(MUJOCO_USE_FILAMENT)
139+
embed_in_bundle(render simulate)
140+
endif()
122141
endif()
123142

124143
# Do not install if macOS Bundles are created as RPATH is managed manually there.
@@ -131,13 +150,20 @@ if(_INSTALL_SAMPLES)
131150
include(TargetAddRpath)
132151

133152
# Add support to RPATH for the samples.
153+
set(MUJOCO_INSTALL_SAMPLES
154+
basic
155+
compile
156+
dependencies
157+
record
158+
testspeed
159+
)
160+
if(MUJOCO_USE_FILAMENT)
161+
list(APPEND MUJOCO_INSTALL_SAMPLES render)
162+
endif()
163+
134164
target_add_rpath(
135165
TARGETS
136-
basic
137-
compile
138-
dependencies
139-
record
140-
testspeed
166+
${MUJOCO_INSTALL_SAMPLES}
141167
INSTALL_DIRECTORY
142168
"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}"
143169
LIB_DIRS
@@ -147,11 +173,7 @@ if(_INSTALL_SAMPLES)
147173
)
148174

149175
install(
150-
TARGETS basic
151-
compile
152-
dependencies
153-
record
154-
testspeed
176+
TARGETS ${MUJOCO_INSTALL_SAMPLES}
155177
EXPORT ${PROJECT_NAME}
156178
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT samples
157179
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT samples

‎sample/cmake/SampleDependencies.cmake‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ set(MUJOCO_DEP_VERSION_glfw3
3535
)
3636
mark_as_advanced(MUJOCO_DEP_VERSION_glfw3)
3737

38+
3839
find_package(Threads REQUIRED)
3940

4041
set(MUJOCO_BUILD_EXAMPLES OFF)
@@ -102,3 +103,7 @@ if(NOT SAMPLE_STANDALONE AND NOT MUJOCO_SAMPLES_USE_SYSTEM_GLFW)
102103
target_compile_options(glfw PRIVATE ${MUJOCO_MACOS_COMPILE_OPTIONS})
103104
target_link_options(glfw PRIVATE ${MUJOCO_MACOS_LINK_OPTIONS})
104105
endif()
106+
107+
# Fetch lodepng dependency.
108+
include(third_party_deps/lodepng)
109+

0 commit comments

Comments
 (0)
⌂ 换网址