Skip to content

Commit

Permalink
Improve AOV system (#295)
Browse files Browse the repository at this point in the history
* Add support for all AOV supported by RPR core

* Split color AOV

Color AOV might have been tonemapped, denoised, and composed with alpha.
Previously there was no way to get unmodified color output from RPR while using tonemapping/denoising/opacity.

* Replace `HDRPR_DISABLE_ALPHA` env. setting with corresponding render setting to allow runtime changes
  • Loading branch information
hshakula authored Jun 11, 2020
1 parent 0aeb7d3 commit ddce62f
Show file tree
Hide file tree
Showing 14 changed files with 441 additions and 150 deletions.
1 change: 1 addition & 0 deletions pxr/imaging/plugin/hdRpr/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ pxr_plugin(hdRpr
${OptIncludeDir}

PRIVATE_CLASSES
aovDescriptor
rendererPlugin
renderDelegate
renderPass
Expand Down
146 changes: 146 additions & 0 deletions pxr/imaging/plugin/hdRpr/aovDescriptor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/************************************************************************
Copyright 2020 Advanced Micro Devices, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
************************************************************************/

#include "aovDescriptor.h"

#include "pxr/base/tf/instantiateSingleton.h"

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

PXR_NAMESPACE_OPEN_SCOPE

const HdRprAovDescriptor kInvalidDesc;

TF_INSTANTIATE_SINGLETON(HdRprAovRegistry);
TF_DEFINE_PUBLIC_TOKENS(HdRprAovTokens, HDRPR_AOV_TOKENS);

HdRprAovRegistry::HdRprAovRegistry() {
const auto rprAovMax = RPR_AOV_COLOR_RIGHT + 1;
const GfVec4f idClearValue(255.0f, 255.0f, 255.0f, 0.0f);

m_aovDescriptors.resize(rprAovMax);
m_aovDescriptors[RPR_AOV_COLOR] = HdRprAovDescriptor(RPR_AOV_COLOR);
m_aovDescriptors[RPR_AOV_DIFFUSE_ALBEDO] = HdRprAovDescriptor(RPR_AOV_DIFFUSE_ALBEDO); // XXX: RPR's albedo can be noisy in some cases, so we left it as multisampled
m_aovDescriptors[RPR_AOV_VARIANCE] = HdRprAovDescriptor(RPR_AOV_VARIANCE);
m_aovDescriptors[RPR_AOV_OPACITY] = HdRprAovDescriptor(RPR_AOV_OPACITY);
m_aovDescriptors[RPR_AOV_EMISSION] = HdRprAovDescriptor(RPR_AOV_EMISSION);
m_aovDescriptors[RPR_AOV_DIRECT_ILLUMINATION] = HdRprAovDescriptor(RPR_AOV_DIRECT_ILLUMINATION);
m_aovDescriptors[RPR_AOV_INDIRECT_ILLUMINATION] = HdRprAovDescriptor(RPR_AOV_INDIRECT_ILLUMINATION);
m_aovDescriptors[RPR_AOV_AO] = HdRprAovDescriptor(RPR_AOV_AO);
m_aovDescriptors[RPR_AOV_DIRECT_DIFFUSE] = HdRprAovDescriptor(RPR_AOV_DIRECT_DIFFUSE);
m_aovDescriptors[RPR_AOV_DIRECT_REFLECT] = HdRprAovDescriptor(RPR_AOV_DIRECT_REFLECT);
m_aovDescriptors[RPR_AOV_INDIRECT_DIFFUSE] = HdRprAovDescriptor(RPR_AOV_INDIRECT_DIFFUSE);
m_aovDescriptors[RPR_AOV_INDIRECT_REFLECT] = HdRprAovDescriptor(RPR_AOV_INDIRECT_REFLECT);
m_aovDescriptors[RPR_AOV_REFRACT] = HdRprAovDescriptor(RPR_AOV_REFRACT);
m_aovDescriptors[RPR_AOV_VOLUME] = HdRprAovDescriptor(RPR_AOV_VOLUME);
m_aovDescriptors[RPR_AOV_LIGHT_GROUP0] = HdRprAovDescriptor(RPR_AOV_LIGHT_GROUP0);
m_aovDescriptors[RPR_AOV_LIGHT_GROUP1] = HdRprAovDescriptor(RPR_AOV_LIGHT_GROUP1);
m_aovDescriptors[RPR_AOV_LIGHT_GROUP2] = HdRprAovDescriptor(RPR_AOV_LIGHT_GROUP2);
m_aovDescriptors[RPR_AOV_LIGHT_GROUP3] = HdRprAovDescriptor(RPR_AOV_LIGHT_GROUP3);
m_aovDescriptors[RPR_AOV_COLOR_RIGHT] = HdRprAovDescriptor(RPR_AOV_COLOR_RIGHT);
m_aovDescriptors[RPR_AOV_SHADOW_CATCHER] = HdRprAovDescriptor(RPR_AOV_SHADOW_CATCHER);
m_aovDescriptors[RPR_AOV_REFLECTION_CATCHER] = HdRprAovDescriptor(RPR_AOV_REFLECTION_CATCHER);

m_aovDescriptors[RPR_AOV_DEPTH] = HdRprAovDescriptor(RPR_AOV_DEPTH, false, HdFormatFloat32, GfVec4f(std::numeric_limits<float>::infinity()));
m_aovDescriptors[RPR_AOV_UV] = HdRprAovDescriptor(RPR_AOV_UV, false, HdFormatFloat32Vec3);
m_aovDescriptors[RPR_AOV_SHADING_NORMAL] = HdRprAovDescriptor(RPR_AOV_SHADING_NORMAL, false, HdFormatFloat32Vec3);
m_aovDescriptors[RPR_AOV_GEOMETRIC_NORMAL] = HdRprAovDescriptor(RPR_AOV_GEOMETRIC_NORMAL, false);
m_aovDescriptors[RPR_AOV_OBJECT_ID] = HdRprAovDescriptor(RPR_AOV_OBJECT_ID, false, HdFormatInt32, idClearValue);
m_aovDescriptors[RPR_AOV_MATERIAL_IDX] = HdRprAovDescriptor(RPR_AOV_MATERIAL_IDX, false, HdFormatInt32, idClearValue);
m_aovDescriptors[RPR_AOV_OBJECT_GROUP_ID] = HdRprAovDescriptor(RPR_AOV_OBJECT_GROUP_ID, false, HdFormatInt32, idClearValue);
m_aovDescriptors[RPR_AOV_WORLD_COORDINATE] = HdRprAovDescriptor(RPR_AOV_WORLD_COORDINATE, false);
m_aovDescriptors[RPR_AOV_BACKGROUND] = HdRprAovDescriptor(RPR_AOV_BACKGROUND, false);
m_aovDescriptors[RPR_AOV_VELOCITY] = HdRprAovDescriptor(RPR_AOV_VELOCITY, false);
m_aovDescriptors[RPR_AOV_VIEW_SHADING_NORMAL] = HdRprAovDescriptor(RPR_AOV_VIEW_SHADING_NORMAL, false);

m_computedAovDescriptors.resize(kComputedAovsCount);
m_computedAovDescriptors[kNdcDepth] = HdRprAovDescriptor(kNdcDepth, false, HdFormatFloat32, GfVec4f(std::numeric_limits<float>::infinity()), true);
m_computedAovDescriptors[kColorAlpha] = HdRprAovDescriptor(kColorAlpha);

auto addAovNameLookup = [this](TfToken const& name, HdRprAovDescriptor const& descriptor) {
auto status = m_aovNameLookup.emplace(name, AovNameLookupValue(descriptor.id, descriptor.computed));
if (!status.second) {
TF_CODING_ERROR("AOV lookup name should be unique");
}
};

addAovNameLookup(HdAovTokens->color, m_computedAovDescriptors[kColorAlpha]);
addAovNameLookup(HdAovTokens->normal, m_aovDescriptors[RPR_AOV_SHADING_NORMAL]);
addAovNameLookup(HdAovTokens->primId, m_aovDescriptors[RPR_AOV_OBJECT_ID]);
addAovNameLookup(HdAovTokens->Neye, m_aovDescriptors[RPR_AOV_VIEW_SHADING_NORMAL]);
addAovNameLookup(HdAovTokens->depth, m_computedAovDescriptors[kNdcDepth]);
addAovNameLookup(HdRprGetCameraDepthAovName(), m_aovDescriptors[RPR_AOV_DEPTH]);

addAovNameLookup(HdRprAovTokens->rawColor, m_aovDescriptors[RPR_AOV_COLOR]);
addAovNameLookup(HdRprAovTokens->albedo, m_aovDescriptors[RPR_AOV_DIFFUSE_ALBEDO]);
addAovNameLookup(HdRprAovTokens->variance, m_aovDescriptors[RPR_AOV_VARIANCE]);
addAovNameLookup(HdRprAovTokens->opacity, m_aovDescriptors[RPR_AOV_OPACITY]);
addAovNameLookup(HdRprAovTokens->emission, m_aovDescriptors[RPR_AOV_EMISSION]);
addAovNameLookup(HdRprAovTokens->directIllumination, m_aovDescriptors[RPR_AOV_DIRECT_ILLUMINATION]);
addAovNameLookup(HdRprAovTokens->indirectIllumination, m_aovDescriptors[RPR_AOV_INDIRECT_ILLUMINATION]);
addAovNameLookup(HdRprAovTokens->ao, m_aovDescriptors[RPR_AOV_AO]);
addAovNameLookup(HdRprAovTokens->directDiffuse, m_aovDescriptors[RPR_AOV_DIRECT_DIFFUSE]);
addAovNameLookup(HdRprAovTokens->directReflect, m_aovDescriptors[RPR_AOV_DIRECT_REFLECT]);
addAovNameLookup(HdRprAovTokens->indirectDiffuse, m_aovDescriptors[RPR_AOV_INDIRECT_DIFFUSE]);
addAovNameLookup(HdRprAovTokens->indirectReflect, m_aovDescriptors[RPR_AOV_INDIRECT_REFLECT]);
addAovNameLookup(HdRprAovTokens->refract, m_aovDescriptors[RPR_AOV_REFRACT]);
addAovNameLookup(HdRprAovTokens->volume, m_aovDescriptors[RPR_AOV_VOLUME]);
addAovNameLookup(HdRprAovTokens->lightGroup0, m_aovDescriptors[RPR_AOV_LIGHT_GROUP0]);
addAovNameLookup(HdRprAovTokens->lightGroup1, m_aovDescriptors[RPR_AOV_LIGHT_GROUP1]);
addAovNameLookup(HdRprAovTokens->lightGroup2, m_aovDescriptors[RPR_AOV_LIGHT_GROUP2]);
addAovNameLookup(HdRprAovTokens->lightGroup3, m_aovDescriptors[RPR_AOV_LIGHT_GROUP3]);
addAovNameLookup(HdRprAovTokens->colorRight, m_aovDescriptors[RPR_AOV_COLOR_RIGHT]);
addAovNameLookup(HdRprAovTokens->materialIdx, m_aovDescriptors[RPR_AOV_MATERIAL_IDX]);
addAovNameLookup(HdRprAovTokens->objectGroupId, m_aovDescriptors[RPR_AOV_OBJECT_GROUP_ID]);
addAovNameLookup(HdRprAovTokens->geometricNormal, m_aovDescriptors[RPR_AOV_GEOMETRIC_NORMAL]);
addAovNameLookup(HdRprAovTokens->worldCoordinate, m_aovDescriptors[RPR_AOV_WORLD_COORDINATE]);
addAovNameLookup(HdRprAovTokens->primvarsSt, m_aovDescriptors[RPR_AOV_UV]);
addAovNameLookup(HdRprAovTokens->shadowCatcher, m_aovDescriptors[RPR_AOV_SHADOW_CATCHER]);
addAovNameLookup(HdRprAovTokens->reflectionCatcher, m_aovDescriptors[RPR_AOV_REFLECTION_CATCHER]);
addAovNameLookup(HdRprAovTokens->background, m_aovDescriptors[RPR_AOV_BACKGROUND]);
addAovNameLookup(HdRprAovTokens->velocity, m_aovDescriptors[RPR_AOV_VELOCITY]);
addAovNameLookup(HdRprAovTokens->viewShadingNormal, m_aovDescriptors[RPR_AOV_VIEW_SHADING_NORMAL]);
}

HdRprAovDescriptor const& HdRprAovRegistry::GetAovDesc(TfToken const& name) {
auto it = m_aovNameLookup.find(name);
if (it == m_aovNameLookup.end()) {
return kInvalidDesc;
}

return GetAovDesc(it->second.id, it->second.isComputed);
}

HdRprAovDescriptor const& HdRprAovRegistry::GetAovDesc(uint32_t id, bool computed) {
size_t descsSize = computed ? m_computedAovDescriptors.size() : m_aovDescriptors.size();
if (id < 0 || id >= descsSize) {
TF_RUNTIME_ERROR("Invalid arguments: %#x (computed=%d)", id, int(computed));
return kInvalidDesc;
}

if (computed) {
return m_computedAovDescriptors[id];
} else {
return m_aovDescriptors[id];
}
}

TfToken const& HdRprGetCameraDepthAovName() {
#if PXR_VERSION < 2002
return HdAovTokens->linearDepth;
#else
return HdAovTokens->cameraDepth;
#endif
}

PXR_NAMESPACE_CLOSE_SCOPE
123 changes: 123 additions & 0 deletions pxr/imaging/plugin/hdRpr/aovDescriptor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/************************************************************************
Copyright 2020 Advanced Micro Devices, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
************************************************************************/

#ifndef HDRPR_AOV_DESCRIPTOR_H
#define HDRPR_AOV_DESCRIPTOR_H

#include "pxr/base/tf/singleton.h"
#include "pxr/base/tf/staticTokens.h"
#include "pxr/base/gf/vec4f.h"

#include "pxr/imaging/hd/types.h"

#include <RadeonProRender.hpp>

#include <map>

PXR_NAMESPACE_OPEN_SCOPE

#define HDRPR_AOV_TOKENS \
(rawColor) \
(albedo) \
(variance) \
(worldCoordinate) \
(opacity) \
((primvarsSt, "primvars:st")) \
(materialIdx) \
(geometricNormal) \
(objectGroupId) \
(shadowCatcher) \
(background) \
(emission) \
(velocity) \
(directIllumination) \
(indirectIllumination) \
(ao) \
(directDiffuse) \
(directReflect) \
(indirectDiffuse) \
(indirectReflect) \
(refract) \
(volume) \
(lightGroup0) \
(lightGroup1) \
(lightGroup2) \
(lightGroup3) \
(viewShadingNormal) \
(reflectionCatcher) \
(colorRight)

TF_DECLARE_PUBLIC_TOKENS(HdRprAovTokens, HDRPR_AOV_TOKENS);

const rpr::Aov kAovNone = static_cast<rpr::Aov>(-1);

enum ComputedAovs {
kNdcDepth = 0,
kColorAlpha,
kComputedAovsCount
};

struct HdRprAovDescriptor {
uint32_t id;
HdFormat format;
bool multiSampled;
bool computed;
GfVec4f clearValue;

HdRprAovDescriptor(uint32_t id = kAovNone, bool multiSampled = true, HdFormat format = HdFormatFloat32Vec4, GfVec4f clearValue = GfVec4f(0.0f), bool computed = false)
: id(id), multiSampled(multiSampled), format(format), clearValue(clearValue), computed(computed) {

}
};

class HdRprAovRegistry {
public:
static HdRprAovRegistry& GetInstance() {
return TfSingleton<HdRprAovRegistry>::GetInstance();
}

HdRprAovDescriptor const& GetAovDesc(TfToken const& name);
HdRprAovDescriptor const& GetAovDesc(uint32_t id, bool computed);

HdRprAovRegistry(HdRprAovRegistry const&) = delete;
HdRprAovRegistry& operator=(HdRprAovRegistry const&) = delete;
HdRprAovRegistry(HdRprAovRegistry&&) = delete;
HdRprAovRegistry& operator=(HdRprAovRegistry&&) = delete;

private:
HdRprAovRegistry();
~HdRprAovRegistry() = default;

friend class TfSingleton<HdRprAovRegistry>;

private:
struct AovNameLookupValue {
uint32_t id;
bool isComputed;

AovNameLookupValue(uint32_t id, bool isComputed = false)
: id(id), isComputed(isComputed) {

}
};
std::map<TfToken, AovNameLookupValue> m_aovNameLookup;

std::vector<HdRprAovDescriptor> m_aovDescriptors;
std::vector<HdRprAovDescriptor> m_computedAovDescriptors;
};

TfToken const& HdRprGetCameraDepthAovName();

PXR_NAMESPACE_CLOSE_SCOPE

#endif // HDRPR_AOV_DESCRIPTOR_H
2 changes: 2 additions & 0 deletions pxr/imaging/plugin/hdRpr/mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ void HdRprMesh::Sync(HdSceneDelegate* sceneDelegate,
m_geomSubsets = m_topology.GetGeomSubsets();
if (m_geomSubsets.empty()) {
if (auto rprMesh = rprApi->CreateMesh(m_points, m_faceVertexIndices, m_normals, m_normalIndices, m_uvs, m_uvIndices, m_faceVertexCounts, m_topology.GetOrientation())) {
rprApi->SetMeshId(rprMesh, GetPrimId());
m_rprMeshes.push_back(rprMesh);
}
} else {
Expand Down Expand Up @@ -431,6 +432,7 @@ void HdRprMesh::Sync(HdSceneDelegate* sceneDelegate,
}

if (auto rprMesh = rprApi->CreateMesh(subsetPoints, subsetIndexes, subsetNormals, subsetNormalIndices, subsetUv, subsetUvIndices, subsetVertexPerFace, m_topology.GetOrientation())) {
rprApi->SetMeshId(rprMesh, GetPrimId());
m_rprMeshes.push_back(rprMesh);
++it;
} else {
Expand Down
15 changes: 14 additions & 1 deletion pxr/imaging/plugin/hdRpr/python/generateRenderSettingFiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,19 @@ def hidewhen_not_ambient_occlusion_mode(render_setting_categories):
}
]
},
{
'name': 'Alpha',
'settings': [
{
'name': 'enableAlpha',
'ui_name': 'Enable Color Alpha',
'defaultValue': True,
'houdini': {
'hidewhen': 'renderQuality != 3'
}
}
]
},
{
'name': 'UsdNativeCamera',
'settings': [
Expand Down Expand Up @@ -474,7 +487,7 @@ class HdRprConfig {{
if (FILE* f = fopen(rprPreferencePath.c_str(), "rb")) {{
if (!fread(this, sizeof(PrefData), 1, f)) {{
TF_CODING_ERROR("Fail to read rpr preferences dat file");
TF_RUNTIME_ERROR("Fail to read rpr preferences dat file");
}}
fclose(f);
return IsValid();
Expand Down
3 changes: 0 additions & 3 deletions pxr/imaging/plugin/hdRpr/renderBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ void HdRprRenderBuffer::Finalize(HdRenderParam* renderParam) {
bool HdRprRenderBuffer::Allocate(GfVec3i const& dimensions,
HdFormat format,
bool multiSampled) {
TF_VERIFY(!IsMapped());
TF_UNUSED(multiSampled);

if (dimensions[2] != 1) {
Expand All @@ -69,8 +68,6 @@ bool HdRprRenderBuffer::Allocate(GfVec3i const& dimensions,
}

void HdRprRenderBuffer::_Deallocate() {
TF_VERIFY(!IsMapped());

m_width = 0u;
m_height = 0u;
m_format = HdFormatInvalid;
Expand Down
Loading

0 comments on commit ddce62f

Please sign in to comment.