-
Notifications
You must be signed in to change notification settings - Fork 406
Expand file tree
/
Copy pathlanguagespec.tex
More file actions
6199 lines (4976 loc) · 229 KB
/
languagespec.tex
File metadata and controls
6199 lines (4976 loc) · 229 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
\documentclass[11pt,letterpaper]{book}
\setlength{\oddsidemargin}{0.5in}
\setlength{\topmargin}{0in}
\setlength{\evensidemargin}{0.3in}
\setlength{\textwidth}{5.75in}
\setlength{\textheight}{8.5in}
%\setlength{\oddsidemargin}{1.25in}
%\setlength{\evensidemargin}{0.5in}
% don't do this \usepackage{times} % Better fonts than Computer Modern
\renewcommand{\sfdefault}{phv}
\renewcommand{\rmdefault}{ptm}
% don't replace tt -- old is better \renewcommand{\ttdefault}{pcr}
%\usepackage{apalike}
\usepackage{pslatex}
\usepackage{techref}
%\usepackage{epsfig}
\usepackage{verbatim}
\usepackage{moreverb}
\usepackage{graphicx}
\usepackage{xspace}
%\usepackage{multicol}
%\usepackage{color}
\usepackage{hyperref}
%\usepackage{version}
\usepackage{makeidx}
\usepackage[chapter]{algorithm}
\floatname{algorithm}{Listing}
\usepackage{syntax}
\widowpenalty=1000
\clubpenalty=1000
\usepackage{fancyhdr}
\pagestyle{fancy}
\fancyhead[LE,RO]{\bfseries\thepage}
\fancyhead[LO]{\bfseries\rightmark}
\fancyhead[RE]{\bfseries\leftmark}
\fancyfoot[C]{\bfseries Open Shading Language Specification}
\renewcommand{\footrulewidth}{1pt}
\def\langname{Open Shading Language\xspace}
\def\product{{\sffamily Open Shading Language}\xspace}
\def\versionnumber{1.10}
\def\productver{\product\ {\sffamily \versionnumber}\xspace}
\title{
{\Huge{\bf \product}
%\textregistered\
{\bf\sffamily \versionnumber} \medskip \\ \huge
Language Specification
} \bigskip }
\author{
\copyright\ Copyright 2009-2018 Sony Pictures Imageworks Inc., et al. All rights reserved.
\bigskip \\
\vspace{1in} \\
Editor: Larry Gritz \\
\emph{lg@imageworks.com}
}
\date{{\large Date: 31 Mar 2018 \\
% (with corrections, 31 Mar 2018)
}
\bigskip
\bigskip
\bigskip
\bigskip
}
\include{macros}
\def\color{{\cf color}\xspace}
\def\float{{\cf float}\xspace}
\def\inttype{{\cf int}\xspace}
\def\matrix{{\cf matrix}\xspace}
\def\normal{{\cf normal}\xspace}
\def\point{{\cf point}\xspace}
\def\vector{{\cf vector}\xspace}
\def\void{{\cf void}\xspace}
\def\C{{\cf Ci}\xspace}
\def\Ci{{\cf Ci}\xspace}
%\def\opacity{{\cf Oi}\xspace}
\def\Oi{{\cf Oi}\xspace}
\def\I{{\cf I}\xspace}
\def\N{{\cf N}\xspace}
\def\Ng{{\cf Ng}\xspace}
\def\P{{\cf P}\xspace}
\def\dPdu{{\cf dPdu}\xspace}
\def\dPdv{{\cf dPdv}\xspace}
\def\commonspace{{\cf "common"} space\xspace}
\def\shaderspace{{\cf "shader"} space\xspace}
\def\worldspace{{\cf "world"} space\xspace}
\def\cameraspace{{\cf "camera"} space\xspace}
\def\objectspace{{\cf "object"} space\xspace}
\def\rgbspace{{\cf "rgb"} space\xspace}
\def\noise{{\cf noise()}\xspace}
\def\snoise{{\cf snoise()}\xspace}
\def\pnoise{{\cf pnoise()}\xspace}
\def\psnoise{{\cf psnoise()}\xspace}
\def\cellnoise{{\cf cellnoise()}\xspace}
\def\hashnoise{{\cf hashnoise()}\xspace}
\def\illuminance{{\cf illuminance}\xspace}
\def\illuminate{{\cf illuminate}\xspace}
\def\closure{{\cf closure}\xspace}
\def\colorclosure{{\cf closure color}\xspace}
\def\closurecolor{{\cf closure color}\xspace}
\def\closurecolors{{\cf closure color}s\xspace}
\makeindex
\begin{document}
\frontmatter
\maketitle
\newpage
\label{speccopyr}
\vspace*{0.2in}
\noindent The Open Shading Language specification, source code, and
documentation are:
\vspace*{0.2in}
Copyright (c) 2009-2017 Sony Pictures Imageworks Inc., et al.
All Rights Reserved.
\vspace{0.5in}
The code that implements Open Shading Language is licensed under
the BSD 3-clause (also sometimes known as ``new BSD'') license:
\vspace{0.25in}
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
\begin{itemize}
\item Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
\item Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
\item Neither the name of Sony Pictures Imageworks nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
\end{itemize}
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\vspace{0.5in}
This specification and other text documentation about Open Shading
Language is licensed under a the Creative Commons Attribution 3.0
Unported License. \\
\smallskip
\spc \includegraphics[width=0.85in]{Figures/CC-30BY.png}
\spc http://creativecommons.org/licenses/by/3.0/
\bigskip
\newpage
\setcounter{tocdepth}{1}
\tableofcontents
\mainmatter
%\part{Part name}
%\include{blah}
\chapter{Introduction}
\label{chap:intro}
Welcome to Open Shading Language!
\vspace*{0.2in}
Open Shading Language (OSL) is a small but rich language for
programmable shading in advanced 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 for feature film animation and visual effects. The
language specification was developed with input by 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 own applications, whether they are free or commercial,
open or proprietary, as well as to modify the OSL code as you desire,
provided that you retain the original copyright notices as described in
the license.
\section*{How OSL is different from other shading languages}
OSL has syntax similar to C, as well as other shading languages.
However, it is specifically designed for advanced rendering algorithms
and has features such as radiance closures, BSDFs, and deferred ray
tracing as first-class concepts.
OSL has several unique characteristics not found in other shading
languages (certainly not all together). Here are some things you will
find are different in OSL compared to other languages:
\subsubsection*{Surface and volume shaders compute radiance closures, not final colors.}
OSL's 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 may be
evaluated in particular directions, sampled to find important
directions, or saved for later evaluation and re-evaluation.
This new approach is ideal for a physically-based renderer that
supports ray tracing and global illumination.
In contrast, other shading languages usually compute just a surface
color as visible from a particular direction. These old shaders are
"black boxes" that a renderer can do little with but execute to for
this once piece of information (for example, there is no effective way
to discover from them which directions are important to sample).
Furthermore, the physical units of lights and surfaces are often
underspecified, making it very difficult to ensure that shaders are
behaving in a physically correct manner.
\subsubsection*{Surface 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, surface shaders compute a radiance closure
describing how the surface scatters light, and a part of the renderer
called an "integrator" evaluates the closures for a particular set of
light sources and determines in which directions rays should be
traced. Effects that would ordinarily require explicit ray tracing,
such as reflection and refraction, are simply part of the radiance
closure and look 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 the BSDF; 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 the shaders.
\subsubsection*{Surface and light shaders are the same thing.}
OSL does not have a separate kind of shader for light sources. Lights
are simply surfaces that are emissive, and all lights are area lights.
\subsubsection*{Transparency is just another kind of illumination.}
You don't need to explicitly set transparency/opacity variables in the
shader. Transparency is just another way for light to interact with a
surface, and is included in the main radiance closure computed by a
surface shader.
\subsubsection*{Renderer outputs (AOV's) are specified using ``light path expressions.''}
Sometimes it is desirable to output images containing individual
lighting components such as specular, diffuse, reflection, individual
lights, etc. In other languages, this is usually accomplished by
adding a plethora of "output variables" to the shaders that collect
these individual quantities.
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 should contribute to which
outputs. This is all done on the renderer side (though supported by
the OSL implementation). If you desire a new output, there is no need
to modify the shaders at all; you only need to tell the renderer the
new light path expression.
\subsubsection*{Shaders are organized into networks.}
OSL shaders are not monolithic, but rather can be organized into
networks of shaders (sometimes called a shader group, graph, or DAG),
with named outputs of some nodes being connected to named inputs of
other nodes within the network. These connections may be done
dynamically at render time, and do not affect compilation of
individual shader nodes. Furthermore, the individual nodes are
evaluated lazily, only their outputs are "pulled" from the later nodes
that depend on them (shader writers may remain blissfully unaware of
these details, and write shaders as if everything is evaluated
normally).
\subsubsection*{No ``uniform'' and ``varying'' keywords in the language.}
OSL shaders are evaluated in SIMD fashion, executing shaders on many
points at once, but there is no need to burden shader writers with
declaring which variables need to be uniform or varying.
In the open source OSL implementation, this is done both automatically
and dynamically, meaning that a variable can switch back and forth
between uniform and varying, on an instruction-by-instruction basis,
depending on what is assigned to it.
\subsubsection*{Arbitrary derivatives without grids or extra shading points.}
In OSL, you can take derivatives of any computed quantity in a shader,
and use arbitrary quantities as texture coordinates and expect correct
filtering. This does not require that shaded points be arranged in a
rectangular grid, or have any particular connectivity, or that any
"extra points" be shaded.
In the open source OSL implementation, this is possible because
derivatives are not computed by finite differences with neighboring
points, but rather by "automatic differentiation", computing partial
differentials for the variables that lead to derivatives, without any
intervention required by the shader writer.
\vspace{0.5in}
\section*{Acknowledgments}
The original designer and project leader of OSL is Larry Gritz. Other early
developers of OSL are (in order of joining the project): Cliff Stein, Chris
Kulla, Alejandro Conty, Jay Reynolds, Solomon Boulos, Adam Martinez, Brecht
Van Lommel.
Additionally, many others have contributed features, bug fixes, and other
changes: Steve Agland, Shane Ambler, Martijn Berger, Farchad Bidgolirad,
Nicholas Bishop, Stefan Büttner, Matthaus G. Chajdas, Thomas Dinges, Henri
Fousse, Syoyo Fujita, Derek Haase, Sven-Hendrik Haase, John Haddon, Daniel
Heckenberg, Ronan Keryell, Elvic Liang, Max Liani, Bastien Montagne, Erich
Ocean, Mikko Ohtamaa, Alex Schworer, Sergey Sharybin, Stephan Steinbach,
Esteban Tovagliari, Alexander von Knorring, Roman Zulak. (Listed
alphabetically; if we've left anybody out, please let us know.)
We cannot possibly express sufficient gratitude to the managers at Sony
Pictures Imageworks who allowed this project to proceed, supported it
wholeheartedly, and permitted us to release the source, especially Rob
Bredow, Brian Keeney, Barbara Ford, Rene Limberger, and Erik Strauss.
Huge thanks also go to the crack shading team at SPI, and the brave
lookdev TDs and CG supes 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 we've been responsive to your needs.
OSL was not developed in isolation. We owe a debt to the individuals
and studios who patiently read early drafts of the language
specification and gave us very helpful feedback and additional ideas,
and especially to those at other companies who have taken the risk of
incorporating OSL into their products and pipelines.
\bigskip
The open source OSL implementation incorporates or depends upon several
other open source packages:
\begin{itemize}
\item {\cf OpenImageIO} \copyright\ 2008 Larry Gritz et al.
\url{http://openimageio.org}
\item Ilmbase \copyright\ 2006, Industrial Light \& Magic.
\url{http://www.openexr.com}
\item Boost \copyright\ various authors. \url{http://www.boost.org}
\item LLVM \copyright\ 2003-2010 University of Illinois at
Urbana-Champaign. \url{http://llvm.org}
\end{itemize}
These other packages are all distributed under licenses that allow them
to be used by and distributed with \product.
\bigskip
% \section*{Annotations}
%
% \begin{annotate}
% When you see text in this style, it's an annotation. These annotations
% will not be in the final draft of this document. They are notes to the
% readers of early drafts, sometimes questions, sometimes guideposts
% to uncertain areas, sometimes explanations of what is to come but that
% has not yet been fully fleshed out.
%
% \begin{comment}
% Short annotations will sometimes spring up anywhere, but there's also a
% full chapter of discussion of design choices
% (Chapter~\ref{chap:discussion}). Opinionated readers should pay
% particular attention to this chapter, as these big decisions will be the
% hardest to change later.
%\end{comment}
% \end{annotate}
\chapter{The Big Picture}
\label{chap:shaderstructure}
\label{chap:bigpicture}
This chapter attempts to lay out the major concepts of \langname,
define key nomenclature, and sketch out how individual shaders fit
together in the context of a renderer as a whole.
% \begin{annotate}
% Other than the background material of this chapter, the rest of this
% specification deals strictly with the language itself. In the future,
% there will be separate (shorter) documents explaining in detail the use
% of the language compiler, the renderer-side issues, the library and APIs
% for how a renderer actually causes shaders to be evaluated, and so on.
% \end{annotate}
\subsection*{A shader is code that performs a discrete task}
A shader is a program, with inputs and outputs, that performs a specific
task when rendering a scene, such as determining the appearance behavior
of a material or light. The program code is written in \langname, the
specification of which comprises this document.
For example, here is a simple {\cf gamma} shader that performs
simple gamma correction on is {\cf Cin} input, storing the result
in its output {\cf Cout}:
\bigskip
\includegraphics{Figures/shaderschematic}
\medskip
The shader's inputs and outputs are called \emph{shader parameters}.
Parameters have default values, specified in the shader code, but may
also be given new values by the renderer at runtime.
\subsection*{Shader instances}
A particular shader may be used many times in a scene, on different
objects or as different layers in a shader group. Each separate use of
a shader is called a \emph{shader instance}. Although all instances of
a shader are comprised of the same program code, each instance may
override any or all of its default parameter values with its own set of
\emph{instance values}.
Below is a
schematic showing a {\cf gamma} instance with the {\cf gam} parameter
overridden with an instance-specific value of {\cf 2.2}.
\bigskip
\bigspc\spc \includegraphics{Figures/instanceschematic}
\medskip
\subsection*{Shader groups, layers, and connections}
A \emph{shader group}\index{shader group} is an ordered sequence of
individual shaders called \emph{layers}\index{layer}\index{shader layer}
that are executed in turn. Output parameters of an earlier-executed layer
may be \emph{connected} to an input parameter of a later-executed layer.
This connected network of layers is sometimes called a \emph{shader network}
or a \emph{shader DAG} (directed acyclic graph). Of course, it is fine for
the shader group to consist of a single shader layer.
Below is a schematic showing how several shader instances may be
connected to form a shader group.
\bigskip
\noindent \includegraphics{Figures/groupschematic}
\bigskip
\noindent And here is sample pseudo-code shows how the above network may
be assembled using an API in the renderer\footnote{This document does
not dictate a specific renderer API for declaring shader instances,
groups, and connections; the code above is just an example of how
it might be done.}:
\begin{code}
ShaderGroupBegin ()
Shader ("texturemap", /* shader name */
"tex1", /* layer name */
"string name", "rings.tx") /* instance variable */
Shader ("texturemap", "tex2", "string name", "grain.tx")
Shader ("gamma", "gam1", "float gam", 2.2)
Shader ("gamma", "gam2", "float gam", 1)
Shader ("wood", "wood1")
ConnectShaders ("tex1", /* layer name A */
"Cout", /* an output parameter of A */
"gam1", /* layer name B */
"Cin") /* Connect this layer of B to A's Cout */
ConnectShaders ("tex2", "Cout", "gam2", "Cin")
ConnectShaders ("gam1", "Cout", "wood1", "rings")
ConnectShaders ("gam2", "Cout", "wood1", "grain")
ShaderGroupEnd ()
\end{code}
\noindent Or, expressed as serialized text (as detailed in
Chapter~\ref{sec:serialize}):
\begin{code}
param string name "rings.tx" ;
shader "texturemap" "tex1" ;
param string name "grain.tx" ;
shader "texturemap" "tex2" ;
param float gam 2.2 ;
shader "gamma" "gam1" ;
param float gam 1.0 ;
shader "gamma" "gam2" ;
shader "wood" "wood1" ;
connect tex1.Cout gam1.Cin ;
connect tex2.Cout gam2.Cin ;
connect gam1.Cout wood1.rings ;
connect gam2.Cout wood1.grain ;
\end{code}
The rules for which data types may be connected are generally the same as
the rules determining which variables may be assigned to each other in OSL
source code:
\begin{itemize}
\item {\cf source} and {\cf dest} are the same data type.
\item {\cf source} and {\cf dest} are both \emph{triples} (\color, \point,
\vector, or \normal), even if they are not the same kind of triple.
\item {\cf source} is an {\cf int} and {\cf dest} is a {\cf float}.
\item {\cf source} is a {\cf float} or {\cf int} and {\cf dest} is a
\emph{triple} (the scalar value will be replicated for all three components
of the triple).
\item {\cf source} is a single component of an aggregate type (e.g. one
channel of a {\cf color}) and {\cf dest} is a {\cf float} (or vice versa).
\end{itemize}
\subsection*{Geometric primitives}
The \emph{scene} consists of primarily of geometric primitives,
light sources, and cameras.
\emph{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 \emph{primitive
variables} (also sometimes called \emph{interpolated values} or
\emph{user data}). Nearly all shape types will have, among their primitive
variables, control point positions that, when interpolated, actually
designate the shape. Some shapes will also allow the specification of
normals or other shape-specific 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 various ways.
If a shader input parameter's name and type match the name and type
of a primitive variable on the object (and that input parameters is
not already explicitly connected to another layer's output), the
interpolated primitive variable will override the instance value or
default.
\subsection*{Attribute state and shader assignments}
Every geometric primitive has a collection of \emph{attributes} (sometimes
called the \emph{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-specific or user-designated attributes associated with each
object. A particular attribute state may be shared among many geometric
primitives.
The attribute state also includes shader assignments --- the shaders or
shader groups for each of several \emph{shader uses}, such as surface
shaders that designate how light reflects or emits from each point on a shape,
displacement shaders that can add fine detail to the shape on a
point-by-point basis, and volume shaders that describe how light is
scattered within a region of space. A particular renderer may have
additional shader types that it supports.
%\subsection*{Shader types}
%
%There are several types of shaders: surface, displacement, light,
%volume. The type of shader determines what it's allowed to do (for
%example, only displacement shaders can alter the surface position).
%There is also a generic kind of shader that can be used for any of the
%shader uses.
\subsection*{Shader execution state: parameter binding and global variables}
When the body of code of an individual shader is about to execute, all
its parameters are \emph{bound} --- that is, take on specific values
(from connections from other layers, interpolated primitive variables,
instance values, or defaults, in that order).
Certain state about the position on the surface where the shading is
being run is stored in so-called \emph{global variables}. This includes
such useful data as the 3D coordinates of the point being shaded, the
surface normal and tangents at that point, etc.
Additionally, the shader may query other information about other
elements of the attribute state attached to the primitive, and
information about the renderer as a whole (rendering options, etc.).
\subsection*{Surface and volume shaders compute closures}
Surface shaders (and volume shaders) do not by themselves compute the
final color of light emanating from the surface (or along a volume).
Rather, the compute a \emph{closure}, which is a symbolic representation
describing the appearance of the surface, that may be more fully
evaluated later. This is in effect a parameterized formula, in which
some inputs have definite numeric values, but others may depend on
quantities not yet known (such as the direction from which the surface
is being viewed, and the amount of light from each source that is
arriving at the surface).
For example, a surface shader may compute its result like this:
\begin{code}
color paint = texture ("file.tx", u, v);
Ci = paint * diffuse (N);
\end{code}
\noindent In this example, the variable {\cf paint} will take on a
specific numeric value (by looking up from a texture map). But the {\cf
diffuse()} function returns a \colorclosure, not a definite numeric
\color. The output variable {\cf Ci} that represents the appearance of
the surface is also a \colorclosure, whose numeric value is not known
yet, except that it will be the product of {\cf paint} and a Lambertian
reflectance.
\bigskip
\includegraphics{Figures/shaderexecschematic}
\medskip
The closures output by surface and volume shaders can do a number of
interesting things that a mere number cannot:
\begin{itemize}
\item Evaluate: given input and output light directions, compute the
proportion of light propagating from input to output.
\item Sample: given just an input (or output) direction, choose a
scattering direction with a probability distribution that is
proportional to the amount of light that will end up going in various
directions.
\item Integrate: given all lights and a view direction, compute
the total amount of light leaving the surface in the view direction.
\item Recompute: given changes only to lights (or only to one light),
recompute the integrated result without recomputing other lights or
any of the calculations that went into assembling constants in the
closure (such as texture lookups, noise functions, etc.).
\end{itemize}
% \begin{annotate}
% At present, we are assuming that the primitive closure functions (such
% as {\cf diffuse}, {\cf ward}, {\cf cooktorrance}, etc.) are all built
% into the renderer, or implemented as renderer plugins. At a later time,
% possibly in a later draft or maybe not until a truly later version of
% the spec, we will fully spec it out so that closure primitive functions
% may be written in \langname. But I fear that if we do it too soon,
% we'll screw it up. But, yes, the eventual goal is for you to be able to
% write these primitive functions in the language itself.
% \end{annotate}
\subsection*{Integrators}
The renderer contains a number of \emph{integrators} (selectable via the
renderer's API) which will combine 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.
\bigskip
\includegraphics{Figures/integratorschematic}
\medskip
% \begin{annotate}
% At present, this document is written as if the integrators are built
% into the renderer itself (or implemented as renderer plug-ins). At a
% later time, we intend to make it possible for integrators themselves
% to be written in \langname.
% \end{annotate}
\subsection*{Units}
You can tell the renderer (through a global option) what units the scene
is using for distance and time. Then the shader has a built-in function
called {\cf transformu()} that works a lot like {\cf transform()}, but
instead of converting between coordinate systems, it converts among
units. For example,
\begin{code}
displacement bumpy (float bumpdist = 1,
string bumpunits = "cm")
{
// convert bumpdist to common units
float spacing = transformu (bumpunits, "common", bumpdist);
float n = noise (P / spacing);
displace (n);
}
\end{code}
So you can write a shader to achieve some effect in real world units,
and that shader is totally reusable on another show that used different
modeling units.
It knows all the standard names like \qkw{cm}, \qkw{in}, \qkw{km}",
etc., and can convert among any of those, as well as between named
coordinate systems. For example,
\begin{code}
float x = transformu ("object", "mm", 1);
\end{code}
now {\cf x} is the number of millimeters per unit of \objectspace on
that primitive.
\chapter{Lexical structure}
\label{chap:lexical}
\section{Characters}
\label{sec:lexical:chars}
\index{character set}
Source code for \langname consists of ASCII or UTF-8 characters.
The characters for space, tab, carriage return, and linefeed are
collectively referred to as \emph{whitespace}. Whitespace characters
delimit identifiers, keywords, or other symbols, but other than that
have no syntactic meaning. Multiple whitespace characters in a row
are equivalent to a single whitespace character. \index{whitespace}
Source code may be split into multiple lines, separated by end-of-line
markers (carriage return and/or linefeed). Lines may be of any length
and end-of-line markers carry no significant difference from other
whitespace, except that they terminate {\cf //} comments and delimit
preprocessor directives.
\section{Identifiers}
\label{sec:identifiers}
\index{identifiers}
\emph{Identifiers} are the names of variables, parameters, functions,
and shaders. In \langname, identifiers consist of one or more
characters. The first character may be a letter ({\cf A}-{\cf Z} or
{\cf a}-{\cf z}) or underscore (\verb|_|), and subsequent characters may
be letters, underscore, or numerals ({\cf 0}-{\cf 9}). Examples of
valid and invalid identifiers are:
\begin{code}
opacity // valid
Long_name42 // valid - letters, underscores, numbers are ok
_foo // valid - ok to start with an underscore
2smart // invalid - starts with a numeral
bigbuck$ // invalid - $ is an illegal character
\end{code}
\section{Comments}
\label{sec:comments}
\index{comments}
\emph{Comments} are text that are for the human reader of programs, and
are ignored entirely by the \langname compiler. Just like in C++, there
are two ways to designate comments in \langname:
\begin{enumerate}
\item Any text enclosed by {\cf /*} and {\cf */} will be considered
a comment, even if the comment spans several lines.
\begin{code}
/* this is a comment */
/* this is also
a comment, spanning
several lines */
\end{code}
\item Any text following {\cf //}, up to the end of the current line,
will be considered a comment.
\begin{code}
// This is a comment
a = 3; // another comment
\end{code}
\end{enumerate}
\section{Keywords and reserved words}
\label{sec:lexical:keyreserved}
There are two sets of names that you may not use as identifiers:
keywords and reserved words.
The following are \emph{keywords} that have special meaning in
\langname: \index{keywords}
\begin{quote} {\cf
and break closure color continue do else emit float for if illuminance
illuminate int matrix normal not or output point public return string struct
vector void while
}
\end{quote}
The following are \emph{reserved words} that currently have no special
meaning in \langname, but we reserve them for possible future use, or
because they are confusingly similar to keywords in related programming
languages: \index{reserved words}
\begin{quote} {\cf
bool case catch char class const delete default double
enum extern false friend
goto inline long new operator private protected
short signed sizeof static
switch template this throw true try typedef
uniform union unsigned varying virtual volatile
}
\end{quote}
\section{Preprocessor}
\label{sec:preprocessor}
\index{preprocessor} \index{C preprocessor|see{preprocessor}}
\indexapi{\#define}
\indexapi{\#undef}
\indexapi{\#if}
\indexapi{\#ifdef}
\indexapi{\#ifndef}
\indexapi{\#elif}
\indexapi{\#else}
\indexapi{\#endif}
\indexapi{\#include}
\indexapi{\#pragma}
Shader source code is passed through a standard C preprocessor as a
first step in parsing.
Preprocessor directives are designated by a hash mark ({\cf \#}) as the
first character on a line, followed by a preprocessor directive name.
Whitespace may optionally appear between the hash and the directive
name.
\langname compilers support the full complement of C/C++ preprocessing
directives, including:
\begin{code}
#define
#undef
#if
#ifdef
#ifndef
#elif
#else
#endif
#include
#pragma once
\end{code}
\noindent Additionally, the following preprocessor symbols will already be
defined by the compiler:
\smallskip
\begin{tabular}{p{1.5in} p{3.5in}}
{\cf OSL_VERSION_MAJOR} & Major version (e.g., 1) \\[0.5ex]
{\cf OSL_VERSION_MINOR} & Minor version (e.g., 9) \\[0.5ex]
{\cf OSL_VERSION_PATCH} & Patch version (e.g., 3) \\[0.5ex]
{\cf OSL_VERSION} & Combined version number = 10000*major + 100*minor + patch
(e.g., 10903 for version 1.9.3)
\end{tabular}
\chapter{Gross syntax, shader types, parameters}
\label{chap:grosssyntax}
The overall structure of a shader is as follows:
\medskip
\begin{quote}
\em
optional-function-or-struct-declarations \\
shader-type shader-name {\cf (} optional-parameters {\cf )} \\
\rm
{\cf \{ } \\
\em
\spc statements
{\cf \} }
\end{quote}
Note that \emph{statements} may include function or structure
definitions, local variable declarations, or public methods, as well as
ordinary execution instructions (such as assignments, etc.).
\section{Shader types}
\label{sec:shadertypes}
\index{shader types} \index{types!shader}
Shader types include the following: {\cf surface}, {\cf displacement},
{\cf light}, {\cf volume}, and generic {\cf shader}. Some operations
may only be performed from within certain types of shaders (e.g., one
may only call {\cf displace()} or alter \P in a displacement shader),
and some global variables may only be accessed from within certain types
of shaders (e.g., {\cf dPdu} is not defined inside a volume shader).
Following are brief descriptions of the basic types of shaders:
\subsection*{{\cf surface} shaders}
Surface shaders determine the basic material properties of a surface and
how it reacts to light. They are responsible for computing a
\colorclosure that describes the material, and optionally setting
other user-defined 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 not need a separate shader type to describe lights.
\subsection*{{\cf displacement} shaders}
Displacement shaders alter the position and shading normal (or,
optionally, just the shading normal) to make a piece of geometry appear
deformed, wrinkled, or bumpy. They are the only kind of shader that
is allowed to alter a primitive's position.
\subsection*{{\cf volume} shaders}
Volume shaders describe how a participating medium (air, smoke, glass,
etc.) reacts to light and affects the appearance of objects on the other
side of the medium. They are similar to {\cf surface} shaders, except
that they may be called from positions that do not lie upon (and are not
necessarily associated with) any particular primitive.
\subsection*{{\cf shader} generic shaders}
Generic shaders are used for utility code, generic routines that may be
called as individual layers in a shader group. Generic shaders need not
specify a shader type, and therefore may be reused from inside surface,
displacement, or volume shader groups. But as a result, they may
not contain 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).
\section{Shader parameters}
\label{sec:shaderparams}
\index{shader parameters} \index{parameters!shader}
An individual shader has (optionally) many \emph{parameters} whose
values may be set in a number of ways so that a single shader may have
different behaviors or appearances when used on different objects.
\subsection{Shader parameter syntax}
Shader parameters are specified in the shader declaration, in
parentheses after the shader's name. This is much like the parameters
to a \languagename function (or a function in C or similar languages),
except that shader parameters must have an \emph{initializer}, giving a
default value for the parameter. Shader parameter default initializers
may be expressions (i.e., may be computed rather than restricted 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 a simple parameter
declaration looks like this:
\medskip
\spc \emph{type parametername = default-expression}
\medskip
\noindent where \emph{type} is one of the data types described
in Chapter~\ref{chap:types}, \emph{parametername} is the name of the
parameter, and \emph{default-expression} is a valid expression
(see Section~\ref{sec:expressions}). Multiple parameters are
simply separated by commas: