Friday 13 September 2013

Putting all together to generate a procedural tile pattern

Taking all that we have learned from mod( ), odd( ), even( ), whichTile( ) and so on, we can try building a procedural pattern such as this:


















The codes for generating this tile pattern is:

#include "D:\SweeKim\rsl\src\include\zin\zinMacro.h"

surface zinTest()
{
float pulseU, pulseV;
color ColA = (0,0,1), ColB = (0,1,0);
float pulseFreq = 5;

float uu = zinRepeat(u,pulseFreq);
float vv = zinRepeat(v,pulseFreq);

float col = zinWhichTile(u,pulseFreq);
float row = zinWhichTile(v,pulseFreq);

pulseU = (step(0.4,uu) - step(0.6,uu));
pulseV = (step(0.4,vv) - step(0.6,vv));

if(zinOdd(row))
{
if(zinEven(col))
{
ColA = (0.6,0.2,0.7); //purple
ColB = (0.3,0.5,0.7); //light blue
}
}
else
{
if(zinOdd(col))
{
ColA = (0.6,0.2,0.7); //purple
ColB = (0.3,0.5,0.7); //light blue
}
}

Oi = Os;
Ci = mix(ColA,ColB,pulseU * pulseV);
}

First of all, I have injected a #include line to read in the zinMacro.h header file. This header has the macros we need in the following codes, such as zinRepeat, zinWhichTile, zinOdd and zinEven.

float pulseU, pulseV;
- Created two float variables. The intention is to store the horizontal and vertical stripe pattern.

















_________________________________________________________________________________

color ColA = (0,0,1), ColB = (0,1,0);
- Created two color variables. Initialize them to blue and green. These two colors will be served as base colors.


_________________________________________________________________________________
float pulseFreq = 5;
- Created a float variable that decides how many times the pattern repeated. In this case, 5.


_________________________________________________________________________________
float uu = zinRepeat(u,pulseFreq);
float vv = zinRepeat(v,pulseFreq);
- Created another two float variables. The two variables will be used to store the result of repeating the pattern in u and v directions.
- zinRepeat function is defined as following in the zinMacro header file:
#define zinRepeat(x,freq)    (mod((x) * (freq), 1.0))

please refer to the previous post to understand how zinRepeat works.


















_________________________________________________________________________________

float col = zinWhichTile(u,pulseFreq);
float row = zinWhichTile(v,pulseFreq);
- The zinWhichTile function simply return the tile number. If the pulseFreq is 5, the returning value is 0,1,2,3,4. Tow float variables are created to store the value.
- The definition of zinWhichTile is:
 #define zinWhichTile(x,freq) (floor((x) * (freq)))

For more details explanation of how it works please refer to the previous post.

















_________________________________________________________________________________

pulseU = (step(0.4,uu) - step(0.6,uu));
pulseV = (step(0.4,vv) - step(0.6,vv));
- The pulseU and pulseV variables is making a stripe pattern starting from 0.4 to 0.6 from the range 0 to 1. With uu and vv previous set to repeat 5 times, the final result will look like this:
- Please note that even though the images presented here are in color, they are in fact in float values, meaning grayscale images.

















_________________________________________________________________________________

if(zinOdd(row))
{
     if(zinEven(col))
     {
          ColA = (0.6,0.2,0.7); //purple
          ColB = (0.3,0.5,0.7); //light blue
     }
}
else
{
     if(zinOdd(col))
     {
          ColA = (0.6,0.2,0.7); //purple
          ColB = (0.3,0.5,0.7); //light blue
     }
}

- This is the part where we start coloring the tile in different colors based on conditions. We must remember there is already a base color created at the very begining:
color ColA = (0,0,1), ColB = (0,1,0);

Then, check on each row to see if it is in odd number row, using zinOdd function. If so, go onto next condition, if it is in even column, using zinEven function. If both conditions are met, color it accordingly.

Else, if the very first condition returns false, which the result is in even row, go on to next condition to check if it is in odd number column. If so, color it accordingly.

- What we are trying to do here is, if the checking conditions are met, then we use a different color, else just use the default base color.


_________________________________________________________________________________

Ci = mix(ColA,ColB,pulseU * pulseV);
- Final part would be putting all these information together using mix function.





Wednesday 11 September 2013

using mod function to find odd and even number

It is possible to simple use mod function to find odd or even number.

odd(x)     (mod(x,2) = = 1)
even(x)    (mod(x,2) = = 0)


How does modulo works? It is simply take the first number divide by the second number and get the remaining value.

example:
mod(23,4) = 3;

4 x 5 = 20

and the remaining is 3. Therefore the answer is 3.

So, we can do use 2 as the number to divide to, and the remaining will be either 1 or 0. The value of 1, would of course be odd number, and 0 is even.

Please note that this will only work is x is a whole number.


whichtile and floor

To understand the use of whichtile function:

float freq = 5;
column = whichtile(u, freq);
row = whichtile(v,freq);

The definition of whichtile is:

floor(x * freq);
floor function will return the integer value.

example:
0.1 * 5 = 0.5;
floor(0.5) = 0;

0.3 * 5 = 1.5;
floor(1.5) = 1;

floor(2.1) = 2;

floor(6.9) = 6;

and so on....

So the concept is, u and v usually goes from 0 to 1. In whichtile function will take 0 and multiply it to 5 (freq value) then floor function it. Thus:
0.0 * 5 = 0.0;
floor(0.0) = 0;

0.1 * 5 = 0.5;
floor(0.5) = 0;

0.2 * 5 = 1;
floor(1) = 1;

0.3 * 5 = 1.5;
floor(1.5) = 1;

so the result is very much like a staircase:























Tuesday 10 September 2013

mod

Use mod( ) to achieve periodic pattern:

surface zinTest()
{
float pulseFreq = 5;
float pulseUU = (step(0.3,mod(u*pulseFreq,1)) - step(0.6,mod(u*pulseFreq,1)));

Oi = Os;
Ci = mix(color(1,0,0),color(0,1,0),pulseUU);
}























Monday 9 September 2013

smoothstep

Demonstration of smoothstep( ) :

surface zinTest()
{
float sStep = smoothstep(0.3,0.85,u);
Oi = Os;
Ci = mix(color(1,0,0),color(0,1,0),sStep);
}



abs

Example of using abs( ):


step( )

Using step function in RSL as some form of condition operator such as using if .... else...

surface zinTest()
{
float pulseU = (step(0.3,u) - step(0.5,u));
float pulseV = (step(0.3,v) - step(0.5,v));
Oi = Os;
Ci = mix(color(1,0,0),color(0,1,0),(pulseU * pulseV));
}

------------------------------------------------------------------
Ci = mix(color(1,0,0),color(0,1,0),(pulseU + pulseV));




















--------------------------------------------------------------------

Ci = mix(color(1,0,0),color(0,1,0),(pulseU - pulseV));





















--------------------------------------------------------------------
Ci = mix(color(1,0,0),color(0,1,0),(pulseU * pulseV));





















------------------------------------------------------------------
Ci = mix(color(1,0,0),color(0,1,0),(pulseU / pulseV));


?: ternary opertor

?: in programming language is a ternary operator. In a nutshell it means:

condition ? value_if_true : value_if_false

use in the min and max function in C:

float min(float a, float b)
{
       return (a<b?a:b);
}

float max(float a, float b)
{
      return (a<b?b:a);
}

Sunday 8 September 2013

faceforward

Definition from RSL documentation:

vector faceforward(vector N, I [,Nref = Ng])
{
          return sign(-I.Nref) * N;
}

This function is taking I, the incident ray from camera to the shading point, inverse it so that the ray direction is from the shading point back to camera. Then perform a dot product with Ng (surface geometric normal). Any shading point that is facing away from the camera view (the green lines on the image) will have the dot product to return a negative value. The sign function simply return -1 if the dot product calculation returns a negative value. If it is a positive value, the sign function will return positive 1.  Multiply again with the input N, (surface shading normal), the faceforward function eventually return a normal vector that is in negative value if it is facing away from camera.




















Sunday 1 September 2013

Texture Spaces

Current space
- is the one in which shading calculations are normally done. In most renderers,currentspace will turn out to be either cameraspace or worldspace, but you shouldn’t depend on this.

World Space
- is the coordinate system in which the overall layout of your scene is defined. It is the starting point for all other spaces.

Object Space
- is the one in which the surface being shaded was defined. For instance, if the shader is shading a sphere, theobjectspace of the sphere is the coordinate system that was in effect when theRiSpherecall was made to create the sphere. Note that an object made up of several surfaces all using the same shader might have different object spaces for each of the surfaces if there are geometric transformations between the surfaces.

Shader Space
-  is the coordinate system that existed when the shader was invoked (e.g., by anRiSurfacecall). This is a very useful space because it can be attached to a user-defined collection of surfaces at an appropriate point in the hierarchy of the geometric model so that all of the related surfaces share the sameshaderspace.

Cross Product

When performing a cross product operation, the result will be a vector that is perpendicular to both supplied vectors with a length equal to the area of the parallelogram they span.

The most common use for this operation in the computer graphics is to find the rendering normal of surfaces and to find the normal to any given plain in space

Dot Product


Normalize

Formula for normalizing a vector:


Length of a vector










Length of a vector can also be written as square root of dot product v (v.v)

Trigonometry

Some Trigonometry basics:


Math and Geometry Symbols

Some more definitions:


log( ) or natural logarithm

Defination of log( ):













Sometimes you will see a logarithm written without a base, like this:

log(100)

this usually means that the base is really 10.

Natural Lgarithms: Base "e"
Another base that is often used is e (Euler's Number) which is approximately 2.71828.

This is called a "natural logarithm". Mathematicians use this one a lot.

On a calculator it is the "ln" button.

loge(7.389) ≈ 2

Because 2.718282 ≈ 7.389

coefficient exponent and power

Just a little defination: