Lighting component

This component defines light source nodes.

See also X3D specification of the Lighting component.


1. Supported nodes

Lights shine on shapes, making them brighter.

We support these light nodes:

  • DirectionalLight(Pascal API: TDirectionalLightNode)

    Light that has a direction. This light does not have a position (at least, not a position meaningful for the light calculation). It's like a sun, i.e. a very very distant light source, from which all the light rays can be considered parallel.

  • PointLight(Pascal API: TPointLightNode)

    Light that has a position in 3D space, and shines uniformly in all the directions.

  • SpotLight(Pascal API: TSpotLightNode)

    Light that has a position in 3D space, and shines light in the specific direction with a cone of given angle.

  • EnvironmentLight node

    TODO: This is an upcoming light source, that is using a cubemap to describe light source intensity around the target. It can use any X3D cubemap node to describe the environment. Functionality should match match glTF lighting defined by EXT_lights_image_based.

    See design status here.

    It is actually already implemented, and works in some cases. We have initial examples of it here. But do not depend on this light source yet. The API and implementation may change. It's a work-in-progress how to express it best.

2. Which shapes are affected by lights

Only the "lit" shapes (with non-nil material nodes: Material or PhysicalMaterial) are affected by lights.

All these conditions must be satisfied in order for the light to shine (contribute to a color) on a given shape:

  • The light node must be in a "traversed" part of the node graph. This means that if the light is inside an inactive Switch or LOD child, it doesn't shine on anything. This is consistent with the general idea that stuff inside inactive Switch or LOD children is never visible.

  • The shape must be within the light radius (in case of PointLight, SpotLight).

    As a CGE extension, we treat radius values < 0 as "infinity". So just set radius to -1 to disable this limit.

  • If the light has global field set to FALSE, then it only affects the shapes nodes that are sibling to it or below.

    When importing lights from glTF, all the lights are global by default.

    In X3D, by default, DirectionalLight has global=FALSE (otherwise it would affect the whole scene), while PointLight and SpotLight have global=TRUE (because they are typically limited by their radius field).

    See the example directional_light_scope_simple.x3dv to see how the DirectionalLight light scope is limited by default (when it has global=FALSE).

Note that, while your whole scene can have an unlimited number of lights, the number of lights that affect a particular shape is limited. It is limited to 64 by default, but you can change this limit by setting Scene.RenderOptions.MaxLightsPerShape. You can also experiment with it in view3dscene, which has a menu item "View -> Max Lights Per Shape...". Test e.g. on this demo model: gltf/multiple_animated_lights.

3. Gouraud or Phong shading (calculate light per-vertex or per-pixel)

We now render all shapes using prettier Phong shading (per-pixel lighting calculation) by default.

You can manually request faster Gouraud shading (per-vertex lighting calculation). Even then, specific cases may cause using Phong shading. In particular PhysicalMaterial causes Phong shading, so imported glTF models use Phong shading by default. See the Shape.shading field for a description of shading approaches, and how it is determined.

In general we recommend prettier Phong shading. It is a significant boost to quality:

  • Per-pixel lighting means that local lighting effects, in particular spot light cones and specular highlights, are precisely rendered.

  • Lights attenuation is also calculated per-pixel, this sometimes gives much better results.

  • Lights with radius with fixed-function pipeline rendering
    Light with radius with per-pixel lighting (shader pipeline)

    Light radius is also checked per-pixel when necessary (when shape is partially inside, partially outside the light radius). This allows to use "radius" field (on point and spot lights) for much more dramatic lighting effects. For example, compare the two screenshots from light_street_lights_radius demo on the right (from our VRML/X3D demo models).

You can also switch shading for particular shapes.

Pascal Developers: you can switch shading for the whole scene by Scene.RenderOptions.PhongShading := true / false or only for a particular shape using Shape.Shading := shPhong / shGouraud.

4. Problems? Get latest GPU drivers

The engine requires a good graphic card with latest drivers for proper rendering. Before reporting problems, make sure that you have the latest OS version, with the latest drivers. You may need to download latest drivers from

Windows sometimes comes with quite outdated drivers, so be sure to get drivers from above sites. On Linux and macOS, it should be enough to make sure you use the latest version of your system, with all updates applied. On Linux, you may also install the proprietary OpenGL drivers to squeeze best performance (although it's not necessary in many cases, even for 3D games, using CGE or not).