My "Ichiban Boshi" (number 1 Star) |
My previous post about RSL was a bit long, but necessary. However, that article was a bit big when downloaded, especially if we use smartphone and mobile Internet. So, I decided that future OSL posts need to be shorter and broken down into few different posts.
Porting RSL Star to OSL Star
Below is my effort to port code of RSL Star into OSL.I still skipped some of code that is relating to the Closure and focusing on the Texture only. But I added few things and modify the code slightly.
Maybe read this thread about Closure here:
http://www.elysiun.com/forum/showthread.php?291827-Creating-OSL-Closures
Currently, I am only curious about OSL and RSL and how the math function works to create Procedural Textures that is then passed on to the Closure.
// SOURCE http://www.renderman.org/RMR/Shaders/DPShaders/DPStar.sl
// Roughly Ported to OSL by Jimmy Gunawan @ Blender Sushi
// Dated 2013.08.05
shader DPStar(
//float Ka = 1;
//float Kd = 1;
int npoints = 5,
float sctr = 0.5,
float tctr = 0.5,
//float Cs = 0.1, // Cs is probably like original Diffuse Color
//color starcolor = color (1.0000,0.5161,0.0000),
color Color_A = color(1,0,0),
color Color_B = color(0,1,0),
float rmin = 0.07,
float rmax = 0.2,
point Vector = P, // added this so that Vector can be plugged
output color Col_Out = color(0.8)
)
{
float PI = M_PI;
//point Nf = normalize(faceforward(N, I));
//color Ct;
float ss;
float tt;
float angle;
float r;
float a;
float in_out;
float starangle = 2*PI/npoints;
point p0 = rmax * point(cos(0),sin(0),0);
point p1 = rmin * point(cos(starangle/2),sin(starangle/2),0);
point d0 = p1 - p0;
point d1;
float x = Vector[0];
float y = Vector[1];
ss = x - sctr;
tt = y - tctr; // s t become u v or X and Y
angle = atan2(ss, tt) + PI;
r = sqrt(ss*ss + tt*tt);
a = mod(angle, starangle)/starangle;
if (a >= 0.5)
a = 1 - a;
d1 = r * point(cos(a), sin(a),0) - p0;
//in_out = step(0, zcomp(d0^d1));
point FORCE = cross(d0,d1);
in_out = step(0, FORCE[2]);
Col_Out = mix(Color_A,Color_B,in_out);
//Col_Out = mix(Cs, starcolor, in_out);
/* diffuse ("matte") shading model */
//Oi = Os;
//Ci = Os * Ct * (Ka * ambient() + Kd * diffuse(Nf));
}
FUNCTION zcomp() and cross()
It takes me a while to figure out how to translate this RSL function below:zcomp(d0^d1)
Into OSL function:
The Z values of cross(d0,d1) // Cross Product of Point Positions d0 and d1
Below references helps me figure this out:
1. Some great examples here:
http://blenderartists.org/forum/showthread.php?274730-OSL-Porting-from-RSL
2. Google Books preview of book titled "Texturing and Modeling: A Procedural Approach".
Would be nice to have this book on hand, but luckily there is Google Books. That paragraph below helps me understanding what is happening and find the OSL equivalent.
I think that book is available at University of Technology of Sydney (UTS).
I also figure out that if we want to define point in OSL, we have to use syntax like this:
point myPointPos = point(0.2, 0.5, 1.0)
HAPPY ACCIDENTS
During this porting, I actually made few accident or mistakes, but by making "errors" I figure out interesting results...// SOURCE http://www.renderman.org/RMR/Shaders/DPShaders/DPStar.sl
// Roughly Ported to OSL by Jimmy Gunawan
// Dated 2013.08.05
shader DPStar(
//float Ka = 1;
//float Kd = 1;
int npoints = 5,
float sctr = 0.5,
float tctr = 0.5,
//float Cs = 0.1, // Cs is probably like original Diffuse Color
//color starcolor = color (1.0000,0.5161,0.0000),
color Color_A = color(1,0,0),
color Color_B = color(0,1,0),
float rmin = 0.07,
float rmax = 0.2,
point Vector = P, // added this so that Vector can be plugged
output color Col_Out = color(0.8)
)
{
float PI = M_PI;
//point Nf = normalize(faceforward(N, I));
//color Ct;
float ss;
float tt;
float angle;
float r;
float a;
float in_out;
float starangle = 2*PI/npoints;
point p0 = rmax * point(cos(0),sin(0),0);
point p1 = rmin * point(cos(starangle/2),sin(starangle/2),0);
point d0 = p1 - p0;
point d1;
float x = Vector[0];
float y = Vector[1];
ss = x - sctr;
tt = y - tctr; // s t become u v or X and Y
angle = atan2(ss, tt) + PI;
r = sqrt(ss*ss + tt*tt);
a = mod(angle, starangle)/starangle;
if (a >= 0.5)
a = 1 - a;
d1 = r * point(cos(a), sin(a),0) - p0;
//in_out = step(0, zcomp(d0^d1));
//point FORCE = cross(d0,d1);
in_out = step(0, d1[0]);
Col_Out = mix(Color_A,Color_B,in_out);
//Col_Out = mix(Cs, starcolor, in_out);
/* diffuse ("matte") shading model */
//Oi = Os;
//Ci = Os * Ct * (Ka * ambient() + Kd * diffuse(Nf));
}
// SOURCE http://www.renderman.org/RMR/Shaders/DPShaders/DPStar.sl
// Roughly Ported to OSL by Jimmy Gunawan
// Dated 2013.08.05
shader DPStar(
//float Ka = 1;
//float Kd = 1;
int npoints = 5,
float sctr = 0.5,
float tctr = 0.5,
//float Cs = 0.1, // Cs is probably like original Diffuse Color
//color starcolor = color (1.0000,0.5161,0.0000),
color Color_A = color(1,0,0),
color Color_B = color(0,1,0),
float rmin = 0.07,
float rmax = 0.2,
point Vector = P, // added this so that Vector can be plugged
output color Col_Out = color(0.8)
)
{
float PI = M_PI;
//point Nf = normalize(faceforward(N, I));
//color Ct;
float ss;
float tt;
float angle;
float r;
float a;
float in_out;
float starangle = 2*PI/npoints;
point p0 = rmax * point(cos(0),sin(0),0);
point p1 = rmin * point(cos(starangle/2),sin(starangle/2),0);
point d0 = p1 - p0;
point d1;
float x = Vector[0];
float y = Vector[1];
ss = x - sctr;
tt = y - tctr; // s t become u v or X and Y
angle = atan2(ss, tt) + PI;
r = sqrt(ss*ss + tt*tt);
a = mod(angle, starangle)/starangle;
if (a >= 0.5)
a = 1 - a;
d1 = r * point(cos(a), sin(a),0) - p0;
//in_out = step(0, zcomp(d0^d1));
//point FORCE = cross(d0,d1);
//in_out = step(0, a);
Col_Out = mix(Color_A,Color_B,a);
//Col_Out = mix(Cs, starcolor, in_out);
/* diffuse ("matte") shading model */
//Oi = Os;
//Ci = Os * Ct * (Ka * ambient() + Kd * diffuse(Nf));
}
// SOURCE http://www.renderman.org/RMR/Shaders/DPShaders/DPStar.sl
// Roughly Ported to OSL by Jimmy Gunawan
// Dated 2013.08.05
shader DPStar(
//float Ka = 1;
//float Kd = 1;
int npoints = 5,
float sctr = 0.5,
float tctr = 0.5,
//float Cs = 0.1, // Cs is probably like original Diffuse Color
//color starcolor = color (1.0000,0.5161,0.0000),
color Color_A = color(1,0,0),
color Color_B = color(0,1,0),
float rmin = 0.07,
float rmax = 0.2,
point Vector = P, // added this so that Vector can be plugged
output color Col_Out = color(0.8)
)
{
float PI = M_PI;
//point Nf = normalize(faceforward(N, I));
//color Ct;
float ss;
float tt;
float angle;
float r;
float a;
float in_out;
float starangle = 2*PI/npoints;
point p0 = rmax * point(cos(0),sin(0),0);
point p1 = rmin * point(cos(starangle/2),sin(starangle/2),0);
point d0 = p1 - p0;
point d1;
float x = Vector[0];
float y = Vector[1];
ss = x - sctr;
tt = y - tctr; // s t become u v or X and Y
angle = atan2(ss, tt) + PI;
r = sqrt(ss*ss + tt*tt);
a = mod(angle, starangle)/starangle;
//if (a >= 0.5)
// a = 1 - a;
d1 = r * point(cos(a), sin(a),0) - p0;
//in_out = step(0, zcomp(d0^d1));
//point FORCE = cross(d0,d1);
//in_out = step(0, a);
Col_Out = mix(Color_A,Color_B,a);
//Col_Out = mix(Cs, starcolor, in_out);
/* diffuse ("matte") shading model */
//Oi = Os;
//Ci = Os * Ct * (Ka * ambient() + Kd * diffuse(Nf));
}
// SOURCE http://www.renderman.org/RMR/Shaders/DPShaders/DPStar.sl
// Roughly Ported to OSL by Jimmy Gunawan
// Dated 2013.08.05
shader DPStar(
//float Ka = 1;
//float Kd = 1;
int npoints = 5,
float sctr = 0.5,
float tctr = 0.5,
//float Cs = 0.1, // Cs is probably like original Diffuse Color
//color starcolor = color (1.0000,0.5161,0.0000),
color Color_A = color(1,0,0),
color Color_B = color(0,1,0),
float rmin = 0.07,
float rmax = 0.2,
point Vector = P, // added this so that Vector can be plugged
output color Col_Out = color(0.8)
)
{
float PI = M_PI;
//point Nf = normalize(faceforward(N, I));
//color Ct;
float ss;
float tt;
float angle;
float r;
float a;
float in_out;
float starangle = 2*PI/npoints;
point p0 = rmax * point(cos(0),sin(0),0);
point p1 = rmin * point(cos(starangle/2),sin(starangle/2),0);
point d0 = p1 - p0;
point d1;
float x = Vector[0];
float y = Vector[1];
ss = x - sctr;
tt = y - tctr; // s t become u v or X and Y
angle = atan2(ss, tt) + PI;
r = sqrt(ss*ss + tt*tt);
a = mod(angle, starangle)/starangle;
if (a >= 0.5)
a = 1 - a;
d1 = r * point(cos(a), sin(a),0) - p0;
//in_out = step(0, zcomp(d0^d1));
point FORCE = cross(d0,d1);
in_out = step(0, FORCE[2]);
Col_Out = mix(Color_A,Color_B,d1[0]);
//Col_Out = mix(Cs, starcolor, in_out);
/* diffuse ("matte") shading model */
//Oi = Os;
//Ci = Os * Ct * (Ka * ambient() + Kd * diffuse(Nf));
}
There must be some clever Math in there that should be explained. I shall contact one of my friend who is a Math guru to explain what is happening. Anyway, as a visual person, I am quite happy to see something already happening.
The important thing, I think, as CG Artist, who likes to use this OSL capability is to understand what is going on. There are already some examples of procedural RSL Texture that can potentially be ported to OSL. Eventually they are all will be available for us to use, I guess.
So, the next step for Artists is to MIX and MATCH and LAYER the code to create a complete and more complex shader.
For this simple Star OSL shader alone, I made nearly a hundred of mistakes (OSL compile errors), but I think it is worth it and hopefully can contribute a little for the OSL community.
I checked the errors and see what lines is causing the error, and comment out parts and do some tests, repeating this process, I finally got this final OSL Star right!
SOMETIMES I FEEL LIKE A NEWBIE...
The OSL Star has basic star variables: Number of Star, Inner Radius, Outer Radius, X and Y Offset Position. |
It may seem silly to feel excited being able to create simple primitive procedural DOT, LINE, CIRCLE, RING, STRIPES, and ... STAR, when we saw hundred of posts already taking OSL to "high level":
http://www.blenderartists.org/forum/showthread.php?270332-OSL-Goodness
However, I believe that I need to write things like this and will worth it. I hope that some of you feel the same too and contribute little by little.
So, indeed writing Shader is a little bit like "drawing blind".
QUESTIONS ARISE...
It is nice that we can now create procedural Dragon Ball Texture... :)... however, more questions arise:
- The shader seems to be always projected to the Front and Back Surface, how do we limit or make it to show up only on Front Facing Face? Maybe something to do with N (normal) of Surface?
- How to REPEAT and TILE Texture? --- this question keeps popping up and I am not getting answer... I started to see how the U and V can be replaced with P position X and Y, but tiling... is tricky, unless someone can explain. DingTo, if you read this... please help.
READING MATERIAL:
http://blenderartists.org/forum/archive/index.php/t-277284.html - How do we LAYER Texture Procedurally using OSL and how to do layering using Cycles node network?
READING MATERIAL:
http://blenderartists.org/forum/archive/index.php/t-293132.html
http://vadrouillegraphique.blogspot.fr/2013/05/pyla-physically-correct-layer-shader.html - What is a function that adds STROKE? If I want stroke on the star procedurally, for example...
- Can we repeat the Stars IN and OUT?
- What Math equation to use to ROTATE the Star? ANSWERED 2013.08.06.
- Can we create FLOWER instead of STAR?
- Can we actually use RANDOM and SCATTER efficiently for OSL?
- Can we turn STAR shader into SPIDERWEB, BICYCLE WHEEL WIRES, etc...
Will update them when answered.
...QUESTIONS ANSWERED!
Update 2013.08.06:
ROTATE THE STAR
Thanks to Gottfried at BlenderDiplom for his Twitter reply and the answer lies here on his blog:
I must have missed that info last time. I cleaned up the code a bit and highlight the changes in BOLD.
Adding just few lines and variable to the code allowing for rotation of the Star:
// SOURCE http://www.renderman.org/RMR/Shaders/DPShaders/DPStar.sl
// Roughly Ported to OSL by Jimmy Gunawan
// Dated 2013.08.06
shader BSStar(
int npoints = 5,
float sctr = 0.5,
float tctr = 0.5,
color Color_A = color(1,0,0),
color Color_B = color(0,1,0),
float rmin = 0.07,
float rmax = 0.2,
float RotAngle = 0.0,
point Vector = P,
output color Col_Out = color(0.8)
)
{
float PI = M_PI;
float ss;
float tt;
float angle;
float r;
float a;
float in_out;
float starangle = 2*PI/npoints;
point p0 = rmax * point(cos(0),sin(0),0);
point p1 = rmin * point(cos(starangle/2),sin(starangle/2),0);
point d0 = p1 - p0;
point d1;
float x = Vector[0];
float y = Vector[1];
ss = x - sctr;
tt = y - tctr; // s t become u v or X and Y
angle = atan2(ss, tt) + PI/180 * -RotAngle;
r = sqrt(ss*ss + tt*tt);
a = mod(angle, starangle)/starangle;
if (a >= 0.5)
a = 1 - a;
d1 = r * point(cos(a), sin(a),0) - p0;
point ZCOMPONENT = cross(d0,d1);
in_out = step(0, ZCOMPONENT[2]);
Col_Out = mix(Color_A,Color_B,in_out);
}
- PI / 180 is so that the value goes slower when rotation. Converting Radian to Degree, I think.
- I also put MINUS on the RotAngle, so that the rotation is Clockwise when number is increased, it is more logical.
angle = atan2(ss, tt) + PI/180 * RotAngle;
angle = atan2(ss, tt) + PI/180 * -RotAngle; //same thing
angle = atan2(ss, tt) - PI/180 * RotAngle; // same thing
Thanks Goffried, now the Star is rotate-able and animate-able. |
Adding lines by lines and understanding the OSL code is a good way to properly code a shader.
There are already clever Math people out there creating bunch of useful functions, all we need to do is to use and implement them. Sometimes, we really don't always need to understand the whole function and codes, just understanding what it does to allow us to modify them to suit our need.
REPEATING THE STARS
Updated 2013.08.07 after I read this document properly:
float ss = mod(s*RepeatS,1);float tt = mod(t*RepeatT,1);
// Roughly Ported to OSL by Jimmy Gunawan
// Dated 2013.08.07
shader BSStar(
int npoints = 5,
float sctr = 0.5,
float tctr = 0.5,
color Color_A = color(1,0,0),
color Color_B = color(0,1,0),
float rmin = 0.07,
float rmax = 0.2,
float RotAngle = 0.0,
point Vector = P,
float RepeatS = 4.0,
float RepeatT = 4.0,
output color Col_Out = color(0.8)
)
{
float PI = M_PI;
float ss;
float tt;
float angle;
float r;
float a;
float in_out;
float starangle = 2*PI/npoints;
point p0 = rmax * point(cos(0),sin(0),0);
point p1 = rmin * point(cos(starangle/2),sin(starangle/2),0);
point d0 = p1 - p0;
point d1;
float x = Vector[0];
float y = Vector[1];
ss = mod(x * RepeatS, 1) - sctr;
tt = mod(y * RepeatT, 1) - tctr; // s t become u v or X and Y
angle = atan2(ss, tt) + PI/180 * -RotAngle;
r = sqrt(ss*ss + tt*tt);
a = mod(angle, starangle)/starangle;
if (a >= 0.5)
a = 1 - a;
d1 = r * point(cos(a), sin(a),0) - p0;
point ZCOMPONENT = cross(d0,d1);
in_out = step(0, ZCOMPONENT[2]);
Col_Out = mix(Color_A,Color_B,in_out);
}
OSL CLOVER / FLOWER
I need a bit more time to study this one and make sense of it, but probably you can also do study on it.http://blenderartists.org/forum/showthread.php?277334-Flowers-OSL
http://www.youtube.com/watch?feature=player_embedded&v=-z8zLVFCJv4
MORE REFERENCES:
http://www.renderman.org/RMR/RMRShaders.htmlhttp://www.renderman.org/RMR/Shaders/DPShaders/index.html
http://web.engr.oregonstate.edu/~mjb/prman/shaderfunctions.html
Post a Comment