You are on page 1of 111

The OpenGL

Shading Language
Language Version: 1.40
Document Revision: 08
22-Nov-2009
John Kessenich
Version 1.1 Authors: John Kessenich, Dave Baldwin, Randi Rost
Copyright (c) 2008-2009 The Khronos Group Inc. All Rights Reserve.
This speci!ic"tion is protecte #y copyright l"$s "n cont"ins %"teri"l propriet"ry to the Khronos Group&
Inc. It or "ny co%ponents %"y not #e reprouce& repu#lishe& istri#ute& tr"ns%itte& ispl"ye&
#ro"c"st or other$ise e'ploite in "ny %"nner $ithout the e'press prior $ritten per%ission o! Khronos
Group. (ou %"y use this speci!ic"tion !or i%ple%enting the !unction"lity therein& $ithout "ltering or
re%oving "ny tr"e%"r)& copyright or other notice !ro% the speci!ic"tion& #ut the receipt or possession o!
this speci!ic"tion oes not convey "ny rights to reprouce& isclose& or istri#ute its contents& or to
%"nu!"cture& use& or sell "nything th"t it %"y escri#e& in $hole or in p"rt.
Khronos Group gr"nts e'press per%ission to "ny current *ro%oter& Contri#utor or Aopter %e%#er o!
Khronos to copy "n reistri#ute +,-./I0I1/ versions o! this speci!ic"tion in "ny !"shion& provie th"t
,. C2ARG1 is %"e !or the speci!ic"tion "n the l"test "v"il"#le up"te o! the speci!ic"tion !or "ny
version o! the A*I is use $henever possi#le. 3uch istri#ute speci!ic"tion %"y #e re-!or%"tte A3
4.,G A3 the contents o! the speci!ic"tion "re not ch"nge in "ny $"y. The speci!ic"tion %"y #e
incorpor"te into " prouct th"t is sol "s long "s such prouct inclues signi!ic"nt inepenent $or)
evelope #y the seller. A lin) to the current version o! this speci!ic"tion on the Khronos Group $e#-site
shoul #e inclue $henever possi#le $ith speci!ic"tion istri#utions.
Khronos Group %")es no& "n e'pressly iscl"i%s "ny& represent"tions or $"rr"nties& e'press or
i%plie& reg"ring this speci!ic"tion& incluing& $ithout li%it"tion& "ny i%plie $"rr"nties o! %erch"nt"#ility
or !itness !or " p"rticul"r purpose or non-in!ringe%ent o! "ny intellectu"l property. Khronos Group %")es
no& "n e'pressly iscl"i%s "ny& $"rr"nties& e'press or i%plie& reg"ring the correctness& "ccur"cy&
co%pleteness& ti%eliness& "n reli"#ility o! the speci!ic"tion. +ner no circu%st"nces $ill the Khronos
Group& or "ny o! its *ro%oters& Contri#utors or -e%#ers or their respective p"rtners& o!!icers& irectors&
e%ployees& "gents or represent"tives #e li"#le !or "ny "%"ges& $hether irect& inirect& speci"l or
conse5uenti"l "%"ges !or lost revenues& lost pro!its& or other$ise& "rising !ro% or in connection $ith
these %"teri"ls.
Khronos& .penK./1& .penK.G3& .pen6G& .pen-A7& .pen34 13 "n .pen80 "re tr"e%"r)s o!
the Khronos Group Inc. C.44A/A is " tr"e%"r) o! 3ony Co%puter 1ntert"in%ent Inc. use #y
per%ission #y Khronos. .penG4 "n .pen-4 "re registere tr"e%"r)s "n the .penG4 13 logo is "
tr"e%"r) o! 3ilicon Gr"phics Inc. use #y per%ission #y Khronos. All other prouct n"%es& tr"e%"r)s&
"n9or co%p"ny n"%es "re use solely !or ienti!ic"tion "n #elong to their respective o$ners.
2
Table of Contents
1 Introduction.................................................................................................................................1
1.1 Acknowledgments................................................................................................................ 1
1. !hanges ............................................................................................................................... 1
1..1 !hanges since revision " o# version 1.$....................................................................... 1
1.. !hanges since revision % o# version 1.$.......................................................................
1..& 'ummar( o# )unctionalit( di##erences #rom version 1.&..............................................
1..$ 'ummar( o# )unctionalit( di##erences #rom version 1............................................... &
1.& *verview.............................................................................................................................. $
1.$ +rror ,andling......................................................................................................................$
1.% -(.ogra.hical !onventions................................................................................................. $
1." De.recation.......................................................................................................................... $
*verview o# *.en/0 'hading....................................................................................................%
.1 Verte1 2rocessor.................................................................................................................. %
. )ragment 2rocessor.............................................................................................................. %
& Basics.......................................................................................................................................... "
&.1 !haracter 'et........................................................................................................................ "
&. 'ource 'trings...................................................................................................................... "
&.& 2re.rocessor......................................................................................................................... 3
&.$ !omments.......................................................................................................................... 11
&.% -okens................................................................................................................................ 11
&." Ke(words............................................................................................................................1
&.3 Identi#iers........................................................................................................................... 1&
&.4 'tatic 5se........................................................................................................................... 1$
$ Varia6les and -(.es..................................................................................................................1%
$.1 Basic -(.es........................................................................................................................ 1%
$.1.1 Void............................................................................................................................ 13
$.1. Booleans..................................................................................................................... 13
$.1.& Integers....................................................................................................................... 14
$.1.$ )loats.......................................................................................................................... 17
$.1.% Vectors........................................................................................................................8
$.1." 9atrices...................................................................................................................... 8
$.1.3 'am.lers..................................................................................................................... 8
$.1.4 'tructures.................................................................................................................... 1
$.1.7 Arra(s.........................................................................................................................
$.1.18 Im.licit !onversions................................................................................................ $
$. 'co.ing...............................................................................................................................$
$.& 'torage :uali#iers..............................................................................................................."
$.&.1 De#ault 'torage :uali#ier............................................................................................3
$.&. !onstant :uali#ier...................................................................................................... 3
$.&.& !onstant +1.ressions................................................................................................. 3
3
$.&.$ In.uts.......................................................................................................................... 4
$.&.% 5ni#orm...................................................................................................................... 7
$.&.%.1 5ni#orm Blocks...................................................................................................7
$.&.%. 5ni#orm Block 0a(out :uali#iers....................................................................... &8
$.&." *ut.uts....................................................................................................................... &
$.&.3 Inter.olation................................................................................................................&&
$.&.3.1 Redeclaring Built;in Inter.olation Varia6les...................................................... &$
$.$ 2arameter :uali#iers...........................................................................................................&$
$.% 2recision and 2recision :uali#iers..................................................................................... &%
$.%.1 Range and 2recision................................................................................................... &%
$.%. 2recision :uali#iers.................................................................................................... &%
$.%.& De#ault 2recision :uali#iers....................................................................................... &%
$.%.$ Availa6le 2recision :uali#iers....................................................................................&"
$." Variance and the Invariant :uali#ier.................................................................................. &"
$.".1 -he Invariant :uali#ier............................................................................................... &3
$.". Invariance o# !onstant +1.ressions........................................................................... &4
$.3 *rder o# :uali#ication........................................................................................................ &4
% *.erators and +1.ressions........................................................................................................&7
%.1 *.erators............................................................................................................................ &7
%. Arra( *.erations............................................................................................................... $8
%.& )unction !alls.................................................................................................................... $8
%.$ !onstructors....................................................................................................................... $8
%.$.1 !onversion and 'calar !onstructors.......................................................................... $8
%.$. Vector and 9atri1 !onstructors................................................................................. $1
%.$.& 'tructure !onstructors................................................................................................ $&
%.$.$ Arra( !onstructors..................................................................................................... $$
%.% Vector !om.onents............................................................................................................$$
%." 9atri1 !om.onents............................................................................................................$%
%.3 'tructure and Arra( *.erations..........................................................................................$"
%.4 Assignments....................................................................................................................... $"
%.7 +1.ressions........................................................................................................................ $3
%.18 Vector and 9atri1 *.erations..........................................................................................%8
" 'tatements and 'tructure...........................................................................................................%&
".1 )unction De#initions...........................................................................................................%$
".1.1 )unction !alling !onventions.................................................................................... %%
". 'election............................................................................................................................. %3
".& Iteration.............................................................................................................................. %3
".$ Jum.s..................................................................................................................................%4
3 Built;in Varia6les......................................................................................................................"8
3.1 Verte1 'hader '.ecial Varia6les........................................................................................"8
3.1.1 gl<!li.Verte1............................................................................................................. "1
3. )ragment 'hader '.ecial Varia6les................................................................................... "1
4
3.& Verte1 'hader Built;In In.uts........................................................................................... "&
3.$ Built;In !onstants.............................................................................................................. "&
3.% Built;In 5ni#orm 'tate....................................................................................................... "$
3.%.1 ARB<com.ati6ilit( 'tate............................................................................................"$
3." Built;In Verte1 *ut.ut and )ragment In.ut Varia6les......................................................."3
3.".1 ARB<com.ati6ilit( Verte1 *ut.uts and )ragment In.uts......................................... "3
4 Built;in )unctions..................................................................................................................... "7
4.1 Angle and -rigonometr( )unctions....................................................................................38
4. +1.onential )unctions........................................................................................................31
4.& !ommon )unctions............................................................................................................ 3
4.$ /eometric )unctions.......................................................................................................... 3%
4.% 9atri1 )unctions................................................................................................................ 33
4." Vector Relational )unctions...............................................................................................34
4.3 -e1ture 0ooku. )unctions................................................................................................. 37
4.4 )ragment 2rocessing )unctions..........................................................................................47
4.7 =oise )unctions..................................................................................................................71
7 'hading 0anguage /rammar.....................................................................................................7
5
1 Introduction
-his document s.eci#ies onl( version 1.$8 o# the *.en/0 'hading 0anguage. It re>uires <<V+R'I*=<<
to su6stitute 1$8, and re>uires #version to acce.t onl( 1$8. I# #version is declared with 118, 18, or 1&8,
the language acce.ted is a .revious version o# the shading language, which will 6e su..orted de.ending
on the version and t(.e o# conte1t in the *.en/0 A2I. 'ee the *.en/0 /ra.hics '(stem '.eci#ication,
Version &.1, #or details on what language versions are su..orted.
1.1 Acknowledgments
-his s.eci#ication is 6ased on the work o# those who contri6uted to version 1.&8 o# the *.en/0 0anguage
'.eci#ication, the *.en/0 +' .8 0anguage '.eci#ication, version 1.18, and the #ollowing contri6utors to
this version:
Ro6 Barris
2ierre Boudier
2at Brown
=ick Burns
!hris Dodd
9ichael /old
=ick ,aemel
James ,el#ert(
Brent Insko
Je## Juliano
Jon 0eech
Bill 0icea;Kane
Ben?amin 0i.chak
Barthold 0ichten6elt
Bruce 9err(
Daniel Koch
9arc *lano
Ian Romanick
John Rosasco
Dave 'hreiner
Jerem( 'andmel
Ro6ert 'im.son
1
1 Introduction
1.2 Changes
1.2.1 Changes since revision and 7 of version 1.4
!lari#( that discard control #low e1its the shader.
Remove accidental inclusion o# textureGradOffset on samplerCubeSadow.
!lari#( it is generall( an error to redeclare varia6les, including 6uilt;ins.
1.2.2 Changes since revision of version 1.4
Add new sam.ler t(.es to the grammar a..endi1.
9ake the de#ault .recision >uali#ication #or #ragment shader 6e high.
9ake clear that mix@A, isnan@A, and isinf@A work with a scalar bool as well.
)i1 several #ont inconsistencies and t(.ogra.hical errors.
1.2.!
1.2.4 Changes since revision " of version 1.4
!hanged statements a6out version 1.& to 6e a6out version 1.$.
Remove statement a6out redeclaring .redeclared varia6les as flat, this now onl( a..lies when using
the com.ati6ilit( e1tension.
Remove Bde.recatedC statement re#erring to state in the com.ati6ilit( e1tension.
Add matri1 inversion 6uilt;in inverse@A.
'mall num6er o# t(.os #i1ed.
1.2." Su##ar$ of %unctionalit$ differences fro# version 1.!
9inor wording changes, clari#ications, and e1am.les added or changed to kee. in s(nc with the *.en/0
+' s.eci#ication.
-he #ollowing #eatures are added or changed:
Add uni#orm 6locks and la(outs to 6e 6acked 6( the a..lication through 6u##er 6indings.
Rectangular te1tures, including the closure o# the #unctionalit( indicated 6( the original
te1ture<rectangle e1tension, the g.u<shader$ e1tension and the 1.& version o# /0'0.
-e1ture 6u##ers.
Add gl_nstanceD #or instance drawing.
DonDt re>uire writing to gl_!osition.
-he #ollowing #eatures, .reviousl( de.recated, are removed:
2
1 Introduction
5se o# gl_"li#Verte$. 5se gl_"li#Distance instead.
Built;in verte1 shader in.uts.
Built;in uni#orms e1ce.t #or de.th range .arameters
Built;in inter#ace 6etween verte1 and #ragment: gl_%e$"oor&, gl_'og'rag"oor&, and all the color
values.
Built;in two;sided coloring.
)i1ed #unctionalit( #or a .rogramma6le stage. 'u..l( shaders #or all stages currentl( 6eing used.
ftransform@A. 5se invariant out.uts instead.
Removed #eatures were recast under the ARB<com.ati6ilit( e1tension, within this s.eci#ication.
1.2. Su##ar$ of %unctionalit$ differences fro# version 1.2
-he #ollowing is a summar( o# #eatures added in version 1.&:
Integer su..ort:
native signed and unsigned integers, integer vectors, and o.erations
6itwise shi#ts and masking
te1ture indices
te1ture return values
integer uni#orms, verte1 in.uts, verte1 out.uts, #ragment in.uts, and #ragment out.uts
6uilt;in #unction su..ort: a6s, sign, min, ma1, clam., ...
*ther te1ture su..ort:
'iEe >ueries.
-e1ture arra(s.
*##setting.
+1.licit 0*D and derivative controls
switcFcaseFdefault statements.
=ew 6uilt;ins: trunc@A, round@A, round!ven@A, isnan@A, isinf@A, modf@A
h(.er6olic trigonometric #unctions
2re.rocessor token .asting @##A.
5ser;de#ined #ragment out.ut varia6les.
'hader in.ut and out.ut declarations via in and out.
Im.roved com.ati6ilit( with *.en/0 +'
non;.ers.ective @linearA inter.olation @nosperspectiveA
3
1 Introduction
new verte1 in.ut gl_Verte$D.
=ew verte1 out.ut and #ragment shader in.ut gl_"li#Distance().
-he #ollowing is a summar( o# #eatures de.recated in version 1.&:
5se o# the ke(words attribute and var"ing @use in and outA.
5se o# gl_"li#Verte$ @use gl_"li#DistanceA
5se o# gl_'ragData and gl_'rag"olor @use user;de#ined out insteadA.
Built;in attri6utes. 5se user;de#ined verte1 in.uts instead.
)i1ed #unction verte1 or #ragment stages mi1ed with shader .rograms. 2rovide shaders #or all active
.rogramma6le .i.eline stages.
All 6uilt;in te1ture #unction names. 'ee new names.
5se o# the 6uilt;in var(ings gl_'og'rag"oor& and gl_%e$"oor&. 5se user;de#ined varia6le instead.
-he 6uilt in #unction ftransform. 5se the invariant >uali#ier on a verte1 out.ut instead.
9ost 6uilt;in state.
gl_*a$Var+ing'loats @use gl_*a$Var+ing"om#onents insteadA
-wo sided coloring: gl_,ac-"olor and gl_,ac-.econ&ar+"olor.
-he #ollowing is a summar( o# #eatures that have 6een removed in version 1.&:
=one, onl( de.recations occurred in this release.
1.! Overvie&
-his document descri6es %/e 0#en1L ./a&ing Language, version 1.40.
Inde.endent com.ilation units written in this language are called s/a&ers. A #rogram is a com.lete set o#
shaders that are com.iled and linked together. -he aim o# this document is to thoroughl( s.eci#( the
.rogramming language. -he *.en/0 /ra.hics '(stem '.eci#ication will s.eci#( the *.en/0 entr(
.oints used to mani.ulate and communicate with .rograms and shaders.
1.4 'rror (andling
!om.ilers, in general, acce.t .rograms that are ill;#ormed, due to the im.ossi6ilit( o# detecting all ill;
#ormed .rograms. 2orta6ilit( is onl( ensured #or well;#ormed .rograms, which this s.eci#ication
descri6es. !om.ilers are encouraged to detect ill;#ormed .rograms and issue diagnostic messages, 6ut are
not re>uired to do so #or all cases. !om.ilers are re>uired to return messages regarding le1icall(,
grammaticall(, or semanticall( incorrect shaders.
4
1 Introduction
1." T$pographical Conventions
Italic, 6old, and #ont choices have 6een used in this s.eci#ication .rimaril( to im.rove reada6ilit(. !ode
#ragments use a #i1ed width #ont. Identi#iers em6edded in te1t are italiciEed. Ke(words em6edded in te1t
are 6old. *.erators are called 6( their name, #ollowed 6( their s(m6ol in 6old in .arentheses. -he
clari#(ing grammar #ragments in the te1t use 6old #or literals and italics #or non;terminals. -he o##icial
grammar in 'ection 7 B'hading 0anguage /rammarC uses all ca.itals #or terminals and lower case #or
non;terminals.
1. )eprecation
-his version o# the *.en/0 'hading 0anguage de.recates some #eatures. -hese are clearl( called out in
this s.eci#ication as Bde.recatedC. -he( are still .resent in this version o# the language, 6ut are targeted
#or .otential removal in a #uture version o# the shading language. -he *.en/0 A2I has a #orward
com.ati6ilit( mode that will disallow use o# de.recated #eatures. I# com.iling in a mode where use o#
de.recated #eatures is disallowed, their use causes com.ile time errors. 'ee the *.en/0 /ra.hics '(stem
'.eci#ication #or details on what causes de.recated language #eatures to 6e acce.ted or to return an error.
-his version o# the *.en/0 'hading 0anguage also removes some #eatures that were de.recated in the
.revious version. 'ee a6ove #or list o# changes.
5
2 Overvie& of OpenGL Shading
-he *.en/0 'hading 0anguage is actuall( two closel( related languages. -hese languages are used to
create shaders #or the .rogramma6le .rocessors contained in the *.en/0 .rocessing .i.eline.
5nless otherwise noted in this .a.er, a language #eature a..lies to all languages, and common usage will
re#er to these languages as a single language. -he s.eci#ic languages will 6e re#erred to 6( the name o#
the .rocessor the( target: verte1 or #ragment.
9ost *.en/0 state is not tracked or made availa6le to shaders. -(.icall(, user;de#ined varia6les will 6e
used #or communicating 6etween di##erent stages o# the *.en/0 .i.eline. ,owever, a small amount o#
state is still tracked and automaticall( made availa6le to shaders, and there are a #ew 6uilt;in varia6les #or
inter#aces 6etween di##erent stages o# the *.en/0 .i.eline.
2.1 *erte+ ,rocessor
-he verte$ #rocessor is a .rogramma6le unit that o.erates on incoming vertices and their associated data.
!om.ilation units written in the *.en/0 'hading 0anguage to run on this .rocessor are called verte$
s/a&ers. Ghen a com.lete set o# verte1 shaders are com.iled and linked, the( result in a verte$ s/a&er
e$ecuta2le that runs on the verte1 .rocessor.
-he verte1 .rocessor o.erates on one verte1 at a time. It does not re.lace gra.hics o.erations that re>uire
knowledge o# several vertices at a time. -he verte1 shaders running on the verte1 .rocessor must
com.ute the homogeneous .osition o# the incoming verte1.
2.2 %rag#ent ,rocessor
-he 3ragment #rocessor is a .rogramma6le unit that o.erates on #ragment values and their associated
data. !om.ilation units written in the *.en/0 'hading 0anguage to run on this .rocessor are called
3ragment s/a&ers. Ghen a com.lete set o# #ragment shaders are com.iled and linked, the( result in a
3ragment s/a&er e$ecuta2le that runs on the #ragment .rocessor.
A #ragment shader cannot change a #ragmentDs @$, +A .osition. Access to neigh6oring #ragments is not
allowed. -he values com.uted 6( the #ragment shader are ultimatel( used to u.date #rame;6u##er memor(
or te1ture memor(, de.ending on the current *.en/0 state and the *.en/0 command that caused the
#ragments to 6e generated.
6
! -asics
!.1 Character Set
-he source character set used #or the *.en/0 shading languages is a su6set o# A'!II. It includes the
#ollowing characters:
-he letters a#$, A#%& and the underscore @ < A.
-he num6ers '#(.
-he s(m6ols .eriod @.A, .lus @)A, dash @#A, slash @*A, asterisk @+A, .ercent @,A, angled 6rackets @- and
.A, s>uare 6rackets @ / and 0 A, .arentheses @ 1 and 2 A, 6races @ 3 and 4 A, caret @5A, vertical 6ar @ 6 A,
am.ersand @7A, tilde @8A, e>uals @9A, e1clamation .oint @:A, colon @;A, semicolon @<A, comma @&A, and
>uestion mark @=A.
-he num6er sign @#A #or .re.rocessor use.
Ghite s.ace: the s.ace character, horiEontal ta6, vertical ta6, #orm #eed, carriage;return, and line;
#eed.
0ines are relevant #or com.iler diagnostic messages and the .re.rocessor. -he( are terminated 6(
carriage;return or line;#eed. I# 6oth are used together, it will count as onl( a single line termination. )or
the remainder o# this document, an( o# these com6inations is sim.l( re#erred to as a new;line. -here is no
line continuation character.
In general, the languageHs use o# this character set is case sensitive.
-here are no character or string data t(.es, so no >uoting characters are included.
-here is no end;o#;#ile character.
!.2 Source Strings
-he source #or a single shader is an arra( o# strings o# characters #rom the character set. A single shader
is made #rom the concatenation o# these strings. +ach string can contain multi.le lines, se.arated 6( new;
lines. =o new;lines need 6e .resent in a stringI a single line can 6e #ormed #rom multi.le strings. =o
new;lines or other characters are inserted 6( the im.lementation when it concatenates the strings to #orm a
single shader. 9ulti.le shaders can 6e linked together to #orm a single .rogram.
Diagnostic messages returned #rom com.iling a shader must identi#( 6oth the line num6er within a string
and which source string the message a..lies to. 'ource strings are counted se>uentiall( with the #irst
string 6eing string 8. 0ine num6ers are one more than the num6er o# new;lines that have 6een .rocessed.
7
3 Basics
!.! ,reprocessor
-here is a .re.rocessor that .rocesses the source strings as .art o# the com.ilation .rocess.
-he com.lete list o# .re.rocessor directives is as #ollows.
#
#define
#undef
#if
#ifdef
#ifndef
#else
#elif
#endif
#error
#pragma
#extension
#version
#line
-he #ollowing o.erators are also availa6le
defined
##
+ach num6er sign @#A can 6e .receded in its line onl( 6( s.aces or horiEontal ta6s. It ma( also 6e
#ollowed 6( s.aces and horiEontal ta6s, .receding the directive. +ach directive is terminated 6( a new;
line. 2re.rocessing does not change the num6er or relative location o# new;lines in a source string.
-he num6er sign @#A on a line 6( itsel# is ignored. An( directive not listed a6ove will cause a diagnostic
message and make the im.lementation treat the shader as ill;#ormed.
#define and #undef #unctionalit( are de#ined as is standard #or !JJ .re.rocessors #or macro de#initions
6oth with and without macro .arameters.
-he #ollowing .rede#ined macros are availa6le
__LINE__
__FILE__
__VERSION__
__LN4__ will su6stitute a decimal integer constant that is one more than the num6er o# .receding new;
lines in the current source string.
__'L4__ will su6stitute a decimal integer constant that sa(s which source string num6er is currentl(
6eing .rocessed.
8
3 Basics
__V4R.0N__ will su6stitute a decimal integer re#lecting the version num6er o# the *.en/0 shading
language. -he version o# the shading language descri6ed in this document will have __V4R.0N__
su6stitute the decimal integer 1$8.
All macro names containing two consecutive underscores @ >> A are reserved #or #uture use as .rede#ined
macro names. All macro names .re#i1ed with B/0<C @B/0C #ollowed 6( a single underscoreA are also
reserved.
#if& #ifdef& #ifndef& #else& #elif& and #endif are de#ined to o.erate as is standard #or !JJ .re.rocessors.
+1.ressions #ollowing #if and #elif are #urther restricted to e1.ressions o.erating on literal integer
constants, .lus identi#iers consumed 6( the defined o.erator. It is an error to use #if or #elif on
e1.ressions containing unde#ined macro names, other than as arguments to the defined o.erator.
!haracter constants are not su..orted. -he o.erators availa6le are as #ollows.
,recedence Operator class Operators .ssociativit$
1 @highestA .arenthetical grou.ing @ A =A
unar( de#ined
J ; K L
Right to 0e#t
& multi.licative M F N 0e#t to Right
$ additive J ; 0e#t to Right
% 6it;wise shi#t OO PP 0e#t to Right
" relational O P OQ PQ 0e#t to Right
3 e>ualit( QQ LQ 0e#t to Right
4 6it;wise and R 0e#t to Right
7 6it;wise e1clusive or S 0e#t to Right
18 6it;wise inclusive or T 0e#t to Right
11 logical and RR 0e#t to Right
1 @lowestA logical inclusive or T T 0e#t to Right
-he defined o.erator can 6e used in either o# the #ollowing wa(s:
defined identifier
defined ( identifier )
-wo tokens in a macro can 6e concatenated into one token using the token .asting @##A o.erator, as is
standard #or !JJ .re.rocessors. -he result must 6e a valid single token, which will then 6e su6?ect to
macro e1.ansion. -hat is, macro e1.ansion ha..ens onl( a#ter token .asting. -here are no other num6er
sign 6ased o.erators @e.g., no # or #?A, nor is there a si$eof o.erator.
-he semantics o# a..l(ing o.erators to integer literals in the .re.rocessor match those standard in the
!JJ .re.rocessor, not those in the *.en/0 'hading 0anguage.
9
3 Basics
2re.rocessor e1.ressions will 6e evaluated according to the 6ehavior o# the host .rocessor, not the
.rocessor targeted 6( the shader.
#error will cause the im.lementation to .ut a diagnostic message into the shader o6?ectHs in#ormation log
@see the *.en/0 /ra.hics '(stem '.eci#ication #or how to access a shader o6?ectHs in#ormation logA.
-he message will 6e the tokens #ollowing the #error directive, u. to the #irst new;line. -he
im.lementation must then consider the shader to 6e ill;#ormed.
#pragma allows im.lementation de.endent com.iler control. -okens #ollowing #pragma are not su6?ect
to .re.rocessor macro e1.ansion. I# an im.lementation does not recogniEe the tokens #ollowing
#pragma, then it will ignore that .ragma. -he #ollowing .ragmas are de#ined as .art o# the language.
#pragma ST!L
-he S@AGB .ragma is used to reserve .ragmas #or use 6( #uture revisions o# this language. =o
im.lementation ma( use a .ragma whose #irst token is S@AGB.
#pragma optimi"e#on)
#pragma optimi"e#off)
can 6e used to turn o## o.timiEations as an aid in develo.ing and de6ugging shaders. It can onl( 6e used
outside #unction de#initions. B( de#ault, o.timiEation is turned on #or all shaders. -he de6ug .ragma
#pragma de$ug#on)
#pragma de$ug#off)
can 6e used to ena6le com.iling and annotating a shader with de6ug in#ormation, so that it can 6e used
with a de6ugger. It can onl( 6e used outside #unction de#initions. B( de#ault, de6ug is turned o##.
'haders should declare the version o# the language the( are written to. -he language version a shader is
written to is s.eci#ied 6(
#version number
where num2er must 6e a version o# the language, #ollowing the same convention as __V4R.0N__ a6ove.
-he directive B#version 1$8C is re>uired in an( shader that uses version 1.$8 o# the language. An(
num2er re.resenting a version o# the language a com.iler does not su..ort will cause an error to 6e
generated. Version 1.18 o# the language does not re>uire shaders to include this directive, and shaders that
do not include a #version directive will 6e treated as targeting version 1.18. Di##erent shaders
@com.ilation unitsA that are linked together in the same .rogram must 6e the same version.
-he #version directive must occur in a shader 6e#ore an(thing else, e1ce.t #or comments and white s.ace.
10
3 Basics
B( de#ault, com.ilers o# this language must issue com.ile time s(ntactic, grammatical, and semantic
errors #or shaders that do not con#orm to this s.eci#ication. An( e1tended 6ehavior must #irst 6e ena6led.
Directives to control the 6ehavior o# the com.iler with res.ect to e1tensions are declared with the
#extension directive
#extension extension_name : behavior
#extension all : behavior
where e$tension_name is the name o# an e1tension. +1tension names are not documented in this
s.eci#ication. -he token all means the 6ehavior a..lies to all e1tensions su..orted 6( the com.iler. -he
2e/avior can 6e one o# the #ollowing
behavior 'ffect
re/uire Behave as s.eci#ied 6( the e1tension e$tension_name.
/ive an error on the #extension i# the e1tension e$tension_name is not
su..orted, or i# all is s.eci#ied.
enable Behave as s.eci#ied 6( the e1tension e$tension_name.
Garn on the #extension i# the e1tension e$tension_name is not su..orted.
/ive an error on the #extension i# all is s.eci#ied.
&arn Behave as s.eci#ied 6( the e1tension e$tension_name, e1ce.t issue warnings
on an( detecta6le use o# that e1tension, unless such use is su..orted 6( other
ena6led or re>uired e1tensions.
I# all is s.eci#ied, then warn on all detecta6le uses o# an( e1tension used.
Garn on the #extension i# the e1tension e$tension_name is not su..orted.
disable Behave @including issuing errors and warningsA as i# the e1tension
e$tension_name is not .art o# the language de#inition.
I# all is s.eci#ied, then 6ehavior must revert 6ack to that o# the non;e1tended
core version o# the language 6eing com.iled to.
Garn on the #extension i# the e1tension e$tension_name is not su..orted.
-he extension directive is a sim.le, low;level mechanism to set the 6ehavior #or each e1tension. It does
not de#ine .olicies such as which com6inations are a..ro.riate, those must 6e de#ined elsewhere. *rder
o# directives matters in setting the 6ehavior #or each e1tension: Directives that occur later override those
seen earlier. -he all variant sets the 6ehavior #or all e1tensions, overriding all .reviousl( issued
extension directives, 6ut onl( #or the 2e/aviors warn and disable.
11
3 Basics
-he initial state o# the com.iler is as i# the directive
#extension all % disa$le
was issued, telling the com.iler that all error and warning re.orting must 6e done according to this
s.eci#ication, ignoring an( e1tensions.
+ach e1tension can de#ine its allowed granularit( o# sco.e. I# nothing is said, the granularit( is a shader
@that is, a single com.ilation unitA, and the e1tension directives must occur 6e#ore an( non;.re.rocessor
tokens. I# necessar(, the linker can en#orce granularities larger than a single com.ilation unit, in which
case each involved shader will have to contain the necessar( e1tension directive.
9acro e1.ansion is not done on lines containing #extension and #version directives.
#line must have, a#ter macro su6stitution, one o# the #ollowing #orms:
#line line
#line line source-string-number
where line and source-string-num2er are constant integer e1.ressions. A#ter .rocessing this directive
@including its new;lineA, the im.lementation will 6ehave as i# it is com.iling at line num6er line51 and
source string num6er source-string-num2er. 'u6se>uent source strings will 6e num6ered se>uentiall(,
until another #line directive overrides that num6ering.
!.4 Co##ents
!omments are delimited 6( FM and MF, or 6( FF and a new;line. -he 6egin comment delimiters @FM or FFA are
not recogniEed as comment delimiters inside o# a comment, hence comments cannot 6e nested. I# a
comment resides entirel( within a single line, it is treated s(ntacticall( as a single s.ace. =ew;lines are
not eliminated 6( comments.
!." To0ens
-he language is a se>uence o# tokens. A token can 6e
to-en:
-e+6or&
i&enti3ier
integer-constant
3loating-constant
o#erator
< 3 4
12
3 Basics
!. 1e$&ords
-he #ollowing are the ke(words in the language, and cannot 6e used #or an( other .ur.ose than that
de#ined 6( this document:
attribute const uniform var"ing
la"out
centroid flat smoot noperspective
break continue do for wile switc case default
if else
in out inout
float int void bool true false
invariant
discard return
matC matD matE
matCxC matCxD matCxE
matDxC matDxD matDxE
matExC matExD matExE
vecC vecD vecE ivecC ivecD ivecE bvecC bvecD bvecE
uint uvecC uvecD uvecE
lowp mediump igp precision
sampler1A samplerCA samplerDA samplerCube
sampler1ASadow samplerCASadow samplerCubeSadow
sampler1AArra" samplerCAArra"
sampler1AArra"Sadow samplerCAArra"Sadow
isampler1A isamplerCA isamplerDA isamplerCube
isampler1AArra" isamplerCAArra"
usampler1A usamplerCA usamplerDA usamplerCube
usampler1AArra" usamplerCAArra"
samplerCAFect samplerCAFectSadow isamplerCAFect usamplerCAFect
samplerGuffer isamplerGuffer usamplerGuffer
struct
13
3 Basics
-he #ollowing are the ke(words reserved #or #uture use. 5sing them will result in an error:
common partition active
asm
class union enum t"pedef template tis packed
goto
inline noinline volatile public static extern external interface
long sort double alf fixed unsigned superp
input output
vecC vecD vecE dvecC dvecD dvecE fvecC fvecD fvecE
samplerDAFect

filter
image1A imageCA imageDA imageCube
iimage1A iimageCA iimageDA iimageCube
uimage1A uimageCA uimageDA uimageCube
image1AArra" imageCAArra"
iimage1AArra" iimageCAArra" uimage1AArra" uimageCAArra"
image1ASadow imageCASadow
image1AArra"Sadow imageCAArra"Sadow
imageGuffer iimageGuffer uimageGuffer
si$eof cast
namespace using
row>maHor
In addition, all identi#iers containing two consecutive underscores @>>A are reserved as .ossi6le #uture
ke(words.
!.7 Identifiers
Identi#iers are used #or varia6le names, #unction names, structure names, and #ield selectors @#ield
selectors select com.onents o# vectors and matrices similar to structure #ields, as discussed in 'ection %.%
BVector !om.onentsC and 'ection %." B9atri1 !om.onentsC A. Identi#iers have the #orm
i&enti3ier
non&igit
i&enti3ier non&igit
i&enti3ier &igit
14
3 Basics
non&igit: one o#
> a b c d e f g i H k l m n o p I r s t u v w x " $
A G C A ! J G K L M N B O P O Q R F S @ S T U V W %
&igit: one o#
' 1 C D E X Y Z [ (
Identi#iers starting with Bgl<C are reserved #or use 6( *.en/0, and ma( not 6e declared in a shader as
either a varia6le or a #unction. ,owever, as noted in the s.eci#ication, there are some cases where
.reviousl( declared varia6les can 6e redeclared to change or add some .ro.ert(, and .redeclared Ugl<U
names are allowed to 6e redeclared in a shader. onl( #or these s.eci#ic .ur.oses. 9ore generall(, it is an
error to redeclare a varia6le, including those starting Bgl<C.
!.2 Static 3se
'ome language rules descri6ed 6elow de.end on whether something is staticall+ written or used.
A shader contains a static use o# @or static assignment toA a varia6le $ i#, a#ter .re.rocessing, the shader
contains a statement that would read @or writeA $, whether or not run;time #low o# control will cause that
statement to 6e e1ecuted.
15
4 *ariables and T$pes
All varia6les and #unctions must 6e declared 6e#ore 6eing used. Varia6le and #unction names are
identi#iers.
-here are no de#ault t(.es. All varia6le and #unction declarations must have a declared t(.e, and
o.tionall( >uali#iers. A varia6le is declared 6( s.eci#(ing its t(.e #ollowed 6( one or more names
se.arated 6( commas. In man( cases, a varia6le can 6e initialiEed as .art o# its declaration 6( using the
assignment o.erator @9A. -he grammar near the end o# this document .rovides a #ull re#erence #or the
s(nta1 o# declaring varia6les.
5ser;de#ined t(.es ma( 6e de#ined using struct to aggregate a list o# e1isting t(.es into a single name.
-he *.en/0 'hading 0anguage is t(.e sa#e. -here are no im.licit conversions 6etween t(.es, with the
e1ce.tion that an integer value ma( a..ear where a #loating;.oint t(.e is e1.ected, and 6e converted to a
#loating;.oint value. +1actl( how and when this can occur is descri6ed in 'ection $.1.18 BIm.licit
!onversionsC and as re#erenced 6( other sections in this s.eci#ication.
4.1 -asic T$pes
-he *.en/0 'hading 0anguage su..orts the #ollowing 6asic data t(.es, grou.ed as #ollows.
-rans.arent t(.es
T$pe 4eaning
void #or #unctions that do not return a value
bool a conditional t(.e, taking on values o# true or #alse
int a signed integer
uint an unsigned integer
float a single #loating;.oint scalar
vecC a two;com.onent #loating;.oint vector
vecD a three;com.onent #loating;.oint vector
vecE a #our;com.onent #loating;.oint vector
bvecC a two;com.onent Boolean vector
bvecD a three;com.onent Boolean vector
bvecE a #our;com.onent Boolean vector
ivecC a two;com.onent signed integer vector
ivecD a three;com.onent signed integer vector
ivecE a #our;com.onent signed integer vector
16
4 Variables and Types
T$pe 4eaning
uvecC a two;com.onent unsigned integer vector
uvecD a three;com.onent unsigned integer vector
uvecE a #our;com.onent unsigned integer vector
matC a V #loating;.oint matri1
matD a &V& #loating;.oint matri1
matE a $V$ #loating;.oint matri1
matCxC same as a matC
matCxD a #loating;.oint matri1 with columns and & rows
matCxE a #loating;.oint matri1 with columns and $ rows
matDxC a #loating;.oint matri1 with & columns and rows
matDxD same as a matD
matDxE a #loating;.oint matri1 with & columns and $ rows
matExC a #loating;.oint matri1 with $ columns and rows
matExD a #loating;.oint matri1 with $ columns and & rows
matExE same as a matE
)loating 2oint 'am.ler -(.es @o.a>ueA
T$pe 4eaning
sampler1A a handle #or accessing a 1D te1ture
samplerCA a handle #or accessing a D te1ture
samplerDA a handle #or accessing a &D te1ture
samplerCube a handle #or accessing a cu6e ma..ed te1ture
samplerCAFect a handle #or accessing a rectangular te1ture
sampler1ASadow a handle #or accessing a 1D de.th te1ture with com.arison
samplerCASadow a handle #or accessing a D de.th te1ture with com.arison
samplerCAFectSadow a handle #or accessing a rectangular te1ture with com.arison
sampler1AArra" a handle #or accessing a 1D arra( te1ture
samplerCAArra" a handle #or accessing a D arra( te1ture
sampler1AArra"Sadow a handle #or accessing a 1D arra( de.th te1ture with com.arison
samplerCAArra"Sadow a handle #or accessing a D arra( de.th te1ture with com.arison
samplerGuffer a handle #or accessing a 6u##er te1ture
'igned Integer 'am.ler -(.es @o.a>ueA
17
4 Variables and Types
T$pe 4eaning
isampler1A a handle #or accessing an integer 1D te1ture
isamplerCA a handle #or accessing an integer D te1ture
isamplerDA a handle #or accessing an integer &D te1ture
isamplerCube a handle #or accessing an integer cu6e ma..ed te1ture
isamplerCAFect a handle #or accessing an integer D rectangular te1ture
isampler1AArra" a handle #or accessing an integer 1D arra( te1ture
isamplerCAArra" a handle #or accessing an integer D arra( te1ture
isamplerGuffer a handle #or accessing an integer 6u##er te1ture
5nsigned Integer 'am.ler -(.es @o.a>ueA
T$pe 4eaning
usampler1A a handle #or accessing an unsigned integer 1D te1ture
usamplerCA a handle #or accessing an unsigned integer D te1ture
usamplerDA a handle #or accessing an unsigned integer &D te1ture
usamplerCube a handle #or accessing an unsigned integer cu6e ma..ed te1ture
usamplerCAFect a handle #or accessing an unsigned integer rectangular te1ture
usampler1AArra" a handle #or accessing an unsigned integer 1D arra( te1ture
usamplerCAArra" a handle #or accessing an unsigned integer D arra( te1ture
usamplerGuffer a handle #or accessing an unsigned integer 6u##er te1ture
In addition, a shader can aggregate these using arra(s and structures to 6uild more com.le1 t(.es.
-here are no .ointer t(.es.
4.1.1 *oid
)unctions that do not return a value must 6e declared as void. -here is no de#ault #unction return t(.e.
-he ke(word void cannot 6e used in an( other declarations @e1ce.t #or em.t( #ormal or actual .arameter
listsA.
4.1.2 -ooleans
-o make conditional e1ecution o# code easier to e1.ress, the t(.e bool is su..orted. -here is no
e1.ectation that hardware directl( su..orts varia6les o# this t(.e. It is a genuine Boolean t(.e, holding
onl( one o# two values meaning either true or #alse. -wo ke(words true and false can 6e used as literal
Boolean constants. Booleans are declared and o.tionall( initialiEed as in the #ollow e1am.le:
$ool su&&ess' (( de&lare )su&&ess* to $e a +oolean
$ool done , false' (( de&lare and initiali"e )done*
18
4 Variables and Types
-he right side o# the assignment o.erator @ 9 A must 6e an e1.ression whose t(.e is bool.
+1.ressions used #or conditional ?um.s @if& for& =;& wile& do#wileA must evaluate to the t(.e bool.
4.1.! Integers
'igned and unsigned integer varia6les are #ull( su..orted. In this document, the term integer is meant to
generall( include 6oth signed and unsigned integers. 5nsigned integers have e1actl( & 6its o# .recision.
'igned integers use & 6its, including a sign 6it, in twoDs com.lement #orm. *.erations resulting in
over#low or under#low will not cause an( e1ce.tion, nor will the( saturate, rather the( will Bwra.C to (ield
the low;order & 6its o# the result.
Integers are declared and o.tionall( initialiEed with integer e1.ressions, as in the #ollowing e1am.le:
int i- . , /0' (( default integer literal t1pe is int
uint 2 , 3u' (( )u* esta$lis4es t4e t1pe as uint
0iteral integer constants can 6e e1.ressed in decimal @6ase 18A, octal @6ase 4A, or he1adecimal @6ase 1"A
as #ollows.
integer-constant :
&ecimal-constant integer-su33i$o#t
octal-constant integer-su33i$o#t
/e$a&ecimal-constant integer-su33i$o#t
integer-su33i$: one o#
u S
&ecimal-constant :
non7ero-&igit
&ecimal-constant &igit
octal-constant :
'
octal-constant octal-&igit
/e$a&ecimal-constant :
81 /e$a&ecimal-&igit
8W /e$a&ecimal-&igit
/e$a&ecimal-constant /e$a&ecimal-&igit
&igit :
'
non7ero-&igit
non7ero-&igit : one o#
1 C D E X Y Z [ (
octal-&igit ; one o#
' 1 C D E X Y Z
19
4 Variables and Types
/e$a&ecimal-&igit ; one o#
' 1 C D E X Y Z [ (
a b c d e f
A G C A ! J
=o white s.ace is allowed 6etween the digits o# an integer constant, including a#ter the leading ' or a#ter
the leading 'x or 'V o# a constant, or 6e#ore the su##i1 u or S. Ghen the su##i1 u or S is .resent, the
literal has t(.e uint, otherwise the t(.e is int. A leading unar( minus sign @;A is inter.reted as an
arithmetic unar( negation, not as .art o# the constant.
It is an error to .rovide a literal integer whose magnitude is too large to store in a varia6le o# matching
signed or unsigned t(.e.
4.1.4 %loats
)loats are availa6le #or use in a variet( o# scalar calculations. )loating;.oint varia6les are de#ined as in the
#ollowing e1am.le:
float a- $ , 567'
As an in.ut value to one o# the .rocessing units, a #loating;.oint varia6le is e1.ected to match the I+++
single .recision #loating;.oint de#inition #or .recision and d(namic range. It is not re>uired that the
.recision o# internal .rocessing match the I+++ #loating;.oint s.eci#ication #or #loating;.oint o.erations,
6ut the guidelines #or .recision esta6lished 6( the *.en/0 1.$ s.eci#ication must 6e met. 'imilarl(,
treatment o# conditions such as divide 6( 8 ma( lead to an uns.eci#ied result, 6ut in no case should such a
condition lead to the interru.tion or termination o# .rocessing.
)loating;.oint constants are de#ined as #ollows.
3loating-constant :
3ractional-constant e$#onent-#art
o#t
3loating-su33i$o#t

&igit-se8uence e$#onent-#art 3loating-su33i$o#t
3ractional-constant :
&igit-se8uence . &igit-se8uence
&igit-se8uence .
. &igit-se8uence
e$#onent-#art :
e sign
o#t
&igit-se8uence
E sign
o#t
&igit-se8uence
sign : one o#
) \
&igit-se8uence :
&igit
&igit-se8uence &igit
20
4 Variables and Types
3loating-su33i$: one o#
f J
A decimal .oint @ . A is not needed i# the e1.onent .art is .resent. =o white s.ace ma( a..ear an(where
within a #loating;.oint constant, including 6e#ore a su##i1. A leading unar( minus sign @#A is inter.reted as
a unar( o.erator and is not .art o# the #loating;.oint constant
4.1." *ectors
-he *.en/0 'hading 0anguage includes data t(.es #or generic ;, &;, and $;com.onent vectors o#
#loating;.oint values, integers, or Booleans. )loating;.oint vector varia6les can 6e used to store colors,
normals, .ositions, te1ture coordinates, te1ture looku. results and the like. Boolean vectors can 6e used
#or com.onent;wise com.arisons o# numeric vectors. 'ome e1am.les o# vector declaration are:
ve&0 tex&oord5- tex&oord0'
ve&3 position'
ve&/ m1R!+8'
ive&0 textureLoo2up'
$ve&3 less'
InitialiEation o# vectors can 6e done with constructors, which are discussed shortl(.
4.1. 4atrices
-he *.en/0 'hading 0anguage has 6uilt;in t(.es #or V, V&, V$, &V, &V&, &V$, $V, $V&, and $V$
matrices o# #loating;.oint num6ers. -he #irst num6er in the t(.e is the num6er o# columns, the second is
the num6er o# rows. +1am.le matri1 declarations:
mat0 mat0'
mat3 opt9atrix'
mat/ vie:- pro.e&tion'
mat/x/ vie:' (( an alternate :a1 of de&laring a mat/
mat3x0 m' (( a matrix :it4 3 &olumns and 0 ro:s
InitialiEation o# matri1 values is done with constructors @descri6ed in 'ection %.$ B!onstructorsC A in
column;ma?or order.
4.1.7 Sa#plers
'am.ler t(.es @e.g., samplerCAA are e##ectivel( o.a>ue handles to te1tures and their #ilters. -he( are
used with the 6uilt;in te1ture #unctions @descri6ed in 'ection 4.3 B-e1ture 0ooku. )unctionsC A to s.eci#(
which te1ture to access and how it is to 6e #iltered. -he( can onl( 6e declared as #unction .arameters or
uniform varia6les @see 'ection $.&.% B5ni#ormC A. +1ce.t #or arra( inde1ing, structure #ield selection,
and .arentheses, sam.lers are not allowed to 6e o.erands in e1.ressions. 'am.lers aggregated into arra(s
within a shader @using s>uare 6rackets / 0A can onl( 6e inde1ed with integral constant e1.ressions @see
'ection $.&.& B!onstant +1.ressionsCA. 'am.lers cannot 6e treated as l;valuesI hence cannot 6e used as
out or inout #unction .arameters, nor can the( 6e assigned into. As uni#orms, the( are initialiEed onl(
with the *.en/0 A2II the( cannot 6e declared with an initialiEer in a shader. As #unction .arameters,
onl( sam.lers ma( 6e .assed to sam.lers o# matching t(.e. -his ena6les consistenc( checking 6etween
shader te1ture accesses and *.en/0 te1ture state 6e#ore a shader is run.
21
4 Variables and Types
4.1.2 Structures
5ser;de#ined t(.es can 6e created 6( aggregating other alread( de#ined t(.es into a structure using the
struct ke(word. )or e1am.le,
stru&t lig4t ;
float intensit1'
ve&3 position'
< lig4tVar'
In this e1am.le, lig/t 6ecomes the name o# the new t(.e, and lig/tVar 6ecomes a varia6le o# t(.e lig/t.
-o declare varia6les o# the new t(.e, use its name @without the ke(word structA.
lig4t lig4tVar0'
9ore #ormall(, structures are declared as #ollows. ,owever, the com.lete correct grammar is as given in
'ection 7 B'hading 0anguage /rammarC .
struct-&e3inition :
8uali3ier
o#t
struct name
o#t
3 mem2er-list 4 &eclarators
o#t
9
mem2er-list :
mem2er-&eclaration9
mem2er-&eclaration mem2er-list9
mem2er-&eclaration :
2asic-t+#e &eclarators9
where name 6ecomes the user;de#ined t(.e, and can 6e used to declare varia6les to 6e o# this new t(.e.
-he name shares the same name s.ace as other varia6les, t(.es, and #unctions. All .reviousl( visi6le
varia6les, t(.es, constructors, or #unctions with that name are hidden. -he o.tional 8uali3ier onl( a..lies
to an( &eclarators, and is not .art o# the t(.e 6eing de#ined #or name.
'tructures must have at least one mem6er declaration. 9em6er declarators ma( contain .recision
>uali#iers, 6ut ma( not contain an( other >uali#iers. Bit #ields are not su..orted. 9em6er t(.es must 6e
alread( de#ined @there are no #orward re#erencesA. 9em6er declarations cannot contain initialiEers.
9em6er declarators can contain arra(s. 'uch arra(s must have a siEe s.eci#ied, and the siEe must 6e an
integral constant e1.ression thatDs greater than Eero @see 'ection $.&.& B!onstant +1.ressionsCA. +ach
level o# structure has its own name s.ace #or names given in mem6er declaratorsI such names need onl(
6e uni>ue within that name s.ace.
Anon(mous structures are not su..orted. +m6edded structure de#initions are not su..orted.
22
4 Variables and Types
stru&t S ; float f' <'
stru&t T ;
S' (( Error% anon1mous stru&tures disallo:ed
stru&t ; 666 <' (( Error% em$edded stru&tures disallo:ed
S s' (( O2a1% nested stru&tures :it4 name are allo:ed
<'
'tructures can 6e initialiEed at declaration time using constructors, as discussed in 'ection %.$.&
B'tructure !onstructorsC .
4.1.5 .rra$s
Varia6les o# the same t(.e can 6e aggregated into arra(s 6( declaring a name #ollowed 6( 6rackets @ / 0 A
enclosing an o.tional siEe. Ghen an arra( siEe is s.eci#ied in a declaration, it must 6e an integral constant
e1.ression @see 'ection $.&.& B!onstant +1.ressionsC A greater than Eero. I# an arra( is inde1ed with an
e1.ression that is not an integral constant e1.ression, or i# an arra( is .assed as an argument to a #unction,
then its siEe must 6e declared 6e#ore an( such use. It is legal to declare an arra( without a siEe and then
later re;declare the same name as an arra( o# the same t(.e and s.eci#( a siEe. It is illegal to declare an
arra( with a siEe, and then later @in the same shaderA inde1 the same arra( with an integral constant
e1.ression greater than or e>ual to the declared siEe. It is also illegal to inde1 an arra( with a negative
constant e1.ression. Arra(s declared as #ormal .arameters in a #unction declaration must s.eci#( a siEe.
5nde#ined 6ehavior results #rom inde1ing an arra( with a non;constant e1.ression thatHs greater than or
e>ual to the arra(Hs siEe or less than 8. *nl( one;dimensional arra(s ma( 6e declared. All 6asic t(.es and
structures can 6e #ormed into arra(s. 'ome e1am.les are:
float fre=uen&ies>3?'
uniform ve&/ lig4t@osition>/?'
lig4t lig4ts>?'
&onst int numLig4ts , 0'
lig4t lig4ts>numLig4ts?'
An arra( t(.e can 6e #ormed 6( s.eci#(ing a t(.e #ollowed 6( s>uare 6rackets @X YA and including a siEe:
float>7?
-his t(.e can 6e used an(where an( other t(.e can 6e used, including as the return value #rom a #unction
float>7? foo#) ; <
as a constructor o# an arra(
float>7?#36/- /60- 76A- 760- 565)
as an unnamed .arameter
void foo#float>7?)
and as an alternate wa( o# declaring a varia6le or #unction .arameter.
23
4 Variables and Types
float>7? a'
It is an error to declare arra(s o# arra(s:
float a>7?>3?' (( illegal
float>7? a>3?' (( illegal
Arra(s can have initialiEers #ormed #rom arra( constructors:
float a>7? , float>7?#36/- /60- 76A- 760- 565)'
float a>7? , float>?#36/- /60- 76A- 760- 565)' (( same t4ing
5nsiEed arra(s can 6e e1.licitl( siEed 6( an initialiEer at declaration time:
float a>7?'
666
float $>? , a' (( $ is expli&itl1 si"e 7
float $>7? , a' (( means t4e same t4ing
,owever, im.licitl( siEed arra(s cannot 6e assigned to. =ote, this is a rare case that initialiEers and
assignments a..ear to have di##erent semantics.
Arra(s know the num6er o# elements the( contain. -his can 6e o6tained 6( using the length method:
a6lengt4#)' (( returns 7 for t4e a$ove de&larations
-he length method cannot 6e called on an arra( that has not 6een e1.licitl( siEed.
24
4 Variables and Types
4.1.16 I#plicit Conversions
In some situations, an e1.ression and its t(.e will 6e im.licitl( converted to a di##erent t(.e. -he
#ollowing ta6le shows all allowed im.licit conversions:
T$pe of e+pression Can be i#plicitl$ converted to
int
uint
float
ivecC
uvecC
vecC
ivecD
uvecD
vecD
ivecE
uvecE
vecE
-here are no im.licit arra( or structure conversions. )or e1am.le, an arra( o# int cannot 6e im.licitl(
converted to an arra( o# float. -here are no im.licit conversions 6etween signed and unsigned integers.
Ghen an im.licit conversion is done, it is not a re;inter.retation o# the e1.ressionDs 6it .attern, 6ut a
conversion o# its value to an e>uivalent value in the new t(.e. )or e1am.le, the integer value ;X will 6e
converted to the #loating;.oint value ;X.'. Integer values having more 6its o# .recision than a #loating
.oint mantissa will lose .recision when converted to float.
-he conversions in the ta6le a6ove are done onl( as indicated 6( other sections o# this s.eci#ication.
4.2 Scoping
-he sco.e o# a varia6le is determined 6( where it is declared. I# it is declared outside all #unction
de#initions, it has glo6al sco.e, which starts #rom where it is declared and .ersists to the end o# the shader
it is declared in. I# it is declared in a wile test or a for statement, then it is sco.ed to the end o# the
#ollowing su6;statement. *therwise, i# it is declared as a statement within a com.ound statement, it is
sco.ed to the end o# that com.ound statement. I# it is declared as a .arameter in a #unction de#inition, it is
sco.ed until the end o# that #unction de#inition. A #unction 6od( has a sco.e nested inside the #unctionHs
de#inition. -he if statementHs e1.ression does not allow new varia6les to 6e declared, hence does not
#orm a new sco.e.
25
4 Variables and Types
Githin a declaration, the sco.e o# a name starts immediatel( a#ter the initialiEer i# .resent or immediatel(
a#ter the name 6eing declared i# not. 'everal e1am.les:
int x , 5'
;
int x , 0- 1 , x' (( 1 is initiali"ed to 0
<
stru&t S
;
int x'
<'
;
S S , S#A)' (( BSB is onl1 visi$le as a stru&t and &onstru&tor
S' (( BSB is no: visi$le as a varia$le
<
int x , x' (( Error if x 4as not $een previousl1 defined6
All varia6le names, structure t(.e names, and #unction names in a given sco.e share the same name s.ace.
)unction names can 6e redeclared in the same sco.e, with the same or di##erent .arameters, without error.
An im.licitl( siEed arra( can 6e re;declared in the same sco.e as an arra( o# the same 6ase t(.e.
*therwise, within one com.ilation unit, a declared name cannot 6e redeclared in the same sco.eI doing so
results in a redeclaration error. I# a nested sco.e redeclares a name used in an outer sco.e, it hides all
e1isting uses o# that name. -here is no wa( to access the hidden name or make it unhidden, without
e1iting the sco.e that hid it.
-he 6uilt;in #unctions are sco.ed in a sco.e outside the glo6al sco.e users declare glo6al varia6les in.
-hat is, a shaderDs glo6al sco.e, availa6le #or user;de#ined #unctions and glo6al varia6les, is nested inside
the sco.e containing the 6uilt;in #unctions. Ghen a #unction name is redeclared in a nested sco.e, it hides
all #unctions declared with that name in the outer sco.e. )unction declarations @.rotot(.esA cannot occur
inside o# #unctionsI the( must 6e at glo6al sco.e, or #or the 6uilt;in #unctions, outside the glo6al sco.e.
'hared glo6als are glo6al varia6les declared with the same name in inde.endentl( com.iled units
@shadersA o# the same language @verte1 or #ragmentA that are linked together to make a single .rogram.
'hared glo6als share the same name s.ace, and must 6e declared with the same t(.e. -he( will share the
same storage. 'hared glo6al arra(s must have the same 6ase t(.e and the same e1.licit siEe. An arra(
im.licitl( siEed in one shader can 6e e1.licitl( siEed 6( another shader. I# no shader has an e1.licit siEe
#or the arra(, the largest im.licit siEe is used. 'calars must have e1actl( the same t(.e name and t(.e
de#inition. 'tructures must have the same name, se>uence o# t(.e names, and t(.e de#initions, and #ield
names to 6e considered the same t(.e. -his rule a..lies recursivel( #or nested or em6edded t(.es. All
initialiEers #or a shared glo6al must have the same value, or a link error will result.
26
4 Variables and Types
4.! Storage 7ualifiers
Varia6le declarations ma( have one storage >uali#ier s.eci#ied in #ront o# the t(.e. -hese are summariEed
as
7ualifier 4eaning
O none: de#ault P local readFwrite memor(, or an in.ut .arameter to a #unction
const a com.ile;time constant, or a #unction .arameter that is read;onl(
in
centroid in
linkage into a shader #rom a .revious stage, varia6le is co.ied in
linkage with centroid 6ased inter.olation
out
centroid out
linkage out o# a shader to a su6se>uent stage, varia6le is co.ied out
linkage with centroid 6ased inter.olation
attribute de.recatedI linkage 6etween a verte1 shader and *.en/0 #or .er;verte1
data
uniform value does not change across the .rimitive 6eing .rocessed, uni#orms
#orm the linkage 6etween a shader, *.en/0, and the a..lication
var"ing
centroid var"ing
de.recatedI linkage 6etween a verte1 shader and a #ragment shader #or
inter.olated data
*ut.uts #rom a verte1 shader @outA and in.uts to a #ragment shader @inA can 6e #urther >uali#ied with one
o# these inter.olation >uali#iers
7ualifier 4eaning
smoot .ers.ective correct inter.olation
flat no inter.olation
noperspective linear inter.olation
-hese inter.olation >uali#iers ma( onl( .recede the >uali#iers in, centroid in, out, or centroid out in a
declaration. -he( do not a..l( to the de.recated storage >uali#iers var"ing or centroid var"ing. -he(
also do not a..l( to in.uts into a verte1 shader or out.uts #rom a #ragment shader.
0ocal varia6les can onl( use the const storage >uali#ier.
)unction .arameters can use const, in, and out >uali#iers, 6ut as #arameter 8uali3iers. 2arameter
>uali#iers are discussed in 'ection ".1.1 B)unction !alling !onventionsC.
)unction return t(.es and structure #ields do not use storage >uali#iers.
Data t(.es #or communication #rom one run o# a shader e1ecuta6le to its ne1t run @to communicate
6etween #ragments or 6etween verticesA do not e1ist. -his would .revent .arallel e1ecution o# the same
shader e1ecuta6le on multi.le vertices or #ragments.
27
4 Variables and Types
InitialiEers ma( onl( 6e used in declarations o# glo6als with no storage >uali#ier, with a const >uali#ier or
with a uniform >uali#ier. /lo6al varia6les without storage >uali#iers that are not initialiEed in their
declaration or 6( the a..lication will not 6e initialiEed 6( *.en/0, 6ut rather will enter main:; with
unde#ined values.
4.!.1 )efault Storage 7ualifier
I# no >uali#ier is .resent on a glo6al varia6le, then the varia6le has no linkage to the a..lication or shaders
running on other .i.eline stages. )or either glo6al or local un>uali#ied varia6les, the declaration will
a..ear to allocate memor( associated with the .rocessor it targets. -his varia6le will .rovide readFwrite
access to this allocated memor(.
4.!.2 Constant 7ualifier
=amed com.ile;time constants can 6e declared using the const >uali#ier. An( varia6les >uali#ied as
constant are read;onl( varia6les #or that shader. Declaring varia6les as constant allows more descri.tive
shaders than using hard;wired numerical constants. -he const >uali#ier can 6e used with an( o# the 6asic
data t(.es. It is an error to write to a const varia6le outside o# its declaration, so the( must 6e initialiEed
when declared. )or e1am.le,
&onst ve&3 "8xis , ve&3 #A6A- A6A- 56A)'
'tructure #ields ma( not 6e >uali#ied with const. 'tructure varia6les can 6e declared as const, and
initialiEed with a structure constructor.
InitialiEers #or const declarations must 6e constant e1.ressions, as de#ined in 'ection $.&.& B!onstant
+1.ressions.C
4.!.! Constant '+pressions
A constant e$#ression is one o#
a literal value @e.g., X or trueA
a glo6al or local varia6le >uali#ied as const @i.e., not including #unction .arametersA
an e1.ression #ormed 6( an o.erator on o.erands that are all constant e1.ressions, including getting an
element or length o# a constant arra(, or a #ield o# a constant structure, or com.onents o# a constant
vector.
a constructor whose arguments are all constant e1.ressions
a 6uilt;in #unction call whose arguments are all constant e1.ressions, with the e1ce.tion o# the te1ture
looku. #unctions and the noise #unctions. -he 6uilt;in #unctions dJdx, dJd", and fwidt must return
8 when evaluated inside an initialiEer with an argument that is a constant e1.ression.
)unction calls to user;de#ined #unctions @non;6uilt;in #unctionsA cannot 6e used to #orm constant
e1.ressions.
An integral constant e$#ression is a constant e1.ression that evaluates to a scalar signed or unsigned
integer.
28
4 Variables and Types
!onstant e1.ressions will 6e evaluated in an invariant wa( so as to create the same value in multi.le
shaders when the same constant e1.ressions a..ear in those shaders. 'ee section $.".1 B-he Invariant
:uali#ierC #or more details on how to create invariant e1.ressions.
4.!.4 Inputs
'hader in.ut varia6les are declared with the in storage >uali#ier or the centroid in storage >uali#ier. -he(
#orm the in.ut inter#ace 6etween .revious stages o# the *.en/0 .i.eline and the declaring shader. In.ut
varia6les must 6e declared at glo6al sco.e. Values #rom the .revious .i.eline stage are co.ied into in.ut
varia6les at the 6eginning o# shader e1ecution. Varia6les declared as in or centroid in ma( not 6e written
to during shader e1ecution.
Verte1 shader in.ut varia6les @or attri6utesA receive .er;verte1 data. -he( are declared in a verte1 shader
with the in >uali#ier or the de.recated attribute >uali#ier. It is an error to use centroid in or inter.olation
>uali#iers in a verte1 shader in.ut. -he values co.ied in are esta6lished 6( the *.en/0 A2I. It is an
error to use attribute in a non;verte1 shader. Verte1 shader in.uts can onl( 6e float, #loating;.oint
vectors, matrices, signed and unsigned integers and integer vectors. -he( cannot 6e arra(s or structures.
+1am.le declarations in a verte1 shader:
in ve&/ position'
in ve&3 normal'
in ve&0 texCoord'
'ee 'ection 3 BBuilt;in Varia6lesC #or a list o# the 6uilt;in in.ut names.
)ragment shader in.uts @or var(ingsA get .er;#ragment values, t(.icall( inter.olated #rom a .revious
stageDs out.uts. -he( are declared in #ragment shaders with the in storage >uali#ier, the centroid in
storage >uali#ier, or the de.recated var"ing and centroid var"ing storage >uali#iers. )ragment in.uts
can onl( 6e signed and unsigned integers and integer vectors, float, #loating;.oint vectors, matrices, or
arra(s o# these. 'tructures cannot 6e in.ut.
)ragment in.uts are declared as in the #ollowing e1am.les:
in ve&3 normal'
&entroid in ve&0 TexCoord'
invariant &entroid in ve&/ Color'
noperspe&tive out float temperature'
flat in ve&3 m1Color'
noperspe&tive &entroid in ve&0 m1TexCoord'
It is e1.ected that gra.hics hardware will have a small num6er o# #i1ed vector locations #or .assing verte1
in.uts. -here#ore, the *.en/0 'hading language de#ines each non;matri1 in.ut varia6le as taking u. one
such vector location . -here is an im.lementation de.endent limit on the num6er o# locations that can 6e
used, and i# this is e1ceeded it will cause a link error. @Declared in.ut varia6les that are not staticall( used
do not count against this limit.A A scalar in.ut counts the same amount against this limit as a vecE, so
a..lications ma( want to consider .acking grou.s o# #our unrelated #loat in.uts together into a vector to
6etter utiliEe the ca.a6ilities o# the underl(ing hardware. A matri1 in.ut will use u. multi.le locations.
-he num6er o# locations used will e>ual the num6er o# columns in the matri1.
29
4 Variables and Types
4.!." 3nifor#
-he uniform >uali#ier is used to declare glo6al varia6les whose values are the same across the entire
.rimitive 6eing .rocessed. All uniform varia6les are read;onl( and are initialiEed e1ternall( either at link
time or through the A2I. -he link time initial value is either the value o# the varia6leDs initialiEer, i#
.resent, or 8 i# no initialiEer is .resent. 'am.ler t(.es cannot have initialiEers.
+1am.le declarations are:
uniform ve&/ lig4t@osition'
uniform ve&3 &olor , ve&3#A6D- A6D- A60)' (( value assigned at lin2 time
-he uniform >uali#ier can 6e used with an( o# the 6asic data t(.es, or when declaring a varia6le whose
t(.e is a structure, or an arra( o# an( o# these.
-here is an im.lementation de.endent limit on the amount o# storage #or uni#orms that can 6e used #or
each t(.e o# shader and i# this is e1ceeded it will cause a com.ile;time or link;time error. 5ni#orm
varia6les that are declared 6ut not used do not count against this limit. -he num6er o# user;de#ined
uni#orm varia6les and the num6er o# 6uilt;in uni#orm varia6les that are used within a shader are added
together to determine whether availa6le uni#orm storage has 6een e1ceeded.
I# multi.le shaders are linked together, then the( will share a single glo6al uni#orm name s.ace. ,ence,
the t(.es and initialiEers o# uni#orm varia6les with the same name must match across all shaders that are
linked into a single e1ecuta6le.
It is legal #or some shaders to .rovide an initialiEer #or a .articular uni#orm varia6le, while another shader
does not, 6ut all .rovided initialiEers must 6e e>ual.
4.!.".1 3nifor# -loc0s
Varia6le declarations at glo6al sco.e can 6e grou.ed into a named 6lock to .rovide coarser granularit(
#or mani.ulation, sharing, or 6acking than is achieva6le with individual declarations. -his is currentl(
onl( allowed #or uni#orm varia6les grou.ed into uni#orm 6locks. All other uses are reserved.
-he a..lication 6acks a uni#orm 6lock with a 6u##er. -his allows a..lication access to a set o# uni#orm
varia6les through a single 6u##er. -he a..lication will need to >uer( the o##sets o# the varia6les within the
6lock or #ollow standard rules #or 6lock la(out in order to know how to la(out the contents o# a 6u##er
used to 6ack the 6lock.
A uni#orm 6lock @rather than a uni#orm varia6leA is created 6( the uniform ke(word, #ollowed 6( a 6lock
name, #ollowed 6( an o.en curl( 6race @ 3 A as #ollows:
uni3orm-2loc- :
la+out-8uali3ieropt uniform 2loc--name 3 mem2er-list 4 <
la+out-8uali3ier :
la"out 1 la+out-8uali3ier-i&-list 2
mem2er-list :
mem2er-&eclaration
mem2er-&eclaration mem2er-list
30
4 Variables and Types
mem2er-&eclaration :
la+out-8uali3ieropt uniformopt 2asic-t+#e &eclarators <
Ghere declarators are the same as #or other uni#orm varia6le declarations, e1ce.t initialiEers are not
allowed. 0a(out >uali#iers are de#ined in the ne1t section.
)or e1am.le,
uniform Transform ;
mat/ 9odelVie:9atrix'
mat/ 9odelVie:@ro.e&tion9atrix'
uniform mat3 Normal9atrix' (( reuse of uniform is optional
float eformation'
<'
-he a6ove esta6lishes a uni#orm 6lock named B-rans#ormC with #our uni#orms grou.ed inside it.
)loating .oint, integer, and Boolean t(.es are all su..orted, in the same manner as uni#orm declarations
outside o# uni#orm 6locks.
-he names declared inside the 6lock are accessed as i# the( were declared outside the 6lock. In no wa(
does the shader ever access 6lock mem6ers through an( use o# 2loc--name.
5ni#orm 6lock names and varia6le names declared within uni#orm 6locks are sco.ed at the .rogram level.
9atching 6lock names #rom multi.le com.ilation units in the same .rogram must match in terms o#
having the same num6er o# declarations with the same se>uence o# t(.es and the same se>uence o#
mem6er names, as well as having the same mem6er;wise la(out >uali#ication @see ne1t sectionA. An(
mismatch will generate a link error.
'am.ler t(.es are not allowed inside o# uni#orm 6locks. All other t(.es, arra(s, and structures allowed
#or uni#orms are allowed within a uni#orm 6lock.
-here is an im.lementation de.endent limit on the num6er o# uni#orm 6locks that can 6e used .er stage.
I# this limit is e1ceeded, it will cause a link error.
4.!.".2 3nifor# -loc0 La$out 7ualifiers
-he la+out-8uali3ier-i&-list #or uni#orm 6locks is a comma se.arated list o# the #ollowing >uali#iers:
s4ared #default)
pa&2ed
std5/A
ro:_ma.or
&olumn_ma.or #default)
-hese >uali#iers are identi#iers, not ke(words. =one o# these have an( semantic a##ect at all on the usage
o# the varia6les 6eing declaredI the( onl( descri6e how data is laid out in memor(. )or e1am.le, matri1
semantics are alwa(s column;6ased, as descri6ed in the rest o# this s.eci#ication, no matter what la(out
>uali#iers are 6eing used.
5ni#orm 6lock la(out >uali#iers can 6e declared #or glo6al sco.e, on a single uni#orm 6lock, or on a single
6lock mem6er declaration.
31
4 Variables and Types
At glo6al sco.e, it is an error to use la(out >uali#iers to declare a varia6le. Instead, at glo6al sco.e, la(out
>uali#iers a..l( ?ust to the ke(word uniform and esta6lish de#ault >uali#ication #or su6se>uent 6locks:
la+out-&e3aults :
la+out-8uali3ier uniform <
Ghen this is done, the .revious de#ault >uali#ication is #irst inherited and then overridden as .er the
override rules listed 6elow #or each >uali#ier listed in the declaration. -he result 6ecomes the new de#ault
>uali#ication sco.ed to su6se>uent uni#orm 6lock de#initions. 0a(out de#aults can onl( 6e s.eci#ied at
glo6al sco.e.
-he initial state o# com.ilation is as i# the #ollowing were declared:
la1out#s4ared- &olumn_ma.or) uniform'
+1.licitl( declaring this in a shader will return de#aults 6ack to their initial state.
5ni#orm 6locks can 6e declared with o.tional la(out >uali#iers, and so can their individual mem6er
declarations. 'uch 6lock la(out >uali#ication is sco.ed onl( to the content o# the 6lock. As with glo6al
la(out declarations, 6lock la(out >uali#ication #irst inherits #rom the current de#ault >uali#ication and then
overrides it. 'imilarl(, individual mem6er la(out >uali#ication is sco.ed ?ust to the mem6er declaration,
and inherits #rom and overrides the 6lockDs >uali#ication.
-he s/are& >uali#ier overrides onl( the st&140 and #ac-e& >uali#iersI other >uali#iers are inherited. -he
com.ilerFlinker will ensure that multi.le .rograms and .rogramma6le stages containing this de#inition
will share the same memor( la(out #or this 6lock, as long as the( also matched in their ro6_ma<or andFor
column_ma<or >uali#ications. -his allows use o# the same 6u##er to 6ack the same 6lock de#inition across
di##erent .rograms.
-he #ac-e& >uali#ier overrides onl( st&140 and s/are&I other >uali#iers are inherited. Ghen #ac-e& is
used, no sharea6le la(out is guaranteed. -he com.iler and linker can o.timiEe memor( use 6ased on what
varia6les activel( get used and on other criteria. *##sets must 6e >ueried, as there is no other wa( o#
guaranteeing where @and whichA varia6les reside within the 6lock. Attem.ts to share a .acked uni#orm
6lock across .rograms or stages will generall( #ail. ,owever, im.lementations ma( aid a..lication
management o# .acked 6locks 6( using canonical la(outs #or .acked 6locks.
-he st&140 >uali#ier overrides onl( the #ac-e& and s/are& >uali#iersI other >uali#iers are inherited. -he
la(out is e1.licitl( determined 6( this, as descri6ed in the *.en/0 /ra.hics '(stem '.eci#ication.
,ence, as in s/are& a6ove, the resulting la(out is sharea6le across .rograms.
0a(out >uali#iers on mem6er declarations cannot use the s/are&, #ac-e&, or st&140 >uali#iers. -hese can
onl( 6e used at glo6al sco.e or on a 6lock declaration.
-he ro6_ma<or >uali#ier overrides onl( the column_ma<or >uali#ierI other >uali#iers are inherited. It onl(
a##ects the la(out o# matrices. +lements within a matri1 row will 6e contiguous in memor(.
-he column_ma<or >uali#ier overrides onl( the ro6_ma<or >uali#ierI other >uali#iers are inherited. It onl(
a##ects the la(out o# matrices. +lements within a matri1 column will 6e contiguous in memor(.
Ghen multi.le arguments are listed in a la"out declaration, the a##ect will 6e the same as i# the( were
declared one at a time, in order #rom le#t to right, each in turn inheriting #rom and overriding the result
#rom the .revious >uali#ication.
32
4 Variables and Types
)or e1am.le
la1out#ro:_ma.or- &olumn_ma.or)
results in the >uali#ication 6eing column_ma<or. *ther e1am.les:
la1out#s4ared- ro:_ma.or) uniform' (( default is no: s4ared and ro:_ma.or
la1out#std5/A) uniform Transform ; (( la1out of t4is $lo&2 is std5/A
mat/ 95' (( ro:_ma.or
la1out#&olumn_ma.or) mat/ 90' (( &olumn ma.or
mat3 N5' (( ro:_ma.or
<'
uniform T0 ; (( la1out of t4is $lo&2 is s4ared
666
<'
la1out#&olumn_ma.or) uniform T3 ; (( s4ared and &olumn_ma.or
mat/ 93' (( &olumn_ma.or
la1out#ro:_ma.or) mat/ m/' (( ro: ma.or
mat3 N0' (( &olumn_ma.or
<'
4.!. Outputs
'hader out.ut varia6les are declared with the out or centroid out storage >uali#iers. -he( #orm the
out.ut inter#ace 6etween the declaring shader and the su6se>uent stages o# the *.en/0 .i.eline. *ut.ut
varia6les must 6e declared at glo6al sco.e. During shader e1ecution the( will 6ehave as normal
un>uali#ied glo6al varia6les. -heir values are co.ied out to the su6se>uent .i.eline stage on shader e1it.
-here is not an inout storage >uali#ier at glo6al sco.e #or declaring a single varia6le name as 6oth in.ut
and out.ut to a shader. *ut.ut varia6les must 6e declared with di##erent names than in.ut varia6les.
Verte1 out.ut varia6les out.ut .er;verte1 data and are declared using the out storage >uali#ier, the
centroid out storage >uali#ier, or the de.recated var"ing storage >uali#ier. -he( can onl( 6e float,
#loating;.oint vectors, matrices, signed or unsigned integers or integer vectors, or arra(s o# an( these. I# a
verte1 out.ut is a signed or unsigned integer or integer vector, then it must 6e >uali#ied with the
inter.olation >uali#ier flat. 'tructures cannot 6e out.ut.
Verte1 out.uts are declared as in the #ollowing e1am.les:
33
4 Variables and Types
out ve&3 normal'
&entroid out ve&0 TexCoord'
invariant &entroid out ve&/ Color'
noperspe&tive out float temperature' (( var1ing is depre&ated
flat out ve&3 m1Color'
noperspe&tive &entroid out ve&0 m1TexCoord'
)ragment out.uts out.ut .er;#ragment data and are declared using the out storage >uali#ier. It is an error
to use centroid out in a #ragment shader. )ragment out.uts can onl( 6e float, #loating;.oint vectors,
signed or unsigned integers or integer vectors, or arra(s o# an( these. 9atrices and structures cannot 6e
out.ut. )ragment out.uts are declared as in the #ollowing e1am.les:
out ve&/ FragmentColor'
out uint Luminosit1'
4.!.7 Interpolation
-he .resence o# and t(.e o# inter.olation is controlled 6( the storage >uali#iers centroid in and centroid
out, and 6( the o.tional inter.olation >uali#iers smoot, flat, and noperspective as well as 6( de#ault
6ehaviors esta6lished through the *.en/0 A2I when no inter.olation >uali#ier is .resent. Ghen an
inter.olation >uali#ier is used, it overrides settings esta6lished through the *.en/0 A2I. It is a com.ile;
time error to use more than one inter.olation >uali#ier.
A varia6le >uali#ied as flat will not 6e inter.olated. Instead, it will have the same value #or ever(
#ragment within a triangle. -his value will come #rom a single .rovoking verte1, as descri6ed 6( the
*.en/0 /ra.hics '(stem '.eci#ication. A varia6le ma( 6e >uali#ied as flat centroid, which will mean
the same thing as >uali#(ing it onl( as flat.
A varia6le >uali#ied as smoot will 6e inter.olated in a .ers.ective;correct manner over the .rimitive
6eing rendered. Inter.olation in a .ers.ective correct manner is s.eci#ied in e>uations &." and &.4 in the
*.en/0 /ra.hics '(stem '.eci#ication, Version &.8.
A varia6le >uali#ied as noperspective must 6e inter.olated linearl( in screen s.ace, as descri6ed in
e>uation &.3 and the a..ro1imation that #ollows e>uation &.4 in the *.en/0 /ra.hics '(stem
'.eci#ication, Version &.8.
-his .aragra.h onl( a..lies i# inter.olation is 6eing done: I# single;sam.ling, the value is inter.olated to
the .i1elDs center, and the centroid >uali#ier, i# .resent, is ignored. I# multi;sam.ling and the varia6le is
not >uali#ied with centroid, then the value must 6e inter.olated to the .i1elDs center, or an(where within
the .i1el, or to one o# the .i1elDs sam.les. I# multi;sam.ling and the varia6le is >uali#ied with centroid,
then the value must 6e inter.olated to a .oint that lies in 6oth the .i1el and in the .rimitive 6eing
rendered, or to one o# the .i1elDs sam.les that #alls within the .rimitive. Due to the less regular location o#
centroids, their derivatives ma( 6e less accurate than non;centroid inter.olated varia6les.
-he t(.e and .resence o# the inter.olation >uali#iers and storage >uali#iers and invariant >uali#iers o#
varia6les with the same name declared in linked verte1 and #ragments shaders must match, otherwise the
link command will #ail. *nl( those in.ut varia6les read in the #ragment shader e1ecuta6le must 6e written
to 6( the verte1 shader e1ecuta6leI declaring su.er#luous out.ut varia6les in a verte1 shader is
.ermissi6le.
34
4 Variables and Types
4.!.7.1 8edeclaring -uilt9in Interpolation *ariables
-his section onl( a..lies when using the e1tension ARB<com.ati6ilit(.
-he #ollowing .redeclared varia6les can 6e redeclared with an inter.olation >uali#ier:
Verte1 language:
gl_FrontColor #8R+_&ompati$ilit1)
gl_+a&2Color #8R+_&ompati$ilit1)
gl_FrontSe&ondar1Color #8R+_&ompati$ilit1)
gl_+a&2Se&ondar1Color #8R+_&ompati$ilit1)
)ragment language:
gl_Color #8R+_&ompati$ilit1)
gl_Se&ondar1Color #8R+_&ompati$ilit1)
)or e1am.le,
in ve&/ gl_Color' (( prede&lared $1 t4e fragment language
flat in ve&/ gl_Color' (( rede&lared $1 user to $e flat
I# gl_"olor is redeclared with an inter.olation >uali#ier, then gl_'ront"olor and gl_,ac-"olor @i# the(
are written toA must also 6e redeclared with the same inter.olation >uali#ier, and vice versa. I#
gl_.econ&ar+"olor is redeclared with an inter.olation >uali#ier, then gl_'ront.econ&ar+"olor and
gl_,ac-.econ&ar+"olor @i# the( are written toA must also 6e redeclared with the same inter.olation
>uali#ier, and vice versa. -his >uali#ier matching on .redeclared varia6les is onl( re>uired #or varia6les
that are staticall( used within the shaders in a .rogram.
4.4 ,ara#eter 7ualifiers
2arameters can have these >uali#iers.
7ualifier 4eaning
O none: de#ault P same is in
in #or #unction .arameters .assed into a #unction
out #or #unction .arameters .assed 6ack out o# a #unction, 6ut not initialiEed
#or use when .assed in
inout #or #unction .arameters .assed 6oth into and out o# a #unction
2arameter >uali#iers are discussed in more detail in 'ection ".1.1 B)unction !alling !onventionsC.
35
4 Variables and Types
4." ,recision and ,recision 7ualifiers
2recision >uali#iers are added #or code .orta6ilit( with *.en/0 +', not #or #unctionalit(. -he( have the
same s(nta1 as in *.en/0 +', as descri6ed 6elow, 6ut the( have no semantic meaning, which includes no
e##ect on the .recision used to store or o.erate on varia6les.
I# an e1tension adds in the same semantics and #unctionalit( in the *.en/0 +' .8 s.eci#ication #or
.recision >uali#iers, then the e1tension is allowed to reuse the ke(words 6elow #or that .ur.ose.
4.".1 8ange and ,recision
'ection num6er reserved #or #uture use.
4.".2 ,recision 7ualifiers
An( #loating .oint or an( integer declaration can have the t(.e .receded 6( one o# these .recision
>uali#iers:
7ualifier 4eaning
igp =one.
mediump =one.
lowp =one.
)or e1am.le:
lo:p float &olor'
out mediump ve&0 @'
lo:p ive&0 foo#lo:p mat3)'
4ig4p mat/ m'
0iteral constants do not have .recision >uali#iers. =either do Boolean varia6les. =either do #loating .oint
constructors nor integer constructors when none o# the constructor arguments have .recision >uali#iers.
2recision >uali#iers, as with other >uali#iers, do not e##ect the 6asic t(.e o# the varia6le. In .articular,
there are no constructors #or .recision conversionsI constructors onl( convert t(.es. 'imilarl(, .recision
>uali#iers, as with other >uali#iers, do not contri6ute to #unction overloading 6ased on .arameter t(.es. As
discussed in the ne1t cha.ter, #unction in.ut and out.ut is done through co.ies, and there#ore >uali#iers do
not have to match.
-he same o6?ect declared in di##erent shaders that are linked together must have the same .recision
>uali#ication. -his a..lies to in.uts, out.uts, uni#orms, and glo6als.
4.".! )efault ,recision 7ualifiers
-he .recision statement
36
4 Variables and Types
pre&ision pre&isionE=ualifier t1pe'
can 6e used to esta6lish a de#ault .recision >uali#ier. -he t"pe #ield can 6e either int or float, and the
#recision-8uali3ier can 6e lowp, mediump, or igp. An( other t(.es or >uali#iers will result in an error.
I# t+#e is float, the directive a..lies to non;.recision;>uali#ied #loating .oint t(.e @scalar, vector, and
matri1A declarations. I# t+#e is int, the directive a..lies to all non;.recision;>uali#ied integer t(.e @scalar,
vector, signed, and unsignedA declarations. -his includes glo6al varia6le declarations, #unction return
declarations, #unction .arameter declarations, and local varia6le declarations.
=on;.recision >uali#ied declarations will use the .recision >uali#ier s.eci#ied in the most recent precision
statement that is still in sco.e. -he precision statement has the same sco.ing rules as varia6le
declarations. I# it is declared inside a com.ound statement, its e##ect sto.s at the end o# the innermost
statement it was declared in. 2recision statements in nested sco.es override .recision statements in outer
sco.es. 9ulti.le .recision statements #or the same 6asic t(.e can a..ear inside the same sco.e, with later
statements overriding earlier statements within that sco.e.
-he verte1 language has the #ollowing .redeclared glo6all( sco.ed de#ault .recision statements:
pre&ision 4ig4p float'
pre&ision 4ig4p int'
-he #ragment language has the #ollowing .redeclared glo6all( sco.ed de#ault .recision statements:
pre&ision mediump int'
pre&ision 4ig4p float'
4.".4 .vailable ,recision 7ualifiers
-he 6uilt;in macro /0<)RA/9+=-<2R+!I'I*=<,I/, is de#ined to 1:
#define !L_FR8!9ENT_@RECISION_FI!F 5
-his macro is availa6le in 6oth the verte1 and #ragment languages.
4. *ariance and the Invariant 7ualifier
In this section, variance re#ers to the .ossi6ilit( o# getting di##erent values #rom the same e1.ression in
di##erent .rograms. )or e1am.le, sa( two verte1 shaders, in di##erent .rograms, each set gl_!osition with
the same e1.ression in 6oth shaders, and the in.ut values into that e1.ression are the same when 6oth
shaders run. It is .ossi6le, due to inde.endent com.ilation o# the two shaders, that the values assigned to
gl_!osition are not e1actl( the same when the two shaders run. In this e1am.le, this can cause .ro6lems
with alignment o# geometr( in a multi;.ass algorithm.
In general, such variance 6etween shaders is allowed. Ghen such variance does not e1ist #or a .articular
out.ut varia6le, that varia6le is said to 6e invariant.
37
4 Variables and Types
4..1 The Invariant 7ualifier
-o ensure that a .articular out.ut varia6le is invariant, it is necessar( to use the invariant >uali#ier. It can
either 6e used to >uali#( a .reviousl( declared varia6le as 6eing invariant
invariant gl_@osition' (( ma2e existing gl_@osition $e invariant
out ve&3 Color'
invariant Color' (( ma2e existing Color $e invariant
or as .art o# a declaration when a varia6le is declared
invariant &entroid out ve&3 Color'
-he invariant >uali#ier must a..ear 6e#ore an( inter.olation >uali#iers or storage >uali#iers when
com6ined with a declaration. *nl( varia6les out.ut #rom a shader can 6e candidates #or invariance. -his
includes user;de#ined out.ut varia6les and the 6uilt;in out.ut varia6les. )or varia6les leaving a verte1
shader and coming into a #ragment shader with the same name, the invariant ke(word has to 6e used in
6oth the verte1 and #ragment shaders.
-he invariant ke(word can 6e #ollowed 6( a comma se.arated list o# .reviousl( declared identi#iers. All
uses o# invariant must 6e at the glo6al sco.e, and 6e#ore an( use o# the varia6les 6eing declared as
invariant.
-o guarantee invariance o# a .articular out.ut varia6le across two .rograms, the #ollowing must also 6e
true:
-he out.ut varia6le is declared as invariant in 6oth .rograms.
-he same values must 6e in.ut to all shader in.ut varia6les consumed 6( e1.ressions and #low control
contri6uting to the value assigned to the out.ut varia6le.
-he te1ture #ormats, te1el values, and te1ture #iltering are set the same wa( #or an( te1ture #unction
calls contri6uting to the value o# the out.ut varia6le.
All in.ut values are all o.erated on in the same wa(. All o.erations in the consuming e1.ressions and
an( intermediate e1.ressions must 6e the same, with the same order o# o.erands and same
associativit(, to give the same order o# evaluation. Intermediate varia6les and #unctions must 6e
declared as the same t(.e with the same e1.licit or im.licit .recision >uali#iers. An( control #low
a##ecting the out.ut value must 6e the same, and an( e1.ressions consumed to determine this control
#low must also #ollow these invariance rules.
All the data #low and control #low leading to setting the invariant out.ut varia6le reside in a single
com.ilation unit.
+ssentiall(, all the data #low and control #low leading to an invariant out.ut must match.
Initiall(, 6( de#ault, all out.ut varia6les are allowed to 6e variant. -o #orce all out.ut varia6les to 6e
invariant, use the .ragma
38
4 Variables and Types
#pragma ST!L invariant#all)
6e#ore all declarations in a shader. I# this .ragma is used a#ter the declaration o# an( varia6les or
#unctions, then the set o# out.uts that 6ehave as invariant is unde#ined. It is an error to use this .ragma in
a #ragment shader.
/enerall(, invariance is ensured at the cost o# #le1i6ilit( in o.timiEation, so .er#ormance can 6e degraded
6( use o# invariance. ,ence, use o# this .ragma is intended as a de6ug aid, to avoid individuall( declaring
all out.ut varia6les as invariant.
4..2 Invariance of Constant '+pressions
Invariance must 6e guaranteed #or constant e1.ressions. A .articular constant e1.ression must evaluate to
the same result i# it a..ears again in the same shader or a di##erent shader. -his includes the same
e1.ression a..earing in 6oth a verte1 and #ragment shader or the same e1.ression a..earing in di##erent
verte1 or #ragment shaders.
!onstant e1.ressions must evaluate to the same result when o.erated on as alread( descri6ed a6ove #or
invariant varia6les.
4.7 Order of 7ualification
Ghen multi.le >uali#ications are .resent, the( must #ollow a strict order. -his order is as #ollows.
invariant-8uali3ier inter#olation-8uali3ier storage-8uali3ier #recision-8uali3ier
storage-8uali3ier #arameter-8uali3ier #recision-8uali3ier
39
" Operators and '+pressions
".1 Operators
-he *.en/0 'hading 0anguage has the #ollowing o.erators.
,recedence Operator Class Operators .ssociativit$
1 @highestA .arenthetical grou.ing 1 2 =A

arra( su6scri.t
#unction call and constructor structure
#ield or method selector, swiEEler
.ost #i1 increment and decrement
/ 0
1 2
.
)) ##
0e#t to Right
&
.re#i1 increment and decrement
unar(
)) ##
) # 8 :
Right to 0e#t
$ multi.licative + * , 0e#t to Right
% additive ) # 0e#t to Right
" 6it;wise shi#t -- .. 0e#t to Right
3 relational - . -9 .9 0e#t to Right
4 e>ualit( 99 :9 0e#t to Right
7 6it;wise and 7 0e#t to Right
18 6it;wise e1clusive or 5 0e#t to Right
11 6it;wise inclusive or 6 0e#t to Right
1 logical and 77 0e#t to Right
1& logical e1clusive or 55 0e#t to Right
1$ logical inclusive or 6 6 0e#t to Right
1% selection = ; Right to 0e#t
1"
Assignment
arithmetic assignments
9
)9 #9
+9 *9
,9 --9 ..9
79 59 69
Right to 0e#t
13 @lowestA se>uence & 0e#t to Right
-here is no address;o# o.erator nor a dere#erence o.erator. -here is no t(.ecast o.eratorI constructors
are used instead.
40
5 Operators and !pressions
".2 .rra$ Operations
-hese are now descri6ed in 'ection %.3 B'tructure and Arra( *.erationsC.
".! %unction Calls
I# a #unction returns a value, then a call to that #unction ma( 6e used as an e1.ression, whose t(.e will 6e
the t(.e that was used to declare or de#ine the #unction.
)unction de#initions and calling conventions are discussed in 'ection ".1 B)unction De#initionsC .
".4 Constructors
!onstructors use the #unction call s(nta1, where the #unction name is a t(.e, and the call makes an o6?ect
o# that t(.e. !onstructors are used the same wa( in 6oth initialiEers and e1.ressions. @'ee 'ection 7
B'hading 0anguage /rammarC #or details.A -he .arameters are used to initialiEe the constructed value.
!onstructors can 6e used to re>uest a data t(.e conversion to change #rom one scalar t(.e to another
scalar t(.e, or to 6uild larger t(.es out o# smaller t(.es, or to reduce a larger t(.e to a smaller t(.e.
In general, constructors are not 6uilt;in #unctions with .redetermined .rotot(.es. )or arra(s and
structures, there must 6e e1actl( one argument in the constructor #or each element or #ield. )or the other
t(.es, the arguments must .rovide a su##icient num6er o# com.onents to .er#orm the initialiEation, and it
is an error to include so man( arguments that the( cannot all 6e used. Detailed rules #ollow. -he
.rotot(.es actuall( listed 6elow are merel( a su6set o# e1am.les.
".4.1 Conversion and Scalar Constructors
!onverting 6etween scalar t(.es is done as the #ollowing .rotot(.es indicate:
int#$ool) (( &onverts a +oolean value to an int
int#float) (( &onverts a float value to an int
float#$ool) (( &onverts a +oolean value to a float
float#int) (( &onverts a signed integer value to a float
$ool#float) (( &onverts a float value to a +oolean
$ool#int) (( &onverts a signed integer value to a +oolean
uint#$ool) (( &onverts a +oolean value to an unsigned integer
uint#float) (( &onverts a float value to an unsigned integer
uint#int) (( &onverts a signed integer value to an unsigned integer
int#uint) (( &onverts an unsigned integer to a signed integer
$ool#uint) (( &onverts an unsigned integer value to a +oolean value
float#uint) (( &onverts an unsigned integer value to a float value
Ghen constructors are used to convert a float to an int or uint, the #ractional .art o# the #loating;.oint
value is dro..ed. It is unde#ined to convert a negative #loating .oint value to an uint.
Ghen a constructor is used to convert an int, uint, or a float to a bool, 8 and 8.8 are converted to false,
and non;Eero values are converted to true. Ghen a constructor is used to convert a bool to an int, uint,
or float, false is converted to 8 or 8.8, and true is converted to 1 or 1.8.
41
5 Operators and !pressions
-he constructor int1uint2 .reserves the 6it .attern in the argument, which will change the argumentDs
value i# its sign 6it is set. -he constructor uint1int2 .reserves the 6it .attern in the argument, which will
change its value i# it is negative.
Identit( constructors, like float@floatA are also legal, 6ut o# little use.
'calar constructors with non;scalar .arameters can 6e used to take the #irst element #rom a non;scalar.
)or e1am.le, the constructor float@vecDA will select the #irst com.onent o# the vecD .arameter.
".4.2 *ector and 4atri+ Constructors
!onstructors can 6e used to create vectors or matrices #rom a set o# scalars, vectors, or matrices. -his
includes the a6ilit( to shorten vectors.
I# there is a single scalar .arameter to a vector constructor, it is used to initialiEe all com.onents o# the
constructed vector to that scalarHs value. I# there is a single scalar .arameter to a matri1 constructor, it is
used to initialiEe all the com.onents on the matri1Hs diagonal, with the remaining com.onents initialiEed
to 8.8.
I# a vector is constructed #rom multi.le scalars, one or more vectors, or one or more matrices, or a mi1ture
o# these, the vectorDs com.onents will 6e constructed in order #rom the com.onents o# the arguments. -he
arguments will 6e consumed le#t to right, and each argument will have all its com.onents consumed, in
order, 6e#ore an( com.onents #rom the ne1t argument are consumed. 'imilarl( #or constructing a matri1
#rom multi.le scalars or vectors, or a mi1ture o# these. 9atri1 com.onents will 6e constructed and
consumed in column ma?or order. In these cases, there must 6e enough com.onents .rovided in the
arguments to .rovide an initialiEer #or ever( com.onent in the constructed value. It is an error to .rovide
e1tra arguments 6e(ond this last used argument.
I# a matri1 is constructed #rom a matri1, then each com.onent @column i, row <A in the result that has a
corres.onding com.onent @column i, row <A in the argument will 6e initialiEed #rom there. All other
com.onents will 6e initialiEed to the identit( matri1. I# a matri1 argument is given to a matri1 constructor,
it is an error to have an( other arguments.
I# the 6asic t(.e @bool& int& or floatA o# a .arameter to a constructor does not match the 6asic t(.e o# the
o6?ect 6eing constructed, the scalar construction rules @a6oveA are used to convert the .arameters.
42
5 Operators and !pressions
'ome use#ul vector constructors are as #ollows:
ve&3#float) (( initiali"es ea&4 &omponent of t4e ve&3 :it4 t4e float
ve&/#ive&/) (( ma2es a ve&/ :it4 &omponentE:ise &onversion
ve&/#mat0) (( t4e ve&/ is &olumn A follo:ed $1 &olumn 5
ve&0#float- float) (( initiali"es a ve&0 :it4 0 floats
ive&3#int- int- int) (( initiali"es an ive&3 :it4 3 ints
$ve&/#int- int- float- float) (( uses / +oolean &onversions
ve&0#ve&3) (( drops t4e t4ird &omponent of a ve&3
ve&3#ve&/) (( drops t4e fourt4 &omponent of a ve&/
ve&3#ve&0- float) (( ve&36x , ve&06x- ve&361 , ve&061- ve&36" , float
ve&3#float- ve&0) (( ve&36x , float- ve&361 , ve&06x- ve&36" , ve&061
ve&/#ve&3- float)
ve&/#float- ve&3)
ve&/#ve&0- ve&0)
'ome e1am.les o# these are:
ve&/ &olor , ve&/#A6A- 56A- A6A- 56A)'
ve&/ rg$a , ve&/#56A)' (( sets ea&4 &omponent to 56A
ve&3 rg$ , ve&3#&olor)' (( drop t4e /t4 &omponent
-o initialiEe the diagonal o# a matri1 with all other elements set to Eero:
mat0#float)
mat3#float)
mat/#float)
-hat is, result(i)(<) is set to the #loat argument #or all i = < and set to 8 #or all i <.
43
5 Operators and !pressions
-o initialiEe a matri1 6( s.eci#(ing vectors or scalars, the com.onents are assigned to the matri1 elements
in column;ma?or order.
mat0#ve&0- ve&0)' (( one &olumn per argument
mat3#ve&3- ve&3- ve&3)' (( one &olumn per argument
mat/#ve&/- ve&/- ve&/- ve&/)' (( one &olumn per argument
mat3x0#ve&0- ve&0- ve&0)' (( one &olumn per argument
mat0#float- float- (( first &olumn
float- float)' (( se&ond &olumn
mat3#float- float- float- (( first &olumn
float- float- float- (( se&ond &olumn
float- float- float)' (( t4ird &olumn
mat/#float- float- float- float- (( first &olumn
float- float- float- float- (( se&ond &olumn
float- float- float- float- (( t4ird &olumn
float- float- float- float)' (( fourt4 &olumn
mat0x3#ve&0- float- (( first &olumn
ve&0- float)' (( se&ond &olumn
A wide range o# other .ossi6ilities e1ist, to construct a matri1 #rom vectors and scalars, as long as enough
com.onents are .resent to initialiEe the matri1. -o construct a matri1 #rom a matri1:
mat3x3#mat/x/)' (( ta2es t4e upperEleft 3x3 of t4e mat/x/
mat0x3#mat/x0)' (( ta2es t4e upperEleft 0x0 of t4e mat/x/- last ro: is A-A
mat/x/#mat3x3)' (( puts t4e mat3x3 in t4e upperEleft- sets t4e lo:er rig4t
(( &omponent to 5- and t4e rest to A
".4.! Structure Constructors
*nce a structure is de#ined, and its t(.e is given a name, a constructor is availa6le with the same name to
construct instances o# that structure. )or e1am.le:
stru&t lig4t ;
float intensit1'
ve&3 position'
<'
lig4t lig4tVar , lig4t#36A- ve&3#56A- 06A- 36A))'
-he arguments to the constructor will 6e used to set the structureDs #ields, in order, using one argument .er
#ield. +ach argument must 6e the same t(.e as the #ield it sets, or 6e a t(.e that can 6e converted to the
#ieldDs t(.e according to 'ection $.1.18 BIm.licit !onversions.C
'tructure constructors can 6e used as initialiEers or in e1.ressions.
44
5 Operators and !pressions
".4.4 .rra$ Constructors
Arra( t(.es can also 6e used as constructor names, which can then 6e used in e1.ressions or initialiEers.
)or e1am.le,
&onst float &>3? , float>3?#76A- D60- 565)'
&onst float d>3? , float>?#76A- D60- 565)'
float g'
666
float a>7? , float>7?#g- 5- g- 063- g)'
float $>3?'
$ , float>3?#g- g G 56A- g G 06A)'
-here must 6e e1actl( the same num6er o# arguments as the siEe o# the arra( 6eing constructed. I# no siEe
is .resent in the constructor, then the arra( is e1.licitl( siEed to the num6er o# arguments .rovided. -he
arguments are assigned in order, starting at element 8, to the elements o# the constructed arra(. +ach
argument must 6e the same t(.e as the element t(.e o# the arra(, or 6e a t(.e that can 6e converted to the
element t(.e o# the arra( according to 'ection $.1.18 BIm.licit !onversions.C
"." *ector Co#ponents
-he names o# the com.onents o# a vector are denoted 6( a single letter. As a notational convenience,
several letters are associated with each com.onent 6ased on common usage o# .osition, color or te1ture
coordinate vectors. -he individual com.onents o# a vector can 6e selected 6( #ollowing the varia6le
name with .eriod @ . A and then the com.onent name.
-he com.onent names su..orted are:
>$, +, 7, 6? 5se#ul when accessing vectors that re.resent .oints or normals
>r, g, 2, a? 5se#ul when accessing vectors that re.resent colors
>s, t, #, 8? 5se#ul when accessing vectors that re.resent te1ture coordinates
-he com.onent names $, r, and s are, #or e1am.le, s(non(ms #or the same @#irstA com.onent in a vector.
=ote that the third com.onent o# the te1ture coordinate set, r in *.en/0, has 6een renamed # so as to
avoid the con#usion with r @#or redA in a color.
Accessing com.onents 6e(ond those declared #or the vector t(.e is an error so, #or e1am.le:
ve&0 pos'
pos6x (( is legal
pos6" (( is illegal
45
5 Operators and !pressions
-he com.onent selection s(nta1 allows multi.le com.onents to 6e selected 6( a..ending their names
@#rom the same name setA a#ter the .eriod @ . A.
ve&/ v/'
v/6rg$a' (( is a ve&/ and t4e same as .ust using v/-
v/6rg$' (( is a ve&3-
v/6$' (( is a float-
v/6x1' (( is a ve&0-
v/6xg$a' (( is illegal E t4e &omponent names do not &ome from
(( t4e same set6
-he order o# the com.onents can 6e di##erent to swiEEle them, or re.licated:
ve&/ pos , ve&/#56A- 06A- 36A- /6A)'
ve&/ s:i", pos6:"1x' (( s:i" , #/6A- 36A- 06A- 56A)
ve&/ dup , pos6xx11' (( dup , #56A- 56A- 06A- 06A)
-his notation is more concise than the constructor s(nta1. -o #orm an r;value, it can 6e a..lied to an(
e1.ression that results in a vector r;value.
-he com.onent grou. notation can occur on the le#t hand side o# an e1.ression.
ve&/ pos , ve&/#56A- 06A- 36A- /6A)'
pos6x: , ve&0#76A- H6A)' (( pos , #76A- 06A- 36A- H6A)
pos6:x , ve&0#D6A- I6A)' (( pos , #I6A- 06A- 36A- D6A)
pos6xx , ve&0#36A- /6A)' (( illegal E BxB used t:i&e
pos6x1 , ve&3#56A- 06A- 36A)' (( illegal E mismat&4 $et:een ve&0 and ve&3
-o #orm an l;value, swiEEling must 6e a..lied to an l;value o# vector t(.e, contain no du.licate
com.onents, and it results in an l;value o# scalar or vector t(.e, de.ending on num6er o# com.onents
s.eci#ied.
Arra( su6scri.ting s(nta1 can also 6e a..lied to vectors to .rovide numeric inde1ing. 'o in
ve&/ pos'
#os(2) re#ers to the third element o# .os and is e>uivalent to #os.7. -his allows varia6le inde1ing into a
vector, as well as a generic wa( o# accessing com.onents. An( integer e1.ression can 6e used as the
su6scri.t. -he #irst com.onent is at inde1 Eero. Reading #rom or writing to a vector using a constant
integral e1.ression with a value that is negative or greater than or e>ual to the siEe o# the vector is illegal.
Ghen inde1ing with non;constant e1.ressions, 6ehavior is unde#ined i# the inde1 is negative, or greater
than or e>ual to the siEe o# the vector.
". 4atri+ Co#ponents
-he com.onents o# a matri1 can 6e accessed using arra( su6scri.ting s(nta1. A..l(ing a single su6scri.t
to a matri1 treats the matri1 as an arra( o# column vectors, and selects a single column, whose t(.e is a
vector o# the same siEe as the matri1. -he le#tmost column is column 8. A second su6scri.t would then
o.erate on the resulting vector, as de#ined earlier #or vectors. ,ence, two su6scri.ts select a column and
then a row.
46
5 Operators and !pressions
mat/ m'
m>5? , ve&/#06A)' (( sets t4e se&ond &olumn to all 06A
m>A?>A? , 56A' (( sets t4e upper left element to 56A
m>0?>3? , 06A' (( sets t4e /t4 element of t4e t4ird &olumn to 06A
Behavior is unde#ined when accessing a com.onent outside the 6ounds o# a matri1 with a non;constant
e1.ression. It is an error to access a matri1 with a constant e1.ression that is outside the 6ounds o# the
matri1.
".7 Structure and .rra$ Operations
-he #ields o# a structure and the lengt method o# an arra( are selected using the .eriod @ . A.
In total, onl( the #ollowing o.erators are allowed to o.erate on arra(s and structures as whole entities:
#ield or method selector .
e>ualit( 99 :9
assignment 9
inde1ing @arra(s onl(A X Y
-he e>ualit( o.erators and assignment o.erator are onl( allowed i# the two o.erands are same siEe and
t(.e. 'tructure t(.es must 6e o# the same declared structure. Both arra( o.erands must 6e e1.licitl(
siEed. Ghen using the e>ualit( o.erators, two structures are e>ual i# and onl( i# all the #ields are
com.onent;wise e>ual, and two arra(s are e>ual i# and onl( i# all the elements are element;wise e>ual.
Arra( elements are accessed using the arra( su6scri.t o.erator @ / 0 A. An e1am.le o# accessing an arra(
element is
diffuseColor G, lig4tIntensit1>3? J NdotL'
Arra( indices start at Eero. Arra( elements are accessed using an e1.ression whose t(.e is int or uint.
Behavior is unde#ined i# a shader su6scri.ts an arra( with an inde1 less than 8 or greater than or e>ual to
the siEe the arra( was declared with.
Arra(s can also 6e accessed with the method o.erator @ . A and the lengt method to >uer( the siEe o# the
arra(:
lig4tIntensit16lengt4#) (( return t4e si"e of t4e arra1
".2 .ssign#ents
Assignments o# values to varia6le names are done with the assignment o.erator @ 9 A:
lvalueEexpression , rvalueEexpression
47
5 Operators and !pressions
-he lvalue-e$#ression evaluates to an l;value. -he assignment o.erator stores the value o# rvalue-
e$#ression into the l;value and returns an r;value with the t(.e and .recision o# lvalue-e$#ression. -he
lvalue-e$#ression and rvalue-e$#ression must have the same t(.e, or the e1.ression must have a t(.e in
the ta6le in 'ection $.1.18 BIm.licit !onversionsC that converts to the t(.e o# lvalue-e$#ression, in which
case an im.licit conversion will 6e done on the rvalue-e$#ression 6e#ore the assignment is done. An(
other desired t(.e;conversions must 6e s.eci#ied e1.licitl( via a constructor. 0;values must 6e writa6le.
Varia6les that are 6uilt;in t(.es, entire structures or arra(s, structure #ields, l;values with the #ield selector
@ . A a..lied to select com.onents or swiEEles without re.eated #ields, l;values within .arentheses, and l;
values dere#erenced with the arra( su6scri.t o.erator @ / 0 A are all l;values. *ther 6inar( or unar(
e1.ressions, #unction names, swiEEles with re.eated #ields, and constants cannot 6e l;values. -he ternar(
o.erator @=;A is also not allowed as an l;value.
+1.ressions on the le#t o# an assignment are evaluated 6e#ore e1.ressions on the right o# the assignment.
-he other assignment o.erators are
add into @)9A
su6tract #rom @#9A
multi.l( into @+9A
divide into @*9A
modulus into @,9A
le#t shi#t 6( @--9A
right shi#t 6( @..9A
and into @79A
inclusive;or into @69A
e1clusive;or into @59A
where the general e1.ression
lvalue op, expression
is e>uivalent to
lvalue , lvalue op expression
where o# is as descri6ed 6elow, and the l;value and e1.ression must satis#( the semantic re>uirements o#
6oth o# and e>uals @9A.
Reading a varia6le 6e#ore writing @or initialiEingA it is legal, however the value is unde#ined.
".5 '+pressions
+1.ressions in the shading language are 6uilt #rom the #ollowing:
!onstants o# t(.e bool& int& uint& float& all vector t(.es, and all matri1 t(.es.
48
5 Operators and !pressions
!onstructors o# all t(.es.
Varia6le names o# all t(.es.
An arra( name with the length method a..lied.
'u6scri.ted arra( names.
)unction calls that return values.
!om.onent #ield selectors and arra( su6scri.t results.
2arenthesiEed e1.ression. An( e1.ression can 6e .arenthesiEed. 2arentheses can 6e used to grou.
o.erations. *.erations within .arentheses are done 6e#ore o.erations across .arentheses.
-he arithmetic 6inar( o.erators add @)A, su6tract @#A, multi.l( @+A, and divide @*A o.erate on integer and
#loating;.oint scalars, vectors, and matrices. I# one o.erand is #loating;.oint 6ased and the other is
not, then the conversions #rom 'ection $.1.18 BIm.licit !onversionsC are a..lied to the non;#loating;
.oint;6ased o.erand. I# the o.erands are integer t(.es, the( must 6oth 6e signed or 6oth 6e unsigned.
All arithmetic 6inar( o.erators result in the same #undamental t(.e @signed integer, unsigned integer,
or #loating;.ointA as the o.erands the( o.erate on, a#ter o.erand t(.e conversion. A#ter conversion,
the #ollowing cases are valid
-he two o.erands are scalars. In this case the o.eration is a..lied, resulting in a scalar.
*ne o.erand is a scalar, and the other is a vector or matri1. In this case, the scalar o.eration is
a..lied inde.endentl( to each com.onent o# the vector or matri1, resulting in the same siEe vector
or matri1.
-he two o.erands are vectors o# the same siEe. In this case, the o.eration is done com.onent;wise
resulting in the same siEe vector.
-he o.erator is add @)A, su6tract @#A, or divide @*A, and the o.erands are matrices with the same
num6er o# rows and the same num6er o# columns. In this case, the o.eration is done com.onent;
wise resulting in the same siEe matri1.
-he o.erator is multi.l( @+A, where 6oth o.erands are matrices or one o.erand is a vector and the
other a matri1. A right vector o.erand is treated as a column vector and a le#t vector o.erand as a
row vector. In all these cases, it is re>uired that the num6er o# columns o# the le#t o.erand is e>ual
to the num6er o# rows o# the right o.erand. -hen, the multi.l( @+A o.eration does a linear
alge6raic multi.l(, (ielding an o6?ect that has the same num6er o# rows as the le#t o.erand and the
same num6er o# columns as the right o.erand. 'ection %.18 BVector and 9atri1 *.erationsC
e1.lains in more detail how vectors and matrices are o.erated on.
All other cases are illegal.
Dividing 6( Eero does not cause an e1ce.tion 6ut does result in an uns.eci#ied value. 5se the 6uilt;in
#unctions dot& cross& matrixCompOult& and outerQroduct, to get, res.ectivel(, vector dot .roduct,
vector cross .roduct, matri1 com.onent;wise multi.lication, and the matri1 .roduct o# a column
vector times a row vector.
49
5 Operators and !pressions
-he o.erator modulus @,A o.erates on signed or unsigned integers or integer vectors. -he o.erand
t(.es must 6oth 6e signed or 6oth 6e unsigned. -he o.erands cannot 6e vectors o# di##ering siEe. I#
one o.erand is a scalar and the other vector, then the scalar is a..lied com.onent;wise to the vector,
resulting in the same t(.e as the vector. I# 6oth are vectors o# the same siEe, the result is com.uted
com.onent;wise. -he resulting value is unde#ined #or an( com.onent com.uted with a second
o.erand that is Eero, while results #or other com.onents with non;Eero second o.erands remain
de#ined. I# 6oth o.erands are non;negative, then the remainder is non;negative. Results are unde#ined
i# one or 6oth o.erands are negative. -he o.erator modulus @,A is not de#ined #or an( other data
t(.es @non;integer t(.esA.
-he arithmetic unar( o.erators negate @;A, .ost; and .re;increment and decrement @## and ))A o.erate
on integer or #loating;.oint values @including vectors and matricesA. All unar( o.erators work
com.onent;wise on their o.erands. -hese result with the same t(.e the( o.erated on. )or .ost; and
.re;increment and decrement, the e1.ression must 6e one that could 6e assigned to @an l;valueA. 2re;
increment and .re;decrement add or su6tract 1 or 1.8 to the contents o# the e1.ression the( o.erate on,
and the value o# the .re;increment or .re;decrement e1.ression is the resulting value o# that
modi#ication. 2ost;increment and .ost;decrement e1.ressions add or su6tract 1 or 1.8 to the contents
o# the e1.ression the( o.erate on, 6ut the resulting e1.ression has the e1.ressionHs value 6e#ore the
.ost;increment or .ost;decrement was e1ecuted.
-he relational o.erators greater than @.A, less than @-A, greater than or e>ual @.9A, and less than or
e>ual @-9A o.erate onl( on scalar integer and scalar #loating;.oint e1.ressions. -he result is scalar
Boolean. +ither the o.erandsH t(.es must match, or the conversions #rom 'ection $.1.18 BIm.licit
!onversionsC will 6e a..lied to the integer o.erand, a#ter which the t(.es must match. -o do
com.onent;wise relational com.arisons on vectors, use the 6uilt;in #unctions less@an&
less@an!Iual& greater@an& and greater@an!Iual.
-he e>ualit( o.erators eIual 199A, and not e>ual @:9A o.erate on all t(.es. -he( result in a scalar
Boolean. I# the o.erand t(.es do not match, then there must 6e a conversion #rom 'ection $.1.18
BIm.licit !onversionsC a..lied to one o.erand that can make them match, in which case this
conversion is done. )or vectors, matrices, structures, and arra(s, all com.onents, #ields, or elements o#
one o.erand must e>ual the corres.onding com.onents, #ields, or elements in the other o.erand #or the
o.erands to 6e considered e>ual. -o get a vector o# com.onent;wise e>ualit( results #or vectors, use
the 6uilt;in #unctions eIual and not!Iual.
-he logical 6inar( o.erators and @77A, or @ 6 6 A, and e1clusive or @55A o.erate onl( on two Boolean
e1.ressions and result in a Boolean e1.ression. And @77A will onl( evaluate the right hand o.erand
i# the le#t hand o.erand evaluated to true. *r @ 6 6 A will onl( evaluate the right hand o.erand i# the le#t
hand o.erand evaluated to false. +1clusive or @55A will alwa(s evaluate 6oth o.erands.
-he logical unar( o.erator not @:A. It o.erates onl( on a Boolean e1.ression and results in a Boolean
e1.ression. -o o.erate on a vector, use the 6uilt;in #unction not.
-he se>uence @ & A o.erator that o.erates on e1.ressions 6( returning the t(.e and value o# the right;
most e1.ression in a comma se.arated list o# e1.ressions. All e1.ressions are evaluated, in order,
#rom le#t to right.
50
5 Operators and !pressions
-he ternar( selection o.erator @=;A. It o.erates on three e1.ressions @e$#1 = e$#2 ; e$#@A. -his
o.erator evaluates the #irst e1.ression, which must result in a scalar Boolean. I# the result is true, it
selects to evaluate the second e1.ression, otherwise it selects to evaluate the third e1.ression. *nl(
one o# the second and third e1.ressions is evaluated. -he second and third e1.ressions can 6e an(
t(.e, as long their t(.es match, or there is a conversion in 'ection $.1.18 BIm.licit !onversionsC that
can 6e a..lied to one o# the e1.ressions to make their t(.es match. -his resulting matching t(.e is the
t(.e o# the entire e1.ression.
-he oneDs com.lement o.erator @8A. -he o.erand must 6e o# t(.e signed or unsigned integer or integer
vector, and the result is the oneDs com.lement o# its o.erandI each 6it o# each com.onent is
com.lemented, including an( sign 6its.
-he shi#t o.erators @--A and @..A. )or 6oth o.erators, the o.erands must 6e signed or unsigned
integers or integer vectors. *ne o.erand can 6e signed while the other is unsigned. In all cases, the
resulting t(.e will 6e the same t(.e as the le#t o.erand. I# the #irst o.erand is a scalar, the second
o.erand has to 6e a scalar as well. I# the #irst o.erand is a vector, the second o.erand must 6e a scalar
or a vector, and the result is com.uted com.onent;wise. -he result is unde#ined i# the right o.erand is
negative, or greater than or e>ual to the num6er o# 6its in the le#t e1.ressionDs 6ase t(.e. -he value o#
+1 OO + is +1 @inter.reted as a 6it .atternA le#t;shi#ted 6( + 6its. -he value o# +1 PP + is +1 right;
shi#ted 6( + 6it .ositions. I# +1 is a signed integer, the right;shi#t will e1tend the sign 6it. I# +1 is an
unsigned integer, the right;shi#t will Eero;e1tend.
-he 6itwise o.erators and @7A, e1clusive;or @5A, and inclusive;or @6A. -he o.erands must 6e o# t(.e
signed or unsigned integers or integer vectors. -he o.erands cannot 6e vectors o# di##ering siEe. I# one
o.erand is a scalar and the other a vector, the scalar is a..lied com.onent;wise to the vector, resulting
in the same t(.e as the vector. -he #undamental t(.es o# the o.erands @signed or unsignedA must
match, and will 6e the resulting #undamental t(.e. )or and @7A, the result is the 6itwise;and #unction
o# the o.erands. )or e1clusive;or @5A, the result is the 6itwise e1clusive;or #unction o# the o.erands.
)or inclusive;or @6A, the result is the 6itwise inclusive;or #unction o# the o.erands.
)or a com.lete s.eci#ication o# the s(nta1 o# e1.ressions, see 'ection 7 B'hading 0anguage /rammar.C
".16 *ector and 4atri+ Operations
Gith a #ew e1ce.tions, o.erations are com.onent;wise. 5suall(, when an o.erator o.erates on a vector or
matri1, it is o.erating inde.endentl( on each com.onent o# the vector or matri1, in a com.onent;wise
#ashion. )or e1am.le,
ve&3 v- u'
float f'
v , u G f'
will 6e e>uivalent to
v6x , u6x G f'
v61 , u61 G f'
v6" , u6" G f'
And
51
5 Operators and !pressions
ve&3 v- u- :'
: , v G u'
will 6e e>uivalent to
:6x , v6x G u6x'
:61 , v61 G u61'
:6" , v6" G u6"'
and likewise #or most o.erators and all integer and #loating .oint vector and matri1 t(.es. -he e1ce.tions
are matri1 multi.lied 6( vector, vector multi.lied 6( matri1, and matri1 multi.lied 6( matri1. -hese do
not o.erate com.onent;wise, 6ut rather .er#orm the correct linear alge6raic multi.l(.
ve&3 v- u'
mat3 m'
u , v J m'
is e>uivalent to
u6x , dot#v- m>A?)' (( m>A? is t4e left &olumn of m
u61 , dot#v- m>5?)' (( dot#a-$) is t4e inner #dot) produ&t of a and $
u6" , dot#v- m>0?)'
And
u , m J v'
is e>uivalent to
u6x , m>A?6x J v6x G m>5?6x J v61 G m>0?6x J v6"'
u61 , m>A?61 J v6x G m>5?61 J v61 G m>0?61 J v6"'
u6" , m>A?6" J v6x G m>5?6" J v61 G m>0?6" J v6"'
52
5 Operators and !pressions
And
mat3 m- n- r'
r , m J n'
is e>uivalent to
r>A?6x , m>A?6x J n>A?6x G m>5?6x J n>A?61 G m>0?6x J n>A?6"'
r>5?6x , m>A?6x J n>5?6x G m>5?6x J n>5?61 G m>0?6x J n>5?6"'
r>0?6x , m>A?6x J n>0?6x G m>5?6x J n>0?61 G m>0?6x J n>0?6"'
r>A?61 , m>A?61 J n>A?6x G m>5?61 J n>A?61 G m>0?61 J n>A?6"'
r>5?61 , m>A?61 J n>5?6x G m>5?61 J n>5?61 G m>0?61 J n>5?6"'
r>0?61 , m>A?61 J n>0?6x G m>5?61 J n>0?61 G m>0?61 J n>0?6"'
r>A?6" , m>A?6" J n>A?6x G m>5?6" J n>A?61 G m>0?6" J n>A?6"'
r>5?6" , m>A?6" J n>5?6x G m>5?6" J n>5?61 G m>0?6" J n>5?6"'
r>0?6" , m>A?6" J n>0?6x G m>5?6" J n>0?61 G m>0?6" J n>0?6"'
and similarl( #or other siEes o# vectors and matrices.
53
State#ents and Structure
-he #undamental 6uilding 6locks o# the *.en/0 'hading 0anguage are:
statements and declarations
#unction de#initions
selection @if#else and switc#case#default2
iteration 1for& wile& and do#wile2
?um.s 1discard& return& break& and continueA
-he overall structure o# a shader is as #ollows
translation-unit:
glo2al-&eclaration
translation-unit glo2al-&eclaration
glo2al-&eclaration:
3unction-&e3inition
&eclaration
-hat is, a shader is a se>uence o# declarations and #unction 6odies. )unction 6odies are de#ined as
3unction-&e3inition:
3unction-#rotot+#e > statement-list ?
statement-list:
statement
statement-list statement
statement:
com#oun&-statement
sim#le-statement
!url( 6races are used to grou. se>uences o# statements into com.ound statements.
com#oun&-statement:
> statement-list ?
sim#le-statement:
&eclaration-statement
e$#ression-statement
selection-statement
54
6 "tate#ents and "tructure
iteration-statement
<um#-statement
'im.le declaration, e1.ression, and ?um. statements end in a semi;colon.
-his a6ove is slightl( sim.li#ied, and the com.lete grammar s.eci#ied in 'ection 7 B'hading 0anguage
/rammarC should 6e used as the de#initive s.eci#ication.
Declarations and e1.ressions have alread( 6een discussed.
.1 %unction )efinitions
As indicated 6( the grammar a6ove, a valid shader is a se>uence o# glo6al declarations and #unction
de#initions. A #unction is declared as the #ollowing e1am.le shows:
(( protot1pe
returnT1pe fun&tionName #t1peA argA- t1pe5 arg5- 666- t1pen argn)'
and a #unction is de#ined like
(( definition
returnT1pe fun&tionName #t1peA argA- t1pe5 arg5- 666- t1pen argn)
;
(( do some &omputation
return returnValue'
<
where return%+#e must 6e .resent and include a t(.e. +ach o# the t+#eN must include a t(.e and can
o.tionall( include a .arameter >uali#ier andFor const.
A #unction is called 6( using its name #ollowed 6( a list o# arguments in .arentheses.
Arra(s are allowed as arguments and as the return t(.e. In 6oth cases, the arra( must 6e e1.licitl( siEed.
An arra( is .assed or returned 6( using ?ust its name, without 6rackets, and the siEe o# the arra( must
match the siEe s.eci#ied in the #unctionDs declaration.
'tructures are also allowed as argument t(.es. -he return t(.e can also 6e structure.
'ee 'ection 7 B'hading 0anguage /rammarC #or the de#initive re#erence on the s(nta1 to declare and
de#ine #unctions.
All #unctions must 6e either declared with a .rotot(.e or de#ined with a 6od( 6e#ore the( are called. )or
e1am.le:
float m1fun& #float f- (( f is an input parameter
out float g)' (( g is an output parameter
)unctions that return no value must 6e declared as void. )unctions that acce.t no in.ut arguments need
not use void in the argument list 6ecause .rotot(.es @or de#initionsA are re>uired and there#ore there is no
am6iguit( when an em.t( argument list U@ AU is declared. -he idiom B@voidAC as a .arameter list is
.rovided #or convenience.
55
6 "tate#ents and "tructure
)unction names can 6e overloaded. -he same #unction name can 6e used #or multi.le #unctions, as long
as the .arameter t(.es di##er. I# a #unction name is declared twice with the same .arameter t(.es, then the
return t(.es and all >uali#iers must also match, and it is the same #unction 6eing declared. Ghen #unction
calls are resolved, an e1act t(.e match #or all the arguments is sought. I# an e1act match is #ound, all
other #unctions are ignored, and the e1act match is used. I# no e1act match is #ound, then the im.licit
conversions in 'ection $.1.18 BIm.licit !onversionsC will 6e a..lied to #ind a match. 9ismatched t(.es
on in.ut .arameters @in or inout or de#ault2 must have a conversion #rom the calling argument t(.e to the
#ormal .arameter t(.e. 9ismatched t(.es on out.ut .arameters @out or inoutA must have a conversion
#rom the #ormal .arameter t(.e to the calling argument t(.e. Ghen argument conversions are used to #ind
a match, it is a semantic error i# there are multi.le wa(s to a..l( these conversions to make the call match
more than one #unction.
)or e1am.le,
ve&/ f#in ve&/ x- out ve&/ 1)'
ve&/ f#in ve&/ x- out ive&/ 1)' (( o2a1- different argument t1pe
int f#in ve&/ x- out ive&/ 1)' (( error- onl1 return t1pe differs
ve&/ f#in ve&/ x- in ive&/ 1)' (( error- onl1 =ualifier differs
int f#&onst in ve&/ x- out ive&/ 1)' (( error- onl1 =ualifier differs
!alling the #irst two #unctions a6ove with the #ollowing argument t(.es (ields
f#ve&/- ve&/) (( exa&t mat&4 of ve&/ f#in ve&/ x- out ve&/ 1)
f#ve&/- ive&/) (( exa&t mat&4 of ve&/ f#in ve&/ x- out ive&/ 1)
f#ive&/- ve&/) (( error- &onverti$le to $ot4
f#ive&/- ive&/) (( o2a1- &onverti$le onl1 to ve&/ f#in ve&/ x- out ive&/ 1)
5ser;de#ined #unctions can have multi.le declarations, 6ut onl( one de#inition. A shader can rede#ine
6uilt;in #unctions. I# a 6uilt;in #unction is redeclared in a shader @i.e., a .rotot(.e is visi6leA 6e#ore a call
to it, then the linker will onl( attem.t to resolve that call within the set o# shaders that are linked with it.
-he #unction main is used as the entr( .oint to a shader e1ecuta6le. A shader need not contain a #unction
named main, 6ut one shader in a set o# shaders linked together to #orm a single shader e1ecuta6le must.
-his #unction takes no arguments, returns no value, and must 6e declared as t(.e void;
void main#)
;
666
<
-he #unction main can contain uses o# return. 'ee 'ection ".$ BJum.sC #or more details.
It is an error to declare or de#ine a #unction main with an( other .arameters or return t(.e.
.1.1 %unction Calling Conventions
)unctions are called 6( value;return. -his means in.ut arguments are co.ied into the #unction at call time,
and out.ut arguments are co.ied 6ack to the caller 6e#ore #unction e1it. Because the #unction works with
local co.ies o# .arameters, there are no issues regarding aliasing o# varia6les within a #unction. -o
control what .arameters are co.ied in andFor out through a #unction de#inition or declaration:
-he ke(word in is used as a >uali#ier to denote a .arameter is to 6e co.ied in, 6ut not co.ied out.
56
6 "tate#ents and "tructure
-he ke(word out is used as a >uali#ier to denote a .arameter is to 6e co.ied out, 6ut not co.ied in.
-his should 6e used whenever .ossi6le to avoid unnecessaril( co.(ing .arameters in.
-he ke(word inout is used as a >uali#ier to denote the .arameter is to 6e 6oth co.ied in and co.ied
out.
A #unction .arameter declared with no such >uali#ier means the same thing as s.eci#(ing in.
All arguments are evaluated at call time, e1actl( once, in order, #rom le#t to right. +valuation o# an in
.arameter results in a value that is co.ied to the #ormal .arameter. +valuation o# an out .arameter results
in an l;value that is used to co.( out a value when the #unction returns. +valuation o# an inout .arameter
results in 6oth a value and an l;valueI the value is co.ied to the #ormal .arameter at call time and the l;
value is used to co.( out a value when the #unction returns.
-he order in which out.ut .arameters are co.ied 6ack to the caller is unde#ined.
I# the #unction matching descri6ed in the .revious section re>uired argument t(.e conversions, these
conversions are a..lied at co.(;in and co.(;out times.
In a #unction, writing to an in.ut;onl( .arameter is allowed. *nl( the #unctionHs co.( is modi#ied. -his
can 6e .revented 6( declaring a .arameter with the const >uali#ier.
Ghen calling a #unction, e1.ressions that do not evaluate to l;values cannot 6e .assed to .arameters
declared as out or inout.
=o >uali#ier is allowed on the return t(.e o# a #unction.
3unction-#rotot+#e :
#recision-8uali3ier t+#e 3unction-name:const-8uali3ier #arameter-8uali3ier #recision-8uali3ier
t+#e name arra+-s#eci3ier, ... ;
t+#e :
an( 6asic t(.e, arra( t(.e, structure name, or structure &e3inition
const-8uali3ier :
em.t(
const
#arameter-8uali3ier :
em.t(
in
out
inout
name :
em.t(
identi#ier
arra+-s#eci3ier :
em.t(
/ integral-constant-e$#ression 0
57
6 "tate#ents and "tructure
,owever, the const >uali#ier cannot 6e used with out or inout. -he a6ove is used #or #unction
declarations @i.e., .rotot(.esA and #or #unction de#initions. ,ence, #unction de#initions can have unnamed
arguments.
Recursion is not allowed, not even staticall(. 'tatic recursion is .resent i# the static #unction call gra.h o#
the .rogram contains c(cles.
.2 Selection
!onditional control #low in the shading language is done 6( either if, if;else, or switc statements:
selection-statement :
if @ 2ool-e$#ression A statement
if @ 2ool-e$#ression A statement else statement
switc @ init-e$#ression A Z s6itc/-statement-listo#t

[
Ghere s6itc/-statement-list is a list o# Eero or more s6itc/-statement and other statements de#ined 6( the
language, where s6itc/-statement adds some #orms o# la6els. -hat is
s6itc/-statement-list :
s6itc/-statement
s6itc/-statement-list s6itc/-statement
s6itc/-statement :
case constant-e$#ression ;
default ;
statement
I# an if#e1.ression evaluates to true, then the #irst statement is e1ecuted. I# it evaluates to false and there
is an else .art then the second statement is e1ecuted.
An( e1.ression whose t(.e evaluates to a Boolean can 6e used as the conditional e1.ression 2ool-
e$#ression. Vector t(.es are not acce.ted as the e1.ression to if.
!onditionals can 6e nested.
-he t(.e o# init-e$#ression in a switch statement must 6e a scalar integer. I# a case la6el has a constant-
e$#ression o# e>ual value, then e1ecution will continue a#ter that la6el. *therwise, i# there is a default
la6el, e1ecution will continue a#ter that la6el. *therwise, e1ecution ski.s the rest o# the switch statement.
It is an error to have more than one default or a re.licated constant-e$#ression. A break statement not
nested in a loo. or other switch statement @either not nested or nested onl( in if or if;else statementsA will
also ski. the rest o# the switch statement. )all through la6els are allowed, 6ut it is an error to have no
statement 6etween a la6el and the end o# the switc statement.
=o case or default la6els can 6e nested inside other #low control nested within their corres.onding
switc.
.! Iteration
)or, while, and do loo.s are allowed as #ollows:
58
6 "tate#ents and "tructure
for #initEexpression' &onditionEexpression' loopEexpression)
su$Estatement
:4ile #&onditionEexpression)
su$Estatement
do
statement
:4ile #&onditionEexpression)
'ee 'ection 7 B'hading 0anguage /rammarC #or the de#initive s.eci#ication o# loo.s.
-he for loo. #irst evaluates the init-e$#ression, then the con&ition-e$#ression. I# the con&ition-
e$#ression evaluates to true, then the 6od( o# the loo. is e1ecuted. A#ter the 6od( is e1ecuted, a for loo.
will then evaluate the loo#-e$#ression, and then loo. 6ack to evaluate the con&ition-e$#ression, re.eating
until the con&ition-e$#ression evaluates to #alse. -he loo. is then e1ited, ski..ing its 6od( and ski..ing
its loo#-e$#ression. Varia6les modi#ied 6( the loo#-e$#ression maintain their value a#ter the loo. is
e1ited, .rovided the( are still in sco.e. Varia6les declared in init-e$#ression or con&ition-e$#ression are
onl( in sco.e until the end o# the su6;statement o# the for loo..
-he wile loo. #irst evaluates the con&ition-e$#ression. I# true, then the 6od( is e1ecuted. -his is then
re.eated, until the con&ition-e$#ression evaluates to #alse, e1iting the loo. and ski..ing its 6od(.
Varia6les declared in the con&ition-e$#ression are onl( in sco.e until the end o# the su6;statement o# the
while loo..
-he do#wile loo. #irst e1ecutes the 6od(, then e1ecutes the con&ition-e$#ression. -his is re.eated until
con&ition-e$#ression evaluates to #alse, and then the loo. is e1ited.
+1.ressions #or con&ition-e$#ression must evaluate to a Boolean.
Both the con&ition-e$#ression and the init-e$#ression can declare and initialiEe a varia6le, e1ce.t in the
do#wile loo., which cannot declare a varia6le in its con&ition-e$#ression. -he varia6leHs sco.e lasts
onl( until the end o# the su6;statement that #orms the 6od( o# the loo..
0oo.s can 6e nested.
=on;terminating loo.s are allowed. -he conse>uences o# ver( long or non;terminating loo.s are .lat#orm
de.endent.
.4 :u#ps
-hese are the ?um.s:
<um#_statement:
continue<
break<
return<
return e$#ression<
discard< ** in the #ragment shader language onl(
59
6 "tate#ents and "tructure
-here is no BgotoC nor other non;structured #low o# control.
-he continue ?um. is used onl( in loo.s. It ski.s the remainder o# the 6od( o# the inner most loo. o#
which it is inside. )or wile and do#wile loo.s, this ?um. is to the ne1t evaluation o# the loo.
con&ition-e$#ression #rom which the loo. continues as .reviousl( de#ined. )or for loo.s, the ?um. is to
the loo#-e$#ression, #ollowed 6( the con&ition-e$#ression.
-he break ?um. can also 6e used onl( in loo.s and switch statements. It is sim.l( an immediate e1it o#
the inner;most loo. or switch statements containing the break. =o #urther e1ecution o# con&ition-
e$#ression, loo#-e$#ression, or s6itc/-statement is done.
-he discard ke(word is onl( allowed within #ragment shaders. It can 6e used within a #ragment shader to
a6andon the o.eration on the current #ragment. -his ke(word causes the #ragment to 6e discarded and no
u.dates to an( 6u##ers will occur. !ontrol #low e1its the shader, and su6se>uent im.licit or e1.licit
derivatives are unde#ined when this control #low is non;uni#orm @meaning di##erent #ragments within the
.rimitive take di##erent control .athsA. It would t(.icall( 6e used within a conditional statement, #or
e1am.le:
if #intensit1 K A6A)
dis&ard'
A #ragment shader ma( test a #ragmentHs al.ha value and discard the #ragment 6ased on that test.
,owever, it should 6e noted that coverage testing occurs a#ter the #ragment shader runs, and the coverage
test can change the al.ha value.
-he return ?um. causes immediate e1it o# the current #unction. I# it has e$#ression then that is the return
value #or the #unction.
-he #unction main can use return. -his sim.l( causes main to e1it in the same wa( as when the end o#
the #unction had 6een reached. It does not im.l( a use o# discard in a #ragment shader. 5sing return in
main 6e#ore de#ining out.uts will have the same 6ehavior as reaching the end o# main 6e#ore de#ining
out.uts.
60
7 -uilt9in *ariables
7.1 *erte+ Shader Special *ariables
'ome *.en/0 o.erations occur in #i1ed #unctionalit( 6etween the verte1 .rocessor and the #ragment
.rocessor. 'haders communicate with the #i1ed #unctionalit( o# *.en/0 through the use o# 6uilt;in
varia6les.
-hese 6uilt;in verte1 shader varia6les #or communicating with #i1ed #unctionalit( are intrinsicall(
declared as #ollows:
out ve&/ gl_@osition' (( ma1 $e :ritten to
out float gl_@ointSi"e' (( ma1 $e :ritten to
in int gl_VertexI'
in int gl_Instan&eI'
out float gl_Clipistan&e>?' (( ma1 $e :ritten to
I# using the e1tension ARB<com.ati6ilit(, then the #ollowing varia6le is also intrinsicall( declared
out ve&/ gl_ClipVertex' (( 8R+_&ompati$ilit1 onl1
-he varia6le gl_!osition is availa6le onl( in the verte1 language and is intended #or writing the
homogeneous verte1 .osition. It can 6e written at an( time during shader e1ecution. It ma( also 6e read
6ack 6( a verte1 shader a#ter 6eing written. -his value will 6e used 6( .rimitive assem6l(, cli..ing,
culling, and other #i1ed #unctionalit( o.erations, i# .resent, that o.erate on .rimitives a#ter verte1
.rocessing has occurred. Its value is unde#ined i# the verte1 shader e1ecuta6le does not write gl_!osition.
-he varia6le gl_!oint.i7e is availa6le onl( in the verte1 language and is intended #or a verte1 shader to
write the siEe o# the .oint to 6e rasteriEed. It is measured in .i1els. I# gl_!oint.i7e is not written to, its
value is unde#ined in su6se>uent .i.e stages.
-he varia6le gl_Verte$D is a verte1 shader in.ut varia6le that holds an integer inde1 #or the verte1, as
de#ined 6( the *.en/0 /ra.hics '(stem '.eci#ication. Ghile the varia6le gl_Verte$D is alwa(s
.resent, its value is not alwa(s de#ined. )or details on when it is de#ined, see the U'hader In.utsU
su6section U'hader +1ecutionU o# the *.en/0 /ra.hics '(stem '.eci#ication.
-he varia6le gl_nstanceD is a verte1 shader in.ut varia6le that holds the integer inde1 o# the current
.rimitive in an instanced draw call @see *.en/0 /ra.hics '(stem '.eci#icationA. I# the current .rimitive
does not come #rom an instanced draw call, the value o# gl_nstanceD is Eero.
61
7 Built$in Variables
-he varia6le gl_"li#Distance .rovides the #orward com.ati6le mechanism in the verte1 shader #or
controlling user cli..ing. -o use this, a verte1 shader is res.onsi6le #or maintaining a set o# cli. .lanes,
com.uting the distance #rom the verte1 to each cli. .lane, and storing distances to the .lane in
gl_"li#Distance(i) #or each .lane i. A distance o# 8 means the verte1 is on the .lane, a .ositive distance
means the verte1 is inside the cli. .lane, and a negative distance means the .oint is outside the cli. .lane.
-he cli. distances will 6e linearl( inter.olated across the .rimitive and the .ortion o# the .rimitive with
inter.olated distances less than 8 will 6e cli..ed.
-he gl_"li#Distance arra( is .redeclared as unsiEed and must 6e siEed 6( the shader either redeclaring it
with a siEe or inde1ing it onl( with integral constant e1.ressions. -his needs to siEe the arra( to include
all the cli. .lanes that are ena6led via the *.en/0 A2II i# the siEe does not include all ena6led .lanes,
results are unde#ined. -he siEe can 6e at most gl_*a$"li#Distances. -he num6er o# var(ing com.onents
@see gl_*a$Var+ing"om#onents; consumed 6( gl_"li#Distance will match the siEe o# the arra(, no
matter how man( .lanes are ena6led. -he shader must also set all values in gl_"li#Distance that have
6een ena6led via the *.en/0 A2I, or results are unde#ined. Values written into gl_"li#Distance #or
.lanes that are not ena6led have no e##ect.
7.1.1 gl;Clip*erte+
-his section onl( a..lies when the e1tension ARB<com.ati6ilit( is 6eing used.
-he varia6le gl_"li#Verte$ is availa6le onl( in the verte1 language and .rovides a .lace #or verte1
shaders to write the coordinate to 6e used with the user cli..ing .lanes. -he user must ensure the cli.
verte1 and user cli..ing .lanes are de#ined in the same coordinate s.ace. 5ser cli. .lanes work .ro.erl(
onl( under linear trans#orm. It is unde#ined what ha..ens under non;linear trans#orm.
I# a linked set o# shaders #orming the verte1 stage contains no static write to gl_"li#Verte$ or
gl_"li#Distance, 6ut the a..lication has re>uested cli..ing against user cli. .lanes through the A2I, then
the coordinate written to gl_!osition is used #or com.arison against the user cli. .lanes. Griting to
gl_"li#Distance is the .re#erred method #or user cli..ing. It is an error #or a shader to staticall( write
6oth gl_"li#Verte$ and gl_"li#Distance.
-he #ollowing 6uilt;in state is .rovided
&onst int gl_9axClip@lanes , I' (( 8R+_&ompati$ilit1 onl1
uniform ve&/ gl_Clip@lane>gl_9axClip@lanes?' (( 8R+_&ompati$ilit1 onl1
7.2 %rag#ent Shader Special *ariables
-he 6uilt;in s.ecial varia6les that are accessi6le #rom a #ragment shader are intrinsicall( declared as
#ollows:
in ve&/ gl_FragCoord'
in $ool gl_FrontFa&ing'
in float gl_Clipistan&e>?'
out ve&/ gl_FragColor' (( depre&ated
out ve&/ gl_Fragata>gl_9axra:+uffers?' (( depre&ated
out float gl_Fragept4'
+1ce.t as noted 6elow, the( 6ehave as other in.ut and out.ut varia6les.
62
7 Built$in Variables
-he out.ut o# the #ragment shader e1ecuta6le is .rocessed 6( the #i1ed #unction o.erations at the 6ack end
o# the *.en/0 .i.eline.
)ragment shaders out.ut values to the *.en/0 .i.eline using the 6uilt;in varia6les gl_'rag"olor,
gl_'ragData, and gl_'ragDe#t/, unless the discard statement is e1ecuted. Both gl_'rag"olor and
gl_'ragData are de.recatedI the .re#erred usage is to e1.licitl( declare these out.uts in the #ragment
shader using the out storage >uali#ier.
-he #i1ed #unctionalit( com.uted de.th #or a #ragment ma( 6e o6tained 6( reading gl_'rag"oor&.7,
descri6ed 6elow.
De.recated: Griting to gl_'rag"olor s.eci#ies the #ragment color that will 6e used 6( the su6se>uent
#i1ed #unctionalit( .i.eline. I# su6se>uent #i1ed #unctionalit( consumes #ragment color and an e1ecution
o# the #ragment shader e1ecuta6le does not write a value to gl_'rag"olor then the #ragment color
consumed is unde#ined.
Griting to gl_'ragDe#t/ will esta6lish the de.th value #or the #ragment 6eing .rocessed. I# de.th
6u##ering is ena6led, and no shader writes gl_'ragDe#t/, then the #i1ed #unction value #or de.th will 6e
used as the #ragmentHs de.th value. I# a shader staticall( assigns a value to gl_'ragDe#t/, and there is an
e1ecution .ath through the shader that does not set gl_'ragDe#t/, then the value o# the #ragmentHs de.th
ma( 6e unde#ined #or e1ecutions o# the shader that take that .ath. -hat is, i# the set o# linked #ragment
shaders staticall( contain a write to gl_'ragDe#t/, then it is res.onsi6le #or alwa(s writing it.
De.recated: -he varia6le gl_'ragData is an arra(. Griting to gl_'ragData(n) s.eci#ies the #ragment
data that will 6e used 6( the su6se>uent #i1ed #unctionalit( .i.eline #or data n. I# su6se>uent #i1ed
#unctionalit( consumes #ragment data and an e1ecution o# a #ragment shader e1ecuta6le does not write a
value to it, then the #ragment data consumed is unde#ined.
I# a shader staticall( assigns a value to gl_'rag"olor, it ma( not assign a value to an( element o#
gl_'ragData. I# a shader staticall( writes a value to an( element o# gl_'ragData, it ma( not assign a
value to gl_'rag"olor. -hat is, a shader ma( assign values to either gl_'rag"olor or gl_'ragData, 6ut
not 6oth. 9ulti.le shaders linked together must also consistentl( write ?ust one o# these varia6les.
'imilarl(, i# user declared out.ut varia6les are in use @staticall( assigned toA, then the 6uilt;in varia6les
gl_'rag"olor and gl_'ragData ma( not 6e assigned to. -hese incorrect usages all generate com.ile time
errors.
I# a shader e1ecutes the discard ke(word, the #ragment is discarded, and the values o# an( user;de#ined
#ragment out.uts, gl_'ragDe#t/, gl_'rag"olor, and gl_'ragData 6ecome irrelevant.
-he varia6le gl_'rag"oor& is availa6le as an in.ut varia6le #rom within #ragment shaders and it holds the
window relative coordinates @$, +, 7, 1A6A values #or the #ragment. I# multi;sam.ling, this value can 6e #or
an( location within the .i1el, or one o# the #ragment sam.les. -he use o# centroid in does not #urther
restrict this value to 6e inside the current .rimitive. -his value is the result o# the #i1ed #unctionalit( that
inter.olates .rimitives a#ter verte1 .rocessing to generate #ragments. -he 7 com.onent is the de.th value
that would 6e used #or the #ragmentHs de.th i# no shader contained an( writes to gl_'ragDe#t/. -his is
use#ul #or invariance i# a shader conditionall( com.utes gl_'ragDe#t/ 6ut otherwise wants the #i1ed
#unctionalit( #ragment de.th.
)ragment shaders have access to the in.ut 6uilt;in varia6le gl_'ront'acing, whose value is true i# the
#ragment 6elongs to a #ront;#acing .rimitive. *ne use o# this is to emulate two;sided lighting 6( selecting
one o# two colors calculated 6( a verte1 shader.
63
7 Built$in Variables
-he 6uilt;in in.ut varia6le gl_"li#Distance arra( contains linearl( inter.olated values #or the verte1
values written 6( the verte1 shader to the gl_"li#Distance verte1 out.ut varia6le. -his arra( must 6e
siEed in the #ragment shader either im.licitl( or e1.licitl( to 6e the same siEe as it was siEed in the verte1
shader. *nl( elements in this arra( that have cli..ing ena6led will have de#ined values.
7.! *erte+ Shader -uilt9In Inputs
-his section onl( a..lies when the e1tension ARB<com.ati6ilit( is 6eing used.
-he #ollowing .redeclared in.ut names can 6e used #rom within a verte1 shader to access the current
values o# *.en/0 state.
in ve&/ gl_Color' (( ARB<com.ati6ilit( onl(
in ve&/ gl_Se&ondar1Color' (( ARB<com.ati6ilit( onl(
in ve&3 gl_Normal' (( ARB<com.ati6ilit( onl(
in ve&/ gl_Vertex' (( ARB<com.ati6ilit( onl(
in ve&/ gl_9ultiTexCoordA' (( ARB<com.ati6ilit( onl(
in ve&/ gl_9ultiTexCoord5' (( ARB<com.ati6ilit( onl(
in ve&/ gl_9ultiTexCoord0' (( ARB<com.ati6ilit( onl(
in ve&/ gl_9ultiTexCoord3' (( ARB<com.ati6ilit( onl(
in ve&/ gl_9ultiTexCoord/' (( ARB<com.ati6ilit( onl(
in ve&/ gl_9ultiTexCoord7' (( ARB<com.ati6ilit( onl(
in ve&/ gl_9ultiTexCoordH' (( ARB<com.ati6ilit( onl(
in ve&/ gl_9ultiTexCoordD' (( ARB<com.ati6ilit( onl(
in float gl_FogCoord' (( ARB<com.ati6ilit( onl(
7.4 -uilt9In Constants
-he #ollowing 6uilt;in constants are .rovided to verte1 and #ragment shaders. -he actual values used are
im.lementation de.endent, 6ut must 6e at least the value shown. 'ome are de.recated, as indicated in
comments.
((
(( Implementation dependent &onstants6 T4e example values $elo:
(( are t4e minimum values allo:ed for t4ese maximums6
((
&onst int gl_9axTextureLnits , 5H'
&onst int gl_9axVertex8ttri$s , 5H'
&onst int gl_9axVertexLniformComponents , 5A0/'
&onst int gl_9axVar1ingFloats , H/' (( epre&ated
&onst int gl_9axVar1ingComponents , H/'
&onst int gl_9axVertexTextureImageLnits , 5H'
&onst int gl_9axCom$inedTextureImageLnits , 5H'
&onst int gl_9axTextureImageLnits , 5H'
&onst int gl_9axFragmentLniformComponents , 5A0/'
&onst int gl_9axra:+uffers , I'
&onst int gl_9axClipistan&es , I'
-he constant gl_*a$Var+ing'loats is de.recated, use gl_*a$Var+ing"om#onents instead.
64
7 Built$in Variables
7." -uilt9In 3nifor# State
As an aid to accessing *.en/0 .rocessing state, the #ollowing uni#orm varia6les are 6uilt into the
*.en/0 'hading 0anguage. All section num6ers and notations are re#erences to the *.en/0 /ra.hics
'(stem '.eci#ication, Version &.8.
((
(( ept4 range in :indo: &oordinates- se&tion 065065
((
stru&t gl_ept4Range@arameters ;
float near' (( n
float far' (( f
float diff' (( f E n
<'
uniform gl_ept4Range@arameters gl_ept4Range'
7.".1 .8-;co#patibilit$ State
-his section onl( a..lies i# the ARB<com.ati6ilit( e1tension is 6eing used.
((
(( ARB<com.ati6ilit( onl(
((
uniform mat/ gl_9odelVie:9atrix'
uniform mat/ gl_@ro.e&tion9atrix'
uniform mat/ gl_9odelVie:@ro.e&tion9atrix'
uniform mat/ gl_Texture9atrix>gl_9axTextureCoords?'
((
(( ARB<com.ati6ilit( onl(
((
uniform mat3 gl_Normal9atrix' (( transpose of t4e inverse of t4e
(( upper leftmost 3x3 of gl_9odelVie:9atrix
uniform mat/ gl_9odelVie:9atrixInverse'
uniform mat/ gl_@ro.e&tion9atrixInverse'
uniform mat/ gl_9odelVie:@ro.e&tion9atrixInverse'
uniform mat/ gl_Texture9atrixInverse>gl_9axTextureCoords?'
uniform mat/ gl_9odelVie:9atrixTranspose'
uniform mat/ gl_@ro.e&tion9atrixTranspose'
uniform mat/ gl_9odelVie:@ro.e&tion9atrixTranspose'
uniform mat/ gl_Texture9atrixTranspose>gl_9axTextureCoords?'
uniform mat/ gl_9odelVie:9atrixInverseTranspose'
uniform mat/ gl_@ro.e&tion9atrixInverseTranspose'
uniform mat/ gl_9odelVie:@ro.e&tion9atrixInverseTranspose'
uniform mat/ gl_Texture9atrixInverseTranspose>gl_9axTextureCoords?'
65
7 Built$in Variables
((
(( ARB<com.ati6ilit( onl(
((
uniform float gl_NormalS&ale'
((
(( ARB<com.ati6ilit( onl(
((
uniform ve&/ gl_Clip@lane>gl_9axClip@lanes?'
((
(( ARB<com.ati6ilit( onl(
((
stru&t gl_@oint@arameters ;
float si"e'
float si"e9in'
float si"e9ax'
float fadeT4res4oldSi"e'
float distan&eConstant8ttenuation'
float distan&eLinear8ttenuation'
float distan&eMuadrati&8ttenuation'
<'

uniform gl_@oint@arameters gl_@oint'
((
(( ARB<com.ati6ilit( onl(
((
stru&t gl_9aterial@arameters ;
ve&/ emission' (( E&m
ve&/ am$ient' (( 8&m
ve&/ diffuse' (( &m
ve&/ spe&ular' (( S&m
float s4ininess' (( Srm
<'
uniform gl_9aterial@arameters gl_Front9aterial'
uniform gl_9aterial@arameters gl_+a&29aterial'
66
7 Built$in Variables
((
(( ARB<com.ati6ilit( onl(
((
stru&t gl_Lig4tSour&e@arameters ;
ve&/ am$ient' (( 8&li
ve&/ diffuse' (( &li
ve&/ spe&ular' (( S&li
ve&/ position' (( @pli
ve&/ 4alfVe&tor' (( erived% Fi
ve&3 spotire&tion' (( Sdli
float spotExponent' (( Srli
float spotCutoff' (( Crli
(( #range% >A6A-NA6A?- 5IA6A)
float spotCosCutoff' (( erived% &os#Crli)
(( #range% >56A-A6A?-E56A)
float &onstant8ttenuation' (( OA
float linear8ttenuation' (( O5
float =uadrati&8ttenuation'(( O0
<'
uniform gl_Lig4tSour&e@arameters gl_Lig4tSour&e>gl_9axLig4ts?'
stru&t gl_Lig4t9odel@arameters ;
ve&/ am$ient' (( 8&s
<'
uniform gl_Lig4t9odel@arameters gl_Lig4t9odel'
((
(( ARB<com.ati6ilit( onl(
(( erived state from produ&ts of lig4t and material6
((
stru&t gl_Lig4t9odel@rodu&ts ;
ve&/ s&eneColor' (( erived6 E&m G 8&m J 8&s
<'
uniform gl_Lig4t9odel@rodu&ts gl_FrontLig4t9odel@rodu&t'
uniform gl_Lig4t9odel@rodu&ts gl_+a&2Lig4t9odel@rodu&t'
stru&t gl_Lig4t@rodu&ts ;
ve&/ am$ient' (( 8&m J 8&li
ve&/ diffuse' (( &m J &li
ve&/ spe&ular' (( S&m J S&li
<'
uniform gl_Lig4t@rodu&ts gl_FrontLig4t@rodu&t>gl_9axLig4ts?'
uniform gl_Lig4t@rodu&ts gl_+a&2Lig4t@rodu&t>gl_9axLig4ts?'
67
7 Built$in Variables
((
(( ARB<com.ati6ilit( onl(
((
uniform ve&/ gl_TextureEnvColor>gl_9axTextureLnits?'
uniform ve&/ gl_E1e@laneS>gl_9axTextureCoords?'
uniform ve&/ gl_E1e@laneT>gl_9axTextureCoords?'
uniform ve&/ gl_E1e@laneR>gl_9axTextureCoords?'
uniform ve&/ gl_E1e@laneM>gl_9axTextureCoords?'
uniform ve&/ gl_O$.e&t@laneS>gl_9axTextureCoords?'
uniform ve&/ gl_O$.e&t@laneT>gl_9axTextureCoords?'
uniform ve&/ gl_O$.e&t@laneR>gl_9axTextureCoords?'
uniform ve&/ gl_O$.e&t@laneM>gl_9axTextureCoords?'
((
(( ARB<com.ati6ilit( onl(
((
stru&t gl_Fog@arameters ;
ve&/ &olor'
float densit1'
float start'
float end'
float s&ale' (( erived% 56A ( #end E start)
<'

uniform gl_Fog@arameters gl_Fog'
7. -uilt9In *erte+ Output and %rag#ent Input *ariables
5nlike user;de#ined inter.olated varia6les, the ma..ing 6etween the 6uilt;in verte1 out.ut varia6les to the
6uilt;in #ragment in.ut varia6les doesnDt have a strict one;to;one corres.ondence. -wo sets are .rovided,
one #or each language. -heir relationshi. is descri6ed 6elow.
All .rogramma6le .i.eline stages that are in use while rendering must have a shader .rovidedI #i1ed
#unctionalit( is not .rovided #or .rogramma6le stages.
-here are no longer an( 6uilt;in verte1 out.ut varia6les.
-he #ollowing #ragment in.ut varia6le is availa6le in a #ragment shader.
in ve&0 gl_@ointCoord'
-he values in gl_!oint"oor& are two;dimensional coordinates indicating where within a .oint .rimitive
the current #ragment is located, when .oint s.rites are ena6led. -he( range #rom 8.8 to 1.8 across the
.oint. I# the current .rimitive is not a .oint, or i# .oint s.rites are not ena6led, then the values read #rom
gl_!oint"oor& are unde#ined.
7..1 .8-;co#patibilit$ *erte+ Outputs and %rag#ent Inputs
-his section onl( a..lies when using the ARB<com.ati6ilit( e1tension.
68
7 Built$in Variables
Ghen using the ARB<com.ati6ilit( e1tension, the /0 can .rovide #i1ed #unctionalit( 6ehavior #or a
.rogramma6le .i.eline stage. )or e1am.le, mi1ing a #i1ed #unctionalit( verte1 stage with a
.rogramma6le #ragment stage.
-he #ollowing 6uilt;in verte1 out.ut varia6les are availa6le. A .articular one should 6e written to i# an(
#unctionalit( in a corres.onding #ragment shader or #i1ed .i.eline uses it or state derived #rom it.
*therwise, 6ehavior is unde#ined.
out ve&/ gl_FrontColor' (( 8R+_&ompati$ilit1
out ve&/ gl_+a&2Color' (( 8R+_&ompati$ilit1
out ve&/ gl_FrontSe&ondar1Color' (( 8R+_&ompati$ilit1
out ve&/ gl_+a&2Se&ondar1Color' (( 8R+_&ompati$ilit1
out ve&/ gl_TexCoord>?' (( 8R+_&ompati$ilit1- at most :ill $e
(( gl_9axTextureCoords
out float gl_FogFragCoord'(( 8R+_&ompati$ilit1
)or gl_'og'rag"oor&, the value written will 6e used as the BcC value in section &.11 o# the *.en/0
/ra.hics '(stem '.eci#ication, Version &.8, 6( the #i1ed #unctionalit( .i.eline. )or e1am.le, i# the E;
coordinate o# the #ragment in e(e s.ace is desired as BcC, then thatDs what the verte1 shader e1ecuta6le
should write into gl_'og'rag"oor&.
As with all arra(s, indices used to su6scri.t gl_%e$"oor& must either 6e an integral constant e1.ressions,
or this arra( must 6e re;declared 6( the shader with a siEe. -he siEe can 6e at most
gl_*a$%e$ture"oor&s. 5sing inde1es close to 8 ma( aid the im.lementation in .reserving var(ing
resources.
-he #ollowing #ragment in.uts are also availa6le in a #ragment shader:
in float gl_FogFragCoord' (( 8R+_&ompati$ilit1
in ve&/ gl_TexCoord>?' (( 8R+_&ompati$ilit1
in ve&/ gl_Color' (( 8R+_&ompati$ilit1
in ve&/ gl_Se&ondar1Color' (( 8R+_&ompati$ilit1
-he values in gl_"olor and gl_.econ&ar+"olor will 6e derived automaticall( 6( the s(stem #rom
gl_'ront"olor, gl_,ac-"olor, gl_'ront.econ&ar+"olor, and gl_,ac-.econ&ar+"olor 6ased on which
#ace is visi6le. I# #i1ed #unctionalit( is used #or verte1 .rocessing, then gl_'og'rag"oor& will either 6e
the E;coordinate o# the #ragment in e(e s.ace, or the inter.olation o# the #og coordinate, as descri6ed in
section &.11 o# the *.en/0 /ra.hics '(stem '.eci#ication, Version &.8. -he gl_%e$"oor&() values are
the inter.olated gl_%e$"oor&() values #rom a verte1 shader or the te1ture coordinates o# an( #i1ed
.i.eline 6ased verte1 #unctionalit(.
Indices to the #ragment shader gl_%e$"oor& arra( are as descri6ed a6ove in the verte1 shader te1t.
69
2 -uilt9in %unctions
-he *.en/0 'hading 0anguage de#ines an assortment o# 6uilt;in convenience #unctions #or scalar and
vector o.erations. 9an( o# these 6uilt;in #unctions can 6e used in more than one t(.e o# shader, 6ut some
are intended to .rovide a direct ma..ing to hardware and so are availa6le onl( #or a s.eci#ic t(.e o#
shader.
-he 6uilt;in #unctions 6asicall( #all into three categories:
-he( e1.ose some necessar( hardware #unctionalit( in a convenient wa( such as accessing a te1ture
ma.. -here is no wa( in the language #or these #unctions to 6e emulated 6( a shader.
-he( re.resent a trivial o.eration @clam., mi1, etc.A that is ver( sim.le #or the user to write, 6ut the(
are ver( common and ma( have direct hardware su..ort. It is a ver( hard .ro6lem #or the com.iler to
ma. e1.ressions to com.le1 assem6ler instructions.
-he( re.resent an o.eration gra.hics hardware is likel( to accelerate at some .oint. -he trigonometr(
#unctions #all into this categor(.
9an( o# the #unctions are similar to the same named ones in common ! li6raries, 6ut the( su..ort vector
in.ut as well as the more traditional scalar in.ut.
A..lications should 6e encouraged to use the 6uilt;in #unctions rather than do the e>uivalent com.utations
in their own shader code since the 6uilt;in #unctions are assumed to 6e o.timal @e.g., .erha.s su..orted
directl( in hardwareA.
5ser code can re.lace 6uilt;in #unctions with their own i# the( choose, 6( sim.l( re;declaring and de#ining
the same name and argument list. Because 6uilt;in #unctions are in a more outer sco.e than user 6uilt;in
#unctions, doing this will hide all 6uilt;in #unctions with the same name as the re;declared #unction.
Ghen the 6uilt;in #unctions are s.eci#ied 6elow, where the in.ut arguments @and corres.onding out.utA
can 6e float, vecC, vecD, or vecE, gen%+#e is used as the argument. Ghere the in.ut arguments @and
corres.onding out.utA can 6e int, ivecC, ivecD, or ivecE, gen%+#e is used as the argument. Ghere the
in.ut arguments @and corres.onding out.utA can 6e uint, uvecC, uvecD, or uvecE, genB%+#e is used as the
argument. Ghere the in.ut arguments @or corres.onding out.utA can 6e bool, bvecC, bvecD, or bvecE,
gen,%+#e is used as the argument. )or an( s.eci#ic use o# a #unction, the actual t(.es su6stituted #or
gen%+#e, gen%+#e, genB%+#e, or gen,%+#e have to have the same num6er o# com.onents #or all
arguments and #or the return t(.e. 'imilarl( #or mat, which can 6e an( matri1 6asic t(.e.
70
8 Built$in %unctions
2.1 .ngle and Trigono#etr$ %unctions
)unction .arameters s.eci#ied as angle are assumed to 6e in units o# radians. In no case will an( o# these
#unctions result in a divide 6( Eero error. I# the divisor o# a ratio is 8, then results will 6e unde#ined.
-hese all o.erate com.onent;wise. -he descri.tion is .er com.onent.
S$nta+ )escription
gen-(.e radians @gen-(.e &egreesA
!onverts &egrees to radians, i.e.,

148
&egrees
gen-(.e degrees @gen-(.e ra&iansA
!onverts ra&ians to degrees, i.e.,
148

ra&ians
gen-(.e sin @gen-(.e angleA -he standard trigonometric sine #unction.
gen-(.e cos @gen-(.e angleA -he standard trigonometric cosine #unction.
gen-(.e tan @gen-(.e angleA -he standard trigonometric tangent.
gen-(.e asin @gen-(.e $A Arc sine. Returns an angle whose sine is $. -he range
o# values returned 6( this #unction is
[

]
Results are unde#ined i# $1.
gen-(.e acos @gen-(.e $A Arc cosine. Returns an angle whose cosine is $. -he
range o# values returned 6( this #unction is X8, Y.
Results are unde#ined i# $1.
gen-(.e atan @gen-(.e +, gen-(.e $A Arc tangent. Returns an angle whose tangent is +A$. -he
signs o# $ and + are used to determine what >uadrant the
angle is in. -he range o# values returned 6( this
#unction is [, ]. Results are unde#ined i# $ and
+ are 6oth 8.
gen-(.e atan @gen-(.e +_over_$A Arc tangent. Returns an angle whose tangent is
+_over_$. -he range o# values returned 6( this #unction
is
[

]
.
71
8 Built$in %unctions
S$nta+ )escription
gen-(.e sin @gen-(.e $A Returns the h(.er6olic sine #unction
e
$
e
$

gen-(.e cos @gen-(.e $A Returns the h(.er6olic cosine #unction


e
$
e
$

gen-(.e tan @gen-(.e $A Returns the h(.er6olic tangent #unction


sinh $
cosh $
gen-(.e asin @gen-(.e $A Arc h(.er6olic sineI returns the inverse o# sin.
gen-(.e acos @gen-(.e $A Arc h(.er6olic cosineI returns the non;negative inverse
o# cos. Results are unde#ined i# $ O 1.
gen-(.e atan @gen-(.e $A Arc h(.er6olic tangentI returns the inverse o# tan.
Results are unde#ined i# $1.
2.2 '+ponential %unctions
-hese all o.erate com.onent;wise. -he descri.tion is .er com.onent.
S$nta+ )escription
gen-(.e pow @gen-(.e $, gen-(.e +A Returns $ raised to the + .ower, i.e., $
+
Results are unde#ined i# $ C 0.
Results are unde#ined i# $ = 0 and + C= 0.
gen-(.e exp @gen-(.e $A Returns the natural e1.onentiation o# $, i.e., e
$
.
gen-(.e log @gen-(.e $A Returns the natural logarithm o# $, i.e., returns the value
+ which satis#ies the e>uation $ Q e
+
.
Results are unde#ined i# $ C= 0.
gen-(.e expC @gen-(.e $A Returns raised to the $ .ower, i.e.,
$
gen-(.e logC @gen-(.e $A Returns the 6ase logarithm o# $, i.e., returns the value
+ which satis#ies the e>uation $=
+
Results are unde#ined i# $ C= 0.
72
8 Built$in %unctions
S$nta+ )escription
gen-(.e sIrt @gen-(.e $A Returns
$ .
Results are unde#ined i# $ C 0.
gen-(.e inversesIrt @gen-(.e $A
Returns
1
$
.
Results are unde#ined i# $ C= 0.
2.! Co##on %unctions
-hese all o.erate com.onent;wise. -he descri.tion is .er com.onent.
S$nta+ )escription
gen-(.e abs @gen-(.e $A
genI-(.e abs @genI-(.e $A
Returns $ i# $ PQ 8, otherwise it returns \$.
gen-(.e sign @gen-(.e $A
genI-(.e sign @genI-(.e $A
Returns 1.8 i# $ P 8, 8.8 i# $ Q 8, or \1.8 i# $ O 8.
gen-(.e floor @gen-(.e $A Returns a value e>ual to the nearest integer that is less
than or e>ual to $.
gen-(.e trunc @gen-(.e $A Returns a value e>ual to the nearest integer to $ whose
a6solute value is not larger than the a6solute value o# $.
gen-(.e round @gen-(.e $A Returns a value e>ual to the nearest integer to $. -he
#raction 8.% will round in a direction chosen 6( the
im.lementation, .resuma6l( the direction that is #astest.
-his includes the .ossi6ilit( that round@$A returns the
same value as round!ven@$A #or all values o# $.
gen-(.e round!ven @gen-(.e $A Returns a value e>ual to the nearest integer to $. A
#ractional .art o# 8.% will round toward the nearest even
integer. @Both &.% and $.% #or 1 will return $.8.A
gen-(.e ceil @gen-(.e $A Returns a value e>ual to the nearest integer that is
greater than or e>ual to $.
gen-(.e fract @gen-(.e $A Returns $ \ floor @$A.
73
8 Built$in %unctions
S$nta+ )escription
gen-(.e mod @gen-(.e $, #loat +A
gen-(.e mod @gen-(.e $, gen-(.e +A
9odulus. Returns $ \ + floor @$F+A.
gen-(.e modf @gen-(.e $, out gen-(.e iA Returns the #ractional .art o# $ and sets i to the integer
.art @as a whole num6er #loating .oint valueA. Both the
return value and the out.ut .arameter will have the same
sign as $.
gen-(.e min @gen-(.e $, gen-(.e +A
gen-(.e min @gen-(.e $, #loat +A
genI-(.e min @genI-(.e $, genI-(.e +A
genI-(.e min @genI-(.e $, int +A
gen5-(.e min @gen5-(.e $, gen5-(.e +A
gen5-(.e min @gen5-(.e $, uint +A
Returns + i# + O $, otherwise it returns $.
gen-(.e max @gen-(.e $, gen-(.e +A
gen-(.e max @gen-(.e $, #loat +A
genI-(.e max @genI-(.e $, genI-(.e +A
genI-(.e max @genI-(.e $, int +A
gen5-(.e max @gen5-(.e $, gen5-(.e +A
gen5-(.e max @gen5-(.e $, uint +A
Returns + i# $ O +, otherwise it returns $.
gen-(.e clamp @gen-(.e $,
gen-(.e minVal,
gen-(.e ma$ValA
gen-(.e clamp @gen-(.e $,
#loat minVal,
#loat ma$ValA
genI-(.e clamp @genI-(.e $,
genI-(.e minVal,
genI-(.e ma$ValA
genI-(.e clamp @genI-(.e $,
int minVal,
int ma$ValA
gen5-(.e clamp @gen5-(.e $,
gen5-(.e minVal,
gen5-(.e ma$ValA
gen5-(.e clamp @gen5-(.e $,
uint minVal,
uint ma$ValA
Returns min @max @$, minValA, ma$ValA.
Results are unde#ined i# minVal P ma$Val.
74
8 Built$in %unctions
S$nta+ )escription
gen-(.e mix @gen-(.e $,
gen-(.e +,
gen-(.e aA
gen-(.e mix @gen-(.e $,
gen-(.e +,
#loat aA
Returns the linear 6lend o# $ and +, i.e.,
$1a+a
gen-(.e mix @gen-(.e $,
gen-(.e (,
genB-(.e aA
'elects which vector each returned com.onent comes
#rom. )or a com.onent o# a that is false, the
corres.onding com.onent o# $ is returned. )or a
com.onent o# a that is true, the corres.onding
com.onent o# + is returned. !om.onents o# $ and + that
are not selected are allowed to 6e invalid #loating .oint
values and will have no e##ect on the results. -hus, this
.rovides di##erent #unctionalit( than
gen-(.e mix@gen-(.e $, gen-(.e +, gen-(.e@aAA
where a is a Boolean vector.
gen-(.e step @gen-(.e e&ge, gen-(.e $A
gen-(.e step @#loat e&ge, gen-(.e $A
Returns 8.8 i# $ O e&ge, otherwise it returns 1.8.
gen-(.e smootstep @gen-(.e e&ge0,
gen-(.e e&ge1,
gen-(.e $A
gen-(.e smootstep @#loat e&ge0,
#loat e&ge1,
gen-(.e $A
Returns 8.8 i# $ OQ e&ge0 and 1.8 i# $ PQ e&ge1 and
.er#orms smooth ,ermite inter.olation 6etween 8 and 1
when e&ge0 O $ O e&ge1. -his is use#ul in cases where
(ou would want a threshold #unction with a smooth
transition. -his is e>uivalent to:
gen-(.e tI
t Q clam. @@1 \ edge8A F @edge1 \ edge8A, 8, 1AI
return t M t M @& \ M tAI
Results are un&e3ine& i3 e&ge0 D= e&ge1.
genB-(.e isnan @gen-(.e $A Returns true i# $ holds a =a= @not a num6erA
re.resentation in the underl(ing im.lementationDs set o#
#loating .oint re.resentations. Returns false otherwise,
including #or im.lementations with no =a=
re.resentations.
genB-(.e isinf @gen-(.e $A Returns true i# $ holds a .ositive in#init( or negative
in#init( re.resentation in the underl(ing im.lementationDs
set o# #loating .oint re.resentations. Returns false
otherwise, including #or im.lementations with no in#init(
re.resentations.
75
8 Built$in %unctions
2.4 Geo#etric %unctions
-hese o.erate on vectors as vectors, not com.onent;wise.
S$nta+ )escription
#loat lengt @gen-(.e $A Returns the length o# vector $, i.e.,
$[ 8]

$[ 1]

...
#loat distance @gen-(.e #0, gen-(.e #1A Returns the distance 6etween #0 and #1, i.e.,
lengt @#0 E #1A
#loat dot @gen-(.e $, gen-(.e +A Returns the dot .roduct o# $ and +, i.e.,
$[ 8]+ [8]$ [1]+[1]...
vec& cross @vec& $, vec& +A Returns the cross .roduct o# 1 and (, i.e.,
[
$ [1]+[ ]+ [1]$ []
$[ ]+[ 8]+ [ ]$[ 8]
$[8]+ [1]+ [8]$ [1]
]
gen-(.e normali$e @gen-(.e $A Returns a vector in the same direction as $ 6ut with a
length o# 1.
ARB<com.ati6ilit( onl(
vec$ ftransform@A
Availa6le onl( when using the ARB<com.ati6ilit(
e1tension. )or core *.en/0, use invariant.
)or verte1 shaders onl(. -his #unction will ensure that
the incoming verte1 value will 6e trans#ormed in a wa(
that .roduces e1actl( the same result as would 6e
.roduced 6( *.en/0Hs #i1ed #unctionalit( trans#orm. It
is intended to 6e used to com.ute gl_!osition, e.g.,
gl<2osition Q ftransform@A
-his #unction should 6e used, #or e1am.le, when an
a..lication is rendering the same geometr( in se.arate
.asses, and one .ass uses the #i1ed #unctionalit( .ath to
render and another .ass uses .rogramma6le shaders.
gen-(.e faceforward@gen-(.e N,
gen-(.e ,
gen-(.e Nre3A
I# dot@Nre3, A O 8 return N, otherwise return \N.
76
8 Built$in %unctions
S$nta+ )escription
gen-(.e reflect @gen-(.e , gen-(.e NA )or the incident vector and sur#ace orientation N,
returns the re#lection direction:
\ dot@N, A N
N must alread( 6e normaliEed in order to achieve the
desired result.
gen-(.e refract@gen-(.e , gen-(.e N,
#loat etaA
)or the incident vector and sur#ace normal N, and the
ratio o# indices o# re#raction eta, return the re#raction
vector. -he result is com.uted 6(
k Q 1.8 ; eta M eta M @1.8 ; dot@N, A M dot@N, AA
i# @k O 8.8A
return gen-(.e@8.8A
else
return eta M ; @eta M dot@N, A J sIrt@kAA M N
-he in.ut .arameters #or the incident vector and the
sur#ace normal N must alread( 6e normaliEed to get the
desired results.
77
8 Built$in %unctions
2." 4atri+ %unctions
S$nta+ )escription
mat matrixCompOult @mat $, mat +A 9ulti.l( matri1 $ 6( matri1 + com.onent;wise, i.e.,
resultXiYX?Y is the scalar .roduct o# $XiYX?Y and +XiYX?Y.
=ote: to get linear alge6raic matri1 multi.lication, use
the multi.l( o.erator @+A.
mat outerQroduct@vec c, vec rA
mat& outerQroduct@vec& c, vec& rA
mat$ outerQroduct@vec$ c, vec$ rA
mat1& outerQroduct@vec& c, vec rA
mat&1 outerQroduct@vec c, vec& rA
mat1$ outerQroduct@vec$ c, vec rA
mat$1 outerQroduct@vec c, vec$ rA
mat&1$ outerQroduct@vec$ c, vec& rA
mat$1& outerQroduct@vec& c, vec$ rA
-reats the #irst .arameter c as a column vector @matri1
with one columnA and the second .arameter r as a row
vector @matri1 with one rowA and does a linear alge6raic
matri1 multi.l( c M r, (ielding a matri1 whose num6er o#
rows is the num6er o# com.onents in c and whose
num6er o# columns is the num6er o# com.onents in r.
mat transpose@mat mA
mat& transpose@mat& mA
mat$ transpose@mat$ mA
mat1& transpose@mat&1 mA
mat&1 transpose@mat1& mA
mat1$ transpose@mat$1 mA
mat$1 transpose@mat1$ mA
mat&1$ transpose@mat$1& mA
mat$1& transpose@mat&1$ mA
Returns a matri1 that is the trans.ose o# m. -he in.ut
matri1 m is not modi#ied.
mat inverse@mat mA
mat& inverse@mat& mA
mat$ inverse@mat$ mA
Returns a matri1 that is the inverse o# m. -he in.ut
matri1 m is not modi#ied. -he values in the returned
matri1 are unde#ined i# m is singular or .oorl(;
conditioned @nearl( singularA.
78
8 Built$in %unctions
2. *ector 8elational %unctions
Relational and e>ualit( o.erators @-& -9& .& .9& 99& :9A are de#ined to .roduce scalar Boolean results. )or
vector results, use the #ollowing 6uilt;in #unctions. Below, B6vecC is a .laceholder #or one o# bvecC,
bvecD, or bvecE, BivecC is a .laceholder #or one o# ivecC, ivecD, or ivecE, BuvecC is a .laceholder #or
uvecC, uvecD, or uvecE, and BvecC is a .laceholder #or vecC, vecD, or vecE. In all cases, the siEes o# the
in.ut and return vectors #or an( .articular call must match.
S$nta+ )escription
6vec less@an@vec 1, vec (A
6vec less@an@ivec 1, ivec (A
6vec less@an@uvec 1, uvec (A
Returns the com.onent;wise com.are o# $ O +.
6vec less@an!Iual@vec 1, vec (A
6vec less@an!Iual@ivec 1, ivec (A
6vec less@an!Iual@uvec 1, uvec (A
Returns the com.onent;wise com.are o# $ OQ +.
6vec greater@an@vec 1, vec (A
6vec greater@an@ivec 1, ivec (A
6vec greater@an@uvec 1, uvec (A
Returns the com.onent;wise com.are o# $ P +.
6vec greater@an!Iual@vec 1, vec (A
6vec greater@an!Iual@ivec 1, ivec (A
6vec greater@an!Iual@uvec 1, uvec (A
Returns the com.onent;wise com.are o# $ PQ +.
6vec eIual@vec 1, vec (A
6vec eIual@ivec 1, ivec (A
6vec eIual@uvec 1, uvec (A
6vec eIual@6vec 1, 6vec (A
6vec not!Iual@vec 1, vec (A
6vec not!Iual@ivec 1, ivec (A
6vec not!Iual@uvec 1, uvec (A
6vec not!Iual@6vec 1, 6vec (A
Returns the com.onent;wise com.are o# $ QQ +.
Returns the com.onent;wise com.are o# $ LQ +.
6ool an"@6vec 1A Returns true i# an( com.onent o# $ is true.
6ool all@6vec 1A Returns true onl( i# all com.onents o# $ are true.
6vec not@6vec 1A Returns the com.onent;wise logical com.lement o# $.
79
8 Built$in %unctions
2.7 Te+ture Loo0up %unctions
-e1ture looku. #unctions are availa6le to 6oth verte1 and #ragment shaders. ,owever, level o# detail is
not im.licitl( com.uted #or verte1 shaders. -he #unctions in the ta6le 6elow .rovide access to te1tures
through sam.lers, as set u. through the *.en/0 A2I. -e1ture .ro.erties such as siEe, .i1el #ormat,
num6er o# dimensions, #iltering method, num6er o# mi.;ma. levels, de.th com.arison, and so on are also
de#ined 6( *.en/0 A2I calls. 'uch .ro.erties are taken into account as the te1ture is accessed via the
6uilt;in #unctions de#ined 6elow.
-e1ture data can 6e stored 6( the /0 as #loating .oint, unsigned normaliEed integer, unsigned integer or
signed integer data. -his is determined 6( the t(.e o# the internal #ormat o# the te1ture. -e1ture looku.s
on unsigned normaliEed integer and #loating .oint data return #loating .oint values in the range X8, 1Y.
-e1ture looku. #unctions are .rovided that can return their result as #loating .oint, unsigned integer or
signed integer, de.ending on the sam.ler t(.e .assed to the looku. #unction. !are must 6e taken to use
the right sam.ler t(.e #or te1ture access. -he #ollowing ta6le lists the su..orted com6inations o# sam.ler
t(.es and te1ture internal #ormats. Blank entries are unsu..orted. Doing a te1ture looku. will return
unde#ined values #or unsu..orted com6inations.
Internal -e1ture )ormat
)loating 2oint
'am.ler -(.es
'igned Integer
'am.ler -(.es
5nsigned Integer
'am.ler -(.es
)loating .oint 'u..orted
=ormaliEed Integer 'u..orted
'igned Integer 'u..orted
5nsigned Integer 'u..orted
I# an integer sam.ler t(.e is used, the result o# a te1ture looku. is an ivecE. I# an unsigned integer sam.ler
t(.e is used, the result o# a te1ture looku. is a uvecE. I# a #loating .oint sam.ler t(.e is used, the result o#
a te1ture looku. is a vecE, where each com.onent is in the range X8, 1Y.
In the .rotot(.es 6elow, the BgC in the return t(.e Bgvec4C is used as a .laceholder #or nothing, BiC, or BuC
making a return t(.e o# vecE, ivecE, or uvecE. In these cases, the sam.ler argument t(.e also starts with
BgC, indicating the same su6stitution done on the return t(.eI it is either a #loating .oint, signed integer, or
unsigned integer sam.ler, matching the 6asic t(.e o# the return t(.e, as descri6ed a6ove.
)or shadow #orms @the sam.ler .arameter is a shadow;t(.eA, a de.th com.arison looku. on the de.th
te1ture 6ound to sam#ler is done as descri6ed in section &.7.1$ o# the *.en/0 /ra.hics '(stem
'.eci#ication, Version &.8. 'ee the ta6le 6elow #or which com.onent s.eci#ies Dre3. -he te1ture 6ound to
sam#ler must 6e a de.th te1ture, or results are unde#ined. I# a non;shadow te1ture call is made to a
sam.ler that re.resents a de.th te1ture with de.th com.arisons turned on, then results are unde#ined. I# a
shadow te1ture call is made to a sam.ler that re.resents a de.th te1ture with de.th com.arisons turned
o##, then results are unde#ined. I# a shadow te1ture call is made to a sam.ler that does not re.resent a
de.th te1ture, then results are unde#ined.
80
8 Built$in %unctions
In all #unctions 6elow, the 2ias .arameter is o.tional #or #ragment shaders. -he 2ias .arameter is not
acce.ted in a verte1 shader. )or a #ragment shader, i# 2ias is .resent, it is added to the im.licit level o#
detail .rior to .er#orming the te1ture access o.eration. =o 2ias or lo& .arameters #or rectangular te1tures
or te1ture 6u##ers are su..orted 6ecause mi.;ma.s are not allowed #or rectangular te1tures or te1ture
6u##ers.
-he im.licit level o# detail is selected as #ollows: )or a te1ture that is not mi.;ma..ed, the te1ture is used
directl(. I# it is mi.;ma..ed and running in a #ragment shader, the 0*D com.uted 6( the im.lementation
is used to do the te1ture looku.. I# it is mi.;ma..ed and running on the verte1 shader, then the 6ase
te1ture is used.
'ome te1ture #unctions @non;BBodC and non;BGradC versionsA ma( re>uire im.licit derivatives. Im.licit
derivatives are unde#ined within non;uni#orm control #low and #or verte1 shader te1ture #etches.
)or Cube #orms, the direction o# ! is used to select which #ace to do a ;dimensional te1ture looku. in, as
descri6ed in section &.7." in the *.en/0 /ra.hics '(stem '.eci#ication, Version &.8.
)or Arra" #orms, the arra( la(er used will 6e
ma$ 8, min & 1, 3loorla+er8.%
where & is the de.th o# the te1ture arra( and la+er comes #rom the com.onent indicated in the ta6les
6elow.
81
8 Built$in %unctions
S$nta+ )escription
int textureSi$e @gsam.ler1D sam#ler, int lo&A
ivec textureSi$e @gsam.lerD sam#ler, int lo&A
ivec& textureSi$e @gsam.ler&D sam#ler, int lo&A
ivec textureSi$e @gsam.ler!u6e sam#ler, int lo&A
int textureSi$e @sam.ler1D'hadow sam#ler, int lo&A
ivec textureSi$e @sam.lerD'hadow sam#ler, int lo&A
ivec textureSi$e @sam.ler!u6e'hadow sam#ler, int lo&A
ivec textureSi$e @gsam.lerDRect sam#lerA
ivec textureSi$e @sam.lerDRect'hadow sam#lerA
ivec textureSi$e @gsam.ler1DArra( sam#ler, int lo&A
ivec& textureSi$e @gsam.lerDArra( sam#ler, int lo&A
ivec textureSi$e @sam.ler1DArra('hadow sam#ler, int lo&A
ivec& textureSi$e @sam.lerDArra('hadow sam#ler, int lo&A
int textureSi$e @gsam.lerBu##er sam#lerA
Returns the dimensions o# level
lo& @i# .resentA #or the te1ture
6ound to sam#ler, as descri6ed
in section .8.$ o# the *.en/0
/ra.hics '(stem '.eci#ication,
Version &.8, under U-e1ture
'iEe :uer(U.
-he com.onents in the return
value are #illed in, in order, with
the width, height, de.th o# the
te1ture.
)or the arra( #orms, the last
com.onent o# the return value is
the num6er o# la(ers in the
te1ture arra(.
gvec$ texture @gsam.ler1D sam#ler, #loat ! X, #loat 2iasY A
gvec$ texture @gsam.lerD sam#ler, vec ! X, #loat 2iasY A
gvec$ texture @gsam.ler&D sam#ler, vec& ! X, #loat 2iasY A
gvec$ texture @gsam.ler!u6e sam#ler, vec& ! X, #loat 2iasY A
#loat texture @sam.ler1D'hadow sam#ler, vec& ! X, #loat 2iasY A
#loat texture @sam.lerD'hadow sam#ler, vec& ! X, #loat 2iasY A
#loat texture @sam.ler!u6e'hadow sam#ler, vec$ ! X, #loat 2iasY A
gvec$ texture @gsam.ler1DArra( sam#ler, vec ! X, #loat 2iasY A
gvec$ texture @gsam.lerDArra( sam#ler, vec& ! X, #loat 2iasY A
#loat texture @sam.ler1DArra('hadow sam#ler, vec& !
X, #loat 2iasY A
#loat texture @sam.lerDArra('hadow sam#ler, vec$ !A
gvec$ texture @gsam.lerDRect sam#ler, vec !A
#loat texture @sam.lerDRect'hadow sam#ler, vec& !A
5se the te1ture coordinate ! to
do a te1ture looku. in the
te1ture currentl( 6ound to
sam#ler. -he last com.onent o#
! is used as Dre3 #or the shadow
#orms. )or arra( #orms, the arra(
la(er comes #rom the last
com.onent o# ! in the non;
shadow #orms, and the second to
last com.onent o# ! in the
shadow #orms.
gvec$ textureQroH @gsam.ler1D sam#ler, vec ! X, #loat 2iasY A
gvec$ textureQroH @gsam.ler1D sam#ler, vec$ ! X, #loat 2iasY A
gvec$ textureQroH @gsam.lerD sam#ler, vec& ! X, #loat 2iasY A
gvec$ textureQroH @gsam.lerD sam#ler, vec$ ! X, #loat 2iasY A
gvec$ textureQroH @gsam.ler&D sam#ler, vec$ ! X, #loat 2iasY A
#loat textureQroH @sam.ler1D'hadow sam#ler, vec$ !
X, #loat 2iasY A
#loat textureQroH @sam.lerD'hadow sam#ler, vec$ !
X, #loat 2iasY A
gvec$ textureQroH @gsam.lerDRect sam#ler, vec& !A
gvec$ textureQroH @gsam.lerDRect sam#ler, vec$ !A
#loat textureQroH @sam.lerDRect'hadow sam#ler, vec$ !A
Do a te1ture looku. with
.ro?ection. -he te1ture
coordinates consumed #rom !,
not including the last com.onent
o# !, are divided 6( the last
com.onent o# !. -he resulting
&
rd
com.onent o# ! in the
shadow #orms is used as Dre3.
A#ter these values are com.uted,
te1ture looku. .roceeds as in
texture.
82
8 Built$in %unctions
S$nta+ )escription
gvec$ textureBod @gsam.ler1D sam#ler, #loat !, #loat lo&A
gvec$ textureBod @gsam.lerD sam#ler, vec !, #loat lo&A
gvec$ textureBod @gsam.ler&D sam#ler, vec& !, #loat lo&A
gvec$ textureBod @gsam.ler!u6e sam#ler, vec& !, #loat lo&A
#loat textureBod @sam.ler1D'hadow sam#ler, vec& !, #loat lo&A
#loat textureBod @sam.lerD'hadow sam#ler, vec& !, #loat lo&A
gvec$ textureBod @gsam.ler1DArra( sam#ler, vec !, #loat lo&A
gvec$ textureBod @gsam.lerDArra( sam#ler, vec& !, #loat lo&A
#loat textureBod @sam.ler1DArra('hadow sam#ler, vec& !,
#loat lo&A
Do a te1ture looku. as in
texture 6ut with e1.licit 0*DI
lo& s.eci#ies F2ase @see e>uation
&.1" in *.en/0 /ra.hics
'(stem '.eci#ication, Version
&.8A and set the .artial
derivatives in section &.7.3 as
#ollows.
u
$
= 8
v
$
= 8
6
$
= 8
u
+
= 8
v
+
= 8
6
+
= 8
gvec$ textureOffset @gsam.ler1D sam#ler, #loat !,
int o33set X, #loat 2iasY A
gvec$ textureOffset @gsam.lerD sam#ler, vec !,
ivec o33set X, #loat 2iasY A
gvec$ textureOffset @gsam.ler&D sam#ler, vec& !,
ivec& o33set X, #loat 2iasY A
gvec$ textureOffset @gsam.lerDRect sam#ler, vec !,
ivec o33set A
#loat textureOffset @sam.lerDRect'hadow sam#ler, vec& !,
ivec o33set A
#loat textureOffset @sam.ler1D'hadow sam#ler, vec& !,
int o33set X, #loat 2iasY A
#loat textureOffset @sam.lerD'hadow sam#ler, vec& !,
ivec o33set X, #loat 2iasY A
gvec$ textureOffset @gsam.ler1DArra( sam#ler, vec !,
int o33set X, #loat 2iasY A
gvec$ textureOffset @gsam.lerDArra( sam#ler, vec& !,
ivec o33set X, #loat 2iasY A
#loat textureOffset @sam.ler1DArra('hadow sam#ler, vec& !,
int o33set X, #loat 2iasY A
Do a te1ture looku. as in
texture 6ut with o33set added to
the @u,v,6A te1el coordinates
6e#ore looking u. each te1el.
-he o##set value must 6e a
constant e1.ression. A limited
range o# o##set values are
su..ortedI the minimum and
ma1imum o##set values are
im.lementation;de.endent and
given 6(
9I=<2R*/RA9<-+W+0<*))'+- and
9AW<2R*/RA9<-+W+0<*))'+-,
res.ectivel(.
=ote that o33set does not a..l(
to the la(er coordinate #or
te1ture arra(s. -his is e1.lained
in detail in section &.7.3 o# the
*.en/0 /ra.hics '(stem
'.eci#ication, Version &.8,
where o33set is
u
,
v
,
6
.
=ote that te1el o##sets are also
not su..orted #or cu6e ma.s.
83
8 Built$in %unctions
S$nta+ )escription
gvec$ texelJetc @gsam.ler1D sam#ler, int !, int lo&A
gvec$ texelJetc @gsam.lerD sam#ler, ivec !, int lo&A
gvec$ texelJetc @gsam.ler&D sam#ler, ivec& !, int lo&A
gvec$ texelJetc @gsam.lerDRect sam#ler, ivec !A
gvec$ texelJetc @gsam.ler1DArra( sam#ler, ivec !, int lo&A
gvec$ texelJetc @gsam.lerDArra( sam#ler, ivec& !, int lo&A
gvec$ texelJetc @gsam.lerBu##er sam#ler, int !A
5se integer te1ture coordinate !
to looku. a single te1el #rom
sam#ler. -he arra( la(er comes
#rom the last com.onent o# ! #or
the arra( #orms. -he level;o#;
detail lo& @i# .resentA is as
descri6ed in section .8.$ o#
the *.en/0 /ra.hics '(stem
'.eci#ication, Version &.8,
under U-e1el )etchesU.
gvec$ texelJetcOffset @gsam.ler1D sam#ler, int !, int lo&,
int o33setA
gvec$ texelJetcOffset @gsam.lerD sam#ler, ivec !, int lo&,
ivec o33setA
gvec$ texelJetcOffset @gsam.ler&D sam#ler, ivec& !, int lo&,
ivec& o33setA
gvec$ texelJetcOffset @gsam.lerDRect sam#ler, ivec !,
ivec o33setA
gvec$ texelJetcOffset @gsam.ler1DArra( sam#ler, ivec !, int lo&,
int o33setA
gvec$ texelJetcOffset @gsam.lerDArra( sam#ler, ivec& !, int lo&,
ivec o33setA
)etch a single te1el as in
texelJetc o##set 6( o33set as
descri6ed in textureOffset.
gvec$ textureQroHOffset @gsam.ler1D sam#ler, vec !,
int o33set X, #loat 2iasY A
gvec$ textureQroHOffset @gsam.ler1D sam#ler, vec$ !,
int o33set X, #loat 2iasY A
gvec$ textureQroHOffset @gsam.lerD sam#ler, vec& !,
ivec o33set X, #loat 2iasY A
gvec$ textureQroHOffset @gsam.lerD sam#ler, vec$ !,
ivec o33set X, #loat 2iasY A
gvec$ textureQroHOffset @gsam.ler&D sam#ler, vec$ !,
ivec& o33set X, #loat 2iasY A
gvec$ textureQroHOffset @gsam.lerDRect sam#ler, vec& !,
ivec o33set A
gvec$ textureQroHOffset @gsam.lerDRect sam#ler, vec$ !,
ivec o33set A
#loat textureQroHOffset @sam.lerDRect'hadow sam#ler, vec$ !,
ivec o33set A
#loat textureQroHOffset @sam.ler1D'hadow sam#ler, vec$ !,
int o33set X, #loat 2iasY A
#loat textureQroHOffset @sam.lerD'hadow sam#ler, vec$ !,
ivec o33set X, #loat 2iasY A
Do a .ro?ective te1ture looku.
as descri6ed in textureQroH
o##set 6( o33set as descri6ed in
textureOffset.
84
8 Built$in %unctions
S$nta+ )escription
gvec$ textureBodOffset @gsam.ler1D sam#ler, #loat !,
#loat lo&, int o33setA
gvec$ textureBodOffset @gsam.lerD sam#ler, vec !,
#loat lo&, ivec o33setA
gvec$ textureBodOffset @gsam.ler&D sam#ler, vec& !,
#loat lo&, ivec& o33setA
#loat textureBodOffset @sam.ler1D'hadow sam#ler, vec& !,
#loat lo&, int o33setA
#loat textureBodOffset @sam.lerD'hadow sam#ler, vec& !,
#loat lo&, ivec o33setA
gvec$ textureBodOffset @gsam.ler1DArra( sam#ler, vec !,
#loat lo&, int o33setA
gvec$ textureBodOffset @gsam.lerDArra( sam#ler, vec& !,
#loat lo&, ivec o33setA
#loat textureBodOffset @sam.ler1DArra('hadow sam#ler, vec& !,
#loat lo&, int o33setA
Do an o##set te1ture looku. with
e1.licit 0*D. 'ee textureBod
and textureOffset.
gvec$ textureQroHBod @gsam.ler1D sam#ler, vec !, #loat lo&A
gvec$ textureQroHBod @gsam.ler1D sam#ler, vec$ !, #loat lo&A
gvec$ textureQroHBod @gsam.lerD sam#ler, vec& !, #loat lo&A
gvec$ textureQroHBod @gsam.lerD sam#ler, vec$ !, #loat lo&A
gvec$ textureQroHBod @gsam.ler&D sam#ler, vec$ !, #loat lo&A
#loat textureQroHBod @sam.ler1D'hadow sam#ler, vec$ !, #loat lo&A
#loat textureQroHBod @sam.lerD'hadow sam#ler, vec$ !, #loat lo&A
Do a .ro?ective te1ture looku.
with e1.licit 0*D. 'ee
textureQroH and textureBod.
gvec$ textureQroHBodOffset @gsam.ler1D sam#ler, vec !,
#loat lo&, int o33setA
gvec$ textureQroHBodOffset @gsam.ler1D sam#ler, vec$ !,
#loat lo&, int o33setA
gvec$ textureQroHBodOffset @gsam.lerD sam#ler, vec& !,
#loat lo&, ivec o33setA
gvec$ textureQroHBodOffset @gsam.lerD sam#ler, vec$ !,
#loat lo&, ivec o33setA
gvec$ textureQroHBodOffset @gsam.ler&D sam#ler, vec$ !,
#loat lo&, ivec& o33setA
#loat textureQroHBodOffset @sam.ler1D'hadow sam#ler, vec$ !,
#loat lo&, int o33setA
#loat textureQroHBodOffset @sam.lerD'hadow sam#ler, vec$ !,
#loat lo&, ivec o33setA
Do an o##set .ro?ective te1ture
looku. with e1.licit 0*D. 'ee
textureQroH, textureBod, and
textureOffset.
85
8 Built$in %unctions
S$nta+ )escription
gvec$ textureGrad @gsam.ler1D sam#ler, #loat !,
#loat &!&$, #loat &!&+A
gvec$ textureGrad @gsam.lerD sam#ler, vec !,
vec &!&$, vec &!&+A
gvec$ textureGrad @gsam.ler&D sam#ler, vec& !,
vec& &!&$, vec& &!&+A
gvec$ textureGrad @gsam.ler!u6e sam#ler, vec& !,
vec& &!&$, vec& &!&+A
gvec$ textureGrad @gsam.lerDRect sam#ler, vec !,
vec &!&$, vec &!&+A
#loat textureGrad @sam.lerDRect'hadow sam#ler, vec& !,
vec &!&$, vec &!&+A
#loat textureGrad @sam.ler1D'hadow sam#ler, vec& !,
#loat &!&$, #loat &!&+A
#loat textureGrad @sam.lerD'hadow sam#ler, vec& !,
vec &!&$, vec &!&+A
#loat textureGrad @sam.ler!u6e'hadow sam#ler, vec$ !,
vec& &!&$, vec& &!&+A
gvec$ textureGrad @gsam.ler1DArra( sam#ler, vec !,
#loat &!&$, #loat &!&+A
gvec$ textureGrad @gsam.lerDArra( sam#ler, vec& !,
vec &!&$, vec &!&+A
#loat textureGrad @sam.ler1DArra('hadow sam#ler, vec& !,
#loat &!&$, #loat &!&+A
#loat textureGrad @sam.lerDArra('hadow sam#ler, vec$ !,
vec &!&$, vec &!&+A
Do a te1ture looku. as in
texture 6ut with e1.licit
gradients. -he .artial
derivatives o# ! are with res.ect
to window 1 and window (. 'et
s
$
=
{
!
$
#or a 1D te1ture
!.s
$
otherwise
s
+
=
{
!
+
#or a 1D te1ture
!.s
+
otherwise
t
$
=
{
8.8 #or a 1D te1ture
!.t
$
otherwise
t
+
=
{
8.8 #or a 1D te1ture
!.t
+
otherwise
r
$
=
{
8.8 #or 1D or D
!.#
$
cu6e, other
r
+
=
{
8.8 #or 1D or D
!.#
+
cu6e, other
)or the cu6e version, the .artial
derivatives o# ! are assumed to
6e in the coordinate s(stem used
6e#ore te1ture coordinates are
.ro?ected onto the a..ro.riate
cu6e #ace.
86
8 Built$in %unctions
S$nta+ )escription
gvec$ textureGradOffset @gsam.ler1D sam#ler, #loat !,
#loat &!&$, #loat &!&+, int o33setA
gvec$ textureGradOffset @gsam.lerD sam#ler, vec !,
vec &!&$, vec &!&+, ivec o33setA
gvec$ textureGradOffset @gsam.ler&D sam#ler, vec& !,
vec& &!&$, vec& &!&+, ivec& o33setA
gvec$ textureGradOffset @gsam.lerDRect sam#ler, vec !,
vec &!&$, vec &!&+, ivec o33setA
#loat textureGradOffset @sam.lerDRect'hadow sam#ler, vec& !,
vec &!&$, vec &!&+, ivec o33setA
#loat textureGradOffset @sam.ler1D'hadow sam#ler, vec& !,
#loat &!&$, #loat &!&+, int o33set A
#loat textureGradOffset @sam.lerD'hadow sam#ler, vec& !,
vec &!&$, vec &!&+, ivec o33setA
#loat textureGradOffset @sam.ler!u6e'hadow sam#ler, vec$ !,
vec& &!&$, vec& &!&+, ivec o33setA
gvec$ textureGradOffset @gsam.ler1DArra( sam#ler, vec !,
#loat &!&$, #loat &!&+, int o33setA
gvec$ textureGradOffset @gsam.lerDArra( sam#ler, vec& !,
vec &!&$, vec &!&+, ivec o33setA
#loat textureGradOffset @sam.ler1DArra('hadow sam#ler, vec& !,
#loat &!&$, #loat &!&+, int o33setA
#loat textureGradOffset @sam.lerDArra('hadow sam#ler, vec$ !,
vec &!&$, vec &!&+, ivec o33setA
Do a te1ture looku. with 6oth
e1.licit gradient and o##set, as
descri6ed in textureGrad and
textureOffset.
gvec$ textureQroHGrad @gsam.ler1D sam#ler, vec !,
#loat &!&$, #loat &!&+A
gvec$ textureQroHGrad @gsam.ler1D sam#ler, vec$ !,
#loat &!&$, #loat &!&+A
gvec$ textureQroHGrad @gsam.lerD sam#ler, vec& !,
vec &!&$, vec &!&+A
gvec$ textureQroHGrad @gsam.lerD sam#ler, vec$ !,
vec &!&$, vec &!&+A
gvec$ textureQroHGrad @gsam.ler&D sam#ler, vec$ !,
vec& &!&$, vec& &!&+A
gvec$ textureQroHGrad @gsam.lerDRect sam#ler, vec& !,
vec &!&$, vec &!&+A
gvec$ textureQroHGrad @gsam.lerDRect sam#ler, vec$ !,
vec &!&$, vec &!&+A
#loat textureQroHGrad @sam.lerDRect'hadow sam#ler, vec$ !,
vec &!&$, vec &!&+A
#loat textureQroHGrad @sam.ler1D'hadow sam#ler, vec$ !,
#loat &!&$, #loat &!&+A
#loat textureQroHGrad @sam.lerD'hadow sam#ler, vec$ !,
vec &!&$, vec &!&+A
Do a te1ture looku. 6oth
.ro?ectivel(, as descri6ed in
textureQroH, and with e1.licit
gradient as descri6ed in
textureGrad. -he .artial
derivatives &!&$ and &!&+ are
assumed to 6e alread( .ro?ected.
87
8 Built$in %unctions
S$nta+ )escription
gvec$ textureQroHGradOffset @gsam.ler1D sam#ler, vec !,
#loat &!&$, #loat &!&+, int o33setA
gvec$ textureQroHGradOffset @gsam.ler1D sam#ler, vec$ !,
#loat &!&$, #loat &!&+, int o33setA
gvec$ textureQroHGradOffset @gsam.lerD sam#ler, vec& !,
vec &!&$, vec &!&+, vec o33setA
gvec$ textureQroHGradOffset @gsam.lerD sam#ler, vec$ !,
vec &!&$, vec &!&+, vec o33setA
gvec$ textureQroHGradOffset @gsam.lerDRect sam#ler, vec& !,
vec &!&$, vec &!&+, ivec o33setA
gvec$ textureQroHGradOffset @gsam.lerDRect sam#ler, vec$ !,
vec &!&$, vec &!&+, ivec o33setA
#loat textureQroHGradOffset @sam.lerDRect'hadow sam#ler,
vec$ !,
vec &!&$, vec &!&+, ivec o33setA
gvec$ textureQroHGradOffset @gsam.ler&D sam#ler, vec$ !,
vec& &!&$, vec& &!&+, vec& o33setA
#loat textureQroHGradOffset @sam.ler1D'hadow sam#ler, vec$ !,
#loat &!&$, #loat &!&+, int o33setA
#loat textureQroHGradOffset @sam.lerD'hadow sam#ler, vec$ !,
vec &!&$, vec &!&+, vec o33setA
Do a te1ture looku. .ro?ectivel(
and with e1.licit gradient as
descri6ed in textureQroHGrad,
as well as with o##set, as
descri6ed in textureOffset.
88
8 Built$in %unctions
-he #ollowing te1ture #unctions are de.recated.
S$nta+ )escription
vec$ texture1A @sam.ler1D sam#ler,
#loat coor& X, #loat 2iasY A
vec$ texture1AQroH @sam.ler1D sam#ler,
vec coor& X, #loat 2iasY A
vec$ texture1AQroH @sam.ler1D sam#ler,
vec$ coor& X, #loat 2iasY A
vec$ texture1ABod @sam.ler1D sam#ler,
#loat coor&, #loat lo&A
vec$ texture1AQroHBod @sam.ler1D sam#ler,
vec coor&, #loat lo&A
vec$ texture1AQroHBod @sam.ler1D sam#ler,
vec$ coor&, #loat lo&A
De.recated. 'ee corres.onding signature
a6ove without B1DC in the name.
vec$ textureCA @sam.lerD sam#ler,
vec coor& X, #loat 2iasY A
vec$ textureCAQroH @sam.lerD sam#ler,
vec& coor& X, #loat 2iasY A
vec$ textureCAQroH @sam.lerD sam#ler,
vec$ coor& X, #loat 2iasY A
vec$ textureCABod @sam.lerD sam#ler,
vec coor&, #loat lo&A
vec$ textureCAQroHBod @sam.lerD sam#ler,
vec& coor&, #loat lo&A
vec$ textureCAQroHBod @sam.lerD sam#ler,
vec$ coor&, #loat lo&A
De.recated. 'ee corres.onding signature
a6ove without BDC in the name.
vec$ textureDA @sam.ler&D sam#ler,
vec& coor& X, #loat 2iasY A
vec$ textureDAQroH @sam.ler&D sam#ler,
vec$ coor& X, #loat 2iasY A
vec$ textureDABod @sam.ler&D sam#ler,
vec& coor&, #loat lo&A
vec$ textureDAQroHBod @sam.ler&D sam#ler,
vec$ coor&, #loat lo&A
De.recated. 'ee corres.onding signature
a6ove without B&DC in the name.
5se the te1ture coordinate coor& to do a
te1ture looku. in the &D te1ture currentl(
6ound to sam#ler. )or the .ro?ective
@BQroHCA versions, the te1ture coordinate is
divided 6( coor&.8.
vec$ textureCube @sam.ler!u6e sam#ler,
vec& coor& X, #loat 2iasY A
vec$ textureCubeBod @sam.ler!u6e sam#ler,
vec& coor&, #loat lo&A
De.recated. 'ee corres.onding signature
a6ove without B!u6eC in the name.
89
8 Built$in %unctions
S$nta+ )escription
vec$ sadow1A @sam.ler1D'hadow sam#ler,
vec& coor& X, #loat 2iasY A
vec$ sadowCA @sam.lerD'hadow sam#ler,
vec& coor& X, #loat 2iasY A
vec$ sadow1AQroH @sam.ler1D'hadow sam#ler,
vec$ coor& X, #loat 2iasY A
vec$ sadowCAQroH @sam.lerD'hadow sam#ler,
vec$ coor& X, #loat 2iasY A
vec$ sadow1ABod @sam.ler1D'hadow sam#ler,
vec& coor&, #loat lo&A
vec$ sadowCABod @sam.lerD'hadow sam#ler,
vec& coor&, #loat lo&A
vec$ sadow1AQroHBod@sam.ler1D'hadow sam#ler,
vec$ coor&, #loat lo&A
vec$ sadowCAQroHBod@sam.lerD'hadow sam#ler,
vec$ coor&, #loat lo&A
De.recated. 'ame #unctionalit( as the
Btexture] 6ased names a6ove with the same
signature.
2.2 %rag#ent ,rocessing %unctions
)ragment .rocessing #unctions are onl( availa6le in #ragment shaders.
Derivatives ma( 6e com.utationall( e1.ensive andFor numericall( unsta6le. -here#ore, an *.en/0
im.lementation ma( a..ro1imate the true derivatives 6( using a #ast 6ut not entirel( accurate derivative
com.utation. Derivatives are unde#ined within non;uni#orm control #low.
-he e1.ected 6ehavior o# a derivative is s.eci#ied using #orwardF6ackward di##erencing.
)orward di##erencing:
' $&$' $ ~&'&$ $&$ 1a
&'&$ $ ~
' $&$' $
&$
16
Backward di##erencing:
' $&$' $ ~&'&$ $&$ a
&'&$ $ ~
' $' $&$
&$
6
Gith single;sam.le rasteriEation, &$ OQ 1.8 in e>uations 16 and 6. )or multi;sam.le rasteriEation, &$ O
.8 in e>uations 16 and 6.
dJd" is a..ro1imated similarl(, with + re.lacing $.
90
8 Built$in %unctions
A /0 im.lementation ma( use the a6ove or other methods to .er#orm the calculation, su6?ect to the
#ollowing conditions:
1. -he method ma( use .iecewise linear a..ro1imations. 'uch linear a..ro1imations im.l( that higher
order derivatives, dJdx@dJdx@$AA and a6ove, are unde#ined.
. -he method ma( assume that the #unction evaluated is continuous. -here#ore derivatives within the
6od( o# a non;uni#orm conditional are unde#ined.
&. -he method ma( di##er .er #ragment, su6?ect to the constraint that the method ma( var( 6( window
coordinates, not screen coordinates. -he invariance re>uirement descri6ed in section &. o# the
*.en/0 /ra.hics '(stem '.eci#ication, Version &.8, is rela1ed #or derivative calculations, 6ecause
the method ma( 6e a #unction o# #ragment location.
*ther .ro.erties that are desira6le, 6ut not re>uired, are:
$. )unctions should 6e evaluated within the interior o# a .rimitive @inter.olated, not e1tra.olatedA.
%. )unctions #or dJdx should 6e evaluated while holding ( constant. )unctions #or dJd" should 6e
evaluated while holding 1 constant. ,owever, mi1ed higher order derivatives, like dJdx@dJd"@+AA
and dJd"@dJdx@$AA are unde#ined.
". Derivatives o# constant arguments should 6e 8.
In some im.lementations, var(ing degrees o# derivative accurac( ma( 6e o6tained 6( .roviding /0 hints
@section %." o# the *.en/0 /ra.hics '(stem '.eci#ication, Version &.8A, allowing a user to make an
image >ualit( versus s.eed trade o##.
S$nta+ )escription
gen-(.e dJdx @gen-(.e #A Returns the derivative in 1 using local di##erencing #or
the in.ut argument #.
gen-(.e dJd" @gen-(.e #A Returns the derivative in ( using local di##erencing #or
the in.ut argument #.
-hese two #unctions are commonl( used to estimate the
#ilter width used to anti;alias .rocedural te1tures. Ge
are assuming that the e1.ression is 6eing evaluated in
.arallel on a 'I9D arra( so that at an( given .oint in
time the value o# the #unction is known at the grid .oints
re.resented 6( the 'I9D arra(. 0ocal di##erencing
6etween 'I9D arra( elements can there#ore 6e used to
derive d)d1, d)d(, etc.
gen-(.e fwidt @gen-(.e #A Returns the sum o# the a6solute derivative in 1 and (
using local di##erencing #or the in.ut argument #, i.e.,
abs @dJdx @#AA J abs @dJd" @#AAI
91
8 Built$in %unctions
2.5 <oise %unctions
=oise #unctions are availa6le to 6oth #ragment and verte1 shaders. -he( are stochastic #unctions that can
6e used to increase visual com.le1it(. Values returned 6( the #ollowing noise #unctions give the
a..earance o# randomness, 6ut are not trul( random. -he noise #unctions 6elow are de#ined to have the
#ollowing characteristics:
-he return value@sA are alwa(s in the range X;1.8,1.8Y, and cover at least the range X;8.", 8."Y, with a
/aussian;like distri6ution.
-he return value@sA have an overall average o# 8.8
-he( are re.eata6le, in that a .articular in.ut value will alwa(s .roduce the same return value
-he( are statisticall( invariant under rotation @i.e., no matter how the domain is rotated, it has the same
statistical characterA
-he( have a statistical invariance under translation @i.e., no matter how the domain is translated, it has
the same statistical characterA
-he( t(.icall( give di##erent results under translation.
-he s.atial #re>uenc( is narrowl( concentrated, centered somewhere 6etween 8.% to 1.8.
-he( are !
1
continuous ever(where @i.e., the #irst derivative is continuousA
S$nta+ )escription
#loat noise1 @gen-(.e $A Returns a 1D noise value 6ased on the in.ut value $.
vec noiseC @gen-(.e $A Returns a D noise value 6ased on the in.ut value $.
vec& noiseD @gen-(.e $A Returns a &D noise value 6ased on the in.ut value $.
vec$ noiseE @gen-(.e $A Returns a $D noise value 6ased on the in.ut value $.
92
5 Shading Language Gra##ar
-he grammar is #ed #rom the out.ut o# le1ical anal(sis. -he tokens returned #rom le1ical anal(sis are
8TTRI+LTE CONST +OOL FLO8T INT LINT
+RE8O CONTINLE O ELSE FOR IF ISC8R RETLRN SPITCF C8SE EF8LLT
+VEC0 +VEC3 +VEC/ IVEC0 IVEC3 IVEC/ LVEC0 LVEC3 LVEC/ VEC0 VEC3 VEC/
98T0 98T3 98T/ CENTROI IN OLT INOLT LNIFOR9 V8RQIN!
NO@ERS@ECTIVE FL8T S9OOTF L8QOLT
98T0R0 98T0R3 98T0R/
98T3R0 98T3R3 98T3R/
98T/R0 98T/R3 98T/R/
S89@LER5 S89@LER0 S89@LER3 S89@LERCL+E S89@LER5SF8OP S89@LER0SF8OP
S89@LERCL+ESF8OP S89@LER58RR8Q S89@LER08RR8Q S89@LER58RR8QSF8OP
S89@LER08RR8QSF8OP IS89@LER5 IS89@LER0 IS89@LER3 IS89@LERCL+E
IS89@LER58RR8Q IS89@LER08RR8Q LS89@LER5 LS89@LER0 LS89@LER3
LS89@LERCL+E LS89@LER58RR8Q LS89@LER08RR8Q
S89@LER0RECT S89@LER0RECTSF8OP IS89@LER0RECT LS89@LER0RECT
S89@LER+LFFER IS89@LER+LFFER LS89@LER+LFFER
STRLCT VOI PFILE
IENTIFIER TQ@E_N89E FLO8TCONST8NT INTCONST8NT LINTCONST8NT +OOLCONST8NT
FIEL_SELECTION
LEFT_O@ RI!FT_O@
INC_O@ EC_O@ LE_O@ !E_O@ EM_O@ NE_O@
8N_O@ OR_O@ ROR_O@ 9LL_8SSI!N IV_8SSI!N 8_8SSI!N
9O_8SSI!N LEFT_8SSI!N RI!FT_8SSI!N 8N_8SSI!N ROR_8SSI!N OR_8SSI!N
SL+_8SSI!N
LEFT_@8REN RI!FT_@8REN LEFT_+R8COET RI!FT_+R8COET LEFT_+R8CE RI!FT_+R8CE OT
CO998 COLON EML8L SE9ICOLON +8N! 8SF TILE @LLS ST8R SL8SF @ERCENT
LEFT_8N!LE RI!FT_8N!LE VERTIC8L_+8R C8RET 89@ERS8N MLESTION
INV8RI8NT
FI!F_@RECISION 9EIL9_@RECISION LOP_@RECISION @RECISION
-he #ollowing descri6es the grammar #or the *.en/0 'hading 0anguage in terms o# the a6ove tokens.
varia2le_i&enti3ier:
D4N%'4R
#rimar+_e$#ression:
93
9 "&adin' (an'ua'e )ra##ar
varia2le_i&enti3ier
N%"0N.%GN%
BN%"0N.%GN%
'L0G%"0N.%GN%
,00L"0N.%GN%
L4'%_!GR4N e$#ression R1H%_!GR4N
#ost3i$_e$#ression:
#rimar+_e$#ression
#ost3i$_e$#ression L4'%_,RG"I4% integer_e$#ression R1H%_,RG"I4%
3unction_call
#ost3i$_e$#ression D0% '4LD_.4L4"%0N
#ost3i$_e$#ression N"_0!
#ost3i$_e$#ression D4"_0!
integer_e$#ression:
e$#ression
3unction_call:
3unction_call_or_met/o&
3unction_call_or_met/o&:
3unction_call_generic
#ost3i$_e$#ression D0% 3unction_call_generic
3unction_call_generic:
3unction_call_/ea&er_6it/_#arameters R1H%_!GR4N
3unction_call_/ea&er_no_#arameters R1H%_!GR4N
3unction_call_/ea&er_no_#arameters:
3unction_call_/ea&er V0D
3unction_call_/ea&er
3unction_call_/ea&er_6it/_#arameters:
3unction_call_/ea&er assignment_e$#ression
3unction_call_/ea&er_6it/_#arameters "0**G assignment_e$#ression
3unction_call_/ea&er:
3unction_i&enti3ier L4'%_!GR4N
94
9 "&adin' (an'ua'e )ra##ar
AA 1rammar Note: "onstructors loo- li-e 3unctions, 2ut le$ical anal+sis recogni7e& most o3 t/em as
AA -e+6or&s. %/e+ are no6 recogni7e& t/roug/ Jt+#e_s#eci3ierK.
3unction_i&enti3ier:
t+#e_s#eci3ier
D4N%'4R
'4LD_.4L4"%0N
unar+_e$#ression:
#ost3i$_e$#ression
N"_0! unar+_e$#ression
D4"_0! unar+_e$#ression
unar+_o#erator unar+_e$#ression
AA 1rammar Note: No tra&itional st+le t+#e casts.
unar+_o#erator:
!LB.
DG.H
,GN1
%LD4
AA 1rammar Note: No LML or LNL unar+ o#s. !ointers are not su##orte&.
multi#licative_e$#ression:
unar+_e$#ression
multi#licative_e$#ression .%GR unar+_e$#ression
multi#licative_e$#ression .LG.H unar+_e$#ression
multi#licative_e$#ression !4R"4N% unar+_e$#ression
a&&itive_e$#ression:
multi#licative_e$#ression
a&&itive_e$#ression !LB. multi#licative_e$#ression
a&&itive_e$#ression DG.H multi#licative_e$#ression
s/i3t_e$#ression:
a&&itive_e$#ression
s/i3t_e$#ression L4'%_0! a&&itive_e$#ression
s/i3t_e$#ression R1H%_0! a&&itive_e$#ression
95
9 "&adin' (an'ua'e )ra##ar
relational_e$#ression:
s/i3t_e$#ression
relational_e$#ression L4'%_GN1L4 s/i3t_e$#ression
relational_e$#ression R1H%_GN1L4 s/i3t_e$#ression
relational_e$#ression L4_0! s/i3t_e$#ression
relational_e$#ression 14_0! s/i3t_e$#ression
e8ualit+_e$#ression:
relational_e$#ression
e8ualit+_e$#ression 4O_0! relational_e$#ression
e8ualit+_e$#ression N4_0! relational_e$#ression
an&_e$#ression:
e8ualit+_e$#ression
an&_e$#ression G*!4R.GND e8ualit+_e$#ression
e$clusive_or_e$#ression:
an&_e$#ression
e$clusive_or_e$#ression "GR4% an&_e$#ression
inclusive_or_e$#ression:
e$clusive_or_e$#ression
inclusive_or_e$#ression V4R%"GL_,GR e$clusive_or_e$#ression
logical_an&_e$#ression:
inclusive_or_e$#ression
logical_an&_e$#ression GND_0! inclusive_or_e$#ression
logical_$or_e$#ression:
logical_an&_e$#ression
logical_$or_e$#ression P0R_0! logical_an&_e$#ression
logical_or_e$#ression:
logical_$or_e$#ression
logical_or_e$#ression 0R_0! logical_$or_e$#ression
con&itional_e$#ression:
logical_or_e$#ression
logical_or_e$#ression OB4.%0N e$#ression "0L0N assignment_e$#ression
96
9 "&adin' (an'ua'e )ra##ar
assignment_e$#ression:
con&itional_e$#ression
unar+_e$#ression assignment_o#erator assignment_e$#ression
assignment_o#erator:
4OBGL
*BL_G..1N
DV_G..1N
*0D_G..1N
GDD_G..1N
.B,_G..1N
L4'%_G..1N
R1H%_G..1N
GND_G..1N
P0R_G..1N
0R_G..1N
e$#ression:
assignment_e$#ression
e$#ression "0**G assignment_e$#ression
constant_e$#ression:
con&itional_e$#ression
&eclaration:
3unction_#rotot+#e .4*"0L0N
init_&eclarator_list .4*"0L0N
!R4".0N #recision_8uali3ier t+#e_s#eci3ier_no_#rec .4*"0L0N
t+#e_8uali3ier D4N%'4R L4'%_,RG"4 struct_&eclaration_list R1H%_,RG"4 .4*"0L0N
t+#e_8uali3ier .4*"0L0N
3unction_#rotot+#e:
3unction_&eclarator R1H%_!GR4N
3unction_&eclarator:
3unction_/ea&er
3unction_/ea&er_6it/_#arameters
3unction_/ea&er_6it/_#arameters:
97
9 "&adin' (an'ua'e )ra##ar
3unction_/ea&er #arameter_&eclaration
3unction_/ea&er_6it/_#arameters "0**G #arameter_&eclaration
3unction_/ea&er:
3ull+_s#eci3ie&_t+#e D4N%'4R L4'%_!GR4N
#arameter_&eclarator:
t+#e_s#eci3ier D4N%'4R
t+#e_s#eci3ier D4N%'4R L4'%_,RG"I4% constant_e$#ression R1H%_,RG"I4%
#arameter_&eclaration:
#arameter_t+#e_8uali3ier #arameter_8uali3ier #arameter_&eclarator
#arameter_8uali3ier #arameter_&eclarator
#arameter_t+#e_8uali3ier #arameter_8uali3ier #arameter_t+#e_s#eci3ier
#arameter_8uali3ier #arameter_t+#e_s#eci3ier
#arameter_8uali3ier:
AM em#t+ MA
N
0B%
N0B%
#arameter_t+#e_s#eci3ier:
t+#e_s#eci3ier
init_&eclarator_list:
single_&eclaration
init_&eclarator_list "0**G D4N%'4R
init_&eclarator_list "0**G D4N%'4R L4'%_,RG"I4% R1H%_,RG"I4%
init_&eclarator_list "0**G D4N%'4R L4'%_,RG"I4% constant_e$#ression
R1H%_,RG"I4%
init_&eclarator_list "0**G D4N%'4R L4'%_,RG"I4%
R1H%_,RG"I4% 4OBGL initiali7er
init_&eclarator_list "0**G D4N%'4R L4'%_,RG"I4% constant_e$#ression
R1H%_,RG"I4% 4OBGL initiali7er
init_&eclarator_list "0**G D4N%'4R 4OBGL initiali7er
single_&eclaration:
3ull+_s#eci3ie&_t+#e
3ull+_s#eci3ie&_t+#e D4N%'4R
98
9 "&adin' (an'ua'e )ra##ar
3ull+_s#eci3ie&_t+#e D4N%'4R L4'%_,RG"I4% R1H%_,RG"I4%
3ull+_s#eci3ie&_t+#e D4N%'4R L4'%_,RG"I4% constant_e$#ression R1H%_,RG"I4%
3ull+_s#eci3ie&_t+#e D4N%'4R L4'%_,RG"I4% R1H%_,RG"I4% 4OBGL initiali7er
3ull+_s#eci3ie&_t+#e D4N%'4R L4'%_,RG"I4% constant_e$#ression
R1H%_,RG"I4% 4OBGL initiali7er
3ull+_s#eci3ie&_t+#e D4N%'4R 4OBGL initiali7er
NVGRGN% D4N%'4R AA Verte$ onl+.
AA 1rammar Note: No LenumL, or Lt+#e&e3L.
3ull+_s#eci3ie&_t+#e:
t+#e_s#eci3ier
t+#e_8uali3ier t+#e_s#eci3ier
invariant_8uali3ier:
NVGRGN%
inter#olation_8uali3ier:
.*00%H
'LG%
N0!4R.!4"%V4
la+out_8uali3ier:
LGQ0B% L4'%_!GR4N la+out_list R1H%_!GR4N
la+out_list:
D4N%'4R
la+out_list "0**G D4N%'4R
#arameter_t+#e_8uali3ier:
"0N.%
t+#e_8uali3ier:
storage_8uali3ier
la+out_8uali3ier
la+out_8uali3ier storage_8uali3ier
inter#olation_8uali3ier t+#e_8uali3ier
invariant_8uali3ier t+#e_8uali3ier
invariant_8uali3ier inter#olation_8uali3ier t+#e_8uali3ier
99
9 "&adin' (an'ua'e )ra##ar
storage_8uali3ier:
"0N.%
G%%R,B%4 AA Verte$ onl+.
VGRQN1
"4N%R0D VGRQN1
N
0B%
"4N%R0D N
"4N%R0D 0B%
BN'0R*
t+#e_s#eci3ier:
t+#e_s#eci3ier_no_#rec
#recision_8uali3ier t+#e_s#eci3ier_no_#rec
t+#e_s#eci3ier_no_#rec:
t+#e_s#eci3ier_nonarra+
t+#e_s#eci3ier_nonarra+ L4'%_,RG"I4% R1H%_,RG"I4%
t+#e_s#eci3ier_nonarra+ L4'%_,RG"I4% constant_e$#ression R1H%_,RG"I4%
t+#e_s#eci3ier_nonarra+:
V0D
'L0G%
N%
BN%
,00L
V4"2
V4"@
V4"4
,V4"2
,V4"@
,V4"4
V4"2
V4"@
V4"4
BV4"2
BV4"@
100
9 "&adin' (an'ua'e )ra##ar
BV4"4
*G%2
*G%@
*G%4
*G%2P2
*G%2P@
*G%2P4
*G%@P2
*G%@P@
*G%@P4
*G%4P2
*G%4P@
*G%4P4
.G*!L4R1D
.G*!L4R2D
.G*!L4R@D
.G*!L4R"B,4
.G*!L4R1D.HGD0R
.G*!L4R2D.HGD0R
.G*!L4R"B,4.HGD0R
.G*!L4R1DGRRGQ
.G*!L4R2DGRRGQ
.G*!L4R1DGRRGQ.HGD0R
.G*!L4R2DGRRGQ.HGD0R
.G*!L4R1D
.G*!L4R2D
.G*!L4R@D
.G*!L4R"B,4
.G*!L4R1DGRRGQ
.G*!L4R2DGRRGQ
B.G*!L4R1D
B.G*!L4R2D
B.G*!L4R@D
B.G*!L4R"B,4
B.G*!L4R1DGRRGQ
B.G*!L4R2DGRRGQ
.G*!L4R2DR4"%
101
9 "&adin' (an'ua'e )ra##ar
.G*!L4R2DR4"%.HGD0R
.G*!L4R2DR4"%
B.G*!L4R2DR4"%
.G*!L4R,B''4R
.G*!L4R,B''4R
B.G*!L4R,B''4R
struct_s#eci3ier
%Q!4_NG*4
#recision_8uali3ier:
H1H_!R4".0N
*4DB*_!R4".0N
L0R_!R4".0N
struct_s#eci3ier:
.%RB"% D4N%'4R L4'%_,RG"4 struct_&eclaration_list R1H%_,RG"4
.%RB"% L4'%_,RG"4 struct_&eclaration_list R1H%_,RG"4
struct_&eclaration_list:
struct_&eclaration
struct_&eclaration_list struct_&eclaration
struct_&eclaration:
t+#e_s#eci3ier struct_&eclarator_list .4*"0L0N
t+#e_8uali3ier t+#e_s#eci3ier struct_&eclarator_list .4*"0L0N
struct_&eclarator_list:
struct_&eclarator
struct_&eclarator_list "0**G struct_&eclarator
struct_&eclarator:
D4N%'4R
D4N%'4R L4'%_,RG"I4% constant_e$#ression R1H%_,RG"I4%
initiali7er:
assignment_e$#ression
&eclaration_statement:
&eclaration
statement:
com#oun&_statement
102
9 "&adin' (an'ua'e )ra##ar
sim#le_statement
AA 1rammar Note: la2ele& statements 3or .R%"H onl+9 LgotoL is not su##orte&.
sim#le_statement:
&eclaration_statement
e$#ression_statement
selection_statement
s6itc/_statement
case_la2el
iteration_statement
<um#_statement
com#oun&_statement:
L4'%_,RG"4 R1H%_,RG"4
L4'%_,RG"4 statement_list R1H%_,RG"4
statement_no_ne6_sco#e:
com#oun&_statement_no_ne6_sco#e
sim#le_statement
com#oun&_statement_no_ne6_sco#e:
L4'%_,RG"4 R1H%_,RG"4
L4'%_,RG"4 statement_list R1H%_,RG"4
statement_list:
statement
statement_list statement
e$#ression_statement:
.4*"0L0N
e$#ression .4*"0L0N
selection_statement:
' L4'%_!GR4N e$#ression R1H%_!GR4N selection_rest_statement
selection_rest_statement:
statement 4L.4 statement
statement
103
9 "&adin' (an'ua'e )ra##ar
con&ition:
e$#ression
3ull+_s#eci3ie&_t+#e D4N%'4R 4OBGL initiali7er
s6itc/_statement:
.R%"H L4'%_!GR4N e$#ression R1H%_!GR4N L4'%_,RG"4 s6itc/_statement_list
R1H%_,RG"4
s6itc/_statement_list:
AM not/ing MA
statement_list
case_la2el:
"G.4 e$#ression "0L0N
D4'GBL% "0L0N
iteration_statement:
RHL4 L4'%_!GR4N con&ition R1H%_!GR4N statement_no_ne6_sco#e
D0 statement RHL4 L4'%_!GR4N e$#ression R1H%_!GR4N .4*"0L0N
'0R L4'%_!GR4N 3or_init_statement 3or_rest_statement R1H%_!GR4N
statement_no_ne6_sco#e
3or_init_statement:
e$#ression_statement
&eclaration_statement
con&itiono#t:
con&ition
AM em#t+ MA
3or_rest_statement:
con&itiono#t .4*"0L0N
con&itiono#t .4*"0L0N e$#ression
<um#_statement:
"0N%NB4 .4*"0L0N
,R4GI .4*"0L0N
R4%BRN .4*"0L0N
R4%BRN e$#ression .4*"0L0N
D."GRD .4*"0L0N AA 'ragment s/a&er onl+.
AA 1rammar Note: No LgotoL. 1otos are not su##orte&.
104
9 "&adin' (an'ua'e )ra##ar
translation_unit:
e$ternal_&eclaration
translation_unit e$ternal_&eclaration
e$ternal_&eclaration:
3unction_&e3inition
&eclaration
3unction_&e3inition:
3unction_#rotot+#e com#oun&_statement_no_ne6_sco#e

105