Add custom viewport color correction (sRGB/OCIO), bypassing HdxColorCorrectionTask
Hydra's HdxColorCorrectionTask rendered prims black in OCIO mode and could corrupt the GlfDrawTarget bind stack on failure (skipping Unbind), blacking out every later frame including sRGB. Replace it with our own GL post-process: the scene renders linear (RGBA16F) and is corrected by a fullscreen shader -- linear->sRGB encode, or OCIO via the OCIO 2.1 GPU API (GpuShaderDesc plus uploaded 1D/3D LUT textures). OCIO build failures fall back to sRGB (never black) and USD diagnostics are routed to the app log. - core: ViewportColorCorrector + ApplyViewportColorCorrection in UsdSceneRenderer - utils: OcioConfigParser enumerates displays/views/colorspaces/looks from $OCIO - ui: gear-menu OCIO controls (ViewportTile) + per-viewport persistence (ViewportPanel) - Application: point $OCIO at the bundled ACES 1.2 config - CMake: link/copy OpenColorIO, download ACES 1.2 config; plus hdCycles build config (disable OpenVDB/Embree, fix TBB/OpenSubdiv/Imath dirs, exclude CRT DLLs) - main: pre-flight plugin DLL load check to skip plugins with missing deps Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -21,9 +21,14 @@
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
namespace UsdLayerManager {
|
||||
|
||||
/// Custom viewport color-correction post-process (sRGB / OCIO) implemented in
|
||||
/// our own GL shader instead of HdxColorCorrectionTask. Defined in the .cpp.
|
||||
class ViewportColorCorrector;
|
||||
|
||||
/// Bounding box display mode for selected prims.
|
||||
enum class BBoxMode {
|
||||
None, ///< No bounding boxes drawn
|
||||
@@ -40,6 +45,13 @@ enum class ShadingMode {
|
||||
Unlit, ///< Smooth geometry, lighting disabled
|
||||
};
|
||||
|
||||
/// Viewport color correction mode — maps to UsdImagingGLRenderParams::colorCorrectionMode.
|
||||
enum class ColorCorrectionMode {
|
||||
Disabled, ///< No correction (raw linear output)
|
||||
sRGB, ///< Linear → sRGB gamma (default)
|
||||
OpenColorIO, ///< Full OCIO pipeline via bundled ACES 1.2 config
|
||||
};
|
||||
|
||||
class UsdSceneRenderer {
|
||||
public:
|
||||
UsdSceneRenderer();
|
||||
@@ -211,6 +223,18 @@ public:
|
||||
ShadingMode GetShadingMode() const { return m_shadingMode; }
|
||||
void SetShadingMode(ShadingMode m) { m_shadingMode = m; m_forceRefresh = true; }
|
||||
|
||||
ColorCorrectionMode GetColorCorrectionMode() const { return m_colorCorrectionMode; }
|
||||
void SetColorCorrectionMode(ColorCorrectionMode m) { m_colorCorrectionMode = m; m_forceRefresh = true; }
|
||||
|
||||
const std::string& GetOcioDisplay() const { return m_ocioDisplay; }
|
||||
void SetOcioDisplay(std::string v) { m_ocioDisplay = std::move(v); m_forceRefresh = true; }
|
||||
const std::string& GetOcioView() const { return m_ocioView; }
|
||||
void SetOcioView(std::string v) { m_ocioView = std::move(v); m_forceRefresh = true; }
|
||||
const std::string& GetOcioColorSpace() const { return m_ocioColorSpace; }
|
||||
void SetOcioColorSpace(std::string v){ m_ocioColorSpace = std::move(v); m_forceRefresh = true; }
|
||||
const std::string& GetOcioLook() const { return m_ocioLook; }
|
||||
void SetOcioLook(std::string v) { m_ocioLook = std::move(v); m_forceRefresh = true; }
|
||||
|
||||
/// Default material ambient (kA, default 0.2 — matches viewSettingsDataModel.py).
|
||||
float GetDefaultMaterialAmbient() const { return m_defaultMaterialAmbient; }
|
||||
void SetDefaultMaterialAmbient(float v) { m_defaultMaterialAmbient = v; }
|
||||
@@ -239,6 +263,7 @@ private:
|
||||
int m_lastRenderWidth = 0;
|
||||
int m_lastRenderHeight = 0;
|
||||
void InitRenderer();
|
||||
|
||||
void InitGridResources();
|
||||
void RebuildGridVBO(); ///< (Re)build grid line geometry after up-axis or size change.
|
||||
void DestroyGridResources();
|
||||
@@ -310,7 +335,12 @@ private:
|
||||
pxr::GfVec3f m_backgroundColor;
|
||||
|
||||
// Lighting settings (mirrors stageView.py viewSettings)
|
||||
ShadingMode m_shadingMode; // draw mode + lighting flags
|
||||
ShadingMode m_shadingMode; // draw mode + lighting flags
|
||||
ColorCorrectionMode m_colorCorrectionMode; // viewport color correction
|
||||
std::string m_ocioDisplay;
|
||||
std::string m_ocioView;
|
||||
std::string m_ocioColorSpace;
|
||||
std::string m_ocioLook;
|
||||
bool m_ambientLightOnly; // camera headlight
|
||||
bool m_domeLightEnabled; // dome/IBL light
|
||||
bool m_stageIsZup; // used for dome light rotation
|
||||
@@ -361,6 +391,18 @@ private:
|
||||
// --- Camera wireframe cache ---
|
||||
pxr::SdfPathVector m_cachedCameraPaths;
|
||||
bool m_cameraCacheDirty = true;
|
||||
|
||||
// --- Custom color-correction post-process ---------------------------------
|
||||
// The scene is rendered linear (Hydra correction "disabled") and corrected
|
||||
// by our own GL shader, bypassing HdxColorCorrectionTask. ApplyViewport-
|
||||
// ColorCorrection() resolves the linear result into m_ccLinearTex, then
|
||||
// draws a corrected fullscreen quad back into the draw-target FBO.
|
||||
void ApplyViewportColorCorrection(int width, int height);
|
||||
std::unique_ptr<ViewportColorCorrector> m_colorCorrector;
|
||||
GLuint m_ccLinearFBO = 0; ///< FBO wrapping m_ccLinearTex (correction input)
|
||||
GLuint m_ccLinearTex = 0; ///< single-sample linear copy of the Hydra output
|
||||
int m_ccLinearW = 0;
|
||||
int m_ccLinearH = 0;
|
||||
};
|
||||
|
||||
} // namespace UsdLayerManager
|
||||
|
||||
Reference in New Issue
Block a user