Skip to content

Commit c947985

Browse files
Hydrogent: support orthographic camera
1 parent 5e49c20 commit c947985

File tree

1 file changed

+45
-14
lines changed

1 file changed

+45
-14
lines changed

Hydrogent/src/HnCamera.cpp

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2023-2024 Diligent Graphics LLC
2+
* Copyright 2023-2025 Diligent Graphics LLC
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -72,19 +72,50 @@ void HnCamera::Sync(pxr::HdSceneDelegate* SceneDelegate,
7272

7373
if (OrigDirtyBits & pxr::HdCamera::DirtyParams)
7474
{
75-
const float HorzAperture = GetHorizontalAperture();
76-
const float VertAperture = GetVerticalAperture();
77-
const float FocalLength = GetFocalLength();
78-
const pxr::GfRange1f ClippingRange = GetClippingRange();
79-
80-
m_ProjectionMatrix._11 = FocalLength / (0.5f * HorzAperture);
81-
m_ProjectionMatrix._22 = FocalLength / (0.5f * VertAperture);
82-
83-
const HnRenderDelegate* pRenderDelegate = static_cast<const HnRenderDelegate*>(SceneDelegate->GetRenderIndex().GetRenderDelegate());
84-
const IRenderDevice* pDevice = pRenderDelegate->GetDevice();
85-
const RenderDeviceInfo& DeviceInfo = pDevice->GetDeviceInfo();
86-
// USD camera attributes are in scene units, while Diligent expects them in world units
87-
m_ProjectionMatrix.SetNearFarClipPlanes(ClippingRange.GetMin() * MetersPerUnit, ClippingRange.GetMax() * MetersPerUnit, DeviceInfo.GetNDCAttribs().MinZ == -1);
75+
// By an odd convention, lens and filmback properties are measured in tenths of a scene unit rather than "raw" scene units.
76+
// https://openusd.org/dev/api/class_usd_geom_camera.html#UsdGeom_CameraUnits
77+
// So, for example after
78+
// UsdCamera.GetFocalLengthAttr().Set(30.f)
79+
// Reading the attribute will return same value:
80+
// float focalLength;
81+
// UsdCamera.GetFocalLengthAttr().Get(&focalLength); // focalLength == 30
82+
// However
83+
// focalLength = SceneDelegate->GetCameraParamValue(id, HdCameraTokens->focalLength).Get<float>(); // focalLength == 3
84+
constexpr float UsdCamLensUnitScale = 10;
85+
const float HorzApertureUnits = GetHorizontalAperture() * UsdCamLensUnitScale;
86+
const float VertApertureUnits = GetVerticalAperture() * UsdCamLensUnitScale;
87+
const float FocalLengthUnits = GetFocalLength() * UsdCamLensUnitScale;
88+
const pxr::GfRange1f ClippingRangeUnits = GetClippingRange();
89+
90+
// Diligent expects camera attributes in world units
91+
const float HorzApertureMeters = HorzApertureUnits * MetersPerUnit;
92+
const float VertApertureMeters = VertApertureUnits * MetersPerUnit;
93+
const pxr::GfRange1f ClippingRangeMeters = ClippingRangeUnits * MetersPerUnit;
94+
95+
const HnRenderDelegate* pRenderDelegate = static_cast<const HnRenderDelegate*>(SceneDelegate->GetRenderIndex().GetRenderDelegate());
96+
const IRenderDevice* pDevice = pRenderDelegate->GetDevice();
97+
const RenderDeviceInfo& DeviceInfo = pDevice->GetDeviceInfo();
98+
const bool NegativeOneToOneNDCZ = DeviceInfo.GetNDCAttribs().MinZ == -1;
99+
100+
if (GetProjection() == pxr::HdCamera::Projection::Perspective)
101+
{
102+
m_ProjectionMatrix = {};
103+
104+
m_ProjectionMatrix._11 = FocalLengthUnits / (0.5f * HorzApertureUnits);
105+
m_ProjectionMatrix._22 = FocalLengthUnits / (0.5f * VertApertureUnits);
106+
107+
m_ProjectionMatrix.SetNearFarClipPlanes(ClippingRangeMeters.GetMin(), ClippingRangeMeters.GetMax(), NegativeOneToOneNDCZ);
108+
}
109+
else if (GetProjection() == pxr::HdCamera::Projection::Orthographic)
110+
{
111+
112+
m_ProjectionMatrix = float4x4::Ortho(HorzApertureMeters, VertApertureMeters, ClippingRangeMeters.GetMin(), ClippingRangeMeters.GetMax(), NegativeOneToOneNDCZ);
113+
}
114+
else
115+
{
116+
LOG_ERROR_MESSAGE("Unknown camera projection");
117+
m_ProjectionMatrix = float4x4::Identity();
118+
}
88119
}
89120
}
90121

0 commit comments

Comments
 (0)