Community
3ds Max Shading, Lighting and Rendering
Welcome to Autodesk’s 3ds Max Forums. Share your knowledge, ask questions, and explore popular 3ds Max materials topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

OSL frame number control of OSL: 1 of N (color) index

12 REPLIES 12
SOLVED
Reply
Message 1 of 13
10DSpace
495 Views, 12 Replies

OSL frame number control of OSL: 1 of N (color) index

 

I am just starting to get my feet wet with OSL and need some help.   I would like to control the index value on the OSL: 1 of N (color) node by scene frame number according to the following logic:

 

if frame number is  < 100                      then index = 0

if frame number is  ≥ 100 and < 200    then index = 1 

if frame number is  ≥ 200 and < 300    then index = 2

 

I have connected the OSL: Frame Number node into the index input of the OSL: 1 of N (Color) node as shown below:

 

10DSpace_0-1647407113416.png

 

So I need to modify the frame number output in some way before it is fed into the Index input to be consistent with the logic I outlined above rather than a simple linear output of  frame number.  I looked for some OSL math node that might achieve this but came up empty.  Maybe I just overlooked something?  

 

I am sure there is a way using OSL language to modify either the Output of the Frame Number node or the 1 of N Color node or even write a stand-alone node to put between the 2 that does the math, but I would appreciate some help as to the best way to approach this.  

 

Thanks for any help.

12 REPLIES 12
Message 2 of 13
CiroCardoso3v
in reply to: 10DSpace

Something like this should work

 

CiroCardoso3v_0-1647433611480.png

 

Lead Enviroment Artist @Axis Studios

Arnold Discord Server


Ciro Cardoso

EESignature

Message 3 of 13
10DSpace
in reply to: CiroCardoso3v

@CiroCardoso3v 

 

Thanks for the prompt response.  That is close enough of a solution for the example I gave (since the Equality threshold is symmetrical, with Input B set to 150 and Equality threshold set to 50, the 3rd image doesn't switch in at frame 200 but at frame 201).    But I am also interested in more complicated cases that are not symmetrical and involve more than 3 images and irregular lengths of frames.  I am aware that this can be done by creating an .ifl file in notepad and feeding that into the base color slot, but I am looking for OSL alternatives and want to learn OSL anyway.  (I am also playing around with the float script controller to incorporate some more complex scenarios).

 

So with that as background and returning to OSL options, is there a way to add to the number of comparisons in a modified Compare.osl node that would take the frame number and have say 10 less than or equal to comparisons and 10 different results like:

 

if frame number is  < 37                     then Result A

if frame number is  ≥ 37 and < 60    then Result B 

if frame number is  ≥ 60 and < 90    then Result C

if frame number is  ≥ 90 and < 122   then Result D

if frame number is  ≥ 122 and <186    then Result E      ......... etc.... thru to Result 10

 

Or if not with the Compare Node, maybe adapting the the OSL: 1 of N (color) node or some other node?

 

I don't have my arms around OSL code yet, so if you could point me in the right direction I would appreciate it.  I'm trying to use this as a real world case for learning.  Thanks again for your help so far. 

Message 4 of 13
madsd
in reply to: 10DSpace

This is easy to do.

Let me write a proper case proof tomorrow and you can evaluate the code to get insight.

Message 5 of 13
madsd
in reply to: 10DSpace

2022-03-17 02-41-30.gif


Shader code for the proper If case you want to use.
You can also use ifelse in a different structure but this is simple so no need.

Notice ":" separates the 2 gates.


shader ifCase

(

int frame = 0,

output int Out = 0,

)

{

frame < 100 ? Out = 0 : Out;

frame >= 100 and frame < 200 ? Out = 1 : Out;

frame >= 200 and frame < 300 ? Out = 2 : Out;

}

 

Also hosted on my github as an educational entry.
https://github.com/gkmotu/OSL-Shaders/blob/master/ifCase.osl


Using a single line is useful for 1 gate control and single operation.

You can use a regular if function if you have multiple conditional changes, like this:


if ( a < b )
{

c = d;

e = f;

g = h;

}
else
{

c = d*d;

e = f*d;

g = h*d;

}

 

 

 

Consider flagging the post as solution if it proves useful.

Message 6 of 13
madsd
in reply to: 10DSpace

As a small training education session if you want.
- I would ask you to compile a new node that does does it for the 2 nodes Frame time and IfCase, so you just have 1.
- The final examn will involve you include that new shader into the 1 to n color node, so you end with just 1 node instead of 3.

I am here to guide, provided you get stuck.

Message 7 of 13
10DSpace
in reply to: madsd

@madsd 

 

Thanks for the code suggestions.  I will check it out and get back here on the results.  Before I had seen your message,  I managed to stumble through to a solution of my own that works for what I want (different output maps for multiple for custom frame ranges), but although the proper maps are displayed as I scroll the timeline, I notice that the current frame number is not actually displayed in the Input Ref field (it stays at 0.0) which I would have expected since the frame Number is plugged into it from the Frame Number OSL.     So the current frame number is actually being successfully used in the comparisons to achieve the result I want, but just not showing in the Ref Input.  Any thoughts on why?

 

10DSpace_1-1647483140012.png

 

 Thanks for your help and I will study your code and the video on the link to see what I else I might learn from it. 

Message 8 of 13
madsd
in reply to: 10DSpace

In order to see the frame number in the 1 to n Color node, you would need to complete the final examn test I set up in the previous post.

So you need to include the "meat" from the frame shader into the final node.
And that would be the integer with its associated meta data part.
Everything between
[[  stuff ]]
Is considered meta data, and this pulls in the hidden controllers that drives the frame number automatically.

After that you route it to the "if" conditions, and forward that to the 1 to n Color Index value.

This has to be done in the body of the shader.

shader test

( header / UI )
{ body}

Message 9 of 13
CiroCardoso3v
in reply to: 10DSpace

@10DSpace, Mads is your guy.

Lead Enviroment Artist @Axis Studios

Arnold Discord Server


Ciro Cardoso

EESignature

Message 10 of 13
10DSpace
in reply to: CiroCardoso3v

@CiroCardoso3v 

 

Yeah, I'm working on my final exam now. 🙂  Almost there, I think.

Message 11 of 13
10DSpace
in reply to: madsd

@madsd 

 

OK, Professor Mads I have completed my final exam (at least to my satisfaction) thanks to your guidance and some head banging on my part.  I have combined the OSL Frame number node with the modification of the OSL Compare Node that I had previously posted and now the current frame number is reported out as it should in the Current Frame field.  I changed the UI a bit and type declarations (float to int for frame data ).  Everything works as I want it to in a single new node I called Frame_Ranges_To_Outs.osl .   I have attached the OSL if anyone wants to mess around with it. 

 

10DSpace_0-1647538316921.png

 

Concerning use of the C++ " ? " ternary operator in place of "if else",  I prefer using if else, because in my opinion it makes the code more readable.  There may be some elegance to "?" in some circumstances, but I choose clarity over elegance most of the time.    

 

In playing with the UI options available via [[ Metadata stuff]] , I think a nice addition would be able to add more UI elements like groups, separators, and labels to these (like you can with rollouts in Maxscript) to be able to more clearly separate out the inputs section and the output section when viewed in the SME Parameter Editor for OSL Nodes.     Maybe there is a way to do that now, but I couldn't find it in the docs.     The other thing that could be improved is error checking/reporting to the user with a messageBox in certain cases.  Probably not the best example, but nothing happens with this shader if the user doesn't enter any frame inputs in the input fields (the comparisons default to Else = Out = OutH ).  Sure, that should be obvious based on the string labels and string help provided and if you open the OSL code, but reminders to user can save some frustration in my experience. Maybe there is a way to do this and I missed it.  

 

Thanks very much for your (and @CiroCardoso3v ) help.

Message 12 of 13
madsd
in reply to: 10DSpace

You can open a new thread asking for custom UI and I can show instructions to use QT Designer.

If you see my Flowmap thread image you can see I use a custom UI design, fabricated in qt.

You can also go to my github and download the OSL Triplanar map for example, it has some more complex dynamic UI based on switches and dummy triggers. remember that a qt .ui file always needs to be next to the .osl file and have the exact same name.

You need to promote double spinners to the SDK:: versions, right clicking them, and you have to call the widgets the exact same in qt as in OSL, then the feature pairs up and starts working.

 

Message 13 of 13
10DSpace
in reply to: madsd

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Technology Administrators


Autodesk Design & Make Report