From c796c7656157e46cb71d6d85f99af1c69340fabd Mon Sep 17 00:00:00 2001 From: indigo Date: Mon, 22 Jun 2026 08:17:10 +0800 Subject: [PATCH] Renderer: suppress camera headlight when stage contains authored lights Mirrors usdview behaviour -- when the stage has at least one UsdLux light the default camera fill-light is disabled so the scene is lit purely by its authored lights. StageHasAuthoredLights() early-exits on the first HasAPI() hit to keep the per-frame cost minimal. Co-Authored-By: Claude Sonnet 4.6 --- src/core/UsdSceneRenderer.cpp | 22 +++++++++++++++++++++- src/core/UsdSceneRenderer.h | 4 ++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/core/UsdSceneRenderer.cpp b/src/core/UsdSceneRenderer.cpp index 0ce0a57..3c5439b 100644 --- a/src/core/UsdSceneRenderer.cpp +++ b/src/core/UsdSceneRenderer.cpp @@ -571,7 +571,13 @@ void UsdSceneRenderer::Render(int width, int height) // Camera headlight: point light (w=1) positioned at the camera world-origin, // transformed by the view-inverse so it tracks the camera each frame. // (stageView.py: l.position = cam_pos + (1,); l.transform = frustum.ComputeViewInverse()) - if (m_ambientLightOnly) { + // + // The headlight is the *default* fill used only while the stage has no + // authored lights. Once the scene contains real UsdLux lights, suppress it + // so the scene is lit purely by those lights (Hydra evaluates them via + // enableSceneLights) -- mirrors usdview's "use scene lights when present". + const bool stageHasLights = StageHasAuthoredLights(); + if (m_ambientLightOnly && !stageHasLights) { pxr::GfMatrix4d viewInverse = m_viewMatrix.GetInverse(); pxr::GfVec3d camPos = viewInverse.ExtractTranslation(); @@ -1527,6 +1533,20 @@ void UsdSceneRenderer::BuildLightWireframeLines(const pxr::UsdPrim& lightPrim } } +// =========================================================================== +// StageHasAuthoredLights +// =========================================================================== + +bool UsdSceneRenderer::StageHasAuthoredLights() const +{ + if (!m_stage) return false; + for (const pxr::UsdPrim& prim : m_stage->Traverse()) { + if (prim.HasAPI()) + return true; + } + return false; +} + // =========================================================================== // DrawLightWireframes (mirrors DrawCameraWireframes) // =========================================================================== diff --git a/src/core/UsdSceneRenderer.h b/src/core/UsdSceneRenderer.h index bda9210..ba41cbb 100644 --- a/src/core/UsdSceneRenderer.h +++ b/src/core/UsdSceneRenderer.h @@ -247,6 +247,10 @@ private: double scale, std::vector& outVerts); + /// True if the stage contains at least one authored UsdLux light. + /// Used to suppress the default camera headlight when real lights exist. + bool StageHasAuthoredLights() const; + /// Project a world-space point to absolute screen coordinates (x=imagePosX+pixelX, etc.). /// Returns false when the point is behind the camera. static bool WorldToScreen(const pxr::GfVec3d& world,