Spot Light USD Export Produces Incorrect Intensity Values Based on Cone Angle and Source Radius

When exporting Unreal Engine spot lights from a level to USD, lights with identical EV intensity and source radius settings but different outer cone angles produce inconsistent intensity values in the exported USD file.

The root cause seems to be in UsdToUnreal::ConvertLuxShapingAPIIntensityAttr (and my other places where this similar conversion happens for spotlight), the light area in square meters is computed as:

float SolidAngle = 2.f * PI * (1.f - GetSpotLightCosHalfConeAngle(OuterConeAngle));
float AreaInSqMeters = FMath::Max(SolidAngle * FMath::Square(SourceRadius / 100.f), KINDA_SMALL_NUMBER);

It seems the FMath::Max(…, KINDA_SMALL_NUMBER) guard was intended to prevent division by zero. However, because KINDA_SMALL_NUMBER = 1e-4 and the clamp triggers when: SolidAngle × (R/100)² < 1e-4

For example for source radius 1 any cone angle below 32.77°, the area is hard-clamped to 1e-4 regardless of the actual solid angle, making all such lights produce identical — and incorrect — intensity values.

The fix we have internally so far:

Move the clamp inside the expression so it applies only to the radius term, not to the combined product:

 // BEFORE
 
float AreaInSqMeters = FMath::Max(SolidAngle * FMath::Square(SourceRadius / 100.f), KINDA_SMALL_NUMBER);
 
 // AFTER
float AreaInSqMeters = SolidAngle * FMath::Max(FMath::Square(SourceRadius / 100.f), KINDA_SMALL_NUMBER);

To be sincere I’m not convinced the actual formula actually represent what happens in engine, I could be wrong here but what I observe happening in engine is in order to preserve the same visual brightness of a light when it’s outer cone increases I also need to increase it’s lumens intensity. But when exporting those lights to USD the oppose of what is set in the engine happens where the intensity value grows bigger as we the outer cone decrease.

It would be great if someone could explain what is the logic behind this.

Steps to Reproduce

  1. Create 4 Spot Lights in a level
  2. Set their intensity unity to EV and then set the value to 8
  3. Change the intensity unity to Lumens so you can get the conversion from EV to Lumens (This is because of a bug exporting EV as flagged here: [Content removed]
  4. Set their Outer Cone Angles to: 20°, 30°, 40°, 50°
  5. Set the Source Radius to 1
  6. Leave all other properties identical
  7. Export the level to USD.
  8. Inspect the inputs:intensity attribute on each exported light.

Expected Result: The intensity increases as the outer cone angle decreases.

Actual Result:

- 20°, 30° → intensity = same value, clamped in code

- 40°, 50° → intensity = different value, unclamped

The transition point for source radius 1 is at ~32.77°: all cone angles below this threshold are clamped to the same constant intensity; above it, intensities vary correctly with the solid angle.

Hello,

Thanks for reporting this issue, there does appear to be an unintentional clamp in this case. For preventing divide by zero, using UE_SMALL_NUMBER may be preferred, but I’ll defer to my colleagues who are more familiar with the latest changes in this area as to the correct fix and about the way radius and intensity should behave with USD export. I’m reassigning this issue to provide an answer to that, but you may not hear back till Tuesday next week due to the holidays in Europe. I’ve created the following issue for tracking which should be public soon: https://issues.unrealengine.com/issue/UE\-372625