Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add storm support for camera exposure controls #3464

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions pxr/imaging/hdx/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ pxr_library(hdx
colorCorrectionTask
drawTargetTask
effectsShader
exposureScaleTask
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The makefile/package/taskController updates all seem to be "exposureScale", but "linearExposureScale" is included as well. Note that camera ended up with "GetLinearExposureScale" but not "ExposureScale", so possibly we need to nix all of the plain old "exposureScale" stuff.

I couldn't find the pow(2, exposureScale) anywhere in exposureScaleTask, but if we're going with linearExposureScale that doesn't matter.

freeCameraSceneDelegate
freeCameraPrimDataSource
fullscreenShader
Expand Down Expand Up @@ -87,6 +88,7 @@ pxr_library(hdx
shaders/boundingBox.glslfx
shaders/colorChannel.glslfx
shaders/colorCorrection.glslfx
shaders/exposureScale.glslfx
shaders/fullscreen.glslfx
shaders/oitResolveImageShader.glslfx
shaders/outline.glslfx
Expand Down
174 changes: 174 additions & 0 deletions pxr/imaging/hdx/exposureScaleTask.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
//
// Copyright 2024 Pixar
//
// Licensed under the terms set forth in the LICENSE.txt file available at
// https://openusd.org/license.
//
#include "pxr/imaging/hdx/exposureScaleTask.h"
#include "pxr/imaging/hdx/fullscreenShader.h"
#include "pxr/imaging/hdx/package.h"

#include "pxr/imaging/hd/camera.h"
#include "pxr/imaging/hd/perfLog.h"
#include "pxr/imaging/hd/tokens.h"

#include "pxr/imaging/hf/perfLog.h"
#include "pxr/imaging/hio/glslfx.h"

#include "pxr/imaging/hgi/blitCmds.h"
#include "pxr/imaging/hgi/blitCmdsOps.h"
#include "pxr/imaging/hgi/hgi.h"
#include "pxr/imaging/hgi/tokens.h"

PXR_NAMESPACE_OPEN_SCOPE

TF_DEFINE_PRIVATE_TOKENS(
_tokens,
((exposureScaleFrag, "ExposureScaleFragment"))
);

HdxExposureScaleTask::HdxExposureScaleTask(
HdSceneDelegate* delegate,
SdfPath const& id)
: HdxTask(id)
{
}

HdxExposureScaleTask::~HdxExposureScaleTask() = default;

void
HdxExposureScaleTask::_Sync(HdSceneDelegate* delegate,
HdTaskContext* ctx,
HdDirtyBits* dirtyBits)
{
HD_TRACE_FUNCTION();
HF_MALLOC_TAG_FUNCTION();

if (!_compositor) {
_compositor = std::make_unique<HdxFullscreenShader>(
_GetHgi(), "ExposureScale");
}

if ((*dirtyBits) & HdChangeTracker::DirtyParams) {
HdxExposureScaleTaskParams params;

if (_GetTaskParams(delegate, &params)) {
_cameraPath = params.cameraPath;
}
}

// Currently, we're querying GetExposureScale() every frame - not
// sure if there's a better way to detect if this is dirty?
if (_cameraPath.IsEmpty()) {
_exposureScale = 1.0f;
} else {
HdRenderIndex &renderIndex = delegate->GetRenderIndex();
const HdCamera *camera = static_cast<const HdCamera *>(
renderIndex.GetSprim(HdPrimTypeTokens->camera, _cameraPath));
if (!TF_VERIFY(camera)) {
return;
}

_exposureScale = camera->GetExposureScale();
}

*dirtyBits = HdChangeTracker::Clean;
}

void
HdxExposureScaleTask::Prepare(HdTaskContext* ctx,
HdRenderIndex* renderIndex)
{
}

void
HdxExposureScaleTask::Execute(HdTaskContext* ctx)
{
HD_TRACE_FUNCTION();
HF_MALLOC_TAG_FUNCTION();

HgiTextureHandle aovTexture;
_GetTaskContextData(ctx, HdAovTokens->color, &aovTexture);

HgiShaderFunctionDesc fragDesc;
fragDesc.debugName = _tokens->exposureScaleFrag.GetString();
fragDesc.shaderStage = HgiShaderStageFragment;
HgiShaderFunctionAddStageInput(
&fragDesc, "uvOut", "vec2");
HgiShaderFunctionAddTexture(
&fragDesc, "colorIn");
HgiShaderFunctionAddStageOutput(
&fragDesc, "hd_FragColor", "vec4", "color");

// The order of the constant parameters has to match the order in the
// _ParameterBuffer struct
HgiShaderFunctionAddConstantParam(
&fragDesc, "screenSize", "vec2");
HgiShaderFunctionAddConstantParam(
&fragDesc, "exposureScale", "float");

_compositor->SetProgram(
HdxPackageExposureScaleShader(),
_tokens->exposureScaleFrag,
fragDesc);
const auto &aovDesc = aovTexture->GetDescriptor();
if (_UpdateParameterBuffer(
static_cast<float>(aovDesc.dimensions[0]),
static_cast<float>(aovDesc.dimensions[1]))) {
size_t byteSize = sizeof(_ParameterBuffer);
_compositor->SetShaderConstants(byteSize, &_parameterData);
}

_compositor->BindTextures({aovTexture});

_compositor->Draw(aovTexture, /*no depth*/HgiTextureHandle());
}

bool
HdxExposureScaleTask::_UpdateParameterBuffer(
float screenSizeX, float screenSizeY)
{
_ParameterBuffer pb;

pb.exposureScale = _exposureScale;
pb.screenSize[0] = screenSizeX;
pb.screenSize[1] = screenSizeY;

// All data is still the same, no need to update the storage buffer
if (pb == _parameterData) {
return false;
}

_parameterData = pb;

return true;
}


// -------------------------------------------------------------------------- //
// VtValue Requirements
// -------------------------------------------------------------------------- //

std::ostream& operator<<(
std::ostream& out,
const HdxExposureScaleTaskParams& pv)
{
out << "ExposureScaleTask Params: (...) "
<< pv.cameraPath << " "
;
return out;
}

bool operator==(const HdxExposureScaleTaskParams& lhs,
const HdxExposureScaleTaskParams& rhs)
{
return lhs.cameraPath == rhs.cameraPath;
}

bool operator!=(const HdxExposureScaleTaskParams& lhs,
const HdxExposureScaleTaskParams& rhs)
{
return !(lhs == rhs);
}

PXR_NAMESPACE_CLOSE_SCOPE
102 changes: 102 additions & 0 deletions pxr/imaging/hdx/exposureScaleTask.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
//
// Copyright 2024 Pixar
//
// Licensed under the terms set forth in the LICENSE.txt file available at
// https://openusd.org/license.
//
#ifndef HDX_EXPOSURESCALE_TASK_H
#define HDX_EXPOSURESCALE_TASK_H

#include "pxr/pxr.h"
#include "pxr/usd/sdf/path.h"
#include "pxr/imaging/hdx/api.h"
#include "pxr/imaging/hdx/task.h"
#include "pxr/imaging/hdx/tokens.h"
#include "pxr/imaging/hgi/graphicsCmds.h"

PXR_NAMESPACE_OPEN_SCOPE

/// \class HdxExposureScaleTask
///
/// A task for applying an exposure scale for display.
///
class HdxExposureScaleTask : public HdxTask
{
public:
HDX_API
HdxExposureScaleTask(HdSceneDelegate* delegate, SdfPath const& id);

HDX_API
~HdxExposureScaleTask() override;

/// Prepare the tasks resources
HDX_API
void Prepare(HdTaskContext* ctx,
HdRenderIndex* renderIndex) override;

/// Execute the exposure scale task
HDX_API
void Execute(HdTaskContext* ctx) override;

protected:
/// Sync the render pass resources
HDX_API
void _Sync(HdSceneDelegate* delegate,
HdTaskContext* ctx,
HdDirtyBits* dirtyBits) override;

private:
HdxExposureScaleTask() = delete;
HdxExposureScaleTask(const HdxExposureScaleTask &) = delete;
HdxExposureScaleTask &operator =(const HdxExposureScaleTask &) = delete;

// Utility function to update the shader uniform parameters.
// Returns true if the values were updated. False if unchanged.
bool _UpdateParameterBuffer(float screenSizeX, float screenSizeY);

// This struct must match ParameterBuffer in exposureScale.glslfx.
// Be careful to remember the std430 rules.
struct _ParameterBuffer
{
float screenSize[2];
float exposureScale;
bool operator==(const _ParameterBuffer& other) const {
return exposureScale == other.exposureScale &&
screenSize[0] == other.screenSize[0] &&
screenSize[1] == other.screenSize[1];
}
};

std::unique_ptr<class HdxFullscreenShader> _compositor;
_ParameterBuffer _parameterData;

SdfPath _cameraPath;

// The multiplier to be applied to the displayed pixels
float _exposureScale = 1.0f;
};


/// \class HdxExposureScaleTaskParams
///
/// ExposureScaleTask parameters.
///
struct HdxExposureScaleTaskParams
{
SdfPath cameraPath;
};

// VtValue requirements
HDX_API
std::ostream& operator<<(std::ostream& out, const HdxExposureScaleTaskParams& pv);
HDX_API
bool operator==(const HdxExposureScaleTaskParams& lhs,
const HdxExposureScaleTaskParams& rhs);
HDX_API
bool operator!=(const HdxExposureScaleTaskParams& lhs,
const HdxExposureScaleTaskParams& rhs);


PXR_NAMESPACE_CLOSE_SCOPE

#endif
Loading
Loading