DS 4.6 Shader Builder: Function to get the current frame number
JonnyRay
Posts: 1,744
I'm trying to write a function to get the current frame number of an animation sequence so that I can vary a surface shader based on that information. According to the 3Delight Documentation, the information should be available, but I'm not getting the results I'm expecting. My code is currently:
float jrFrameNumber()
{
float Result = 0.0;
float oR = option("Ri:FrameBegin",Result);
return Result;
}
Am I missing something in my RSL code? It seems to always be returning zero.
Comments
I don't know if this means anything or not, but I just did a render to RIB for my test scene (a simple sphere over a plane) and I noticed that the generated RIB doesn't have a BeginFrame tag in it. It has the BeginWorld, BeginTransform, BeginAttribute, etc. But not the BeginFrame. Without that, the rendering engine wouldn't have a value to return when I call for the Ri:FrameBegin option.
Get the current frame number from the Scene (DzScene) global:
Use this in a RenderTime Script to feed it to whatever option/parameter you intend to use it with.
-Rob
Thanks for the tip Rob! :)
I'm having a hard time figuring out how to get the output defined in the RendertimeScript, though. I created an Output Attribute, but it doesn't show in the script block, and I can't bind the script node to the input to the mod function where I need it.
Maybe I misunderstood? Maybe the RenderTime Script should set the value and there should be a function block to read it / feed it into the shader code?
I tried this, without any luck.
var nFrame = Scene.getFrame();
Shader.setFloatToken( “__foo_bar”, nFrame );
Shader.setFloatAttrib( “foo”, “float bar”, nFrame );
The shaderbuilder parameter __foo_bar is still zero.
Animating a shader oiver time is a very important feature for a rendertool.
I also tried changing my function as follows...
No dice there either.
Some work I was doing to try to clean up my Renderman Shaders conversion exercise gives me some ideas on this. I'll try them again tonight or over the weekend.
I finally got this to work! A short video where the opacity is modified based on the frame number...
Animated Opacity
Relevant code that I used...
A macro called jrFrameNumber
Global Code
Initialization Code
Evaluation Code
Then I have a RenderTime Script defined and connected to the shader output block that looks like this...
Note that I also defined an output parameter for the script that looks like this...
- Parameter Attributes
-- Float
-- Attribute (out)
- Shader Attributes
-- Name: user
-- Token: float FrameNumber
-- Default: undefined
So I had this cool idea about how to use this new information for a cool effect in a displacement shader. But first I needed to understand the mathematics to define ripples in a pond. Apparently there is no simple way to describe this phenomenon. :( Every reference material I have found so far seems to start with the assumption that I'm already conversant in fluid dynamics. :long:
How exact are you wanting to be? It should be possible to take the ST values and apply some trig to get a series of circles, then use frame number as an offset to make them move. (That is, use something like
displacement value = sin( ( (S + Soffset) ^ 2 + ( T + Toffset) ^ 2 + scalar1 * frame ) / scalar2 )
with Soffset and Toffset used to move the centre of the circles from (0,0) and the scalars used to keep everything in range)
Yeah, I was thinking I could fake it with a sine wave and just scale the amplitude myself based on the distance from the center of the effect. I was just hoping to find something pre-made. But it seems most mathematical models of ripples want to talk about angular velocities and are more concerned with the velocity of the wave than the amplitude.
well, using a sin wave isn't "faking" it, it's how they work. Semi-odd that water knows advanced mathematics, but I suppose it doesn't have to understand to obey. ;)
The Laws of Physics, or in this case, Fluid Dynamics, are 99.9% understood, so you might as well go with that. That pesky, missing percent point will (probably never) be resolved, but that's just for the picky. The caveat being, "we know at least half of what we know is wrong, we just don't know which half."
So fake it in. Using Sin waves. That's the way water does it. If that still seems like cheating, use cosine waves instead. Either way, it will be/look realistic, because in the last 4.5+ billion years, water has already tried all the others, and they just weren't as good. When water starts thinking "That's not the look I was going for!", you kind of have to step back and defer to it's judgement.
There is no simple answer. Fluid Dynamics: in physics it's a minimum 1 term course, but usually three years; in Engineering I presume min 3, and probably way more if you want to build bridges; Even Medical Doctor's have to take a couple - Blood flow is a liquid.
You can actually get a full degree, and masters and then doctorate, in, wait for it, Fluid Dynamics...
There is no "simple" answer. ;) Oh wait, except for distance-scaled, Amplitude modulated, Sin waves... Them work awesome! ;)
Of course, that is going to look/be a little to smooth and uniform, so you also need some "Noise"... make ripples and deviations and such. Normally wind provides that, but likely your 3D world doesn't have that. So fake THAT part! Use/add Noise - Perlin, Gausian, (gasp) random, or whatever.
So... like Fluid Dynamics and the simplicity if it all? check this out:
http://physbam.stanford.edu/
You can even download their code. Simple! hehe... read, learn and implement that, and then in the end you'll probably/maybe say "Nah! I think I'll fake it in with a Sin wave..." lol