Purely dynamic description for shader?

Hi all!
When registering a shader plugin, the "RegisterShaderPlugin" function has a string parameter naming the resource file that should be used for the shader. The docs say this:

The name has to be unique, i.e. "Tdisplay" cannot be used for 2 different descriptions

For my rendering plugin, I am trying to dynamically create GUI representations for externally stored shaders (compiled OSL shaders), loading all shaders in a given directory. This means that the number of shaders to be created, and their descriptions, is not known at compile time but only at runtime (loaded when c4d starts). The solution I am looking at for this is to register the same shader plugin multiple times, but with different IDs. By associating the ID with a specific OSL-shader file, I can then build the correct GUI, representing the OSL shader, in the GetDDescription function of the shader. This almost works, except for the fact that as soon as I register more than one shader, I get a warning in the c4d console that the same description file is being used more than once, and the description is not loaded.

Since the entire GUI is build in GetDDescription, I would not really need the description resource file at all. Is there any way that I can register a shader without specifying a resource file? E.g., is there any way to have a purely dynamic description?

I am also looking a using the RegisterDescription() function to load the resource file once and then using LoadDescription(id) in GetDDescription to load it. So far, I have not had any luck with this approach.

Any other suggestions?

Thanks!
/Filip

A possible workaround would be to ask users to create a "dummy" description resource file for every OSL shader they want to load, but since everything else would be handled dynamically it would be a lot more elegant if I was able to use the same resource file for multiple shaders.

/Filip

Have you thought about just having one shader? And inside that one shader you then select the OSL Shader that you want it to use? And when they select it you then build the descriptions for it?

Hi @Filip,

thank you for reaching out to us. We are however a little bit confused about your question, since you already gave the answer yourself. I'll answer in bullet points to make things quicker:

  • You cannot register any NodeData base plugin type without providing a description.
  • You can however just provide the container in your description resource, let's call it BaseDescription, and then just dynamically modify that description on an instance level via NodeData::GetDDescription. To simplify this you could also use LoadDescription to load in resource definitions. This can also be done piecewise, e.g., you could for example consecutively load in a CommonDescription and then a NoiseDescription.
  • What you cannot do, is a ShaderData instance being polymorphic regarding Cinema 4D's type symbol name. So the name flag in your BaseDescription cannot be modified. Which in turn means for example, that you cannot have different type names in the attribute manager for a noise shader and gradient shader node - if you follow this BaseDescription approach.

You of course already knew all this, hence our confusion 🙂 If we missed your point, I would have to ask you to explain your goals to us again.

Cheers,
Ferdinand

Thanks for the input @kbar ! That's certainly a possibility, and I believe that is how RSL shaders were handled in the old cineman module. I'll consider this.

/Filip

Thanks for the detailed breakdown @ferdinand! Yes, I'm very familiar with how plugins are "usually" registered. Since what I'm trying to do here (registering "auto generated" plugins dynamically) is a bit unusual, I just wanted to check if there was any possible workarounds that I was missing.

Another option I am considering is to write the neccesary description files from to disk from my plugin, and then use them in registration. This would require that my plugin has write access to the directory where the files would be stored. This has to be the "/res" directory of the plugin, right? Is there anyway I could guarantee to have write access there?

/Filip

Hi @Filip,

I am still a bit confused, you talk about:

Another option I am considering, is to write the necessary description files from to disk from my plugin, and then use them in registration.

  1. So you talk about multiple descriptions, but a singular plugin, which I do not understand. No matter what you do, you can only register a plugin once and provide a singular description for it. You cannot register the same plugin with multiple descriptions.
    edit: No matter what you do, you can only register a plugin ID once and provide a singular description for it. You cannot register the same plugin ID with multiple descriptions.
  2. About the dynamically created description files - you can manually register a description via RegisterDescription, but that would not help you much, since you are then still bound to the places where Cinema expects to find resource descriptions. You also would still be bound by point 1.
  3. About the r/w access on resource file locations. This depends on the access rights Cinema 4D instance is running with, the path where a user stores your plugin, the OS any many other things. So the answer probably is: No, this cannot be guaranteed, in fact there is a good chance that you won't have write access. This is also not supported by us, so we unfortunately cannot provide support on that.

I think my problem is still that I do not fully understand what you are trying to do. If you want to have a singular plugin type that can take upon different shapes, then simply define an empty description and load in whatever resource you need in GetDDescription . You still can predefine your descriptions in multiple files and have them all handled by one plugin?

Cheers,
Ferdinand

@ferdinand said in Purely dynamic description for shader?:

  1. So you talk about multiple descriptions, but a singular plugin, which I do not understand. No matter what you do, you can only register a plugin once and provide a singular description for it. You cannot register the same plugin with multiple descriptions.

I have to disagree here. The Cinema 4D Multipasses for example are implemented in exactly this way. ( by registering multiple descriptions though)

Hi @mp5gosu,

thanks for jumping in, you said:

I have to disagree here. The Cinema 4D Multipasses for example are implemented in exactly this way. ( by registering multiple descriptions though)

Do you have an example for where a plugin id is registered multiple times in this fashion?

I would have said that VideoPostData should work in the same way as other nodes in this regard, no matter if you just pass the automatically registered description symbol, or another description symbol that has been registered separately with RegisterDescription. I might be wrong about that, but I currently cannot see how and where that should work. So it would be nice if you could share an example.

What might be the confusion here is, that you can of course register the same implementation multiple times. But these then would pop up as different plugins in Cinema 4D - which is probably not what @Filip is trying to do. At least from my current understanding.

Cheers,
Ferdinand

Sure. The reason why I know that is, I do it occassionally. 🙂
Niklas answered me that question a while ago: https://plugincafe.maxon.net/topic/9400/12588_multiple-nodedata-descriptions-solved/2

But it seems, there's a misunderstanding here. Multiple plugin IDs cannot be registered. But you can create a composite plugin with different descriptions.
I usually do that with NodeData plugins.

Best,
Robert

Hi @mp5gosu,

thank you for the link. Judging by your link, Nikklas shows there how to load in descriptions based on an ID stored in the nodes BaseContainer. Which seems mostly to be what @Filip is already doing. I would say that this is not proof of my statement

No matter what you do, you can only register a plugin (ID) once and provide a singular description for it. You cannot register the same plugin (ID) with multiple descriptions.

being wrong. I am not trying to be overly pedantic here, but I would otherwise redact my previous comment. You can modify the description of an instance, but I think that was clear by the scope of the whole thread. I think this all boils down (at least for me) to not being 100% clear on what @Filip is trying to do exactly.

And just to be clear: We are grateful for community comments, and we are of course also wrong from time to time. But I had to make sure here that my statement is actually wrong. You can of course always look at things from different angles, but I would still consider the quoted part to be mostly unambiguous and correct. I added the word ID in my statement to make clear that I was talking about a plugin registration and not the plugin implementation. Thank you for your inputs so far!

Cheers,
Ferdinand

Sure, your statement was correct. That's why I mentioned the possible misunderstanding here. That's on my side (as usual :)).
You posts are invavuable for all of us, so I'd be damned if I'm going to accuse you of being wrong. 😛

Hey @mp5gosu,

thank you for your feedback. And just to be clear: I wasn't picky about me being wrong. In fact I am usually grateful if someone points out something I did wrong as this usually prevents further complications down the road for me 😉 And my initial statement was probably a bit fuzzy, which is why I did add the word ID.

I just wanted to make the topic as clear as possible for future readers if my statement was indeed categorically wrong or not. Please do not hesitate to point out anything that might be wrong or at least ambiguous about my statements in the future. Although Maxon effectively does provide a service here, a single person cannot know everything about the Cinema 4D API, so we are very grateful about any help we can get.

Cheers,
Ferdinand

Hi all! Thanks for your input in this matter.

For now, I have solved my problem by creating the needed resource files from my own code, before I register the plugin using these newly created resource files. This will do for now, although it means I have to ensure that the "res" folder of my plugin has write permission. I will try to solve that in the installer.

"What might be the confusion here is, that you can of course register the same implementation multiple times. But these then would pop up as different plugins in Cinema 4D - which is probably not what @Filip is trying to do. At least from my current understanding."
-This is actually exactly what I am doing! I am registering the same plugin class multiple times, using a different ID. Since the behaviour of the class depends on the ID, this appears to the user to be a series of entirely different shader plugins, which is my intention. The problem was that each such plugin also needed its own unique resource files (to avoid the problem that the resource name has to be unique). But as stated above, I'm solving this by creating the resource files themselves on the fly, whenever they are needed.

I consider this problem solved for now.

Best regards
/Filip

Hi @Filip,

okay, thank you for the clarification.

Cheers,
Ferdinand