Halloween Costume ideas 2015
Articles by "programming"
@dorothiar #arttips #interview 101 2 Column Template 2012 mentee 2013 2013 mentee 2014 2014 mentee 2014 Portfolio Winner 2014 SCBWI Portfolio Mentorship Winner 2015 mentee 3 Column Template 360 3d 3d print 3d printing 3delight 8bit Abbey McCulloch abstract acryla gouache acrylic action addon adobe Adobe Flash CS3 Adobe Illustrator Advanced Tutorials advection Advertising advice Agata Wierzbicka agents airplane Al Wiseman ALA Alan E. Cober Alan Lee Alex Ross Alexandra Compain-Tissier Alexandra Lekias Alexandra Levasseur Alexandre Korobov Alexis Winter algorithm alien ALT Amelie Hegardt Amit Shimoni amusement an Ana Aranda analog Andrea Hrjnak Andrea Hrnjak andrea offermann andreaoffermann andreazuill Andy Musser Angela DiTerlizzi Angelika Peißker animal logic animals animation animation nodes anime anisculpt Anja Kroencke Anna Higgie Anna Jensen Anna McKay Annabel Briens AnneBerry Anneke Krull Annu Kilpeläinen anstudy anthology António Soares ar arduino area armature arrange array array modifier arrow art art director art directors Art is fun! art reps art tools Artaksiniya arthictecture arthur rackham artists artwork ase Ashlyn Anstee Asian aspiring asset atom attribute attribute transfer audio Audrey Kawasaki augmented reality aurasma Aurelius Battaglia author illustrator automatic automation Autumn Whitehurst avatar Avrom Yanovsky AW14/15 award awards Babeth Lafon Babies baboon Baby Love Background background color bacteria bake baking ball Bamboo banner Banner images banner making Barbara Dziadosz barcode basic bbox beads beats Bec Winnel beginner Bel Johnstone Ben Denison Bernie Fuchs Berto Martinez Beth Krush better photos bge Bijou Karman Bike biscuit bishop black and white black and white art Blair Breitenstein blam blender blender game engine blender3d blending Blinkie Blinky blob blocks Blog Tips blogger Blogging Friends blogs Blonde blur effect in pixlr and photoshop blur images and pictures bmesh bmesh viewer bolognaragazziaward bombing bone bone modeling bones book book launch books boomerang bottle bounding box bowl bpy brian eno brian ormiston Brian Sanders brian won brick bridge Bridget Davies bright Brooke Boynton Hughes build modifier building burns business Buttons bvh cage Caitlin Shearer caldecott calibration camera camera settings camera tips Candle capcom card career Carole Wilmet cartoony Cassandra Rhodin cast Catherine Campbell Cecilia Carlstedt cell center pivot centipede cg cg photography chair challenge Chanel changin color in pixlr changing color chaos character Character Bible character development charcoal charles Charlie Dot Charlie Hebdo Children children's book illustration chocolate Christina Drejenstam christina forshay Christina K christinaforshay Christmas Cindy Derby circle circle dance city cityengine clock clones cloning cloth Cloud based clover CMYK Coco Chanel Cody and the Fountain of Happiness coffee collect collection Collections collision color color balance color cast color correction color mode color study colorful Commercial Use complexity component compositing composition computational thinking computer concept art Condensed Posts conference connect connect the dot connection Connie Lim Conrad Roset constrain constrast contagion content Contest contracts control converter copy copyright Corinna Luyken count Courtney Brims crack Craft craftsmanship Craig & Karl creative creativity creature cricket Cristina Garcia Martin critic criticism critique Crop Crop Tool cross section crowd csv cubism curve curve modifier custom Custom Blog Design Custom Blog Design Tutorial Custom Blog Designers Custom Illustration custom properties Custom Signature custom xml cut cutting plane cycle cycles dae Damien Florébert Cuypers Dan Hillier dance Daniel Egnéus Daniel Segrove Danny Roberts Daren Newman Dasha Tolstikova data data path David Blossom david diaz David Shrigley David Stone Martin Dean Hardscrabble Debbie debbie ohi debbieohi deform deformer degrees deleting background in pixler demo demoscene desaturation of images design design by numbers design process Design Tips dictionaries dictionary Different Text Writing in Pixlr digital digital paint Digital Scrapbook Freebies Digital Scrapbooking disk distance distractions distribute diversion DIY DIY Contest Dolf Veenvliet Doll Doll Bones dolls domino domino effect doodle Doodles door doraemon Doris Jackson Dorothia Rohner dots dpi draw drawing drill driven driver drivers dual versions dummy duplicate duplicates duplication dupliframe dvd dynamic dynamic paint dynamic text E Simms Campbell Easy easy pixlr Easy Tutorials Ed Graham Ed Vebell editing editing photos editors education effect effects ego Eleanor Dalton electric Elia Fernández eliza wheeler Elizabeth Mayville elizawheeler Emily Forgot Emma Zanelli emoticon happy-face Emotional storytelling empathetic characters empty entoforms envy epicycloid EPS Illustration Epson scanner erasers Erin Armstrong Erin Petson erinoshea ernest shepard Esra Roise euler evaluate line Eveline Tarunadjaja evenly spacing vertex event everywhere door exhibition Expandable Posts experiments explode exploded view export expression extrude eye eye color in pixlr eye trick eyeball face rig facial expressions facial setup factory Faiyaz Jafri Families fashion illustration fashion week fcurve feature Featured Fee Harding Feedback fence Fernanda Guedes fibonacci Fifi Lapin file File Types Finalists Finding Nemo fire fix photos Flash Tutorials flicker flip flip flop floor flop flow flower Flowers fnmatch focal point follow up font Fontaine Anderson Fonts food footage For Sale force form formula fractal fracture frame Frames Francois Berthoud Frank Bellamy Frank Furlong Franklin McMahon freckles Fred Steffen FrederiqueBertrand Free for Commercial Use Free for Personal Use Free Stock Photography Free transform tool Freebies Frenchillustration Fritz Siebel frosted mylar fruit ninja Fumi Mini Nakamura Fun function futurism FW2017 fx Gabriel Moreno Gabriella Ibarra game game animation gameart gamma gangnam style Garance Doré Gary Fernandéz gel medium generate generative generator geometric geometry Gerald Lazare Géraldine Georges GIF Gildo Medina Girl Giuseppe Castellano Giveaway glorar goals golden ratio google google docs Google Tools Grant Young graph graphite graphite transfer grease pencil grid group group node growth Gucci Guest Guil Godier gustave dore hair handbook Harper's Bazaar harpercollins Harvey Schmidt Haute Couture head Headers heat map Helena Hauss hexagon hexagonal grid Hiroshi Mizuno Hiroshi Tanabe Holiday Holly Black homology honeycomb hook horror houdini how to how to blur a face or an object in pixlr How to change eye color how to delete an object how to desaturate an image how to edit a image in pixlr how to erase an object how to fix red eye problem how to fix red eyes in pixlt How to fix the parts in pixlr in photoshop How to make a banner in pixlr How to overlap the nevus how to remove a object How to remove an object in pixlr how to remove red eyes How to Remove the Background of an Image in Pixlr How to remove the parts that you don't want in pixlr and photoshop how to replace color How to write a Patterned Text in Pixlr how-to Hsiao-Ron Cheng hsv hue humor Hyshil I love illustration magazine idea ideas Igor+André illusion illustrating illustration illustration board Illustration Books Illustration Intensive Illustration Now! Fashion illustration process Illustrations Illustrative Berlin illustrator Illustrator Intensive Illustrator Tutorials iloveillustration magazine image ediditing lessons Image Ready image sequences image theft imaginative import import text import vertex color improving photos inbetween index visualizer Info Ingrid Bockting ink inktober input Inspiration inspirational quotes install instance instance switching intensive interaction Intermediate Tutorials internet interoperability interpolation intersect intersect edges intersecting intersection interview introduction invoke subprogram io ipad Irana Doucer Isabella Hemmersbach islam islamic iteration Izzie Klingels Jack Hearne Jack Tremblay James Dignan James Gurney japanese Jason Brooks Jean Kim Jeanne Detallante Jen and Chris Creed Photography jen betton Jen Rofé Jenny Mörtsell Jeremy Combot Jeslyn Kate Jesse Auersalo Jessica Jessica Lanan jessicalanan jewellery jewelry jiggle Jim Schaeffing Joe Bowler Joe Cleary Joe Isom Joe Krush Johanna Goodman john maeda John Vernon Lord joint Jordan Sondler JPEG JPG jpop juana martinez-neal juanamartinezneal Judge Judit Garcia Talavera Judith van den Hoek Judy Byron Schachner Jules Julien Julian Beever Julie Verhoeven Jump Break Tool JW Anderson K-Fai Steele Kaethe Butcher Kareem Iliya karel zeman Kate van Harreveld Kathrin Kuhn Kathryn Ault Noble Kathryn Noble Katie Kath kdtree Kei Meguro Kelly Beeman Kelly Light Kelly Smith kelly sonnack Kelly Thompson keyframe keyframing kidlit kidlitartists kimberlygee Kirkus Review Kisoo Chai Kodak Konstantin Kakanias Korean illustration Kotaro Chiba Kozue Himi Kremos Ksenia Finogeeva KT Smail kuler Kustaa Saksi Lanan Laptop larry gritz lasso tool latte lattice Laura Callaghan Laura Laine Lauren Rille layer layering Layla Holzer layout leaf learning learning blender LED Leendert meets Ingrid lego length Leonard Starr lessons levels LFW A/W 14 liangzhu liero lightbox lighting lightning Lina Bodén Lina Ekstrand Linda Dorn line line connect line drawing lines Links Linky Love Linn Olofsdotter Lionel Gilbert Lisa Anchin Lisa Billvik Lisa Krannichfeld lisaanchin lisbeth zwerger Liselotte Watkins list list comprehension List First Last listing locator lofting logo Logo Design Lola Dupré London Fashion Week loop looping loops looptools Lorraine Fox lossless lossy lost weekend lostweekend lotte reininger Louis Glanzman louis vuitton Luciana Rondolini luciograph LULU* lv Lynnie Zulu Mac macgyver macouno maeda Magda Antoniuk magic Magnus Voll Mathiassen mailing mailings maker Makiko Sugawa making banners Malika Favre MAMP mandala manga map map range maplelam mapping Marcel George Maren Esdar Margot Macé Margot van Huijkelom Maribeth Olson Marie El-Ahmar Marilyn Conover Marina Esmeraldo Marine Marbleindex mario Marlies Niemeijer Marsha Riti Martha Rago Martin Krusche Martine Johanna mask masking material materials math matrix matrix apply matryoshka Matt Baker matte medium Matthew Woodson maya maze mdd Meagan Morrison measure megaman Megan Hess Meizhen Xu Mel Crawford memory mentee mentees mentors mentorship program Mercer Mayer Meridth McKean Gimbel mesh mesh cutter meshlab Meta Tags metal gear rising Meyoko Mia Overgaard Micca mice Michael Sanderson Michela Picchi middle grade midi miku Milan milipede minidom Minima Mio Matsumoto mirror cut Misc Miss Blackbirdy miss maple's seeds Miss Take Mitchell Hooks mixamo mixing Mobile Apps mocap mod model modeling modifier modular modulation modulus mold molecule molly idle Molly Ruttan Molly Ruttan Illustration money monitors monkey mono-zero monster monster university morph morpher mosaic mosquito motion motion capture motion capture mouse motion trail moto360 mountain muji Muriel Wood Murray Tinkelman mushroom Music and Podcasts My dead pony Nadia Flower Naiad Einsel Naja Conrad-Hansen Natalie Brockett Natalie Foss nathan vegdahl nautilus Nav Bar navigation needle-felting negotiating Neil Boyle neon nescbwi14 nested New Blogger Questions New Blogger Template Tutorials new user pixlr new year new york New York Fashion week Newbery nicholas nicholas bishop Nicholas Hong Niki Pilkington Niso Ramponi nla No Software node node-based nodebox noise non linear animation Non-Web Font normal Noumeda Carbone npr number NURBS NYFW object object color change object info octopus offset Ola Volo Olaf Hayek old formats opaque projector open movie open shading language open source openshadinglanguage opensoundcontrol optical organization origami original art show Ornaments osc Oscar Schlienger osipa osl outline outliner output Pages paint paint weight painting painting on illustration board painting on wood painting with movie painting with numbers Pair pandas panorama Paper paper lantern parabola parametric parent parenting particle particle info node particles pat david Pat Zietlow Miller pattern Patterned Text Paul Faassen Paul X. Johnson Paula Sanz Caballero PC pdb pebbles pencil Pencil Sketch pencils Penguin perfume perlin Peter Helck Photo CD.8B photo editing software Photo Reference Photobucket photographing art Photographs photography photomerge photoshop Photoshop Brushes Photoshop CS3 Photoshop elements photoshop pixlr desaturaion Photoshop tips Photoshop Tutorials Picture Book Builders picture books Pierre Louis Mascia Piet Paris Pietari Posti pingpong pinnochio pipes pixar pixel pixel art pixel generator pixlr Pixlr advanced Pixlr blog pixlr desaturate keep a colorful part pixlr editting pixlr express Pixlr forum Pixlr free transform Pixlr Lesson Pixlr lessons Pixlr mobile Pixlr resizing images pixlr shortcuts Pixlr tools pixlr tutorial pixlr tutorial with pictures Pixlr Tutorials pixlr white black pixlr.com plant plot plotting ply PNG PNG Illustration podcast point point color pointilism polka dots polyCut polygon Pomme Chan pop-overs portfolio Portfolio award portfolio showcase portfolio-advice portrait position Post Dividers postcard poster Posting pot powdered graphite powerhousemuseum Prada presentation print printmaking Prize procedular procedural process processing programming projection Promotion property prototype PSD psy publishing pulse puppet puppetry pydriver pydrivers pyhandler pyhandlers pyramide python quad quick select set quick tips qumarion Rabbit Moon Rachel Ryle radians radius ramp random random motion randomization randomize range float raspi Ray Houlihan reading reading XML READY-TO-WEAR realflow Rebecca Clarke rebecca dautremer Rebecka Skog rebuild recursive recursivedrawing red eye remove reducing glare reference referencing release remesh modifier remix removal remove remove red eyes remove unwanted objects Removing backgroung render rendering renderman repeat repeater repeating replace replacement replacing color representation rerouter resample resampling research Resizing image resolutions retopology retro review revolve rgb rib Ricardo Fumanal Richard Scarry rig rigging rigify Rikke Jorgensen ring ripple roadkill Robert Heindel Robert J. Lee Robert McCloskey Robert Shore Roberta Zeta Robin Rosenthal robot robotic rocks Rodolfo Montalvo Roller Coaster rotation Rousseau rsl Rubin Pfeffer ruler tool Russ Mills russian rut S/S14 S/S15 S/S16 Sabine Pieper sadako Saftey Pins Sainte Maria Sale Sam Weber Sanda Suy Sandy Kossin santoso Sara Andreasson Sara Singh Sarah Jacoby saturation artist tools scan scanners scanning scatter scbwi SCBWI 2015 mentee SCBWI conference scbwi germany SCBWI mentorship scbwi-la scratch scratchboards screensaver screw screw modifier script scrub sculpting seamless Seamless Patterns Search Engines select by material select by name select by type SEO sequence series set keyframe set keyframes shader shading shadow Shannon Stirnweis shape grammars shape key shapekeys shapes shards shatter Sheilah Beckett shell ship shipping shipwright Shoes SHOWstudio shuffle Sid Barron Sidebar Titles Signature Silja Goetz silkworm Simon and Schuster Simon Varela simple simplicity simulation sine Site Engine Optimization Sjoukje Bierma sketch Sketches sketching skin skin modifier skinning slice slicing slides sloth slow parent smoke smoothstep SN snake Sneek Peek snippet Snow Snow White Snowflakes soccerball social media Social Media Buttons Social Networking society of illustrators Society6 soft body softbody Sonia Menti sound sound wave space spaceship sparta special spider spiderman spiderweb spin spiral Spiros Halaris Spiros Halaris x Urban Decay spline Spot Healing Tool spreadsheet SS16 stack stacking stair stamp Stan Galli star starfish stencyl step Steven G. Dobson still Stina Persson stone stones storytelling strand strand info strands street art string stripes structure studies studio style stylistic summary Summary Posts Summer sun supplies surface Susan Farrington suzanne Suzanne Kaufman sverchok swatch switch sydney system table table of contents take out background Tal Drori tangent tangled Taschen teaching teapot Template Templates tentacle Tess Jacobson Tex Avery text text editor Text Formats Text Styles in Pixlr texture texturing The Cartorialist The Grudge Keeper The Purple Book thinker1 Thomas B. Sawyer thread TIFF tile tilecam tiling time time code Tina Berning Tina Kugler tips tips for artists Toby Neilan Tom Baxter Tom Bjarnason tombow tomie depaola tool tools topology tower Tracy Turnbull Train transfer drawing transferring sketch transform transformation transit travel triangle wave Tricia Springstubb trigger tris tristan lock tube tubes Tutorials twitter type tool typeface typography unbake unity3d universal unquad utah uv valentine Valentino Valerie Servais vanilla variable variation variety vase vector vectorized Velwyn Yossy venus Veronica Ballart Lilja vertex vertex color vertex group vertex paint vertex weight VFX Victoria Boysen video Videos viewer Vintage virtual virtual studio visualization vivid vividfestival VOGUE volumetric voronoi Vote voxel voxelated voxelation walking teapot Walter Einsel wand tool water soluble graphite watercolor wav wave we need diverse books web webbing Week Themes weight welcome Wendy magazine Wendy Plovmand what casues red eyes What is Pixlr Wherever You Go Wide Awake Bear wiggle Will Davies Winner Winnie Fitch Winnie Truong Winter wire wired wireframe wolfram Woman wood woodwork wool wooly wordpress work workflow World writing writing XML www.pixlr.com XML YA yayoi kusama Yelena Bryksenkova yoda Yoko Furusho Yuliya zaha hadid zen zsphere

Icospherical Suzanne Clones.
Positioning monkeys into Icosphere Vertex position.

If you are following this blog, or just randomly browsing the articles, you might notice that I have strange interest over node-based procedural modeling and animation method. I like the idea on how we can crunch numbers and data to the computer, and let the computer does some complex processing for you. And I also have big interest on data visualization. So whenever there is an opportunity to explore such tools in Blender, I jump on it.

By now, there are already quite a few node-based add-ons for Blender as for today. Eventually, they will be unified under one Blender node tree, I have that believe in Blender. I am quite picky on which node-based add on to choose. So far, I found Sverchok and recently Animation Nodes (AN).

The tools I pick based on my familiarity with Maya, Houdini, and a bit of Softimage ICE. I think node-based system shoud be user friendly and does it the Blender way, yet universal.

Sverchok is one Blender add-on that I have seriously explored in the past for its node-based procedural ability. I believe Sverchok was originally designed for procedural 3D modeling, however, Sverchok also can "move" and "animate" mesh and later on can animate objects thanks to Sverchok developers that allow animation to happen.

Animation Nodes (AN), is yet another add-on that allows us to create procedural animation in Blender by creating and connecting nodes, and let the data flow do the animation job.

One can think of procedural node-based worklow just like creating, modifying, and transforming a non-destructive ways, similar to Blender's own Modifiers. For example, there are Mesh Modifiers and Animation Curve Modifiers (inside Graph Editor, allowing you to generate, tweak and modify animation curve without destroying anything).


1. Generator Modifier inside Graph Editor.
2. Adding Noise Modifier on top of Generator Modifier, and Multiplying them together.


Few words of cautions, when dealing with node-based system, you may need to be comfortable with some programming concepts, such as:

  • Data types (float, integer, string, vector, matrix, etc)
  • Data conversion
  • Arrays and Lists
  • Loop and Iteration
  • Functions
  • Variables
However, unlike typed programming language, node-based is usually more visual and less abstract. In fact, node-based is can be really very advantageous and helpful for "non-technical" computer artists to have this ability to clearly see what is going on without worrying about the complexity of language. You could create a complex setup and modify certain setup for own purpose just by understanding the logic.

In my own word and understanding, a node is really a container that hides complexity and reveal functions, so we may care more about the data input, data output and data flow to get the final result. How all the functions work together. A bit like LEGO bricks, we kind of need to know what each block can do and how it can attach together to build a structure.

Understanding the concepts is more important than memorizing complex node-tree. You will find really quickly that there are many possibilities to achieve the same result. Some are more elegant, simpler, some are complex underneath, but beautifully presented. Sometimes a complex node-tree is good for some matters, but the more specialized, the harder to customize. 

Now, AN probably does not have a full complete set of animation nodes at this point, but it is growing and the number of nodes will continue to increase as it is continue to mature. Keep in mind also that nodes might change over time, this is the nature of the tool, once again I have to mention.

What really intrigues me with tool like AN, is the openness and potential both for learning and development. If you have enough skills you can eventually create your own nodes that you can share with other artists. And when we collaboratively create node-tree of certain setup, ideally we can re-use and build more complex tools.

So in this article thinking about Animation Nodes, I am trying to map out our learning areas. So I will be jumping around from topic to topic.

Enough preaching, let's explore this Animation Nodes add-on together! 


THINKING ANIMATION PROCEDURALLY

Manually animating in computer graphics involves keyframing values of attributes in different frames. The animation will then be created when the computer interpolate or create in betweens for those values that we specified when we playback the time. The speed of acceleration and the weighting of the interpolation (animation curve) can be adjusted manually via Graph Editor, whether we have linear motion, slow in slow out, stepped, etc.

NOTE: For character animation, usually animating involving posing the character controllers (!) and animator worried more about the actual emotion or story to tell. We will get there, but at the moment, we go to the most basic first.

In reality we are really controlling the motion of object using f-curve over time. Simple enough concepts that takes a while to understand. Make sure you understand that concept first.

Procedurally animating is pretty similar, just that user is a little bit more exposed into smaller components. We still be dealing with VALUES over TIME, and then CONTROL-ing how the values get interpolated.

Procedural animation is great for something that involves repetitions. Every so often, we would like to apply similar animations to a bunch of objects, with slight offsets or variations. Perhaps it is a building with lots of windows that we like to open at slightly different time, or maybe it is the lights that need to turn on not at the same time, but in a slightly offset kind of way (more interesting).

What can we control or animate? Ideally we want our node based to control everything. Animation Nodes seems to be able to do so already, even at this stage. If there are missing tools, one can always write Python code for it or request the developers.


1. Objects (tranform of objects: Translate, Rotate, Scale, Visibility)
2. Text
3. Mesh (vertices) or Curve
4. Color
5. Attributes
6. Others

Usually Motion Graphics animation deals a lot with these kinds of animations. It's good idea to look around for inspiration on YouTube or Vimeo for this kind of things.

Before dealing with complex nodes and array of multiple objects and exciting stuffs like loops, we should really start by building simple node-tree setup that does something to an object.

This is when you are free to experiment yourself by observing NODES and guessing what and how they function with the rest of nodes. Do make mistakes, but find out why and figure out how to resolve it.

In fact, if I think of "storyline" of learning curve for AN, it is going to go like this:
1. Positioning static object(s), eg. in flat map coordinate or spherical
2. Arranging object(s)
3. Animating object
4. Working with multiple objects
4. Other stuffs.

GENERATING SIMPLE MOTION RECIPE

Node Recipes:

  • Time Info (!)
  • Combine/Separate Vector
  • Object Transforms
There is ONE really special value that we can use for animation, and that is TIME, and it is commonly shown as Frames or Subframes when playback is run (Ctrl+A hotkey).

Time at the very basic means we are aware of Start Frame, End Frame, playback length or durations. Later on, you will find out that we can have "multiple timelines" for each object. It's one of biggest driving force of animation.

In AN, time value is accessed via "Time Info" node. When you run the playback or scrub in timeline, the Time value is also changing. Time Info node spits out Frame number value as Floating value (fractional).

So at the very basic, we could in theory plug that single value to control Translate XYZ, Rotate XYZ, and Scale XYZ of Object Transform.


Above, you see I plug a single value output from Time Info node into X of "Combine Vector". Then, I plug the Vector (3 values) into the position of Object Transform node to DRIVE the default "Cube" object in 3D scene.

You may notice that moving object one unit per frame is too big of a step, so we can reduce the speed for example by multiplying the value with 0.1. This results in Time that is 10 times slower (1/10). Below is how I figure it out.

I use Debug node already here. This is a quick way to see the OUTPUT VALUES at any point in the node tree. There are few debug nodes here, we will sure be looking at them time to time.


Now that you are familiar about Time value output, you can try pluggging this into Scale, this time below I plug it into Scale XYZ so it will "grow" the scale of "Cube" overtime.

If the value is the same for all 3 values Vector, you can use "Vector from Value" node, instead of plugging 3 noodles into "Combine Vector" slots.


You can also try plugging the value into Rotate XYZ.


Noticed that you have this automatically created "Vector to Euler" node. And you also have option to use Degree.

In degree, 360 degree is a full rotation. In Euler angle, .... well I do not know, maybe you know. But we can SEE the result in 3D. I use Suzanne the monkey object so I can tell if it hits 360 degree rotation.

NOTE: Later on this Vector business is important to indicate the direction axis of an object, especially when dealing with Matrix. A bit too advanced for now, I supposed.


Knowing that we can use values to control many things using nodes, we need to think of DRIVE and DRIVEN values.

Straight from top of my head, procedural motion can be driven using:
- Generated Values / Numbers
- Other Objects (master and slave)
- F-Curve via keyframing
- Math (with formula or expressions over time)
- Sound > Curve

NODE: VECTOR WIGGLE

Vector Wiggle is an interesting node. When we feed Time Info node (frame) into the Evolution, it will spit out smooth Vector positions over time and can drive an object so it is moving just like insect fly in the air.

I believe this Wiggle is also called 3 x Noise values (XYZ). Unlike Random that gives a random values resulting in a jumpy values between frame, Noise will give values that are closer to each other, meaning smoother motion.

Okey, so far, we know Time and Vector Wiggle can drive the motion of objects. Vector Wiggle itself is a specialized node that is based on Math Formula and Expressions. I might cover and explore this are more in depth. But looking at Math through procedural animation is a lof of fun.

Complex procedural motions can be created using Physics, Dynamics, and perhaps Particle simulations and behaviour animation like used in games. Actually if we get creative, maybe we can already use Blender's dynamics to work together with AN node.

MOTION BY COPYING OTHER MOTION



Above will result of 2 x Suzanne to be always on the left and right side of Cube object, 3 units apart.


MOTION BY F-CURVE

When we hit I to keyframe an object transforms, we are very likely creating minimum of 9 f-curves for translateXYZ, rotationXYZ, and scaleXYZ.

I believe we could "sample" and modify animation curve using AN nodes. I have not yet looked into this, but this could be interesting.


JUMP AHEAD: F-CURVE ANIMATION OFFSET SNAKE MOTION via TEMPLATE

AN add-on gives a bunch of really useful templates to use and to study. Feel free to try them. Personally I found the templates to be pretty complex, however, can be broken down.


When I tried to create this snake motions, I was doing it like below. The differences between above and below is that:

ABOVE: From the template, we are able to create this Master and Slaves very quickly. One object is animated using f-curve, and then all the rest of objects, become slaves clones of another object / same object as the master.

BELOW: Here the node tree is using a simple Loop system that simply delay the motion of clones to follow one master. I am doing it in a way that I understand it.









AN MATH NODES


Reciprocal Number node contains lots of basic Math Formula that you can use for noding. Maybe it should be called Math Formula node? :)

Expression node allows you to more easily type formula and creates your own input variables and plugging your own numbers.


Sine wave + Cosine wave = Circular Motion (translation)



AN TEXT OBJECT

AN add-on seems to be capable of dealing with Blender Text Object quite elegantly. There are few AN nodes that are dealing especially with text/string type of data and output it into Text Object.

In fact, I have a feeling that we can talk and play with Text Object. String type of object is really very interesting. If you know Python scripting a bit, Python is pretty amazing when slicing, combining text, list of text, etc, etc.



You create Blender Text Object and use the eyedropper thing to source the Text Object on Text Object Output node. THEN, you activate that Text Input button thingy and input your own text.


Random Text node generates string of text characters.




Create List node & Get List of Element node

You will get this really often with AN nodes especially when you started to dealing with multiple inputs. You supply some list of data/values and then you pick an element based on "Index".

In Python, let say we have list of text:
mylist = [ "Apple", "Banana", "Papaya", "Durian" ]

mylist[0] => "Apple"
mylist[2] => "Papaya"



String of Text can be totally awesome, I cannot emphasis this more.

Imagine if we supply text like this:

  • 010001000100
  • 010101010101
  • 000100010001

Those text can easily become like audio beats to procedurally control animations!

OTHER RECOMMENDED LANGUAGES

I really do not want to overload you with programming theories, however if you are serious about node and procedural workflow, you may want to also side-learn creative programming languages below that are available and open source.

  • ChucK (audio programming)
  • Processing (creative visual programming, based on Java and Javascript p5.js)
  • Python (Blender scripting language and also language that is used widely in computer graphics and many areas).

You can learn it in tandem, but if too hard, you pick one below while learning tool like Animation Nodes (AN). The idea is to understand the logic and concept of programming and the flow of data, not so much about the language itself.

In this post, I will talk about random stuff that is not necessarily related to Blender, however, it is in line toward my interest in understanding Blender Game Engine (BGE) and Game Programming with Python.

Or at least the concept of interaction between languages and programs and the real-world mechanic.

MANY LANGUAGES => MANY MACHINES

In recent months, I have been dealing with some programming languages:
  • Python
  • Processing
  • ChucK
  • Scratch
I am also experimenting a little bit with the Raspberry Pi computing (Linux OS, small cheap affordable computer, but can be powerful).

I have not touched much of Arduino board yet, but maybe eventually I am heading toward that direction.

-----------------------------------------------------------------------------------------------------
UPDATE 2014.03.17:
I finally did get encounter with Arduino board and I learned that programming for Arduino is similar to Processing, except that we have more direct connection I/O (input and output) with this hardware microcontroller, which is cool!

Thanks to Powerhouse Museum and Thinker1 Arduino board, I am actually learning some basic foundations. James Oliver is the guy to ask about Thinker1, he is a teacher at ThinkSpace and really good at explaining things.

Anyways, I learn that since Arduino speak like Processing, we could use Processing language to load OSC related library, or you could also use the "serial". Serial is kind of the data being passed from hardware that the computer can then listen to. Arduino board like Thinker1 has Potentiometer (knob) and Button INPUT.

So, if it is in Blender, we could use Python that listen to "serial", if we want Arduino board to control whatever we want in Blender. Or, we could use OSC to control the Arduino board (LED, sound, etc).
-----------------------------------------------------------------------------------------------------

Now, one thing cool about Raspberry Pi is its portability (it is also economic). And moreover, inside the small computer, it has built in Python and Scratch program. It is not capable of running Blender yet, because of the system limitation, maybe in the near future?

All those are not directly related to Blender. However, it is about to get a little bit more interesting once one figure out how to bridge and link all of them together.

Imagine:
- Controlling LED light(s) using Blender
- Controlling Robots motion using Blender.
- Home automation using Blender (if you really want to) --- of course, nowadays is more popular for people to control anything using their smartphone touch or voice assistant like SIRI. But nothing can stop us to use Blender Game interface to control the outside world :)

Well, the above example is probably a bit out of reach, but not impossible! Try something easier first:
- Triggering procedural sound in ChucK using Blender.
- Controlling Blender Game Engine objects, using arbitrary controller
- Using Blender simulation to control real world robot and object.

Again, since I am not from programming, computer science or electronic engineering background, all these are new discovery. I have been always curious on how one program can talk to another program, or how one machine can control another machine. So, if you never program before, we are on the same boat!

Do not be afraid with programming.

Saying that, bridging virtual to real world seems to be something that needs to be explored more and it is going to be a lot easier, only if everyone got the access and tools to do so. Very exciting areas to explore but there are some challenges, no doubt!

BABY STEPS, BABY TALKS

I am very new to OSC (Open Sound Controller) and actually to MIDI controller. Kind of heard about them but not until today that I am really using it.

I am really just a baby in this area. In fact, I feel like in the "kindergarten". However, I remember John Maeda said something like this:
"I’d rather be green and growing than ripe and ready to rot"
http://scholarlykitchen.sspnet.org/2009/09/23/john-maeda-and-the-art-of-staying-green-and-growing/

(John Maeda is one of my hero inspiration.)

With OSC setup, we could use it to control not only sound, but passing the data to drive other things. As much as I am excited when little thing works (and failed), this kind of Bridging stuff can be a bit complicated to setup. But not impossible, just need to follow the steps.

This video kind of talk about OSC in easy to understand manner.
https://www.youtube.com/watch?v=jQD1S27f3dU

I really started with Processing, ChucK, and Scratch as a test bed since those programs already have easy way to use the OSC protocol.

So, the first few steps, I manage to do this "TALK" between apps:
1. iPad => MIDI Controller => Processing => visual trigger
2. iPad => MIDI Controller => ChucK => sound trigger
3. iPad => TouchOSC app => Scratch => trigger some animation, action, sound

I don't need to get into details of all those, but basically, it is quite interesting when we are able to TRIGGER ACTION from and within app and external hardware/controller.

Scratch is the easiest to implement and execute. There are 2 versions of Scratch: 1.4 and newer 2.0. I use the older one:
http://scratch.mit.edu/scratch_1.4/

So, I will use both SCRATCH and BLENDER to help us understand this whole OSC business.

This is one of my inspirator: "How BGE and Scratch can inline"
http://www.youtube.com/watch?v=nCFVJYpz_vk

With Blender, I am sure someone out there is already doing some works related to OSC and automation. And since Blender speaks Python, there must be Python library we can use.

For most of these experimentation, I realized how often we still need to be dependent on someone else's code (more experienced coder) and previous research.

I guess this is totally fine, we really do not need to unnecessary re-invent the wheel, as long we give credits back to the coder and understand what is happening to then use it for our own goal and usage. This is indirect collaboration and totally cool.

BRIDGING BGE, PYTHON and OSC

We know that Blender speaks Python 3.3 and BGE (Blender Game Engine) can do real-time and dynamic value changing and triggering things. So... this is exactly the topic and keyword I use when researching using Google. A little bit advanced topic, we need to tackle it step by step.

THE CHALLENGE:
Make Blender to talk to Scratch using Python.
http://wiki.scratch.mit.edu/wiki/Remote_Sensor_Connections

BLENDER PYTHON => OSC => SCRATCH
(not yet BGE, but eventually go that way).

Let's see how this journey actually goes...

1. Scratch bridge via OSC:
Scratch has built in Remote Sensor and this means, as long we can create OSC bridge from external, we can trigger things inside Scratch, easily.
http://www.kasperkamperman.com/blog/scratch-osc-bridge/

I tried using iPad TouchOSC app following the above method and it works. The "Scratch OSC Bridge" program, which is created in Processing (Java) by KasperKamperman is a handy little helper.

2. Scratch can communicate via Python 2 and 3 and OSC (indirect method)
We always need to be aware of the Python Library we use, to make sure the version will work with Blender Python 3.3.

Scratch and Python 2.7
http://wiki.scratch.mit.edu/wiki/Communicating_to_Scratch_via_Python_with_a_GUI

Scratch and Python 3.3 (didn't work as smoothly)

I thought that I could just copy paste and use the Python 3.3 script inside Blender to send message to Scratch. Somehow, it failed.

So, I am using a different Python Library, luckily below works, otherwise I am stucked.

4. Python scripting can help with OSC sending and receiving stuff.
Python is really the ULTIMATE KEY here, when we want to talk to and from Blender to the outside app or external hardware. OSC is also the SECOND KEY. We want to be able to send message to specific ADDRESS and PORT.

Dealga McArdle (Blender Scripting blog master) gave me a really nice hint: Try Python OSC Library for Python 3.3.
https://pypi.python.org/pypi/python-osc#downloads

>> INSTALLING 3RD PARTY EXTERNAL PYTHON PACKAGE AND MODULE
I have probably touched this topic at some point, but just to refresh again. If you want to bring in 3rd party Python Library from outside to be used inside Blender, simply place it here:
C:\Program Files\Blender Foundation\Blender\2.69\python\lib\site-packages

So, remember: site-packages is the folder where you want to put outside Python script.

Restart Blender, and then Blender can then source and import the Python library (module) as needed.
from blah import blah

So, I tried and I manage to make Blender talks to Scratch, receiving OSC Path and Message.

Thanks Dealga for example code, this is the original code (I think Dealga is playing with Pure Data or ChucK)
https://gist.github.com/zeffii/7264092

EXAMPLE CODE: (Blender talk to Scratch to randomly move the cat in X and Y)
import time
import random
from pythonosc import osc_message_builder
from pythonosc import udp_client

tick_duration = 0.1

ip = "127.0.0.1"
port = 8000
client = udp_client.UDPClient(ip, port)
osc_msg = osc_message_builder.OscMessageBuilder

for j in range(50):
    value_a = random.randrange(-240,240)
    value_b = random.randrange(-180,180)
    value_c = 3
    
    message_out_list = [value_a, value_b, value_c]
    
    msg = osc_msg(address = "/BLAH")
    for i in message_out_list:
        msg.add_arg(i)

    print(message_out_list)
    msg = msg.build()
    client.send(msg)
    time.sleep(tick_duration)

print("-" * 50)


SCRATCH CONTROLLING ROBOT...

If Scratch ables to control Robot, Blender can too...
http://www.dexterindustries.com/BrickPi/program-it/scratch/
http://www.dexterindustries.com/BrickPi/

Python...

If there is Python, we can probably control it using Blender Game Engine (BGE).

Something like this:

But how?

TO BE CONTINUED .....

LINKS

Blender and Scratch
http://www.youtube.com/watch?v=nCFVJYpz_vk

Blender BGE Python Tutorial
Kris Occhipinti
http://www.youtube.com/watch?v=g6CjnC1T0lA

http://www.surreal.asturnazari.es/node/178

PureData and Blender: (In French language)
http://wiki.labomedia.org/index.php/Communication_entre_Pure-data_et_Blender_en_OSC

I am currently reading this book titled "Open Shading Language for Blender" by Michel Anders. This book was first mentioned at Blender Nation blog not long ago:
http://www.blendernation.com/2013/10/30/new-book-open-shading-language-for-blender/



Finally.

The very 1st book to talk about OSL in Blender! Yey~! Here it is the first original and fresh book that properly covers OSL! This is actually quite a BIG thing, although somewhat very modest. Just like when Blender goes from 2.49 to 2.5x until today, it was MAJOR, but very MODEST.

I really like that attitude, big kudos to Blender and people like Michel.

So, I got my hand on the book, it only cost under A$10 (after all money conversions) and it worths every dollars. It may be cheaper for you depending on the strength of your currency.
https://www.smashwords.com/books/view/368598

I downloaded the epub format and reading the book on iBooks (iPad).

THE AUTHOR: MICHEL ANDERS
Let's talk about the author a little bit that I knew of (by searching on Google).

This Blender OSL book is the 3rd book that Michel self-published, as mentioned here:
https://www.smashwords.com/profile/view/varkenvarken

Apart from this original OSL book, Michel also has written an active blog on OSL:
http://blenderthings.blogspot.nl

I actually read that blog a lot during my OSL study and exploration. Many shaders over there are pretty complex though!

Michel other blog:
http://michelanders.blogspot.com.au

There is some more personal trivia about the author inside the book, which is kind of nice.

TOPICS COVERED IN THE BOOK
The book started with introduction on why you would learn to write OSL code for shading and texturing.

That question above is definitely something everyone had in mind when they stumbled into something called OSL or Open Shading Language.

Some are probably happy to just use the already provided nodes (which is alright, and can get you quite far in production), while some others get more curious and like to know more about OSL and unlock its huge potential.

From intro topic, the book quickly moves to simple practical OSL shader. It covers a bit about Data types (int, float, string, void, point like data types, array, struct).

Slowly the topics ramp into important topics like: Patterns, Vectors, Normals.

I quite like one chapter titled "Mapping vectors" which covers multiplication (Scale) and Rotation of vectors. This is very important and gladly he answered this big question I had for a very long time.

From then on, Michel goes into specific simple procedural textures and shaders like the basic Checker texture, Polka Dots, before soon we get to more exotic and interesting shaders: Leopard shader, Diamondplate, etc. I have to admit that some shaders are pretty sophisticated.

Michel will give you "warning" whenever we are dealing with Math inside the shader. Math is something that often scares the artist, but we should not be because computer will do the complex calculation based on certain formula, we just need to set it up. So that is the idea that I still tell myself every now and then.

In between shader examples, he will go through and break down the Math behind it. There are thing like Symetry operations concept that explain how we can create a complex texture by mirroring it.

There is one chapter that talks about Splatter shader, where we could use our own PNG texture and randomly stamp the images, here is an example usage using my own coin.png texture (it has Alpha):



With the book, he also provided the working example files, the OSL files and Blender files. Over 80+ shaders given for you to use and to study.

MY VERDICT
I have to say that I am very happy to get hand on this book. It helps me a lot to put together my OSL knowledge so far in place. If I have time to revisit my older post on OSL, I could make the code more efficient followint the example structure of Shader shown on the book.

It is very inspiring for me. Maybe one day I write and publish my own book as well.

Many other books that talk about procedural textures (mostly for Renderman) goes really complex, too fast. But this one slowly explains what important and covers the foundation to help you move.

Similarly to myself, I think Michel put big emphasis on the procedural texture design and creations. OSL can actually do a bit more on top of procedural texture creations, however the most fun bit is the texture creation.

This book is MUST HAVE book in your library for any Shader Artists who has interest in learning OSL or shader writing in general.

MATTER OF CODING AND PROGRAMMING
Again, I have to give encouragement for "artist" who never write code before, since writing OSL shaders involves creating functions and goes further with Computer Graphics theory.

Programming ... is not hard, it just takes time to learn.  I was afraid of any coding few years back, which I wish I had not been.

Just like I used to have fear of cooking and used to order foods from restaurants or just cook instant noodles in the past, well... apparently cooking from raw ingredients is not that hard.

Surely, we cannot create amazingly delicious foods at the beginning. But by time and with time, we eventually can.

Watch some movies like these for inspirations (fairly off-topic, but to make a point):
- Jiro: Dream of Sushi
- Taishoken: God of Ramen

And you will figure out soon that many of "amazing works" out there are simply taking some time to create and every skill takes dedication and passion (and obsession) to master.

I don't know what path of programming you will go through from ZERO to HERO, but I am sure you will find a way to overcome any obstacle if you continue not to give up. Remember you can always ask and there are always some nice people out there will answer when you are stuck.

Many of solutions are out there. In fact, many of tools to help you are out there as well.

Processing Programming Language
Start here:
http://www.imaginary-institute.com/blog/author/andrew/
http://funprogramming.org/
But also read some great books out there on Processing.

ChucK Music Programming -> NEW!
https://www.coursera.org/course/chuck101
http://chuck.cs.princeton.edu

There is also Pure Data, Super Collider, and Max (node based).

DESIGN BY NUMBERS by John Maeda
John Maeda's book DBN and tool to learn visual programming is a must read and explore.

Python Programming
http://learnpythonthehardway.org
And many more sources on Python. Remember that inside Blender, we already have Python to play with on any computer at any time. If you use Mac or Linux operating system, you already have Python. Even Raspberry Pi computer has Python!

There is a joy in continuosly learning and discovering, and if you are in Computer Graphics, never stop learning.

OTHER STUFFS
Crazy WebGL Mario at Shader Toy:
https://www.shadertoy.com/view/Msj3zD


Simple Brick OSL port of RSL Brick Texture on Suzanne

With some self-courage, I am attempting to write an introduction post on OSL, to make more sense of Open Shading Language (OSL) that has been implemented inside Blender for over a year today.

I know it myself that this is not going to be easy, but somewhat I have big interest in this area and some of you are too.

I found shader writing to be really abstract, just like learning to read and write a program or when thinking of high level Math. Very elegant and exotic area. None of them makes sense at first. Even when someone attempting to explain it to you, it takes time until you get it or ... maybe you will never quite get it, unless, you push yourself to actually write the code and slowly see what happens.

Although Shader Writing may seems hard and complicated, there is a joy in it and guaranteed a big discovery to be found. I personally feel that shader writing and programming are very free-ing, just like drawing and sketching. Kind of meditative in the way.

In shader writing, we are able to define our own rules and parameters, we can be experimental (highly recommended to do so), and we may get outcome that sometimes accidental, but mostly the way we want it.

Shader Writing is probably not much different than trying to control Particles and Volume with Force.

I advice you to look around first for some available materials that talk about OSL. They are around, although things are all over the place. You will definitely find some simple OSL ... and then big gap that show you complex OSL codes.

Start from here:
http://www.openshading.com/

I think Dingto of Blender developer/artist is one person you need to channel your brain into when it comes to Blender Cycles and OSL implementation.

Once again, like a good absorbing sponge, I will try to absorb some wealth of information from other blogs and forums, and try to restructure and filter the contents and write it down here.

Hopefully, you can get something from this. Have a believe that by writing the unknown, one will learn something along the way.

NOTE: I promise that I am going to write down the sources of every OSL codes that I collects and rewrite in here, with some additional notes of my own. All credits of OSL source belong to the person posting it at the forum.

This post will just be a basic of OSL. Probably at the beginning, it is quite an achievement to create Sine Curve. Maybe some day, we can create fancy screensaver Shader ala MacOS or maybe creating all sort of PATTERNS like Ukrainian patterns, Batik, etc, etc.

Without further a due, let's get started.

WHAT IS OSL?

In my own word:
OSL is another written shading languages just like RSL (Renderman Shading Language), GLSL, etc .... basically a collection of functions and parameter values to describe how mesh surface (pixel) should look when rendered.

OSL is dependant on Closure for light --> I might not be 100% here correct, but anyways, for now, just think if you want Diffuse, Glass, Metalic look, you simply assign and pass to available Closure. You could write your own Closure, but that is an advanced OSL area.

Read more about OSL here, find out where it is originated (Sony Picture Imageworks):
https://github.com/imageworks/OpenShadingLanguage

Let's create an analogy, imagine a modern photography + post-processing today that is using Smartphone + endless Apps.. there are SO MANY filters available that enable smartphone users to capture an image and post-process it in realtime/not so realtime.

OSL allows that kind of ability, giving user power to write and code a shader from scratch or mix and match it the way you like.

For general users, it is totally fine to just use the existing Nodes in Cycles and you probably never have to write or code in OSL. There are plenty already, and you can create nice shaders. There is Uber Shader in Cycles for example (that can certainly be re-written as OSL shader).

Node network creation of Shader is fine, but the problem with visual programming using nodes is that at some point, it gets really complex that actually things will be better written as code. This is when Shader Writing like OSL may come in handy.

You can actually translate any Blender Cycles Node network and combine it into a single OSL Shader. It is not unlike collapsing a complex Blender Cycles network into "easy to use node". More or less the same in that context, simplifying a complex network of nodes into a single node with INPUT(s) and OUTPUT(s).

However, OSL can do a lot more:

Quip + Quipcam:
http://vadrouillegraphique.blogspot.fr/2013/06/quip-and-quipcam-fast-fx-shaders.html

OSL Interior Mapping:
http://fbbdev.wordpress.com/2012/10/12/cycles-osl-interior-shader/

OSL goes further at low level, the unknown area, the complexity.

Note: OSL is also a language used by Arnold, another good commercial rendering engine, I heard.

WHAT IS MY BACKGROUND IN SHADER WRITING?

Not much, actually *cough*.

OSL is my first time attempt to do shader writing seriously. So, I am sorry if I am not really an expert. Being really honest, I am probably as newbie in shader writing as many of you. Experts in OSL may laugh at what I wrote.

In the past, I used to be very into Maya's Hypershade and connecting nodes to create Texture and Shader. I still am, although not as often --- unless required. I like some of Maya procedural shader nodes. Not long ago, Maya got something called Substance node, which is pretty handy node that takes a pre-package Substance materials:
http://www.allegorithmic.com/products/substance-designer

The Substance workflow is kind of nice allowing streamlined procedural creation and also baking textures into Diffuse Map, Specular Map, Normal Map, and so on.

Maya also has a nice Pixar Renderman (PRMan) integration at some point, that allows user to use Renderman Shader using a node.

Few years ago, I actually tried to learn RSL (Renderman Shading Language)... I did read some books about RSL and flicked through some of them. The basics, I sort of understand, but it gets seriously complicated and the problem is the available materials are too hard to follow for me at the time.

Next, I am also exploring some VEX shading nodes in Houdini Mantra. Houdini has quite a powerful render engine and complex shader network creations. Blender renderer Cycles is slowly started to look like Houdini Mantra. Especially with OSL being developed.
http://www.tokeru.com/t/bin/view/Maya/MayaToHoudini

And I also studied some Processing language. This somewhat helps in visualizing code that creates Texture.

I have not much experimenting with Blender Cycles Node Networking.

All those above actually helps me to get where I am now: Writing OSL code in Blender.

Maybe one day I get back to RSL again when required. However right at this moment, I am happy to be able to get into OSL Shader Writing in Blender, on any computer I could find whether I am at Library or on friend's computer. All we need is a computer and Internet and Blender.

The advantage of this Blender environment is that we are all learning it together and this great learning tool is available for everyone and can be used in production right away.

I personally think there is a huge gap between:
THE BASIC ----> THE VERY COMPLEX OF THINGS.

However, nothing should stop you taking the first step.

NOTE: Do not believe everything I wrote in here, I am trying to figure out a lot of thing about OSL magic. Maybe you will figure it out yourself ;)

BLENDER SETUP FOR OSL

In order to start using OSL, you need to set Blender environment.

1. Set Render Engine to Cycles.

2. Enable OSL.
OSL only works in CPU mode at the moment.

3. Set the Layout
You can arrange the layout as you like, but I like to use the Compositing Layout and modify it myself like below:

4. Use Script Node (the PyNode in Blender)

Everytime you point the Script node into the path of OSL Shader, you will "compile" the OSL Shader. It turns bunch of Text codes into a single useful NODE with INPUT and OUTPUT slots.

5. Name it.
I recommend that you always name your OSL like this: *.osl inside the Text Editor. Doing this, you let Blender know what you are writing and you have OSL highlighting and also special OSL update button:

6. You want to always see the changes you made with OSL code (everytime you click on Script Node Update), so you need to enable Texture Render real time thing in Blender Cycles: Viewport Shading - Rendered.

You can certainly COPY and PASTE OSL code examples below to see the resulting Texture.

However, I want you to retype every single code below so you can start to see the PATTERN and understand the SYNTAX and make a lot of mistakes and fixes the mistakes.

You need to be able to write the code from top of your head, then can eventually start changing and modifying the code for your own need.

THE BASICS STRUCTURE OF OSL

#include "stdosl.h"

shader NAME_OF_SHADER
(
// HEADER_DECLARATION_OF_INPUT_VARIABLES
varType varName1 = value, 
varType varName2 = value, 
varType varName3 = value, 
output color Col = (0.8)

)

{
// BODY, FUNCTIONS

Col = .... ;

}

An Empty OSL Shader looks like this: (one of OSL templates provided with Blender)

shader name()
{

}

This OSL Shader template just like a template for FUNCTION in programming language, right?

A good idea is to start with simple functions, see the pattern and get really familiar with it, before going to complex OSL. Use a flat plane mesh to check the shadings, probably work in 2D first.

At this moment, I think I will just focus on OSL Shader TEXTURE creation. Not so much on other complex stuffs that OSL can do. I am happy to be able to

Let's do a step by step exploration of OSL from the easiest OSL Shader Texture we could create.

THE INVISIBLES: INTERNAL AND GLOBAL VARIABLES

“Use the Force, Luke” - Yoda.

NOTE: I will start to use some Star Wars and The Matrix analogy and quotes here to make OSL makes more sense.

There are some variables in OSL that is not visible, but they are there. We must remember that we cannot really change what is already there in nature, but can use them and drive them to create and see the FORCE.

Some of these "INVISIBLES" we will use today:

Point Surface (P) = positions of pixel in XYZ, which as you can see later we can separate into X, Y, Z by accessing P[0], P[1], and P[2].

Normal (N) = this is Object Surface attribute that is normally perpendicular to the surface, this is also some kind of Vector type of 3 values.

u and v

OSL Specs from Sony Picture Imagesworks is a handy documentation book.

OSL: Color

shader simpleColor(
    color myColor = color(1,0,0),
    output color Col_Out = color(0.6)
)

{

}

(Above incomplete OSL Shader will compile and we can see INPUTS and OUTPUTS port, but it does nothing much).

You see above how I am defining the "argument variables" for the Shader function. I have 2 variables: myColor and Col_Out.

Those variables were defined as variable type of Color. Those variables need to be assigned a default value. The function color(R,G,B) or color(Greyscale) is required for variable of type Color.

You also notice that I describe Col_Out variable as OUTPUT. This is required. Important: every Output Variables needs default initializer. You can have multiple Outputs.

Ok, now we have minimum INPUT and OUTPUT.

This OSL Shader, if we use it now, won't be much of usage, but it is already working. Color value of 0.6 greyscale value that will be used as Color output when we plug and pass the value into a Closure (Diffuse BSDF node).



The Shader is incomplete though, because we did not tell any connection between "myColor" and the actual output of "Col_Out". I assign a Red color (1,0,0) to myColor, but it is not used, yet.

Let's do that now.

shader simpleColor(
    color myColor = color(1,0,0),
    output color Col_Out = color(0.6)

)

{
    Col_Out = myColor;
}


That is the simplest shader. You made it so far and you did a good job.

OUTPUT CLOSURE

From the above setup, we pass on the OSL Shader (Texture) into a Diffuse BSDF Closure.

We could, actually integrate the Closure into the OSL Shader itself, like so:

shader simpleColor(
    color myColor = color(1,0,0),
    output color Col_Out = color(0.6),
    output closure color MyBSDF = diffuse(N)

)

{
    Col_Out = myColor;
    normal Nn = normalize(N);
    MyBSDF = Col_Out * diffuse(Nn);
}


There are many other available Closures that you can use right away:
...

OSL: Mixer 2 Colors > 1 Color

After we create the simple Color Shader, next we can re-create Mix node using OSL. We leave the Closure for now and just focusing on Texture Color.

NOTE: However, writing code that generate procedural Texture is not easy either, but more visual.

shader mixer(
    
    color ValueA = color(1,0,0),
    color ValueB = color(0,0,1),
    float Fac = 0.5,
    output color Color_Out = color(0.8)
    
)

{
    Color_Out = mix(ValueA, ValueB, Fac);
}




Another simple shader that mixes 2 Color (ValueA and ValueB) into 1 Color based on Fac value.

Next we will use P (point) attribute as mixing factor, which will in fact create a Gradient.

OSL: Gradient X, Y, Z

Gradient or ramp blending can be created by using the floating value of Point position in either of 3 axis (x/y/z). This is the first time we will use the invisibles Global Variable: Point Positions (P). They will start to create THE FORCE.

shader gradient(
    point Vector = P,
    color ValueA = color(1,0,0),
    color ValueB = color(0,0,1),
    //float Fac = 0.5,
    output color Color_Out = color(0.8)
    
)

{
    float x = P[0];
    float y = P[1];
    float z = P[2]; 

    Color_Out = mix(ValueA, ValueB, x);
}

NOTE: I did something that slightly wrong above, where I am assigning the P (position attribute) inside the functions, while I also already defining Vector attribute that has P values. To be more correct, I should have done:

float x = Vector[0];
float y = Vector[1];
float z = Vector[2];

Here, we are basically separating Vector 3 Values of Point into 3 Floats. At this moment, I have unconnected pipe between the INPUT Vector which is assigned P by default and recreating internal values.

Based on Point X

Above, based on Pixel Point Position, we create OSL Texture with gradient that spans across 2 value. Instead of using x, we can also use y or z.

Based on Point Y

Based on Point Z
Let's take another brave step by assigning the Point position into sin() function. We can think sin() function as one of the Invisible Forces. We could later starting to create our own Forces.

OSL: Stripes Gradient Sine X, Y, Z

Here, you could already experiment on using Math function like sin(), cos().

shader smooth_stripes(
    point Vector = P,
    color ValueA = color(1,0,0),
    color ValueB = color(0,0,1),
    //float Fac = 0.5,
    output color Color_Out = color(0.8)
    
)

{
    float x = P[0];
    float y = P[1];
    float z = P[2]; 
    
    Color_Out = mix(ValueA, ValueB, sin(x));
}


This is one way you could create Stripe Texture. There are actually many ways to achieve this.

With this method, you will notice that we are getting "Smooth" Stripes. The reason being: function like Sine gives a Smooth Wave Curve that smoothly goes between the 2 Colors back and forth.

What if we want a stripe without smoothing? We can use function floor().

shader stripes(
    point Vector = P,
    color ValueA = color(1,0,0),
    color ValueB = color(0,0,1),
    //float Fac = 0.5,
    output color Color_Out = color(0.8)
 
)

{
    float x = P[0];
    float y = P[1];
    float z = P[2];
 
    Color_Out = mix(ValueA, ValueB, floor(sin(x))+1); // I give an offset value of 1 here
}


Other than using floor() function, you may see in other OSL that multiplying it with a constant will turn Smooth force into a Hard-Edge force.

OSL: Single Line

Before we go too far with "repeating texture", we take a few steps back to create just a single line based on the gradient/ramp.

This is quite important for our understanding.

Still based on above OSL code, we can create a line using abs() function which means instead of getting gradient/ramp, we are getting something that is more like a parabolic curve (somewhere in there we have -1 to 1 value, although the lines goes into infinity).

Here, you will see how I am starting to create "The Force". This is probably the first interesting thing you see in OSL. We could call it formula or function, or any other name, but I think I will call it force.

shader line(
    point Vector = P,
    color ValueA = color(1,0,0),
    color ValueB = color(0,0,1),
    //float Fac = 0.5,
    output color Color_Out = color(0.8)
    
)

{
    float x = P[0];
    float y = P[1];
    float z = P[2]; 
    
    float FORCE = 1/abs(x);
    
    Color_Out = mix(ValueA, ValueB, FORCE);
}



You can INVERT the line if you use abs() function on the FORCE. For above, instead of BLUE line, we can have RED line.


OSL: Better Line

I need to add this here, this is probably a better function for LINE.

/*
    SOURCE: http://nccastaff.bournemouth.ac.uk/jmacey/Renderman/ 
*/

shader Lines (
    color LineColor = color(1,0,0),
    color MixColor = color(1,1,1),
    float fuzz = 0.025,
    float LineSize = 0.1,
    float Orient = 0,
    float offset = 0.5,
    output color Col_Out = color(0.2)
)

{
    color Ct;
    float s = P[0];
    float t = P[1];
    
    // we care about texturing only
    float inTop;
    float dist;
    
    if(Orient==0)
        dist = abs(t-offset);
    else
        dist = abs(s-offset);
    
    float inLine;
    
    inTop = 1 - smoothstep(LineSize/2.0 - fuzz, LineSize/2.0+fuzz, dist);
    
    Ct = mix(MixColor, LineColor, inTop);
    Col_Out = Ct;
    
}

OSL: Diagonal Line

Adding the absolute FORCE of X and Y and we get... diagonal force.

shader line(
    point Vector = P,
    color ValueA = color(1,0,0),
    color ValueB = color(0,0,1),
    //float Fac = 0.5,
    output color Color_Out = color(0.8)
    
)

{
    float x = P[0];
    float y = P[1];
    float z = P[2]; 
    
    float FORCE = abs(x + y);
    
    Color_Out = mix(ValueA, ValueB, FORCE);
}


OSL: Single Line Sine Wave


# include "stdosl.h"

shader wave_line (
    float amplitude = 2.0,
    float offset = 0.0,
    point Vector = P,
    color colorA = color(1,0,0),
    output color Col_Out = color(0.8)
    
)

{

    float x = P[0];
    float y = P[1];
    Col_Out = 1/abs(x + sin(y + offset) * amplitude);

}



LIMITING THE FORCE

“There is No Spoon” - Neo.

I am not quite sure what is happening here, but one day I decided to use clamp() function and the resulting is kind of TRIMMING the force back into invisibility.

# include "stdosl.h"

shader wave_line_clamped (
    float amplitude = 2.0,
    float offset = 0.0,
    point Vector = P,
    color colorA = color(1,0,0),
    output color Col_Out = color(0.8)
    
)

{

    float x = P[0];
    float y = P[1];
    float FORCE = x + sin(y + offset) * amplitude;
    float CLAMPER = clamp (FORCE, 0, 1);
    float INVERT = 1/abs(CLAMPER);
    Col_Out = INVERT;

}


Another clamping stuff, see how we can BEND the SPOON(or FORCE), like in the Matrix.

# include "stdosl.h"

shader wave_line_clamped (
    float amplitude = 2.0,
    float offset = 0.0,
    point Vector = P,
    color colorA = color(1,0,0),
    output color Col_Out = color(0.8)
    
)

{

    float x = P[0];
    float y = clamp (P[1], -5,5);
    float FORCE = x + sin(y + offset) * amplitude;
    float INVERT = 1/abs(FORCE);
    Col_Out = INVERT;

}


# include "stdosl.h"

shader wave_line (
    float amplitude = 2.0,
    float offset = 0.0,
    point Vector = P,
    color colorA = color(1,0,0),
    output color Col_Out = color(0.8)
    
)

{

    float x = P[0];
    float y = P[1];
    float FORCE = x + sin(y + offset) * amplitude;
    float CLAMPER = clamp(FORCE,-1, 1);
    float INVERT = 1/abs(CLAMPER);
    Col_Out = INVERT;

}


# include "stdosl.h"

shader wave_line (
    float amplitude = 2.0,
    float offset = 0.0,
    point Vector = P,
    color colorA = color(1,0,0),
    output color Col_Out = color(0.8)
 
)

{

    float x = P[0];
    float y = P[1];
    float FORCE = x + sin(y + offset) * amplitude;
    float CLAMPER = smoothstep(FORCE,-1, 1);
    float INVERT = 1/abs(CLAMPER);
    Col_Out = INVERT;

}


# include "stdosl.h"

shader wave_line (
    float amplitude = 2.0,
    float offset = 0.0,
    point Vector = P,
    color colorA = color(1,0,0),
    output color Col_Out = color(0.8)
    
)

{

    float x = P[0];
    float y = P[1];
    float FORCE = x + sin(y + offset) * amplitude;
    float CLAMPER = noise(FORCE,y);
    float INVERT = 1/abs(CLAMPER);
    Col_Out = INVERT;

}


shader line(
    point Vector = P,
    color ValueA = color(1,0,0),
    color ValueB = color(0,0,1),
    //float Fac = 0.5,
    output color Color_Out = color(0.8)
    
)

{
    float x = P[0];
    float y = P[1];
    float z = P[2]; 
    
    y = mod(cos(abs(y)), 2);
    
    float FORCE = abs( x + y * 2 );
    
    Color_Out = mix(ValueA, ValueB, FORCE);
}


shader line(
    point Vector = P,
    color ValueA = color(1,0,0),
    color ValueB = color(0,0,1),
    //float Fac = 0.5,
    output color Color_Out = color(0.8)
 
)

{
    float x = P[0];
    float y = P[1];
    float z = P[2];
 
    y = abs(sin(y));
 
    float FORCE = abs( x + y * 2 );
 
    Color_Out = mix(ValueA, ValueB, FORCE);
}


OSL: MODULATION STRIPES

We can add and multiple forces.

Here is another way of getting a stripes...

# include "stdosl.h"

shader mutiple_lines(
    point Vector = P,
    color ValueA = color(1,0,0),
    color ValueB = color(0,0,1),
    float Fac = 0.5,
    output color Color_Out = color(0.8)
    
)

{
    float x = P[0];
    float y = P[1];
    float z = P[2];
    float stripeX = mod(abs(sin(x)), 1);
    float stripeY = mod(abs(sin(y)), 1);
    float stripeZ = mod(abs(sin(z)), 1);
    float FORCE = stripeX * stripeY * stripeZ;
    Color_Out = mix(ValueA, ValueB, 1/FORCE);
}


You see how above, I am "multiplying" values of Stripes in X, Y, Z and ended up with a combination. Multiply, Add, etc, works similar to when you are doing Layering and Blending of Texture.

Or, maybe we can do it like below for Stripes along X only:

shader gradient(
    int Stripe = 1,
    point Vector = P,
    color ValueA = color(1,0,0),
    color ValueB = color(0,0,1),
    float Fac = 0.5,
    output color Color_Out = color(0.8)
)

{
    float x = P[0];
    float y = P[1];
    float z = P[2];
    float stripeX = mod(abs(sin(x * Stripe * 0.1)), 1);
    //float stripeY = mod(abs(sin(y)), 1);
    //float stripeZ = mod(abs(sin(z)), 1);
    float FORCE = stripeX;
    Color_Out = mix(ValueA, ValueB, 1/FORCE);
}


UPDATE 20130802: More on MODULO
I am reading my own writing and testing some of the codes. Probably I need to clean up some of the OSL writing so that it makes more sense. I still do not quite get the MODULO mod() function. It supposed to repeat, but does not always work as I expected it. Lots of Math functions are a little bit strange. So, let's explore how MODULO functions...

1. Starting with Gradient/Ramp/Blend based on X.

shader stripes(
    color Color_A = color(1,0,0),
    color Color_B = color(0,0,1),
    float Fac = 0.5,
    point Vector = P,
    output color Color_Out = color(0.8)

)

{
   
    float x = Vector[0];
    float y = Vector[1];
    Color_Out = mix(Color_A, Color_B, Fac + x);
}


Writing the code like above allowing you to add Noise or other node that will Fac into the gradient.

2. Inserting Modulo.
shader stripes(
    color Color_A = color(1,0,0),
    color Color_B = color(0,0,1),
    float Fac = 0.5,
    point Vector = P,
    output color Color_Out = color(0.8)

)

{
   
    float x = Vector[0];
    float y = Vector[1];
   
    float FORCE = mod(x,1);
   
    Color_Out = mix(Color_A, Color_B, Fac + FORCE);
}


Thing does repeat, although I cheated and scale the original object. Probably we need to insert another Variable to control the Scaling.

I also found that the modulation is not quite right.


3. Mixing Sin/Cos with Modulo
shader stripes(
    color Color_A = color(1,0,0),
    color Color_B = color(0,0,1),
    float Fac = 0.5,
    point Vector = P,
    output color Color_Out = color(0.8)

)

{
   
    float x = Vector[0];
    float y = Vector[1];
   
    x = sin(y);
    float FORCE = mod(x, 0);
   
    Color_Out = mix(Color_A, Color_B, Fac + FORCE);
}



4. More exploration.

shader stripes(
    color Color_A = color(1,0,0),
    color Color_B = color(0,0,1),
    float Fac = 0.5,
    point Vector = P,
    output color Color_Out = color(0.8)

)

{
    
    float x = Vector[0];
    float y = Vector[1];
    
    x = sin(x) + sin(y);
    float FORCE = mod(x, 0);
    
    Color_Out = mix(Color_A, Color_B, Fac + FORCE);
}


5. Adding the Z into calculation of the FORCE.

shader stripes(
    color Color_A = color(1,0,0),
    color Color_B = color(0,0,1),
    float Fac = 0.5,
    point Vector = P,
    output color Color_Out = color(0.8)

)

{
   
    float x = Vector[0];
    float y = Vector[1];
    float z = Vector[2];
   
    x = sin(x) + cos(y) + cos(z);
    float FORCE = mod(x, 0);
   
    Color_Out = mix(Color_A, Color_B, Fac + FORCE);
}


This is one of those happy surprise, I was not expecting the texture to work like this.

6. Further more... this time I increase the Modulo and also I use Blender built in Noise and ColorRamp function to further refine the texture.
shader stripes(
    color Color_A = color(1,0,0),
    color Color_B = color(0,0,1),
    float Fac = 0.5,
    point Vector = P,
    output color Color_Out = color(0.8)

)

{
   
    float x = Vector[0];
    float y = Vector[1];
    float z = Vector[2];
   
    x = sin(x) + cos(y) + cos(z);
    float FORCE = mod(x, 1);
   
    Color_Out = mix(Color_A, Color_B, Fac + FORCE);
}



This started to resemble an interesting Tile Design that we may find inside Islamic Mosques.

Although of course this Texture Tile is rather simple, however I am quite happy with the outcome so far. Maybe you could come up with more intricate texture just based on the simple knowledge.

I have plenty of questions such as:

  • How to Tile properly?
  • How to Rotate and Animate the texture? Is it just via Offset or more?
  • How to create Flower or Star pattern?
  • What is a good efficient Shader calculation? 

Dark Side Suzanne

I reckoned, it is a good idea to explore some of Islamic Art at some point, which is really originated from clever Mathematical formulas. Maybe my future post.

That could make a nice topic or even a book that is exploring the Islamic Art and Computer Graphics. Or maybe Buddhist Art and Computer Graphics, or Christians and CG. I don't know. I am pretty universal regarding religions and beliefs...

Anyways, basically all kinds of Patterns from around the world: Oriental, Chinese, Japanese, Korean, Thai, Indonesian, Egyptians, Persian, Ukrainian etc.

shader stripes(
    color Color_A = color(1,0,0),
    color Color_B = color(0,0,1),
    float Fac = 0.5,
    point Vector = P,
    output color Color_Out = color(0.8)

)

{
    
    float x = Vector[0];
    float y = Vector[1];
    float z = Vector[2];
    
    x = sin(x) + cos(y) * 0.5 ;
    float FORCE = mod(x, 0);
    
    Color_Out = mix(Color_A, Color_B, Fac + FORCE);
}

Katamari Ball?

shader stripes(
    color Color_A = color(1,0,0),
    color Color_B = color(0,0,1),
    float Stripes = 5.0,
    float Fac = 0.5,
    point Vector = P,
    output color Color_Out = color(0.8)

)

{
    
    float x = Vector[0];
    float y = Vector[1];
    float z = Vector[2];
    
    x = sin(y * Stripes ) + cos(y * Stripes) ;
    float FORCE = x;
    
    Color_Out = mix(Color_A, Color_B, Fac + FORCE);
}




OSL: Circle, based on Dingto's YIN YANG OSL Shader

“Be Water, my Friend.” - Bruce Lee.

I think Dingto's YIN YANG is probably one of the most beautiful interesting example. Google for it to get the original OSL.

I broke down his Yin Yang OSL into just a Circle. I think we can study further the Yin Yang OSL to understand some more.

Dingto's Yin Yang OSL, keep looking at this shader with sense of wonder...

However, for now, something like below create a solid Circle.

float circle(float x, float y) 
{
    float nx = x;
    float ny = y;
    x = nx*cos(0.2) - ny*sin(0.2);
    y = nx*sin(0.2) + ny*cos(0.2);
    float h = x*x + y*y;
    float b = h - 100;
    return b;
}

shader gradient(
    point Vector = P,
    color ValueA = color(1,0,0),
    color ValueB = color(0,0,1),
    //float Fac = 0.5,
    output color Color_Out = color(0.8)
    
)

{
    float x = P[0];
    float y = P[1];
    float z = P[2]; 
    
    float XXX = circle(x,y);
    
    Color_Out = mix(ValueA, ValueB, XXX) ;
}


OSL: Dots (with Size and OffsetX, OffsetY)

float graph2d(float x, float y, float size) {
   float g = (x * x + y * y) / size;
   return g;
}


shader dot(
    point Vector = P,
    color ValueA = color(1,0,0),
    color ValueB = color(0,0,1),
    float offsetX = 0.0,
    float offsetY = 0.0,
    float size = 10.0,
    output color Color_Out = color(0.8)
    
)

{

    float x = P[0];
    float y = P[1];
    float z = P[2]; 
    
    x += offsetX;
    y += offsetY;
    
    float FORCE = graph2d(x,y, size);
    
    
    Color_Out = mix(ValueA, ValueB, FORCE);
}


float graph2d(float x, float y, float size) {
   float g = (x * x + y * y) / size;
   return g;
}


shader dot(
    point Vector = P,
    color ValueA = color(1,0,0),
    color ValueB = color(0,0,1),
    float offsetX = 0.0,
    float offsetY = 0.0,
    float size = 10.0,
    output color Color_Out = color(0.8)
    
)

{

    float x = P[0];
    float y = P[1];
    float z = P[2]; 
    
    x += offsetX;
    y += offsetY;
    
    float FORCE = graph2d(x,y, size);
    
    
    Color_Out = mix(ValueA, ValueB, 1/FORCE);
}

I think I did it wrong with this, but I quite like the result.


OSL: Pie / Watermelon

Based on Gottfried Hofmann's Pie OSL.
http://www.blenderartists.org/forum/showthread.php?270332-OSL-Goodness

#include "stdosl.h"

color pie(point p, int Divides, float Angle, float Noise)
{
    float angle_new;
    angle_new = atan2(p[0],p[1]) + Angle*3.1415926/180.0;
    return color(0.5 - 0.5*sin(angle_new * Divides - Noise - 0.5));
}

shader pie(
    int Divides = 2,
    float Angle = 5.0,
    float Noise = 0.0,
    point Vector = P,
    output color Color = color(0.0, 0.0, 0.0))
{
    Color = pie(Vector, Divides, Angle, Noise);
}


OSL: Volley Ball


Kind of similar to above Pie OSL, but somewhat different.

# include "stdosl.h"

shader volleyBall (
    float amplitude = 2.0,
    float offset = 0.0,
    float frequency = 1.0,
    point Vector = P,
    float Angle = 0.0,
    output color Col_Out = color(0.8)
    
)

{

    float x = P[0];
    float y = P[1];
    float z = P[2];
    
    float angle_intern = atan2(x, y) + Angle * 3.1415926/180.0;
    float formula = sin(frequency*angle_intern + offset) * amplitude + cos(frequency*angle_intern+ offset) * amplitude;
    Col_Out = 1/abs(formula);

}


OSL: Clockwise Gradient


shader clockwise(
    point Vector = P,
    color ValueA = color(1,0,0),
    color ValueB = color(0,0,1),
    float Fac = 0.5,
    output color Color_Out = color(0.8)
    
)

{
    float x = P[0];
    float y = P[1];
    float z = P[2];
    float value = smoothstep(x, y, 1);
    Color_Out = mix(ValueA, ValueB, value);
}


OSL: Strength of Line

“The Force is strong with this one” - Darth Vader.

Here, we can see how we can control the strength of the Force using our own Constant Variables.

# include "stdosl.h"

shader lineForce (
    int Stripes = 5,
    point Pos = P,
    color MyColor = color(0.2,0.3,1.0),
    float Thickness = 1.0,
    float Glow = 1.0,
    output color Col = (0.8)  // or Out
)
{
    float t;
    float posX = Pos[0];
    float posY = Pos[1];
    t = Thickness/abs(posX) / Glow; // inverted absolute of PositionX
    

    for (int i=0; i < Stripes; i++){
        posY += i * 5;
        t *= 1/abs(posX);
    }

    //t *= posX - 0.5;


    Col = t * MyColor; // assign it to the output slot
}

OSL: Spiral

Work in progress....

OSL: Multiple Circles

Work in progress....


OSL: Circle With Border / The Ring

http://bencrowder.net/blog/2013/05/open-shading-language-in-blender/

Ben's example of Circle With Border Texture OSL Shader is actually quite interesting. Here we can see how he uses Distance Field (or Force) to create Ring. This is probably some kind of Shader you can use to create poster of Japanese horror Movie "The Ring".



#include "stdosl.h"

// SOURCE: http://bencrowder.net/blog/2013/05/open-shading-language-in-blender/

shader ring(
    float intensity = 0.1,
    float border = 0.4,
    float radius = 1.0,
    output color Out = color(0.8, 0.6, 0.4)
)

{

    point pt = P;     // The point that gets passed in
    float x = pt[0];  // OSL uses array indices for x,y
    float y = pt[1];

    // Get the distance from (0, 0) to the point we're processing and then
    // subtract from the radius to get the distance from the circle to the point
    float dist = radius - sqrt(x * x + y * y);
    
    // If dist < 0, point is outside the circle
    // If dist > border, point is inside the circle
    // If dist <= border && dist > 0, point is on the circle
    float t = 0;
    if (dist > border) {
        t = 1;
    } else if (dist > 0) {
        t = dist / border;
    }
    
    // Add the intensity control and make sure the value >= 0
    float final = abs(intensity / t);
    
    // Create the output color (and drop the red channel by half)
    color c = color(final / 2, final, final);
    
    
    Out = c;
}

The way the texture shader is written above is very interesting allowing user to plug other node into the INPUT attribute of the OSL: Ring and get different result immediately. This is kind of thing we should think when we write our own OSL node.



TRANSFORM TEXTURE WITH OBJECT

To avoid "texture swimming", we need to assign Texture Space to our OSL Texture. We can either doing it directly inside OSL or using Blender Cycles Texture Coordinate node and Mapping node that goes into the Vector position.

If you add a single code below, it will properly assign Texture Space to the "object" space.

point P = transform("object", Vector);

Again, you probably notice that in all above OSL code, I have been using it P directly, and this is kind of the "wrong way". I always use Vector = P variables.

I should have done this:
x = Vector[0];
y = Vector[1];
z = Vector[2];

So, if we correctly use the actual Variables, we can do something like below, if we do not want to assign Texture Object Space in OSL code:


SELF-QUESTION: Texture Space? ST in RSL, UV in OSL? UVW? Does it matter? If I am not wrong, we can use global variables U and V.

RSL PORT: CHECKERED PATTERN

Based on:
http://renderman.pixar.com/view/simple-shader-writing

This is my first attempt to port RSL Shader to OSL. I am not fully understand it, I seem to replace S and T with the Position X and Position Y of Pixel and it seems to work. I also leave some other RSL global variables that does not seemed to be required, such as Opacity. I am not sure yet how Opacity is being treated inside OSL.


# include "stdosl.h"

shader checkered (
    int frequencyS = 1,
    int frequencyT = 1,
    int bendScaleS = 1,
    int bendScaleT = 1,
    int modAmount = 2,
    float fac = 0.5, 
    color Color1 = color(1,0,0),
    color Color2 = color(0,1,0),
    point Pos = P,
    output color ColorOut = color(0.8),
    output closure color MyBSDF = diffuse(N)

)

{
    float PI =  3.1415926535897932/180.0;
    //float PI = math.pi;
    float posX = Pos[0];
    float posY = Pos[1];
    float s = posX;
    float t = posY;

    float ss = s + sin(t * 2 * PI) * bendScaleS;
    float tt = t + sin(s * 2 * PI) * bendScaleT;
    
    float stripeS = floor(ss * frequencyS);
    float stripeT = floor(tt * frequencyT);
    
    float xxx = mod(stripeS + stripeT, modAmount);

    normal Nn = normalize(N);
    ColorOut = mix(Color1, Color2, xxx);
    MyBSDF = ColorOut * diffuse(Nn);

}


RSL PORT: 3D TEXTURE?


# include "stdosl.h"

// http://www.fundza.com/rman_shaders/pattern3d/index.html

surface sine3d(
    float freq = 4,
    float amp = 0.5,
    float offset = 0,
    float blur = 0.05,
    output color Col_Out = color(0.8)    
)
{
// Convert the shading point to the object coordinate system.
point p = transform("object", P);
  
// Get the coordinates of the shading point.
float x = p[0];
float z = p[2];


// The arc tangent of the shading point will be in radians 
// (-3.142 to 3.142) ie -180 to 180 degress.
float theta = atan2(x,z);


// Generate a sine wave - remapped to 0 to 1.
float wave = (sin(theta * freq) + 1) * 0.5;
  
// Adjust the height and position of the sine wave.
float waveHt = wave * amp + offset;


// Get a filtered value of the wave height.
waveHt = smoothstep(waveHt - blur, waveHt + blur, p[1]);

Col_Out = mix(color(1,1,1), color(0,0,0), waveHt);
}


It's always interesting to manually translate Shader code from one language to another, it helps to understand both language and see the differences. Comment out parts with // notation. Maybe syntax or variable from one language is different and you can // comment out that lines and see if the translated code is compiled in the new language.

If we study hard learning OSL, maybe we can get to know RSL too and it is great.
http://www.smartcg.com/tech/cg/courses/RMan/notes/index.html

Quicky Porting: RSL Turbul Function
At this moment, I don't quite understand the RSL Ka, Kd, Ks, faceforward(), normalize() function, etc and how it translates properly to OSL. However, I am interested with the function turbul() in this code below:
http://www.smartcg.com/tech/cg/courses/RMan/notes/Class02/Class02.html

// SOURCE: http://www.smartcg.com/tech/cg/courses/RMan/notes/Class02/Class02.html
// Roughly ported from RSL to OSL by Jimmy Gunawan, 2013, Blender Sushi.

float turbul(
    point PP,
    int n
)

{
  float t;
  if(n==4)
   t = 0.5333*(noise(PP) + 0.5*(noise(2*PP)) + 0.25*(noise(4*PP)) + 0.125*(noise(8*PP)));
  else if (n==3)
   t = 0.5714*(noise(PP) + 0.5*(noise(2*PP)) + 0.25*(noise(4*PP)));
  else if (n==2)
   t = 0.6667*(noise(PP) + 0.5*(noise(2*PP)));
  else if (n==1)
   t = noise(PP);

   return t;
}

shader smarble(
    //float Ka=1,
    //float Kd=0.6,
    //float Ks=0.4,
    //float roughness=0.2,
    //float Ksin=1.0,
    float freq=0.1,
    int n=4,
    color myColor = color(1,1,0),
    output color Col_Out = color(.25)
)
{

   point PP;
    float cmi;
    normal Nf;
    vector V;
    color diffuseColor;

    //Nf = faceforward(normalize(N), I);
    //V = -normalize(I);
    PP = transform("shader", P) * freq;
    
      // float t = 0.5*(1+sin(Ksin*3.1415*turbul(PP,n)));
      float FORCE = turbul(PP,n);
      // print(u);

/*
    color base = color spline(FORCE,
        color (0.8, 0.2, 0.05),
        color (0.8, 0.2, 0.05),
        color (0.8,0.5,0.3),
        color (0.6,0.594,0.58),
        color (0.3,0.3,0.4),
        color (0.05, 0.05, 0.1),
        color (0.8,0.79,0.77),
        color (0.8,0.8,0.79)
    );
*/
    //color based = color(1,0,0);

    Col_Out = FORCE;

}

The actual OSL Shader which I ported from RSL roughly (I stripped out some of the functions) is returning an interesting B&W turbulance kind of noise. This kind of thing is plug-able to the ColorRamp node to give color.







Or something like below...



Camouflage Suzanne.


Back to 3D Texture Sine 3D....

shader sine3d(
    color colorA = color(1,0,0),
    color colorB = color(0,1,0),
    float freq = 4,
    float amp = 0.5,
    float offset = 0,
    point Vector = P,
    float blur = 0.05,
    output color Col_Out = color(0.3)
)

{
    point p = transform("object", Vector);

    float x = p[0];
    float z = p[2];
      
    // The arc tangent of the shading point will be in radians 
    // (-3.142 to 3.142) ie -180 to 180 degress.
    float theta = atan2(x,z);
      
    // Generate a sine wave - remapped to 0 to 1.
    float wave = (sin(theta * freq) + 1) * 0.5;
      
    // Adjust the height and position of the sine wave.
    float waveHt = wave * amp + offset;
      
    // Get a filtered value of the wave height.
    waveHt = smoothstep(waveHt - blur, waveHt + blur, p[1]);
      
    // Control the mixing of two colors by the waveHt.
    //Oi = mix(color(1,1,1), color(0,0,0), waveHt);
    //Ci = Oi * Cs * wave;

    Col_Out = mix(colorA, colorB, waveHt);    
}


You can always change the code and play around with the code, save every changes and make notes. Here for example, I am curious about the waveHt variable, I just replace it with the wave and I am getting something that looks like Pie OSL:

shader sine3d(
    color colorA = color(1,0,0),
    color colorB = color(0,1,0),
    float freq = 4,
    float amp = 0.5,
    float offset = 0,
    point Vector = P,
    float blur = 0.05,
    output color Col_Out = color(0.3)
)

{
    point p = transform("object", Vector);

    float x = p[0];
    float z = p[2];
      
    // The arc tangent of the shading point will be in radians 
    // (-3.142 to 3.142) ie -180 to 180 degress.
    float theta = atan2(x,z);
      
    // Generate a sine wave - remapped to 0 to 1.
    float wave = (sin(theta * freq) + 1) * 0.5;
      
    // Adjust the height and position of the sine wave.
    float waveHt = wave * amp + offset;
      
    // Get a filtered value of the wave height.
    waveHt = smoothstep(waveHt - blur, waveHt + blur, p[1]);
      
    // Control the mixing of two colors by the waveHt.
    //Oi = mix(color(1,1,1), color(0,0,0), waveHt);
    //Ci = Oi * Cs * wave;

    Col_Out = mix(colorA, colorB, wave);    
}


I am not a Math expert, so I take apart code by changing values of attributes.

Here is another RSL code "Simple Sine RSL" converted into OSL. In RSL, there is something called S and T which is related to Texture. I think in OSL it is U and V.

/*SOURCE
http://fundza.com/rman_shaders/pattern3d/index.html
*/

#include "stdosl.h"

shader simple_sine(
    float  freq = 5,
    output color Col_Out = color(0.8),
    point Vector = P
)
{
    float x = Vector[0];
 
    float  sinval = sin(u * 2 * M_PI * freq); // instead of ST in RSL, we use UV in OSL
   
    // Remap from -1 to +1 to 0 to 1
    sinval = (sinval + 1) * 0.5;
    //sinval = sinval;

   
    //Oi = Os;
    //Ci = Oi * Cs * sinval;
    Col_Out = sinval;
}


That is interesting, I am getting result that is different from the original RSL. Why is that? Maybe the S and T in RSL is different to U and V in OSL? Maybe there is additional information I need to plug into the U and V to make it correct? It's okey if I could not get the answer now, maybe tomorrow.


RSL PORT: Brick Texture

// Based on RSL Brick Texture 
// from Book "Texture & Modeling Procedural A Procedural Approach"
// pages 39-40

# include "stdosl.h"

shader brick(
    float BMWIDTH = 5,
    float BMHEIGHT = 5,
    float MORTARTHICKNESS = 0.1,
    point Vector = P,
    //float Ka = 1,
    //float Kd = 1,
    color Cbrick = color (0.5,0.15,0.14),
    color Cmortar = color(0.5, 0.5, 0.5),
    output color Col_Out = color(0.7)

)

{
    color Ct;
    point Nf;
    float ss;
    float tt;
    float th;
    float sbrick;
    float tbrick;
    float w;
    float h;
    
    //Nf = normalize(faceforward(N, I));
    
    float x = Vector[0];
    float y = Vector[1];
    
    float MWF = MORTARTHICKNESS * 0.5/BMWIDTH;
    float MHF = MORTARTHICKNESS * 0.5/BMHEIGHT;
    
    
    ss = x / BMWIDTH;
    tt = y / BMHEIGHT;

    if (mod(tt * 0.5, 1) > 0.5)
    {
        ss += 0.5;
    }

    sbrick = floor(ss);
    tbrick = floor(tt);
    
    ss -= sbrick;
    tt -= tbrick;
    
    w = step(MWF,ss) - step(1-MWF,ss);
    h = step(MHF, tt) - step(1-MHF, tt);
    Ct = mix(Cmortar, Cbrick, w*h);
    
    Col_Out = Ct;

}


OSL: Stripes + Noise Node + ColorRamp

Sometimes, we can just do something like below, instead of specifying Color in the code, we can just pass on the texture functions:

# include "stdosl.h"

shader multipleStripes (
    float amplitude = 2.0,
    float offset = 0.0,
    float frequency = 1.0,
    point Vector = P,
    output color Col_Out = color(0.8)
    
)

{

    float x = P[0];
    float y = P[1];
    float z = P[2];
    
    float formula = sin(frequency*x + offset) * amplitude + cos(frequency*x + offset) * amplitude;
    Col_Out = 1/abs(formula);

}



OSL DOODLE

This is one of my random exploration of OSL. I am still not sure about things, such as Math Function that PLOT (in 2D or 3D) and Math Function that actually works and create 3D Solid Texture that is volumetric. Just like how we can already do with Blender Internal Renderer to certain extent.

Something like this is nice:

It would be nice if someone could explain it to me until it is crystal clear and I will write additional note in here so that you can understand it.

Anyways, I just plug some Plotting function into the Point Position Float values:

#include "stdosl.h"

// SOURCE: http://trac.sagemath.org/ticket/1888


float ffx(float t)
{
    return (2 + cos(2*t))*cos(3*t);
}

float ffy(float t)
{
    return (2 + cos(2*t))*sin(3*t);
}

float ffz(float t)
{
    return sin(4*t);
}


shader study_001 (
    point Vector = P,
    color ColorA = color(1,0,0),
    color ColorB = color(0,1,0),
    output color Color_Out = color(0.8)
    
)

{
    float x = Vector[0];
    float y = Vector[1];
    float z = Vector[2];
    
    float fx = ffx(x);
    float fy = ffy(y);
    float fz = ffz(z);
    
    // parametric_plot3d( (fx, fy, fz), (t, 0, 6*pi), plot_points = 500, frame=False)
    
    Color_Out = mix(fx, fy, fz);

}

NOISE FUNCTIONS IN OSL

Cell, Noise, Voronoi....

We can either use Noise Functions directly inside OSL or utilize the already existing Blender Noise nodes such as Voronoi, etc.

noise()

WHAT IS THAT "INCLUDE" STUFF?

You probably notice one line: # include "stdosl.h" this line allow you to use some useful functions. You can read this file using normal text editor.

TILING: XY Wizard

Tiling texture is an interesting area.

Read a great discussion about tiling here, download XY Wizard and study it.
http://blenderartists.org/forum/showthread.php?277284-Tiles-Texture-OSL

FUNCTIONS

color()

clamp()
sin()
mod()
floor()
abs()

CLOSURE

diffuse(N)

FURTHER SELF STUDY

There is no best way to learn this OSL stuff on your own by reading examples. The answers are already there, you just need to see it.

Start from here and see how Dingto recreating some of Blender's built in cycles node using OSL:
http://www.openshading.com/osl/example-shaders/

For example, node_brick_texture.osl from Open Shading website, is a recreation of Brick Texture node that is buit in with Cycles. You can have a look and compare that Brick Texture OSL code with simpler Brick OSL code that I ported from RSL.

Study some RSL shaders from website like FUNDZA. RSL and OSL are kind of similar.

If you are ambitious, you can check out Houdini's VEX code, play around with VEX node network. It is similar to Blender's Node Network, but inside it, you have component level nodes: sin(), abs(), and more. Translating and porting Houdini VEX maybe slightly complicated.

I have not looked into GLSL to OSL porting, but some tutorials out there is doing that.

You may notice all above what we have been writing is really just to end up as color() OUTPUT. We use mix(valueA, valueB, Fac) a lot. And what we have been modifying is the Fac value using Math.

That is the basic of OSL Texture writing.

RELATED LINKS

OSL
http://blenderthings.blogspot.com/
http://www.blenderartists.org/forum/showthread.php?270332-OSL-Goodness
http://blog.selfshadow.com/
http://blenderartists.org/forum/showthread.php?274730-OSL-Porting-from-RSL
http://elbrujodelatribu.blogspot.fr/
http://learningblender3dsoftware.blogspot.com/2012/11/hello-osl.html
http://www.elysiun.com/forum/showthread.php?301168-A-color-stencil-node

RSL
http://hosukchang.com/
http://xrt.wikidot.com/
http://www.fundza.com/index.html

MKRdezign

Contact Form

Name

Email *

Message *

Powered by Blogger.
Javascript DisablePlease Enable Javascript To See All Widget