Add intensity and range parameters to lights.

PiperOrigin-RevId: 758603199
Change-Id: I74e88bdfeedd9224e84d953f237d68eca79e6cb7
This commit is contained in:
Google DeepMind
2025-05-14 03:27:06 -07:00
committed by Copybara-Service
parent a6c3a287d6
commit fa95fe0c59
15 changed files with 160 additions and 52 deletions
+57 -37
View File
@@ -2866,11 +2866,15 @@ and the +Y axis points up. Thus the frame position and orientation are the key a
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This element creates a light, which moves with the body where it is defined. To create a fixed light, define it in the
world body. The lights created here are in addition to the default headlight which is always defined and is adjusted via
the :ref:`visual <visual>` element. MuJoCo relies on the standard lighting model in OpenGL (fixed functionality)
augmented with shadow mapping. The effects of lights are additive, thus adding a light always makes the scene brighter.
The maximum number of lights that can be active simultaneously is 8, counting the headlight. The light is shining along
the direction specified by the dir attribute. It does not have a full spatial frame with three orthogonal axes.
world body. The lights created here are in addition to the headlight which is always defined and is configured via the
:ref:`visual <visual>` element. Lights shine along the direction specified by the dir attribute. They do not have
a full spatial frame with three orthogonal axes.
By default, MuJoCo uses the standard OpenGL (fixed functional) Phong lighting model for its rendering, with augmented
with shadow mapping. (See the OpenGL documentation for more information, including details about various attributes.)
MJCF also supports alternative lighting models (e.g. physically-based rendering) by providing additional attributes.
Attributes may be applied or ignored depending on the lighting model being used.
.. _body-light-name:
@@ -2919,12 +2923,6 @@ the direction specified by the dir attribute. It does not have a full spatial fr
these clipping planes bound the cone or box shadow volume in the light direction. As a result, some shadows
(especially those very close to the light) may be clipped.
.. _body-light-bulbradius:
:at:`radius`: :at-val:`real, "0.02"`
Radius of the light, affects shadow softness. This attribute has no effect in MuJoCo's native renderer, but it can be
useful when rendering scenes with an external renderer.
.. _body-light-active:
:at:`active`: :at-val:`[false, true], "true"`
@@ -2941,11 +2939,45 @@ the direction specified by the dir attribute. It does not have a full spatial fr
:at:`dir`: :at-val:`real(3), "0 0 -1"`
Direction of the light.
.. _body-light-diffuse:
:at:`diffuse`: :at-val:`real(3), "0.7 0.7 0.7"`
The color of the light. For the Phong (default) lighting model, this defines the diffuse color of
the light.
.. _body-light-intensity:
:at:`intensity`: :at-val:`real, "1000.0"`
The intensity of the light source, measured in candela, used for physically-based lighting models.
This is unused by the default Phong lighting model.
.. _body-light-ambient:
:at:`ambient`: :at-val:`real(3), "0 0 0"`
The ambient color of the light, used by the default Phong lighting model.
.. _body-light-specular:
:at:`specular`: :at-val:`real(3), "0.3 0.3 0.3"`
The specular color of the light, used by the default Phong lighting model.
.. _body-light-range:
:at:`range`: :at-val:`real, "10.0"`
The effective range of the light. Objects further than this distance from the light position
will not be illuminated by this light. This only applies to spotlights.
.. _body-light-bulbradius:
:at:`bulbradius`: :at-val:`real, "0.02"`
The radius of the light source which can affect shadow softness depending on the
renderer. This only applies to spotlights.
.. _body-light-attenuation:
:at:`attenuation`: :at-val:`real(3), "1 0 0"`
These are the constant, linear and quadratic attenuation coefficients in OpenGL. The default corresponds to no
attenuation. See the OpenGL documentation for more information on this and all other OpenGL-related properties.
These are the constant, linear and quadratic attenuation coefficients for Phong lighting.
The default corresponds to no attenuation.
.. _body-light-cutoff:
@@ -2957,22 +2989,6 @@ the direction specified by the dir attribute. It does not have a full spatial fr
:at:`exponent`: :at-val:`real, "10"`
Exponent for spotlights. This setting controls the softness of the spotlight cutoff.
.. _body-light-ambient:
:at:`ambient`: :at-val:`real(3), "0 0 0"`
The ambient color of the light.
.. _body-light-diffuse:
:at:`diffuse`: :at-val:`real(3), "0.7 0.7 0.7"`
The diffuse color of the light.
.. _body-light-specular:
:at:`specular`: :at-val:`real(3), "0.3 0.3 0.3"`
The specular color of the light.
.. _body-composite:
:el-prefix:`body/` |-| **composite** (*)
@@ -8257,26 +8273,30 @@ if omitted.
.. _default-light-dir:
.. _default-light-bulbradius:
.. _default-light-directional:
.. _default-light-castshadow:
.. _default-light-active:
.. _default-light-diffuse:
.. _default-light-intensity:
.. _default-light-ambient:
.. _default-light-specular:
.. _default-light-bulbradius:
.. _default-light-range:
.. _default-light-attenuation:
.. _default-light-cutoff:
.. _default-light-exponent:
.. _default-light-ambient:
.. _default-light-diffuse:
.. _default-light-specular:
.. _default-light-mode:
:el-prefix:`default/` |-| **light** (?)
+8 -6
View File
@@ -317,9 +317,11 @@
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`active<body-light-active>` | :ref:`pos<body-light-pos>` | :ref:`dir<body-light-dir>` | :ref:`bulbradius<body-light-bulbradius>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`attenuation<body-light-attenuation>` | :ref:`cutoff<body-light-cutoff>` | :ref:`exponent<body-light-exponent>` | :ref:`ambient<body-light-ambient>` | |
| | | | :ref:`intensity<body-light-intensity>` | :ref:`range<body-light-range>` | :ref:`attenuation<body-light-attenuation>` | :ref:`cutoff<body-light-cutoff>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`diffuse<body-light-diffuse>` | :ref:`specular<body-light-specular>` | :ref:`mode<body-light-mode>` | :ref:`target<body-light-target>` | |
| | | | :ref:`exponent<body-light-exponent>` | :ref:`ambient<body-light-ambient>` | :ref:`diffuse<body-light-diffuse>` | :ref:`specular<body-light-specular>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`mode<body-light-mode>` | :ref:`target<body-light-target>` | | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |_| body |br| |_| |L| | | .. table:: |
@@ -1457,13 +1459,13 @@
| :ref:`light | ? | :class: mjcf-attributes |
| <default-light>` | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`pos<default-light-pos>` | :ref:`dir<default-light-dir>` | :ref:`bulbradius<default-light-bulbradius>` | :ref:`directional<default-light-directional>` | |
| | | | :ref:`pos<default-light-pos>` | :ref:`dir<default-light-dir>` | :ref:`bulbradius<default-light-bulbradius>` | :ref:`intensity<default-light-intensity>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`castshadow<default-light-castshadow>` | :ref:`active<default-light-active>` | :ref:`attenuation<default-light-attenuation>` | :ref:`cutoff<default-light-cutoff>` | |
| | | | :ref:`range<default-light-range>` | :ref:`directional<default-light-directional>` | :ref:`castshadow<default-light-castshadow>` | :ref:`active<default-light-active>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`exponent<default-light-exponent>` | :ref:`ambient<default-light-ambient>` | :ref:`diffuse<default-light-diffuse>` | :ref:`specular<default-light-specular>` | |
| | | | :ref:`attenuation<default-light-attenuation>` | :ref:`cutoff<default-light-cutoff>` | :ref:`exponent<default-light-exponent>` | :ref:`ambient<default-light-ambient>` | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
| | | | :ref:`mode<default-light-mode>` | | | | |
| | | | :ref:`diffuse<default-light-diffuse>` | :ref:`specular<default-light-specular>` | :ref:`mode<default-light-mode>` | | |
| | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ |
+------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| |_| default |br| |_| |L| | | .. table:: |
+9 -1
View File
@@ -1178,6 +1178,8 @@ struct mjModel_ {
mjtByte* light_directional; // directional light (nlight x 1)
mjtByte* light_castshadow; // does light cast shadows (nlight x 1)
float* light_bulbradius; // light radius for soft shadows (nlight x 1)
float* light_intensity; // intensity, in candela (nlight x 1)
float* light_range; // range of effectiveness (nlight x 1)
mjtByte* light_active; // is light on (nlight x 1)
mjtNum* light_pos; // position rel. to body frame (nlight x 3)
mjtNum* light_dir; // direction rel. to body frame (nlight x 3)
@@ -2030,7 +2032,9 @@ typedef struct mjsLight_ { // light specification
mjtByte active; // is light active
mjtByte directional; // is light directional or spot
mjtByte castshadow; // does light cast shadows
double bulbradius; // bulb radius, for soft shadows
float bulbradius; // bulb radius, for soft shadows
float intensity; // intensity, in candelas
float range; // range of effectiveness
float attenuation[3]; // OpenGL attenuation (quadratic model)
float cutoff; // OpenGL cutoff
float exponent; // OpenGL exponent
@@ -2838,6 +2842,8 @@ struct mjvLight_ { // OpenGL light
mjtByte directional; // directional light
mjtByte castshadow; // does light cast shadows
float bulbradius; // bulb radius for soft shadows
float intensity; // intensity, in candelas
float range; // range of effectiveness
};
typedef struct mjvLight_ mjvLight;
struct mjvOption_ { // abstract visualization options
@@ -3055,6 +3061,8 @@ struct mjvSceneState_ {
mjtByte* light_directional;
mjtByte* light_castshadow;
float* light_bulbradius;
float* light_intensity;
float* light_range;
mjtByte* light_active;
float* light_attenuation;
float* light_cutoff;
+2
View File
@@ -845,6 +845,8 @@ struct mjModel_ {
mjtByte* light_directional; // directional light (nlight x 1)
mjtByte* light_castshadow; // does light cast shadows (nlight x 1)
float* light_bulbradius; // light radius for soft shadows (nlight x 1)
float* light_intensity; // intensity, in candela (nlight x 1)
float* light_range; // range of effectiveness (nlight x 1)
mjtByte* light_active; // is light on (nlight x 1)
mjtNum* light_pos; // position rel. to body frame (nlight x 3)
mjtNum* light_dir; // direction rel. to body frame (nlight x 3)
+3 -1
View File
@@ -396,7 +396,9 @@ typedef struct mjsLight_ { // light specification
mjtByte active; // is light active
mjtByte directional; // is light directional or spot
mjtByte castshadow; // does light cast shadows
double bulbradius; // bulb radius, for soft shadows
float bulbradius; // bulb radius, for soft shadows
float intensity; // intensity, in candelas
float range; // range of effectiveness
float attenuation[3]; // OpenGL attenuation (quadratic model)
float cutoff; // OpenGL cutoff
float exponent; // OpenGL exponent
+4
View File
@@ -271,6 +271,8 @@ struct mjvLight_ { // OpenGL light
mjtByte directional; // directional light
mjtByte castshadow; // does light cast shadows
float bulbradius; // bulb radius for soft shadows
float intensity; // intensity, in candelas
float range; // range of effectiveness
};
typedef struct mjvLight_ mjvLight;
@@ -504,6 +506,8 @@ struct mjvSceneState_ {
mjtByte* light_directional;
mjtByte* light_castshadow;
float* light_bulbradius;
float* light_intensity;
float* light_range;
mjtByte* light_active;
float* light_attenuation;
float* light_cutoff;
+2
View File
@@ -302,6 +302,8 @@
XMJV( mjtByte, light_directional, nlight, 1 ) \
XMJV( mjtByte, light_castshadow, nlight, 1 ) \
XMJV( float, light_bulbradius, nlight, 1 ) \
XMJV( float, light_intensity, nlight, 1 ) \
XMJV( float, light_range, nlight, 1 ) \
XMJV( mjtByte, light_active, nlight, 1 ) \
X ( mjtNum, light_pos, nlight, 3 ) \
X ( mjtNum, light_dir, nlight, 3 ) \
+51 -1
View File
@@ -2243,6 +2243,22 @@ STRUCTS: Mapping[str, StructDecl] = dict([
doc='light radius for soft shadows',
array_extent=('nlight',),
),
StructFieldDecl(
name='light_intensity',
type=PointerType(
inner_type=ValueType(name='float'),
),
doc='intensity, in candela',
array_extent=('nlight',),
),
StructFieldDecl(
name='light_range',
type=PointerType(
inner_type=ValueType(name='float'),
),
doc='range of effectiveness',
array_extent=('nlight',),
),
StructFieldDecl(
name='light_active',
type=PointerType(
@@ -6735,6 +6751,16 @@ STRUCTS: Mapping[str, StructDecl] = dict([
type=ValueType(name='float'),
doc='bulb radius for soft shadows',
),
StructFieldDecl(
name='intensity',
type=ValueType(name='float'),
doc='intensity, in candelas',
),
StructFieldDecl(
name='range',
type=ValueType(name='float'),
doc='range of effectiveness',
),
),
)),
('mjvOption',
@@ -7851,6 +7877,20 @@ STRUCTS: Mapping[str, StructDecl] = dict([
),
doc='',
),
StructFieldDecl(
name='light_intensity',
type=PointerType(
inner_type=ValueType(name='float'),
),
doc='',
),
StructFieldDecl(
name='light_range',
type=PointerType(
inner_type=ValueType(name='float'),
),
doc='',
),
StructFieldDecl(
name='light_active',
type=PointerType(
@@ -10600,9 +10640,19 @@ STRUCTS: Mapping[str, StructDecl] = dict([
),
StructFieldDecl(
name='bulbradius',
type=ValueType(name='double'),
type=ValueType(name='float'),
doc='bulb radius, for soft shadows',
),
StructFieldDecl(
name='intensity',
type=ValueType(name='float'),
doc='intensity, in candelas',
),
StructFieldDecl(
name='range',
type=ValueType(name='float'),
doc='range of effectiveness',
),
StructFieldDecl(
name='attenuation',
type=ArrayType(
+2
View File
@@ -1076,6 +1076,8 @@ This is useful for example when the MJB is not available as a file on disk.)"));
X(directional);
X(castshadow);
X(bulbradius);
X(intensity);
X(range);
#undef X
#define X(var) DefinePyArray(mjvLight, #var, &MjvLightWrapper::var)
+2
View File
@@ -2172,6 +2172,8 @@ void mjv_makeLights(const mjModel* m, const mjData* d, mjvScene* scn) {
thislight->directional = m->light_directional[i];
thislight->castshadow = m->light_castshadow[i];
thislight->bulbradius = m->light_bulbradius[i];
thislight->intensity = m->light_intensity[i];
thislight->range = m->light_range[i];
if (!thislight->directional) {
f2f(thislight->attenuation, m->light_attenuation+3*i, 3);
thislight->exponent = m->light_exponent[i];
+2 -1
View File
@@ -203,6 +203,8 @@ void mjs_defaultLight(mjsLight* light) {
// intrinsics
light->castshadow = 1;
light->bulbradius = 0.02;
light->intensity = 1000.0;
light->range = 10.0;
light->active = 1;
light->attenuation[0] = 1;
light->cutoff = 45;
@@ -404,4 +406,3 @@ void mjs_defaultKey(mjsKey* key) {
void mjs_defaultPlugin(mjsPlugin* plugin) {
memset(plugin, 0, sizeof(mjsPlugin));
}
+2
View File
@@ -2675,6 +2675,8 @@ void mjCModel::CopyTree(mjModel* m) {
mjuu_copyvec(m->light_pos+3*lid, pl->pos, 3);
mjuu_copyvec(m->light_dir+3*lid, pl->dir, 3);
m->light_bulbradius[lid] = pl->bulbradius;
m->light_intensity[lid] = pl->intensity;
m->light_range[lid] = pl->range;
mjuu_copyvec(m->light_attenuation+3*lid, pl->attenuation, 3);
m->light_cutoff[lid] = pl->cutoff;
m->light_exponent[lid] = pl->exponent;
+8 -5
View File
@@ -167,8 +167,9 @@ const char* MJCF[nMJCF][mjXATTRNUM] = {
{"camera", "?", "17", "orthographic", "fovy", "ipd", "resolution", "pos", "quat",
"axisangle", "xyaxes", "zaxis", "euler", "mode", "focal", "focalpixel",
"principal", "principalpixel", "sensorsize", "user"},
{"light", "?", "13", "pos", "dir", "bulbradius", "directional", "castshadow", "active",
"attenuation", "cutoff", "exponent", "ambient", "diffuse", "specular", "mode"},
{"light", "?", "15", "pos", "dir", "bulbradius", "intensity", "range",
"directional", "castshadow", "active", "attenuation", "cutoff", "exponent",
"ambient", "diffuse", "specular", "mode"},
{"pair", "?", "7", "condim", "friction", "solref", "solreffriction", "solimp",
"gap", "margin"},
{"equality", "?", "3", "active", "solref", "solimp"},
@@ -280,9 +281,9 @@ const char* MJCF[nMJCF][mjXATTRNUM] = {
{"camera", "*", "20", "name", "class", "orthographic", "fovy", "ipd", "resolution", "pos",
"quat", "axisangle", "xyaxes", "zaxis", "euler", "mode", "target",
"focal", "focalpixel", "principal", "principalpixel", "sensorsize", "user"},
{"light", "*", "16", "name", "class", "directional", "castshadow", "active",
"pos", "dir", "bulbradius", "attenuation", "cutoff", "exponent", "ambient", "diffuse",
"specular", "mode", "target"},
{"light", "*", "18", "name", "class", "directional", "castshadow", "active",
"pos", "dir", "bulbradius", "intensity", "range", "attenuation", "cutoff",
"exponent", "ambient", "diffuse", "specular", "mode", "target"},
{"plugin", "*", "2", "plugin", "instance"},
{"<"},
{"config", "*", "2", "key", "value"},
@@ -1856,6 +1857,8 @@ void mjXReader::OneLight(XMLElement* elem, mjsLight* light) {
ReadAttr(elem, "pos", 3, light->pos, text);
ReadAttr(elem, "dir", 3, light->dir, text);
ReadAttr(elem, "bulbradius", 1, &light->bulbradius, text);
ReadAttr(elem, "intensity", 1, &light->intensity, text);
ReadAttr(elem, "range", 1, &light->range, text);
ReadAttr(elem, "attenuation", 3, light->attenuation, text);
ReadAttr(elem, "cutoff", 1, &light->cutoff, text);
ReadAttr(elem, "exponent", 1, &light->exponent, text);
+2
View File
@@ -604,6 +604,8 @@ void mjXWriter::OneLight(XMLElement* elem, const mjCLight* light, mjCDef* def,
// defaults and regular
WriteAttr(elem, "bulbradius", 1, &light->bulbradius, &def->Light().bulbradius);
WriteAttr(elem, "intensity", 1, &light->intensity, &def->Light().intensity);
WriteAttr(elem, "range", 1, &light->range, &def->Light().range);
WriteAttrKey(elem, "directional", bool_map, 2, light->directional, def->Light().directional);
WriteAttrKey(elem, "castshadow", bool_map, 2, light->castshadow, def->Light().castshadow);
WriteAttrKey(elem, "active", bool_map, 2, light->active, def->Light().active);
+6
View File
@@ -5433,6 +5433,8 @@ public unsafe struct mjModel_ {
public byte* light_directional;
public byte* light_castshadow;
public float* light_bulbradius;
public float* light_intensity;
public float* light_range;
public byte* light_active;
public double* light_pos;
public double* light_dir;
@@ -6077,6 +6079,8 @@ public unsafe struct mjvLight_ {
public byte directional;
public byte castshadow;
public float bulbradius;
public float intensity;
public float range;
}
[StructLayout(LayoutKind.Sequential)]
@@ -6357,6 +6361,8 @@ public unsafe struct model {
public byte* light_directional;
public byte* light_castshadow;
public float* light_bulbradius;
public float* light_intensity;
public float* light_range;
public byte* light_active;
public float* light_attenuation;
public float* light_cutoff;