Skip to content

Commit

Permalink
[hdx] add HdxExposureScaleTask
Browse files Browse the repository at this point in the history
  • Loading branch information
pmolodo committed Dec 11, 2024
1 parent 3e3e940 commit adb7ebb
Show file tree
Hide file tree
Showing 9 changed files with 370 additions and 0 deletions.
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
freeCameraSceneDelegate
fullscreenShader
hgiConversions
Expand Down Expand Up @@ -86,6 +87,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
7 changes: 7 additions & 0 deletions pxr/imaging/hdx/package.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,13 @@ HdxPackageRenderPassShadowShader()
return shader;
}

TfToken
HdxPackageExposureScaleShader()
{
static TfToken shader = _GetShaderPath("exposureScale.glslfx");
return shader;
}

TfToken
HdxPackageColorChannelShader()
{
Expand Down
1 change: 1 addition & 0 deletions pxr/imaging/hdx/package.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ TfToken HdxPackageRenderPassColorWithOccludedSelectionShader();
TfToken HdxPackageRenderPassIdShader();
TfToken HdxPackageRenderPassPickingShader();
TfToken HdxPackageRenderPassShadowShader();
TfToken HdxPackageExposureScaleShader();
TfToken HdxPackageColorChannelShader();
TfToken HdxPackageColorCorrectionShader();
TfToken HdxPackageVisualizeAovShader();
Expand Down
34 changes: 34 additions & 0 deletions pxr/imaging/hdx/shaders/exposureScale.glslfx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
-- glslfx version 0.1

//
// Copyright 2024 Pixar
//
// Licensed under the terms set forth in the LICENSE.txt file available at
// https://openusd.org/license.
//

-- configuration
{
"techniques": {
"default": {
"ExposureScaleFragment": {
"source": [ "ExposureScale.Fragment" ]
}
}
}
}


-- glsl ExposureScale.Fragment


void main(void)
{
vec2 fragCoord = uvOut * screenSize;
vec4 color = HgiTexelFetch_colorIn(ivec2(fragCoord));

// Only color, not alpha is exposure scaled!
color.rgb *= exposureScale;

hd_FragColor = color;
}
Loading

0 comments on commit adb7ebb

Please sign in to comment.