Add per-viewport cull style option

Exposes UsdImagingGLCullStyle as a Cull Style sub-menu in the gear popup
(Back Unless Double-Sided / Back / Front / Nothing / No Opinion). Defaults
to BackUnlessDoubleSided, matching usdview. Setting persists per-viewport
to viewport_settings.ini.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-30 08:15:20 +08:00
parent 7586d380e9
commit 781d464f47
5 changed files with 35 additions and 1 deletions
+2 -1
View File
@@ -174,6 +174,7 @@ UsdSceneRenderer::UsdSceneRenderer()
, m_aaEnabled(false)
, m_backgroundColor(0.15f, 0.15f, 0.15f)
, m_shadingMode(ShadingMode::SmoothShaded)
, m_cullStyle(CullStyle::BackUnlessDoubleSided)
, m_colorCorrectionMode(ColorCorrectionMode::sRGB)
, m_ambientLightOnly(true)
, m_domeLightEnabled(false)
@@ -728,7 +729,7 @@ void UsdSceneRenderer::Render(int width, int height)
m_renderParams.showRender = m_showRender;
m_renderParams.enableSampleAlphaToCoverage = true;
m_renderParams.gammaCorrectColors = false;
m_renderParams.cullStyle = pxr::UsdImagingGLCullStyle::CULL_STYLE_BACK_UNLESS_DOUBLE_SIDED;
m_renderParams.cullStyle = static_cast<pxr::UsdImagingGLCullStyle>(m_cullStyle);
m_renderParams.enableSceneMaterials = true;
m_renderParams.enableSceneLights = true;
m_renderParams.highlight = true;
+13
View File
@@ -43,6 +43,15 @@ enum class ShadingMode {
Unlit, ///< Smooth geometry, lighting disabled
};
/// Back-face culling style — maps directly to UsdImagingGLCullStyle.
enum class CullStyle {
NoOpinion = 0,
Nothing = 1,
Back = 2,
Front = 3,
BackUnlessDoubleSided = 4,
};
/// Viewport color correction mode — maps to UsdImagingGLRenderParams::colorCorrectionMode.
enum class ColorCorrectionMode {
Disabled, ///< No correction (raw linear output)
@@ -240,6 +249,9 @@ public:
ShadingMode GetShadingMode() const { return m_shadingMode; }
void SetShadingMode(ShadingMode m) { m_shadingMode = m; m_forceRefresh = true; }
CullStyle GetCullStyle() const { return m_cullStyle; }
void SetCullStyle(CullStyle c) { m_cullStyle = c; m_forceRefresh = true; }
ColorCorrectionMode GetColorCorrectionMode() const { return m_colorCorrectionMode; }
void SetColorCorrectionMode(ColorCorrectionMode m) { m_colorCorrectionMode = m; m_forceRefresh = true; }
@@ -358,6 +370,7 @@ private:
// Lighting settings (mirrors stageView.py viewSettings)
ShadingMode m_shadingMode; // draw mode + lighting flags
CullStyle m_cullStyle; // back/front/none face culling
ColorCorrectionMode m_colorCorrectionMode; // viewport color correction
std::string m_ocioDisplay;
std::string m_ocioView;
+2
View File
@@ -670,6 +670,7 @@ void ViewportPanel::SaveSettings(const std::string& path) const
f << "AmbientLightOnly=" << (s.ambientLightOnly ? 1 : 0) << "\n";
f << "DomeLightEnabled=" << (s.domeLightEnabled ? 1 : 0) << "\n";
f << "ShadingMode=" << s.shadingMode << "\n";
f << "CullStyle=" << s.cullStyle << "\n";
}
}
@@ -741,6 +742,7 @@ void ViewportPanel::LoadSettings(const std::string& path)
else if (key == "AmbientLightOnly") ts.ambientLightOnly = (val == "1");
else if (key == "DomeLightEnabled") ts.domeLightEnabled = (val == "1");
else if (key == "ShadingMode") ts.shadingMode = toInt(val, ts.shadingMode);
else if (key == "CullStyle") ts.cullStyle = toInt(val, ts.cullStyle);
}
}
+17
View File
@@ -106,6 +106,7 @@ ViewportTileSettings ViewportTile::GetSettings() const
s.ambientLightOnly = m_renderer.GetAmbientLightOnly();
s.domeLightEnabled = m_renderer.GetDomeLightEnabled();
s.shadingMode = static_cast<int>(m_renderer.GetShadingMode());
s.cullStyle = static_cast<int>(m_renderer.GetCullStyle());
return s;
}
@@ -126,6 +127,7 @@ void ViewportTile::ApplySettings(const ViewportTileSettings& s)
m_renderer.SetAmbientLightOnly(s.ambientLightOnly);
m_renderer.SetDomeLightEnabled(s.domeLightEnabled);
m_renderer.SetShadingMode(static_cast<ShadingMode>(s.shadingMode));
m_renderer.SetCullStyle(static_cast<CullStyle>(s.cullStyle));
}
// ---------------------------------------------------------------------------
@@ -1018,6 +1020,21 @@ void ViewportTile::RenderCompactToolbar(int tileIndex)
ImGui::EndMenu();
}
// -- Cull Style --------------------------------------------------
if (ImGui::BeginMenu("Cull Style")) {
CullStyle curCull = m_renderer.GetCullStyle();
auto cullItem = [&](const char* label, CullStyle style) {
if (ImGui::MenuItem(label, nullptr, curCull == style))
m_renderer.SetCullStyle(style);
};
cullItem("Back Unless Double-Sided", CullStyle::BackUnlessDoubleSided);
cullItem("Back", CullStyle::Back);
cullItem("Front", CullStyle::Front);
cullItem("Nothing", CullStyle::Nothing);
cullItem("No Opinion", CullStyle::NoOpinion);
ImGui::EndMenu();
}
// -- AOV ---------------------------------------------------------
{
pxr::TfTokenVector aovs = m_renderer.GetRendererAovs();
+1
View File
@@ -32,6 +32,7 @@ struct ViewportTileSettings {
bool ambientLightOnly = true;
bool domeLightEnabled = false;
int shadingMode = 0;
int cullStyle = 4; // CullStyle::BackUnlessDoubleSided
bool showGuides = false;
bool showProxy = true;
bool showRender = false;