diff --git a/render_delegate/nodes/driver_main.cpp b/render_delegate/nodes/driver_main.cpp index f28e787d49..0589427f69 100644 --- a/render_delegate/nodes/driver_main.cpp +++ b/render_delegate/nodes/driver_main.cpp @@ -157,10 +157,9 @@ driver_process_bucket color.resize(pixelCount, AI_RGBA_ZERO); const auto* in = static_cast(colorData); for (auto i = decltype(pixelCount){0}; i < pixelCount; i += 1) { + color[i] = in[i]; if (ids[i] == -1) { - color[i] = AI_RGBA_ZERO; - } else { - color[i] = in[i]; + color[i].a = 0.0f; } } driverData->colorBuffer->WriteBucket( diff --git a/render_delegate/render_pass.cpp b/render_delegate/render_pass.cpp index 51c89256f2..e2b3eb1169 100644 --- a/render_delegate/render_pass.cpp +++ b/render_delegate/render_pass.cpp @@ -52,6 +52,7 @@ TF_DEFINE_PRIVATE_TOKENS(_tokens, ((aovSettingFormat, "driver:parameters:aov:format")) (sourceName) (sourceType) + (dataType) (raw) (lpe) (primvar) @@ -136,6 +137,60 @@ ArnoldAOVTypes _GetArnoldTypesFromTokenType(const TfToken& type) } } +const TfToken& _GetTokenFromRenderBufferType(const HdRenderBuffer* buffer) +{ + // Use a wide type to make sure all components are set. + if (Ai_unlikely(buffer == nullptr)) { + return _tokens->color4f; + } + const auto format = buffer->GetFormat(); + switch (format) { + case HdFormatUNorm8: + return _tokens->uint8; + case HdFormatUNorm8Vec2: + return _tokens->color2u8; + case HdFormatUNorm8Vec3: + return _tokens->color3u8; + case HdFormatUNorm8Vec4: + return _tokens->color4u8; + case HdFormatSNorm8: + return _tokens->int8; + case HdFormatSNorm8Vec2: + return _tokens->color2i8; + case HdFormatSNorm8Vec3: + return _tokens->color3i8; + case HdFormatSNorm8Vec4: + return _tokens->color4i8; + case HdFormatFloat16: + return _tokens->half; + case HdFormatFloat16Vec2: + return _tokens->half2; + case HdFormatFloat16Vec3: + return _tokens->half3; + case HdFormatFloat16Vec4: + return _tokens->half4; + case HdFormatFloat32: + return _tokens->_float; + case HdFormatFloat32Vec2: + return _tokens->float2; + case HdFormatFloat32Vec3: + // We prefer RGB aovs instead of AI_TYPE_VECTOR. + return _tokens->color3f; + case HdFormatFloat32Vec4: + return _tokens->float4; + case HdFormatInt32: + return _tokens->_int; + case HdFormatInt32Vec2: + return _tokens->int2; + case HdFormatInt32Vec3: + return _tokens->int3; + case HdFormatInt32Vec4: + return _tokens->int4; + default: + return _tokens->color4f; + } +} + } // namespace HdArnoldRenderPass::HdArnoldRenderPass( @@ -158,10 +213,11 @@ HdArnoldRenderPass::HdArnoldRenderPass( AiNodeSetStr(_mainDriver, str::name, _delegate->GetLocalNodeName(str::renderPassMainDriver)); // Even though we are not displaying the prim id buffer, we still need it to detect background pixels. - _fallbackBuffers = { - {HdAovTokens->color, {&_fallbackColor, {}}}, - {HdAovTokens->depth, {&_fallbackDepth, {}}}, - {HdAovTokens->primId, {&_fallbackPrimId, {}}}}; + // clang-format off + _fallbackBuffers = {{HdAovTokens->color, {&_fallbackColor, {}}}, + {HdAovTokens->depth, {&_fallbackDepth, {}}}, + {HdAovTokens->primId, {&_fallbackPrimId, {}}}}; + // clang-format on _fallbackOutputs = AiArrayAllocate(3, 1, AI_TYPE_STRING); // Setting up the fallback outputs when no const auto beautyString = @@ -365,27 +421,31 @@ void HdArnoldRenderPass::_Execute(const HdRenderPassStateSharedPtr& renderPassSt _GetOptionalSetting(binding.aovSettings, _tokens->sourceType, _tokens->raw); const auto sourceName = _GetOptionalSetting( binding.aovSettings, _tokens->sourceName, binding.aovName.GetString()); - if (sourceName == HdAovTokens->color) { + // When using a raw buffer, we have special behavior for color, depth and ID. Otherwise we are creating + // an aov with the same name. We can't just check for the source name; for example: using a primvar + // type and displaying a "color" or a "depth" user data is a valid use case. + const auto isRaw = sourceType == _tokens->raw; + if (isRaw && sourceName == HdAovTokens->color) { *outputs = AtString( TfStringPrintf("RGBA RGBA %s %s", filterName != nullptr ? filterName : boxName, mainDriverName) .c_str()); AiNodeSetPtr(_mainDriver, str::color_pointer, binding.renderBuffer); - } else if (sourceName == HdAovTokens->depth) { + } else if (isRaw && sourceName == HdAovTokens->depth) { *outputs = AtString(TfStringPrintf( "P VECTOR %s %s", filterName != nullptr ? filterName : closestName, mainDriverName) .c_str()); AiNodeSetPtr(_mainDriver, str::depth_pointer, binding.renderBuffer); - } else if (sourceName == HdAovTokens->primId) { + } else if (isRaw && sourceName == HdAovTokens->primId) { *outputs = AtString(TfStringPrintf( "ID UINT %s %s", filterName != nullptr ? filterName : closestName, mainDriverName) .c_str()); AiNodeSetPtr(_mainDriver, str::id_pointer, binding.renderBuffer); } else { - // Houdini specific - const auto format = - _GetOptionalSetting(binding.aovSettings, _tokens->aovSettingFormat, _tokens->color3f); + // Querying the data format from USD, with a default value of color3f. + const auto format = _GetOptionalSetting( + binding.aovSettings, _tokens->dataType, _GetTokenFromRenderBufferType(buffer.buffer)); // Creating a separate driver for each aov. buffer.driver = AiNode(_delegate->GetUniverse(), str::HdArnoldDriverAOV); const auto driverNameStr = _delegate->GetLocalNodeName( @@ -498,7 +558,7 @@ void HdArnoldRenderPass::_Execute(const HdRenderPassStateSharedPtr& renderPassSt auto* color = _fallbackColor.Map(); auto* depth = _fallbackDepth.Map(); #ifdef USD_HAS_UPDATED_COMPOSITOR - _compositor.UpdateColor(_width, _height, HdFormat::HdFormatUNorm8Vec4, color); + _compositor.UpdateColor(_width, _height, HdFormat::HdFormatFloat32Vec4, color); #else _compositor.UpdateColor(_width, _height, reinterpret_cast(color)); #endif