diff options
author | Patrick Mours <pmours@nvidia.com> | 2022-04-12 19:08:25 +0300 |
---|---|---|
committer | Patrick Mours <pmours@nvidia.com> | 2022-04-13 13:24:21 +0300 |
commit | c31b89e76e0d216fc7b8807aa8ccd815b30ed93d (patch) | |
tree | 29dde38264c83ed9588e02322ff9d6a9c75ee872 /intern | |
parent | 3a88f151c49f820ebb1589377958b397b1d9b96c (diff) |
Cycles: Add support for "stageMetersPerUnit" Hydra render setting
This can be useful to match transforms to what native Cycles
would see in Blender, as USD typically uses centimeters, but
Blender uses meters. This patch also fixes the hardcoded focal
length multiplicator, which is now using the same units as
everything else. Default of "stageMetersPerUnit" is 0.01 to match
the USD default of centimeters.
Differential Revision: https://developer.blender.org/D14630
Diffstat (limited to 'intern')
-rw-r--r-- | intern/cycles/hydra/camera.cpp | 57 | ||||
-rw-r--r-- | intern/cycles/hydra/camera.h | 8 | ||||
-rw-r--r-- | intern/cycles/hydra/geometry.inl | 6 | ||||
-rw-r--r-- | intern/cycles/hydra/light.cpp | 11 | ||||
-rw-r--r-- | intern/cycles/hydra/render_delegate.cpp | 26 | ||||
-rw-r--r-- | intern/cycles/hydra/render_pass.cpp | 5 | ||||
-rw-r--r-- | intern/cycles/hydra/session.h | 11 |
7 files changed, 91 insertions, 33 deletions
diff --git a/intern/cycles/hydra/camera.cpp b/intern/cycles/hydra/camera.cpp index c746a107899..62042cbbcd2 100644 --- a/intern/cycles/hydra/camera.cpp +++ b/intern/cycles/hydra/camera.cpp @@ -3,6 +3,7 @@ * Copyright 2022 Blender Foundation */ #include "hydra/camera.h" +#include "hydra/session.h" #include "scene/camera.h" #include <pxr/base/gf/frustum.h> @@ -12,6 +13,19 @@ HDCYCLES_NAMESPACE_OPEN_SCOPE extern Transform convert_transform(const GfMatrix4d &matrix); +Transform convert_camera_transform(const GfMatrix4d &matrix, float metersPerUnit) +{ + Transform t = convert_transform(matrix); + // Flip Z axis + t.x.z *= -1.0f; + t.y.z *= -1.0f; + t.z.z *= -1.0f; + // Scale translation + t.x.w *= metersPerUnit; + t.y.w *= metersPerUnit; + t.z.w *= metersPerUnit; + return t; +} #if PXR_VERSION < 2102 // clang-format off @@ -61,13 +75,20 @@ void HdCyclesCamera::Sync(HdSceneDelegate *sceneDelegate, if (*dirtyBits & DirtyBits::DirtyTransform) { sceneDelegate->SampleTransform(id, &_transformSamples); + bool transform_found = false; for (size_t i = 0; i < _transformSamples.count; ++i) { if (_transformSamples.times[i] == 0.0f) { _transform = _transformSamples.values[i]; _data.SetTransform(_transform); + transform_found = true; break; } } + + if (!transform_found && _transformSamples.count) { + _transform = _transformSamples.values[0]; + _data.SetTransform(_transform); + } } #else if (*dirtyBits & DirtyBits::DirtyViewMatrix) { @@ -236,18 +257,21 @@ void HdCyclesCamera::Finalize(HdRenderParam *renderParam) HdCamera::Finalize(renderParam); } -void HdCyclesCamera::ApplyCameraSettings(Camera *cam) const +void HdCyclesCamera::ApplyCameraSettings(HdRenderParam *renderParam, Camera *cam) const { - ApplyCameraSettings(_data, _windowPolicy, cam); + ApplyCameraSettings(renderParam, _data, _windowPolicy, cam); + + const float metersPerUnit = static_cast<HdCyclesSession *>(renderParam)->GetStageMetersPerUnit(); array<Transform> motion(_transformSamples.count); - for (size_t i = 0; i < _transformSamples.count; ++i) - motion[i] = convert_transform(_transformSamples.values[i]) * - transform_scale(1.0f, 1.0f, -1.0f); + for (size_t i = 0; i < _transformSamples.count; ++i) { + motion[i] = convert_camera_transform(_transformSamples.values[i], metersPerUnit); + } cam->set_motion(motion); } -void HdCyclesCamera::ApplyCameraSettings(const GfCamera &dataUnconformedWindow, +void HdCyclesCamera::ApplyCameraSettings(HdRenderParam *renderParam, + const GfCamera &dataUnconformedWindow, CameraUtilConformWindowPolicy windowPolicy, Camera *cam) { @@ -261,20 +285,22 @@ void HdCyclesCamera::ApplyCameraSettings(const GfCamera &dataUnconformedWindow, GfCamera::Orthographic == CAMERA_ORTHOGRAPHIC); cam->set_camera_type(static_cast<CameraType>(data.GetProjection())); + const float metersPerUnit = static_cast<HdCyclesSession *>(renderParam)->GetStageMetersPerUnit(); + auto viewplane = data.GetFrustum().GetWindow(); auto focalLength = 1.0f; if (data.GetProjection() == GfCamera::Perspective) { viewplane *= 2.0 / viewplane.GetSize()[1]; // Normalize viewplane - focalLength = data.GetFocalLength() * 1e-3f; + focalLength = data.GetFocalLength() * GfCamera::FOCAL_LENGTH_UNIT * metersPerUnit; cam->set_fov(GfDegreesToRadians(data.GetFieldOfView(GfCamera::FOVVertical))); } - cam->set_sensorwidth(data.GetHorizontalAperture() * GfCamera::APERTURE_UNIT); - cam->set_sensorheight(data.GetVerticalAperture() * GfCamera::APERTURE_UNIT); + cam->set_sensorwidth(data.GetHorizontalAperture() * GfCamera::APERTURE_UNIT * metersPerUnit); + cam->set_sensorheight(data.GetVerticalAperture() * GfCamera::APERTURE_UNIT * metersPerUnit); - cam->set_nearclip(data.GetClippingRange().GetMin()); - cam->set_farclip(data.GetClippingRange().GetMax()); + cam->set_nearclip(data.GetClippingRange().GetMin() * metersPerUnit); + cam->set_farclip(data.GetClippingRange().GetMax() * metersPerUnit); cam->set_viewplane_left(viewplane.GetMin()[0]); cam->set_viewplane_right(viewplane.GetMax()[0]); @@ -282,14 +308,15 @@ void HdCyclesCamera::ApplyCameraSettings(const GfCamera &dataUnconformedWindow, cam->set_viewplane_top(viewplane.GetMax()[1]); if (data.GetFStop() != 0.0f) { - cam->set_focaldistance(data.GetFocusDistance()); + cam->set_focaldistance(data.GetFocusDistance() * metersPerUnit); cam->set_aperturesize(focalLength / (2.0f * data.GetFStop())); } - cam->set_matrix(convert_transform(data.GetTransform()) * transform_scale(1.0f, 1.0f, -1.0f)); + cam->set_matrix(convert_camera_transform(data.GetTransform(), metersPerUnit)); } -void HdCyclesCamera::ApplyCameraSettings(const GfMatrix4d &worldToViewMatrix, +void HdCyclesCamera::ApplyCameraSettings(HdRenderParam *renderParam, + const GfMatrix4d &worldToViewMatrix, const GfMatrix4d &projectionMatrix, const std::vector<GfVec4d> &clipPlanes, Camera *cam) @@ -298,7 +325,7 @@ void HdCyclesCamera::ApplyCameraSettings(const GfMatrix4d &worldToViewMatrix, GfCamera data; data.SetFromViewAndProjectionMatrix(worldToViewMatrix, projectionMatrix); - ApplyCameraSettings(data, CameraUtilFit, cam); + ApplyCameraSettings(renderParam, data, CameraUtilFit, cam); #else TF_CODING_ERROR("Not implemented"); #endif diff --git a/intern/cycles/hydra/camera.h b/intern/cycles/hydra/camera.h index 8b7fed5a6bb..d839164317f 100644 --- a/intern/cycles/hydra/camera.h +++ b/intern/cycles/hydra/camera.h @@ -17,12 +17,14 @@ class HdCyclesCamera final : public PXR_NS::HdCamera { HdCyclesCamera(const PXR_NS::SdfPath &sprimId); ~HdCyclesCamera() override; - void ApplyCameraSettings(CCL_NS::Camera *targetCamera) const; + void ApplyCameraSettings(PXR_NS::HdRenderParam *renderParam, CCL_NS::Camera *targetCamera) const; - static void ApplyCameraSettings(const PXR_NS::GfCamera &cameraData, + static void ApplyCameraSettings(PXR_NS::HdRenderParam *renderParam, + const PXR_NS::GfCamera &cameraData, PXR_NS::CameraUtilConformWindowPolicy windowPolicy, CCL_NS::Camera *targetCamera); - static void ApplyCameraSettings(const PXR_NS::GfMatrix4d &worldToViewMatrix, + static void ApplyCameraSettings(PXR_NS::HdRenderParam *renderParam, + const PXR_NS::GfMatrix4d &worldToViewMatrix, const PXR_NS::GfMatrix4d &projectionMatrix, const std::vector<PXR_NS::GfVec4d> &clipPlanes, CCL_NS::Camera *targetCamera); diff --git a/intern/cycles/hydra/geometry.inl b/intern/cycles/hydra/geometry.inl index 007fc6f2667..3e02a59ea83 100644 --- a/intern/cycles/hydra/geometry.inl +++ b/intern/cycles/hydra/geometry.inl @@ -153,7 +153,11 @@ void HdCyclesGeometry<Base, CyclesBase>::Sync(HdSceneDelegate *sceneDelegate, // Update transforms of all instances for (size_t i = 0; i < transforms.size(); ++i) { - const Transform tfm = convert_transform(_geomTransform * transforms[i]); + const float metersPerUnit = + static_cast<HdCyclesSession *>(renderParam)->GetStageMetersPerUnit(); + + const Transform tfm = transform_scale(make_float3(metersPerUnit)) * + convert_transform(_geomTransform * transforms[i]); _instances[i]->set_tfm(tfm); } } diff --git a/intern/cycles/hydra/light.cpp b/intern/cycles/hydra/light.cpp index b691da0d6a6..c0b4b3a3f38 100644 --- a/intern/cycles/hydra/light.cpp +++ b/intern/cycles/hydra/light.cpp @@ -54,11 +54,16 @@ void HdCyclesLight::Sync(HdSceneDelegate *sceneDelegate, const SdfPath &id = GetId(); if (*dirtyBits & DirtyBits::DirtyTransform) { + const float metersPerUnit = + static_cast<HdCyclesSession *>(renderParam)->GetStageMetersPerUnit(); + + const Transform tfm = transform_scale(make_float3(metersPerUnit)) * #if PXR_VERSION >= 2011 - const Transform tfm = convert_transform(sceneDelegate->GetTransform(id)); + convert_transform(sceneDelegate->GetTransform(id)); #else - const Transform tfm = convert_transform( - sceneDelegate->GetLightParamValue(id, HdTokens->transform).Get<GfMatrix4d>()); + convert_transform( + sceneDelegate->GetLightParamValue(id, HdTokens->transform) + .Get<GfMatrix4d>()); #endif _light->set_tfm(tfm); diff --git a/intern/cycles/hydra/render_delegate.cpp b/intern/cycles/hydra/render_delegate.cpp index a954c3e4d72..faefe9382e9 100644 --- a/intern/cycles/hydra/render_delegate.cpp +++ b/intern/cycles/hydra/render_delegate.cpp @@ -33,11 +33,12 @@ TF_DEFINE_PRIVATE_TOKENS(_tokens, ); TF_DEFINE_PRIVATE_TOKENS(HdCyclesRenderSettingsTokens, + (stageMetersPerUnit) ((device, "cycles:device")) ((threads, "cycles:threads")) - ((time_limit, "cycles:time_limit")) + ((timeLimit, "cycles:time_limit")) ((samples, "cycles:samples")) - ((sample_offset, "cycles:sample_offset")) + ((sampleOffset, "cycles:sample_offset")) ); // clang-format on @@ -424,7 +425,7 @@ HdRenderSettingDescriptorList HdCyclesDelegate::GetRenderSettingDescriptors() co descriptors.push_back({ "Time Limit", - HdCyclesRenderSettingsTokens->time_limit, + HdCyclesRenderSettingsTokens->timeLimit, VtValue(0.0), }); descriptors.push_back({ @@ -434,7 +435,7 @@ HdRenderSettingDescriptorList HdCyclesDelegate::GetRenderSettingDescriptors() co }); descriptors.push_back({ "Sample Offset", - HdCyclesRenderSettingsTokens->sample_offset, + HdCyclesRenderSettingsTokens->sampleOffset, VtValue(0), }); @@ -452,7 +453,11 @@ void HdCyclesDelegate::SetRenderSetting(const PXR_NS::TfToken &key, const PXR_NS Scene *const scene = _renderParam->session->scene; Session *const session = _renderParam->session; - if (key == HdCyclesRenderSettingsTokens->time_limit) { + if (key == HdCyclesRenderSettingsTokens->stageMetersPerUnit) { + _renderParam->SetStageMetersPerUnit( + VtValue::Cast<double>(value).GetWithDefault(_renderParam->GetStageMetersPerUnit())); + } + else if (key == HdCyclesRenderSettingsTokens->timeLimit) { session->set_time_limit( VtValue::Cast<double>(value).GetWithDefault(session->params.time_limit)); } @@ -462,7 +467,7 @@ void HdCyclesDelegate::SetRenderSetting(const PXR_NS::TfToken &key, const PXR_NS samples = std::min(std::max(1, samples), max_samples); session->set_samples(samples); } - else if (key == HdCyclesRenderSettingsTokens->sample_offset) { + else if (key == HdCyclesRenderSettingsTokens->sampleOffset) { session->params.sample_offset = VtValue::Cast<int>(value).GetWithDefault( session->params.sample_offset); ++_settingsVersion; @@ -484,19 +489,22 @@ VtValue HdCyclesDelegate::GetRenderSetting(const TfToken &key) const Scene *const scene = _renderParam->session->scene; Session *const session = _renderParam->session; - if (key == HdCyclesRenderSettingsTokens->device) { + if (key == HdCyclesRenderSettingsTokens->stageMetersPerUnit) { + return VtValue(_renderParam->GetStageMetersPerUnit()); + } + else if (key == HdCyclesRenderSettingsTokens->device) { return VtValue(TfToken(Device::string_from_type(session->params.device.type))); } else if (key == HdCyclesRenderSettingsTokens->threads) { return VtValue(session->params.threads); } - else if (key == HdCyclesRenderSettingsTokens->time_limit) { + else if (key == HdCyclesRenderSettingsTokens->timeLimit) { return VtValue(session->params.time_limit); } else if (key == HdCyclesRenderSettingsTokens->samples) { return VtValue(session->params.samples); } - else if (key == HdCyclesRenderSettingsTokens->sample_offset) { + else if (key == HdCyclesRenderSettingsTokens->sampleOffset) { return VtValue(session->params.sample_offset); } else { diff --git a/intern/cycles/hydra/render_pass.cpp b/intern/cycles/hydra/render_pass.cpp index 9d47dfc5c8d..8f6f934b898 100644 --- a/intern/cycles/hydra/render_pass.cpp +++ b/intern/cycles/hydra/render_pass.cpp @@ -117,10 +117,11 @@ void HdCyclesRenderPass::_Execute(const HdRenderPassStateSharedPtr &renderPassSt #endif if (const auto camera = static_cast<const HdCyclesCamera *>(renderPassState->GetCamera())) { - camera->ApplyCameraSettings(scene->camera); + camera->ApplyCameraSettings(_renderParam, scene->camera); } else { - HdCyclesCamera::ApplyCameraSettings(renderPassState->GetWorldToViewMatrix(), + HdCyclesCamera::ApplyCameraSettings(_renderParam, + renderPassState->GetWorldToViewMatrix(), renderPassState->GetProjectionMatrix(), renderPassState->GetClipPlanes(), scene->camera); diff --git a/intern/cycles/hydra/session.h b/intern/cycles/hydra/session.h index 7e649c1847a..8d5553bf6d7 100644 --- a/intern/cycles/hydra/session.h +++ b/intern/cycles/hydra/session.h @@ -29,6 +29,16 @@ class HdCyclesSession final : public PXR_NS::HdRenderParam { void UpdateScene(); + double GetStageMetersPerUnit() const + { + return _stageMetersPerUnit; + } + + void SetStageMetersPerUnit(double stageMetersPerUnit) + { + _stageMetersPerUnit = stageMetersPerUnit; + } + PXR_NS::HdRenderPassAovBinding GetDisplayAovBinding() const { return _displayAovBinding; @@ -52,6 +62,7 @@ class HdCyclesSession final : public PXR_NS::HdRenderParam { private: const bool _ownCyclesSession; + double _stageMetersPerUnit = 0.01; PXR_NS::HdRenderPassAovBindingVector _aovBindings; PXR_NS::HdRenderPassAovBinding _displayAovBinding; }; |