Ghost Lights#

Overview#

A ghost light illuminates the scene while reducing or removing the visible light source from camera, reflection, and refraction paths. This is a non-physical artistic control. Use it to remove distracting highlights or hide a source that should affect lighting without appearing in the image.

Ghost-light controls operate at three levels. More specific values take precedence:

  1. A RenderProduct supplies global behavior for invisible lights.

  2. ghostFactor overrides those values for one light.

  3. primvars:omni:rtx:ghostFactor overrides both for one receiving object.

Primary-Ray Visibility#

visibleInPrimaryRay controls whether the light source itself is visible to the camera. It does not disable the light’s illumination.

USD declaration

Description

bool visibleInPrimaryRay

Shows or hides light geometry from camera rays. Dome and distant lights default to true; other supported lights default to false.

The following comparison changes only primary-ray visibility. The wall and subjects remain illuminated in both panels:

Rect light hidden and visible to primary camera rays while providing the same illumination

Primary-ray visibility hides the source without turning off its illumination.#

Per-Light Ghost Factor#

ghostFactor controls how a light source appears in specular and glossy interactions. It applies even when the source is visible to primary rays.

USD declaration

Description

float ghostFactor = -1

A negative value disables the per-light override. Zero leaves reflections and refractions unchanged. Any positive value removes perfect-specular appearances; increasing toward 1 suppresses progressively rougher glossy appearances. One hides the source from all but diffuse interactions.

The following comparison keeps the rect light visible to the camera while changing its ghost factor. Look at the light reflected in the two material spheres. Notice that the sharper reflection on the chrome sphere disappears much more quickly than the rougher reflection on the grey sphere.

Reflections of a rect light with ghost factors of 0, 0.5, and 1

A positive ghost factor removes the perfect-specular reflection and increasingly attenuates glossy reflections.#

Global Controls#

Apply OmniRtxSettingsCommonAPI_1 to a RenderProduct to configure the fallback behavior for lights hidden from primary rays:

USD declaration

Description

token omni:rtx:lights:visibilityOverride = "perLight"

Uses each light’s primary-ray visibility. forceVisible and forceInvisible override every light.

float omni:rtx:lights:reflectionVisibleRoughnessThreshold = 0

For an invisible light without a per-light ghost factor, hide it from reflection paths whose material roughness is below this threshold. The supported range is 0 through 1.

float omni:rtx:lights:refractionVisibleRoughnessThreshold = 0

For an invisible light without a per-light ghost factor, hide it from refraction paths whose material roughness is below this threshold. The supported range is 0 through 1.

A threshold of zero leaves the source visible in glossy interactions. Raising the threshold hides it from progressively rougher paths. These RenderProduct values do not affect a visible light unless the light has its own non-negative ghostFactor.

Per-Object Override#

Author float primvars:omni:rtx:ghostFactor = -1 on geometry to override ghosting for interactions on that object. The value follows the same scale as the per-light factor. A negative value disables the object override.

The object value takes precedence over the per-light and RenderProduct values. For a visible light, it applies only when that light also has a non-negative per-light ghostFactor. This prevents an object override from unexpectedly ghosting every visible light in the scene.

Authoring Ghost Lights#

The following examples hide a rect light from camera rays, ghost its glossy appearance, add an object-specific override, and configure the RenderProduct fallbacks:

def Xform "World"
{
    def RectLight "Softbox"
    {
        # Keep illuminating the scene, but hide the source from camera rays.
        bool visibleInPrimaryRay = false

        # Suppress the source in specular and glossy interactions.
        float ghostFactor = 0.5
    }

    def Sphere "Subject"
    {
        # Per-object ghosting overrides the light and RenderProduct values.
        float primvars:omni:rtx:ghostFactor = 1
    }
}

def "Render"
{
    def RenderProduct "Camera" (
        prepend apiSchemas = ["OmniRtxSettingsCommonAPI_1"]
    )
    {
        token omni:rtx:lights:visibilityOverride = "perLight"
        float omni:rtx:lights:reflectionVisibleRoughnessThreshold = 0.15
        float omni:rtx:lights:refractionVisibleRoughnessThreshold = 0.8
    }
}
light = UsdLux.RectLight.Define(stage, "/World/Softbox")
# Keep illuminating the scene, but hide the source from camera rays.
light.GetPrim().CreateAttribute(
    "visibleInPrimaryRay", Sdf.ValueTypeNames.Bool
).Set(False)
# Suppress the source in specular and glossy interactions.
light.GetPrim().CreateAttribute("ghostFactor", Sdf.ValueTypeNames.Float).Set(0.5)

subject = UsdGeom.Sphere.Define(stage, "/World/Subject")
# Per-object ghosting overrides the light and RenderProduct values.
UsdGeom.PrimvarsAPI(subject).CreatePrimvar(
    "omni:rtx:ghostFactor",
    Sdf.ValueTypeNames.Float,
    UsdGeom.Tokens.constant,
).Set(1.0)

product = UsdRender.Product.Define(stage, "/Render/Camera")
product.GetPrim().ApplyAPI("OmniRtxSettingsCommonAPI_1")
product.GetPrim().GetAttribute("omni:rtx:lights:visibilityOverride").Set(
    "perLight"
)
product.GetPrim().GetAttribute(
    "omni:rtx:lights:reflectionVisibleRoughnessThreshold"
).Set(0.15)
product.GetPrim().GetAttribute(
    "omni:rtx:lights:refractionVisibleRoughnessThreshold"
).Set(0.8)

Further Reading#

Refer to Common Attributes for the controls that change the light’s actual diffuse and specular contribution.