Extensible 3D (X3D)
Part 1: Architecture and base components
17 Lighting component
The name of this component is "Lighting". This name shall be used when referring to this component in the COMPONENT statement (see 7.2.5.4 Component statement).
This clause describes the Lighting component of this part of ISO/IEC 19775. This includes how light sources are defined and positioned as well as how lights effect the rendered image. Table 17.1 provides links to the major topics in this clause.
The following node types are light source nodes:
PointLight and SpotLight illuminate all objects in the world that fall within
their volume of lighting influence regardless of location within the transformation
hierarchy (by default, when their global field is TRUE
).
PointLight defines this volume of influence as a sphere centred at
the light (defined by a radius). SpotLight defines the volume of influence as
a solid angle defined by a radius and a cut-off angle. DirectionalLight nodes
illuminate only the objects descended from the light's parent grouping node,
including any descendent children of the parent grouping nodes
(by default, when their global field is FALSE
).
Shape nodes are illuminated by the sum of all of the lights in the world that affect them. This includes the contribution of both the direct and ambient illumination from light sources. Ambient illumination results from the scattering and reflection of light originally emitted directly by light sources. The amount of ambient light is associated with the individual lights in the scene. This is a gross approximation to how ambient reflection actually occurs in nature.
Any node used as a source of illumination is derived
from X3DLightNode.
All light sources contain an intensity,
a color, and an ambientIntensity
field. The intensity field specifies the brightness of the direct emission
from the light, and the ambientIntensity specifies the intensity of the
ambient emission from the light. Light intensity may range from 0.0 (no light
emission) to 1.0 (full intensity)infinity. The color field specifies the spectral
colour properties of both the direct and ambient light emission as an RGB value.
The on field specifies whether the light is enabled or disabled. If the value
is FALSE
, the light is disabled and will
not affect any nodes in the scene. If the value is TRUE
,
the light will affect other nodes according to
the 17.2.1.2 Scoping of lights.
In the physical lighting model (see 17.2.2.6 Physical lighting model) the intensity value should correspond to:
luminous intensity in candela (lm/sr) in case of PointLight and SpotLight.
illuminance in lux (lm/m2) in case of DirectionalLight.
In the physical lighting model, the ambientIntensity value is unused. Future specification versions may introduce a use for it, therefore we recommend leaving it at 0 (default) in case of physical rendering, to avoid future changes.
In case of the unlit lighting model all lights are ignored. See the 17.2.2.4 Unlit lighting model.
Each light type defines a global field that determines whether the light is global or scoped. Global lights illuminate all objects that fall within their volume of lighting influence. Scoped lights only illuminate objects that are in the same transformation hierarchy as the light; i.e., only the children and descendants of its enclosing parent group are illuminated. This allows the creation of realistic effects such as lights that illuminate a single room.
The X3D lighting model provides detailed equations that specify the colours to apply to each geometric object. For each object, the values of the Material, color, and/or texture currently being applied to the object are combined with the lights illuminating the object and the currently bound X3DFogObject (if specified). These equations are designed to simulate the physical properties of light striking a surface.
If a programmable shader is defined for an Appearance node, the lighting model shall be disabled and replaced by the functionality implemented by the shader program. See 31 Programmable shaders component for more information.
A Shape node is unlit if either of the following is true:
NOTE Geometry nodes that represent lines or points do not support lighting.
If the shape is unlit, the colour (Irgb) and alpha (A, 1−transparency) of the shape at each point on the shape's geometry is specified in Table 17.2.
Table 17.2 — Unlit colour and alpha mapping
Texture type | Colour per-vertex or per-face |
Colour NULL |
---|---|---|
No texture | Irgb= ICrgb A = 1 |
Irgb= (1, 1, 1) A = 1 |
Intensity (one-component) |
Irgb= IT
× ICrgb A = 1 |
Irgb = (IT,IT,IT
) A = 1 |
Intensity+Alpha (two-component) |
Irgb= I T
× ICrgb A = AT |
Irgb= (IT,IT,IT
) A = AT |
RGB (three-component) |
Irgb= ITrgb A = 1 |
Irgb= ITrgb A = 1 |
RGBA (four-component) |
Irgb= ITrgb A = AT |
Irgb= ITrgb A = AT |
where:
AT = normalized [0, 1] alpha value from 2 or
4 component texture image
ICrgb = interpolated per-vertex
colour, or per-face colour, from Color node
IT = normalized [0, 1] intensity from 1 or 2
component texture image
ITrgb= colour from 3-4
component texture image
If the Shape node is lit (i.e., a Material and an Appearance node are specified for the Shape), the Material and Texture nodes determine the diffuse colour for the lighting equation as specified in Table 17.3.
The Material's diffuseColor field modulates the color in the texture. Hence, a diffuseColor of white will result in the pure color of the texture, while a diffuseColor of black will result in a black diffuse factor regardless of the texture.
The Material's transparency field modulates the alpha in the texture. Hence, a transparency of 0 will result in an alpha equal to that of the texture. A transparency of 1 will result in an alpha of 0 regardless of the value in the texture.
Table 17.3 — Lit colour and alpha mapping
Texture type | Colour per-vertex or per-face |
Color node NULL |
No texture | ODrgb
= ICrgb A = 1-TM |
ODrgb
= IDrgb A = 1-TM |
Intensity texture (one-component) |
ODrgb
= IT × ICrgb A = 1-TM |
ODrgb
= IT × IDrgb A = 1-TM |
Intensity+Alpha texture (two-component) |
ODrgb
= IT × ICrgb A = AT |
ODrgb
= IT × IDrgb A = AT |
RGB texture (three-component) |
ODrgb
= ITrgb A = 1-TM |
ODrgb
= ITrgb A = 1-TM |
RGBA texture (four-component) |
ODrgb
= ITrgb A = AT |
ODrgb
= ITrgb A = AT |
where:
IDrgb = material diffuseColor
ODrgb = diffuse factor,
used in lighting equations below
TM = material transparency
All other terms are as defined in 17.2.2.2 Lighting off.
An ideal X3D implementation will evaluate the following lighting equation at each point on a lit surface. RGB intensities at each point on a geometry (Irgb) are given by:
Irgb = IFrgb × (1 -f0)
+ f0
× (OE
rgb + SUM( oni
× attenuationi
× spoti × ILrgb
× (ambienti + diffusei
+ specular i)))
where:
attenuationi = 1 / max(c1
+ c2 × dL
+ c3 × dL²
, 1 )
ambienti = Iia
× ODrgb × Oa
diffusei = Ii
× ODrgb × (
N · L
)
specular i = Ii
× OSrgb × (
N · ((L
+ V) / |L + V|))shininess
× 128
and:
Table 17.4 — Calculation of the spotlight factor
Condition (in order) | spoti = |
---|---|
lighti is PointLight or DirectionalLight | 1 |
spotAngle ≥ spotCO | 0 |
spotAngle ≤ spotBW | 1 |
spotBW < spotAngle < spot CO | (spotAngle - spotCO ) / (spotBW - spotCO) |
Table 17.5 — Calculation of the fog interpolant
Condition | f0 = |
---|---|
no fog | 1 |
fogType "LINEAR", dV < fogVisibility | (fogVisibility-dV) / fogVisibility |
fogType "LINEAR", dV > fogVisibility | 0 |
fogType "EXPONENTIAL", dV < fogVisibility | exp(-dV / (fogVisibility-dV ) ) |
fogType "EXPONENTIAL", dV > fogVisibility | 0 |
The X3D lighting equations are based on the simple illumination equations given in [FOLEY] and [OPENGL].
The X3D lighting model provides detailed equations that specify the colours to apply to each geometric object. For each object, the values of the material, color, and/or texture currently being applied to the object are combined with the lights illuminating the object and the currently bound X3DFogObject (if specified). These equations are designed to simulate the physical properties of light striking a surface.
If a programmable shader is defined for an Appearance node, the lighting model shall be disabled and replaced by the functionality implemented by the shader program. See 31 Programmable shaders component for more information.
Backward compatibility note: The lighting equations in X3D 4.0 are backward compatible with X3D 3.3. If you take a combination of X3D 3.3 material and light nodes, and simply use them in X3D 4.0 (leaving the new X3D 4.0 fields at their default values) then the rendering result will be equivalent. The only exception to this statement is differentiating between grayscale and RGB textures, which is discussed in section below in 17.2.2.2 Texture sampling.
When sampling any texture, the grayscale texture is exactly equivalent to using an RGB texture with all 3 components (red, green, blue) equal.
When sampling any texture, the texture without an alpha channel is exactly equivalent to using a texture with an alpha channel filled with 1 (indicating opaque).
These rules make treatment of the textures simple, and consistent with other 3D authoring software. They are also consistent with how the graphic APIs and GPU shaders query the textures.
The browsers are encouraged to optimize loading of the textures, to not load all textures as 4 channels (RGBA) to the GPU. Intensity texture can be loaded as just 1 channel, intensity + alpha is only 2 channels, RGB texture without alpha is 3 channels. Optimizing this loading is useful to keep GPU memory usage low, and to keep texture loading time smaller. However, this is just an optimization. Performing it is optional, and the rendering result should be the same as if all textures were loaded as full RGBA textures.
Backward compatibility note: In X3D version 3, the treatment of grayscale and RGB textures was not consistent. In some cases (using ImageTexture node, but not inside MultiTexture) grayscale texture resulted in a different rendering result than the equivalent RGB texture (with all red, green, blue components equal). As this was inconsistent (within X3D, and with other software and model formats), uneasy to implement (browsers needed to investigate the image header), needlessly limiting to authors, and the implementation was inconsistent across the existing browsers — in X3D 4.0 it was streamlined.
The declarations and definitions below are presented using a pseudo-code similar to the usual shading language code.
The function declarations look like this: functionName(typeOfParameter1 parameter1, typeOfParameter2 parameter2, ...). Type names are underlined.
The types can be X3D nodes, scalars (float), vectors with 2, 3 or 4 components (vector2, vector3, vector4), universal type (vectorAny which can represent any vector or scalar).
In function definitions, we often extract vector components with syntax like: thisVector.rgb (converts vector4 to vector3, discarding alpha channel) or thisVector.a (converts vector4 to float, extracting alpha channel value).
The symbol × performs a component-wise multiplication of vectors.
The symbol · is a modified vector dot product that always returns value >= 0, defined like this:
x · y = max(0.0, dotProduct(x, y))
The mixTexture(vector4 color, X3DTextureNode texture) function, used in the equations below, takes care of mixing an RGBA color with the RGBA value sampled from the texture at the given shape point.
If the texture is NULL
, then this function just returns
unmodified color.
Otherwise, if the texture is not a MultiTexture, then
mixTexture(color, texture) = color × textureSample(texture)
The textureSample(texture) is a function sampling the texture (recovering a single color from an array of pixels), with the correct texture coordinates and transformation.
In effect the color modulates the color from the texture.
The alpha (opacity) values are multiplied too, hence:
Otherwise, if the texture is a MultiTexture, then the mixTexture modifies this color following the MultiTexture mode specification. This is only possible when the MultiTexture is provided in the Appearance.texture field. See 12.2.5 Coexistence of textures specified in material nodes with the "Appearance.texture" field for details when multi-texturing is used.
The lerp(float factor, vectorAny x, vectorAny y) function performs a standard linear interpolation, applicable to scalars or vectors of any dimension:
lerp(factor, x, y) = x * (1 - factor) + y * factor = x + (y - x) * factor
The occlusion(vector4 color) function, used in the equations below for Phong and physical lighting model, is used to apply the occlusionTexture effect that can be specified in these nodes.
If the occlusionTexture was not provided (left NULL
)
then this function just returns unmodified color.
If the occlusionTexture was provided, then
occlusion(color) = lerp(occlusionStrength, color, color * textureSample(occlusionTexture).r)
In effect, the occlusionTexture multiplies the input color when occlusionStrength is 1.0. the occlusionTexture has no effect when when occlusionStrength is 0.0. Values in-between of occlusionStrength allow to smoothly interpolate between these two states.
The applyColorPerVertex(vector4 color) is used to change the color in case geometry uses Color or ColorRGBA nodes. All the lighting models use this function, although it affects a different parameter: emissiveParameter in case of unlit model, diffuseParameter in case of Phong model, and baseParameter in case of physical model. The function returns:
The interpolated per-vertex colour, or per-face colour, from the Color node, if the Color node is provided in the geometry color field.
Resulting rgb is derived from the values in the Color node.
Resulting a (alpha component) is taken from input color.a in this case.
Otherwise, the interpolated per-vertex colour, or per-face colour, from the ColorRGBA node, if the ColorRGBA node is provided in the geometry color field.
Resulting rgba vector is derived from the values in the ColorRGBA node.
Otherwise (if the geometry color field is empty) then it returns unmodified color.
The future X3D versions may introduce an option for Color and ColorRGBA to multiply the input color, instead of replacing it.
Moreover we define the following vectors:
N = normalized normal vector at this point on geometry. This vector is interpolated from vertex normals specified in a node derived from X3DNormalNode or calculated by the browser. It is modified by the normalTexture providing normals in the tangent space (see X3DOneSidedMaterialNode definition).
V = normalized vector from point on geometry to viewer's position.
The following definitions are specific to a light source i, which is indicated by a subscript in this text:
Li is, conceptually, direction to the light i. It is precisely defined like this:
Li = (PointLight/SpotLight) normalized vector from point on geometry to light source i position
Li = (DirectionalLight) negated and normalized direction of light source i
attenuationi = 1 / max(c1 + c2 × lightDistance + c3 × lightDistance² , 1 )
where
c1, c2, c3 are the values from light i attenuation field.
lightDistance is the distance from light to point on geometry, in light's coordinate system.
oni = 1, if light source i affects this point on the geometry or 0 if it doesn't.
The following conditions indicate that light source i does not affect this geometry:
FALSE
spoti is the spotlight factor. It calculates intensity within the SpotLight cone. Table 17.4 specifies how it is calculated. It relies on the following terms:
spotDirectioni = normalized SpotLight i direction field.
spotAngle = arcCosine(-L · spotDirectioni)
Table 17.4 — Calculation of the spotlight factor
Condition (in order) | spoti = |
---|---|
lighti is PointLight or DirectionalLight | 1 |
spotAngle ≥ SpotLight.cutOffAngle | 0 |
spotAngle ≤ SpotLight.beamWidth | 1 |
SpotLight.beamWidth < spotAngle < lightSource.cutOffAngle | (spotAngle - SpotLight.cutOffAngle) / (SpotLight.beamWidth - SpotLight.cutOffAngle) |
The applyFog(vector4 color) is used to change the color using the fog. Is it used by all lighting models, as the last operation performed on the color. The definition is:
applyFog(color) = lerp(fogInterpolant(fogDistance), fogColor, color)
where:
fogInterpolant is the fog interpolant, see Table 17.5 for calculation.
fogDistance is the distance from point on geometry to viewer's position, in coordinate system of current fog node.
fogColor is the currently bound fog's color.
Table 17.5 — Calculation of the fogInterpolant(FogDistance) function:
Condition | fogInterpolant(fogDistance) = |
---|---|
no fog | 1 |
fogType "LINEAR", fogDistance < fogVisibility | (fogVisibility - fogDistance) / fogVisibility |
fogType "LINEAR", fogDistance > fogVisibility | 0 |
fogType "EXPONENTIAL", fogDistance < fogVisibility | exp(-FogDistance / (fogVisibility - fogDistance ) ) |
fogType "EXPONENTIAL", fogDistance > fogVisibility | 0 |
A Shape node is unlit if either of the following is true:
The shape's appearance field is NULL (default).
The material field in the Appearance node is NULL (default).
The material field in the Appearance node contains a node of type UnlitMaterial.
In the first two cases above, the rendering is exactly equivalent as if the Appearance node
was provided (not NULL
),
and the material field inside contained an UnlitMaterial
with all the fields at their default.
Effectively, it means a white untextured unlit material is the default.
NOTE Geometry nodes that represent lines or points do not support lighting if the normal vectors for them are not provided.
If the shape is unlit, the RGBA color of the shape at each point on the shape's geometry is calculated using this equation:
fragmentColor = applyFog(mixTexture(applyColorPerVertex(emissiveParameter), emissiveTextureParameter))
where:emissiveParameter.rgb (RGB channels) are taken from UnlitMaterial.emissiveColor.
emissiveParameter.a (alpha channel) is taken from 1 - UnlitMaterial.transparency.
emissiveTextureParameter is equal to:
emissiveTexture of the UnlitMaterial node,
if it is not NULL
.
Otherwise, Appearance.texture, if the UnlitMaterial
has emissiveTexture equal NULL
,
but Appearance.texture is not NULL
.
See 12.2.5 Coexistence of textures specified in material nodes with the "Appearance.texture" field.
Otherwise (if both the UnlitMaterial.emissiveTexture and Appearance.texture are NULL
)
then emissiveTextureParameter is NULL
.
In other words, the mixTexture(...) function used above
simply returns the unmodified applyColorPerVertex(emissiveParameter).
The Shape node is lit with a Phong lighting model if the Appearance node is specified for the Shape, and the material field contains a Material node.
Note: This node is simply called Material for historical reasons. Conceptually, you should think about it now as a PhongMaterial.
The rendered fragment (pixel) color is determined by these equations:
fragmentColor = applyFog(emissiveParameter + occlusion(sumOverAllLights(lightContributioni)))
lightContributioni = oni × attenuationi × spoti × (ambienti + diffusei + speculari)
An ideal X3D implementation will evaluate the following lighting equation at each point on a lit surface. The means that we advise using Phong shading and assume it when writing equations below. For implementations that perform Gouraud shading see 17.2.2.8 Gouraud shading section.
The meaning of all the terms is explained below.
Material parameters
First, the parameters whose value doesn't depend on the light source:
The material diffuseParameter is calculated as follows:
diffuseParameter = mixTexture(applyColorPerVertex(diffuseParameter), diffuseTextureParameter)
where:diffuseParameter.a (RGB channels) is taken from Material.diffuseColor.
diffuseParameter.a (alpha channel) is taken from 1 - Material.transparency.
diffuseTextureParameter is equal to:
diffuseTexture of the Material node,
if it is not NULL
.
Otherwise, Appearance.texture, if the Material
has diffuseTexture equal NULL
,
but Appearance.texture is not NULL
.
See 12.2.5 Coexistence of textures specified in material nodes with the "Appearance.texture" field.
Otherwise (if both the Material.diffuseTexture and Appearance.texture are NULL
)
then diffuseTextureParameter is NULL
.
In other words, the mixTexture(...) function used above
simply returns the unmodified applyColorPerVertex(diffuseParameter).
The remaining parameters are defined below:
ambientParameter = ambientIntensity × diffuseColor × textureSample(ambientTexture).rgb
emissiveParameter = emissiveColor × textureSample(emissiveTexture).rgb
specularParameter = specularColor × textureSample(specularTexture).rgb
shininessParameter = shininess × textureSample(shininessTexture).a × 128
In the above equations, if the given texture is NULL
then behave as if the textureSample(texture) returned a white opaque value (1, 1, 1, 1).
Light parameters
Now we can define terms that depend on the light source:
ambienti = lightSource.ambientIntensity × ambientParameter
diffusei = lightSource.intensity × diffuseParameter × (N · L)
speculari = lightSource.intensity × specularParameter × (N · ((L + V) / |L + V|))shininessParameter
The Shape node is lit with a Physical lighting model if the Appearance node are specified for the Shape, and the material field contains a PhysicalMaterial node. We perform in this case a physically-based rendering.
The rendered fragment (pixel) color is determined by these equations:
fragmentColor = applyFog(emissiveParameter + occlusion(sumOverAllLights(lightContributioni)))
lightContributioni = oni × attenuationi × spoti × physicalLightContributioni
The input values used by the physical lighting equation are as follows:
baseParameter = mixTexture(applyColorPerVertex(baseParameter), baseTextureParameter)
where:baseParameter.a (RGB channels) is taken from PhysicalMaterial.baseColor.
baseParameter.a (alpha channel) is taken from 1 - PhysicalMaterial.transparency.
baseTextureParameter is equal to:
baseTexture of the PhysicalMaterial node,
if it is not NULL
.
Otherwise, Appearance.texture, if the PhysicalMaterial
has baseTexture equal NULL
,
but Appearance.texture is not NULL
.
See 12.2.5 Coexistence of textures specified in material nodes with the "Appearance.texture" field.
Otherwise (if both the PhysicalMaterial.baseTexture and Appearance.texture are NULL
)
then baseTextureParameter is NULL
.
In other words, the mixTexture(...) function used above
simply returns the unmodified applyColorPerVertex(baseParameter).
metallicParameter = PhysicalMaterial.metallic × textureSample(PhysicalMaterial.metallicRoughnessTexture).b
roughnessParameter = PhysicalMaterial.roughness × textureSample(PhysicalMaterial.metallicRoughnessTexture).g
If the metallicRoughnessTexture is NULL, then metallicParameter and roughnessParameter are just equal to (respectively) metallic and roughness values given by the PhysicalMaterial node.
Using the baseParameter, metallicParameter and roughnessParameter, the physical lighting model performs the exact same computations as the recommended glTF lighting model, to calculate physicalLightContributioni value. See glTF 2.0 specification section about lighting equations and glTF-Sample-Viewer implementation of it. Future revisions of this draft will contain the final recommended equations.
The Phong lighting equations are based on the simple illumination equations given in [FOLEY] and [OPENGL].
The physical lighting equations are based on the glTF 2.0 specification.
An ideal X3D implementation will evaluate the lighting equation at each point on a lit surface. The lighting equations in previous sections assume that you use Phong shading (not to be confused with Phong lighting model). In case of Phong shading, lighting is calculated at each fragment (pixel of the screen).
However, some implementations perform Gouraud shading, either by default, or as an option for the user (for efficiency), or as a fallback for an older GPUs. In such case, the lighting equations given above cannot be reproduced precisely. In Gouraud shading, you calculate lighting per-vertex, which means that it doesn't make sense to use texture information to modify material parameters.
In case when Gouraud shading is used we recommend this algorithm:
The vertex shader calculates lighting equations,
ignoring any texture information (as if all the textures were NULL
).
The fragment shader multiplies the resulting interpolated color by the main texture. The main texture is:
If the given texture is NULL
, then use the Appearance.texture.
If the Appearance.texture is also NULL, no texture is used.
All channels (RGB and alpha) are affected by the main texture.
This method of determining the main texture is deliberately 100% consistent with:
The way how the Appearance.texture cooperates with textures inside the materials, following section 12.2.5 Coexistence of textures specified in material nodes with the "Appearance.texture" field. Appearance.texture may be used in place of Material.diffuseTexture, or UnlitMaterial.emissiveTexture, or PhysicalMaterial.baseTexture.
The determination which texture contains the alpha channel that is multiplied by material transparency. We take it from alpha channel of Material.diffuseTexture, or UnlitMaterial.emissiveTexture, or PhysicalMaterial.baseTexture.
This recommendation tries to preserve the intended look as much as possible in Gouraud shading.
Note: This recommendation actually doesn't change anything in case of UnlitMaterial. And this is correct, Gouraud shading actually doesn't change how the UnlitMaterial can be implemented.
Note: When using PhysicalMaterial on older hardware, some implementations may fall back to the Phong lighting model. If this is necessary, we recommend using PhysicalMaterial.baseColor as the Phong diffuse factor, and PhysicalMaterial.baseTexture as the texture to multiply the resulting color.
X3DLightNode : X3DChildNode { SFFloat [in,out] ambientIntensity 0 [0,1] SFColor [in,out] color 1 1 1 [0,1] SFBool [in,out] global FALSE SFFloat [in,out] intensity 1 [0,1] SFFloat [in,out] intensity 1 [0,∞] SFNode [in,out] metadata NULL [X3DMetadataObject] SFBool [in,out] on TRUE }
The X3DLightNode abstract node type is the base type from which all node types that serve as light sources are derived. A description of the ambientIntensity, color, intensity, and on fields is in 17.2.1 Light source semantics. A description of the global field is in 17.2.1.2 Scoping of lights.
DirectionalLight : X3DLightNode { SFFloat [in,out] ambientIntensity 0 [0,1] SFColor [in,out] color 1 1 1 [0,1] SFVec3f [in,out] direction 0 0 -1 (-∞,∞) SFBool [in,out] global FALSE SFFloat [in,out] intensity 1 [0,1] SFFloat [in,out] intensity 1 [0,∞] SFNode [in,out] metadata NULL [X3DMetadataObject] SFBool [in,out] on TRUE }
The DirectionalLight node defines a directional light source that illuminates along rays parallel to a given 3-dimensional vector. A description of the ambientIntensity, color, intensity, and on fields is in 17.2.1 Light source semantics. A description of the global field is in 17.2.1.2 Scoping of lights.
The direction field specifies the direction vector of the illumination emanating from the light source in the local coordinate system. Light is emitted along parallel rays from an infinite distance away. A directional light source illuminates only the objects in its enclosing parent group. The light may illuminate everything within this coordinate system, including all children and descendants of its parent group. The accumulated transformations of the parent nodes affect the light.
DirectionalLight nodes do not attenuate with distance. A precise description of X3D's lighting equations is contained in 17.2.2 Lighting model.
PointLight : X3DLightNode { SFFloat [in,out] ambientIntensity 0 [0,1] SFVec3f [in,out] attenuation 1 0 0 [0,∞) SFColor [in,out] color 1 1 1 [0,1] SFBool [in,out] global TRUE SFFloat [in,out] intensity 1 [0,1] SFFloat [in,out] intensity 1 [0,∞] SFVec3f [in,out] location 0 0 0 (-∞,∞) SFNode [in,out] metadata NULL [X3DMetadataObject] SFBool [in,out] on TRUE SFFloat [in,out] radius 100 [0,∞) }
The PointLight node specifies a point light source at a 3D location in the local coordinate system. A point light source emits light equally in all directions; that is, it is omnidirectional. PointLight nodes are specified in the local coordinate system and are affected by ancestor transformations. A description of the global field is in 17.2.1.2 Scoping of lights.
Subclause 17.2.1 Light source semantics, contains a detailed description of the ambientIntensity, color, and intensity fields.
A PointLight node illuminates geometry within radius length base units of its location. Both radius and location are affected by ancestors' transformations (scales affect radius and transformations affect location). The radius field shall be greater than or equal to zero.
PointLight node's illumination falls off with distance as specified by three attenuation coefficients. The attenuation factor is:
1/max(attenuation[0] + attenuation[1] × r + attenuation[2] × r2, 1)
where r is the distance from the light to the surface being illuminated. The default is no attenuation. An attenuation value of (0, 0, 0) is identical to (1, 0, 0). Attenuation values shall be greater than or equal to zero. A detailed description of X3D's lighting equations is contained in 17.2.2 Lighting model.
SpotLight : X3DLightNode { SFFloat [in,out] ambientIntensity 0 [0,1] SFVec3f [in,out] attenuation 1 0 0 [0,∞) SFFloat [in,out] beamWidth π/4 (0,π/2] SFColor [in,out] color 1 1 1 [0,1] SFFloat [in,out] cutOffAngle π/2 (0,π/2] SFVec3f [in,out] direction 0 0 -1 (-∞,∞) SFBool [in,out] global TRUE SFFloat [in,out] intensity 1 [0,1] SFFloat [in,out] intensity 1 [0,∞] SFVec3f [in,out] location 0 0 0 (-∞,∞) SFNode [in,out] metadata NULL [X3DMetadataObject] SFBool [in,out] on TRUE SFFloat [in,out] radius 100 [0,∞) }
The SpotLight node defines a light source that emits light from a specific point along a specific direction vector and constrained within a solid angle. Spotlights may illuminate geometry nodes that respond to light sources and intersect the solid angle defined by the SpotLight. Spotlight nodes are specified in the local coordinate system and are affected by ancestors' transformations. A description of the global field is in 17.2.1.2 Scoping of lights.
A detailed description of ambientIntensity, color, intensity, and the lighting equations of X3D is provided in 17.2.1 Light source semantics. More information on lighting concepts can be found in 17.2.2 Lighting model, including a detailed description of the X3D lighting equations.
The location field specifies a translation offset of the centre point of the light source from the light's local coordinate system origin. This point is the apex of the solid angle which bounds light emission from the given light source. The direction field specifies the direction vector of the light's central axis defined in the local coordinate system.
The on field specifies whether the light source emits light. If on is TRUE, the light source is emitting light and may illuminate geometry in the scene. If on is FALSE, the light source does not emit light and does not illuminate any geometry.
The radius field specifies the radial extent of the solid angle and the maximum distance from location that may be illuminated by the light source. The light source does not emit light outside this radius. The radius shall be greater than or equal to zero.
Both radius and location are affected by ancestors' transformations (scales affect radius and transformations affect location).
The cutOffAngle field specifies the outer bound of the solid angle. The light source does not emit light outside of this solid angle. The beamWidth field specifies an inner solid angle in which the light source emits light at uniform full intensity. The light source's emission intensity drops off from the inner solid angle (beamWidth) to the outer solid angle (cutOffAngle) as described in the following equations:
angle = the angle between the Spotlight's direction vector and the vector from the Spotlight location to the point to be illuminated if (angle ≥ cutOffAngle): multiplier = 0 else if (angle ≤ beamWidth): multiplier = 1 else: multiplier = (angle - cutOffAngle) / (beamWidth - cutOffAngle) intensity(angle) = SpotLight.intensity × multiplier
If the beamWidth is greater than the cutOffAngle, beamWidth is defined to be equal to the cutOffAngle and the light source emits full intensity within the entire solid angle defined by cutOffAngle. Both beamWidth and cutOffAngle shall be greater than 0.0 and less than or equal to π/2. Figure 17.1 depicts the beamWidth, cutOffAngle, direction, location, and radius fields of the SpotLight node.
SpotLight illumination falls off with distance as specified by three attenuation coefficients. The attenuation factor is:
1/max(attenuation[0] + attenuation[1] × r + attenuation[2] × r2 , 1)
where r is the distance from the light to the surface being illuminated. The default is no attenuation. An attenuation value of (0, 0, 0) is identical to (1, 0, 0). Attenuation values shall be greater than or equal to zero. A detailed description of X3D's lighting equations is contained in 17.2.2 Lighting model.
The Lighting component provides three levels of support as specified in Table 17.6.
Table 17.6 — Lighting component support levels
Level | Prerequisites | Nodes/Features | Support |
---|---|---|---|
1 | Core 1 Shape 1 |
||
X3DLightNode (abstract) | n/a | ||
DirectionalLight | Not scoped by parent Group or Transform. | ||
2 | Core 1 Shape 1 |
||
All Level 1 Lighting nodes | All fields as supported in Level 1. | ||
PointLight | radius optionally supported. Linear attenuation. | ||
SpotLight | beamWidth optionally supported. radius optionally supported. Linear attenuation. | ||
3 | Core 1 Shape 1 |
||
All Level 2 Lighting nodes | All fields fully supported. | ||
4 | Core 1 Shape 1 |
||
All nodes | All fields and capabilities fully supported. |