Render Tree-Gonometry

March 13th, 2008 by Stefano Jannuzzo - Viewed 18922 times -

After so many years, Xsi still does not ship any basic trigonometric functions like sine and cosine. Although they are very easy to code for a shader writer, it is, however, possible to dig them out of the existing nodes.

This is an example of how sometimes you can write a phenomenon just to downgrade a more powerful node to get what you need.

The starting point is noticing that the node that more resembles the sine and cosine look is the Wave one. By connecting it straight to the surface and setting the parameters as shown, you have something really looking like a cosine function.

Wave shader

To enlarge the wave period to match the cosine’s, we simply need to devide the input by 2*PI.

Cosine Shader

Now we can push everything into a single phenomenon, having just one input parameter (the cosine argument).
This is the connection section:

Node "sib_scalar_math_basic" = guid "{3843DA00-A1F4-11D3-AE51-00A0C96E63E1}";
Node "sib_scalars_to_vector" = guid "{6405C7C0-623C-11D3-8C0A-00A0243E3672}";
Node "mib_texture_wave" = guid "{5092B017-B473-11D1-90E1-0000F804EB21}";
Node "sib_color_to_scalar" = guid "{865EBB7A-BCFA-11D1-90E9-0000F804EB21}";

Connection "sib_scalar_math_basic::input1" = interface "x";
Connection "sib_scalar_math_basic::input2" = value 6.28318;
Connection "sib_scalar_math_basic::op" = value 3;

Connection "sib_scalars_to_vector::inputX" = "sib_scalar_math_basic";
Connection "sib_scalars_to_vector::inputY" = value 0.0;
Connection "sib_scalars_to_vector::inputZ" = value 0.0;
Connection "sib_scalars_to_vector::modeX" = value 1;
Connection "sib_scalars_to_vector::modeY" = value 2;
Connection "sib_scalars_to_vector::modeZ" = value 3;

Connection "mib_texture_wave::coord" = "sib_scalars_to_vector";
Connection "mib_texture_wave::amplitude_x" = value 1.0;
Connection "mib_texture_wave::amplitude_y" = value 0.0;
Connection "mib_texture_wave::amplitude_z" = value 0.0;
Connection "mib_texture_wave::offset" = value 0.0;

Connection "sib_color_to_scalar::input" = "mib_texture_wave";

Connection root = "sib_color_to_scalar";

Cosine shader used as displacement

Having the cosine, it is now easy to get the sine also, since

sin(x) = -cos(x+PI/2)

Just make up another phenomenon and “code” the identity:

Node "cos" = guid "{19671972-1008-0000-8410-6A45FDB990DD}";
Node "sib_scalar_math_basic" = guid "{3843DA00-A1F4-11D3-AE51-00A0C96E63E1}";
Node "sib_scalar_math_unary" = guid "{A0471300-AC2E-11D3-AE56-00A0C96E63E1}";

//add PI/2 to the input parameter
Connection "sib_scalar_math_basic::input1" = interface "x";
Connection "sib_scalar_math_basic::input2" = value 1.57079;
Connection "sib_scalar_math_basic::op" = value 0;

//send result to cos
Connection "cos::x" = "sib_scalar_math_basic";

//negate result
Connection "sib_scalar_math_unary::input" = "cos";
Connection "sib_scalar_math_unary::op" = value 1;

Connection root = "sib_scalar_math_unary";

You can download the two spdl’s from here.

Of course you can also go further, since tan = sin/cos, cot = cos/sin, etc. Getting the inverse functions, instead, is another matter.

4 Responses to “Render Tree-Gonometry”

  1. 234234 says:

    sorry for the newb question, but what where is the “point” node in xsi? Also, what are the .spdl files? how do you run them?

  2. very cool technique, thanks a lot for showing it to us. Finally I now understand what a phenomenon is and how to build one, very handy!

  3. About Phenomenon… You can also check out this other article by Stefano:

  4. To answer 234234, I believe “point” is the vector_state node set to use intersection point.