HdMaterialNode: Linked input parameter value missing in USD 25.x

Hello there,

I’m working on some shader export refactoring for V-Ray in Solaris and have an issue I’m not quite sure how to solve.

Given the USD shader:


def Shader "dirt" {
    uniform token info:id = "vray:TexDirt"
    // ...
    float inputs:radius = 0.2
    float inputs:radius.connect = </material_dirt/berconNoise1.outputs:intensity>
    // ...
}

In USD < 25 HdMaterialNode::parameters contain the radius value, but in USD >= 25.05 (Houdini 21.x) radius value is missing…

I’ve tried using scene index:

template <typename T>
static bool getNodeParameterValueFromSceneIndex(
	const HdSceneIndexPrim &materialPrim,
	const TfToken &nodeName,
	const TfToken &paramName,
	T &outValue
) {
	if (!materialPrim.dataSource)
		return false;
	HdMaterialSchema materialSchema = HdMaterialSchema::GetFromParent(materialPrim.dataSource);
	if (!materialSchema)
		return false;
	const HdMaterialNetworkSchema networkSchema = materialSchema.GetMaterialNetwork(HdVRayTokens->vray);
	if (!networkSchema)
		return false;
	const HdMaterialNodeContainerSchema nodes = networkSchema.GetNodes();
	const HdMaterialNodeSchema nodeSchema = nodes.Get(nodeName);
	if (!nodeSchema)
		return false;

	const auto params = nodeSchema.GetParameters();
	auto paramNames = params.GetNames();
	const HdMaterialNodeParameterSchema paramSchema = params.Get(paramName);
	if (!paramSchema) {
		// Parameter value doesn't exist...
		return false;
	}

	const HdSampledDataSourceHandle valueDs = paramSchema.GetValue();
	if (!valueDs)
		return false;

	const VtValue value = valueDs->GetValue(0.0f);
	return vtGetValue(value, outValue);
}

But that doesn’t work, paramSchema is missing radius value as well.

So, the question is - how to get the radius input value?

Best regards,

Andrei

Hey Andrei,

I believe It’s intentional behaviour from the Hydra 2 / Scene Index refactor, not a bug.

When an input has a connection, USD’s GetValueProducingAttributes() traces through to the upstream output and that’s what gets stored in inputConnections, not the default parameters. The authored fallback value (0.2 in your case) just isn’t surfaced anywhere in the Scene Index representation. So your Scene Index approach fails for exactly the same reason as the old HdMaterialNode::parameters path.

edit: Removed the rest of my comment. The advice was based on a custom addition that doesn’t apply here.

Well, that’s sad, cause it’s like breaks a lot of things…

Hope that unblocks you!

Not really cause there is no way to get a stage pointer from Hydra API (not from HdRenderParam nor from HdSceneDelegate)…

Any way I could workaround this with some custom scene index?

I just realized the reason I have a stage ptr is because we modified our usd to access it for other reasons, so apologies. I should have checked out our vanilla branch (I’ll edit my last post).

Edit: ignore the following text because I mistakenly forgot we were talking about the authored fallback and not the unauthored fallback value.

are you able to access the SDR/NDR (depending on your USD version since the latter was folded into the former) independently of Hydra? Since you have the shader ID, you can look up its known parameters from there and I believe that should get you the fallback value as well. Essentially treating it as a lookup.

Hm, won’t this give me input’s schema default value?

Ah yeah sorry I mis recalled your original question (should have woken up more…the dog woke me up really early) and thought we were talking about the unauthored fallback value not the authored one

Yeah, unfortunately I don’t have a good solution to find the fallback to the connection.

I don’t know how to achieve what you want in Houdini unfortunately in that case. In our custom USD build, I had to do what I mentioned in my original response where I passed in the stage as part of the driver params to Hydra. We couldn’t find a solution without modifying USD directly to surface what we needed. We’re also stuck in a weird Hydra 1/2 hybrid state and maybe it would be easier with a custom scene index filter if we were purely Hydra 2.

Our use case was slightly different in that I needed to lookup a sibling prim but in effect it turns out the same that we both needed to traverse something outside the Hydra view of the world.

Of course you can’t modify Houdini’s usd build to do that (well not easily anyway).

I think the best bet is to either talk to SideFX to see if they can give Hydra users a stage pointer or passing through the fallbacks and they in turn could work with Pixar to standardize that mechanism. Or if Houdini is purely Hydra 2 now you might be able to do it with a scene index filter but I’m not super confident about overriding it.

Sorry for misunderstanding the question.

Unfortunatelly, modifying USD is not an option… Ok, I’ll figure out smth, tnx for your help!

If you find a good solution, please report back. I’d be curious how you achieve it.

Well, so far the only solution I see is to add some automated translation of additional values like:

def Shader "dirt" {
    float inputs:radius.connect = </material_dirt/berconNoise1.outputs:intensity>
    float inputs:radius_value = 0.2
}

This could probably cause other issue in the future, but seems to be the only way to make it work…