Arnold AOV shader override/assignment per object

45 views
Skip to first unread message

Matthias Bjarnason

unread,
Oct 14, 2025, 12:44:16 PM (8 days ago) Oct 14
to gaffer-dev
Hey all,

I'm trying to create AOV shader assignments (aiAOVWriteRGB etc.) per object in Gaffer, with no luck and would like to hear if anyone has come up with a nice solution for this.

The problem I'm facing is that the aiAOVWrite nodes require a "passthrough" shader to work else, unconnected, it overrides the upstream shader assignment (beauty).
Which works as expected, BUT in our case, we load shaders/materials into our scenes as published "shader/look" box assets that are locked (i.e. no option to promote attributes to the published box after the fact. box can also contain multiple shaders). ...and therefore it's a non-option to "fetch" the shader(output) from upstream unless the box is "broken up".

The ShaderTweakProxy node seems like the perfect node to "fetch" the assigned material, of a given object, to do exactly this ...but unfortunately that node is not compatible with the ShaderAssignments node, necessary to connect the aiAOVWrite.

Are there any other neat ways of doing this in Gaffer or am I missing something super obvious - is there a "shader output lookup/fetch" nodes somewhere I'm missing?

...just to add... yes, each Arnold standard shader does have its "built-in" AOV plugs, for custom assignments, but those we're also trying avoid changing, as they are shader focused NOT object focused. Besides, in a hypothetical scenario, if one wants to create 30 utility AOVs the shader only allows for max 8. While daisy-chaining aiAOVWrite notes is pretty much limitless.

...and yes, Crypto (object) is the almighty savior in scenarios such as this except it doesn't help if one needs to plug in say an RGB texture to use as AOV utility.

Any help greatly appreciated.

Best,
- M


John Haddon

unread,
Oct 15, 2025, 4:33:14 AM (8 days ago) Oct 15
to gaffe...@googlegroups.com
Hi Matthias,

It would be a nice feature to be able to use ShaderTweaks/ShaderTweaksProxy to insert a new terminal shader, but that's not currently possible - feel free to open an issue for it if you would like.

But depending on exactly what you want your AOV to look like, I think there may be a better solution anyway. Arnold supports the idea of global AOV shaders that are active for all objects, independent of what shaders are assigned to them. And those global shaders can use shaders like `user_data_rgb` to grab per-object values. You can assign such per-object values using a CustomAttributes node in Gaffer, and because they inherit through the hierarchy they are really flexible - you can assign a default value at the root, and overrides on specific geometry lower down. And this is much cheaper than shader tweaks because it's just a tiny bit of data per object, instead of a whole new shader network.

I've attached an example that I hope illustrates this. I used a Spreadsheet with the CustomAttributes node as a convenient way of defining values for different locations, but you can define it however you want. I used a flat color value for simplicity, but I assume you could make a string and read that with `user_data_string` to feed a texture lookup.

Hope that helps,
Cheers...
John



--
You received this message because you are subscribed to the Google Groups "gaffer-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gaffer-dev+...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/gaffer-dev/6f7e5fbd-2b93-423a-ba7a-d4d8de86a568n%40googlegroups.com.
arnoldGlobalAOVShader.gfr

Matthias Bjarnason

unread,
Oct 15, 2025, 3:16:57 PM (7 days ago) Oct 15
to gaffer-dev
Hey John,

Thanks for the help and the example - really appreciate it.
Yes, this method, you suggest is quite good and I am completely onboard with flexible and cheap - It basically solves everything I was chasing in terms of applying single colors(IDs) to a defined object(s) which is fantastic.

However ... trying to pipe through a custom attribute string / texture path using this method (as you mentioned as well)  ...I just can't seem to get that to work. I do not get the user_data_string node to pass the attribute/path through into an aiimage node - Arnold doesn't even want to render (no errors, no nothing ... just halts immediately) ...thought this was so straight forward but I'm definitely missing something. :p
And on that note, I do not immediately see how one can utilize this method if one wants to connect a utility shader, not just a flat color value e.g. say you only want Gaffer Bot's boots to have an ambient occlusion shader applied in a custom AOV. ...which would be the ultimate control scenario here.
Just now, I tried even connecting a shader's output straight to a CustomAttribute nodes's value plugs (instead of just selecting a flat rgb color value) - long shot, I know ...just had to try it while writing this up :) -  AOV is blank although Beauty renders fine.

Now, unfortunately I am unable to upload an example scene (based on yours) to illustrate my (highly likely to be incorrect) mistakes/typos so could I please ask you to make a basic example of this in your demo script ...that is, if there even is a simple solution for this?

Thanks again for all the trouble.

Best,

Daniel Dresser

unread,
Oct 15, 2025, 8:10:52 PM (7 days ago) Oct 15
to gaffer-dev
> trying to pipe through a custom attribute string / texture path using this method (as you mentioned as well)  ...I just can't seem to get that to work. I do not get the user_data_string node to pass the attribute/path through into an aiimage node

This should definitely work. The major gotcha with this is often the attribute naming convention. In order to get the Gaffer Arnold backend to output the attributes as user data ( rather than trying to map them to specific render controls ), you need to prefix your attribute name with "user:" ( and then use the full name including the "user:" prefix in user_data_string ).

> And on that note, I do not immediately see how one can utilize this method if one wants to connect a utility shader, not just a flat color value

This approach can't be used if you need to assign a different shader to different objects in the scene ( that would require the new feature for ShaderTweaks that John mentioned doesn't exist yet ). But if number of different permutations you need is small, you might be able to achieve it with a SwitchRgba connected to an AovWriteRgb connected to ArnoldAOVShader ( you'd use an attribute to control the switch to control which objects get ambient occlusion ).

-Daniel

Matthias Bjarnason

unread,
Oct 16, 2025, 6:07:07 AM (6 days ago) Oct 16
to gaffer-dev
Hey Daniel,

This SwitchRgba "workaround" works great - thank you. I can assign various utility shaders this way and switch between/assign the objects using a spreadsheet - great!

Passing the string attribute through a user_data_string node into an aiimage node, however, still does not work for me (to switch between texture file paths) - I believe I'm doing that exactly as you describe above but there might be some other "gotcha" apart from exposing the correct attribute name (it shows up correctly in the Scene Inspector down stream ...so probably correct) - Arnold just won't have it.
Would be great if you could try this on your end and see if you get it to work.

All that said, seeing that the SwitchRgba trick works fine to assign utility shaders (with textures) to defined objects, trying to pass the path/string through an attribute some other way might not be necessary at all. ... just a bit frustrating to not get that method working to cover all options. :p

Thanks again guys!
Best,

John Haddon

unread,
Oct 16, 2025, 6:46:30 AM (6 days ago) Oct 16
to gaffe...@googlegroups.com
On Wed, Oct 15, 2025 at 8:17 PM Matthias Bjarnason <matthias....@rvx.is> wrote:
However ... trying to pipe through a custom attribute string / texture path using this method (as you mentioned as well)  ...I just can't seem to get that to work. I do not get the user_data_string node to pass the attribute/path through into an aiimage node - Arnold doesn't even want to render (no errors, no nothing ... just halts immediately) ...thought this was so straight forward but I'm definitely missing something.

By default Arnold will abort the render if it fails to find a texture, so my guess is you were hitting something like that. I've attached an updated example which shows textures working, with a gaffer logo plastered on the torso, but nothing on the other objects.
Cheers...
John 
arnoldGlobalAOVShader.gfr

Matthias Bjarnason

unread,
Oct 16, 2025, 10:06:47 AM (6 days ago) Oct 16
to gaffer-dev
Hey John,

Thanks again for the example file. Your example works perfectly!! ...and it's, from what I can tell, EXACTLY same as the one I made. But for some funky reason this doesn't work in my script at all. I even copied your CustomAttribute node (and spreadsheet) into my script to see what happens, renamed my AOV (to match yours) ...and nothing, nada - dead. :p

At least your scene proves that this is possible ...so, I think, I'll have to start this again in a new script and see if something just broke under my script's hood at some point.

I'll report back if I figure out what in the h**l is going on. Until then , thanks for all the help guys, super appreciate it.

Best,

Matthias Bjarnason

unread,
Oct 16, 2025, 11:09:40 AM (6 days ago) Oct 16
to gaffer-dev
Alrightythen! Soooooo, it was the darn "ignore missing textures" (within the aiimage node), which isn't checked by default (obviously), AND I assumed wouldn't be an issue since the texture file path was being provided by the attribute the whole time. sssnarf!

Thanks again guys.
Reply all
Reply to author
Forward
0 new messages