93
Open Shading Language 1.6 Language Specification c Copyright 2009-2014 Sony Pictures Imageworks Inc., et al. All rights reserved. Editor: Larry Gritz [email protected] Date: 14 Nov, 2014

Osl Languagespec

Embed Size (px)

DESCRIPTION

OSL Language Specification

Citation preview

Open Shading Language 1.6Language SpecicationcCopyright 2009-2014 Sony Pictures Imageworks Inc., et al. All rights reserved.Editor: Larry [email protected]: 14 Nov, 2014iiThe Open Shading Language specication, source code, and documentation are:Copyright (c) 2009-2014 Sony Pictures Imageworks Inc., et al. All Rights Reserved.The code that implements Open Shading Language is licensed under the BSD 3-clause (alsosometimes known as new BSD) license:Redistribution and use in source and binary forms, with or without modication, are per-mitted provided that the following conditions are met:Redistributions of source code must retain the above copyright notice, this list of condi-tions and the following disclaimer.Redistributions in binary form must reproduce the above copyright notice, this list of con-ditions and the following disclaimer in the documentation and/or other materials providedwith the distribution.Neither the name of Sony Pictures Imageworks nor the names of its contributors maybe used to endorse or promote products derived from this software without specic priorwritten permission.THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIB-UTORS AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUTNOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-NESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THECOPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUD-ING, BUT NOT LIMITEDTO, PROCUREMENT OF SUBSTITUTE GOODS ORSERVICES;LOSS OF USE, DATA, ORPROFITS; ORBUSINESS INTERRUPTION) HOWEVERCAUSEDAND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABIL-ITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAYOUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OFSUCH DAMAGE.This specication and other text documentation about Open Shading Language is licensedunder a the Creative Commons Attribution 3.0 Unported License.http://creativecommons.org/licenses/by/3.0/Open Shading Language SpecicationContents1 Introduction 12 The Big Picture 53 Lexical structure 113.1 Characters. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113.2 Identiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113.3 Comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113.4 Keywords and reserved words . . . . . . . . . . . . . . . . . . . . . . . . . . 123.5 Preprocessor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124 Gross syntax, shader types, parameters, functions 134.1 Shader types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134.2 Shader parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144.3 Shader metadata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164.4 Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204.5 Public methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205 Data types 235.1 int . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235.2 float . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245.3 color . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255.4 Point-like types: point, vector, normal . . . . . . . . . . . . . . . . . . . . 265.5 matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295.6 string . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305.7 void. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305.8 Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305.9 Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315.10 Closures. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326 Language Syntax 336.1 Variable declarations and assignments . . . . . . . . . . . . . . . . . . . . . . 336.2 Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356.3 Control ow: if,while,do,for . . . . . . . . . . . . . . . . . . . . . . . 386.4 Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40iiiiv CONTENTS6.5 Global variables. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 407 Standard Library Functions 437.1 Basic math functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 437.2 Geometric functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 467.3 Color functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 497.4 Matrix functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 507.5 Pattern generation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 517.6 Derivatives and area operators . . . . . . . . . . . . . . . . . . . . . . . . . . 557.7 Displacement functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 567.8 String functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 567.9 Texture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 597.10 Material Closures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 667.11 Renderer state and message passing . . . . . . . . . . . . . . . . . . . . . . . 707.12 Dictionary Lookups. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 727.13 Miscellaneous. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 748 Formal Language Grammar 759 Describing shader groups 81A Glossary 85Index 87Open Shading Language Specication1 IntroductionWelcome to Open Shading Language!Open Shading Language (OSL) is a small but rich language for programmable shading inadvanced renderers and other applications, ideal for describing materials, lights, displacement,and pattern generation.OSL was developed by Sony Pictures Imageworks for use in its in-house renderer used forfeature lm animation and visual effects. The language specication was developed with inputby other visual effects and animation studios who also wish to use it.OSL is distributed under the New BSD license. In short, you are free to use it in your ownapplications, whether they are free or commercial, open or proprietary, as well as to modify theOSL code as you desire, provided that you retain the original copyright notices as described inthe license.How OSL is different from other shading languagesOSL has syntax similar to C, as well as other shading languages. However, it is specicallydesigned for advanced rendering algorithms and has features such as radiance closures, BSDFs,and deferred ray tracing as rst-class concepts.OSL has several unique characteristics not found in other shading languages (certainly notall together). Here are some things you will nd are different in OSL compared to other lan-guages:Surface and volume shaders compute radiance closures, not nal colors.OSLs surface and volume shaders compute an explicit symbolic description, called a closure,of the way a surface or volume scatters light, in units of radiance. These radiance closures maybe evaluated in particular directions,sampled to nd important directions,or saved for laterevaluation and re-evaluation. This new approach is ideal for a physically-based renderer thatsupports ray tracing and global illumination.In contrast, other shading languages usually compute just a surface color as visible froma particular direction. These old shaders are black boxes that a renderer can do little withbutexecutetoforthisoncepieceofinformation(forexample, thereisnoeffectivewaytodiscover from them which directions are important to sample). Furthermore, the physical unitsof lights and surfaces are often underspecied, making it very difcult to ensure that shadersare behaving in a physically correct manner.12 CHAPTER 1. INTRODUCTIONSurface and volume shaders do not loop over lights or shoot rays.There are no light loops or explicitly traced rays in OSL surface shaders. Instead, surfaceshaders compute a radiance closure describing how the surface scatters light, and a part of therenderer called an integrator evaluates the closures for a particular set of light sources anddeterminesinwhichdirectionsraysshouldbetraced. Effectsthatwouldordinarilyrequireexplicit ray tracing, such as reection and refraction, are simply part of the radiance closure andlook like any other BSDF.Advantages of this approach include that integration and sampling may be batched or re-ordered to increase ray coherence; a ray budget can be allocated to optimally sample theBSDF; the closures may be used by for bidirectional ray tracing or Metropolis light transport;and the closures may be rapidly re-evaluated with new lighting without having to re-run theshaders.Surface and light shaders are the same thing.OSL does not have a separate kind of shader for light sources. Lights are simply surfaces thatare emissive, and all lights are area lights.Transparency is just another kind of illumination.You dont need to explicitly set transparency/opacity variables in the shader. Transparency isjust another way for light to interact with a surface, and is included in the main radiance closurecomputed by a surface shader.Renderer outputs (AOVs) are specied using light path expressions.Sometimes it is desirable to output images containing individual lighting components such asspecular, diffuse, reection, individual lights, etc. In other languages, this is usually accom-plished by adding a plethora of output variables to the shaders that collect these individualquantities.OSL shaders need not be cluttered with any code or output variables to accomplish this.Instead, there is a regular-expression-based notation for describing which light paths shouldcontribute to which outputs. This is all done on the renderer side (though supported by the OSLimplementation). If you desire a new output, there is no need to modify the shaders at all; youonly need to tell the renderer the new light path expression.Shaders are organized into networks.OSL shaders are not monolithic, but rather can be organized into networks of shaders (some-times called a shader group, graph, or DAG), with named outputs of some nodes being con-nected to named inputs of other nodes within the network. These connections may be donedynamically at render time, and do not affect compilation of individual shader nodes. Further-more, the individual nodes are evaluated lazily, only their outputs are pulled from the laternodes that depend on them (shader writers may remain blissfully unaware of these details, andwrite shaders as if everything is evaluated normally).Open Shading Language Specication3No uniform and varying keywords in the language.OSL shaders are evaluated in SIMD fashion,executing shaders on many points at once,butthere is no need to burden shader writers with declaring which variables need to be uniform orvarying.IntheopensourceOSLimplementation, thisisdonebothautomaticallyanddynami-cally, meaning that a variable can switch back and forth between uniform and varying, on aninstruction-by-instruction basis, depending on what is assigned to it.Arbitrary derivatives without grids or extra shading points.In OSL, you can take derivatives of any computed quantity in a shader, and use arbitrary quanti-ties as texture coordinates and expect correct ltering. This does not require that shaded pointsbe arranged in a rectangular grid, or have any particular connectivity, or that any extra pointsbe shaded.In the open source OSL implementation, this is possible because derivatives are not com-puted by nite differences with neighboring points, but rather by automatic differentiation,computing partial differentials for the variables that lead to derivatives, without any interventionrequired by the shader writer.AcknowledgmentsThe main developers of OSL are (in order of joining the project):Larry GritzCliff SteinChris KullaAlejandro ContyJay ReynoldsSolomon BoulosAdam MartinezBrecht Van LommelWe cannot possibly express sufcient gratitude to the managers at Sony Pictures Image-works who allowed this project to proceed, supported it wholeheartedly, and permitted us torelease the source, especially Rob Bredow, Brian Keeney, Barbara Ford, Rene Limberger, andErik Strauss.Huge thanks also go to the crack shading team at SPI, and the brave lookdev TDs and CGsupes willing to use OSL on their shows. They served as our guinea pigs, inspiration, testers,and a fantastic source of feedback. Thank you, and we hope weve been responsive to yourneeds.OSL was not developed in isolation. We owe a debt to the individuals and studios whopatiently read early drafts of the language specication and gave us very helpful feedback andOpen Shading Language Specication4 CHAPTER 1. INTRODUCTIONadditional ideas. (I hope to mention them by name after we get permission of the people andstudios involved.)TheopensourceOSLimplementationincorporatesordependsuponseveralotheropensource packages:OpenImageIOc2008 Larry Gritz et al. http://openimageio.orgIlmbase c2006, Industrial Light & Magic. http://www.openexr.comBoost cvarious authors. http://www.boost.orgLLVMc2003-2010 University of Illinois at Urbana-Champaign. http://llvm.orgThese other packages are all distributed under licenses that allow them to be used by anddistributed with Open Shading Language.Open Shading Language Specication2 The Big PictureThis chapter attempts to lay out the major concepts of Open Shading Language, dene keynomenclature, and sketch out how individual shaders t together in the context of a renderer asa whole.Other than the background material of this chapter, the rest of this specication deals strictlywith the language itself. In the future, there will be separate (shorter) documents explaining indetail the use of the language compiler, the renderer-side issues, the library and APIs for how arenderer actually causes shaders to be evaluated, and so on.A shader is code that performs a discrete taskA shader is a program, with inputs and outputs, that performs a specic task when rendering ascene, such as determining the appearance behavior of a material or light. The program code iswritten in Open Shading Language, the specication of which comprises this document.For example, here is a simple gamma shader that performs simple gamma correction on isCin input, storing the result in its output Cout:Outputs{float gam = 1,output color Cout = 1Cout = pow (Cin, 1/gam);}shader gamma (color Cin = 1,gamCinCoutInputs)Theshadersinputsandoutputsarecalledshaderparameters. Parametershavedefaultvalues, specied in the shader code, but may also be given newvalues by the renderer at runtime.Shader instancesA particular shader may be used many times in a scene, on different objects or as differentlayers in a shader group. Each separate use of a shader is called a shader instance. Although all56 CHAPTER 2. THE BIG PICTUREinstances of a shader are comprised of the same program code, each instance may override anyor all of its default parameter values with its own set of instance values.Below is a schematic showing a gamma instance with the gam parameter overridden with aninstance-specic value of 2.2.2.2gammaCin Coutgam(1,1,1)Shader groups and layersA shader group is an ordered sequence of individual shaders called layers that are executed inturn. Output parameters of an earlier-executed layer may be connected to an input parameter ofa later-executed layer.This connected network of layers is sometimes called a shader networkor a shader DAG (directed acyclic graph). Of course, it is ne for the shader group to consist ofa single shader layer.Below is a schematic showing how several shader instances may be connected to form ashader group.layer 5: "wood1"texturemapnamestCouttexturemapnamestCoutlayer 3: "gam1"gammaCin Coutgam 2.2layer 4: "gam2"gammaCin Coutgam 1.0ringsgrainwoodCilayer 2: "tex2"layer 1: "tex1""rings.tx""grain.tx"And here is sample pseudo-code shows how the above network may be assembled using an APIin the renderer1:ShaderGroupBegin()Shader("texturemap", /*shadername*/"tex1", /*layername*/"stringname","rings.tx") /*instancevariable*/Shader("texturemap","tex2","stringname","grain.tx")1This document does not dictate a specic renderer API for declaring shader instances, groups, and connections;the code above is just an example of how it might be done.Open Shading Language Specication7Shader("gamma","gam1","floatgam",2.2)Shader("gamma","gam2","floatgam",1)Shader("wood","wood1")ConnectShaders("tex1", /*layernameA*/"Cout", /*anoutputparameterofA*/"gam1", /*layernameB*/"Cin") /*ConnectthislayerofBtoAsCout*/ConnectShaders("tex2","Cout","gam2","Cin")ConnectShaders("gam1","Cout","wood1","rings")ConnectShaders("gam2","Cout","wood1","grain")ShaderGroupEnd()Or, expressed as serialized text (as detailed in Appendix ??):paramstringname"rings.tx";shader"texturemap""tex1";paramstringname"grain.tx";shader"texturemap""tex2";paramfloatgam2.2;shader"gamma""gam1";paramfloatgam1.0;shader"gamma""gam2";shader"wood""wood1";connecttex1.Coutgam1.Cin;connecttex2.Coutgam2.Cin;connectgam1.Coutwood1.rings;connectgam2.Coutwood1.grain;Geometric primitivesThe scene consists of primarily of geometric primitives, light sources, and cameras.Geometric primitives are shapes such as NURBS, subdivision surfaces, polygons, and curves.The exact set of supported primitives may vary from renderer to renderer.Each geometric primitive carries around a set of named primitive variables. Nearly all shapetypes will have, among their primitive variables, control point positions that, when interpolated,actually designate the shape. Some shapes will also allow the specication of normals or othershape-specic data. Arbitrary user data may also be attached to a shape as primitive variables.Primitive variables may be interpolated in a variety of ways: one constant value per primitive,one constant value per face, or per-vertex values that are interpolated across faces in variousways.If a shader input parameters name and type match the name and type of a primitive variableon the object (and that input parameters is not already explicitly connected to another layersoutput), the interpolated primitive variable will override the instance value or default.Attribute state and shader assignmentsEvery geometric primitive has a collection of attributes (sometimes called the graphics state)that includes its transformation matrix, the list of which lights illuminate it, whether it is one-sided or two-sided, shader assignments, etc. There may also be a long list of renderer-specicOpen Shading Language Specication8 CHAPTER 2. THE BIG PICTUREor user-designated attributes associated with each object. A particular attribute state may beshared among many geometric primitives.The attribute state also includes shader assignments the shaders or shader groups for eachof several shader uses, such as surface shaders that designate how light reects from each pointon the shape,displacement shaders that can add ne detail to the shape on a point-by-pointbasis, volume shaders that describe how light is scattered within a region of space, and lightshaders that describe how light is emitted from a light source. A particular renderer may haveadditional shader types that it supports.Shader execution state: parameter binding and global variablesWhen the body of code of an individual shader is about to execute, all its parameters are bound that is, take on specic values (from connections from other layers, interpolated primitivevariables, instance values, or defaults, in that order).Certain state about the position on the surface where the shading is being run is stored inso-called global variables. This includes such useful data as the 3D coordinates of the pointbeing shaded, the surface normal and tangents at that point, etc.Additionally, the shader may query other information about other elements of the attributestate attached to the primitive, and information about the renderer as a whole (rendering options,etc.).Surface and volume shaders compute closuresSurface shaders (and volume shaders) do not by themselves compute the nal color of lightemanating from the surface (or along a volume). Rather, the compute a closure, which is a sym-bolic representation describing the appearance of the surface, that may be more fully evaluatedlater. This is in effect a parameterized formula, in which some inputs have denite numericvalues, but others may depend on quantities not yet known (such as the direction from whichthe surface is being viewed, and the amount of light from each source that is arriving at thesurface).For example, a surface shader may compute its result like this:colorpaint=texture("file.tx",u,v);Ci=paint*diffuse(N);In this example, the variable paint will take on a specic numeric value (by looking up froma texture map). But the diffuse() function returns a closurecolor, not a denite numericcolor. The output variable Ci that represents the appearance of the surface is also a closurecolor, whose numeric value is not known yet, except that it will be the product of paint and aLambertian reectance.closure colorglobal state variablesprimitive variablesinstance variablestexturesshader codeexecutes(0.5,0.1,0.8) * lambert((0.4,0.3,0.5))The closures output by surface and volume shaders can do a number of interesting thingsthat a mere number cannot:Open Shading Language Specication9Evaluate: given input and output light directions, compute the proportion of light propa-gating from input to output.Sample: given just an input (or output) direction,choose a scattering direction with aprobability distribution that is proportional to the amount of light that will end up goingin various directions.Integrate: given all lights and a view direction, compute the total amount of light leavingthe surface in the view direction.Recompute: given changes only to lights (or only to one light), recompute the integratedresult without recomputing other lights or any of the calculations that went into assem-bling constants in the closure (such as texture lookups, noise functions, etc.).At present,we are assuming that the primitive closure functions (such asdiffuse,ward,cooktorrance, etc.)are all built into the renderer, or implemented as renderer plugins.At alater time, possibly in a later draft or maybe not until a truly later version of the spec, we will fullyspec it out so that closure primitive functions may be written in Open Shading Language. But Ifear that if we do it too soon, well screw it up. But, yes, the eventual goal is for you to be able towrite these primitive functions in the language itself.IntegratorsThe renderer contains a number of integrators (selectable via the renderers API) which willcombine the color closures computed by surfaces and volumes with the light sources and view-dependent information, to yield the amount of light visible to the camera.visible from camerafrom surface shaderlightsglobal variablesviewdependentcolor closureintegratorfinal colorAt present, thisdocument iswrittenasif theintegratorsarebuilt intotherendereritself (orimplemented as renderer plug-ins). At a later time, we intend to make it possible for integratorsthemselves to be written in Open Shading Language.UnitsYou can tell the renderer (through a global option) what units the scene is using for distanceand time. Then the shader has a built-in function calledtransformu() that works a lot liketransform(), but instead of converting between coordinate systems, it converts among units.For example,Open Shading Language Specication10 CHAPTER 2. THE BIG PICTUREdisplacementbumpy(floatbumpdist=1,stringbumpunits="cm"){//convertbumpdisttocommonunitsfloatspacing=transformu(bumpunits,"common",bumpdist);floatn=noise(P/spacing);displace(n);}So you can write a shader to achieve some effect in real world units, and that shader istotally reusable on another show that used different modeling units.It knows all the standard names like "cm", "in", "km", etc., and can convert among any ofthose, as well as between named coordinate systems. For example,floatx=transformu("object","mm",1);now x is the number of millimeters per unit of "object" space on that primitive.Open Shading Language Specication3 Lexical structure3.1 CharactersSource code for Open Shading Language consists of ASCII or UTF-8 characters.The characters for space, tab, carriage return, and linefeed are collectively referred to aswhitespace. Whitespace characters delimit identiers, keywords, or other symbols, but otherthan that have no syntactic meaning. Multiple whitespace characters in a row are equivalent toa single whitespace character.Source code may be split into multiple lines, separated by end-of-line markers (carriagereturn and/or linefeed). Lines may be of any length and end-of-line markers carry no signif-icant difference from other whitespace,except that they terminate// comments and delimitpreprocessor directives.3.2 IdentiersIdentiers are the names of variables,parameters, functions, and shaders. In Open ShadingLanguage, identiers consist of one or more characters. The rst character may be a letter (A-Zora-z) or underscore (_), and subsequent characters may be letters, underscore, or numerals(0-9). Examples of valid and invalid identiers are:opacity //validLong_name42 //valid-letters,underscores,numbersareok_foo //valid-oktostartwithanunderscore2smart //invalid-startswithanumeralbigbuck$ //invalid-$isanillegalcharacter3.3 CommentsComments are text that are for the human reader of programs, and are ignored entirely by theOpen Shading Language compiler. Just like in C++, there are two ways to designate commentsin Open Shading Language:1. Any text enclosed by /* and */ will be considered a comment, even if the comment spansseveral lines.1112 CHAPTER 3. LEXICAL STRUCTURE/*thisisacomment*//*thisisalsoacomment,spanningseverallines*/2. Any text following //, up to the end of the current line, will be considered a comment.//Thisisacommenta=3; //anothercomment3.4 Keywords and reserved wordsThere are two sets of names that you may not use as identiers: keywords and reserved words.The following are keywords that have special meaning in Open Shading Language:breakclosurecolorcontinuedoelseemitfloatforifilluminanceilluminateintmatrixnormaloutputpointpublicreturnstringstructvectorvoidwhileThe following are reserved words that currently have no special meaning in Open ShadingLanguage, but we reserve them for possible future use, or because they are confusingly similarto keywords in related programming languages:boolcasecatchcharclassconstdeletedefaultdoubleenumexternfalsefriendgotoinlinelongnewoperatorprivateprotectedshortsignedsizeofstaticswitchtemplatethisthrowtruetrytypedefuniformunionunsignedvaryingvirtualvolatile3.5 PreprocessorShader source code is passed through a standard C preprocessor as a rst step in parsing.Preprocessor directives are designated by a hash mark (#) as the rst character on a line,followed by a preprocessor directive name. Whitespace may optionally appear between thehash and the directive name.Open Shading Language compilers support the full complement of C/C++ preprocessingdirectives, including:#define#undef#if#ifdef#ifndef#elif#else#endif#includeOpen Shading Language Specication4 Gross syntax, shader types,parameters, functionsThe overall structure of a shader is as follows:optional-function-or-struct-declarationsshader-type shader-name ( optional-parameters ){statements}Note that statements may include function or structure denitions, local variable declara-tions, or public methods, as well as ordinary execution instructions (such as assignments, etc.).4.1 Shader typesShader types include the following: surface, displacement, light, volume, and genericshader. Some operations may only be performed from within certain types of shaders (e.g.,one may only call displace() or alter P in a displacement shader), and some global variablesmay only be accessed from within certain types of shaders (e.g.,dPdu is not dened inside avolume shader).Following are brief descriptions of the basic types of shaders:surface shadersSurface shaders determine the basic material properties of a surface and how it reacts to light.They are responsible for computing a closurecolor that describes the material, and option-ally setting other user-dened output variables. They may not alter the position of the surface.Surface shaders are written as if they describe the behavior of a single point on the primitive,and the renderer will choose the positions surface at which the shader must be evaluated.Surface shaders also are used to describe emissive objects, i.e., light sources. OSL does notneed a separate shader type to describe lights.1314 CHAPTER 4. GROSS SYNTAX, SHADER TYPES, PARAMETERS, FUNCTIONSdisplacement shadersDisplacement shaders alter the position and shading normal (or, optionally, just the shadingnormal) to make a piece of geometry appear deformed, wrinkled, or bumpy. They are the onlykind of shader that is allowed to alter a primitives position.volume shadersVolume shaders describe how a participating medium (air, smoke, glass, etc.) reacts to lightand affects the appearance of objects on the other side of the medium. They are similar tosurface shaders, except that they may be called from positions that do not lie upon (and arenot necessarily associated with) any particular primitive.shader generic shadersGeneric shaders are used for utility code, generic routines that may be called as individual layersin a shader group. Generic shaders need not specify a shader type, and therefore may be reusedfrom inside surface, displacement, or volume shader groups. But as a result, they may notcontain any functionality that cannot be performed from inside all shader types (for example,they may not alter P, which can only be done from within a displacement shader).4.2 Shader parametersAn individual shader has (optionally) many parameters whose values may be set in a number ofways so that a single shader may have different behaviors or appearances when used on differentobjects.4.2.1 Shader parameter syntaxShader parameters are specied in the shader declaration, in parentheses after the shaders name.This is much like the parameters to a englishfunction (or a function in C or similar languages),except that shader parameters must have an initializer, giving a default value for the parameter.Shader parameter default initializers may be expressions (i.e., may be computed rather thanrestricted to numeric constants), and are evaluated in the order that the parameters are declared,and may include references to previously-declared parameters. Formally, the grammar for asimple parameter declaration looks like this:type parametername = default-expressionwhere type is one of the data types described in Chapter 5, parametername is the name of theparameter, and default-expression is a valid expression (see Section 6.2). Multiple parametersare simply separated by commas:type1 parameter1 = expr1 , type2 parameter2 = expr2 , ...Fixed-length, one-dimensional array parameters are declared as follows:type parametername [ array-length ]= { expr0 , expr1 ... }Open Shading Language Specication4.2. SHADER PARAMETERS 15where array-length is a positive integer constant giving the length of the array, and the initializeris a series of initializing expressions listed between curly braces. The rst initializing expres-sion provides the initializer for the rst element of the array, the second expression providesthe initializer for the second element of the array, and so on. If the number of initializing ex-pressions is less than the length of the array, any additional array elements will have undenedvalues.Arrays may also be declared without a set length:type parametername []= { expr0 , expr1 ... }where no array length is found between the square brackets. This indicates that the arrayslength will be determined based on whatever is passed in a connection from the output ofanother shader in the group (take on the length of that output), an instance value (take on thelength specied by the declaration of the instance value), or a primitive variable (length deter-mined by its declaration on the primitive). If no instance value, primitive value, or connectionis supplied, then the number of initializing expressions will determine the length, as well as thedefault values, of the array.Structure parameters are also straightforward to declare:structure-type parametername = { expr0 , expr1 ... }where structure-type is the name of a previously-declared struct type, and the expr initializerscorrespond to each respective eld within the structure. An initializer of appropriate type isrequired for every eld of the structure.4.2.2 Shader output parametersShader parameters are, by default, read-only in the body of the shader. However, special outputparameters may be altered by execution of the shader. Parameters may be designated outputsby use of the output keyword immediately prior to the type declaration of the parameter:output type parametername = expr(Output parameters may be arrays and structures, but we will omit spelling out the obvioussyntax here.)Output parameters may be connected to inputs of later-run shader layers in the shader group,maybequeriedbylater-runshadersinthegroupviamessagepassing(i.e., getmessage()calls), or used by the renderer as an output image channel (in a manner described through therenderers API).4.2.3 Shader parameter exampleHere is an example of a shader declaration, with several parameters:surfacewood(/*Simpleparamswithconstantinitializers*/floatKd=0.5,colorwoodcolor=color(.7,.5,.3),stringtexturename="wood.tx",/*Computedfromanearlierparameter*/Open Shading Language Specication16 CHAPTER 4. GROSS SYNTAX, SHADER TYPES, PARAMETERS, FUNCTIONScolorringcolor=0.25*woodcolor,/*Fixed-lengtharray*/colorpaintcolors[3]={color(0,.25,0.7),color(1,1,1),color(0.75,0.5,0.2)},/*variable-lengtharray*/intpattern[]={2,4,2,1},/*outputparameter*/outputcolorCunlit=0){...}4.2.4 How shader parameters get their valuesShader parameters get their values in the following manner, in order of decreasing priority:If the parameter has been designated by the renderer to be connected to an output param-eter of a previously-executed shader layer within the shader group, that is the value it willget.If the parameter matches the name and type of a per-primitive, per-face, or per-vertexprimitive variable on the particular piece of geometry being shaded, the parameters valuewill be computed by interpolating the primitive variable for each position that must beshaded.If there is no connection or primitive variable, the parameter may will take on an in-stance value, if that parameter was given an explicit per-instance value at the time thatthe renderer referenced the shader (associating it with an object or set of objects).If none of these overrides is present, the parameters value will be determined by execut-ing the parameter initialization code in the shader.This triage is performed per parameter, in order of declaration. So, for example, in the codesample above where the default value forringcolor is a scaled version ofwoodcolor, thisrelationship would hold whether woodcolor was the default, an instance value, an interpolatedprimitive value, or was connected to another layers output. Unless ringcolor itself was givenan instance, primitive, or connection value, in which case thats what would be used.4.3 Shader metadataA shader may optionally include metadata (data about the shader, as opposed to data used bythe shader). Metadata may be used to annotate the shader or any of its individual parameterswith additional hints or information that will be compiled into the shader and may be queriedbyapplications. Acommonuseofmetadataistospecifyuserinterfacehintsaboutshaderparameters for example, that a particular parameter should only take on integer values, shouldhave an on/off checkbox, is intended to be a lename, etc.Open Shading Language Specication4.3. SHADER METADATA 17Metadata is specied inside double brackets[[ and]] enclosing a comma-separated listof metadata items. Each metadatum looks like a parameter declaration having a data type,name, and initializer. However, metadata may only be simple types or arrays of simple types(not structs or closures) and their value initializers must be numeric or string constants (notcomputed expressions).Metadata about the shader as a whole is placed between the shader name and the parameterlist. Metadata about shader parameters are placed immediately after the parameters initial-izing expression, but before the comma or closing parentheses that terminates the parameterdescription.Below is an example shader declaration showing the use of shader and parameter metadata:surfacewood[[stringhelp="Realisticwoodshader"]](floatKd=0.5[[stringhelp="Diffusereflectivity",floatmin=0,floatmax=1]],colorwoodcolor=color(.7,.5,.3)[[stringhelp="Basecolorofthewood"]],colorringcolor=0.25*woodcolor[[stringhelp="Colorofthedarkrings"]],stringtexturename="wood.tx"[[stringhelp="Texturemapforthegrain",stringwidget="filename"]],intpattern=0[[stringwidget="mapper",stringoptions="oak:0|elm:1|walnut:2"]]){...}Themetadataarenotsemanticallymeaningful; thatis, themetadatadoesnotaffecttheactual execution of the shader. Most metadata exist only to be embedded in the compiled shaderand able to be queried by other applications, such as to construct user interfaces for shaderassignment that allow usage tips, appropriate kinds of widgets for setting each parameter, etc.Thechoiceofmetadataandtheirmeaningiscompletelyuptotheshaderwriterand/ormodeling system. However, we propose some conventions below. These conventions are notintended to be comprehensive,nor to meet all your needs merely to establish a commonnomenclature for the most common metadata uses.The use of metadata is entirely optional on the part of the shader writer, and any applicationthat queries shader metadata is free to honor or ignore any metadata it nds.stringlabelA short label to be displayed in the UI for this parameter. If not present, the parametername itself should be used as the widget label.Open Shading Language Specication18 CHAPTER 4. GROSS SYNTAX, SHADER TYPES, PARAMETERS, FUNCTIONSstringhelpHelp text that describes the purpose and use of the shader or parameter.stringpageHelps to group related widgets by page.stringwidgetThe type of widget that should be used to adjust this parameter. Suggested widget types:"number"Provide a slider and/or numeric input.This is the default widget type for float orint parameters. Numeric inputs also may be inuenced by the following metadata:"min", "max", "sensitivity", "digits", "slider", "slidermin", "slidermax","slidercenter", "sliderexponent"."string"Provide a text entry widget. This is the default widget type for string parameters."boolean"Provide a pop-up menu with Yes and No options. Works on strings or numbers.With strings, Yes and No values are used, with numbers, 0 and 1 are used."checkBox"A boolean widget displayed as a checkbox. Works on strings or numbers. Withstrings, Yes and No values are used, with numbers, 0 and 1 are used."popup"A pop-up menu of literal choices. This widget further requires parameter metadata"options" (a string listing the supported menu items, delimited by the | char-acter), and optionally "editable" (an integer, which if nonzero means the widgetshould allow the text eld should be directly editable). For example:stringwrap="default"[[stringwidget="popup",stringoptions="default|black|clamp|periodic|mirror"]]"mapper"A pop-up with associative choices (an enumerated type, if the values are integers).This widget further requires parameter metadata "options", a |-delimited stringwith key:value pairs. For example:intpattern=0[[stringwidget="mapper",stringoptions="oak:0|elm:1|walnut:2"]]Open Shading Language Specication4.3. SHADER METADATA 19"filename"A le selection dialog."null"A hidden widget.floatminfloatmaxintminintmaxThe minimum and/or maximum value that the parameter may take on.floatsensitivityintsensitivityThe precision or step size for incrementing or decrementing the value (within the appro-priate min/max range).intdigitsThe number of digits to show (-1 for full precision).intsliderIf nonzero, enables display of a slider sub-widget. This also respects the following addi-tional metadata that control the slider specically: "slidermin" (minimum value for theslider, "slidermax" (maximum value for the slider), "slidercenter" (origin value forthe slider), "sliderexponent" (nonlinear slider options).stringURLProvides a URL for full documentation of the shader or parameter.stringunitsGives the assumed units, if any, for the parameter (e.g., "cm", "sec", "degrees"). Thecompiler or renderer may issue a warning if it detects that this assumption is being vi-olated(forexample, thecompilercanwarnifa"degrees"variableispassedastheargument to cos).Open Shading Language Specication20 CHAPTER 4. GROSS SYNTAX, SHADER TYPES, PARAMETERS, FUNCTIONS4.4 FunctionsYou may dene functions much like in C or C++.return-type function-name ( optional-parameters ){statements}Parameters to functions are similar to shader parameters, except that they do not permitinitializers. A function call must pass values for all formal parameters. Function parametersin Open Shading Language are all passed by reference, and are read-only within the body ofthe function unless they are also designated as output (in the same manner as output shaderparameters).Like for shaders, statements inside functions may be actual executions (assignments, func-tion call, etc.), local variable declarations (visible only from within the body of the function),or local function declarations (callable only from within the body of the function).The return type may be any simple data type, astruct, or aclosure. Functions maynot return arrays. The return type may be void, indicating that the function does not return avalue (and should not contain a return statement). A return statement inside the body of thefunction will halt execution of the function at that point, and designates the value that will bereturned (if not a void function).Functions may be overloaded. That is, multiple functions may be dened to have the samename, as long as they have differently-typed parameters, so that when the function is called thelist of arguments can disambiguate which version of the function is desired.4.5 Public methodsOrdinary (non-public) functions inside a shader may be called only from within the shader; theydo not generate entry points that the renderer is aware of.A public method is a function that may be directly called by the renderer. Only top-levellocal functions of a shader that is, declared within the braces that dene the local scope ofthe shader, but not within any other such function may be public methods. A function maybe designated a public method by using the public keyword immediately before the functiondeclaration:shader-type shader-name ( params ){public return-type function-name ( optional-parameters ){statements}...}Open Shading Language Specication4.5. PUBLIC METHODS 21A given renderer will publish a list of public methods (names, arguments expected, and returnvalue) that has particular meaning for that renderer. For example, a renderer may honor a publicmethodpublicfloatmaxdisplacement()that computesandreturnsthemaximumdistancethat adisplacement shaderwill moveanysurface points.At some later point, this spec will recommend several standard public methods that shouldbe honored by most renderers.Open Shading Language Specication22 CHAPTER 4. GROSS SYNTAX, SHADER TYPES, PARAMETERS, FUNCTIONSOpen Shading Language Specication5 Data typesOpen Shading Language provides several built-in simple data types for performing computa-tions inside your shader:int Integer datafloat Scalar oating-point data (numbers)pointvectornormalThree-dimensional positions, directions, and surface orientationscolor Spectral reectivities and light energy valuesmatrix 44 transformation matricesstring Character strings (such as lenames)void Indicates functions that do not return a valueIn addition, you may create arrays and structures (much like C), and Open Shading Lan-guage has a new type of data structure called a closure.The remainder of this chapter will describe the simple and aggregate data types available inOpen Shading Language.5.1 intThebasictypefordiscretenumericvaluesisint. Thesizeoftheinttypeisrenderer-dependent, but is guaranteed to be at least 32 bits.Integer constants are constructed the same way as in C. The following are examples of intconstants: 1, -32, etc.Unlike C, no unsigned, bool, char, short, or long types are supplied. This is to simplify theprocess of writing shaders (as well as implementing shading systems).The following operators may be used with int values (in order of decreasing precedence,with each box holding operators of the same precedence):2324 CHAPTER 5. DATA TYPESoperation resultint ++ int post-increment by 1int -- int post-decrement by 1++ int int pre-increment by 1-- int int pre-decrement by 1-int int unary negation int int bitwise complement (1 and 0 bits ipped)! int int boolean not (1 if operand is zero, otherwise 0)int*int int multiplicationint/int int divisionint%int int modulusint+int int additionint-int int subtractionintint int shift rightint=int int 1 if the rst value is greater than or equal to the second, else 0int==int int 1 if the two values are equal, else 0int!=int int 1 if the two values are different, else 0int&int int bitwise andintint int bitwise exclusive orint|int int bitwise orint&&int int boolean and (1 if both operands are nonzero, otherwise 0)int||int int boolean or (1 if either operand is nonzero, otherwise 0)5.2 floatThe basic type for scalar oating-point numeric values is float. The size of the float type isrenderer-dependent, but is guaranteed to be at least IEEE 32-bit oat (the standard C float datatype). Individual renderer implementations may choose to implement float with even moreprecision (such as using the C double as the underlying representation).Floating-point constants are constructed the same way as in C. The following are examplesof float constants: 1.0, 2.48, -4.3e2.An int may be used in place of a float when used with any valid float operator. In suchcases, the int will be promoted to a float and the resulting expression will be float. An intmay also be passed to a function that expects a float parameters, with the int automaticallypromoted to float.Open Shading Language Specication5.3. COLOR 25The following operators may be used with float values (in order of decreasing precedence,with each box holding operators of the same precedence):operation resultfloat ++ float post-increment by 1float -- float post-decrement by 1++ float float pre-increment by 1-- float float pre-decrement by 1-float float unary negationfloat*float float multiplicationfloat/float float divisionfloat+float float additionfloat-float float subtractionfloat=float int 1 if the rst value is greater than or equal to the second,else 0float==float int 1 if the two values are equal, else 0float!=float int 1 if the two values are different, else 05.3 colorThe color type is used to represent 3-component (RGB) spectral reectivities and light ener-gies. You can assemble a color out of three oats, either representing an RGB triple or someother color space known to the renderer, as well as from a single oat (replicated for all threechannels). Following are some examples:color(0,0,0) //blackcolor("rgb",.75,.5,.5) //pinkishcolor("hsv",.2,.5,.63) //specifyin"hsv"spacecolor(0.5) //sameascolor(0.5,0.5,0.5)All these expressions above return colors in "rgb" space. Even the third example returns acolor in "rgb" space specically, the RGB value of the color that is equivalent to hue 0.2,saturation 0.5, and value 0.63. In other words, when assembling a color from components givenrelative to a specic color space in this manner, there is an implied transformation to"rgb"space. Table 5.1 lists the built-in color spaces.Colors may be assigned another color or a float value (which sets all three components tothe value). For example:colorC;C=color(0,0.3,0.3);C=0.5; //sameasC=color(0.5,0.5,0.5)Open Shading Language Specication26 CHAPTER 5. DATA TYPESTable 5.1: Names of color spaces."rgb" The coordinate system that all colors start out in, and in which the rendererexpects to nd colors that are set by your shader."hsv" hue, saturation, and value."hsl" hue, saturation, and lightness."YIQ" the color space used for the NTSC television standard."XYZ" CIE XYZ coordinates."xyY" CIE xyY coordinates.Colors can have their individual components examined and set using the[] array accessnotation. For example:colorC;floatg=C[1]; //getthegreencomponentC[0]=0.5; //settheredcomponentComponents 0, 1, and 2 are red, green, and blue, respectively. It is an error to access a colorcomponent with an index outside the [0...2] range.The following operators may be used with color values (in order of decreasing precedence,with each box holding operators of the same precedence):operation resultcolor [ int] float component access- color color unary negationcolor * color color component-wise multiplicationcolor * float color scalingfloat * color color scalingcolor / color color component-wise divisioncolor / float color scalingfloat / color color scalingcolor + color color component-wise additioncolor - color color component-wise subtractioncolor == color int 1 if the two values are equal, else 0color != color int 1 if the two values are different, else 0All of the binary operators may combine a scalar value (float or int) with a color, treat-ing the scalar if it were a color with three identical components.5.4 Point-like types: point, vector, normalPoints, vectors, and normals are similar data types with identical structures but subtly differentsemantics. We will frequently refer to them collectively as the point-like data types whenmaking statements that apply to all three types.Open Shading Language Specication5.4. POINT-LIKE TYPES: POINT, VECTOR, NORMAL 27Apoint is a position in 3D space. Avector has a length and direction, but does notexist in a particular location. A normal is a special type of vector that is perpendicular to asurface, and thus describes the surfaces orientation. Such a perpendicular vector uses differenttransformation rules than ordinary vectors, as we will describe below.All of these point-like types are internally represented by three oating-point numbers thatuniquely describe a position or direction relative to the three axes of some coordinate system.Allpoints, vectors, andnormalsaredescribedrelativetosomecoordinatesystem. Alldata provided to a shader (surface information, graphics state, parameters, and vertex data) arerelative to one particular coordinate system that we call the "common" coordinate system. The"common" coordinate system is one that is convenient for the renderers shading calculations.You can assemble a point-like type out of three oats using a constructor:point(0,2.3,1)vector(a,b,c)normal(0,0,1)These expressions are interpreted as a point, vector, and normal whose three components arethe oats given, relative to "common" space .Aswithcolors, youmayalsospecifythecoordinatesrelativetosomeothercoordinatesystem:Q=point("object",0,0,0);This example assigns to Q the point at the origin of "object" space. However, this state-ment does not set the components of Q to (0,0,0)! Rather, Q will contain the "common" spacecoordinates of the point that is at the same location as the origin of "object" space. In otherwords, the point constructor that species a space name implicitly species a transformation to"common" space. This type of constructor also can be used for vectors and normals.The choice of "common" space is renderer-dependent, though will usually be equivalent toeither "camera" space or "world" space.Somecomputationsmaybeeasierinacoordinatesystemotherthan"current"space.For example, it is much more convenient to apply a solid texture to a moving object in its"object" space than in "current" space. For these reasons, SL provides a built-in transformfunction that allows you to transform points, vectors, and normals among different coordinatesystems (see Section 7.2). Note, however, that Open Shading Language does not keep track ofwhich point variables are in which coordinate systems. It is the responsibility of the shader pro-grammer to keep track of this and ensure that, for example, lighting computations are performedusing quantities in "common" space.Several coordinate systems are predened by name, listed in Table 5.2. Additionally, a ren-derer will probably allowfor additional coordinate systems to be named in the scene description,and these names may also be referenced inside your shader to designate transformations.Point types can have their individual components examined and set using the [] array accessnotation. For example:pointP;floaty=P[1]; //gettheycomponentP[0]=0.5; //setthexcomponentOpen Shading Language Specication28 CHAPTER 5. DATA TYPESTable 5.2: Names of predeclared geometric spaces."common" The coordinate system that all spatial values start out in and the one in whichall lighting calculations are carried out. Note that the choice of"common"space may be different on each renderer."object" The local coordinate system of the graphics primitive (sphere, patch, etc.) thatwe are shading."shader" The local coordinate system active at the time that the shader was instanced."world" The world coordinate system designated in the scene."camera" The coordinate system with its origin at the center of the camera lens, x-axispointing right, y-axis pointing up, and z-axis pointing into the screen."screen" The coordinate system of the cameras image plane (after perspective trans-formation, if any). Coordinate (0,0) of "screen" space is looking along thez-axis of "camera" space."raster" 2Dpixel coordinates, with (0,0) as the upper-left corner of the image and (xres,yres) as the lower-right corner."NDC" 2D Normalized Device Coordinates like raster space, but normalized sothat x and y both run from 0 to 1 across the whole image, with (0,0) being atthe upper left of the image, and (1,1) being at the lower right.Components 0, 1, and 2 are x, y, and z, respectively.It is an error to access a point componentwith an index outside the [0...2] range.The following operators may be used with point-like values (in order of decreasing prece-dence, with each box holding operators of the same precedence):operation resultptype [ int] float component access- ptype vector component-wise unary negationptype * ptype ptype component-wise multiplicationfloat * ptype ptype scaling of all componentsptype * float ptype scaling of all componentsptype / ptype ptype component-wise divisionptype / float ptype division of all componentsfloat / ptype ptype division by all componentsptype + ptype ptype component-wise additionptype - ptype vector component-wise subtractionptype == ptype int 1 if the two values are equal, else 0ptype != ptype int 1 if the two values are different, else 0The generic ptype is listed in places where any of point, vector, or normal may be used.All of the binary operators may combine a scalar value (float orint) with a point-liketype, treating the scalar if it were point-like with three identical components.Open Shading Language Specication5.5. MATRIX 295.5 matrixOpen Shading Language has a matrix type that represents the transformation matrix requiredto transform points and vectors between one coordinate system and another. Matrices are rep-resented internally by 16 oats (a 44 homogeneous transformation matrix).A matrix can be constructed from a single oat or 16 oats. For example:matrixzero=0; //makesamatrixwithall0componentsmatrixident=1; //makestheidentitymatrix//Constructamatrixfrom16floatsmatrixm=matrix(m00,m01,m02,m03,m10,m11,m12,m13,m20,m21,m22,m23,m30,m31,m32,m33);Assigning a single oating-point number x to a matrix will result in a matrix with diagonalcomponents all beingxand other components being zero (i.e., xtimes the identity matrix).Constructing a matrix with 16 oats will create the matrix whose components are those oats,in row-major order.Similar to point-like types, a matrix may be constructed in reference to a named space://Constructmatricesrelativetosomethingotherthan"common"matrixq=matrix("shader",1);matrixm=matrix("world",m00,m01,m02,m03,m10,m11,m12,m13,m20,m21,m22,m23,m30,m31,m32,m33);The rst form creates the matrix that transforms points from"current" space to"shader"space. Transforming points by this matrix is identical to calling transform("shader",...).The second form prepends the current-to-world transformation matrix onto the 4 4 matrixwith components m0,0...m3,3. Note that although we have used "shader" and "world" spacein our examples, any named space is acceptable.A matrix may also be constructed from the names of two coordinate systems, yielding thematrix that transforms coordinates from the rst named space to the second named space:matrixm=matrix("object","world");The example returns the object-to-world transformation matrix.Matrix variables can be tested for equality and inequality with the == and != boolean op-erators. Also, the * operator between matrices denotes matrix multiplication, while m1/m2denotes multiplying m1 by the inverse of matrix m2. Thus, a matrix can be inverted by writing1/m. In addition, some functions will accept matrix variables as arguments, as described inSection 7.Individual components of a matrix variable may be set or accessed using array notation, forexample,matrixM;floatx=M[row][col];M[row][col]=1;Open Shading Language Specication30 CHAPTER 5. DATA TYPESValid component indices are integers on [0...3]. It is an error to access a matrix componentwith either a row or column outside this range.The following operators may be used with matrices (in order of decreasing precedence, witheach box holding operators of the same precedence):operation resultmatrix [ int][ int] float component access (row, column)- matrix matrix unary negationmatrix * matrix matrix matrix multiplicationmatrix * float matrix component-wise scalingfloat * matrix matrix component-wise scalingmatrix / matrix matrix multiply the rst matrix by the inverse of the secondmatrix / float matrix component-wise divisionfloat / matrix matrix multiply the float by the inverse of the matrixmatrix == matrix int 1 if the two values are equal, else 0matrix != matrix int 1 if the two values are different, else 05.6 stringThe string type may hold character strings. The main application of strings is to provide thenames of les where textures may be found. Strings can be compared using == and !=.String constants are denoted by surrounding the characters with double quotes, as in "Iamastringliteral".As in C programs, string literals may contain escape sequences such as\n (newline), \r (carriage return), \t (tab), \" (double quote), \\ (backslash).Twoquote-quotedstringliteralsthatareseparatedonlybywhitespace(spaces, tabs, ornewlines) will be automatically concatenated into a single string literal. In other words,"foo" "bar"is exactly equivalent to "foobar".5.7 voidThevoid type is used to designate a function that does not return a value. No variable mayhave type void.5.8 ArraysArrays of any of the basic types are supported, provided that they are 1D and statically sized,using the usual syntax for C-like languages:floatd[10]; //Declareanuninitializedarrayfloatc[3]={0.1,0.2,3.14}; //Initializethearrayfloatf=c[1]; //AccessoneelementOpen Shading Language Specication5.9. STRUCTURES 31The built-in function arraylength() returns the number of elements in an array. For ex-ample:floatc[3];intclen=arraylength(c); //shouldreturn3There are two circumstances when arrays do not need to have a declared length an arrayparameter to a function, and a shader parameter that is an array. This is indicated by emptyarray brackets, as shown in the following example:floatsum(floatx[]){floats=0;for(inti=0; i expr (integer shift right)expr & expr (bitwise and)expr | expr (bitwise or)expr expr (bitwise exclusive or)The operators+, -, *, /, and the unary- (negation) may be used on most of the nu-meric types. For multicomponent types (color, point, vector, normal, matrix), theseoperators combine their arguments on a component-by-component basis. The only op-erators that may be applied to thematrix type are* and/, which respectively denotematrix-matrix multiplication and matrix multiplication by the inverse of another matrix.The integer and bit-wise operators %, , &, |, , and may only be used with expres-sions of type int.For details on which operators are allowed, please consult the operator tables for eachindividual type in Chapter 5.Relational operators (all lower precedence than the arithmetic operators):Open Shading Language Specication6.2. EXPRESSIONS 37expr == expr (equal to)expr != expr (not equal to)expr < expr (less then)expr expr (greater than)expr >= expr (greater than or equal)The == and != operators may be performed between any two values of equal type, and areperformed component-by-component for multi-component types. The = maynot be used to compare multi-component types.An int expression may be compared to a float (and is treated as if they are both float).Afloat expression may be compared to a multi-component type (and is treated as amulti-component type as if constructed from a single oat).Relation comparisons produce Boolean (true/false) values. These are implemented asint values, 0 if false and 1 if true.Logical unary and binary operators:! exprexpr1 && expr2expr1 || expr2Forthelogical operators, numericexpressions(intorfloat)areconsideredtrueifnonzero, false if zero. Multi-component types (such as color) are considered true anycomponent is nonzero, false all components are zero. Strings are considered true if theyare nonempty, false if they are the empty string ("").another expression enclosed in parentheses: (). Parentheses may be used to guaranteeassociativity of operations.Type casts, specied either by having the type name in parentheses in front of the valueto cast (C-style typecasts) or the type name called as a constructor (C++-style type con-structors):(vector)P /*castapointtoavector*/(point)f /*castafloattoapoint*/(color)P /*castapointtoacolor!*/vector(P) /*Meansthesamething*/point(f)color(P)The three-component types (color, point, vector, normal) may be cast to other three-component types. A float may be cast to any of the three-component types (by placingthe oat in all three components) or to a matrix (which makes a matrix with all diagonalcomponents being the float). Obviously, there are some type casts that are not allowedbecause they make no sense, like casting a point to a float, or casting a string to anumerical type.Open Shading Language Specication38 CHAPTER 6. LANGUAGE SYNTAXfunction callsassignment expressions: same thing as var=varOPexpr :var = expr (assign)var += expr (add)var -= expr (subtract)var *= expr (multiply)var /= expr (divide)int-var &= int-expr (bitwise and)int-var |= int-expr (bitwise or)int-var = int-expr (bitwise exclusive or)int-var = int-expr (integer shift right)Note that the integer and bit-wise operators are only allowed with int variables and ex-pressions. In general, varOP=expr is allowed only if var=varOPexpr is allowed,and means exactly the same thing. Please consult the operator tables for each individualtype in Chapter 5.ternary operator, just like C:condition ? expr1 : expr2This expression takes on the value of expr1 if condition is true (nonzero), or expr2 ifcondition is false (zero).Please refer to Chapter 5,where the section describing each data type describes the fullcomplement of operators that may be used with the type. Operator precedence in Open ShadingLanguage is identical to that of C.6.3 Control ow: if, while, do, forConditionals in Open Shading Language just like in C or C++:if( condition )truestatementandif( condition )truestatementelsefalsestatementThe statements can also be entire blocks, surrounded by curly braces. For example,Open Shading Language Specication6.3. CONTROL FLOW: IF, WHILE, DO, FOR 39if(s>0.5){x=s;y=1;}else{x=s+t;}The condition may be any valid expression, including:The result of any comparison operator (such as 0 and ceil if x < 0).typefmod(typea,typeb)typemod(typea,typeb)The fmod() function returns the oating-point remainder of a/b, i.e., is the oating-pointequivalent of the integer % operator. It is nearly identical to the C or C++ fmod function,except that in OSL, fmod(a,0) returns 0, rather than NaN. Note that if a < 0, the returnvalue will be negative.The mod() function returns aboor(a/b), which will always be a positive number orzero. As an example, fmod(-0.25,1.0)=-0.25, but mod(-0.25,1.0)=0.75. Forpositive a they return the same value.For both functions, the type may be any of float, point, vector, normal, or color.Open Shading Language Specication46 CHAPTER 7. STANDARD LIBRARY FUNCTIONStypemin(typea,typeb)typemax(typea,typeb)typeclamp(typex,typeminval,typemaxval)The min() and max() functions return the minimum or maximum, respectively, of a listof two or more values. The clamp function returnsmin(max(x,minval),maxval),that is, the value x clamped to the specied range.typemix(typex,typey,typealpha)typemix(typex,typey,floatalpha)The mix function returns a linear blending : x (1) +y ()intisnan(floatx)intisinf(floatx)intisfinite(floatx)Theisnan() function returns 1 if x is a not-a-number (NaN) value, 0 otherwise. Theisinf()functionreturns1ifxisaninnite(InforInf)value, 0otherwise. Theisfinite() function returns 1 ifxis an ordinary number (neither innite nor NaN),0 otherwise.floaterf(floatx)floaterfc(floatx)The erf() function returns the error function erf(x) =2

x0 et2dt. The erfc returns thecomplementary error function 1-erf(x) (useful in maintaining precision for large valuesof x).7.2 Geometric functionsptypeptype(floatf)ptypeptype(floatx,floaty,floatz)Constructsapoint-likevalue(ptypemaybeanyofpoint, vector, ornormal)fromindividual float values. If constructed from a single float, the value will be replicatedfor x, y, and z.ptypeptype(stringspace,f)ptypeptype(stringspace,floatx,floaty,floatz)Constructsapoint-likevalue(ptypemaybeanyofpoint, vector, ornormal)fromindividual float coordinates, relative to the named coordinate system. In other words,point(space,x,y,z)Open Shading Language Specication7.2. GEOMETRIC FUNCTIONS 47is equivalent totransform(space,"common",point(x,y,z))(And similarly for vector/normal.)floatdot(vectorA,vectorB)Returns the inner product of the two vectors (or normals), i.e., A B =AxBx+AyBy+AzCz.vectorcross(vectorA,vectorB)Returns the cross product of two vectors (or normals), i.e., AB.floatlength(vectorV)floatlength(normalV)Returns the length of a vector or normal.floatdistance(pointP0,pointP1)Returns the distance between two points.floatdistance(pointP0,pointP1,pointQ)Returns the distance from Q to the closest point on the line segment joining P0 and P1.vectornormalize(vectorV)normalnormalize(normalV)Return a vector in the same direction as Vbut with length 1, that is, V/length(V) .vectorfaceforward(vectorN,vectorI,vectorNref)vectorfaceforward(vectorN,vectorI)Ifdot(Nref,I)< 0, returnsN, otherwise returns-N. For the version with only twoarguments, Nref is implicitly Ng, the true surface normal. The point of these routines isto return a version of N that faces towards the camera in the direction opposite of I.To further clarify the situation, here is the implementation of faceforward expressed inOpen Shading Language:vectorfaceforward(vectorN,vectorI,vectorNref){return(I.Nref>0)?-N:N;}vectorfaceforward(vectorN,vectorI){returnfaceforward(N,I,Ng);}Open Shading Language Specication48 CHAPTER 7. STANDARD LIBRARY FUNCTIONSvectorreflect(vectorI,vectorN)ForincidentvectorIandsurfaceorientationN,returnsthereectiondirectionR=I-2*(N.I)*N.Notethat Nmustbenormalized(unitlength)forthisformulatoworkproperly.vectorrefract(vectorI,vectorN,floateta)Forincident vectorIandsurfaceorientationN, returnstherefractiondirectionusingSnellslaw. Theetaparameteristheratiooftheindexofrefractionofthevolumecontaining I divided by the index of refraction of the volume being entered. The resultis not necessarily normalized and a zero-length vector is returned in the case of total in-ternal reection. For reference, here is the equivalent Open Shading Language of theimplementation:vectorrefract(vectorI,vectorN,floateta){floatIdotN=dot(I,N);floatk=1-eta*eta*(1-IdotN*IdotN);return(k| < | | >=| == | !=| &| | || &&| ||unary-op ::=- | ! | incdec-op ::=++ | --type-constructor ::= typespec ( expression-list )function-call ::= identier ( function-args-opt )Open Shading Language Specication79function-args ::= expression { , expression }assign-expression ::= variable-lvalue assign-op expressionassign-op ::== | *= | /= | += | -= | &= | |= | = | =ternary-expression ::= expression ? expression : expressiontypecast-expression ::=( simple-typename ) expressionOpen Shading Language Specication80 CHAPTER 8. FORMAL LANGUAGE GRAMMAROpen Shading Language Specication9 Describing shader groupsBelow, we propose a simple grammar giving a standard way to serialize (i.e., express as text)a full shader group, including instance values and connectivity of the shader layers. There areonly three statements/operations: set an instance value, make a shader instance, and connecttwo instances.paramtype paramname value... ;paramtype paramname value... [[metadata...]] ;Declare an instance value of a shader parameter to be applied to the next shader state-ment. We refer to the parameter values set, which have not yet had their shader declared,as pending parameters.The paramname is the name of the parameter whose instance values are being specied.The type is one of the basic numeric or string data types described in Chapter 5 (int,float, color, point, vector, normal, matrix, orstring), or an array thereof (in-dicated by the usual notation of [size]). The type must match the declared type of theparameter in the shader.The actual values are listed individually, with multiple values (in the case of an array or anaggregate such as a color) simply separated by whitespace. If fewer values are suppliedthan the total number of array elements or aggregate components, the remainder will beunderstood to be lled with 0 values. String values must be enclosed in double quotes("likethis").The param statement is terminated by a semicolon (;).Optionally,metadata hints may be supplied enclosed by double brackets,immediatelybefore the semicolon.shadershadername layername ;Declares a shader instance, which will receive any pending parameters that were declaredsince the previous shader statement (and in the process, clear the list of pending param-eters).The shadername is an identier that species the name of the shader to use as the masterfor this instance. Thelayername is an identier that names the layer (e.g.,to subse-quently specify it as a source or destination for connections).The shader statement is terminated by a semicolon (;).8182 CHAPTER 9. DESCRIBING SHADER GROUPSconnectsource layername.paramname destination layername.paramname ;Establish a connection between an output parameter of a source layer and an input param-eter of a destination layer, both of which have been previously declared within this group.The source layer must have preceded the destination layer when they were declared, andthe parameters must exist and be of a compatible type so that it is meaningful to estab-lish a connection (for example, you may connect a color to a color, but you may notconnect a color to a matrix).If the named parameters are structures, the two structures must have identical data layout,and establishing the connection will connect each corresponding data member. It is alsopossible to make a connection of just a single member of a structure by using the usualdot syntax, for example, for layers A and B, "connectA.c.xB.y" might connect Asparameter c, member x, to Bs parameter y (the types of c.x in A and y in B must match).The connect statement is terminated by a semicolon (;).Exampleparamstringname"rings.tx"; set pending nameparamfloatscale3.5; set pending scaleshader"texturemap""tex1"; tex1 layer, picks up name, scaleparamstringname"grain.tx";shader"texturemap""tex2";paramfloatgam2.2;shader"gamma""gam1";paramfloatgam1.0;shader"gamma""gam2";paramcolorwoodcolor0.420.380.22; example of a color paramshader"wood""wood1";connecttex1.Coutgam1.Cin; connect tex1s Cout to gam1s Cinconnecttex2.Coutgam2.Cin;connectgam1.Coutwood1.rings;connectgam2.Coutwood1.grain;Open Shading Language SpecicationAppendices83A GlossaryAttribute state. The set of variables that determines all the properties (other than shape) of ageometric primitive such as its local transformation matrix, the surface, displacement,and volume shaders to be used, which light sources illuminate objects that share the at-tribute state, whether surfaces are one-sided or two-sided, etc. Basically all of the optionsthat determine the behavior and appearance of the primitives, that are not determined bythe shape itself or the code of the shaders. A single attribute state may be shared amongmultiple geometric primitives. Also sometimes called graphics state.Built-in function. A function callable from within a shader, where the implementation of thefunction is provided by the renderer (as opposed to a function that the shader author writesin Open Shading Language itself).Closure. A symbolic representation of a function to be called, and values for its parameters,that are packaged up to be evaluated at a later time to yield a nal numeric value.Connection. A routing of the value of an output parameter of one shader layer to an inputparamter of another shader layer within the same shader group.Default parameter value. The initial value of a shader parameter, if the renderer does notoverride it with an instance value, an interpolated primitive variable, or a connection toan output parameter of another layerwithin the group. The default value of a shaderparameter is explicitly given in the code for that shader, and may either be a constant or acomputed expression.Geometric primitive. A single shape, such as a NURBS patch, a polygon or subdivision mesh,a hair primitive, etc.Global variables. The set of built-in variables describing the common renderer inputs to allshaders (as opposed to shader-specic parameters). These include position (P), surfacenormal (N), surface tangents (dPdu, dPdv), as well as standard radiance output (Ci). Dif-ferent shader types support different subsets of the global variables.Graphics state. See attribute state.Group. See shader group.Input parameter. A read-only shader parameter that provides a value to control a shadersbehavior. Can also refer to a read-only parameter to a shader function.8586 APPENDIX A. GLOSSARYInstance value. Aconstant valuethat overridesadefault parametervalueforaparticularshader instance. Each instance of a shader may have a completely different set of in-stance values for its parameters.Layer. See shader layer.Output parameter. A read/write shader parameter allows a shader to provide outputs beyondthe global variables such asCi. Can also refer to a read/write parameter to a shaderfunction, allowing a function to provide more outputs than a simple return value.Primitive. Usually refers to a geometric primitive.Primitive variable. A named variable, and values, attached to an individual geometric prim-itive. Primitive variables may have one of serveral interpolation methods such as asingle value for the whole primitive, a value for each piece or face of the primitive, orper-vertex values that are smoothly interpolated across the surface.Public method. A function within a shader that has an entry point that is visible and directlycallable by the renderer, as opposed to merely being called from other code within theshader. Public methods must be top-level (not dened within other functions) and mustbe preceeded by the public keyword.Shader. A small self-contained program written in Open Shading Language, used to extendthe functionality of a renderer with custom behavior of materials and lights. A particularshader may have multiple shader instances within a scene, each of which has ts uniqueinstance parameters, transformation, etc.Shader function. AfunctionwritteninOpenShadingLanguagethat maybecalledfromwithin a shader.Shader group. An ordered collection of shader instances (individually called the layers of agroup) that are executed to collectively determine material properties or displacement ofa geometric primitive, emission of a light source, or scattering properties of a volume.In addition to executing sequentially, layers within a group may optionally have any oftheir input parameters explicitly connected to output parameters of other layers within thegroup in an acyclic manner (thus, sometimes being referred to as a shader network).Shader instance. A particular reference to a shader, with a unique set of instancevalues,transformation, and potentially other attributes. Each shader instance is a separate entity,despite their sharing executable code.Shader network. See shader group.Shader layer. An individual shader instance within a shader group.Shader parameter. A named input or output variable of a shader. Input parameters provideknobs that control the behavior of a shader; output parameters additional provide a wayfor shaders to produce additional output beyond the usual global variables.Shading. The computations within a renderer that implement the behavior and visual appear-ance of materials and lights.Open Shading Language SpecicationIndex#define, 12#elif, 12#else, 12#endif, 12#if, 12#ifdef, 12#ifndef, 12#include, 12#undef, 12aastep(), 55abs(), 45absorption, 68acos(), 44area(), 55arraylength(), 74arrays, 30arrays, 34asin(), 44atan(), 44atan2(), 44backfacing(), 72background, 69blackbody(), 50bump mapping, 56bump(), 56C preprocessor, see preprocessorcalculatenormal(), 55ceil(), 45cellnoise(), 54character set, 11clamp(), 46color, 25color functions, 49color(), 49comments, 11concat(), 57cos(), 44cosh(), 44cross(), 47debug(), 69degrees(), 43derivative functions, 55derivatives, 55determinant(), 51diffuse(), 66displace(), 56displacement, 56distance(), 47do/while, 39dot(), 47Dx(), 55Dy(), 55emission, 69environment(), 62erf(), 46erfc(), 46error(), 57exit(), 74exp(), 44exp2(), 44expm1(), 44expressions, 35fabs(), 45faceforward(), 47filterwidth(), 55float, 24floor(), 45fmod(), 45for, 39format(), 568788 INDEXfprintf(), 57fresnel(), 48function calls, 40functionsclosures, 66color, 49declarations, 20derivatives and area, 55displacement, 56geometric, 46mathematical, 43matrix, 50pattern generation, 51renderer state, 70string, 56texture, 59trigonometric, 44geometric functions, 46getattribute(), 70getmatrix(), 51getmessage(), 71gettextureinfo(), 63global variables, 40holdout(), 69hypot(), 45identiers, 11if, 38int, 23inversesqrt(), 45isconnected(), 72isfinite(), 46isinf(), 46isnan(), 46isotropic, 68keywords, 12length(), 47log(), 44log10(), 44log2(), 44logb(), 45luminance(), 49material closure functions, 66mathematical constants, 43mathematical functions, 43matrix, 29matrix functions, 50matrix(), 50max(), 46message passing, 70metadata, 16microfacet(), 67min(), 46mix(), 46mod(), 45noise(), 51, 53normal, 26normal(), 46normalize(), 47output parametersshader, 15parametersshader, 14pattern generation functions, 51phong(), 66pnoise(), 53, 54point, 26point(), 46pow(), 44preprocessor, 12printf(), 56psnoise(), 54public, 20public methods, 20radians(), 43raytype(), 72reflect(), 48reflection(), 67refract(), 48refraction(), 67reserved words, 12rotate(), 48round(), 45setmessage(), 71Open Shading Language SpecicationINDEX 89shader metadata, 16shader output parameters, 15shader parameters, 14shader types, 13sign(), 45sin(), 44sincos(), 44sinh(), 44smoothstep(), 51snoise(), 53spline(), 54splineinverse(), 54split(), 57sqrt(), 45standard library functions, 74startswith(), 57step(), 51stof(), 57stoi(), 57string, 30string functions, 56strlen(), 57struct, 31, 34structures, see structsubstr(), 58surfacearea(), 72tan(), 44tanh(), 44texture functions, 59texture mapping, 59texture(), 59texture3d(), 60trace, 73transform(), 48transformc(), 50transformu(), 49translucent(), 68transparent(), 68transpose(), 51trigonometry, 44trunc(), 45types, 2332color, 25float, 24int, 23matrix, 29normal, 26point, 26string, 30vector, 26void, 30arrays, 30, 34shader, 13structures, 31units, 49variable declarations, 33vector, 26vector(), 46void, 30ward(), 66warning(), 57while, 39whitespace, 11Open Shading Language Specication