Halloween Costume ideas 2015
Articles by "shader"
@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

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

Up until today, I believe I have spent over 100+ hours to study about OSL (Open Shading Language). I believe that's a good first steps for someone who never wrote Shaders before.

Maybe this shader can also be called Mummy OSL Shader.

I know I am still very much a beginner in Shader Writing. There are still plenty of things about OSL that I honestly do not understand. For most of part, I understand it in certain way, but maybe someone in the future will correct me or help me to understand it better.

I am still confused about Closure in OSL, for example. So far, I am only dealing with Procedural Texture creation in OSL.

With better understanding of the code, I think we can create our own Closure. However, we can actually mix and match the pre-built closures like Diffuse, Glass, Glossy, etc. within a single node. Lots of power. But I think before we get there, I like to focus with procedural Texture creation and design.

This post is a little intermezzo to note  down what I have learned so far on OSL, how I got this far. Hopefully if you are also starting to write OSL from zero, you can pickup a thing or two.

TEXTURE CREATIONS: NODE OR CODE?

Things are surely a lot easier when we connect nodes to create Shader, right? Cycles Node Network is brilliant as it is, so easy to use to create beautiful render using the built in nodes. It is quite a robust system already.

The additional Script Node that allows us to write our own node using OSL is even making Cycles in Blender more amazing. It is not yet GPU accelerated as of today, OSL is still CPU only render, but I still find it pretty fast and great to try ideas.

Interestingly enough, I found that whenever I rewrite a snippet of code that actually recreates the same thing of what the built-in node can already do (Noise, Voronoi, Cellnoise, etc), I gain a little more layers of knowledge.

I figure that a lot of interesting procedural textures are all based on Noise function. By layering Noise function, we create turbulance. And turbulance texture itself is really good powerful for adding details.

With a bit of knowledge of shader writing, it is as if now I am starting to be able to see better, to break down and to think about Texture (procedurally or non procedurally) in more details and also simplified at the same time.

Shader writing (RSL, OSL, GLSL, etc) is really quite challenging area but also rewarding experience. Perhaps shader writing is not for everyone, but you should try first.

As a prequisite, it helps to know a little bit about programming (Python is my basis, but I knew a bit of MEL scripting which is a little bit like C) in order to learn to write and code shader. Good grasp of programming concept should be ok to get you started in shader writing.

I remember the first time writing OSL, by following and rewriting code that is shown by other great Blender Artists and Developers out there.

  • Thomas Dingto
  • Geofrey..

RSL to OSL

"I have to learn and understand RSL (RenderMan Shading Language) in order to understand OSL!". That is the sentence that kept telling myself whenever I am stuck.

There are materials out there that talk about Shader Writing. I tried to read and digest all the available RenderMan books at the library that I (am lucky enough) to have access to. Some of the RenderMan books are already pretty dusty and many years old.

Here are list of the books I could find at the UTS (University of Technology of Sydney) Library:

  • The RenderMan Shading Language Guide
  • Advanced RenderMan: Creating CGI for Motion Pictures
    http://www.larrygritz.com/arman/materials.html
  • Essential RenderMan
  • Rendering for beginners : image synthesis using RenderMan
  • The RenderMan companion : a programmer's guide to realistic computer graphics

I probably can grasp about 25-30% of those materials, I have to re-read them again in the near future if I need to get deeper.

There are so many amazing RSL Shaders I discover along the way.

Some shaders are SIMPLE but very CLEVER and actually a good exercise for beginner:
  • Bowling Pin
  • Pencil
  • Ruled Paper
  • Watermelon
  • Banana
  • Woods

The issue with learning RenderMan is ACCESS to it. Like everything in life, often it is all about ACCESS to the tool and the materials.

I am currently using Pixar Photorealistic RenderMan (PRMan) to dig RenderMan. I happened to have access to it, thanks to one nice guy from Pixar. Since I have this privilege, I definitely MUST take this opportunity to study and use the tool while I can.

However, if one does not have access to PRMan, 3Delight is a good alternative.

It is only recently that I look into RenderMan properly and its latest development with their Physically Plausible GPShaders (General Purpose Shaders), I can see how things have changed over the years. PRMan implementation inside Maya is fantastic. It is really a lot easier to get a highly realistic render.

ONLINE SOURCES FOR RSL AND OSL

Ok, so apart from those great legacy books on RenderMan to read, there are plenty of online materials that are really helpful.

Pixar's documentation of RenderMan:
http://renderman.pixar.com/resources/current/rps/rslFunctions.html

Although RSL is not OSL, they have similarities.

This online note by Steve May (Pixar) actually the one that finally clicks with my brain.
http://accad.osu.edu/~smay/RManNotes/index.html

Malcolm Kesson's priceless RSL materials at FUNDZA
http://www.fundza.com/

Inigo Quilez notes and YouTube
http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
http://www.iquilezles.org/www/articles/functions/functions.htm

Check ShaderToy:
https://www.shadertoy.com/

MY FIRST SHADER: OSL Wooly

I hope that this shader is pretty original.

This took nearly 3 hours to render... but looks quite nice.

It is very simple actually, started with just 2 stripes, originated from this RLS shader:
http://accad.osu.edu/~smay/RManNotes/RegularPatterns/transitions.html#cross_tile

I also found some hints from:
http://www.fundza.com/rman_shaders/surface/index.html
http://www.fundza.com/rman_shaders/displacement/index.html

I figure that I could introduce 2 kind of "randomization". We don't really use random function in shader writing I think.

Let me quote Larry Gritz from OSL Developer Thread:

"I can't really think of a good use for random(), since you can't guarantee the order of shading, it wouldn't be stable from run to run.  The only thing I can think of is for use in sampling, but (a) the whole point of OSL is that you don't need to be doing sampling in the shader anymore, and (b) even if you did, it would be better for us to think of a way to provide specialized functions that were reproducible and better-stratified than just having a uniform RNG. 

As for hash(), the idea there was something like the cellnoise trick.  What I had in mind was just using a strong has on the floating point bits of whatever you passed in (like the hash we use on the integer lattice values to generate infinite, non-repeating cellnoise values). 

Since nobody seems to care enough to notice that these are unimplemented, I'm fine with removing them from the spec.  We can always add them back if we decide that there is a legit use case. "


The "random" and "details" can apparently come from:
1. Random color per object.
http://blenderartists.org/forum/archive/index.php/t-277986.html
2. Random by multi-layering the same texture using simple loops.

This one post from BlendBits actually has snippet of "random function" using Cellnoise function.
http://blendbits.blogspot.com.au/2013/05/lens-flare-shader-for-blender-cycles.html

Champagne Gold with lots of Colors stripes. Sounds familiar?

Wooly OSL Shader is very simple. Just repetition of lines that is rotated slightly. It is a 2D texture.

Maybe with the same idea, we can create Pokemon Ball OSL Shader.



Here, at BlenderThings blog, again it introduces one shader that uses "randomization".
http://blenderthings.blogspot.com.au/2012/12/a-hagelslag-sprinkles-osl-shader-for.html

Out of curiosity, I often plug one OSL Shader into another Shader. In this case below I plug the Sprinkles OSL into my Wooly OSL Shader:

Interesting cartoony style NPR shader, not perfect, but has potential.

Shaders that are using multi-layers randomization is indeed slow to render, but looks nice and detailed. With Blender, "slow render" is not an easy, we can always have unlimited render farm.

Over one hour and still rendering a single frame...
I tried combining this shader with pre-built nodes in Cycles:


TAKING WOOLY OSL SHADER TO THE NEXT STAGE

At current stage, I think Wooly OSL Shader is still a work in progress. I would like so that each line is more 3D like thread, with a bit of shadowing whenever it overlaps layer below it.

I think some OSL experts out there can probably take it to high level production ready shader.

These concepts below are crucial to understand and able to write OSL:

  • PROGRAMMING CONCEPT >> Variable declaration, Loop, .... 
  • STRUCTURE & CONSTRUCT >> we can write OSL in whatever way we like, however without proper planning, we could easily get lost with the code. following a good construct and having a plan will help us to have manageable and flexible reusable code.
  • MATH & BASIC FUNCTIONS: sin(), cos(), atan2(), smoothstep(), 
  • INCLUDE >> When you see word INCLUDE, usually that is when we source some snippet or macro or helper functions that is bundled as external file.
  • LAYERS & BLENDING >> I only found this concept quite recently and I would like to implement my previous OSL writing so that every "shape" or "texture" created procedurally can be easily layered on top of one another.

REWRITING THE WOOLY SHADER FROM SCRATCH...

The whole code is like this:

THE CODE: WOOLY OSL SHADER

(TO BE CLEANED UP)

/* ALL HELPER FUNCTIONS COME BEFORE THE ACTUAL SHADER */

void rotate2d (

    float x,
    float y,
    float rad,
    float ox,
    float oy,
    float rx,
    float ry
)
{
    rx = ((x) - (ox)) * cos(rad) - ((y) - (oy)) * sin(rad) + (ox);
    ry = ((x) - (ox)) * sin(rad) + ((y) - (oy)) * cos(rad) + (oy);
}


color blend(

    color a,
    color b,
    color x
)

{

    return ((a) * (1-(x)) + (b) * (x));
}

float pulse (

    float a, 
    float b, 
    float fuzz, 
    float x
)
{
    return (smoothstep((a)-(fuzz), (a), (x)) - smoothstep((b)-(fuzz), (b), (x)));
}





/* THE ACTUAL SHADER CODE BELOW */


shader crosstile(

    float rot = 45,
    color Cs = color(1.0),
    color Os = color(1.0),
    float fuzz = 0.05,
    int seed = 231,
    int iteration = 10,
    vector Pos = P,
    output color Oi = color(0.2),
    // output color Ci = color(0.2),
    output color Col_Out = color(0.5)
)
{
    // we have to do this in OSL
    // becayse we do not have Global Variable s and t
    float s = Pos[0];
    float t = Pos[1];

    // background layer

    color surface_color = Cs;
    color surface_opac = Os;
    
    // initialize layer
    color layer_color = color(0.1);
    color layer_opac = color(0.2);
    
    /*
    // vertical bar layer
    layer_color = color(0.1,0.5,0.22);
    layer_opac = pulse(0.35, 0.65, fuzz, s);
    surface_color = blend(surface_color, layer_color, layer_opac);
    */
    
    // THANKS FOR CODE SNIPPET
    // http://blendbits.blogspot.com.au/2013/05/lens-flare-shader-for-blender-cycles.html
    
    // Generate repeatable sequences of 'random' numbers - based on nrand and seed settings.
     float nrand = 0;
          
     // Random helper function
     float urand () {
       nrand += 1; 
       return cellnoise(nrand, seed);
     } 


    // multiple rotating bars with random values

    float ss;
    float tt;
    float power;
    for (float i=0.0; i<iteration; i++){
    
        // want random
        float Random=0;
        float R=0;
        float G=0;
        float B=0;
        getattribute("object:random", Random);
        R=trunc(Random*100.0)/100.0;
        G=trunc((Random*100.0-trunc(Random*100.0))*100.0)/100.0;
        B=trunc((Random*10000.0-trunc(Random*10000.0))*100.0)/100.0;
        
        rotate2d(s,t,radians(rot * i * urand()), 0.5*urand(), 0.5*urand(), ss, tt);   
        //layer_color = color(0,(i+1)/iteration,0);
        layer_color = color((i+1)/iteration * urand(), G*0.5 , B*0.4);
        layer_opac = pulse(0.50, 0.55, fuzz, tt);
        surface_color = blend(surface_color, layer_color, layer_opac);
    }

  for (float i=0.0; i<iteration; i++){
    
        // want random
        float Random=0;
        float R=0;
        float G=0;
        float B=0;
        getattribute("object:random", Random);
        R=trunc(Random*100.0)/100.0;
        G=trunc((Random*100.0-trunc(Random*100.0))*100.0)/100.0;
        B=trunc((Random*10000.0-trunc(Random*10000.0))*100.0)/100.0;
        
        rotate2d(s,t,radians(rot * i * urand()), 0.5*urand(), 0.5*urand(), ss, tt);   
        //layer_color = color(0,(i+1)/iteration,0);
        layer_color = color((i+1)/iteration * urand(), G*0.5 , B*0.4);
        layer_opac = pulse(0.50, 0.55, fuzz, ss);
        surface_color = blend(surface_color, layer_color, layer_opac);
    }

    
    /*
    // horizontal bar layer
    layer_color = color(0.1,0.1,0.3);
    layer_opac = pulse(0.35, 0.65, fuzz, t);
    surface_color = blend(surface_color, layer_color, layer_opac);
    */
    
    // output if we need to specify CLOSURE
    
    Oi = surface_opac;
    // Ci = surface_opac * surface_color;
    Col_Out = surface_opac * surface_color;
    
}


I want to show step by step process how I get to the current look of Wooly OSL Shader.

(TO BE ADDED)

BONUS: SPLINE FUNCTION

Spline function is like Color Ramp node in Cycles. Allowing us to have multiple color array to blend. Useful for things like FIRE.

color colorarray[X] = { .... }

spline("linear", colorarray ....


BONUS: PULSE FUNCTION

Pulse is like the combination of smoothstep...

OTHER LINKS

Simple Blend Dissolve using OSL


It has been a while since last post. I have a lot to think in my mind. Basically, on one side I like to start making a more finished/polished artworks, while on the other side, I always love the idea of exploring and experimenting with creative ideas in Computer Graphics in general and especially in Blender.

I think I can do both (Quality vs Creative Quantity). Just takes a bit more time in refining.

I also want to go back to doing Animation, although at the same time, I love doing technical works: Rigging, VFX, Particles, etc.

The thing I found with Shader Writing is that this is a never-ending study and exploration. Well almost like everything in CG is like that. The more we dig, the more we found a new complexity. I like the idea of understanding the simplicity of things. Complexity is not always needed.

Anyway, for this post on OSL, I think I will just dump one big large code that is basically containing some useful functions in relation to BLENDING MODE. We probably learn about Layer Blending from Photoshop, as we know we have few Blending Modes to mix 2 layers of pixels together:
  • Multiply
  • Darken
  • Lighten
  • Dodge
  • Burn
  • etc
Most of information and code about Blending is pretty much translated from book "The Renderman Shading Language Guide" by Rudy Cortes and Saty Raghavachary.
http://www.amazon.com/The-RenderMan-Shading-Language-Guide/dp/1598632868

DESIGN PHILOSOPHY OF SHADER WRITING
I like to quote a paragraph from the book above from page 362-363 in regards to Procedural Pattern Creation and Design:
"The most effective strategy to employ toward procedural pattern generation is to divide and conquer. When presented with a pattern to synthesize, the idea is to break the pattern into distinct layers, create each layer using an independent block of code, and then combine the layers to obtain the pattern sought."

I have my own frustration when learning this Shader Writing. Sometimes it feels like re-inventing the wheels. Also, there are not many experts out there care to share their knowledge to help newbies. Lots of important documents are old and starting to break as we are moving to a more modern way. There is as if a huge gaps that artists to leap ahead in order for them to be able to take advantage of the tools.

I think we can take the analogy of Instant Ramen and real Ramen/Noodles made by hand. Or any kind of instant food (pizza, pasta, fried rice etc). Handmade takes longer but may taste a lot better and fresh and healthier too. Understanding of ingredients will make you a better chef. These days, people living in modern city got their fruits, vegetables and meats already pre-made and so easy to cook. Of course it is not always necessary to be able to cut the meat or to plant vegetables and wait for fruits, because that will not be efficient, however, a certain kind of understanding of the component will help us a lot when we are using "all purpose nodes" to create custom original texture that we needs.

More reading as recommendation:
http://www.renderman.org/RMR/Publications/

I really do learn a lot about Shader Writing from RSL (Renderman Shading Language). Slowly, hopefully, we all can gain enough knowledge to translate RSL knowledge to OSL. Somebody with good Shader Writing and OSL knowledge and experience ought to write a NEW book to help future shader writers in near future!

Now, that book above also mentioned a few times that the origin of the blending mode functions were taken from: http://www.pegtop.net/delphi/articles/blendmodes/

The "pegtop" website is the work of Jens Gruschel. So I have to thank him also for the knowledge. These are priceless bits of knowledge of the legacy of shader writing.

NOTE: In this code example, I am also using OSL syntax that load Image File from directory.

I am using these 2 images as Texture to use inside OSL:
TEAPOT A: This is a generic Blender Cycles Render of a basic teapot I modeled in Blender a while ago.
TEAPOT B: This is a photograph of this awesome limited edition Renderman walking teapot (thanks Moxy!), 
Using the code below, we are loading the 2 image textures above and blend the two together.

It is very simple thing that we can easily do using Blender Mix Node, but with the idea of learning OSL Shader Writing, we are trying to recreate it with code.

The always handy MIX node.

THE "BLEND MODE" CODE

// HELPER FUNCTIONS THAT CHANGES THE BLENDING
// SOURCE:
//    The RenderMan Shading Language Guide Book
//    By Rudy Cortes and Saty Raghavachary
//    Also: Works of Jens Gruschel (http://pegtop.net)

// OVER MODE
color colorOver(color BaseMap, color Layer, float LayerOpac){
    return mix(BaseMap, Layer, LayerOpac);
}

// ADD MODE
color colorAdd(color BaseMap, color Layer, float LayerOpac){
    return BaseMap + (Layer * LayerOpac);
}

// SUBSTRACT MODE
color colorSubstract(color BaseMap, color Layer, float LayerOpac){
    return BaseMap + ((Layer-1) * LayerOpac);
}


// MULTIPLY MODE
color colorMultiply(color BaseMap, color Layer, float LayerOpac){
    return BaseMap * ((Layer * LayerOpac) + (1-LayerOpac));
}

// COLOR DISSOLVE
color colorDissolve(color BaseMap, color Layer, float LayerOpac){
    //float Random = 5.0;
    //getattribute("object:random", Random);
    float myRandom = noise("snoise", P * 7);
    color out;
    if(myRandom < (LayerOpac))
        out = Layer;
    else
        out = BaseMap;
        
    return out;
}

// SCREEN MODE
color colorScreen(color BaseMap, color Layer, float LayerOpac){
    return 1 - ((1-BaseMap) * (1-Layer * LayerOpac));
}

// COLOR OVERLAY
color colorOverlay(color BaseMap, color Layer, float LayerOpac){
    //float layerval = colorToFloat(Layer);
    //float layerval = Layer[1];
    
    // color to grayscale (luminocity method)
    // READ: http://www.johndcook.com/blog/2009/08/24/algorithms-convert-color-grayscale/
    float layerval = 0.21 * Layer[0] + 0.71 * Layer[1] + 0.07 * Layer[2];

    return (layerval>0.5) ? (2*BaseMap*Layer*LayerOpac)+BaseMap*(1-LayerOpac):
    1 - ((1-BaseMap) * (1-Layer*LayerOpac))*(2-(1-LayerOpac));
}

// COLOR DARKEN
color colorDarken(color BaseMap, color Layer, float LayerOpac){
    float baseval = 0.21 * BaseMap[0] + 0.71 * BaseMap[1] + 0.07 * BaseMap[2];
    float layerval = 0.21 * Layer[0] + 0.71 * Layer[1] + 0.07 * Layer[2];
    return (baseval<layerval) ? BaseMap: Layer * LayerOpac + (BaseMap*(1-LayerOpac));
    
}

// COLOR LIGHTEN
color colorLighten(color BaseMap, color Layer, float LayerOpac){
    float baseval = 0.21 * BaseMap[0] + 0.71 * BaseMap[1] + 0.07 * BaseMap[2];
    float layerval = 0.21 * Layer[0] + 0.71 * Layer[1] + 0.07 * Layer[2];
    return (baseval>layerval) ? BaseMap: Layer * LayerOpac + (BaseMap*(1-LayerOpac));
    
}

// COLOR DIFFERENCE
color colorAbs(color col){
    return color(abs(col[0]), abs(col[1]), abs(col[2]));
}

color colorDifference(color BaseMap, color Layer, float LayerOpac){
    return colorAbs(BaseMap - (Layer * LayerOpac));
}

// COLOR HARDLIGHT
color colorHardlight(color BaseMap, color Layer, float LayerOpac){
    float layerval = 0.21 * Layer[0] + 0.71 * Layer[1] + 0.07 * Layer[2];
    return (layerval<0.5) ? (2*BaseMap*Layer*LayerOpac)+BaseMap*(1-LayerOpac):1-((1-BaseMap)*(1-Layer*LayerOpac))*(2-(1-LayerOpac));
    
}


// COLOR SOFTLIGHT
color colorSoftlight(color BaseMap, color Layer, float LayerOpac){
    color ctemp = BaseMap * Layer;
    return mix(BaseMap, ctemp+(BaseMap*(1-((1-BaseMap)*(1-Layer))-ctemp)), LayerOpac);
}

// COLOR DODGE
color colorDodge(color BaseMap, color Layer, float LayerOpac){
    color ctemp = mix(BaseMap, BaseMap/max(1-Layer, color(0.00001)), LayerOpac);
    return clamp(ctemp, color(0), color(1));
}

// COLOR BURN
color colorBurn(color BaseMap, color Layer, float LayerOpac){
    color ctemp = mix(BaseMap, 1-((1-BaseMap)/max(Layer, color(0.00001))), LayerOpac);
    return clamp(ctemp, color(0), color(1));
}



shader blending (
    color BaseMap = color(1,0,0),
    color Layer = color (0,1,0),
    float LayerOpac = 0.5,
    string filenameA = "/Users/jimmygunawan/Desktop/teapotA.png" ,
    string filenameB = "/Users/jimmygunawan/Desktop/teapotB.png" ,
    vector Pos = P,
    output color ColOut = color(0.2)
)
{

    color TextureA = texture(filenameA, Pos[0], 1.0 - Pos[1]);
    color TextureB = texture(filenameB, Pos[0], 1.0 - Pos[1]);
    
    // change the BLENDING MODE using the helper function of your choice above
    //ColOut = colorOver(TextureA, TextureB, LayerOpac);
    //ColOut = colorBurn(TextureA, TextureB, LayerOpac);
    //ColOut = colorHardlight(TextureA, TextureB, LayerOpac);
    ColOut = colorDissolve(TextureA, TextureB, LayerOpac);
}


Feel free to modify and mix the code above.



QUESTION ARISE...

If we compare the built-in Blender MIX Node that does blending with the function above, we can see that the result is a bit different sometimes. I am wondering why is that happening? Is it because things got "normalized" with the premade node and more correct?

I guess I need to compare the code from the book with what comes with Blender. Further investigation needed.

However, with the above code example, we start to think about LAYERING in OSL. OSL is certainly handy for:
- Procedural Pattern and Texture creation
- Texture Mapping
- Complex Blending
- Utility

I guess, the "best" of OSL is when shader writing is used together with the node network, so this is something we (more artists than coders) can always kept in mind.


REWRITING OSL CODE FOR LAYERING

Still reading this book, but I am most interested with Chapter 12 "Procedural Patterns".

Although some part is still quite complicated to understand, the book is quite consistent in term of explaining the concept of "LAYERING" and "PROCEDURAL PATTERN".

This one example is also translated from the book to OSL. It seems complex at a glance, but this is actually simple and it explains a lot of things. I like how the code is nicely organized and every functions are separated from the main Shader code:

  • Helper Function to Rotate Texture in 2D: rotate2d() 
  • Few other helper functions: pulse(), repeat(), blend()
  • Concept of Layering and Opacity (Masking) using code.

CODE:

// converted from book Renderman Shading Language Guide
// page 370, for shader called "Optical Illussion"
// OSL code translation by Jimmy Gunawan

// the following HELPER FUNCTIONS was translated from 'rmannotes.sl'

float pulse (
    float a, 
    float b, 
    float fuzz, 
    float x
)
{
    return (smoothstep((a)-(fuzz), (a), (x)) - smoothstep((b)-(fuzz), (b), (x)));
}

float repeat(
    float x,
    float freq
)
{
    return (mod((x) * (freq), 1.0));
}

/*
rotate2d is taken from rmannotes.sl
2D rotation of point(x,y) about origin(ox,oy) by and angle rad.
the resulting point is (rx, ry).

*/

void rotate2d (
    float x,
    float y,
    float rad,
    float ox,
    float oy,
    float rx,
    float ry
)
{
    rx = ((x) - (ox)) * cos(rad) - ((y) - (oy)) * sin(rad) + (ox);
    ry = ((x) - (ox)) * sin(rad) + ((y) - (oy)) * cos(rad) + (oy);
}


color blend(
    color a,
    color b,
    color x
)

{
    return ((a) * (1-(x)) + (b) * (x));
}

    
shader optill(
    float fuzziness = 0.025,
    float freq = 10,
    float thickness1 = 0.75,
    float thickness2 = 0.75,
    float rot = 45,
    color baseColor = color(0,0,0),
    color c1 = color(1,0,0),
    color c2 = color(0,1,0),
    vector Pos = P,
    output color ColOut = color(1)
)
{
    color surface_color;
    color layer_color;
    
    color surface_opac;
    color layer_opac;

    float fuzz = fuzziness;
    float ss;
    float tt;
    
    surface_color = baseColor;
    surface_opac = color(0);
    
    // assign pixel position as s and t
    float s = Pos[0];
    float t = Pos[1];
    
    // rotate stuff in 2D
    rotate2d(s,t,radians(rot), 0.5, 0.5, ss, tt);    
    
    // repeat pattern
    ss = repeat(ss, freq);
    tt = repeat(tt, freq);
    
    float pwh = thickness1 * 1.0/freq;
    float pwv = thickness2 * 1.0/freq;
    
    // This is Layer 1 covering Layer 0 (Base Layer)
    layer_opac = pulse(0.5-pwh, 0.5+pwh, fuzz, ss);
    surface_color = blend(surface_color, c1, layer_opac);

    // This is Layer 2 covering Layer 1
    layer_opac = pulse(0.5-pwv, 0.5+pwv, fuzz, tt);
    surface_color = blend(surface_color, c2, layer_opac);

    ColOut = surface_color;
    
    // I omited some code in relation to "Opacity"
    // because I am not quite sure how it works.
    // However I will revise it in the future, hopefully!
    
}

The result of the above code can be seen as below.

We have 3 Layers (Color):
- Base
- c1
- c2




We can then try something like below:



We are using Image Textures and using the code above to layer them together:





Thing started to get more interesting, right? I thought so too.

Some parts may still be abstract, but when the code is arranged this way, we started to see something that looks like typical 2D Layerings in 2D image editing packages.

All contained within a single node, instead of complex noodles of node network.

The book is really teaching concept of:
- MULTI LAYER
- OPACITY or MASK
- BLEND as CODE

When thinking of Shader this way, whether we are using pre-made nodes, custom procedural textures, or image textures, or combinations of everything, thing is a lot more simple. We separate the problem in layers and then we will start LAYERING the COMPLEXITY, while still having enough CONTROL to achieve the look we like.

EXPLICIT vs IMPLICIT FUNCTIONS

At this moment, perhaps for me, the hardest part of the code is to think of Pattern Creation "IMPLICITELY", instead of "EXPLICITELY".

When doing coding to draw a shape in program like Processing, we can simply say things like:
ellipse(5,5,0,0); 
// draw an ellipse shape of size of 5x5 pixel at position (0,0).
// http://processing.org/reference/ellipse_.html

That's above is actually a simple function that is using EXPLICIT FUNCTIONS.

However, when doing SHADER WRITING (like OSL, OpenGL, RSL), even to create a simple shape of ellipse, we need to think kind of inside out. We are using IMPLICIT FUNCTIONS.
http://www.sciencehq.com/mathematics/implicit-and-explicit-functions.html


MORE OSL RELATED LINKS

http://spectralbattle.wordpress.com/2011/04/12/added-new-osl-function-texture/
http://blenderthings.blogspot.com.au/2013/01/gabor-noise-for-cycles-osl.html
http://blendbits.blogspot.com.au/2013/05/lens-flare-shader-for-blender-cycles.html
http://blenderartist.org/forum/showthread.php?293132-PYLA-PhYsically-correct-LAyers-with-OSL
http://peter.cassetta.info/material-library/submitting-help/
http://www.elysiun.com/forum/showthread.php?306353-Starscape-Texture-OSL
http://www.blenderartists.org/forum/showthread.php?277986-Random-Color-OSL
http://www.sfdm.scad.edu/faculty/mkesson/vsfx419/wip/spring11/eric_kurzmack/toon.html
http://blenderthings.blogspot.com.au/2013/02/simplex-noise-for-open-shading-language.html



My "Ichiban Boshi" (number 1 Star)

My previous post about RSL was a bit long, but necessary. However, that article was a bit big when downloaded, especially if we use smartphone and mobile Internet. So, I decided that future OSL posts need to be shorter and broken down into few different posts.

Porting RSL Star to OSL Star

Below is my effort to port code of RSL Star into OSL.

I still skipped some of code that is relating to the Closure and focusing on the Texture only. But I added few things and modify the code slightly.

Maybe read this thread about Closure here:
http://www.elysiun.com/forum/showthread.php?291827-Creating-OSL-Closures

Currently, I am only curious about OSL and RSL and how the math function works to create Procedural Textures that is then passed on to the Closure.

// SOURCE http://www.renderman.org/RMR/Shaders/DPShaders/DPStar.sl
// Roughly Ported to OSL by Jimmy Gunawan @ Blender Sushi
// Dated 2013.08.05

shader DPStar(
    //float Ka = 1;
    //float Kd = 1;
    int npoints = 5,
    float sctr = 0.5,
    float tctr = 0.5,
    //float Cs = 0.1, // Cs is probably like original Diffuse Color
    //color starcolor = color (1.0000,0.5161,0.0000),
    color Color_A = color(1,0,0),
    color Color_B = color(0,1,0),
    float rmin = 0.07,
    float rmax = 0.2,
    point Vector = P, // added this so that Vector can be plugged
    output color Col_Out = color(0.8)
)

{
    float PI = M_PI; 
    //point Nf = normalize(faceforward(N, I));
    //color Ct;
    float ss;
    float tt;
    float angle;
    float r;
    float a;
    float in_out;
    float starangle = 2*PI/npoints;

    
    point p0 = rmax * point(cos(0),sin(0),0);
    point p1 = rmin * point(cos(starangle/2),sin(starangle/2),0);
    
    point d0 = p1 - p0;
    point d1;
    
    float x = Vector[0];
    float y = Vector[1];

    ss = x - sctr;
    tt = y - tctr; // s t become u v or X and Y
    angle = atan2(ss, tt) + PI;
    r = sqrt(ss*ss + tt*tt);
    a = mod(angle, starangle)/starangle;
    
    if (a >= 0.5)
        a = 1 - a;

    d1 = r * point(cos(a), sin(a),0) - p0;
    
    //in_out = step(0, zcomp(d0^d1));
    
    point FORCE = cross(d0,d1);
    
    in_out = step(0, FORCE[2]);
    
    Col_Out = mix(Color_A,Color_B,in_out);
   

    //Col_Out = mix(Cs, starcolor, in_out);
    
    /* diffuse ("matte") shading model */
    //Oi = Os;
    //Ci = Os * Ct * (Ka * ambient() + Kd * diffuse(Nf));
}






FUNCTION zcomp() and cross()

It takes me a while to figure out how to translate this RSL function below:
zcomp(d0^d1)

Into OSL function:
The Z values of cross(d0,d1) // Cross Product of Point Positions d0 and d1


Below references helps me figure this out:

1. Some great examples here:
http://blenderartists.org/forum/showthread.php?274730-OSL-Porting-from-RSL


2. Google Books preview of book titled "Texturing and Modeling: A Procedural Approach".
Would be nice to have this book on hand, but luckily there is Google Books. That paragraph below helps me understanding what is happening and find the OSL equivalent.

I think that book is available at University of Technology of Sydney (UTS).


I also figure out that if we want to define point in OSL, we have to use syntax like this:

point myPointPos = point(0.2, 0.5, 1.0)

HAPPY ACCIDENTS

During this porting, I actually made few accident or mistakes, but by making "errors" I figure out interesting results...

// SOURCE http://www.renderman.org/RMR/Shaders/DPShaders/DPStar.sl
// Roughly Ported to OSL by Jimmy Gunawan
// Dated 2013.08.05

shader DPStar(
    //float Ka = 1;
    //float Kd = 1;
    int npoints = 5,
    float sctr = 0.5,
    float tctr = 0.5,
    //float Cs = 0.1, // Cs is probably like original Diffuse Color
    //color starcolor = color (1.0000,0.5161,0.0000),
    color Color_A = color(1,0,0),
    color Color_B = color(0,1,0),
    float rmin = 0.07,
    float rmax = 0.2,
    point Vector = P, // added this so that Vector can be plugged
    output color Col_Out = color(0.8)
)

{
    float PI = M_PI; 
    //point Nf = normalize(faceforward(N, I));
    //color Ct;
    float ss;
    float tt;
    float angle;
    float r;
    float a;
    float in_out;
    float starangle = 2*PI/npoints;

    
    point p0 = rmax * point(cos(0),sin(0),0);
    point p1 = rmin * point(cos(starangle/2),sin(starangle/2),0);
    
    point d0 = p1 - p0;
    point d1;
    
    float x = Vector[0];
    float y = Vector[1];

    ss = x - sctr;
    tt = y - tctr; // s t become u v or X and Y
    angle = atan2(ss, tt) + PI;
    r = sqrt(ss*ss + tt*tt);
    a = mod(angle, starangle)/starangle;
    
    if (a >= 0.5)
        a = 1 - a;

    d1 = r * point(cos(a), sin(a),0) - p0;
    
    //in_out = step(0, zcomp(d0^d1));
    
    //point FORCE = cross(d0,d1);
    
    in_out = step(0, d1[0]);
    
    Col_Out = mix(Color_A,Color_B,in_out);
   

    //Col_Out = mix(Cs, starcolor, in_out);
    
    /* diffuse ("matte") shading model */
    //Oi = Os;
    //Ci = Os * Ct * (Ka * ambient() + Kd * diffuse(Nf));
}


// SOURCE http://www.renderman.org/RMR/Shaders/DPShaders/DPStar.sl
// Roughly Ported to OSL by Jimmy Gunawan
// Dated 2013.08.05

shader DPStar(
    //float Ka = 1;
    //float Kd = 1;
    int npoints = 5,
    float sctr = 0.5,
    float tctr = 0.5,
    //float Cs = 0.1, // Cs is probably like original Diffuse Color
    //color starcolor = color (1.0000,0.5161,0.0000),
    color Color_A = color(1,0,0),
    color Color_B = color(0,1,0),
    float rmin = 0.07,
    float rmax = 0.2,
    point Vector = P, // added this so that Vector can be plugged
    output color Col_Out = color(0.8)
)

{
    float PI = M_PI; 
    //point Nf = normalize(faceforward(N, I));
    //color Ct;
    float ss;
    float tt;
    float angle;
    float r;
    float a;
    float in_out;
    float starangle = 2*PI/npoints;

    
    point p0 = rmax * point(cos(0),sin(0),0);
    point p1 = rmin * point(cos(starangle/2),sin(starangle/2),0);
    
    point d0 = p1 - p0;
    point d1;
    
    float x = Vector[0];
    float y = Vector[1];

    ss = x - sctr;
    tt = y - tctr; // s t become u v or X and Y
    angle = atan2(ss, tt) + PI;
    r = sqrt(ss*ss + tt*tt);
    a = mod(angle, starangle)/starangle;
    
    if (a >= 0.5)
        a = 1 - a;

    d1 = r * point(cos(a), sin(a),0) - p0;
    
    //in_out = step(0, zcomp(d0^d1));
    
    //point FORCE = cross(d0,d1);
    
    //in_out = step(0, a);
    
    Col_Out = mix(Color_A,Color_B,a);
   

    //Col_Out = mix(Cs, starcolor, in_out);
    
    /* diffuse ("matte") shading model */
    //Oi = Os;
    //Ci = Os * Ct * (Ka * ambient() + Kd * diffuse(Nf));
}


// SOURCE http://www.renderman.org/RMR/Shaders/DPShaders/DPStar.sl
// Roughly Ported to OSL by Jimmy Gunawan
// Dated 2013.08.05

shader DPStar(
    //float Ka = 1;
    //float Kd = 1;
    int npoints = 5,
    float sctr = 0.5,
    float tctr = 0.5,
    //float Cs = 0.1, // Cs is probably like original Diffuse Color
    //color starcolor = color (1.0000,0.5161,0.0000),
    color Color_A = color(1,0,0),
    color Color_B = color(0,1,0),
    float rmin = 0.07,
    float rmax = 0.2,
    point Vector = P, // added this so that Vector can be plugged
    output color Col_Out = color(0.8)
)

{
    float PI = M_PI;
    //point Nf = normalize(faceforward(N, I));
    //color Ct;
    float ss;
    float tt;
    float angle;
    float r;
    float a;
    float in_out;
    float starangle = 2*PI/npoints;

   
    point p0 = rmax * point(cos(0),sin(0),0);
    point p1 = rmin * point(cos(starangle/2),sin(starangle/2),0);
   
    point d0 = p1 - p0;
    point d1;
   
    float x = Vector[0];
    float y = Vector[1];

    ss = x - sctr;
    tt = y - tctr; // s t become u v or X and Y
    angle = atan2(ss, tt) + PI;
    r = sqrt(ss*ss + tt*tt);
    a = mod(angle, starangle)/starangle;
   
    //if (a >= 0.5)
    //    a = 1 - a;

    d1 = r * point(cos(a), sin(a),0) - p0;
   
    //in_out = step(0, zcomp(d0^d1));
   
    //point FORCE = cross(d0,d1);
   
    //in_out = step(0, a);
   
    Col_Out = mix(Color_A,Color_B,a);
 

    //Col_Out = mix(Cs, starcolor, in_out);
   
    /* diffuse ("matte") shading model */
    //Oi = Os;
    //Ci = Os * Ct * (Ka * ambient() + Kd * diffuse(Nf));
}


// SOURCE http://www.renderman.org/RMR/Shaders/DPShaders/DPStar.sl
// Roughly Ported to OSL by Jimmy Gunawan
// Dated 2013.08.05

shader DPStar(
    //float Ka = 1;
    //float Kd = 1;
    int npoints = 5,
    float sctr = 0.5,
    float tctr = 0.5,
    //float Cs = 0.1, // Cs is probably like original Diffuse Color
    //color starcolor = color (1.0000,0.5161,0.0000),
    color Color_A = color(1,0,0),
    color Color_B = color(0,1,0),
    float rmin = 0.07,
    float rmax = 0.2,
    point Vector = P, // added this so that Vector can be plugged
    output color Col_Out = color(0.8)
)

{
    float PI = M_PI; 
    //point Nf = normalize(faceforward(N, I));
    //color Ct;
    float ss;
    float tt;
    float angle;
    float r;
    float a;
    float in_out;
    float starangle = 2*PI/npoints;

    
    point p0 = rmax * point(cos(0),sin(0),0);
    point p1 = rmin * point(cos(starangle/2),sin(starangle/2),0);
    
    point d0 = p1 - p0;
    point d1;
    
    float x = Vector[0];
    float y = Vector[1];

    ss = x - sctr;
    tt = y - tctr; // s t become u v or X and Y
    angle = atan2(ss, tt) + PI;
    r = sqrt(ss*ss + tt*tt);
    a = mod(angle, starangle)/starangle;
    
    if (a >= 0.5)
        a = 1 - a;

    d1 = r * point(cos(a), sin(a),0) - p0;
    
    //in_out = step(0, zcomp(d0^d1));
    
    point FORCE = cross(d0,d1);
    
    
    in_out = step(0, FORCE[2]);
    
    Col_Out = mix(Color_A,Color_B,d1[0]);
   

    //Col_Out = mix(Cs, starcolor, in_out);
    
    /* diffuse ("matte") shading model */
    //Oi = Os;
    //Ci = Os * Ct * (Ka * ambient() + Kd * diffuse(Nf));
}



There must be some clever Math in there that should be explained. I shall contact one of my friend who is a Math guru to explain what is happening. Anyway, as a visual person, I am quite happy to see something already happening.

The important thing, I think, as CG Artist, who likes to use this OSL capability is to understand what is going on. There are already some examples of procedural RSL Texture that can potentially be ported to OSL. Eventually they are all will be available for us to use, I guess.

So, the next step for Artists is to MIX and MATCH and LAYER the code to create a complete and more complex shader.

For this simple Star OSL shader alone, I made nearly a hundred of mistakes (OSL compile errors), but I think it is worth it and hopefully can contribute a little for the OSL community.

I checked the errors and see what lines is causing the error, and comment out parts and do some tests, repeating this process, I finally got this final OSL Star right!

SOMETIMES I FEEL LIKE A NEWBIE...

The OSL Star has basic star variables: Number of Star, Inner Radius, Outer Radius, X and Y Offset Position.

It may seem silly to feel excited being able to create simple primitive procedural DOT, LINE, CIRCLE, RING, STRIPES, and ... STAR, when we saw hundred of posts already taking OSL to "high level":
http://www.blenderartists.org/forum/showthread.php?270332-OSL-Goodness

However, I believe that I need to write things like this and will worth it. I hope that some of you feel the same too and contribute little by little.

So, indeed writing Shader is a little bit like "drawing blind".

QUESTIONS ARISE...

It is nice that we can now create procedural Dragon Ball Texture... :)


... however, more questions arise:
  • The shader seems to be always projected to the Front and Back Surface, how do we limit or make it to show up only on Front Facing Face? Maybe something to do with N (normal) of Surface?
  • How to REPEAT and TILE Texture? --- this question keeps popping up and I am not getting answer... I started to see how the U and V can be replaced with P position X and Y, but tiling... is tricky, unless someone can explain. DingTo, if you read this... please help.
    READING MATERIAL:
    http://blenderartists.org/forum/archive/index.php/t-277284.html
  • How do we LAYER Texture Procedurally using OSL and how to do layering using Cycles node network?
    READING MATERIAL:
    http://blenderartists.org/forum/archive/index.php/t-293132.html
    http://vadrouillegraphique.blogspot.fr/2013/05/pyla-physically-correct-layer-shader.html
  • What is a function that adds STROKE? If I want stroke on the star procedurally, for example...
  • Can we repeat the Stars IN and OUT?
  • What Math equation to use to ROTATE the Star? ANSWERED 2013.08.06.
  • Can we create FLOWER instead of STAR?
  • Can we actually use RANDOM and SCATTER efficiently for OSL?
  • Can we turn STAR shader into SPIDERWEB, BICYCLE WHEEL WIRES, etc...

Will update them when answered.

...QUESTIONS ANSWERED!

Update 2013.08.06:
ROTATE THE STAR
Thanks to Gottfried at BlenderDiplom for his Twitter reply and the answer lies here on his blog:

I must have missed that info last time. I cleaned up the code a bit and highlight the changes in BOLD.

Adding just few lines and variable to the code allowing for rotation of the Star:
// SOURCE http://www.renderman.org/RMR/Shaders/DPShaders/DPStar.sl
// Roughly Ported to OSL by Jimmy Gunawan
// Dated 2013.08.06

shader BSStar(
    int npoints = 5,
    float sctr = 0.5,
    float tctr = 0.5,
    color Color_A = color(1,0,0),
    color Color_B = color(0,1,0),
    float rmin = 0.07,
    float rmax = 0.2,
    float RotAngle = 0.0,
    point Vector = P,
    output color Col_Out = color(0.8)
)

{
    float PI = M_PI; 
    float ss;
    float tt;
    float angle;
    float r;
    float a;
    float in_out;
    float starangle = 2*PI/npoints;

    
    point p0 = rmax * point(cos(0),sin(0),0);
    point p1 = rmin * point(cos(starangle/2),sin(starangle/2),0);
    
    point d0 = p1 - p0;
    point d1;
    
    float x = Vector[0];
    float y = Vector[1];

    ss = x - sctr;
    tt = y - tctr; // s t become u v or X and Y
    angle = atan2(ss, tt) + PI/180 * -RotAngle;
    r = sqrt(ss*ss + tt*tt);
    a = mod(angle, starangle)/starangle;
    
    if (a >= 0.5)
        a = 1 - a;

    d1 = r * point(cos(a), sin(a),0) - p0;
    
    point ZCOMPONENT = cross(d0,d1);
    
    in_out = step(0, ZCOMPONENT[2]);
    
    Col_Out = mix(Color_A,Color_B,in_out);

}

  • PI / 180 is so that the value goes slower when rotation. Converting Radian to Degree, I think.
  • I also put MINUS on the RotAngle, so that the rotation is Clockwise when number is increased, it is more logical.
    angle = atan2(ss, tt) + PI/180 * RotAngle;
    angle = atan2(ss, tt) + PI/180 * -RotAngle; //same thing
    angle = atan2(ss, tt) - PI/180 * RotAngle; // same thing


Thanks Goffried, now the Star is rotate-able and animate-able.

Adding lines by lines and understanding the OSL code is a good way to properly code a shader.

There are already clever Math people out there creating bunch of useful functions, all we need to do is to use and implement them. Sometimes, we really don't always need to understand the whole function and codes, just understanding what it does to allow us to modify them to suit our need.

REPEATING THE STARS

Updated 2013.08.07 after I read this document properly:

float ss mod(s*RepeatS,1);
float tt mod(t*RepeatT,1);


// SOURCE http://www.renderman.org/RMR/Shaders/DPShaders/DPStar.sl
// Roughly Ported to OSL by Jimmy Gunawan
// Dated 2013.08.07

shader BSStar(
    int npoints = 5,
    float sctr = 0.5,
    float tctr = 0.5,
    color Color_A = color(1,0,0),
    color Color_B = color(0,1,0),
    float rmin = 0.07,
    float rmax = 0.2,
    float RotAngle = 0.0,
    point Vector = P,
    float RepeatS = 4.0,
    float RepeatT = 4.0,
    output color Col_Out = color(0.8)
)

{
    float PI = M_PI; 
    float ss;
    float tt;
    float angle;
    float r;
    float a;
    float in_out;
    float starangle = 2*PI/npoints;

    
    point p0 = rmax * point(cos(0),sin(0),0);
    point p1 = rmin * point(cos(starangle/2),sin(starangle/2),0);
    
    point d0 = p1 - p0;
    point d1;
    
    float x = Vector[0];
    float y = Vector[1];

    ss = mod(x * RepeatS, 1) - sctr;
    tt = mod(y * RepeatT, 1) - tctr; // s t become u v or X and Y
    angle = atan2(ss, tt) + PI/180 * -RotAngle;
    r = sqrt(ss*ss + tt*tt);
    a = mod(angle, starangle)/starangle;
    
    if (a >= 0.5)
        a = 1 - a;

    d1 = r * point(cos(a), sin(a),0) - p0;
    
    point ZCOMPONENT = cross(d0,d1);
    
    in_out = step(0, ZCOMPONENT[2]);
    
    Col_Out = mix(Color_A,Color_B,in_out);

}



OSL CLOVER / FLOWER

I need a bit more time to study this one and make sense of it, but probably you can also do study on it.
http://blenderartists.org/forum/showthread.php?277334-Flowers-OSL
http://www.youtube.com/watch?feature=player_embedded&v=-z8zLVFCJv4

MORE REFERENCES:

http://www.renderman.org/RMR/RMRShaders.html
http://www.renderman.org/RMR/Shaders/DPShaders/index.html
http://web.engr.oregonstate.edu/~mjb/prman/shaderfunctions.html



MKRdezign

Contact Form

Name

Email *

Message *

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