open shading language for blender...mastered learning open shading language for blender you will...
TRANSCRIPT
OpenShadingLanguageforBlender
ByMichelAnders
Copyright2013,2016MichelAnders
BlenderMarketEdition
BlenderMarketEdition,LicenseNotes
Thisebookislicensedforyourpersonalenjoymentonly.Thisebookmaynotbere-soldorgivenawaytootherpeople.Ifyouwouldliketosharethisbookwithanotherperson,pleasepurchaseanadditionalcopyforeachrecipient.Ifyou’rereadingthisbookanddidnotpurchaseit,oritwasnotpurchasedforyouruseonly,thenpleasereturntoBlenderMarketandpurchaseyourowncopy.
Thankyouforrespectingthehardworkofthisauthor
2
TableofContents
Intro 4WhatareOSLshadersgoodfor? 6Readinghints 8Codeavailability 8Averysimpleshader 9Datatypes 15Controlstructures 19Points,vectorsandnormals 26Mappingvectors 29Patterns 33Polkadots 38Leopardshader 43Diamondplate 54Symmetryoperations 59Victorianeracastironcovers 69Ripples 80Concreteshader 86Citruspeel 95Ceilingplaster 101Amountainshader 106Lotsofprettypictures 111Hedgeshader 115Griddisplays 123DebuggingOSLcode 129TheOSLpreprocessor 131Additionalinformation 133
136
Intro
Whoshouldreadthisbook?
Anyonewhowantstoextendhisorherskillsetindesigningmaterials.BlendersnodesystemisalreadyprettypowerfulbutifyouwanttohavetotalcontroloverthematerialsyoudesignforBlendersCyclesrendererorifyouwanttohavesomespecificnodestoeaseyourworkflow,learningOpenShadingLanguageisamust.AlsomanyshaderswrittenfortheRenderman(tm)ShadingLanguagearefairlyeasytoporttoOSL.
Whatkindoftopicswillbecovered?
Thisbookfocusesonwritingpracticalshaderswhichmeansyoucandownloadthecodeanduseitasisor,evenbetter,learnfromitbyadaptingittoyourneeds.OftenevendetailsinthecodeareexplainedtolowerthelearningcurvebutontheotherhandsomespecialisttopicsnotspecifictoOSLarenotcovered(anexampleisregularexpressions).Eachshaderthatwedevelopiscoveredinitsownsectionandspecificareasofinterestarelistedatthebeginningofeachsection.
IsOpenShadingLanguagerestrictedtoBlender?
Inprincipleno:CurrentlyV-RaysupportsOSLandAutodeskBeastwillalsosupportOSLandmaybeotherpaid3Dapplicationswillsupportitonceitgainsmomentum,butatthismomentBlenderistheonlyopensourceapplicationthathasadaptedOSL.ThismightwellchangeinthefutureasOSLiswelldocumentedandcanbereadilyadaptedtootherrenderers.
WhatskillsdoIneedtobenefitfromthisbook?
YoushouldbebefairlycomfortableinusingBlender.YouneednotbeaanexperiencedartistbutyoushouldknowyourwayaroundandknowhowtocreatematerialsfortheCyclesrendererwithBlender'snodesystem.Youshouldalsoknowhowtoprogram.Againyouneedn'tbeaseasonedsoftwaredeveloperbutitcertainlyhelpsifyouknowhowtoprogramshortpiecesofcodeinanyprocedurallanguagelikeC,C++,Java,Pythonoreven(visual)Basic.OpenShadingLanguageisaC-likelanguageandquiteeasytolearn.Itdoesn'trelyonconceptslikeobjectorientationnordoesitdependonhardtomasterthingslikepointersanditsdatatypesarelimitedbutadequateforthejob.Inshort,logicalthinkingwillgetyoualongwayandtheintroductorychapterswillintroducethemostimportantideas.IfyoucanprogramashortprogramthatliststhefirsttenevenintegersintheprogramminglanguageofyourchoiceOSLwillposenoproblem.
Besidesprogramming,writingshadersinvolvessomemathandgeometryaswellbutnothingabovehighschoolmath.Wewillexplaineachmathissueweencounterandwillconcentrateonhowtouse
4
thingswithoutdelvingintothesmalldetails.Whereappropriatelinkstorelevanttopicsonthewebwillbeprovided.
WherecanIfindmoreaboutOpenShadingLanguage?
ThesinglemostimportantsiteistheGitHubrepositoryofOSL.NotbecauseyouneedtogetthesourcecodebutforemostbecauseitistherepositoryoftheOSLLanguageSpecification.OnceyoumasteredlearningOpenShadingLanguageforBlenderyouwillfindtheLanguagespecificationavaluablereference.
IntheappendicesIlistsomeadditionalsiteswhichareworthvisitingtolearnmoreaboutOSL.
5
WhatareOSLshadersgoodfor?WhenshouldyouconsiderprogrammingashaderinOSL?Youmightdoitforfunofcoursebuteventhenyouneedtobalancethecostsversustheprofits.Afterallittakestimetolearnanewlanguageandimplementingandmaintainingshaderstakessomeefforttoo.SowhenistherereallyaneedtoimplementashaderinOSL?Thefollowingcriteriamayhelpyoudecide:
AshaderwouldbeimpossibleorveryhardtocreateinBlender'snodesystem
Thisisthemostclearcutcriterion.Blender'snodesystemisimmenselypowerfulbutstillsomethingsareimpossible.ForexampleOSLprovidesnoisetypeslikeGabornoisethatyoumightwanttousebutthatBlender'snodesystemdoesnotprovide(yet).Regularpatternsarealsoquitedifficultorimpossibletogeneratewithnodesbecausethenumberofregulartextureinputsislimitedtowave,gradient,checkerandbrick.Evenifpossibleanodesystemmightneedanenormousamountofnodes.Likewiserandomdistributionsofregularelementslikeripplesonapondcausedbyraindropsarehard.Basicallyanythingthatisnaturallyexpressedasarepetition(aprogrammedloop)orhasmanydecisionstomake(manyif/elsestatements)isgenerallyeasiertoprogramthantoconstructfromnodes.
Ashaderbasedonnodeswouldtaketomuchmemory
Ifyourshaderwoulduseimagetexturesyouwouldneedlargeonestobeabletozoomincloseandgetgoodresultseveniftheshadedpartcoversonlyafewpixels.AproceduralshaderlikeoneimplementedinOSLwouldtakethesameamountofmemoryregardlesswhetheryouneedhighorlowresolution.Ofcourseit'softeneasiertouseimagetexturesbutifsizemattersyoumightwanttocreatesuchtexturesprogrammatically.Beingabletoproduceatextureatanylevelofdetailmightalsopreventaliasingeffectsandadditionallyprogrammedshadersoftendon'tdependonuv-unwrapping.Notdependingonuv-mapssavestimebecauseyoudon'thavetocreateonebutalsomightgetridofseams.(whenuv-unwrappingyouhavetomakesurethatseamsareinvisibleorlineupwiththeedgesofatileableimage.)
Ashaderbasedonnodeswouldbetooslow
Blender'snodesystemisn'tslowatallbutifyouneedverymanynodestoimplementyourshader,asolutionthatisbundledinasingleOSLshadermightbequiteabitfaster.Ontheotherhand,OSLshadersarecurrentlylimitedtoexecutionontheCPUandthereforecannotbenefitfromthepotentiallymustfasterGPU.
SotherealanswertothequestionofwhentouseanOSLshaderis,aswithmostnon-trivialquestions:"itdepends".Itispossiblyeasiesttocobbletogetherafirstapproximationoftheshaderyouhaveinmindfromnodes.Ifindoingsothenumberofnodesneededincreasesquicklyoryou
6
encounterthingsthatcannotbedoneatall,considerwritinganOSLnode.
7
ReadinghintsTypesettingabookcontainingafairamountofsourcecodeisfiendishlydifficult,especiallybecauseyouhavetoallowfortheverysmallwidthofsomereadingdevices.Thereforethecodeisformattedtofitveryshortlinewidthsbutthatmightattimesnotbeverycomfortabletoread,inwhichcaseIrecommendlookingattheoriginalsourcecode(seebelow)whichisgenerallynotformatted.
Itmightalsobeagoodideatoturnoffoverridingthestylesheetsassociatedwiththise-book.Manye-readers(notablyAldiko)dothisbydefault,whichisfinefornon-fictionbutforbookswithlotsofillustrationsthisdoesn'tlookgood.Disablingthisoverrideletyouenjoythebookbetter.Inmostreadersitisstillpossibletoseparatelysetthesizeofthetext.
CodeavailabilityThesourcecodeshowninthebookisfreelyavailableonGitHub:https://github.com/varkenvarken/osl-shadersThesourcecodeislicensedasopensourceunderaGPLv3license.
Note:allexampleshadersinthisbookarepresentasan.oslfileintheShadersdirectorybutforeachshaderfilethereisalsoanaccompanying.blendfilewiththesamenamethatdemonstratesitsuse.Simplybyopeningthisfileandselecting'Rendered'asdisplaymodeinthe3dviewwillshowcasetheshader.(WhenopeningthefileBlendersetsthedisplaymodetosolidsoitisnecessarytoresetthistorenderedtoseetheeffect.)
8
AverysimpleshaderFocusareas
howtoprepareBlendertouseOpenShadingLanguagecreatingyourfirstOSLshadertroubleshooting
PreparingBlender
BecausemosterrorsthatmayoccurwhenworkingwithOSLwillappearintheconsole,itisagoodideatomakesuretheconsoleisvisible.Forunix-likesystemslikeLinuxorOSXthisisdonebystartingBlenderfromacommandline(forexampleanxterm).ForWindowsaconsolecreatedafterBlenderhasstartedbyselectingWindow -> Toggle console.
DonotconfusethisconsolewithBlendersbuilt-inPythonconsole,thatisacompletelydifferentandunrelatedentity.
OSLiscurrentlyonlyavailableforCycles(notforBlendersinternalrenderer)sowehavetocheckifallprerequisitesaremet.
OpenanewBlenderfilewithjustasingleobject,alampandacamera.
Ifyouhaven'tchangedyourstartuppreferencesthedefaultstartupwilldooralternativelyyoumaydownloadandopenblank.blendfromtheShadersdirectoryinthecodeaccompanyingthisbook,
verifythatyouhaveselectedCyclesasyourrendererasshowninthescreenshot
verifythatyouwillusetheCPUtorender
(nottheGPUasOSLiscurrentlyonlyavailableontheCPU)File -> User Preferences -> System
,
verifythatOSLisenabled
ChecktheOpenShadingLanguageboxintheproperties.
9
Toverifythateverythingisworkingasexpectedyoumustbeabletoworkwiththenodeeditor.Asuggestedlayoutisshownbelow(thatisthelayoutthatblank.blendhas)
blank.blendhasadefaultnodebasedmaterialalreadyassignedtoitsplanebutiftheobjectinyourstartupfilehasnomaterialyoucansimplyassignanewonebyselectingtheobjectandclickingNewinthenodeeditor.
CreatingyourfirstOSLshader
Ifyouhavewrittenashaderthefollowingstepsareneededtouseitaspartofanodebasedmaterial:
addanewscriptnode,pointittothecodeyouhavewritten,connectthesocketstoothernodes.
Letshaveacloserlookateachofthesesteps.
TouseashaderasanewnodeinBlendersCyclesrendererwemustaddaScriptnodetoanodebasedmaterial.ClickAdd->Script->Scriptinthenodeeditormenuandanewnodeisaddedto
10
yourmaterial.Itdoesn'thaveanyinputoroutputsocketsyetbutitdoesletyouchooseeitheranexternalscript(=OSLcodethatresidesinatextfileondisk)oraninternalscript(=OSLcodepresentinoneofBlenderstexteditorbuffers)
Eachmethodisfinebutbothhavetheirprosandcons.Anexternalfileiseasiertodistributeonitsownandmaybemaintainedaspartofaseparatecollectionofshaderswhileashadercontainedinthetexteditorisapartofyour.blendfileandwillbesavedwiththerestofyourscene.BlenderstexteditorissufficientforsmallshadersbutforlargershadersusinganexternaleditorisoftenpreferableandifyoudownloadshadersfromtheShadersdirectoryinthecodeaccompanyingthisbookyoucanselectExternalandusethefilebrowserthatopenstopointtothedownloadedfile.
SelectExternalandclickonthetextfieldtoopenafilebrowser,chooseShaders/firstshader.oslandconfirmyourchoiceoralternatively,selectInternal,copythecodeshownbelowtotheinternaltexteditorandclickonthetextfieldtoselectyourinternaltextfile.
Whenyouselecteitheraninternaltextbufferoranexternalfile,theshaderiscompiledautomaticallyandifeverythingwentwellsomeinputandoutputsocketswillappear.
Ifsomethingwentwrongwhilecompilingtheshaderashortmessageisshowninthetopmenubar
andpossiblyadditionalinformationisshownontheconsole.Ifthathappens(andifyouwriteashaderyourselfinsteadofusingadownloadedsampleshaderthisisverylikelytohappenbecausewritinganewnon-trivialshaderwithoutanysyntaxerrorsinonegoishighlyimprobable),fixtheerrorsandclicktherecompilebutton(thebuttonontherightsideofascriptnodenexttothetextfield.
firstshader.oslisashaderwithjustoneinputsocket,acolor(andhenceshownwithayellowdot)andoneoutputsocket,alsoacolor.Youmayconnectitsoutputsockettothecolorinputofthe
11
diffuseshaderofyourmaterialasshowninthescreenshot.
Ifyounowselect'Rendered'inthe3dviewmenu
youseethattheshaderhastakenthedefaultbrightwhiteinputcoloranddarkeneditsignificantly.Letshavealookathecodeforfirstshader.oslandseehowthishascomeabout:
01. shader darken(02. color In = 1,03. output color Out = 104. ){05. Out = In * 0.5;06. }
Notethatthelinenumbersprecedingthecodeareforreferenceonlyandnotpartoftheshadercode.
Thefirstlinedeclaresagenericshadercalleddarken(therearemoretypesofshaderinOSLbutnotallarecurrentlysupportedbyBlender.Mostshadersinthisbookaredefinedasgenericshaderswiththeshaderkeyword.Whenweencounterdifferentshaderslaterontheirdifferenceswillbeexplained).
AshaderlookslikeafunctionwithparametersandthesecondlinedefinesainputparametercalledIn.Thetypeofthisparameteriscolor(oneofthebasictypesofOSL)anditsdefaultvalueis1,meaningthatallthreecomponentsofthecolor(red,greenandblue)willbesettoonemakingthedefaultcolorbrightwhite.
ThenextlinedefinesaparameterOut,whichisalsoacolorwiththedefaultsetto1,i.e.white.Itismarkedasanoutputparameterbytheoutputkeyword.Whentheshaderiscompiled,Blenderadds
12
socketstothenodeforeachparameter.Inputparameterswillappearassocketsontheleftsideofthenodeandoutputparameterswillappearontheright.Blenderwillcolorthesesocketsbasedontheirtypes,withyellowforcolorparameters.
Allparametersmustbedefinedwithadefault.Thedefaultofaninputparameterisusedifnoothernodesareconnectedtothissocket.Ifaninputsocketisnotconnecteditsvaluecanbechangedbytheenduserbyclickingonit.Dependingonthetypeofsocketasuitableeditorwillpopup,forexampleacolorpickerifitisacolor.Avalueofanunconnectedinputsocketcanevenbeanimated(byinsertingakeyframebyhoveringoveritwiththemouseandpressingI),justlikealmosteverythingelseinBlender.
Thedefaultvalueofanoutputsocketisusedifnowhereinthebodyoftheshaderavalueisassignedtoit.
Thebodyofthisshaderconsistofasingleline(line5)thatmultipliestheInvalueby0.5andassignsittotheOutparameter.Multiplyingacolorbyasinglevaluewillmultiplyeachcomponentbythatvaluesointhisexamplewedarkenallcolorcomponentsbythesameamount.
ThisexampleshaderisofcourseaboutassimpleasashadercanbeandmaybenotallthatusefulbutitdoesshowhowBlendertakescareofmuchoftheworkofmakinganewnodeusablebyaddingsocketswithappropriateeditorstothenewnodebasedonthetypesoftheinputandoutputparameters.
Troubleshooting
Whenyouusescriptnodesafewthingsmaygowrongbesideyourscripthavingsyntaxerrors.Mostconfigurationerrorswon'tevenshowupaserrorsontheconsoleandoftenallyouseethenisthatyourmaterialappearsblackwhenrendered.Themostcommononesare:
youcannotaddascriptnode
whenyouclickaddinthenodeeditorandyoudon'thaveachoicelistedcalled'Script'youprobablyforgottoselectCyclesasyourrenderenginebecausetheinternalrendererdoesn'tsupportscriptnodes.(InBlenderversionsbefore2.68therewasaScriptentryfortheinternaleditorbutclickingithadnoeffect)
compilationgoeswellbutthematerialshowsupasauniformcolor
youforgottochecktheOSLbuttonintherenderoptions
thereisnoOSLbuttonintherenderoptions
thisoptionisonlyavailableifyouuseCyclesasyourrenderengineandselectCPUrendering
13
14
DatatypesFocusareas
Simpledatatypes(numbers,strings,vectors,colors)Compounddatatypes(arrays)Userdefineddatatypes(structs)
OSLhasseveraldatatypesthatmaybeusedtorepresentnumericalvaluesandstringsbutalsothingslikepoints,vectororcollectionsofthesevalues.Thissectiongivesabriefoverviewofthemostimportantissuestogetyoustartedquickly.Thisoverviewisbynomeanscomplete:fordetailsyoubestrefertochapter5oftheOSLlanguagespecification.
Simpledatatypes
int
anintrepresentspositiveandnegativeintegervalues.Allintegeroperationsfoundinmostprogramminglanguagesaresupported(includingmodulo%andthebitwiseoperatorsand&,or|andxor^).Integersareatleast32bitswide(i.e.mayholdvaluesabout±2000,000,000butdependingonyourplatformmuchlarger64bitwideintegersmaybeimplemented.Don'tdependonthisifyouwanttowriteportableshaders!).Anintisalsousedasabooleanvaluewhere0equalsfalseandanyothervaluetrue(OSLdoesn'thaveanexplicitbooleantype.Infactallsimpletypesmaybeusedasbooleanvalues,eachwithitsownrulesforwhichvaluesareconsideredtrue.Inthisbookwesticktointvaluesforbooleans.RefertotheOSLlanguagespecificationfordetails).
example:
int a = 4;int b = a * 5;
float
afloatrepresentspositiveandnegativefractionalvalues.Itcanatleastrepresentvaluesassmall1e-35orasbigas1e35with7decimalsofprecision(tobepreciseitisatleasta32bitfloatconformingtotheIEEEspecification.Onsomeplatformsthismaybea64bitfloatwithmoreprecisionandawiderrangebutdon'tdependonitifportabilityisimportant).Anywhereafloatisusedanintmaybeusedaswell;itwillbeautomaticallyconvertedtoafloat.Alltheusualoperationsaresupportedforfloatsandthereiswholehostofstandardfunctionsavailableaswell,includingtrigonometricfunctions,exponentiation,etc.
15
example:
float a = -1.4;float b = sin(a*1e-3);
string
astringisasequenceofcharacters.Itsmainuseisinspecifyingfilenamesoftextures.Theoperationsarechieflylimitedtocomparisonsbutafairnumberofstandardfunctionsareprovidedaswell,includingsupportforregularexpressions.
example:
string a = "filename.png";
void
Voidisnotavaluepersebutusedtoexplicitlysignifytheabsenceofavalue,forexampleaswithafunctionthathasonlysideeffectsbutdoesn'treturnanything.
pointlikedatatypes
pointlikedatatypeshaveincommonthattheyallconsistofthreefloatingpointvaluesandthattheyallshareacommonsetofoperationslikemultiplicationandaddition.Theydifferinsubtledetailsundersomeconditionsbutfornowwecantreatthemasequalbutwithanamethatrelatestotheirpurpose.Thecomponentsofapointlikedatatypecanbeaccessedwithanindexthatstartsa0forthefirstcomponent.Operationsbetweenapointliketypeandafloatwillperformtheoperationonallthreecomponentsindividually.Thisincludesassignment:inthecodebelowweassignthevalue7toallcomponentsofthevariableb.
example:
point a = point(1,0,0);point b = point(0,1,0);vector v = a - b;normal n = cross(a,b);a[0] = 3;b = 7;b = b + v * 5;
point
apointisusedtorepresentalocationorpositionintheworld,suchasthelocationoftheobject
16
beingshaded.Youcanaddtopointstotranslatethem,multiplytoscalethemorcallthebuilt-infunctionrotate()torotatethemaroundanaxis
vector
avectorrepresentsadirectionoralinesegmentbetweenpoints.Itispossibletotranslate,scaleandrotatetheminthesamewayaspointsandOSLprovidesanumberoffunctionstoperformcommonvectoroperationsincludingcalculationitslength,normalizingitandcalculatingthecrossanddotproductoftwovectorstonameafew.
Thesefunctionsarejustashappytoacceptpointsornormalsbutmostoftenwethinkofthesefunctionsinthecontextofvectors.Manyshadersinthisbookusevectorsandsomebasicunderstandingofthemisnecessarybutinmostcasestheiruseisexplainedindetail.EspeciallythefirstfewshadersthatwewillencounterinthethenextchapterintroducenotonlyhowtouseOSLasalanguagebutwillimplementafewshadersthatperformsomebasicvectoroperationsjusttogetfamiliar.
normal
anormalisavectorthatdenotesadirectionperpendiculartosomething,oftenafaceofamesh.Anythingyoucandowithapointoravectoryoucandowithanormalaswellbutbecausethedirectionperpendiculartoasurfaceplayssuchanimportantroleindesigningshadersitsusefultohaveaseparatenameforsuchavector.(Whenweencounterclosures(=lightscatteringfunctions)wewillseethattheseclosuresdefinewhichfractionoftheincominglightisreflectedrelativetothenormal.Forexamplewhenlightisreflectedfromaperfectmirrortheangleofthereflectedlightrelativetothesurfacenormalisthesameastheangleoftheangleoftheincominglightrelativetothesurfacenormal)
color
acolorisnotpointlikeinthesensethatithasageometricalsignificancebutitdoeshavethreecomponents(hererepresentingthered,blueandgreencomponentsofacolor)andsharesoperationswiththegeometricaltypeslikeindexing,addition,etc.Inmanycasesnoneofthecomponentswillhaveavaluegreaterthanonebutthisisnotmandatory.
matrix
Amatrixisnotpointlikeatallbutacollectionof4x4floatsthatismainlyusedtotransformpointlikedatatypes.BecauseOSLprovidesalotofstandardfunctionsforpointliketypessuchasrotationandtransformationsbetweendifferentvectorspaces,wewillnotusethematrixtypeinthisbook.
17
aggregatetypes
Ifwewanttomanipulatemorethanonesimplevalueasoneitemweneedsomewaytoaggregatethem.ForthispurposeOSLoffersarraysandstructs.
array
Anarrayisalistofitemsofthesametype.Eachofthosecanbeaccessedbyusinganindexinthesamewayascomponentsofpointliketypesmaybeaccessed.Thelengthofanarrayisfixedonceitisdeclared.
example:
float a[4];float b[3] = { 3, 4, 5 };point c[5];a[2]=b[1]*8;int alength = arraylength(a);
Notethatthefirstelementofanarrayhasanindexof0.Inthefirstlinewedefineanarrayawithfourelements.Thebarrayisdefinedwiththreeelementsandtheyareeachinitializedtoavalue.Asthecarrayshows,arraysarenotlimitedtofloatvaluesbutmaybepoint-liketypesaswell.
struct
Astructisacollectionofitemsofdifferenttypes.Eachofthosecanbeaccessedbyname.Astructissomewhatlikeanewtype:Onceyouhavedefinedastructyoucanuseittodeclarevariables.
example:
struct ray{ point start; vector direction;};
ray view = { point(0,0,0), vector(0,0,1) };view.point[2] = 5;
18
ControlstructuresFocusareas
makingdecisions,if/elsestatementsrepeatingactivities,forandwhileloops
Likeanyprogramminglanguageworthitssalt,OSLhasitsshareofcontrolstructurestomakedecisionsandrepeatactions.ThesecontrolstructuresarealmostidenticaltothosefoundinCorC++andaredocumentedindetailinthelanguagespecification.Inthissectionwegiveashortoverviewinthecontextofsomesimpleshaderstogetafeelingforwhatispossible.
Leftorright,youdecide
Makingdecisionsandgeneratingdifferentoutputbasedonsomeconditionispresentinalmosteveryshaderbutthemosttrivial.Inourexampleshaderwewanttoproduceanoutputvalueof1ifaninputvalueliesbetweentogivenlimits.Suchashadernodemightbeusedforexampletoproducesharpedgedareasfromasmoothnoiseinput.Anexampleisshownintheimagetogetherwithanodesetup.
Thecodethatimplementsthisshaderisshownbelow:
ThecodeisavailableinShaders/range.osl
01. shader range(02. float Value = 0,03. float Low = 0,04. float High = 0,05. 06. output float Fac = 0
19
07. ){08. if( Value >= Low && Value <= High ){09. Fac = 1;10. }11. }
Theshaderhasthreeinputparameters:theValuewewanttotestandtheLowandHighvaluesthatspecifytherangethatwillreturnavalueof1.Theresult,either0or1,isreturnedinthesingleoutputparameterFac.
Thebodyofthecodeconsistsofasingleifstatement(line8).Anifstatementconsistsofanexpressionbetweenparenthesesandbody.Thebodyconsistsofasinglestatementoragroupofstatementsbetweencurlybracesandisonlyexecutediftheexpressionoftheifstatementevaluatestonon-zero.Becauseifstatementsmaybenested(thebodymaycontainotherifstatements)itmightbecomeunclearwhatthestructureofthecodeissointhisbookwealwaysusethecurlybraces,evenifthereisjustasinglestatementinthebodytoclearlyindicatewhichpieceofcodebelongstowhichifstatement.
Theexpressionofanifstatementmaybearbitrarilycomplex.Herewecheckifthevalueislargerorequaltothelowerlimitandcombinethiswithachecktoseeifthevalueislessthanorequaltotheupperlimit.The&&operator(logicaland)indicatesthatbothconditionsshouldbetrue.AlistofalloperatorsthatcanbeusedcanbefoundintheOSLlanguagespecification,chapter6.Ifexpressionsarecomplexortheprecedenceofoperatorsmakesitnecessary,parenthesesmaybeusedtogrouppartsoftheexpression.Inthiscaseweassignthevalue1totheoutputparameterFaciftheconditionistrue.
Inthepreviousexampleweassignedadefaultvaluetoanoutputparameterandchangedthisvalueifaconditionwasmet.Sometimeshoweverwewanttotakedifferentactionsiftheconditionisnotmet.Forthispurposetheifstatementhasanoptionalelsepart.
Intheshaderpresentedbelowwewanttoproducethreedifferentoutputcolors,dependingonaninputvaluebeingbelow,insideoraboveagivenrange.
20
Thecodefortheshaderisgivenbelowandcomparedtotherangeshaderthisshaderhasthreeextrainputparameters,thecolorswewanttochoosefrom.Thesingleoutputparameteristhechosencolor.
CodeavailableinShaders/colorrange.osl
01. shader colorrange(02. float Value = 0,03. float Low = 0,04. float High = 0,05. color LowColor = 0,06. color MidColor = 0.5, // grey07. color HighColor = 1,08. 09. output color Color = 010. ){11. Color = LowColor;12. if( Value >= Low && Value <= High ){13. Color = MidColor;14. } else {15. if( Value > High ){16. Color = HighColor;17. }18. }19. }
ThefirstlineassignsLowColortotheoutputparameterasadefault.Theifstatementagaincheckswhethertheinputvalueisinthespecifiedrangebutifthisnotthecasetheelsepart(line14)isexecuted.Thiselsepartcontainsagainanifstatementthatchecksiftheinputvalueisabovetheuppervalueiftherangeandifso,assignsHighColortotheoutputparameter.Notethatinthis
21
exampleagainnoneofthecurlybracesintheifstatementswereneededbutweusedthemanywaytogetherwithconsistentindentationtoavoidconfusion.
IfearImightberepeatingmyself
Makingdecisionsisafundamentalfeatureofaprogramminglanguageandsoistheabilitytorepeatanactionagivennumberoftimes.TothisendOSLofferstheforstatementwhichisusedinthenextshadertoproduceagivennumberofstripes.
CodeavailableinShaders/stripes.osl
01. shader stripes(02. point Pos = P,03. int Number = 4,04. 05. output float Fac = 006. ){07. float x = mod(Pos[0],1);08. 09. int i;10. for(i=1; i <= Number; i++){11. if( x < (float)i/Number ){12. Fac = i % 2;13. break;14. }15. }16. }
Theinputparametersofthestripesshaderarethepositionbeingshaded(Pos)andthenumberofstripeswewanttoproduce(Number).ThesingleoutputparameterFacwillbeeither0or1foralternatingstripes.
22
Inthebodyoftheshaderwemakesurethatthevalueofthexcoordinateisintherange[0,1]bycalculatingthexcomponentofthepositionbeingshadedmoduloone.Thisguaranteesthatforlargervaluesofxthepatternthatwegenerateforthe[0,1]rangeisrepeated.
Theforstatementrepeatsthestatementsinitsbodyasoftenasspecifiedbythethreesemi-colonseparatedexpressionsbetweenparentheses(line10).Aswiththebodyoftheifstatementthecurlybracesareoptionalifthebodyconsistsofasinglestatementbutinthisbookwealwaysusethem.
Thefirstexpressionfollowingtheforkeywordinitializesthecontrolvariablei.Thesecondexpressionisaconditionandaslongasthisconditionistruethebodyoftheforstatementisexecuted.Thethirdexpressionisevaluatedaftereachexecutionofthebodyandisusedtoincrementthecontrolvariableby1.(Theexpressionsinaforstatementarenotlimitedtoonesaffectingacontrolvariable.Detailscanbefoundinthelanguagespecification)
Thebodyoftheforstatementitselfconsistsofasingleifstatement.Theexpressioninthisifstatementchecksifthexcoordinateissmallerthantheupperlimitofthestripewearecurrentlychecking.Forexample,ifNumberis4(wewantfourstripes)thefirsttimewecheckthisexpressionisx < 1/4(istartscountingfromonebecausethatisthevaluewegaveitintheinitializationexpressionoftheforstatement).Thesecondtimearoundthisexpressionisx < 2/4(becauseafterthefirstexecutionofthebodyoftheforstatementthecontrolvariableiwasincrementedby1).Notethatwehadtocasttheivariabletoafloattomakesurethatthedivisionresultedinafraction.Hadwenotdonethiswewouldhavebeendividingintegersandwewouldhavegotthevalue0insteadofafraction.
Iftheexpressionevaluatestotrue,weassigntheoutputvariableFacthevalueofthecontrolvariableimodulo2.Thiswillalternatebetween0an1dependingonwhetheriisevenorodd.Iftheexpressionistruewenotonlyassignavaluetotheoutputparameterbutstopexecutingtheforstatementaltogether.Thisisdonewiththebreakstatement.Ifwewouldexecutetheremaining
23
iterationsofforloopthetestwouldevaluatetotrueagain(ifxissmallerthan1/4itisalsosmallerthan2/4,3/4,etc.)soweneedtobreakoutofthelooptopreventassigningthewrongvaluetotheoutputparameter.
Wearenotalwaysinthepositiontodeterminebeforehandhowmanyrepetitionsareneeded.Inthosecasesitmightbebettertouseawhileloop,whichwillexecuteitsbodyaslongasanexpressionistrue.
Inthisexampleshaderwedonotwanttoproduceafixednumberofstripesbutstripsthatgetprogressivelysmalleruntiltheyaredeemedsmallenough.Thislowerlimitonthewidthofthestripsisaninputparameter.
Thecentralideaintheimplementationpresentedhereistocheckifthex-coordinateisbelowacertainlimitandifnot,extendthislimitwithavaluedxandcheckagain.OneachsuccessiveiterationthisvaluedxisdiminishedbyaquarteruntilitissmallerthaninputparameterLimit.
CodeavailableinShaders/smallerstripes.osl
01. shader smallerstripes(02. point Pos = P,03. float Limit = 0.01,04. 05. output float Fac = 006. ){07. float x = mod(Pos[0],1)*2;08. float dx = 0.5;09. float xlimit = dx;10. 11. float ActualLimit =
24
12. Limit>0.001 ? Limit : 0.01;13. while( dx >= ActualLimit ){14. if( x < xlimit ){15. break;16. }17. Fac = abs(Fac-1);18. dx *= 0.75;19. xlimit += dx;20. }21. }
TopreventanendlessloopwecheckifLimitislargerthansomesmallvalueandifso,assignittothevariableActualLimit.Ifnotwetake0.001asasafeminimum.Therearetwothingsworthnotinghere:WeneedthisextravariableActualLimitbecauseaninputparameterlikeLimitisreadonly,wecannotchangeitsvalue.Alsoyoumightwonderwhatthestrangeexpressionontherighthandsideoftheassignmentdoes(line12).Thisisinfactjustanifstatementdisguisedasanexpression,anidiomdirectlycopiedfromtheClanguage.Thevalueoftheexpressiona ? b : cisequaltobifaistrue(nonzero)andcifaisfalse.
Thewhilestatementconsistsofanexpressionbetweenparenthesesandabody(line13).Thebodyisexecutedaslongastheexpressionistrue.Thebodymightconsistofasinglestatementorseveralstatementsenclosedincurlybraces.Forclaritywewillalwaysusecurlybraces,justaswedoforifandforstatements.
Thebodyofthewhileloopcontainsanifstatementthatchecksifthex-coordinateisbelowthecurrentlimit.Ifso,webreakoutofthewhileloop.SincetherearenostatementsfollowingthewhileloopthismeansthattheoutputparameterFacwillholdwhatevervalueitisholdingatthatinstant.Therefore,ifthex-coordinatewasnotbelowthecurrentlimitwemustnotonlyextendthelimitagainstwhichwewillcheckinthenextiterationbutalsoflipthevalueofFac.Facisafloatingpointvalueandtheexpressionabs(Fac-1)isonewaytoconvertavaluefrom0to1andviceversa.
Thefinaltwolinesofthebodyshortenthewidthdxofthestripeby25%andaddthiswidthtothexlimitvariable.
25
This is the end of the sample.
If you would like to purchase the full version or if you are interested in my other books, please visit
https://cgcookiemarkets.com/vendor/varkenvarken/