OpenGL(R) Shading Language (2nd Edition) [2 ed.] 0321334892, 9780321334893

Please anyone tell me where it is. I only find source code for 2nd edition

286 3 7MB

English Pages 637 Year 2006

Report DMCA / Copyright

DOWNLOAD PDF FILE

Recommend Papers

OpenGL(R) Shading Language (2nd Edition) [2 ed.]
 0321334892, 9780321334893

  • 0 0 0
  • Like this paper and download? You can publish your own PDF file online for free in a few minutes! Sign Up
File loading please wait...
Citation preview

OpenGL® Shading Language, Second Edition By Randi J. Rost ............................................... Publisher: Addison W e sle y Pr ofe ssion a l Pub Dat e: Ja n u a r y 2 5 , 2 0 0 6 Print I SBN- 10: 0 - 3 2 1 - 3 3 4 8 9 - 2 Print I SBN- 13: 9 7 8 - 0 - 3 2 1 - 3 3 4 8 9 - 3 Pages: 8 0 0

Table of Cont ent s | I ndex

" As t he 'Red Book' is known t o be t he gold st andard for OpenGL, t he 'Or ange Book' is considered t o be t he gold st andard for t he OpenGL Shading Language. Wit h Randi's ext ensive knowledge of OpenGL and GLSL, you can be assured you will be learning from a gr aphics indust ry vet eran. Wit hin t he pages of t he second edit ion you can find t opics from beginning shader developm ent t o advanced t opics such as t he spherical harm onic light ing m odel and m ore." David Tom m eraasen, CEO/ Program m er, Plasm a Soft ware " This will be t he definit ive guide for OpenGL shaders; no ot her book goes int o t his det ail. Rost has done an excellent j ob at set t ing t he st age for shader developm ent , what t he purpose is, how t o do it , and how it all fit s t oget her. The book includes great exam ples and det ails, and good addit ional coverage of 2.0 changes! " Jeffery Galinovsky, Direct or of Em erging Market Plat form Developm ent , I nt el Corporat ion " The coverage in t his new edit ion of t he book is pit ched j ust right t o help m any new shaderwrit ers get st art ed, but wit h enough deep inform at ion for t he 'old hands.'" Marc Olano, Assist ant Professor, Universit y of Maryland " This is a really great book on GLSLwell writ t en and organized, very accessible, and wit h good real- world exam ples and sam ple code. The t opics flow nat urally and easily, explanat ory code fragm ent s are insert ed in very logical places t o illust rat e concept s, and all in all, t his book m akes an excellent t ut orial as w ell as a reference." John Car ey, Chief Technology Officer, C.O.R.E. Feat ure Anim at ion Ope n GL® Sh a din g La n gu a ge , Se con d Edit ion , ext ensively updat ed for OpenGL 2.0, is t he experienced applicat ion program m er's guide t o writ ing shaders. Part reference, part t ut orial, t his book t horoughly explains t he shift from fixed- funct ionalit y gr aphics hardware t o t he new era of program m able graphics hardw are and t he addit ions t o t he OpenGL API t hat support t his program m abilit y. Wit h OpenGL and shaders writ t en in t he OpenGL Shading Language, applicat ions can perform bet t er, achieving st unning graphics effect s by using t he capabilit ies of bot h t he visual processing unit and t he cent ral processing unit . I n t his book, you will find a det ailed int roduct ion t o t he OpenGL Shading Language ( GLSL) and t he new OpenGL funct ion calls t hat support it . The t ext begins by describing t he synt ax and sem ant ics of t his high- level program m ing language. Once t his foundat ion has been est ablished, t he book explores t he creat ion and m anipulat ion of shader s using new OpenGL funct ion calls. Ope n GL® Sh a din g La n gu a ge , Se con d Edit ion , includes updat ed descript ions for t he language and all t he GLSL ent ry point s added t o OpenGL 2.0; new chapt ers t hat discuss

light ing, shadows, and surface charact erist ics; and an under - t he- hood look at t he im plem ent at ion of RealWorldz, t he m ost am bit ious GLSL applicat ion t o dat e. The second edit ion also feat ures 18 ext ensive new exam ples of shaders and t heir underlying algorit hm s, including z

I m age- based light ing

z

Light ing wit h spherical harm onics

z

Am bient occlusion

z

Shadow m apping

z

Volum e shadows using deferred light ing

z

War d's BRDF m odel

The color plat e sect ion illust rat es t he power and sophist icat ion of t he OpenGL Shading Language. The API Funct ion Reference at t he end of t he book is an excellent guide t o t he API ent ry point s t hat support t he OpenGL Shading Language. Also included is a convenient Quick Reference Card t o GLSL.

OpenGL® Shading Language, Second Edition By Randi J. Rost ............................................... Publisher: Addison W e sle y Pr ofe ssion a l Pub Dat e: Ja n u a r y 2 5 , 2 0 0 6 Print I SBN- 10: 0 - 3 2 1 - 3 3 4 8 9 - 2 Print I SBN- 13: 9 7 8 - 0 - 3 2 1 - 3 3 4 8 9 - 3 Pages: 8 0 0

Table of Cont ent s | I ndex

Copyright Praise for OpenGL® Shading Language, Second Edition Praise for the First Edition of OpenGL® Shading Language Foreword Foreword to the First Edition Preface Intended Audience About This Book About the Shader Examples Errata Typographical Conventions About the Author About the Contributors Acknowledgments Chapter 1. Review of OpenGL Basics Section 1.1. OpenGL History Section 1.2. OpenGL Evolution Section 1.3. Execution Model Section 1.4. The Frame Buffer Section 1.5. State Section 1.6. Processing Pipeline Section 1.7. Drawing Geometry Section 1.8. Drawing Images Section 1.9. Coordinate Transforms Section 1.10. Texturing Section 1.11. Summary Section 1.12. Further Information Chapter 2. Basics Section 2.1. Introduction to the OpenGL Shading Language Section 2.2. Why Write Shaders? Section 2.3. OpenGL Programmable Processors Section 2.4. Language Overview Section 2.5. System Overview Section 2.6. Key Benefits Section 2.7. Summary Section 2.8. Further Information Chapter 3. Language Definition Section 3.1. Example Shader Pair Section 3.2. Data Types Section 3.3. Initializers and Constructors Section 3.4. Type Conversions Section 3.5. Qualifiers and Interface to a Shader

Section 3.6. Flow Control Section 3.7. Operations Section 3.8. Preprocessor Section 3.9. Preprocessor Expressions Section 3.10. Error Handling Section 3.11. Summary Section 3.12. Further Information Chapter 4. The OpenGL Programmable Pipeline Section 4.1. The Vertex Processor Section 4.2. The Fragment Processor Section 4.3. Built-in Uniform Variables Section 4.4. Built-in Constants Section 4.5. Interaction with OpenGL Fixed Functionality Section 4.6. Summary Section 4.7. Further Information Chapter 5. Built-in Functions Section 5.1. Angle and Trigonometry Functions Section 5.2. Exponential Functions Section 5.3. Common Functions Section 5.4. Geometric Functions Section 5.5. Matrix Functions Section 5.6. Vector Relational Functions Section 5.7. Texture Access Functions Section 5.8. Fragment Processing Functions Section 5.9. Noise Functions Section 5.10. Summary Section 5.11. Further Information Chapter 6. Simple Shading Example Section 6.1. Brick Shader Overview Section 6.2. Vertex Shader Section 6.3. Fragment Shader Section 6.4. Observations Section 6.5. Summary Section 6.6. Further Information Chapter 7. OpenGL Shading Language API Section 7.1. Obtaining Version Information Section 7.2. Creating Shader Objects Section 7.3. Compiling Shader Objects Section 7.4. Linking and Using Shaders Section 7.5. Cleaning Up Section 7.6. Query Functions Section 7.7. Specifying Vertex Attributes Section 7.8. Specifying Uniform Variables Section 7.9. Samplers Section 7.10. Multiple Render Targets Section 7.11. Development Aids Section 7.12. Implementation-Dependent API Values Section 7.13. Application Code for Brick Shaders Section 7.14. Summary Section 7.15. Further Information Chapter 8. Shader Development Section 8.1. General Principles Section 8.2. Performance Considerations Section 8.3. Shader Debugging

Section 8.4. Shader Development Tools Section 8.5. Scene Graphs Section 8.6. Summary Section 8.7. Further Information Chapter 9. Emulating OpenGL Fixed Functionality Section 9.1. Transformation Section 9.2. Light Sources Section 9.3. Material Properties and Lighting Section 9.4. Two-Sided Lighting Section 9.5. No Lighting Section 9.6. Fog Section 9.7. Texture Coordinate Generation Section 9.8. User Clipping Section 9.9. Texture Application Section 9.10. Summary Section 9.11. Further Information Chapter 10. Stored Texture Shaders Section 10.1. Access to Texture Maps from a Shader Section 10.2. Simple Texturing Example Section 10.3. Multitexturing Example Section 10.4. Cube Mapping Example Section 10.5. Another Environment Mapping Example Section 10.6. Glyph Bombing Section 10.7. Summary Section 10.8. Further Information Chapter 11. Procedural Texture Shaders Section 11.1. Regular Patterns Section 11.2. Toy Ball Section 11.3. Lattice Section 11.4. Bump Mapping Section 11.5. Summary Section 11.6. Further Information Chapter 12. Lighting Section 12.1. Hemisphere Lighting Section 12.2. Image-Based Lighting Section 12.3. Lighting with Spherical Harmonics Section 12.4. The ÜberLight Shader Section 12.5. Summary Section 12.6. Further Information Chapter 13. Shadows Section 13.1. Ambient Occlusion Section 13.2. Shadow Maps Section 13.3. Deferred Shading for Volume Shadows Section 13.4. Summary Section 13.5. Further Information Chapter 14. Surface Characteristics Section 14.1. Refraction Section 14.2. Diffraction Section 14.3. BRDF Models Section 14.4. Polynomial Texture Mapping with BRDF Data Section 14.5. Summary Section 14.6. Further Information Chapter 15. Noise Section 15.1. Noise Defined

Section 15.2. Noise Textures Section 15.3. Trade-offs Section 15.4. A Simple Noise Shader Section 15.5. Turbulence Section 15.6. Granite Section 15.7. Wood Section 15.8. Summary Section 15.9. Further Information Chapter 16. Animation Section 16.1. On/Off Section 16.2. Threshold Section 16.3. Translation Section 16.4. Morphing Section 16.5. Other Blending Effects Section 16.6. Vertex Noise Section 16.7. Particle Systems Section 16.8. Wobble Section 16.9. Summary Section 16.10. Further Information Chapter 17. Antialiasing Procedural Textures Section 17.1. Sources of Aliasing Section 17.2. Avoiding Aliasing Section 17.3. Increasing Resolution Section 17.4. Antialiased Stripe Example Section 17.5. Frequency Clamping Section 17.6. Summary Section 17.7. Further Information Chapter 18. Non-Photorealistic Shaders Section 18.1. Hatching Example Section 18.2. Technical Illustration Example Section 18.3. Mandelbrot Example Section 18.4. Summary Section 18.5. Further Information Chapter 19. Shaders for Imaging Section 19.1. Geometric Image Transforms Section 19.2. Mathematical Mappings Section 19.3. Lookup Table Operations Section 19.4. Color Space Conversions Section 19.5. Image Interpolation and Extrapolation Section 19.6. Blend Modes Section 19.7. Convolution Section 19.8. Summary Section 19.9. Further Information Chapter 20. RealWorldz Section 20.1. Features Section 20.2. RealWorldz Internals Section 20.3. Implementation Section 20.4. Atmospheric Effects Section 20.5. Ocean Section 20.6. Clouds Section 20.7. Summary Section 20.8. Further Information Chapter 21. Language Comparison Section 21.1. Chronology of Shading Languages

Section 21.2. RenderMan Section 21.3. OpenGL Shader (ISL) Section 21.4. HLSL Section 21.5. Cg Section 21.6. Summary Section 21.7. Further Information Appendix A. Language Grammar Appendix B. API Function Reference Implementation-Dependent API Values for GLSL Other Queriable Values for GLSL glAttachShader glBindAttribLocation glCompileShader glCreateProgram glCreateShader glDeleteProgram glDeleteShader glDetachShader glDrawBuffers glEnableVertexAttribArray glGetActiveAttrib glGetActiveUniform glGetAttachedShaders glGetAttribLocation glGetProgram glGetProgramInfoLog glGetShader glGetShaderInfoLog glGetShaderSource glGetUniform glGetUniformLocation glGetVertexAttrib glGetVertexAttribPointer glIsProgram glIsShader glLinkProgram glShaderSource glUniform glUseProgram glValidateProgram glVertexAttrib glVertexAttribPointer OpenGL 1.5 to OpenGL 2.0 GLSL Migration Guide Afterword Glossary Further Reading Index

Copyright Many of t he designat ions used by m anufact urers and sellers t o dist inguish t heir product s are clai t radem arks. Where t hose designat ions appear in t his book, and t he publisher was aware of a t ra claim , t he designat ions have been print ed wit h init ial capit al let t ers or in all capit als. The aut hor and publisher have t aken care in t he preparat ion of t his book, but m ake no expresse im plied warrant y of any kind and assum e no responsibilit y for errors or om issions. No liabilit y is assum ed for incident al or consequent ial dam ages in connect ion wit h or arising out of t he use of t infor m at ion or progr am s cont ained herein. Hew let t - Packard Com pany m akes no warrant y as t o t he accuracy or com plet eness of t he m at eria included in t his t ext and hereby disclaim s any responsibilit y t herefore. The publisher offers excellent discount s on t his book when ordered in quant it y for bulk purchases special sales, which m ay include elect ronic versions and/ or cust om covers and cont ent part icular your business, t raining goals, m arket ing focus, and branding int er est s. For m ore inform at ion, ple cont act : U.S. Corporat e and Governm ent Sales ( 800) 382- 3419 corpsales@pear sont echgroup.com For sales out side t he U.S., please cont act : I nt ernat ional Sales int ernat ional@pear soned.com Visit us on t he Web: www .awprofessional.com

Library of Congress Cat aloging- in- Publicat ion Dat a Rost , Randi J., 1960 OpenGL shading language / Randi J. Rost ; wit h cont ribut ions by John M. Kessenich . . . [ et al.] . p. cm . I ncludes bibliographical references and index. I SBN 0- 321- 33489- 2 ( pbk. : alk. paper) 1. Com put er graphics. 2. OpenGL. I . Kessenich, John M. I I . Tit le. T385.R665 2006 006.6'86dc22 2005029650 Copyright © 2006 Pearson Educat ion, I nc. Chapt er 3 © 2003 John M. Kessenich Port ions of Chapt er 4 © 2003 Bart hold Licht enbelt All right s reserved. Print ed in t he Unit ed St at es of Am erica. This publicat ion is prot ect ed by copy and perm ission m ust be obt ained fr om t he publisher prior t o any pr ohibit ed reproduct ion, st orag ret rieval syst em , or t ransm ission in any form or by any m eans, elect ronic, m echanical, phot ocop

recording, or likewise. For inform at ion regarding perm issions, writ e t o:

Pear son Educat ion, I nc Right s and Cont ract s Depart m ent 75 Arlingt on St reet , Suit e 300 Bost on, MA 02116 Fax ( 617) 848- 7047 Text print ed in t he Unit ed St at es on recycled paper at Courier in St ought on, Massachuset t s. First print ing, January 2006

Dedication To Baby Cakes, Baby Doll, Love Bug, and Lit t le Zookat hanks for your love and support To Mom and Popm y first and best t eachers

Praise for OpenGL® Shading Language, Second Edition " As t he 'Red Book' is known t o be t he gold st andard for OpenGL, t he 'Orange Book' is considered t o be t he gold st andard for t he OpenGL Shading Language. Wit h Randi's ext ensive knowledge of OpenGL and GLSL, you can be assured you will be learning from a gr aphics indust ry vet eran. Wit hin t he pages of t he second edit ion you can find t opics from beginning shader developm ent t o advanced t opics such as t he spherical harm onic light ing m odel and m ore." David Tom m eraasen CEO/ Program m er Plasm a Soft ware " This will be t he definit ive guide for OpenGL shaders; no ot her book goes int o t his det ail. Rost has done an excellent j ob at set t ing t he st age for shader developm ent , what t he purpose is, how t o do it , and how it all fit s t oget her. The book includes great exam ples and det ails, and good addit ional coverage of 2.0 changes! " Jeffery Galinovsky Direct or of Em erging Market Plat form Developm ent I nt el Corporat ion " The coverage in t his new edit ion of t he book is pit ched j ust right t o help m any new shaderwrit ers get st art ed, but wit h enough deep inform at ion for t he 'old hands.'" Marc Olano Assist ant Professor Universit y of Maryland " This is a really great book on GLSLwell writ t en and organized, very accessible, and wit h good real- world exam ples and sam ple code. The t opics flow nat urally and easily, explanat ory code fragm ent s are insert ed in very logical places t o illust rat e concept s, and all in all, t his book m akes an excellent t ut orial as w ell as a reference." John Car ey Chief Technology Officer C.O.R.E. Feat ure Anim at ion

Praise for the First Edition of OpenGL® Shading Language " The aut hor has done an excellent j ob at set t ing t he st age for shader developm ent , what t he purpose is, how t o do it , and how it all fit s t oget her. He t hen develops on t he advanced t opics covering a great breadt h in t he appropriat e level of det ail. Tr uly a necessary book t o own for any graphics developer! " Jeffery Galinovsky St rat egic Soft ware Program Manager, I nt el Corporat ion " OpenGL® Shading Language provides a t im ely, t horough, and ent ert aining int roduct ion t o t he only OpenGL ARB- approved high- level shading language in exist ence. Whet her an expert or a novice, t here are gem s t o be discovered t hroughout t he book, and t he reference pages will be your const ant com panion as you dig int o t he dept hs of t he shading API s. From algorit hm s t o API s, t his book has you covered." Bob Kuehne CEO, Blue Newt Soft ware " Com put er graphics and rendering t echnologies j ust t ook a giant leap for ward wit h hardw are vendors rapidly adopt ing t he new OpenGL Shading Language. This book present s a det ailed t reat m ent of t hese excit ing t echnologies in a w ay t hat is ext r em ely helpful for visualizat ion and gam e developers." Andy McGovern Founder Virt ual Geographies, I nc. " The OpenGL Shading Language is at t he epicent er of t he program m able graphics revolut ion, and Randi Rost has been at t he cent er of t he developm ent of t his significant new indust ry st andard. I f you need t he inside t rack on how t o use t he OpenGL Shading Language t o unleash new visual effect s and unlock t he supercom put er hiding inside t he new generat ion of graphics hardware, t hen t his is t he book for you." Neil Trevet t Senior Vice President Market Developm ent 3Dlabs

Foreword To m e, gr aphics shaders are about t he coolest t hings t o ever happen in com put er graphics. I grew up in gr aphics in t he 1970s, wat ching t he m ost am azing people do t he m ost am azing t hings wit h t he m at hem at ics of graphics. I rem em ber Jim Blinn's bum p- m apping t echnique, for inst ance, and what effect s it was able t o creat e. The m et hod was decept ively sim ple, but t he visual im pact was m om ent ous. True, it t ook a subst ant ial am ount of t im e for a com put er t o work t hrough t he pixel- by- pixel soft ware process t o m ake t hat result ing im age, but we only cared about t hat a lit t le bit . I t was t he effect t hat m at t ered. My m em ory now fast - forwards t o t he 1980s. Speed becam e a m aj or issue, wit h pract it ioners like Jim Clark working on placing graphics algorit hm s in silicon. This result ed in t he blossom ing of com panies such as Evans & Sut herland and Silicon Graphics. They brought fast , int eract ive 3D gr aphics t o t he m asses, but t he com prom ise was t hat t hey forced us int o doing our work using st andard API s t hat could easily be hardware support ed. Deep- down procedural t echniques such as bum p- m apping could not follow where t he hardware was leading. But t he am azing t echniques survived in soft ware. Rob Cook's classic paper on shade t r ees brought at t ent ion t o t he idea of using soft ware " shaders" t o perform t he pixel- by - pixel com put at ions t hat could deliver t he great effect s. This was em bodied by t he Phot orealist ic Render Man rendering soft w are. The book Render Man Com panion by St eve Upst ill is st ill t he first reference t hat I point m y st udent s t o when t hey want t o learn about t he inner workings of shaders. The abilit y t o achieve such fine- grained cont rol over t he graphics rendering process gave RenderMan users t he abilit y t o creat e t he dazzling, realist ic effect s seen in Pixar anim at ion short s and TV com m ercials. The process was st ill m iles away from real t im e, but t he seed of t he idea of giving an int eract ive applicat ion developer t hat t ype of cont rol was plant ed. And it was such a powerful idea t hat it was only a m at t er of t im e unt il it grew. Now, fast - forward t o t he st art of t he new m illennium . The m aj or influence on graphics was no longer science and engineering applicat ions. I t had becom e gam es and ot her form s of ent ert ainm ent . ( Nowhere has t his been m ore obvious t han in t he com posit ion of t he SI GGRAPH Exhibit ion.) Because gam es live and die by t heir abilit y t o deliver realist ic effect s at int eract ive speeds, t he shader seed plant ed a few years earlier was ready t o flourish in t his new dom ain. The capacit y t o place procedural graphics rendering algorit hm s int o t he graphics hardware was definit ely an idea whose t im e had com e. I nt erest ingly, it brought t he graphics com m unit y full circle. We sear ched old SI GGRAPH proceedings t o see how pixel- by- pixel scene cont rol was perform ed in soft ware t hen, so we could " re- invent " it using int eract ive shader code. So, here we are in t he present , reading Randi Rost 's OpenGL® Shading Language. This is t he next book I point m y shader- int rigued st udent s t o, aft er Upst ill's. I t is also t he one t hat I , and t hey, use m ost oft en day t o day. By now, m y first edit ion is pret t y worn. But great newsI have an excuse t o replace it ! This second edit ion is a m aj or enhancem ent over t he first . This is m ore t han j ust er rat a correct ions. There is subst ant ial new m at erial in t his book. New chapt ers on light ing, shadows, surface charact erist ics, and RealWorldz are essent ial for serious effect s program m ers. There are also 18 new shader exam ples. The ones I especially like are shadow m apping, vert ex noise, im age- based light ing, and environm ent al m apping wit h cube m aps. But t hey are all really good, and you will find t hem all useful. The OpenGL Shading Language is now part of st andard OpenGL. I t will be used everywhere. There is no r eason not t o. Anybody int erest ed in effect s graphics program m ing will want t o read t his book cover t o cover. There are m any nugget s t o uncover. But GLSL is useful even beyond t hose borders. For exam ple, w e use it in our visualizat ion research her e at OSU ( dom e t ransform at ion, line int egral convolut ion, im age com pression, t er rain dat a m apping, et c.) . I know t hat GLSL will find considerable applicat ions in m any ot her non- gam e areas as well.

I want t o express m y appreciat ion t o Randi, who obviously st art ed w orking on t he first edit ion of t his book even before t he GLSL specificat ion was fully decided upon. This m ust have m ade t he book ext ra difficult t o writ e, but it let t he rest of us j um p on t he inform at ion as soon as it was st able. Thanks, t oo, for t his second edit ion. I t will m ake a significant cont ribut ion t o t he shader- progr am m ing com m unit y, and we appreciat e it . Mike Bailey, Ph.D. Professor, Com put er Science Oregon St at e Universit y

Foreword to the First Edition This book is an am azing m easure of how far and how fast int eract ive shading has advanced. Not t oo m any years ago, procedural shading was som et hing done only in offline product ion rendering, creat ing som e of t he great results we all know from t he m ovies, but w ere not anywhere close t o int eract ive. Then a few research proj ect s appeared, allow ing a slight ly m odified but largely int act t ype of procedural shading t o run in real t im e. Finally, in a rush, widely accessible com m ercial syst em s st art ed t o support shading. Today, we've com e t o t he point where a real- t im e shading language developed by a cross- vendor group of OpenGL par t icipant s has achieved official designat ion as an OpenGL Archit ect ure Review Board approved ext ension. This book, writ t en by one of t hose m ost responsible for spearheading t he developm ent and accept ance of t he OpenGL shading language, is your guide t o t hat language and t he ext ensions t o OpenGL t hat let you use it . I cam e t o m y int erest in procedural shading from a st range direct ion. I n 1990, I st art ed graduat e school at t he Universit y of Nort h Carolina in Chapel Hill because it seem ed like a good place for som eone w hose prim ary int erest was int eract ive 3D graphics. There, I st art ed working on t he Pixel- Planes proj ect . This proj ect had produced a new graphics m achine wit h several int erest ing feat ures beyond it s perfor m ance at r endering large num ber s of polygons per second. One feat ure in part icular had an enorm ous im pact on t he research direct ions I 've followed for t he past 13 years. Pixel- Planes 5 had program m able pixel processorslot s of t hem . Program m ing t hese processors was sim ilar in m any ways t o t he assem bly- language fragm ent program s t hat have burst ont o t he graphics scene in t he past few years. Program m ing t hem was exhilarat ing, yet also t horoughly exasperat ing. I was far fr om t he only person t o not ice bot h t he power and pain of writ ing low- level code t o execut e per- pixel. Anot her group wit hin t he Pixel- Planes t eam built an assem bler for shading code t o m ake it a lit t le easier t o writ e, alt hough it was st ill bot h difficult t o writ e a good shader and ever- so- rewarding once you had it working. The shaders produced will be fam iliar t o anyone who has seen dem os of any of t he lat est graphics product s, and not surprisingly you'll find versions of m any of t hem in t his book: wood, clouds, brick, rock, reflect ive wavy wat er, and ( of course) t he Mandelbrot fract al set . The rewards and difficult ies present ed by Pixel- Planes 5 shaders guided m any of t he design decisions behind t he next m achine, PixelFlow. PixelFlow was designed and built by a universit y/ indust ry part nership wit h indust rial part icipat ion first by Division, t hen by Hewlet t Packard. The result was t he first int eract ive syst em capable of running procedural shaders com piled fr om a high- level shading language. PixelFlow was dem onst rat ed at t he SI GGRAPH conference in 1997. For a few years t hereaft er, if you were fort unat e enough t o be at UNCChapel Hill, you could writ e procedural shaders and run t hem in real- t im e when no one else could. And, of course, t he only way t o see t hem in act ion was t o go t here. I left UNC for a shading proj ect at SGI , wit h t he hopes of providing a com m ercially support ed shading language t hat could be used on m ore t han j ust one m achine at one sit e. Meanwhile, a shading language research proj ect st art ed up at St anfor d, wit h som e im port ant result s for shading on PC- level graphics hardware. PC graphics vendors across t he board st art ed t o add low- level shading capabilit ies t o t heir hardware. Soon, people everyw here could w rit e shading code sim ilar in m any ways t o t hat which had so inspired m e on t he Pixel Planes 5 m achine. And, not surprisingly, soon people everyw here also knew t hat w e were going t o need a higher- level language for int eract ive shading. Research cont inues int o t he use, im provem ent , and abuse of t hese languages at m y lab at Universit y of Maryland, Balt im ore Count y; and at m any, m any ot hers. However, t he m ere exist ence of real- t im e high- level shading languages is no longer t he subj ect of t hat research. I nt eract ive shading languages have m oved from t he research phase t o wide availabilit y. There

are a num ber of opt ions for anyone w ant ing t o develop an applicat ion using t he shading capabilit ies of m odern graphics hardware. The principal choices are Cg, HLSL, and t he OpenGL Shading Language. The last of w hich has t he dist inct ion of being t he only one t hat has been t hrough a rigorous m ult ivendor review process. I part icipat ed in t hat process, as did over t wo dozen represent at ives from a dozen com panies and universit ies. This brings us back full circle t o t his book. I f you are holding t his book now, you are m ost likely int erest ed in som e of t he sam e ideals t hat drove t he cr eat ion of t he OpenGL Shading Language, t he desire for a cr oss- OS, cross- plat form , robust and st andardized shading language. You w ant t o learn how t o use all of t hat ? Open up and st art reading. Then get shading! Marc Olano Universit y of Maryland Balt im ore Count y, MD Sept em ber 2003

Preface For j ust about as long as t here has been graphics hardw are, t here has been pr ogram m able graphics hardware. Over t he years, building flexibilit y int o graphics hardware designs has been a necessary w ay of life for hardware developer s. Graphics API s cont inue t o evolve, and because a hardware design can t ake t w o years or m ore from st art t o finish, t he only w ay t o guarant ee a hardware product t hat can support t he t hen current graphics API s at it s release is t o build in som e degree of program m abilit y from t he very beginning. Unt il recent ly, t he realm of program m ing graphics hardware belonged t o j ust a few people, m ainly researchers and graphics hardware driver developers. Research int o program m able graphics hardware has been t aking place for m any years, but t he point of t his research has not been t o produce viable hardware and soft ware for applicat ion developers and end users. The graphics hardware driver developers have focused on t he im m ediat e t ask of providing support for t he im port ant graphics API s of t he t im e: PHI GS, PEX, I ris GL, OpenGL, Direct 3D, and so on. Unt il recent ly, none of t hese API s exposed t he program m abilit y of t he underlying hardware, so applicat ion developers have been forced int o using t he fixed funct ionalit y provided by t radit ional graphics API s. Hardware com panies have not exposed t he program m able underpinnings of t heir product s because of t he high cost of educat ing and support ing cust om ers t o use low- level, device- specific int erfaces and because t hese int erfaces t ypically change quit e radically wit h each new gener at ion of graphics hardwar e. Applicat ion developers who use such a device- specific int erface t o a piece of gr aphics hardware face t he daunt ing t ask of updat ing t heir soft ware for each new generat ion of hardw are t hat com es along. And forget about support ing t he applicat ion on hardw are fr om m ult iple vendors! As we m oved int o t he 21st cent ury, som e of t hese fundam ent al t enet s about graphics hardware were challenged. Applicat ion developers pushed t he envelope as never before and dem anded a variet y of new feat ures in hardw are in order t o creat e m or e and m ore sophist icat ed onscreen effect s. As a result , new graphics hardware designs becam e m ore program m able t han ever before. St andard graphics API s w ere challenged t o keep up wit h t he pace of hardware innovat ion. For OpenGL, t he result was a spat e of ext ensions t o t he cor e API as hardware vendors st ruggled t o support a range of int erest ing new feat ures t hat t heir cust om ers were dem anding. The cr eat ion of a st andard, cross- plat form , high- level shading language for com m ercially available gr aphics hardware w as a w at ershed event for t he graphics indust ry. A paradigm shift occurred, one t hat t ook us from t he world of rigid, fixed funct ionalit y graphics hardware and graphics API s t o a brave new world where t he visual processing unit , or VPU ( i.e., graphics hardw are) , is as im port ant as t he cent ral processing unit , or CPU. The VPU is opt im ized for processing dynam ic m edia such as 3D graphics and video. Highly parallel processing of float ingpoint dat a is t he prim ary t ask for VPUs, and t he flexibilit y of t he VPU m eans t hat it can also be used t o process dat a ot her t han a st ream of t radit ional graphics com m ands. Applicat ions can t ake advant age of t he capabilit ies of bot h t he CPU and t he VPU, using t he st rengt hs of each t o opt im ally perform t he t ask at hand. This book describes how graphics hardware program m abilit y is exposed t hrough a high- level language in t he leading cross- plat form 3D graphics API : OpenGL. This language, t he OpenGL Shading Language, let s applicat ions t ake t ot al cont rol over t he m ost im port ant st ages of t he graphics processing pipeline. No longer rest rict ed t o t he gr aphics rendering algorit hm s and form ulas chosen by hardware designers and frozen in silicon, soft ware developers are beginning t o use t his pr ogram m abilit y t o creat e st unning effect s in real t im e.

Intended Audience The pr im ary audience for t his book is applicat ion program m ers who want t o writ e shaders. This book can be used as bot h a t ut orial and a reference book by people int erest ed in learning t o writ e shaders wit h t he OpenGL Shading Language. Som e will use t he book in one fashion, and som e in t he ot her. The organizat ion is am enable t o bot h uses and is based on t he assum pt ion t hat m ost people won't read t he book in sequent ial order from back t o front ( but som e int r epid readers of t he first edit ion report ed t hat t hey did j ust t hat ! ) . Readers do not need previous knowledge of OpenGL t o absorb t he m at erial in t his book, but such knowledge is very helpful. A brief review of OpenGL is included, but t his book does not at t em pt t o be a t ut orial or reference book for OpenGL. Anyone at t em pt ing t o develop an OpenGL applicat ion t hat uses shaders should be arm ed wit h OpenGL pr ogram m ing docum ent at ion in addit ion t o t his book. Com put er graphics has a m at hem at ical basis, so som e knowledge of algebra, t rigonom et r y, and calculus will help readers underst and and appreciat e som e of t he det ails present ed. Wit h t he advent of pr ogram m able graphics hardware, key part s of t he graphics processing pipeline are once again under t he cont rol of soft w are developers. To develop shaders successfully in t his environm ent , developers m ust underst and t he m at hem at ical basis of com put er graphics.

About This Book This book has t hree m ain part s. Chapt ers 1 t hrough 8 t each t he reader about t he OpenGL Shading Language and how t o use it . This part of t he book covers det ails of t he language and det ails of t he OpenGL com m ands t hat creat e and m anipulat e shaders. To supply a basis for writ ing shaders, Chapt ers 9 t hrough 20 cont ain a gallery of shader exam ples and som e explanat ion of t he underlying algorit hm s. This part of t he book is bot h t he baseline for a reader's shader developm ent and a springboard for inspiring new ideas. Finally, Chapt er 21 com pares ot her not able com m ercial shading languages, and Appendices A and B cont ain reference m at erial for t he language and t he API ent ry point s t hat support it . The chapt ers are arranged t o suit t he needs of t he reader who is least fam iliar wit h OpenGL and shading languages. Cert ain chapt ers can be skipped by reader s who are m ore fam iliar w it h bot h t opics. This book has som ewhat com part m ent alized chapt ers in order t o allow such usage. z

z

z

z

z

z

z

z

z

z

Chapt er 1 review s t he fundam ent als of t he OpenGL API . Readers already fam iliar w it h OpenGL m ay skip t o Chapt er 2. Chapt er 2 int roduces t he OpenGL Shading Language and t he OpenGL ent ry point s t hat have been added t o support it . I f you want t o know what t he OpenGL Shading Language is all about and you have t im e t o read only t w o chapt ers of t his book, t his chapt er and Chapt er 3 are t he ones t o read. Chapt er 3 t hor oughly describes t he OpenGL Shading Language. This m at erial is organized t o present t he det ails of a program m ing language. This sect ion serves as a useful reference sect ion for reader s who have developed a general underst anding of t he language. Chapt er 4 discusses how t he newly defined program m able part s of t he rendering pipeline int eract wit h each ot her and wit h OpenGL's fixed funct ionalit y. This discussion includes descript ions of t he built - in variables defined in t he OpenGL Shading Language. Chapt er 5 describes t he built - in funct ions t hat are part of t he OpenGL Shading Language. This sect ion is a useful reference sect ion for readers wit h an underst anding of t he language. Chapt er 6 present s and discusses a fairly sim ple shader exam ple. People who lear n best by diving in and st udying a r eal exam ple w ill benefit from t he discussion in t his chapt er. Chapt er 7 describes t he ent ry point s t hat have been added t o OpenGL t o support t he creat ion and m anipulat ion of shaders. Applicat ion program m ers who want t o use shaders in t heir applicat ion m ust underst and t his m at erial. Chapt er 8 present s som e general advice on shader developm ent and describes t he shader developm ent process. I t also describes t ools t hat are current ly available t o aid t he shader developm ent process. Chapt er 9 begins a series of chapt ers t hat present and discuss shaders wit h a com m on charact erist ic. I n t his chapt er, shaders t hat duplicat e som e of t he fixed funct ionalit y of t he OpenGL pipeline are present ed. Chapt er 10 present s a few shaders t hat are based on t he capabilit y t o st ore dat a in and ret rieve dat a fr om t ext ure m aps.

z

z

z z

z z

z

z

z

z

z

z

z

z

Chapt er 11 is devot ed t o shaders t hat are procedural in nat ure; t hat is, effect s are com put ed algorit hm ically rat her t han being based on inform at ion st ored in t ext ures. Chapt er 12 present s several alt ernat ive light ing m odels t hat can be im plem ent ed wit h OpenGL shaders. Chapt er 13 discusses algorit hm s and shaders for producing shadows. Chapt er 14 delves int o t he det ails of shaders t hat im plem ent m ore realist ic surface charact erist ics, including refract ion, diffr act ion, and m ore realist ic reflect ion. Chapt er 15 describes noise and t he effect s t hat can be achieved wit h it s proper use. Chapt er 16 cont ains exam ples of how shaders can creat e rendering effect s t hat vary over t im e. Chapt er 17 cont ains a discussion of t he aliasing problem and how shaders can be writ t en t o reduce t he effect s of aliasing. Chapt er 18 illust r at es shaders t hat achieve effect s ot her t han phot orealism . Such effect s include t echnical illust rat ion, sket ching or hat ching effect s, and ot her st ylized rendering. Chapt er 19 present s several shaders t hat m odify im ages as t hey are being dr awn wit h OpenGL. Chapt er 20 describes som e of t he t echniques and algorit hm s used in a com plex OpenGL applicat ion t hat m akes ext ensive use of t he OpenGL Shading Language. Chapt er 21 com pares t he OpenGL Shading Language wit h ot her not able com m ercial shading languages. Appendix A cont ains t he language gram m ar t hat m ore clearly specifies t he OpenGL Shading Language. Appendix B cont ains refer ence pages for t he API ent ry point s t hat are relat ed t o t he OpenGL Shading Language. Finally, Glossary collect s t erm s defined in t he book, Furt her Reading gat hers all t he chapt er references and adds m ore, and I ndex ends t he book.

About the Shader Examples The shaders cont ained in t his book are prim arily short program s t hat illust rat e t he capabilit ies of t he OpenGL Shading Language. None of t he exam ple shaders should be presum ed t o illust rat e t he " best " way of achieving a part icular effect . ( I ndeed, t he " best " way t o im plem ent cert ain effect s m ay have yet t o be discovered t hrough t he power and flexibilit y of program m able graphics hardware.) Perfor m ance im provem ent s for each shader are possible for any given hardware t arget . For m ost of t he shader s, im age qualit y m ay be im pr oved if great er care is t aken t o reduce or elim inat e causes of aliasing. The source code for t hese shaders is writ t en in a way t hat I believe represent s a reasonable t rade- off bet w een source code clarit y, port abilit y, and perform ance. Use t hem t o learn t he OpenGL Shading Language, and im prove on t hem for use in your ow n pr oj ect s. All t he im ages produced for t his book were done eit her on t he first graphics accelerat or t o provide support for t he OpenGL Shading Language, t he 3Dlabs Wildcat VP, or it s successor, t he 3Dlabs Wildcat Realizm . I have t aken as m uch car e as possible t o pr esent shader s t hat are done " t he right way" for t he OpenGL Shading Language rat her t han t hose wit h idiosyncrasies from t heir developm ent on t he very early im plem ent at ions of t he OpenGL Shading Language. Elect ronic ver sions of m ost of t hese shaders are available t hrough a link at t his book's Web sit e at ht t p: / / 3dshaders.com

Errata I know t hat t his book cont ains som e errors, but I 've done m y best t o keep t hem t o a m inim um . I f you find any errors, please report t hem t o m e ( [email protected] ) and I will keep a running list on t his book's Web sit e at ht t p: / / 3dshaders.com

Typographical Conventions This book cont ains a num ber of t ypographical convent ions t o enhance readabilit y and underst anding. z

SMALL CAPS are used for t he first occurrence of defined t erm s.

z

I t alics are used for em phasis, docum ent t it les, and coordinat e values such as x, y, and z.

z

Bold se r if is used for language keywords.

z

Sans serif is used for m acros and sym bolic const ant s t hat appear in t he t ext .

z

Bold sans serif is used for funct ion nam es.

z

Italic sans serif is used for variables, param et er nam es, spat ial dim ensions, and m at rix

com ponent s. z

Fixed width is used for code exam ples.

About the Author Ra n di Rost is current ly t he Direct or of Developer Relat ions at 3Dlabs. I n t his role, he leads a t eam t hat is devot ed t o educat ing developers and helping t hem t ake advant age of new graphics hardw are t echnology. He leads a t eam t hat produces developm ent t ools, exam ple program s, docum ent at ion, and whit e papers; cont ribut es t o st andards and open source effort s; and assist s developers in a variet y of w ays. Before his Developer Relat ions role, Randi was t he m anager of 3Dlabs' Fort Collins, Colorado, graphics soft ware t eam . This group drove t he definit ion of t he OpenGL 2.0 st andard and im plem ent ed OpenGL drivers for 3Dlabs' graphics product s. Before j oining 3Dlabs, Randi was a graphics soft ware archit ect for Hewlet t - Packard's Graphics Soft ware Lab and t he chief archit ect for graphics soft ware at Kubot a Graphics Corporat ion. Randi has been involved in t he graphics indust ry for m ore t han 25 years and has part icipat ed in em erging graphics st andards effort s for over 20 years. He has been involved wit h t he design and evolut ion of OpenGL since before version 1.0 was released in 1992. He is one of t he few people credit ed as a cont ribut or for each m aj or revision of OpenGL, up t hrough and including OpenGL 2.0. He was one of t he chief archit ect s and t he specificat ion aut hor for PEX, and he was a m em ber of t he Graphics Perform ance Charact erizat ion ( GPC) Com m it t ee during t he developm ent of t he Pict ure- Level Benchm ark ( PLB) . He served as 3Dlabs' repr esent at ive t o t he Khronos Group from t he t im e t he gr oup st art ed in 1999 unt il t he OpenML 1.0 specificat ion was released, and he chaired t he graphics subcom m it t ee of t hat organizat ion during t his t im e. He received t he Nat ional Com put er Graphics Associat ion ( NCG) 1993 Achievem ent Award for t he Advancem ent of Graphics St andards. Randi has part icipat ed in or organized num erous graphics t ut orials at SI GGRAPH, Eurographics, and t he Gam e Developer's conference since 1990. He has given t ut orials on t he OpenGL Shading Language at SI GGRAPH 2002 and SI GGRAPH 2003 and m ade pr esent at ions on t his t opic at t he Gam e Developer's Conference in 2002 and 2003. I n 2004, Randi t aught OpenGL Shading Language Mast erClasses across Nort h Am erica, Europe, and Japan. Randi received his B.S. in com put er science and m at hem at ics fr om Minnesot a St at e Universit y, Mankat o, in 1981 and his M.S. in com put ing science from t he Universit y of California, Davis, in 1983. On a dreary wint er day, you m ight find Randi in a desolat e region of sout hern Wyom ing, following a road less t raveled.

About the Contributors Ba r t h old Licht e n be lt received his m ast er's degree in elect rical engineering in 1994 from t he Universit y of Twent e in t he Net herlands. From 1994 t o 1998, he worked on volum e rendering t echniques at Hew let t - Packard Com pany, first at Hewlet t - Packard Laborat ories in Palo Alt o, California, and lat er at Hewlet t - Packard's graphics soft ware lab in Fort Collins, Colorado. During t hat t im e, he coaut hored t he book, I nt roduct ion t o Volum e Rendering, and wrot e several papers on t he subj ect . He was awarded four pat ent s in t he field of volum e rendering. I n 1998, Bart hold j oined Dynam ic Pict ur es ( subsequent ly acquired by 3Dlabs) , where he worked on bot h Direct 3D and OpenGL drivers for professional graphics accelerat ors. Since 2001, he has been heavily involved in effort s t o ext end t he OpenGL API and was t he lead aut hor of t he t hree ARB ext ensions t hat suppor t t he OpenGL Shading Language. Bart hold also led t he im plem ent at ion of 3Dlabs' first dr ivers t hat use t hese ext ensions. He current ly m anages 3Dlabs' Program m able Graphics Developm ent Group in Fort Collins, Colorado. Joh n Ke sse n ich , a Colorado nat ive, has w orked in Fort Collins as a soft ware archit ect in a variet y of fields including CAD applicat ions, operat ing syst em kernels, and 3D graphics. He received a pat ent for using Web browsers t o navigat e t hrough huge collect ions of source code and anot her for processor archit ect ure. John st udied m at hem at ics and it s applicat ion t o com put er graphics, com put er languages, and com pilers at Colorado St at e Universit y, receiving a bachelor's degree in applied m at hem at ics in 1985. Lat er, while working at Hewlet t - Packard, he earned his m ast er's degree in applied m at hem at ics in 1988. John has been working on OpenGL drivers since 1999 at 3Dlabs, and has been leading t he 3Dlabs shading language com piler developm ent effort since 2001. John was t he lead aut hor for t he OpenGL Shading Language specificat ion, and in t his role he was one of t he leader s of t he t echnical effort t o finalize and st andardize it as part of core OpenGL. H u gh M a la n is a com put er graphics program m er current ly working for Real Tim e Worlds in Dundee, Scot land. I n 1997, he received B.S. degrees in m at hem at ics and physics from Vict oria Universit y in Wellingt on, New Zealand, and followed t hat wit h a year in t he honors program for m at hem at ics. He subsequent ly received an M.S. in com put er graphics from Ot ago Universit y in Dunedin, New Zealand. Aft er receiving his M.S., Hugh worked on 3D paint and UV m apping t ools at Right Hem isphere, and t hen j oined Pandrom eda, I nc t o develop t he RealWorldz dem o for 3Dlabs ( described in Chapt er 20) . M icha e l W e ible n received his B.S. in elect rical engineering from t he Universit y of Maryland, College Park, in 1989. Mike began exploring com put er graphics in t he 1980s, and developed 3D renderers for t he TRS- 80 Model 100 lapt op and Am iga 1000. Using OpenGL and I risGL since 1993, he has developed global- scale synt het ic environm ent s, visual sim ulat ions, and virt ual realit y applicat ions, which have been present ed at such venues as t he Unit ed St at es Capit ol, EPCOT Cent er, DARPA, NASA, and SI GGRAPH. He has been awarded t wo U.S. pat ent s, and has published several papers and art icles. I n 2003, Mike j oined 3Dlabs in Fort Collins, Colorado, where he is current ly an engineer wit h t he 3Dlabs Developer Relat ions group, focusing on applicat ions of hardw are- accelerat ed r endering using t he OpenGL Shading Language. Mike current ly cont ribut es t o several open- source soft ware proj ect s, such as spearheading t he int egrat ion of OpenGL Shading Language support int o OpenSceneGraph.

Acknowledgments John Kessenich of 3Dlabs was t he prim ary aut hor of t he OpenGL Shading Language specificat ion docum ent and t he aut hor of Chapt er 3 of t his book. Som e of t he m at erial from t he OpenGL Shading Language specificat ion docum ent was m odified and included in Chapt ers 3, 4, and 5, and t he OpenGL Shading Language gram m ar writ t en by John for t he specificat ion is included in it s ent iret y in Appendix A. John worked t irelessly t hroughout t he st andardizat ion effort discussing, resolving, and docum ent ing language and API issues; updat ing t he specificat ion t hrough num erous revisions; and providing insight and educat ion t o m any of t he ot her part icipant s in t he effort . John also did som e of t he early shader developm ent , including t he very first versions of t he wood, bum p m ap, and environm ent m apping shaders discussed in t his book. Bart hold Licht enbelt of 3Dlabs was t he prim ary aut hor and docum ent edit or of t he OpenGL ext ension specificat ions t hat defined t he OpenGL Shading Language API . Som e m at erial from t hose specificat ions has been adapt ed and included in Chapt er 7. Bart hold worked t ir elessly updat ing t he specificat ions; discussing, resolving, and docum ent ing issues; and guiding t he part icipant s of t he ARB- GL2 working group t o consensus. Bart hold is also t he coaut hor of Chapt er 4 of t his book. Since August 2005, Bart hold has been working at NVI DI A, where he is involved in OpenGL st andardizat ion effort s. The indust rywide init iat ive t o define a high- level shading effort for OpenGL was ignit ed by a whit e paper called The OpenGL 2.0 Shading Language, writ t en by Dave Baldw in ( 2001) of 3Dlabs. Dave's ideas provided t he basic fram ework from w hich t he OpenGL Shading Language has evolved. Publicat ion of t his whit e paper occurred alm ost a year before any publicat ion of inform at ion on com pet ing, com m ercially viable, high- level shading languages. I n t his respect , Dave deserves credit as t he t railblazer for a st andard high- level shading language. Dave cont inued t o be heavily involved in t he design of t he language and t he API during it s form at ive m ont hs. His original whit e paper also included code for a variet y of shaders. This code served as t he st art ing point for several of t he shaders in t his book: not ably, t he brick shaders present ed in Chapt er 6 and Chapt er 17, t he t radit ional shaders present ed in Chapt er 9, t he ant ialiased checkerboard shader in Chapt er 17, and t he Mandelbrot shader in Chapt er 18. St eve Koren of 3Dlabs w as responsible for get t ing t he aliased brick shader and t he Mandelbrot shader working on real hardw are for t he first t im e. Mike Weiblen developed and described t he GLSL diffract ion shader in Chapt er 14, cont ribut ed a discussion of scene graphs and t heir uses in Chapt er 8, cont ribut ed t o t he shadow volum e shader in Sect ion 13.3, and com piled t he quick reference card included at t he back of t he book. Philip Rideout was inst rum ent al in developing fram eworks for writ ing and t est ing shaders. Many of t he illust rat ions in t his book were generat ed wit h Philip's GLSLdemo and deLight applicat ions. Philip also cont ribut ed several of t he shaders in t his book, including t he shadow shaders in Chapt er 13 and t he sphere m orph and vert ex noise shaders in Chapt er 16. Joshua Doss developed t he init ial version of t he glyph bom bing shader described in Chapt er 10. He and I nderaj Bains were t he coaut hors of ShaderGen, a t ool t hat verified t he fixed funct ionalit y code segm ent s pr esent ed in Chapt er 9 and t hat can aut om at ically generat e working shaders fr om current fixed funct ionalit y st at e. Teri Morrison cont ribut ed t he OpenGL 1.5 t o 2.0 m igrat ion guide t hat appears in Appendix B. Bart hold Licht enbelt t ook t he pict ures t hat were used t o creat e t he Old Town Square environm ent m aps. Hugh Malan of Pandrom eda was t he prim ary im plem ent or of an am azing dem o called RealWorldz t hat was developed for 3Dlabs by Pandrom eda and is t he aut hor of t he m at erial t hat discusses t his applicat ion in Chapt er 20. Ken " Doc Moj o" Musgrave, Craig McNaught on, and Jonat han Dapra of Pandrom eda cont ribut ed enorm ously t o t he success of t his effort . Clift on

Robin and Mike Weiblen were key cont ribut ors from 3Dlabs. Hugh also cont ribut ed t he init ial version of t he shadow volum e shader discussed in Sect ion 13.3. Bert Freudenberg of t he Universit y of Magdeburg developed t he hat ching shader described in Chapt er 18. As part of t his effort , Bert also explored som e of t he issues involved wit h analyt ic ant ialiasing wit h program m able graphics hardware. I have incorporat ed som e of Ber t 's diagram s and result s in Chapt er 17. Bill Licea- Kane of ATI Research developed t he t oy ball shader present ed in Chapt er 11 and provided m e wit h it s " t heor y of operat ion." The st ripe shader included in Chapt er 11 was im plem ent ed by Light Work Design, Lt d. Ant onio Tej ada of 3Dlabs conceived and im plem ent ed t he w obble shader present ed in Chapt er 16. William " Prot on" Vaughn of Newt ek provided a num ber of excellent m odels for use in t his book. I t hank him for t he use of his Pug m odel t hat appears in Color Plat es 19 and 22 and t he Drum m er m odel t hat appears in Color Plat e 20. Christ ophe Desse of xt rm 3D.com also allowed m e t o use som e of his great m odels. I used his Spacem an m odel in Color Plat e 17, his Scout walker m odel in Color Plat e 18, and his Ore m odel in Color Plat e 21. Thanks are owed t o William and Christ ophe not only for allowing m e t o use t heir m odels in t his book, but for also cont ribut ing t hese m odels and m any ot hers for public use. I would like t o t hank m y colleagues at 3Dlabs for t heir assist ance wit h t he OpenGL 2.0 effort in general and for help in developing t his book. Specifically, t he 3Dlabs com piler t eam has been doing am azing work im plem ent ing t he OpenGL Shading Language com piler, linker, and obj ect support in t he 3Dlabs OpenGL im plem ent at ion. Dave Hoult on and Mike Weiblen worked on Render Monkey and ot her shader developm ent t ools. Dave also worked closely wit h com panies such as SolidWorks and Light Work Design t o enable t hem t o t ake full advant age of t he OpenGL Shading Language. Teri Morrison and Na Li im plem ent ed and t est ed t he original OpenGL Shading Language ext ensions, and Teri, Bart hold, and Mat t hew William s im plem ent ed t he official OpenGL 2.0 API support in t he 3Dlabs drivers. This work has m ade it possible t o creat e t he code and im ages t hat appear in t his book. The Fort Collins soft ware t eam , which I was privileged t o lead for several years, was responsible for producing t he publicly available specificat ions and source code for t he OpenGL Shading Language and OpenGL Shading Language API . Dale Kirkland, Jerem y Morris, Phil Huxley, and Ant onio Tej ada of 3Dlabs were involved in m any of t he OpenGL 2.0 discussions and provided a wealt h of good ideas and encouragem ent as t he effort m oved forward. Ant onio also im plem ent ed t he first parser for t he OpenGL Shading Language. Ot her m em bers of t he 3Dlabs dr iver developm ent t eam s in Fort Collins, Colorado; Egham , U.K.; Madison, Alabam a; and Aust in, Texas have cont ribut ed t o t he effort as well. The 3Dlabs execut ive st aff should be com m ended for having t he vision t o m ove forward wit h t he OpenGL 2.0 proposal and t he courage t o allocat e resources t o it s developm ent . Thanks t o Osm an Kent , Hock Leow, Neil Tr evet t , Jerry Pet erson, Jeff Lit t le, and John Schim pf in part icular. Num erous ot her people have been involved in t he OpenGL 2.0 discussions. I would like t o t hank m y colleagues and fellow ARB represent at ives at ATI , SGI , NVI DI A, I nt el, Microsoft , Evans & Sut herland, I BM, Sun Microsyst em s, Apple, I m aginat ion Technologies, Dell, Com paq, and HP for cont ribut ing t o discussions and for helping t o m ove t he process along. I n part icular, Bill LiceaKane of ATI chaired t he ARB- GL2 working group since it s creat ion and successfully st eered t he group t o a rem arkable achievem ent in a relat ively short t im e. Bill, Evan Hart , Jerem y Sandm el, Benj am in Lipchak, and Glenn Ort ner of ATI also provided insight ful review and st udious com m ent s for bot h t he OpenGL Shading Language and t he OpenGL Shading Language API . St eve Glanville and Cass Everit t of NVI DI A were ext rem ely helpful during t he design of t he OpenGL Shading Language, and Pat Brown of NVI DI A cont ribut ed enorm ously t o t he developm ent of t he OpenGL Shading Language API . Ot hers wit h not able cont ribut ions t o t he final specificat ions include Marc Olano of t he Universit y of Maryland/ Balt im ore Count y; Jon Leech of SGI ; Folker Scham el of Spinor; Mat t Cruikshank, St eve Dem low, and Karel Zuiderveld of Vit al I m ages; Allen Akin, cont ribut ing as an individual; and Kurt Akeley of NVI DI A. Num er ous ot hers provided review or com m ent ary t hat helped im prove t he specificat ion docum ent s. I t hink t hat special recognit ion should go t o people who were not affiliat ed wit h a graphics

hardw are com pany and st ill part icipat ed heavily in t he ARBGL2 working group. When represent at ives from a bunch of com pet ing hardware com panies get t oget her in a room and t ry t o reach agr eem ent on an im port ant st andard t hat m at erially affect s each of t hem , t here is oft en squabbling over det ails t hat will cause one com pany or anot her ext ra gr ief in t he short t erm . Marc Olano and Folker Scham el cont r ibut ed enorm ously t o t he st andar dizat ion effort as " neut ral" t hird part ies. Tim e and t im e again, t heir com m ent s helped lead t he group back t o a higher ground. Allen Akin and Mat t Cruikshank also cont ribut ed in t his regard. Thanks, gent lem en, for your t echnical cont ribut ions and your valuable but underappreciat ed work as " refer ees." A big t hank you goes t o t he soft ware developers who have t aken t he t im e t o t alk wit h us, send us e- m ail, or answer survey quest ions on ht t p: / / opengl.org. Our ult im at e aim is t o provide you wit h t he best possible API for doing graphics applicat ion developm ent , and t he t im e t hat you have spent t elling us what you need has been invaluable. A few I SVs lobbied long and hard for cert ain feat ures, and t hey were able t o convince us t o m ake som e significant changes t o t he original OpenGL 2.0 proposal. Thanks, all you soft war e developers, and keep t elling us what you need! A debt of grat it ude is owed t o t he designers of t he C program m ing language, t he designers of RenderMan, and t he designer s of OpenGL, t he t hree st andards t hat have provided t he st rongest influence on our effort s. Hopefully, t he OpenGL Shading Language will cont inue t heir t r adit ions of success and excellence. The reviewers of various draft s of t his book have helped great ly t o increase it s qualit y. Thanks t o John Carey, St eve Cunningham , Bert Fr eudenberg, Michael Garland, Jeffrey Galinovsky, Dave Hoult on, John Kessenich, Slawek Kilanowski, Bob Kuehne, Na Li, Bart hold Licht enbelt , Andy McGovern, Teri Morrison, Marc Olano, Brad Rit t er, Philip Rideout , Teresa Rost , Folker Scham el, Maryann Sim m ons, Mike Weiblen, and t w o anonym ous reviewers for reviewing som e or all of t he m at erial in t his book. Your com m ent s have been great ly appreciat ed! Clark Wolt er worked wit h m e on t he design of t he cover im age, and he im proved and perfect ed t he original concept s. Thanks go t o m y t hree children, Rachel, Hannah, and Zachary, for giving up som e play t im e wit h Daddy for a while, and for t he sm iles, giggles, hugs, and kisses t hat helped m e get t hrough t his proj ect . Finally, t hank you, Teresa, t he love of m y life, for t he support you've given m e in writ ing t his book. These have been busy t im es in our personal lives t oo, but you have had t he pat ience, st rengt h, and cour age t o see it t hrough t o com plet ion. Thank you for helping m e m ake t his book a realit y.

Chapter 1. Review of OpenGL Basics This chapt er briefly reviews t he OpenGL applicat ion program m ing int erface t o lay t he foundat ion for t he m at erial in subsequent chapt ers. I t is not an exhaust ive overview. I f you are already ext rem ely fam iliar w it h OpenGL, you can safely skip ahead t o t he next chapt er. I f you are fam iliar wit h anot her 3D graphics API , you can glean enough inform at ion here about OpenGL t o begin using t he OpenGL Shading Language for shader developm ent . Unless ot herwise not ed, descript ions of OpenGL funct ionalit y are based on t he OpenGL 2.0 specificat ion.

1.1. OpenGL History OpenGL is an indust ry- st andard, cross- plat form APPLI CATI ON PROGRAMMI NG I NTERFACE ( API ) . The specificat ion for t his API was finalized in 1992, and t he first im plem ent at ions appeared in 1993. I t was largely com pat ible wit h a propriet ary API called I ris GL ( Graphics Library) t hat was designed and support ed by Silicon Graphics, I nc. To est ablish an indust ry st andard, Silicon Graphics collaborat ed wit h various ot her graphics hardware com panies t o creat e an open st andard, which was dubbed " OpenGL." The evolut ion of OpenGL is cont rolled by t he OpenGL Archit ect ure Review Board, or ARB, creat ed by Silicon Graphics in 1992. This group is governed by a set of by- laws, and it s prim ary t ask is t o guide OpenGL by cont rolling t he specificat ion and conform ance t est s. The original ARB cont ained represent at ives from SGI , I nt el, Microsoft , Com paq, Digit al Equipm ent Corporat ion, Evans & Sut herland, and I BM. The ARB current ly has as m em bers 3Dlabs, Apple, ATI , Dell, I BM, I nt el, NVI DI A, SGI , and Sun Microsyst em s. OpenGL shar es m any of I ris GL's design charact erist ics. I t s int ent ion is t o provide access t o graphics hardware capabilit ies at t he lowest possible level t hat st ill provides hardware independence. I t is designed t o be t he lowest level int erface for accessing graphics hardw are. OpenGL has been im plem ent ed in a variet y of operat ing environm ent s, including Macs, PCs, and UNI X- based syst em s. I t has been support ed on a variet y of hardware archit ect ures, from t hose t hat support lit t le in hardware ot her t han t he fram e buffer it self t o t hose t hat accelerat e virt ually ever yt hing in hardw are. Since t he release of t he init ial OpenGL specificat ion ( version 1.0) in June 1992, six revisions have added new funct ionalit y t o t he API . The current version of t he OpenGL specificat ion is 2.0. The first conform ant im plem ent at ions of OpenGL 1.0 began appearing in 1993. z

z

z

z

z

Version 1.1 was finished in 1997 and added support for t w o im port ant capabilit iesvert ex arrays and t ext ure obj ect s. The specificat ion for OpenGL 1.2 was released in 1998 and added support for 3D t ext ures and an opt ional set of im aging funct ionalit y. The OpenGL 1.3 specificat ion was com plet ed in 2001 and added support for cube m ap t ext ures, com pressed t ext ures, m ult it ext ures, and ot her t hings. OpenGL 1.4 was com plet ed in 2002 and added aut om at ic m ipm ap generat ion, addit ional blending funct ions, int ernal t ext ure form at s for st oring dept h values for use in shadow com put at ions, support for drawing m ult iple vert ex arrays wit h a single com m and, m ore cont rol over point rast erizat ion, cont rol over st encil wrapping behavior, and various addit ions t o t ext uring capabilit ies. The OpenGL 1.5 specificat ion was published in Oct ober 2003. I t added support for vert ex buffer obj ect s, shadow com parison funct ions, occlusion queries, and nonpower - of- 2 t ext ures.

All versions of OpenGL t hr ough 1.5 w ere based on a fixed- funct ion pipelinet he user could cont rol various param et ers, but t he underlying funct ionalit y and order of processing were fixed. OpenGL 2.0, finalized in Sept em ber 2004, opened up t he processing pipeline for user cont rol by providing pr ogram m abilit y for bot h vert ex processing and fragm ent processing as part of t he core OpenGL specificat ion. Wit h t his version of OpenGL, applicat ion developers have been able t o im plem ent t heir own rendering algorit hm s, using a high- level shading language. The addit ion of program m abilit y t o OpenGL represent s a fundam ent al shift in it s design, hence t he change t o version num ber 2.0 from 1.5. However, t he change t o t he m aj or version num ber does not

represent any loss of com pat ibilit y wit h previous versions of OpenGL. OpenGL 2.0 is com plet ely backward com pat ible wit h OpenGL 1.5applicat ions t hat run on OpenGL 1.5 can run unm odified on OpenGL 2.0. Ot her feat ures added in 2.0 include support for m ult iple render t arget s ( rendering t o m ult iple buffers sim ult aneously) , nonpower- of- 2 t ext ures ( t hus easing t he rest rict ion t hat t ext ures m ust always be a power of 2 in each dim ension) , point sprit es ( screenaligned t ext ured quadrilat erals t hat are drawn wit h t he point pr im it ive) , and separat e st encil funct ionalit y for front - and back- facing surfaces.

1.2. OpenGL Evolution Because of it s fundam ent al design as a fixed funct ion st at e m achine, before OpenGL 2.0, t he only way t o m odify OpenGL was t o define ext ensions t o it . Therefore, a great deal of funct ionalit y is available in various OpenGL im plem ent at ions in t he form of ext ensions t hat expose new hardware funct ionalit y. OpenGL has a well- defined ext ension m echanism , and hardw are vendors are fr ee t o define and im plem ent feat ures t hat expose new hardw are funct ionalit y. Since only OpenGL im plem ent ors can im plem ent ext ensions, t here w as previously no way for applicat ions t o ext end t he funct ionalit y of OpenGL beyond what was pr ovided by t heir OpenGL provider. To dat e, close t o 300 ext ensions have been defined. Ext ensions t hat are support ed by only one vendor are ident ified by a short pr efix unique t o t hat vendor ( e.g., SGI for ext ensions developed by Silicon Graphics, I nc.) . Ext ensions t hat are support ed by m ore t han one vendor are denot ed by t he prefix EXT in t he ext ension nam e. Ext ensions t hat have been t horoughly reviewed by t he ARB are designat ed wit h an ARB prefix in t he ext ension nam e t o indicat e t hat t hey have a special st at us as a recom m ended way of exposing a cert ain piece of funct ionalit y. Ext ensions t hat achieve t he ARB designat ion are candidat es t o be added t o st andard OpenGL. Published specificat ions for OpenGL ext ensions are available at t he OpenGL ext ension regist ry at ht t p: / / oss.sgi.com / proj ect s/ ogl- sam ple/ regist ry . The ext ensions support ed by a part icular OpenGL im plem ent at ion can be det erm ined by calling t he OpenGL glGetString funct ion wit h t he sym bolic const ant GL_EXTENSI ONS. The ret urned st ring cont ains a list of all t he ext ensions support ed in t he im plem ent at ion, and som e vendors current ly support close t o 100 separat e OpenGL ext ensions. I t can be a lit t le bit daunt ing for an applicat ion t o t ry and det erm ine whet her t he needed ext ensions are present on a variet y of im plem ent at ions, and what t o do if t hey're not . The proliferat ion of ext ensions has been prim arily a posit ive fact or for t he developm ent of OpenGL, but in a sense, it has becom e a vict im of it s own success. I t allows hardware vendors t o expose new feat ures easily, but it present s applicat ion developers wit h a dizzying array of nonst andard opt ions. Like any st andards body, t he ARB is caut ious about prom ot ing funct ionalit y from ext ension st at us t o st andard OpenGL. Before version 2.0 of OpenGL, none of t he underlying program m abilit y of graphics har dw are was exposed. The original designers of OpenGL, Mark Segal and Kurt Akeley, st at ed, " One reason for t his decision is t hat , for perform ance reasons, graphics hardw are is usually designed t o apply cert ain operat ions in a specific order; replacing t hese operat ions wit h arbit rary algorit hm s is usually infeasible." This st at em ent m ay have been m ost ly t rue when it was writ t en in 1994 ( t here were program m able graphics archit ect ures even t hen) . But t oday, all of t he graphics hardware t hat is being produced is program m able. Because of t he proliferat ion of OpenGL ext ensions and t he need t o support Microsoft 's Direct X API , hardw are vendors have no choice but t o design program m able gr aphics archit ect ures. As discussed in t he rem aining chapt ers of t his book, providing applicat ion program m ers wit h access t o t his program m abilit y is t he purpose of t he OpenGL Shading Language.

1.3. Execution Model The OpenGL API is focused on drawing graphics int o fr am e buffer m em ory and, t o a lesser ext ent , in reading back values st or ed in t hat fram e buffer . I t is som ewhat unique in t hat it s design includes support for drawing t hreedim ensional geom et ry ( such as point s, lines, and polygons, collect ively referred t o as PRI MI TI VES) as w ell as for draw ing im ages and bit m aps. The execut ion m odel for OpenGL can be described as client - server. An applicat ion program ( t he client ) issues OpenGL com m ands t hat are int erpret ed and processed by an OpenGL im plem ent at ion ( t he server) . The applicat ion program and t he OpenGL im plem ent at ion can execut e on a single com put er or on t w o different com put ers. Som e OpenGL st at e is st ored in t he addr ess space of t he applicat ion ( client st at e) , but t he m aj orit y of it is st ored in t he addr ess space of t he OpenGL im plem ent at ion ( server st at e) . OpenGL com m ands are always processed in t he order in which t hey are received by t he server , alt hough com m and com plet ion m ay be delayed due t o int erm ediat e operat ions t hat cause OpenGL com m ands t o be buffered. Out - of- order execut ion of OpenGL com m ands is not perm it t ed. This m eans, for exam ple, t hat a prim it ive will not be drawn unt il t he pr evious prim it ive has been com plet ely draw n. This in- order execut ion also applies t o queries of st at e and fram e buffer read operat ions. These com m ands ret urn result s t hat are consist ent wit h com plet e execut ion of all previous com m ands. Dat a binding for OpenGL occurs when com m ands are issued, not when t hey are execut ed. Dat a passed t o an OpenGL com m and is int erpret ed when t he com m and is issued and copied int o OpenGL m em ory if needed. Subsequent changes t o t his dat a by t he applicat ion have no effect on t he dat a t hat is now st ored wit hin OpenGL.

1.4. The Frame Buffer OpenGL is an API for drawing graphics, and so t he fundam ent al purpose for OpenGL is t o t ransform dat a provided by an applicat ion int o som et hing t hat is visible on t he display screen. This processing is oft en referred t o as RENDERI NG. Typically, t his pr ocessing is accelerat ed by specially designed hardware, but som e or all operat ions of t he OpenGL pipeline can be perform ed by a soft ware im plem ent at ion running on t he CPU. I t is t ransparent t o t he user of t he OpenGL im plem ent at ion how t his division am ong t he soft w are and hardw are is handled. The im port ant t hing is t hat t he result s of rendering conform t o t he result s defined by t he OpenGL specificat ion. The hardware t hat is dedicat ed t o drawing graphics and m aint aining t he cont ent s of t he display screen is oft en called t he GRAPHI CS ACCELERATOR. Graphics accelerat ors t ypically have a region of m em ory t hat is dedicat ed t o m aint aining t he cont ent s of t he display. Every visible pict ure elem ent ( pixel) of t he display is represent ed by one or m or e byt es of m em ory on t he graphics accelerat or. A grayscale display m ight have a byt e of m em ory t o represent t he gray level at each pixel. A color display m ight have a byt e of m em ory for each of red, green, and blue in order t o repr esent t he color value for each pixel. This so- called DI SPLAY MEMORY is scanned ( refreshed) a cert ain num ber of t im es per second in order t o m aint ain a flicker- free represent at ion on t he display. Graphics accelerat ors also t ypically have a region of m em ory called OFFSCREEN MEMORY t hat is not displayable and is used t o st ore t hings t hat aren't visible. OpenGL assum es t hat allocat ion of display m em ory and offscr een m em ory is handled by t he window syst em . The window syst em decides which port ions of m em ory m ay be accessed by OpenGL and how t hese port ions are st ruct ured. I n each environm ent in w hich OpenGL is support ed, a sm all set of funct ion calls t ie OpenGL int o t hat part icular environm ent . I n t he Microsoft Windows environm ent , t his set of rout ines is called WGL ( pronounced " wiggle" ) . I n t he X Window Syst em environm ent , t his set of rout ines is called GLX. I n t he Macint osh environm ent , t his set of rout ines is called AGL. I n each environm ent , t his set of calls support s such t hings as allocat ing and deallocat ing regions of graphics m em ory, allocat ing and deallocat ing dat a st ruct ures called GRAPHI CS CONTEXTS t hat m aint ain OpenGL st at e, select ing t he current graphics cont ext , select ing t he region of graphics m em ory in w hich t o dr aw, and synchronizing com m ands bet ween OpenGL and t he window syst em . The region of graphics m em ory t hat is m odified as a result of OpenGL rendering is called t he FRAME BUFFER. I n a windowing syst em , t he OpenGL not ion of a fram e buffer corresponds t o a window. Facilit ies in window- syst em - specific OpenGL r out ines let users select t he fram e buffer charact erist ics for t he window. The windowing syst em t ypically also clarifies how t he OpenGL fram e buffer behaves w hen w indow s overlap. I n a nonw indowed syst em , t he OpenGL fram e buffer corresponds t o t he ent ire display. A window t hat support s OpenGL rendering ( i.e., a fram e buffer) m ay consist of som e com binat ion of t he follow ing: z

Up t o four color buffers

z

A dept h buffer

z

A st encil buffer

z

An accum ulat ion buffer

z

A m ult isam ple buffer

z

One or m ore auxiliary buffers

Most graphics hardware support s bot h a front buffer and a back buffer in order t o perform DOUBLE BUFFERI NG. This allows t he applicat ion t o render int o t he ( offscreen) back buffer while displaying t he ( visible) front buffer. When rendering is com plet e, t he t wo buffers are swapped so t hat t he com plet ed rendering is now displayed as t he front buffer and rendering can begin anew in t he back buffer. When double buffering is used, t he end user never sees t he graphics when t hey are in t he pr ocess of being drawn, only t he finished im age. This t echnique allows sm oot h anim at ion at int eract ive rat es. St er eo view ing is support ed by having a color buffer for t he left eye and one for t he right eye. Double buffering is support ed by having bot h a front and a back buffer. A double- buffered st ereo window w ill t herefore have four color buffers: front left , front right , back left , and back right . A norm al ( nonst ereo) double- buffered window will have a front buffer and a back buffer. A single- buffered window will have only a front buffer. I f 3D obj ect s are t o be drawn wit h hidden- surface r em oval, a DEPTH BUFFER is needed. This buffer st ores t he dept h of t he displayed obj ect at each pixel. As addit ional obj ect s are drawn, a dept h com parison can be perform ed at each pixel t o det erm ine whet her t he new obj ect is visible or obscured. A STENCI L BUFFER is used for com plex m asking operat ions. A com plex shape can be st ored in t he st encil buffer, and subsequent drawing operat ions can use t he cont ent s of t he st encil buffer t o det erm ine whet her t o updat e each pixel. The ACCUMULATI ON BUFFER is a color buffer t hat t ypically has higherprecision com ponent s t han t he color buffers. Several im ages can t hus be accum ulat ed t o produce a com posit e im age. One use of t his capabilit y would be t o draw several fram es of an obj ect in m ot ion int o t he accum ulat ion buffer. When each pixel of t he accum ulat ion buffer is divided by t he num ber of fram es, t he result is a final im age t hat shows m ot ion blur for t he m oving obj ect s. Sim ilar t echniques can be used t o sim ulat e dept h- of- field effect s and t o perform high- qualit y full- screen ant ialiasing. Norm ally, w hen obj ect s are draw n, a single decision is m ade as t o whet her t he graphics prim it ive affect s a pixel on t he screen. The MULTI SAMPLE BUFFER is a buffer t hat allows everyt hing t hat is render ed t o be sam pled m ult iple t im es wit hin each pixel in order t o perform high- qualit y full- screen ant ialiasing w it hout rendering t he scene m ore t han once. Each sam ple wit hin a pixel cont ains color, dept h, and st encil inform at ion, and t he num ber of sam ples per pixel can be queried. When a window includes a m ult isam ple buffer, it does not include separat e dept h or st encil buffers. As obj ect s are rendered, t he color sam ples are com bined t o produce a single color value, and t hat color value is passed on t o be writ t en int o t he color buffer. Because m ult isam ple buffers cont ain m ult iple sam ples ( oft en 4, 8, or 16) of color, dept h, and st encil for every pixel in t he w indow, t hey can use up large am ount s of offscreen graphics m em ory. AUXI LI ARY BUFFERS are offscreen m em ory buffers t hat can st ore arbit rary dat a such as int erm ediat e result s from a m ult ipass rendering algorit hm . A fram e buffer m ay have 1, 2, 3, 4, or even m ore associat ed auxiliary buffers.

1.5. State OpenGL was designed as a st at e m achine for updat ing t he cont ent s of a fram e buffer . The process of t urning geom et ric prim it ives, im ages, and bit m aps int o pixels on t he screen is cont rolled by a fairly large num ber of st at e set t ings. These st at e set t ings are ort hogonal t o one anot herset t ing one piece of st at e does not affect t he ot hers. Cum ulat ively, t he st at e set t ings define t he behavior of t he OpenGL rendering pipeline and t he way in which prim it ives are t ransform ed int o pixels on t he display device. OpenGL st at e is collect ed int o a dat a st ructure called a graphics cont ext . Window- syst em specific funct ions creat e and delet e graphics cont ext s. Anot her window- syst em - specific call designat es a graphics cont ext and an OpenGL fram e buffer t hat are used as t he t ar get s for subsequent OpenGL com m ands. Quit e a few ser ver - side st at e values in OpenGL have j ust t wo st at es: on or off. To t urn a m ode on, you m ust pass t he appropriat e sym bolic const ant t o t he OpenGL com m and glEnable. To t urn a m ode off, you pass t he sym bolic const ant t o glDisable. You enable client - side st at e ( such as point ers t hat define vert ex arrays) wit h glEnableClientState and disable it wit h glDisableClientState. OpenGL m aint ains a server- side st ack for pushing and popping any or all of t he defined st at e values. This st ack can be m anipulat ed wit h glPushAttrib and glPopAttrib. Sim ilarly, client st at e can be m anipulat ed on a second st ack wit h glPushClientAttrib and glPopClientAttrib. glGet is a generic funct ion t hat can query m any of t he com ponent s of a graphics cont ext . Sym bolic const ant s are defined for sim ple st at e it em s ( e.g., GL_CURRENT_COLOR and GL_LI NE_WI DTH) , and t hese values can be passed as argum ent s t o glGet t o ret rieve t he current value of t he indicat ed com ponent of a graphics cont ext . Variant s of glGet ret urn t he st at e value as an int eger, float , double, or boolean. More com plex st at e values ar e r et urned by " get " funct ions t hat are specific t o t hat st at e value, for inst ance, glGetClipPlane, glGetLight, and glGetMaterial. Error condit ions can be det ect ed wit h t he glGetError funct ion.

1.6. Processing Pipeline For specifying t he behavior of OpenGL, t he various operat ions are defined t o be applied in a part icular order, so we can also t hink of OpenGL as a GRAPHI CS PROCESSI NG PI PELI NE. Let 's st art by looking at a block diagram of how OpenGL was defined up t hrough OpenGL 1.5. Figur e 1.1 is a diagram of t he so- called FI XED FUNCTI ONALI TY of OpenGL. This diagram shows t he fundam ent als of how OpenGL has worked since it s incept ion and is a sim plified represent at ion of how OpenGL st ill works. I t shows t he m ain feat ures of t he OpenGL pipeline for t he purposes of t his overview. Som e new feat ures were added t o OpenGL in versions 1.1 t hrough 1.5, but t he basic archit ect ure of OpenGL rem ained unchanged unt il OpenGL 2.0. We use t he t erm fixed funct ionalit y because every OpenGL im plem ent at ion is required t o have t he sam e funct ionalit y and a result t hat is consist ent wit h t he OpenGL specificat ion for a given set of input s. Bot h t he set of operat ions and t he order in which t hey occur are defined ( fixed) by t he OpenGL specificat ion.

Figu r e 1 .1 . Ove r vie w of Ope n GL ope r a t ion [View full size image]

I t is im port ant t o not e t hat OpenGL im plem ent at ions are not required t o m at ch pr ecisely t he order of operat ions shown in Figur e 1.1. I m plem ent at ions are free t o m odify t he order of operat ions as long as t he rendering result s are consist ent w it h t he OpenGL specificat ion. Many innovat ive soft w are and hardware archit ect ures have been designed t o im plem ent OpenGL, and m ost block diagr am s of t hose im plem ent at ions look not hing like Figur e 1.1. How ever, t he diagram does ground our discussion of t he way t he rendering process appears t o work in OpenGL, even if t he underlying im plem ent at ion does t hings a bit different ly.

1.7. Drawing Geometry As you can see from Figur e 1.1, dat a for dr awing geom et ry ( point s, lines, and polygons) st art s off in applicat ion- cont rolled m em ory ( 1) . This m em ory m ay be on t he host CPU, or, wit h t he help of som e recent addit ions t o OpenGL or under- t he- covers dat a caching by t he OpenGL im plem ent at ion, it m ay act ually reside in video m em ory on t he graphics accelerat or. Eit her way, t he fact is t hat it is m em ory t hat cont ains geom et ry dat a t hat t he applicat ion can cause t o be drawn.

1.7.1. Geometry Specification The geom et ric prim it ives support ed in OpenGL are point s, lines, line st rips, line loops, polygons, t riangles, t r iangle st rips, t riangle fans, quadrilat erals, and quadrilat eral st rips. There are t hree m ain ways t o send geom et ry dat a t o OpenGL. The first is t he vert ex- at - a- t im e m et hod, which calls glBegin t o st art a prim it ive and calls glEnd t o end it . I n bet ween are com m ands t hat set specific VERTEX ATTRI BUTES such as vert ex posit ion, color, norm al, t ext ure coordinat es, secondary color, edge flags, and fog coordinat es, using calls such as glVertex, glColor, glNormal, and glTexCoord. ( A num ber of variant s of t hese funct ion calls allow t he applicat ion t o pass t hese values wit h various dat a t ypes as well as t o pass t hem by value or by reference.) Up t hrough version 1.5 of OpenGL, t here was no way t o send arbit rary ( user- defined) pervert ex dat a. The only per- vert ex at t ribut es allowed were t hose specifically defined in t he OpenGL specificat ion. OpenGL 2.0 added a m et hod for sending arbit rary per- vert ex dat a; t hat m et hod is described in Sect ion 7.7 " Specifying Vert ex At t r ibut es." When t he vert ex- at - a- t im e m et hod is used, t he call t o glVertex signals t he end of t he dat a definit ion for a single vert ex, and it m ay also define t he com plet ion of a prim it ive. Aft er glBegin is called and a pr im it ive t ype is specified, a graphics prim it ive is com plet ed whenever glVertex is called enough t im es t o com plet ely specify a prim it ive of t he indicat ed t ype. For independent t riangles, a t riangle is com plet ed every t hird t im e glVertex is called. For t riangle st rips, a t riangle is com plet ed when glVertex is called for t he t hird t im e, and an addit ional connect ing t riangle is com plet ed for each subsequent call t o glVertex. The second m et hod of draw ing prim it ives is t o use vert ex arrays. Wit h t his m et hod, applicat ions st ore vert ex at t ribut es in user - defined ar rays, set up point ers t o t he arrays, and use glDrawArrays, glMultiDrawArrays, glDrawElements, glMultiDrawElements, glDrawRangeElements, or glInterleavedArrays t o dr aw a large num ber of prim it ives at once. Because t hese ent ry point s can efficient ly pass large am ount s of geom et ry dat a t o OpenGL, applicat ion developers are encouraged t o use t hem for port ions of code t hat ar e ext rem ely perform ance crit ical. Using glBegin and glEnd requires a funct ion call t o specify each at t ribut e of each vert ex, so t he funct ion call overhead can becom e subst ant ial when obj ect s wit h t housands of vert ices are drawn. I n cont rast , vert ex arrays can be used t o draw a large num ber of prim it ives wit h a single funct ion call aft er t he vert ex dat a is organized int o arrays. Processing t he array dat a in t his fashion can be fast er because it is oft en m ore efficient for t he OpenGL im plem ent at ion t o deal wit h dat a organized in t his way. The current array of color values is specified wit h glColorPointer, t he current array of vert ex posit ions is specified wit h glVertexPointer, t he current array of norm al vect ors is specified wit h glNormalPointer, and so on. The funct ion glInterleavedArrays can specify and enable several int erleaved arrays sim ult aneously ( e.g., each vert ex m ight be defined wit h t hree float ing- point values represent ing a norm al followed by t hree float ing- point values represent ing a vert ex posit ion.) The pr eceding t w o m et hods are referred t o as drawing in I MMEDI ATE MODE because prim it ives are rendered as soon as t hey have been specified. The t hird m et hod involves st oring eit her t he vert ex- at - a- t im e funct ion calls or t he vert ex array calls in a DI SPLAY LI ST, an OpenGL- m anaged dat a st ruct ure t hat st ores com m ands for lat er execut ion. Display list s can include com m ands t o set st at e as well as com m ands t o draw geom et ry. Display list s are st ored on t he server side and can be processed lat er wit h glCallList or glCallLists. This is not illust rat ed in Figur e 1.1, but it is

anot her way t hat dat a can be provided t o t he OpenGL processing pipeline. The definit ion of a display list is init iat ed wit h glNewList, and display list definit ion is com plet ed wit h glEndList. All t he com m ands issued bet w een t hose t w o calls becom e part of t he display list , alt hough cert ain OpenGL com m ands are not allowed wit hin display list s. Depending on t he im plem ent at ion, DI SPLAY LI ST MODE can provide a perform ance advant age over im m ediat e m ode. St oring com m ands in a display list gives t he OpenGL im plem ent at ion an opport unit y t o opt im ize t he com m ands in t he display list for t he underlying hardw are. I t also gives t he im plem ent at ion t he chance t o st ore t he com m ands in a locat ion t hat enables bet t er drawing perform ance, perhaps even in m em ory on t he graphics accelerat or. Of course, som e ext r a com put at ion or dat a m ovem ent is usually required t o im plem ent t hese opt im izat ions, so applicat ions will t ypically see a perform ance benefit only if t he display list is execut ed m ore t han once. New API calls in version 1.5 of OpenGL perm it t ed vert ex ar ray dat a t o be st or ed in server - side m em ory. This m echanism t ypically provides t he highest perform ance rendering because t he dat a can be st ored in m em ory on t he gr aphics accelerat or and need not be t ransferred over t he I / O bus each t im e it is rendered. The API also support s t he concept of efficient ly st ream ing dat a from client t o server. The glBindBuffer com m and creat es a buffer obj ect , and glBufferData and glBufferSubData specify t he dat a values in such a buffer. glMapBuffer can m ap a buffer obj ect int o t he client 's address space and obt ain a point er t o t his m em ory so t hat dat a values can be specified direct ly. The com m and glUnmapBuffer m ust be called before t he values in t he buffer are accessed by subsequent GL rendering com m ands. glBindBuffer can also m ake a part icular buffer obj ect part of current st at e. I f buffer obj ect 0 is bound when calls are m ade t o vert ex array point er com m ands such as glColorPointer, glNormalPointer, glVertexPointer, and so on, t he point er param et er t o t hese calls is underst ood t o be a point er t o client - side m em ory. When a buffer obj ect ot her t han 0 is bound, t he point er param et er is underst ood t o be an offset int o t he current ly bound buffer obj ect . Subsequent calls t o one of t he vert ex array drawing com m ands ( e.g., glMultiDrawArrays) can t hus obt ain t heir vert ex dat a from eit her client - or server - side m em ory or a com binat ion t hereof. OpenGL support s t he rendering of curves and surfaces w it h evaluat ors. Evaluat or s use a polynom ial m apping t o produce vert ex at t ribut es such as color, norm al, and posit ion t hat are sent t o t he vert ex processing st age j ust as if t hey had been provided by t he client . See t he OpenGL specificat ion for a com plet e descript ion of t his funct ionalit y.

1.7.2. Per-Vertex Operations No m at t er which of t hese m et hods is used, t he net result is t hat geom et ry dat a is t ransferred int o t he first st age of processing in OpenGL, VERTEX PROCESSI NG ( 2) . At t his point , vert ex posit ions are t ransform ed by t he m odelview and proj ect ion m at rices, norm als are t ransform ed by t he inverse t ranspose of t he upper left m ost 3 x 3 m at rix t aken from t he m odelview m at rix, t ext ure coordinat es are t ransform ed by t he t ext ure m at rices, light ing calculat ions are applied t o m odify t he base color, t ext ure coordinat es m ay be aut om at ically generat ed, color m at erial st at e is applied, and point sizes are com put ed. All of t hese t hings are rigidly defined by t he OpenGL specificat ion. They are perform ed in a specific order, according t o specific form ulas, wit h specific it em s of OpenGL st at e cont rolling t he process. Because t he m ost im port ant t hings t hat occur in t his st age are t r ansform at ion and light ing, t he vert ex processing st age is som et im es called TRANSFORMATI ON AND LI GHTI NG, or, m ore fam iliarly, T&L. There is no applicat ion cont rol t o t his process ot her t han m odifying OpenGL st at e values: t urning light ing on or off wit h glEnable/ glDisable; changing light ing at t ribut es wit h glLight and glLightModel; changing m at erial propert ies wit h glMaterial; or m odifying t he m odelview m at rix by calling m at rix m anipulat ion funct ions such as glMatrixMode, glLoadMatrix, glMultMatrix, glRotate, glScale, glTranslate. At t his st age of processing, each vert ex is t reat ed independent ly. The vert ex posit ion com put ed by t he t ransform at ion st age is used in subsequent clipping operat ions. The t ransform at ion pr ocess is discussed in det ail in Sect ion 1.9. Light ing effect s in OpenGL are cont rolled by m anipulat ion of t he at t ribut es of one or m ore of t he sim ulat ed light sources defined in OpenGL. The num ber of light sources support ed by an OpenGL im plem ent at ion is specifically lim it ed t o GL_MAX_LI GHTS. This value can be queried

wit h glGet and m ust be at least 8. Each sim ulat ed light sour ce in OpenGL has at t ribut es t hat cause it t o behave as a direct ional light source, a point light source, or a spot light . Light at t ribut es t hat can be adj ust ed by an applicat ion include t he color of t he em it t ed light , defined as am bient , diffuse, and specular RGBA int ensit y values; t he light source posit ion; at t enuat ion fact ors t hat define how rapidly t he int ensit y drops off as a funct ion of dist ance; and direct ion, exponent , and cut off fact ors for spot light s. These at t ribut es can be m odified for any light wit h glLight. I ndividual light s can be t urned on or off by a call t o glEnable/glDisable wit h a sym bolic const ant t hat specifies t he affect ed light source. Light ing produces a pr im ary and secondary color for each ver t ex. The ent ire process of light ing can be t ur ned on or off by a call t o glEnable/glDisable wit h t he sym bolic const ant GL_LI GHTI NG. I f light ing is disabled, t he values of t he prim ary and secondary color are t aken from t he last color value set wit h t he glColor com m and and t he last secondary color set wit h t he glSecondaryColor com m and. The effect s from enabled light sources are used in conj unct ion wit h surface m at erial propert ies t o det erm ine t he lit color at a part icular vert ex. Mat er ials are charact erized by t he color of light t hey em it ; t he color of am bient , diffuse, and specular light t hey reflect ; and t heir shininess. Mat erial propert ies can be defined separat ely for front - facing surfaces and for back- facing surfaces and ar e specified w it h glMaterial. Global light ing param et ers are cont rolled wit h glLightModel. You can use t his funct ion t o z z

z

z

Set t he value used as t he global am bient light ing value for t he ent ire scene. Specify w het her t he light ing calculat ions assum e a local viewer or one posit ioned at infinit y. ( This affect s t he com put at ion of specular reflect ion angles.) I ndicat e w het her one- or t wo- sided light ing calculat ions are perform ed on polygons. ( I f one- sided, only front m at erial propert ies are used in light ing calculat ions. Ot herwise, norm als are reversed on back- facing polygons and back m at erial propert ies are used t o perform t he light ing com put at ion.) Specify whet her a separat e specular color com ponent is com put ed. ( This specular com ponent is lat er added t o t he result of t he t ext uring st age t o provide specular highlight s.)

1.7.3. Primitive Assembly Aft er vert ex processing, all t he at t r ibut es associat ed wit h each vert ex are com plet ely det erm ined. The vert ex dat a is t hen sent on t o a st age called PRI MI TI VE ASSEMBLY ( 3) . At t his point t he vert ex dat a is collect ed int o com plet e prim it ives. Point s require a single vert ex, lines require t w o, t riangles require t hree, quadrilat erals requir e four, and general polygons can have an arbit rary num ber of vert ices. For t he vert ex- at - a- t im e API , an argum ent t o glBegin specifies t he prim it ive t ype; for vert ex arrays, t he prim it ive t ype is passed as an argum ent t o t he funct ion t hat draw s t he vert ex array. The prim it ive assem bly st age effect ively collect s enough vert ices t o const ruct a single prim it ive, and t hen t his prim it ive is passed on t o t he next st age of processing. The reason t his st age is needed is t hat at t he very next st age, operat ions are perform ed on a set of vert ices, and t he operat ions depend on t he t ype of prim it ive. I n part icular, clipping is done different ly, depending on whet her t he pr im it ive is a point , line, or polygon.

1.7.4. Primitive Processing The next st age of processing ( 4) , act ually consist s of several dist inct st eps t hat have been com bined int o a single box in Figur e 1.1 j ust t o sim plify t he diagram . The first st ep t hat occurs is clipping. This operat ion com pares each prim it ive t o any user- defined clipping planes set by

calling glClipPlane as well as t o t he VI EW VOLUME est ablished by t he MODELVI EW - PROJECT MATRI X, which is t he concat enat ion of t he m odelview and proj ect ion m at r ices. I f t he prim it ive is com plet ely wit hin t he view volum e and t he user- defined clipping planes, it is passed on for subsequent processing. I f it is com plet ely out side t he view volum e or t he user- defined clipping planes, t he prim it ive is rej ect ed, and no furt her processing is required. I f t he pr im it ive is part ially in and part ially out , it is divided ( CLI PPED ) in such a way t hat only t he port ion wit hin t he clip volum e and t he user- defined clipping planes is passed on for furt her processing. Anot her operat ion t hat occur s at t his st age is perspect ive proj ect ion. I f t he current view is a perspect ive view , each vert ex has it s x, y, and z com ponent s divided by it s hom ogeneous coordinat e w . Follow ing t his, each vert ex is t ransform ed by t he current viewport t ransform at ion ( set wit h glDepthRange and glViewport) t o generat e window coordinat es. Cert ain OpenGL st at es can be set t o cause an operat ion called CULLI NG t o be perform ed on polygon prim it ives at t his st age. Wit h t he com put ed window coordinat es, each polygon prim it ive is t est ed t o see whet her it is facing away from t he current viewing posit ion. The culling st at e can be enabled wit h glEnable, and glCullFace can be called t o specify t hat back- facing polygons will be discarded ( culled) , front - facing polygons will be discarded, or bot h will be discarded.

1.7.5. Rasterization Geom et ric prim it ives t hat are passed t hrough t he OpenGL pipeline cont ain a set of dat a at each of t he vert ices of t he pr im it ive. At t he next st age ( 5) , prim it ives ( point s, lines, or polygons) are decom posed int o sm aller unit s corresponding t o pixels in t he dest inat ion fram e buffer. This process is called RASTERI ZATI ON. Each of t hese sm aller unit s generat ed by rast erizat ion is referred t o as a FRAGMENT. For inst ance, a line m ight cover five pixels on t he screen, and t he process of rast erizat ion convert s t he line ( defined by t wo vert ices) int o five fragm ent s. A fragm ent com prises a window coordinat e and dept h and ot her associat ed at t ribut es such as color, t ext ure coordinat es, and so on. The values for each of t hese at t r ibut es are det erm ined by int erpolat ion bet w een t he values specified ( or com put ed) at t he vert ices of t he pr im it ive. At t he t im e t hey are rast erized, vert ices have a prim ary color and a secondary color. The glShadeModel funct ion specifies whet her t hese color values are int erpolat ed bet w een t he ver t ices ( SMOOTH SHADI NG) or whet her t he color values for t he last vert ex of t he prim it ive are used for t he ent ire pr im it ive ( FLAT SHADI NG) . Each t ype of prim it ive has different rast erizat ion rules and different OpenGL st at e. Point s have a widt h cont rolled by glPointSize and ot her rendering at t ribut es t hat are defined by glPointParameter. OpenGL 2.0 added t he abilit y t o dr aw an arbit r ary shape at each point posit ion by m eans of a t ext ure called a POI NT SPRI TE. Lines have a widt h t hat is cont rolled wit h glLineWidth and a st ipple pat t ern t hat is set wit h glLineStipple. Polygons have a st ipple pat t ern t hat is set wit h glPolygonStipple. Polygons can be dr awn as filled, out line, or vert ex point s depending only on t he value set wit h glPolygonMode. The dept h values for each fragm ent in a polygon can be m odified by a value t hat is com put ed wit h t he st at e set wit h glPolygonOffset. The orient at ion of polygons t hat are t o be considered front facing can be set wit h glFrontFace. The process of sm oot hing t he j agged appearance of a prim it ive is called ANTI ALI ASI NG. Prim it ive ant ialiasing can be enabled wit h glEnable and t he appropriat e sym bolic const ant : GL_POI NT_SMOOTH, GL_LI NE_SMOOTH, or GL_POLYGON_SMOOTH.

1.7.6. Fragment Processing Aft er fragm ent s have been generat ed by rast erizat ion, a num ber of oper at ions occur on fragm ent s. Collect ively, t hese operat ions are called FRAGMENT PROCESSI NG ( 6) . Perhaps t he m ost im port ant operat ion t hat occurs at t his point is called TEXTURE MAPPI NG. I n t his operat ion, t he t ext ure coordinat es associat ed wit h t he fragm ent are used t o access a region of graphics m em ory called TEXTURE MEMORY ( 7) . OpenGL defines a lot of st at e values t hat affect how t ext ures are accessed as well as how t he ret rieved values are applied t o t he current fragm ent . Many ext ensions have been defined t o t his area t hat is rat her com plex t o begin wit h. We spend som e t im e t alking about t ext uring operat ions in Sect ion 1.10.

Ot her operat ions t hat occur at t his point are FOG ( m odifying t he color of t he fr agm ent depending on it s dist ance from t he view point ) and COLOR SUM ( com bining t he values of t he fragm ent 's prim ary color and secondary color) . Fog param et ers ar e set wit h glFog, and secondary colors are vert ex at t ribut es t hat can be passed in wit h t he vert ex at t ribut e com m and glSecondaryColor or t hat can be com put ed by t he light ing st age.

1.7.7. Per-Fragment Operations Aft er fragm ent processing, fragm ent s are subm it t ed t o a set of fairly sim ple operat ions called PER- FRAGMENT OPERATI ONS ( 8) . These include t est s like t he following: z PI XEL OWNERSHI P TEST

Det erm ines whet her t he dest inat ion pixel is visible or obscured by an overlapping window

z SCI SSOR TEST

Clips fragm ent s against a rect angular region set wit h glScissor

z ALPHA TEST

Decides whet her t o discard t he fragm ent on t he basis of t he fr agm ent 's value and t he funct ion set wit h glAlphaFunc

ALPHA

z STENCI L TEST

Com pares t he value in t he st encil buffer w it h a reference value, using a com parison set w it h glStencilFunc and glStencilOp, by which it decides t he fat e of t he fragm ent

z DEPTH TEST

Uses t he funct ion est ablished wit h glDepthFunc t o com pare t he dept h of t he incom ing fragm ent t o t he dept h st ored in t he fram e buffer

Blending, dit hering, and logical operat ions are also considered per - fragm ent operat ions. The blending operat ion calculat es t he color t o be writ t en int o t he fram e buffer using a blend of t he fragm ent 's color, t he color st ored in t he fram e buffer, and t he blending st at e as est ablished by glBlendFunc, glBlendColor, and glBlendEquation. Dit hering is a m et hod of t rading spat ial resolut ion for color resolut ion, but t oday's graphics accelerat ors cont ain enough fram e buffer m em ory t o m ake t his t r ade- off unnecessary. The final fragm ent value is writ t en int o t he fram e buffer wit h t he logical operat ion set by glLogicOp. Each of t he per- fragm ent operat ions is concept ually sim ple and nowadays can be im plem ent ed efficient ly and inexpensively in hardware. Som e of t hese operat ions also involve reading values from t he fram e buffer ( i.e., color, dept h, or st encil) . Wit h t oday's hardware, all t hese back- end rendering operat ions can be perform ed at m illions of pixels per second, even t hose t hat require reading from t he fram e buffer.

1.7.8. Frame Buffer Operations Things t hat cont rol or affect t he w hole fram e buffer are called FRAME BUFFER OPERATI ONS ( 9) . Cert ain OpenGL st at e cont rols t he region of t he fram e buffer int o which prim it ives are drawn. OpenGL support s display of st ereo im ages as well as double buffering, so a num ber of choices are available for t he rendering dest inat ion. Regions of t he fram e buffer are called BUFFERS and are referred t o as t he front , back, left , right , fr ont left , front right , back left , back right , fr ont and back, and aux0, aux1, and so on up t o t he num ber of auxiliary buffers support ed m inus 1. Any of t hese buffers can be set as t he dest ination for subsequent r endering operat ions w it h glDrawBuffer. Mult iple buffers can be est ablished as t he dest inat ion for rendering wit h glDrawBuffers. Regions wit hin t he draw buffer( s) can be writ e prot ect ed. The glColorMask funct ion det erm ines whet her writ ing is allowed t o t he red, green, blue, or alpha com ponent s of t he dest inat ion buffer. The glDepthMask funct ion det erm ines whet her t he dept h com ponent s of t he dest inat ion buffer can be m odified. The glStencilMask funct ion cont rols t he writ ing of part icular bit s in t he st encil com ponent s of t he dest inat ion buffer. Values in t he fram e buffer can be init ialized wit h glClear. Values t hat will be used t o init ialize t he color com ponent s, dept h com ponent s, st encil com ponent s, and accum ulat ion buffer com ponent s are set wit h glClearColor,

glClearDepth, glClearStencil, and glClearAccum, respect ively. The accum ulat ion buffer operat ion can be specified w it h glAccum.

For perform ance, OpenGL im plem ent at ions oft en em ploy a variet y of buffering schem es in order t o send larger bat ches of graphics pr im it ives t o t he 3D graphics hardwar e. To m ake sure t hat all graphics prim it ives for a specific rendering cont ext are progressing t oward com plet ion, an applicat ion should call glFlush. To m ake sure t hat all graphics prim it ives for a part icular rendering cont ext have finished rendering, an applicat ion should call glFinish. This com m and blocks unt il t he effect s of all pr evious com m ands have been com plet ed. Blocking can be cost ly in t erm s of perform ance, so glFinish should be used sparingly. The overall effect of t hese st ages is t hat graphics prim it ives defined by t he applicat ion are convert ed int o pixels in t he fram e buffer for subsequent display. But so far, we have discussed only geom et ric prim it ives such as point s, lines, and polygons. OpenGL also renders bit m ap and im age dat a.

1.8. Drawing Images As m ent ioned previously, OpenGL has a great deal of support for dr awing im ages in addit ion t o it s support for drawing 3D geom et ry. I n OpenGL parlance, im ages are called PI XEL RECTANGLES. The values t hat define a pixel rect angle st art out in applicat ion- cont rolled m em ory as shown in Figur e 1.1 ( 11) . Color or grayscale pixel rect angles are rendered int o t he fram e buffer w it h glDrawPixels, and bit m aps are rendered int o t he fram e buffer wit h glBitmap. I m ages t hat are dest ined for t ext ure m em ory are specified wit h glTexImage or glTexSubImage. Up t o a point , t he sam e basic pr ocessing is applied t o t he im age dat a supplied wit h each of t hese com m ands.

1.8.1. Pixel Unpacking OpenGL reads im age dat a provided by t he applicat ion in a variet y of form at s. Param et ers t hat define how t he im age dat a is st ored in m em ory ( lengt h of each pixel row, num ber of rows t o skip before t he first one, num ber of pixels t o skip before t he first one in each row , et c.) can be specified wit h glPixelStore. So t hat operat ions on pixel dat a can be defined m ore precisely, pixels read from applicat ion m em ory ar e convert ed int o a coherent st ream of pixels by an operat ion referred t o as PI XEL UNPACKI NG ( 12) . When a pixel rect angle is t ransferred t o OpenGL by a call like glDrawPixels, t his operat ion applies t he current set of pixel unpacking param et ers t o det erm ine how t he im age dat a should be read and int erpret ed. As each pixel is read from m em ory, it is convert ed t o a PI XEL GROUP t hat cont ains eit her a color, a dept h, or a st encil value. I f t he pixel group consist s of a color, t he im age dat a is dest ined for t he color buffer in t he fram e buffer. I f t he pixel gr oup consist s of a dept h value, t he im age dat a is dest ined for t he dept h buffer. I f t he pixel group consist s of a st encil value, t he im age dat a is dest ined for t he st encil buffer. Color values ar e m ade up of a r ed, a green, a blue, and an alpha com ponent ( i.e., RGBA) and are const ruct ed from t he input im age dat a according t o a set of rules defined by OpenGL. The result is a st ream of RGBA values t hat are sent t o OpenGL for furt her processing.

1.8.2. Pixel Transfer Aft er a coherent st ream of im age pixels is cr eat ed, pixel rect angles undergo a series of operat ions called PI XEL TRANSFER ( 13) . These operat ions are applied whenever pixel rect angles are t ransferred from t he applicat ion t o OpenGL ( glDrawPixels, glTexImage, glTexSubImage) , from OpenGL back t o t he applicat ion ( glReadPixels) , or w hen t hey ar e copied wit hin OpenGL ( glCopyPixels, glCopyTexImage, glCopyTexSubImage) . The behavior of t he pixel t ransfer st age is m odified wit h glPixelTransfer. This com m and set s st at e t hat cont rols whet her red, green, blue, alpha, and dept h values are scaled and biased. I t can also set st at e t hat det erm ines whet her incom ing color or st encil values are m apped t o different color or st encil values t hrough t he use of a lookup t able. The lookup t ables used for t hese operat ions are specified wit h t he glPixelMap com m and. Som e addit ional operat ions t hat occur at t his st age are part of t he OpenGL I MAGI NG SUBSET, which is an opt ional par t of OpenGL. Hardware vendors t hat find it im port ant t o support advanced im aging capabilit ies will support t he im aging subset in t heir OpenGL im plem ent at ions, and ot her vendors will not support it . To det erm ine whet her t he im aging subset is suppor t ed, applicat ions need t o call glGetString wit h t he sym bolic const ant GL_EXTENSI ONS. This ret urns a list of ext ensions support ed by t he im plem ent at ion; t he applicat ion should check for t he presence of t he st ring " ARB_im aging" wit hin t he ret urned ext ension st ring. The pixel t ransfer operat ions t hat are defined t o be part of t he im aging subset are convolut ion, color m at rix, hist ogram , m in/ m ax, and addit ional color lookup t ables. Toget her, t hey provide powerful im age processing and color correct ion operat ions on im age dat a as it is being t ransferred t o, from , or wit hin OpenGL.

1.8.3. Rasterization and Back-End Processing Following t he pixel t ransfer st age, fragm ent s are generat ed t hrough rast erizat ion of pixel rect angles in m uch t he sam e way as t hey are generat ed from 3D geom et ry ( 14) . This pr ocess, along wit h t he current OpenGL st at e, det erm ines w here t he im age w ill be draw n in t he fram e buffer. Rast erizat ion t akes int o account t he current RASTER POSI TI ON , which can be set wit h glRasterPos or glWindowPos, and t he current zoom fact or, which can be set wit h glPixelZoom and which causes an im age t o be m agnified or reduced in size as it is drawn. Aft er fragm ent s have been generat ed from pixel rect angles, t hey undergo t he sam e set of fragm ent processing oper at ions as geom et ric prim it ives ( 6) and t hen go on t o t he rem ainder of t he OpenGL pipeline in exact ly t he sam e m anner as geom et ric prim it ives, all t he way unt il pixels are deposit ed in t he fram e buffer ( 8, 9, 10) . Pixel values provided t hrough a call t o glTexImage or glTexSubImage do not go t hrough rast erizat ion or t he subsequent fragm ent processing but direct ly updat e t he appropriat e port ion of t ext ure m em ory ( 15) .

1.8.4. Read Control Pixel rect angles are read from t he fram e buffer and ret urned t o applicat ion m em ory wit h glReadPixels. They can also be read fr om t he fram e buffer and writ t en t o anot her port ion of t he fram e buffer wit h glCopyPixels, or t hey can be read from t he fr am e buffer and writ t en int o t ext ure m em ory wit h glCopyTexImage or glCopyTexSubImage. I n all of t hese cases, t he port ion of t he fram e buffer t hat is t o be read is cont rolled by t he READ CONTROL st age of OpenGL and set wit h t he glReadBuffer com m and ( 16) . The values read from t he fram e buffer are sent t hrough t he pixel t ransfer st age ( 13) in which various im age processing operat ions can be perform ed. For copy operat ions, t he result ing pixels are sent t o t ext ure m em ory or back int o t he fram e buffer, depending on t he com m and t hat init iat ed t he t ransfer. For read operat ions, t he pixels are for m at t ed for st orage in applicat ion m em ory under t he cont rol of t he PI XEL PACKI NG st age ( 17) . This st age is t he m irr or of t he pixel unpacking st age ( 12) , in t hat param et ers t hat define how t he im age dat a is t o be st ored in m em ory ( lengt h of each pixel row, num ber of rows t o skip before t he first one, num ber of pixels t o skip before t he first one in each row, et c.) can be specified wit h glPixelStore. Thus, applicat ion developers enj oy a lot of flexibilit y in det erm ining how t he im age dat a is ret ur ned from OpenGL int o applicat ion m em ory.

1.9. Coordinate Transforms The purpose of t he OpenGL graphics processing pipeline is t o convert t hreedim ensional descript ions of obj ect s int o a t wo- dim ensional im age t hat can be displayed. I n m any ways, t his process is sim ilar t o using a cam era t o convert a real- world scene int o a t wo- dim ensional print . To accom plish t he t ransform at ion from t hree dim ensions t o t wo, OpenGL defines several coordinat e spaces and t ransform at ions bet ween t hose spaces. Each coordinat e space has som e propert ies t hat m ake it useful for som e part of t he rendering process. The t ransform at ions defined by OpenGL afford applicat ions a gr eat deal of flexibilit y in defining t he 3D- t o- 2D m apping. For success at writ ing shaders in t he OpenGL Shading Language, underst anding t he various t ransform at ions and coor dinat e spaces used by OpenGL is essent ial. I n com put er graphics, MODELI NG is t he process of defining a num erical r epresent at ion of an obj ect t hat is t o be render ed. For OpenGL, t his usually m eans creat ing a polygonal represent at ion of an obj ect so t hat it can be drawn wit h t he polygon prim it ives built int o OpenGL. At a m inim um , a polygonal represent at ion of an obj ect needs t o include t he coordinat es of each vert ex in each polygon and t he connect ivit y inform at ion t hat defines t he polygons. Addit ional dat a m ight include t he color of each vert ex, t he sur face norm al at each ver t ex, one or m ore t ext ure coordinat es at each vert ex, and so on. I n t he past , m odeling an obj ect was a painst aking effort , requiring pr ecise physical m easurem ent and dat a ent ry. ( This is one of t he reasons t he Ut ah t eapot , m odeled by Mart in Newell in 1975, has been used in so m any gr aphics im ages. I t is an int erest ing obj ect , and t he num erical dat a is fr eely available. Several of t he shaders present ed in t his book are illust rat ed wit h t his obj ect ; see, for exam ple, Color Plat e 24.) More recent ly, a variet y of m odeling t ools have becom e available, bot h hardware and soft ware, and t his has m ade it relat ively easy t o creat e num erical repr esent at ions of t hr eedim ensional obj ect s t hat are t o be rendered. Three- dim ensional obj ect at t ribut es, such as vert ex posit ions and surface norm als, are defined in OBJECT SPACE. This coordinat e space is one t hat is convenient for describing t he obj ect t hat is being m odeled. Coordinat es are specified in unit s t hat are convenient t o t hat part icular obj ect . Microscopic obj ect s m ay be m odeled in unit s of angst rom s, everyday obj ect s m ay be m odeled in inches or cent im et ers, buildings m ight be m odeled in feet or m et ers, planet s could be m odeled in m iles or kilom et ers, and galaxies m ight be m odeled in light years or parsecs. The origin of t his coordinat e syst em ( i.e., t he point ( 0, 0, 0) ) is also som et hing t hat is convenient for t he obj ect being m odeled. For som e obj ect s, t he origin m ight be placed at one corner of t he obj ect 's t hree- dim ensional bounding box. For ot her obj ect s, it m ight be m ore convenient t o define t he origin at t he cent roid of t he obj ect . Because of it s int im at e connect ion wit h t he t ask of m odeling, t his coordinat e space is also oft en referred t o as MODEL SPACE or t he MODELI NG COORDI NATE SYSTEM. Coordinat es are referred t o equivalent ly as obj ect coordinat es or m odeling coordinat es. To com pose a scene t hat cont ains a variet y of t hree- dim ensional obj ect s, each of which m ight be defined in it s own unique obj ect space, we need a com m on coordinat e syst em . This com m on coordinat e syst em is called WORLD SPACE or t he WORLD COORDI NATE SYSTEM, and it provides a com m on fram e of reference for all obj ect s in t he scene. Once all t he obj ect s in t he scene are t ransform ed int o a single coordinat e syst em , t he spat ial relat ionships bet ween all t he obj ect s, t he light sources, and t he viewer are know n. The unit s of t his coordinat e syst em are chosen in a way t hat is convenient for describing a scene. You m ight choose feet or m et ers if you are com posing a scene t hat represent s one of t he room s in your house, but you m ight choose cit y blocks as your unit s if you are com posing a scene t hat repr esent s a cit y skyline. The choice for t he origin of t his coordinat e syst em is also arbit rary. You m ight define a t hree- dim ensional bounding box for your scene and set t he origin at t he corner of t he bounding box such t hat all of t he ot her coor dinat es of t he bounding box have posit ive values. Or you m ay want t o pick an im port ant point in your scene ( t he corner of a building, t he locat ion of a key charact er, et c.) and m ake t hat t he origin.

Aft er world space is defined, all t he obj ect s in t he scene m ust be t ransform ed from t heir own unique obj ect coordinat es int o world coordinat es. The t ransform at ion t hat t akes coordinat es from obj ect space t o world space is called t he MODELI NG TRANSFORMATI ON. I f t he obj ect 's m odeling coordinat es are in feet but t he world coordinat e syst em is defined in t erm s of inches, t he obj ect coordinat es m ust be scaled by a fact or of 12 t o produce world coordinat es. I f t he obj ect is defined t o be facing forward but in t he scene it needs t o be facing backwards, a rot at ion m ust be applied t o t he obj ect coordinat es. A t ranslat ion is also t ypically required t o posit ion t he obj ect at it s desired locat ion in world coordinat es. All of t hese individual t ransform at ions can be put t oget her int o a single m at rix, t he MODEL TRANSFORMATI ON MATRI X, t hat represent s t he t ransform at ion from obj ect coordinat es t o world coordinat es. Aft er t he scene has been com posed, t he view ing param et ers m ust be specified. One aspect of t he view is t he vant age point ( i.e., t he eye or cam era posit ion) from which t he scene will be viewed. Viewing param et ers also include t he focus point ( also called t he lookat point or t he direct ion in which t he cam era is point ed) and t he up direct ion ( e.g., t he cam era m ay be held sideways or upside down) . The viewing param et ers collect ively define t he VI EWI NG TRANSFORMATI ON, and t hey can be com bined int o a m at rix called t he VI EWI NG MATRI X. A coordinat e m ult iplied by t his m at rix is t ransform ed from world space int o EYE SPACE, also called t he EYE COORDI NATE SYSTEM. By definit ion, t he origin of t his coordinat e syst em is at t he viewing ( or eye) posit ion. Coordinat es in t his space are called eye coordinat es. The spat ial relat ionships in t he scene rem ain unchanged, but orient ing t he coordinat e syst em in t his way m akes it easy t o det erm ine t he dist ance from t he viewpoint t o various obj ect s in t he scene. Alt hough som e 3D graphics API s allow applicat ions t o separat ely specify t he m odeling m at rix and t he view ing m at r ix, OpenGL com bines t hem int o a single m at rix called t he MODELVI EW MATRI X. This m at rix is defined t o t ransform coordinat es from obj ect space int o eye space ( see Figur e 1.2) .

Figu r e 1 .2 . Coor din a t e spa ce s a n d t r a n sfor m s in Ope n GL

You can m anipulat e a num ber of m at rices in OpenGL. Call t he glMatrixMode funct ion t o select t he m odelview m at rix or one of OpenGL's ot her m at rices. Load t he current m at rix wit h t he ident it y m at r ix by calling glLoadIdentity, or replace it wit h an arbit rary m at rix by calling glLoadMatrix. Be sure you know what you're doing if you specify an arbit rary m at rixt he t ransform at ion m ight give you a com plet ely incom prehensible im age! You can also m ult iply t he current m at rix by an arbit rary m at rix by calling glMultMatrix. Applicat ions oft en st art by set t ing t he current m odelview m at rix t o t he view m at rix and t hen add on t he necessary m odeling m at rices. You can set t he m odelview m at rix t o a reasonable viewing t ransform at ion wit h t he gluLookAt funct ion. ( This funct ion is not part of OpenGL proper but is part of t he OpenGL ut ilit y library t hat is provided wit h every OpenGL im plem ent at ion.) OpenGL act ually support s a st ack of m odelview m at r ices, and you can duplicat e t he t opm ost m at r ix and copy it ont o t he t op of t he st ack wit h glPushMatrix. When t his is done, you can concat enat e ot her t ransform at ions t o t he t opm ost m at rix wit h t he funct ions glScale, glTranslate, and glRotate t o define t he m odeling t ransform at ion for a part icular t hreedim ensional obj ect in t he scene. Then, pop t his t opm ost m at rix off t he st ack wit h glPopMatrix t o get back t o t he original view t ransform at ion m at rix. Repeat t he process for each obj ect in t he scene. At t he t im e light source posit ions are specified wit h t he glLight funct ion, t hey are t r ansform ed by t he current m odelview m at rix. Therefore, light posit ions are st ored wit hin OpenGL as eye coordinat es. You m ust set up t he m odelview m at rix t o perform t he proper t r ansform at ion before light posit ions are specified or you won't get t he light ing effect s t hat you expect . The light ing calculat ions t hat occur in OpenGL are defined t o happen on a per- vert ex basis in t he eye coordinat e syst em . For t he necessary reflect ion com put at ions, light posit ions and surface norm als m ust be in t he sam e coordinat e system . OpenGL im plem ent at ions oft en choose t o do light ing calculat ions in eye space; t herefore, t he incom ing surface nor m als have t o be t ransform ed int o eye space as w ell. You accom plish t his by t ransform ing surface norm als by t he inverse t ranspose of t he upper left m ost 3 x 3 m at rix t aken from t he m odelview m at rix. At t hat point , you can apply t he pervert ex light ing form ulas defined by OpenGL t o det erm ine t he lit color at each vert ex. Aft er coordinat es have been t ransform ed int o eye space, t he next t hing is t o define a viewing volum e. This is t he region of t he t hree- dim ensional scene t hat is visible in t he final im age. The t ransform at ion t hat t akes t he obj ect s in t he viewing volum e int o CLI P SPACE ( also known as t he CLI PPI NG COORDI NATE SYSTEM , a coordinat e space t hat is suit able for clipping) is called t he PROJECTI ON TRANSFORMATI ON . I n OpenGL, you est ablish t he proj ect ion t r ansform at ion by calling glMatrixMode t o select t he proj ect ion m at rix and t hen set t ing t his m at rix appropriat ely. Param et ers t hat m ay go int o creat ing an appropriat e proj ect ion m at rix are t he field of view ( how m uch of t he scene is visible) , t he aspect rat io ( t he horizont al field of view m ay differ from t he vert ical field of view) , and near and far clipping planes t o elim inat e t hings t hat are t oo far aw ay or t oo close ( for perspect ive proj ect ions, weirdness will occur if you t ry t o draw t hings t hat are at or behind t he viewing posit ion) . Three ut ilit y funct ions set t he pr oj ect ion m at rix: glOrtho, glFrustum, and gluPerspective. The difference bet w een t hese funct ions is t hat glOrtho defines a parallel proj ect ion ( i.e., parallel lines in t he scene are pr oj ect ed t o parallel lines in t he final t w o- dim ensional im age) , whereas glFrustum and gluPerspective define perspect ive proj ect ions ( i.e., parallel lines in t he scene are foreshort ened t o pr oduce a vanishing point in t he im age, such as r ailroad t racks converging t o a point in t he dist ance) .

FRUSTUM CLI PPI NG is t he process of elim inat ing any graphics pr im it ives t hat lie out side an axisaligned cube in clip space. This cube is defined such t hat t he x, y, and z com ponent s of t he clip space coordinat e are less t han or equal t o t he w com ponent for t he coordinat e, and great er t han or equal t o - w ( i.e., - w x w, - w y w, and - w z w) . Graphics prim it ives ( or port ions t hereof) t hat lie out side t his cube are discarded. Frust um clipping is always perform ed on all incom ing prim it ives in OpenGL. USER CLI PPI NG, on t he ot her hand, is a feat ure t hat can be enabled or disabled by t he applicat ion. Applicat ions can call glClipPlane t o specify one or m ore clipping planes t hat furt her rest rict t he size of t he viewing volum e, and each clipping plane can be individually enabled w it h glEnable. At t he t im e user clipping planes are specified, OpenGL t ransform s t hem int o eye space using t he inverse of t he current m odelview m at rix. Each plane specified in t his m anner defines a half- space, and only t he port ions of pr im it ives t hat lie wit hin t he int ersect ion of t he view volum e and all of t he enabled half- spaces defined by user clipping planes are drawn. The next st ep in t he t ransform at ion of vert ex posit ions is t he perspect ive divide. This operat ion divides each com ponent of t he clip space coordinat e by t he hom ogeneous coordinat e w . The result ing x, y, and z com ponent s range from [ - 1,1] , and t he result ing w coordinat e is alw ays 1, so it is no longer needed. I n ot her wor ds, all t he visible graphics prim it ives are t r ansform ed int o a cubic region bet ween t he point ( - 1, - 1, - 1) and t he point ( 1, 1, 1) . This is t he NORMALI ZED DEVI CE COORDI NATE SPACE, which is an int erm ediat e space t hat allows t he viewing area t o be properly m apped ont o a viewport of arbit rary size and dept h. Pixels wit hin a window on t he display device aren't referred t o wit h float ing- point coordinat es from - 1 t o 1; t hey are usually referred t o wit h coordinat es defined in t he WI NDOW COORDI NATE SYSTEM, where x values range from 0 t o t he widt h of t he window m inus 1, and y values range from 0 t o t he height of t he window m inus 1. Therefore, one m ore t ransform at ion st ep is required. The VI EWPORT TRANSFORMATI ON specifies t he m apping from norm alized device coordinat es int o window coordinat es. You specify t his m apping by calling t he OpenGL funct ions glViewport, which specifies t he m apping of t he x and y coordinat es, and glDepthRange, which specifies t he m apping of t he z coordinat e. Graphics prim it ives are rast erized in t he window coordinat e syst em .

1.10. Texturing The area of t ext ure m apping is one of t he m ore com plex areas of t he OpenGL API . I t has been ext ended m ore oft en t han m ost of t he ot her areas of OpenGL prim arily because t his was t he area of graphics for w hich hardw are was t he least m at ure when OpenGL was defined in t he early 1990s. The program m abilit y added t hrough t he OpenGL Shading Language in OpenGL 2.0 m akes t his area m uch m ore st raight forw ard, but t he exist ing OpenGL API s are st ill used t o creat e, m odify, and define t he behavior of t ext ures. This sect ion describes t he t ext uring funct ionalit y as it exist ed for OpenGL 1.5. Som e significant changes have been m ade t o t his m odel by OpenGL 2.0, part icularly t o t he concept of t ext ure unit s, and are described lat er in t his book. OpenGL current ly support s four basic t ypes of t ext ure m aps: onedim ensional, t wo- dim ensional, t hree- dim ensional, and cube m aps. ( Only one- and t w o- dim ensional t ext ures were support ed in OpenGL 1.0.) A 1D TEXTURE is an array cont aining widt h pixel values, a 2D TEXTURE is an array cont aining widt h x height pixel values, and a 3D TEXTURE is an array cont aining widt h x height x dept h pixel values. A CUBE MAP TEXTURE cont ains six t wo- dim ensional t ext ures: one for each m aj or axis direct ion ( i.e., ± x, ± y, and ± z) . OpenGL has t he not ion of a TEXTURE UNI T. A t ext ure unit corresponds t o t he underlying piece of graphics hardware t hat perform s t he var ious t ext uring operat ions. Wit h OpenGL 1.3, support was added for m ult iple t ext ure unit s. Each t ext ure unit m aint ains t he following st at e for perform ing t ext uring oper at ions: z

Enabled/ disabled st at e of t he t ext ure unit

z

Text ure m at rix st ack t hat for t ransform ing incom ing t ext ure coordinat es

z

St at e used for aut om at ic t ext ure coordinat e generat ion

z

Text ure environm ent st at e

z

Curr ent 1D t ext ure

z

Curr ent 2D t ext ure

z

Curr ent 3D t ext ure

z

Current cube m ap t ext ure

Com m ands t o set t he st at e in t he preceding list operat e on t he ACTI VE TEXTURE UNI T. Text ure unit s are num bered fr om 0 t o GL_MAX_TEXTURE_UNI TS 1 ( a value t hat can be queried wit h glGet) , and t he act ive t ext ur e unit can be set wit h glActiveTexture wit h a sym bolic const ant indicat ing t he desired t ext ure unit . Subsequent com m ands t o set st at e in t he preceding list operat e on only t he act ive t ext ur e unit . A t ext ure unit can be enabled for 1D, 2D, 3D, or cube m ap t ext uring by calling glEnable wit h t he appropriat e sym bolic const ant . The act ive t ext ure unit specifies t he t ext ure unit accessed by com m ands involving t ext ure coordinat e pr ocessing. Such com m ands include t hose accessing t he current t ext ure m at rix st ack ( if GL_MATRI X_MODE is GL_TEXTURE) , glTexGen, glEnable/glDisable ( if any enum erat ed value for t ext ure coordinat e generat ion is select ed) , as well as queries of t he current t ext ure coordinat es and current rast er t ext ure coordinat es. The act ive t ext ure unit select or also select s t he t ext ure unit accessed by com m ands involving t ext ure im age processing. Such com m ands include all variant s of glTexEnv, glTexParameter, and glTexImage com m ands; glBindTexture; glEnable/glDisable for

any t ext ure t arget ( e.g., GL_TEXTURE_2D) ; and queries of all such st at e. A TEXTURE OBJECT is creat ed as follows: call glBindTexture and provide a t ext ure t arget ( a sym bolic const ant t hat indicat es whet her t he t ext ure will be a 1D, 2D, 3D, or cube m ap t ext ure) and a previously unused t ext ure nam e ( an int eger ot her t han zero) t hat can be used t o refer t o t he newly creat ed t ext ure obj ect . The newly creat ed t ext ure obj ect also becom es act ive and is used in subsequent t ext uring operat ions. I f glBindTexture is called wit h a t ext ure nam e t hat has already been used, t hat previously creat ed t ext ure becom es act ive. I n t his way, an applicat ion can cr eat e any num ber of t ext ures and sw it ch bet ween t hem easily. Aft er a t ext ure obj ect has been creat ed, t he pixel values t hat define t he t ext ure can be provided. Pixel values for a 3D t ext ure can be supplied by glTexImage3D, pixel values for 2D or cube m ap t ext ures can be provided by glTexImage2D, and pixel values for a 1D t ext ure can be specified by glTexImage1D. I n versions 1.01.5 of OpenGL, when any of t hese t hree com m ands was used, each dim ension of t he t ext ure m ap had t o be a size t hat was a power of 2 ( including t he border widt h) . OpenGL 2.0 allows t ext ures t o have sizes t hat are not rest rict ed t o being powers of 2. These funct ions all work in t he sam e way as glDrawPixels, except t hat t he pixels const it ut ing a t ext ure are deposit ed int o t ext ure m em ory before rast erizat ion. I f only a port ion of a t ext ure needs t o be respecified, t he glTexSubImage1D/2D/3D funct ions can be used. When any of t hese t hree com m ands is used, t here is no power- of- 2 rest rict ion on t he t ext ure size. Text ures can be creat ed or m odified wit h values copied from fram e buffer m em ory by glCopyTexImage1D/2D or glCopyTexSubImage1D/2D/3D. OpenGL also provides a m et hod for specifying t ext ures wit h com pressed im age form at s. Applicat ions can use t he com m ands glCompressedTexImage1D/2D/3D and glCompressedTexSubImage1D/2D/3D t o cr eat e and st ore com pressed t ext ures in t ext ure m em ory. Com pressed t ext ures m ay use significant ly less m em ory on t he gr aphics accelerat or and t hereby enhance an applicat ion's funct ionalit y or perform ance. St andard OpenGL does not define any part icular com pressed im age form at s, so applicat ions need t o query t he ext ension st ring in order t o det erm ine t he com pressed t ext ure form at s support ed by a part icular im plem ent at ion. Each of t he preceding t ext ure creat ion com m ands includes a LEVEL- OF- DETAI L argum ent t hat support s t he creat ion of MI PMAP TEXTURES. A m ipm ap t ext ure is an ordered set of arrays represent ing t he sam e im age. Each array has a resolut ion t hat is half t he pr evious one in each dim ension. The idea behind m ipm aps is t hat m ore pleasing final im ages will result if t he t ext ure t o be used has roughly t he sam e resolut ion as t he obj ect being drawn on t he display. I f a m ipm ap t ext ure is supplied, OpenGL can aut om at ically choose t he appr opriat ely sized t ext ur e ( i.e., MI PMAP LEVEL) for use in drawing t he obj ect on t he display. I nt erpolat ion bet ween t he TEXELS ( pixels t hat com prise a t ext ure) of t wo m ipm ap levels can also be perform ed. Obj ect s t hat are t ext ured wit h m ipm ap t ext ures can t herefore be rendered wit h high qualit y, no m at t er how t hey change size on t he display. Aft er a t ext ure obj ect has been defined and bound t o a t ext ure unit , propert ies ot her t han t he pixels t hat define t he t ext ure can be m odified wit h t he com m and glTexParameter. This com m and set s param et ers t hat cont rol how t he t ext ure obj ect is t reat ed when it is specified, changed, or accessed. Text ure obj ect param et ers include z

z

z

The wrapping behavior in each dim ensionWhet her t he t ext ur e r epeat s, clam ps, or is m ir rored when t ext ure coordinat es go out side t he range [ 0,1] The m inificat ion filt erHow t he t ext ure is t o be sam pled if t he m apping from t ext ure space t o window space causes t he t ext ure im age t o be m ade sm aller t han a one- t o- one pixel m apping in order t o be m apped ont o t he surface The m agnificat ion filt erHow t he t ext ure is t o be sam pled if t he m apping from t ext ure space t o window space causes t he t ext ure im age t o be m ade larger t han a one- t o- one pixel m apping in order t o be m apped ont o t he surface

z z

z

The border color t o be used if t he wrapping behavior indicat es clam ping t o a border color The pr iorit y t o be assigned t o t he t ext ureA value from [ 0,1] t hat t ells OpenGL t he im port ance of perform ance for t his t ext ure Values for clam ping and biasing t he level- of- det ail value t hat is aut om at ically com put ed by OpenGL

z

The level t hat is defined as t he base ( highest - resolut ion) level for a m ipm ap t ext ure

z

The level t hat is defined as t he m axim um ( lowest - resolut ion) level for a m ipm ap t ext ure

z

z

Dept h com parison valuesWhet her a com parison operat ion should be perform ed when t he t ext ure is accessed, what t ype of com parison operat ion should be perform ed, and how t o t reat t he result of t he com parison ( t hese values ar e used wit h dept h t ext ures t o im plem ent shadowing) A value t hat signifies whet her m ipm ap levels are t o be com put ed aut om at ically by OpenGL whenever t he base level is specified or m odified

The m anner in which a t ext ure value is applied t o a graphics prim it ive is cont rolled by t he param et ers of t he t ext ure environm ent , which are set wit h t he glTexEnv funct ion. The set of fixed form ulas for replacing an obj ect color wit h a value com put ed t hrough t ext ure access is rat her lengt hy. Suffice it t o say t hat t ext ure funct ions include replacem ent , m odulat ion, decal applicat ion, blending, adding, enabling point sprit es, and even m ore com plex com bining of red, green, blue, and alpha com ponent s. A wide variet y of t ext uring effect s can be achieved wit h t he flexibilit y provided by t he glTexEnv funct ion. This funct ion can also specify an addit ional pert ext ureunit level- of- det ail bias t hat is added t o t he per- t ext ure- obj ect level- of- det ail bias previously described. OpenGL support s t he concept of m ult it ext uring, by which t he result s of m ore t han one t ext ure access are com bined t o det erm ine t he value of t he fragm ent . Each t ext ure unit has a t ext ure environm ent funct ion. Text ure unit s are connect ed serially. The first t ext ure unit com put es a fragm ent value by using t he t ext ure value t hat it reads fr om t ext ure m em ory and it s t ext ure environm ent funct ion, and passes on t he result t o be used as t he input fr agm ent value for t he second t ext ur e unit . This fragm ent value is used t oget her wit h t he t ext ure environm ent funct ion for t he second t ext ure unit and t he t ext ure value read from t ext ure m em ory by t he second t ext ure unit t o provide t he input fragm ent value for t he t hir d t ext ure unit . This process is repeat ed for all enabled t ext ure unit s. Aft er t ext ure obj ect s have been defined and one or m ore t ext ur e unit s have been properly set up and enabled, t ext uring is perform ed on all subsequent gr aphics prim it ives. Text ure coordinat es are supplied at each vert ex wit h glTexCoord or glMultiTexCoord ( for use wit h vert ex- at a- t im e ent ry point s) or as an array indicat ed by glTexCoordPointer ( for use wit h ver t ex array com m ands) . The glMultiTexCoord com m and specifies t ext ure coordinat es t hat are t o be operat ed on by a specific t ext ure unit . This com m and specifies t he t ext ure unit as well as t he t ext ure coordinat es t o be used. The com m and glTexCoord is equivalent t o t he com m and glMultiTexCoord wit h it s t ext ure param et er set t o GL_TEXTURE0. For vert ex arrays, it is necessary t o call glClientActiveTexture bet ween each call t o glTexCoordPointer in order t o specify different t ext ure coordinat e arrays for different t ext ure unit s. Text ure coordinat es can also be generat ed aut om at ically by OpenGL. Param et ers for cont rolling aut om at ic t ext ure coordinat e generat ion are set on a per- t ext ure unit basis wit h t he glTexGen com m and. This funct ion let s t he applicat ion select a t ext ure generat ion funct ion and supply coefficient s for t hat funct ion for t he current ly act ive t ext ure unit . Support ed t ext ure generat ion funct ions are obj ect linear ( useful for aut om at ically generat ing t ext ure coordinat es for t errain m odels) , eye linear ( useful for producing dynam ic cont our lines on m oving obj ect s) , and sphere

m ap ( useful for a t ype of environm ent m apping t hat requires j ust one t ext ure) . When t ext ure coordinat es have been sent t o OpenGL or generat ed by t he t ext ure unit 's t ext ure gener at ion funct ion, t hey are t ransform ed by t he t ext ure unit 's current t ext ure t ransform at ion m at r ix. The glMatrixMode com m and select s t he t ext ure m at rix st ack for m odificat ion, and subsequent m at rix com m ands m odify t he t ext ure m at rix st ack of t he current ly act ive t ext ure unit . The current t ext ure t r ansform at ion m at rix can t ranslat e t he t ext ure across t he obj ect , rot at e it , st ret ch it , shrink it , and so on. Bot h t ext ure gener at ion and t ext ure t ransform at ion ar e defined by OpenGL t o occur as part of vert ex processing ( i.e., t hey are perform ed once pervert ex before rast erizat ion) . is t he process by which t he t ext ure coordinat es are used by a t ext ure unit t o access t he enabled t ext ure for t hat unit . I t occurs aft er rast erizat ion of t he gr aphics prim it ive and int erpolat ion of t he t ransform ed t ext ure coordinat es. The t ext ure access is perform ed according t o t he bound t ext ure obj ect 's param et ers for filt ering, wrapping, com put ed level- ofdet ail, and so on.

TEXTURE ACCESS

Aft er a t ext ure value has been ret rieved, it is com bined wit h t he incom ing color value according t o t he t ext ure funct ion est ablished by calling glTexEnv. This operat ion is called TEXTURE APPLI CATI ON. This com put at ion produces a new fragm ent color value t hat is used for all subsequent processing of t he fragm ent . Bot h t ext ure access and t ext ure applicat ion are defined t o occur on every fragm ent t hat result s from t he rast erizat ion process.

1.11. Summary This chapt er has briefly reviewed t he fundam ent als of t he OpenGL API . I n it , w e've t ouched on t he m aj orit y of t he im port ant OpenGL funct ion calls. I f you haven't used OpenGL for quit e som e t im e, t he hope is t hat t his review chapt er has been enough t o orient you properly for t he t ask of using t he OpenGL Shading Language t o writ e shaders. I f you have been using anot her 3D graphics program m ing API , t he hope is t hat t his short overview is enough t o get you st art ed using OpenGL and w rit ing your own shaders. I f not , t he next sect ion list s a num ber of resources for learning m ore about OpenGL.

1.12. Further Information The Web sit e ht t p: / / opengl.org has t he lat est inform at ion for t he OpenGL com m unit y, forum s for developers, and links t o a variet y of dem os and t echnical inform at ion. OpenGL developers should bookm ark t his sit e and visit it oft en. The st andard reference books for t he OpenGL API are t he OpenGL Pr ogram m ing Guide, Fift h Edit ion ( 2005) and t he OpenGL Reference Manual, Fourt h Edit ion ( 2004) , bot h by t he OpenGL Ar chit ect ure Review Board. Anot her useful OpenGL book is OpenGL SuperBible, Third Edit ion, by Richard S. Wright , Jr. and Benj am in Lipchak ( 2004) . A good overview of OpenGL is provided in t he t echnical paper " The Design of t he OpenGL Graphics I nt erface" by Mark Segal and Kurt Akeley ( 1994) . Of course, t he definit ive docum ent on OpenGL is t he specificat ion it self, The OpenGL Graphics Syst em : A Specificat ion, ( Version 2.0) , by Mark Segal and Kurt Akeley, edit ed by Jon Leech and Pat Brown ( 2004) . The OpenGL.org Web sit e, ht t p: / / opengl.org, is also a good source for finding source code for OpenGL exam ple program s. Anot her useful sit e is Tom Nuyden's sit e at ht t p: / / delphi3d.net . The hardw are vendors t hat suppor t OpenGL t ypically provide lot s of exam ple program s, especially for newer OpenGL funct ionalit y and ext ensions. The SGI , NVI DI A, and ATI Web sit es are part icularly good in t his regard. 1 . 3Dlabs developer Web sit e. ht t p: / / developer.3dlabs.com 2 . ATI developer Web sit e. ht t p: / / w ww .at i.com / developer 3 . Delphi3D Web sit e. ht t p: / / delphi3d.net 4 . NVI DI A developer Web sit e. ht t p: / / developer.nvidia.com 5 . OpenGL Archit ect ure Review Board, Dave Shreiner, J. Neider, T. Davis, and M. Woo, OpenGL Program m ing Guide, Fift h Edit ion: The Official Guide t o Learning OpenGL, Version 2, Addison- Wesley, Reading, Massachuset t s, 2005. 6 . OpenGL Archit ect ure Review Board, OpenGL Reference Manual, Fourt h Edit ion: The Official Reference t o OpenGL, Version 1.4, Edit or: Dave Shreiner, Addison- Wesley, Reading, Massachuset t s, 2004. 7 . OpenGL, official Web sit e. ht t p: / / opengl.org 8 . Segal, Mark, and Kurt Akeley, The OpenGL Graphics Syst em : A Specificat ion ( Version 2.0) , Edit or ( v1.1) : Chris Fr azier, ( v1.21.5) : Jon Leech, ( v2.0) : Jon Leech and Pat Brow n, Sept . 2004. ht t p: / / w ww .opengl.org/ docum ent at ion/ spec.ht m l 9 . Segal, Mark, and Kurt Akeley, The Design of t he OpenGL Graphics I nt erface, Silicon Graphics I nc., 1994. ht t p: / / wwws.sun.com / soft ware/ graphics/ opengl/ OpenGLdesign.pdf 1 0 . SGI OpenGL Web sit e. ht t p: / / www.sgi.com / soft ware/ opengl 1 1 . Wright , Richard, and Benj am in Lipchak, OpenGL SuperBible, Third Edit ion, Sam s Publishing, 2005. ht t p: / / www.st arst onesoft ware.com / OpenGL/ opengl_superbbile.ht m

Chapter 2. Basics This chapt er int roduces t he OpenGL Shading Language t o get you st art ed writ ing your own shaders as quickly as possible. When you finish reading t his chapt er, you should underst and how program m abilit y has been added t o OpenGL and be ready t o t ackle t he det ails of t he shading language descript ion in t he next t hree chapt ers and t he sim ple exam ple in Chapt er 6. Aft er t hat , you can learn m ore det ails about t he API t hat support s t he shading language or explore t he exam ples cont ained in t he lat er chapt ers.

2.1. Introduction to the OpenGL Shading Language This book helps you learn and use a high- level graphics progr am m ing language form ally called t he OPENGL SHADI NG LANGUAGE. I nform ally, t his language is som et im es refer red t o as GLSL. This language has been m ade part of t he OpenGL st andard as of OpenGL 2.0. The recent t rend in graphics hardware has been t o replace fixed funct ionalit y wit h program m abilit y in areas t hat have grown exceedingly com plex. Two such areas are vert ex processing and fragm ent processing. Vert ex processing involves t he operat ions t hat occur at each vert ex, m ost not ably t ransform at ion and light ing. Fragm ent s are per- pixel dat a st ruct ures t hat are creat ed by t he rast erizat ion of graphics pr im it ives. A fragm ent cont ains all t he dat a necessary t o updat e a single locat ion in t he fram e buffer. Fragm ent processing consist s of t he operat ions t hat occur on a per- fragm ent basis, m ost not ably reading from t ext ure m em ory and applying t he t ext ure value( s) at each fragm ent . Wit h t he OpenGL Shading Language, t he fixed funct ionalit y st ages for vert ex processing and fragm ent processing have been augm ent ed wit h program m able st ages t hat can do everyt hing t he fixed funct ionalit y st ages can doand a whole lot m ore. The OpenGL Shading Language allows applicat ion program m ers t o expr ess t he processing t hat occurs at t hose program m able point s of t he OpenGL pipeline. The OpenGL Shading Language code t hat is int ended for execut ion on one of t he OpenGL program m able processors is called a SHADER. The t erm OPENGL SHADER is som et im es used t o different iat e a shader writ t en in t he OpenGL Shading Language from a shader writ t en in anot her shading language such as RenderMan. Because t wo program m able processors are defined in OpenGL, t here are t wo t ypes of shaders: VERTEX SHADERS and FRAGMENT SHADERS. OpenGL provides m echanism s for com piling shaders and linking t hem t o form execut able code called a PROGRAM. A program cont ains one or m ore EXECUTABLES t hat can run on t he program m able processing unit s. The OpenGL Shading Language has it s root s in C and has feat ur es sim ilar t o RenderMan and ot her shading languages. The language has a rich set of t ypes, including vect or and m at rix t ypes t o m ake code m ore concise for t ypical 3D gr aphics operat ions. A special set of t ype qualifiers m anages t he unique form s of input and out put needed by shader s. Som e m echanism s from C+ + , such as funct ion overloading based on argum ent t ypes and t he capabilit y t o declare variables where t hey are first needed inst ead of at t he beginning of blocks, have also been borrowed. The language includes support for loops, subrout ine calls, and condit ional expressions. An ext ensive set of built - in funct ions provides m any of t he capabilit ies needed for im plem ent ing shading algorit hm s. I n brief, z z

z

z z

The OpenGL Shading Language is a high- level procedural language. As of OpenGL 2.0, it is part of st andard OpenGL, t he leading cross- plat form , operat ingenvironm ent - independent API for 3D graphics and im aging. The sam e language, wit h a sm all set of differences, is used for bot h vert ex and fragm ent shaders. I t is based on C and C+ + synt ax and flow cont rol. I t nat ively support s vect or and m at rix operat ions since t hese ar e inher ent t o m any graphics algorit hm s.

z

I t is st rict er wit h t ypes t han C and C+ + , and funct ions are called by value- ret urn.

z

I t uses t ype qualifiers rat her t han reads and writ es t o m anage input and out put .

z

I t im poses no pract ical lim it s t o a shader's lengt h, nor does t he shader lengt h need t o be queried.

The following sect ions cont ain som e of t he key concept s t hat you will need t o underst and in order t o use t he OpenGL Shading Language effect ively. The concept s are covered in m uch m ore det ail lat er in t he book, but t his int roduct ory chapt er should help you underst and t he big pict ure.

2.2. Why Write Shaders? Unt il recent ly, OpenGL has present ed applicat ion program m ers wit h a flexible but st at ic int erface for put t ing graphics on t he display device. As described in Chapt er 1, you could t hink of OpenGL as a sequence of operat ions t hat occurred on geom et ry or im age dat a as it was sent t hrough t he graphics hardware t o be displayed on t he screen. Various param et ers of t hese pipeline st ages could be alt ered t o select variations on t he processing t hat occurred for t hat pipeline st age. But neit her t he fundam ent al operat ion of t he OpenGL graphics pipeline nor t he order of operat ions could be changed t hrough t he OpenGL API . By exposing support for t radit ional rendering m echanism s, OpenGL has evolved t o serve t he needs of a fair ly br oad set of applicat ions. I f your part icular applicat ion was well served by t he t radit ional rendering m odel present ed by OpenGL, you m ay never need t o writ e shaders. But if you have ever been frust rat ed because OpenGL did not allow you t o define area light s, or because light ing calculat ions are perform ed per- vert ex rat her t han perfragm ent or, if you have run int o any of t he m any lim it at ions of t he t radit ional OpenGL rendering m odel, you m ay need t o wr it e your own OpenGL shader. The OpenGL Shading Language and it s support ing OpenGL API ent ry point s allows applicat ion developers t o define t he pr ocessing t hat occurs at key point s in t he OpenGL processing pipeline by using a high- level program m ing language specifically designed for t his purpose. These key point s in t he pipeline are defined t o be program m able in order t o give developers com plet e freedom t o define t he processing t hat occurs. This let s developers ut ilize t he underlying graphics hardware t o achieve a m uch wider range of rendering effect s. To get an idea of t he range of effect s possible w it h OpenGL shader s, t ake a m inut e now and browse t hrough t he color im ages t hat are included in t his book. This book present s a variet y of shaders t hat only begin t o scrat ch t he surface of what is possible. Wit h each new generat ion of graphics hardware, m ore com plex rendering t echniques can be im plem ent ed as OpenGL shaders and can be used in real- t im e rendering applicat ions. Here's a brief list of what 's possible wit h OpenGL shaders: z

I ncreasingly realist ic m at erialsm et als, st one, w ood, paint s, and so on

z

I ncreasingly realist ic light ing effect sarea light s, soft shadows, and so on

z

Nat ural phenom enafire, sm oke, wat er, clouds, and so on

z

Advanced rendering effect sglobal illum inat ion, ray - t racing, and so on

z

z

Non- phot orealist ic m at erialspaint erly effect s, pen- and- ink drawings, sim ulat ion of illust rat ion t echniques, and so on New uses for t ext ure m em oryst orage of norm als, gloss values, polynom ial coefficient s, and so on

z

Procedural t ext uresdynam ically generat ed 2D and 3D t ext ures, not st at ic t ext ure im ages

z

I m age processingconvolut ion, unsharp m asking, com plex blending, and so on

z

Anim at ion effect skey fram e int erpolat ion, part icle syst em s, procedurally defined m ot ion

z

User program m able ant ialiasing m et hods

z

General com put at ionsort ing, m at hem at ical m odeling, fluid dynam ics, and so on

Many of t hese t echniques have been available before now only t hrough soft ware im plem ent at ions. I f t hey were at all possible t hrough OpenGL, t hey were possible only in a lim it ed way. The fact t hat t hese t echniques can now be im plem ent ed wit h hardware accelerat ion provided by dedicat ed graphics hardw are m eans t hat rendering perform ance can be increased dr am at ically and at t he sam e t im e t he CPU can be off- loaded so t hat it can perform ot her t asks.

2.3. OpenGL Programmable Processors The int roduct ion of program m able vert ex and fragm ent processors is t he biggest change t o OpenGL since it s incept ion and is t he reason a high- level shading language is needed. I n Chapt er 1, we discussed t he OpenGL pipeline and t he fixed funct ionalit y t hat im plem ent s vert ex processing and fragm ent processing. Wit h t he int roduct ion of program m abilit y, t he fixed funct ionalit y vert ex processing and fixed funct ionalit y fragm ent pr ocessing ar e disabled w hen an OpenGL Shading Language program is m ade current ( i.e., m ade part of t he current rendering st at e) . Figur e 2.1 shows t he OpenGL processing pipeline when t he program m able processors are act ive. I n t his case, t he fixed funct ionalit y vert ex and fragm ent processing shown in Figur e 1.1 are replaced by pr ogram m able vert ex and fragm ent processors as shown in Figur e 2.1. All ot her part s of t he OpenGL processing pipeline rem ain t he sam e.

Figu r e 2 .1 . Ope n GL logica l dia gr a m sh ow in g pr ogr a m m a ble pr oce ssor s for ve r t e x a n d fr a gm e n t sh a de r s r a t he r t ha n fix e d fu n ct ion a lit y [View full size image]

This diagram illust rat es t he st ream processing nat ure of OpenGL m ade possible by t he program m able processors t hat are defined as part of t he OpenGL Shading Language. Dat a flows from t he applicat ion t o t he vert ex processor, on t o t he fragm ent processor, and ult im at ely t o t he fram e buffer. The OpenGL Shading Language was carefully designed t o allow hardware im plem ent at ions t o perform parallel processing of bot h vert ices and fragm ent s. This gives graphics hardware vendors t he opport unit y t o produce fast er graphics hardware wit h m ore parallel processors wit h each new generat ion of hardware.

2.3.1. Vertex Processor The VERTEX PROCESSOR is a program m able unit t hat operat es on incom ing vert ex values and t heir associat ed dat a. The vert ex processor usually perform s t radit ional graphics operat ions such as t he following: z

Vert ex t ransform at ion

z

Norm al t ransform at ion and norm alizat ion

z

Text ure coordinat e generat ion

z

Text ure coordinat e t ransform at ion

z

Light ing

z

Color m at erial applicat ion

Because of it s general purpose program m abilit y, t his processor can also be used t o perform a variet y of ot her com put at ions. Shaders t hat are int ended t o run on t his processor are called vert ex shaders. Vert ex shaders can specify a com plet ely general sequence of operat ions t o be applied t o each vert ex and it s associat ed dat a. Vert ex shaders t hat perform som e of t he com put at ions in t he preceding list m ust cont ain t he code for all desired funct ionalit y from t he preceding list . For inst ance, it is not possible t o have t he exist ing fixed funct ionalit y perform t he vert ex and norm al t ransform at ion but t o have a vert ex shader perform a specialized light ing funct ion. The vert ex shader m ust be writ t en t o perform all t hree funct ions. The vert ex processor does not replace graphics operat ions t hat require knowledge of several vert ices at a t im e or t hat require t opological knowledge. OpenGL operat ions t hat rem ain as fixed funct ionalit y in bet ween t he vert ex processor and t he fragm ent pr ocessor include perspect ive divide and viewport m apping, prim it ive assem bly, frust um and user clipping, backface culling, t w o- sided light ing select ion, polygon m ode, polygon offset , select ion of flat or sm oot h shading, and dept h range. Figur e 2.2 shows t he dat a values t hat ar e used as input s t o t he vert ex processor and t he dat a values t hat are produced by t he vert ex processor. Vert ex shaders express t he algorit hm t hat execut es on t he vert ex processor t o pr oduce out put values based on t he provided input values. Type qualifiers t hat are defined as part of t he OpenGL Shading Language m anage t he input t o t he vert ex processor and t he out put fr om it .

Figu r e 2 .2 . Ve r t e x pr oce ssor in pu t s a n d ou t pu t s [View full size image]

Variables defined in a vert ex shader can be qualified as ATTRI BUTE VARI ABLES. These represent values t hat are frequent ly passed from t he applicat ion t o t he vert ex processor. Because t his t ype of variable is used only for dat a from t he applicat ion t hat defines vert ices, it is perm it t ed only as part of a vert ex shader. Applicat ions can provide at t ribut e values bet ween calls t o glBegin and glEnd or wit h vert ex ar ray calls, so t hey can change as oft en as every vert ex. There are t wo t ypes of at t ribut e variables: built in and user defined. St andard at t ribut e variables in OpenGL include t hings like color, surface norm al, t ext ure coordinat es, and vert ex posit ion. The OpenGL calls glColor, glNormal, glVertex, and so on, and t he OpenGL vert ex arr ay drawing com m ands can send st andard OpenGL vert ex at t ribut es t o t he vert ex processor. When a vert ex shader is execut ing, it can access t hese dat a values t hrough built - in at t ribut e variables nam ed gl_Color, gl_Normal, gl_Vertex, and so on. Because t his m et hod rest rict s vert ex at t ribut es t o t he set t hat is already defined by OpenGL, a new int erface allows applicat ions t o pass arbit rary per- vert ex dat a. Wit hin t he OpenGL API , generic vert ex at t ribut es are defined and referenced by num bers from 0 up t o som e im plem ent at ion- dependent m axim um value. The com m and glVertexAttrib sends generic vert ex at t ribut es t o OpenGL by specifying t he index of t he generic at t ribut e t o be m odified and t he value for t hat generic at t ribut e. Vert ex shaders can access t hese generic vert ex at t ribut es t hrough user- defined at t ribut e variables. Anot her new OpenGL com m and, glBindAttribLocation, allows an applicat ion t o t ie t oget her t he index of a generic vert ex at t ribut e and t he nam e w it h w hich t o associat e t hat at t ribut e in a vert ex shader .

UNI FORM VARI ABLES pass dat a values from t he applicat ion t o eit her t he vert ex processor or t he fragm ent processor. Uniform variables t ypically provide values t hat change relat ively infrequent ly. A shader can be writ t en so t hat it is param et erized wit h uniform variables. The applicat ion can pr ovide init ial values for t hese uniform variables, and t he end user can m anipulat e t hem t hrough a gr aphical user int erface t o achieve a var iet y of effect s wit h a single shader. But uniform variables cannot be specified bet ween calls t o glBegin and glEnd, so t hey can change at m ost once per prim it ive. The OpenGL Shading Language support s bot h built - in and user- defined uniform variables. Vert ex shaders and fragm ent shaders can access cur rent OpenGL st at e t hrough built - in uniform variables cont aining t he reserved prefix " gl_" . Applicat ions can m ake arbit rary dat a values available direct ly t o a shader t hrough user- defined uniform variables. glGetUniformLocation obt ains t he locat ion of a user- defined uniform variable t hat has been defined as par t of a shader. Dat a can be loaded int o t his locat ion wit h anot her new OpenGL com m and, glUniform. Variat ions of t his com m and facilit at e loading of float ing- point , int eger, Boolean, and m at rix values, as well as arrays of t hese. Anot her new feat ure is t he capabilit y of vert ex processors t o read from t ext ure m em ory. This allows vert ex shaders t o im plem ent displacem ent m apping algorit hm s, am ong ot her t hings. ( However, t he m inim um num ber of vert ex t ext ure im age unit s required by an im plem ent at ion is 0, so t ext ure- m ap access from t he vert ex processor st ill m ay not be possible on all im plem ent at ions t hat support t he OpenGL Shading Language.) For accessing m ipm ap t ext ures, level of det ail can be specified direct ly in t he shader. Exist ing OpenGL param et ers for t ext ure m aps define t he behavior of t he filt ering operat ion, bor ders, and wr apping. Concept ually, t he vert ex processor operat es on one vert ex at a t im e ( but an im plem ent at ion m ay have m ult iple vert ex processors t hat operat e in parallel) . The vert ex shader is execut ed once for each vert ex passed t o OpenGL. The design of t he vert ex processor is focused on t he funct ionalit y needed t o t ransform and light a single vert ex. Out put from t he vert ex shader is accom plished part ly wit h special out put variables. Vert ex shaders m ust com put e t he hom ogeneous posit ion of t he coordinat e in clip space and st ore t he result in t he special out put variable gl_Position. Values t o be used during user clipping and point rast erizat ion can be st ored in t he special out put variables gl_ClipVertex and gl_PointSize. Variables t hat define dat a t hat is passed from t he vert ex processor t o t he fragm ent pr ocessor are called VARYI NG VARI ABLES. Bot h built - in and user- defined varying variables are support ed. They are called varying variables because t he values are pot ent ially different at each vert ex and perspect ive- correct int erpolat ion is perform ed t o provide a value at each fragm ent for use by t he fragm ent shader. Built - in varying variables include t hose defined for t he st andard OpenGL color and t ext ure coordinat e values. A vert ex shader can use a user- defined varying variable t o pass along anyt hing t hat needs t o be int erpolat ed: colors, norm als ( useful for per- fragm ent light ing com put at ions) , t ext ure coordinat es, m odel coordinat es, and ot her ar bit rary values. There is act ually no harm ( ot her t han a possible loss of perform ance) in having a vert ex shader calculat e m or e varying var iables t han are needed by t he fragm ent shader. A warning m ay be generat ed if t he fragm ent shader consum es few er var ying variables t han t he ver t ex shader produces. But you m ay have good reasons t o use a som ewhat generic ver t ex shader w it h a variet y of fragm ent shaders. The fragm ent shaders can be writ t en t o use a subset of t he varying variables produced by t he vert ex shader. Developers of applicat ions t hat m anage a large num ber of shaders m ay find t hat reducing t he cost s of shader developm ent and m aint enance is m ore im port ant t han squeezing out a t iny bit of addit ional perform ance. The vert ex processor out put ( special out put variables and user- defined and built - in varying variables) is sent t o subsequent st ages of processing t hat are defined exact ly t he sam e as t hey are for fixed- funct ion pr ocessing: prim it ive assem bly, user clipping, frust um clipping, perspect ive divide, viewport m apping, polygon offset , polygon m ode, shade m ode, and culling.

2.3.2. Fragment Processor

The FRAGMENT PROCESSOR is a program m able unit t hat oper at es on fragm ent values and t heir associat ed dat a. The fr agm ent processor usually perform s t radit ional graphics operat ions such as t he following: z

Operat ions on int erpolat ed values

z

Text ure access

z

Text ure applicat ion

z

Fog

z

Color sum

A w ide variet y of ot her com put at ions can be perform ed on t his processor. Shaders t hat are int ended t o run on t his pr ocessor are called fragm ent shader s. Fr agm ent shader s express t he algorit hm t hat execut es on t he fragm ent processor and produces out put values based on t he input values t hat are provided. A fragm ent shader cannot change a fragm ent 's x/ y posit ion. Fragm ent shaders t hat perform som e of t he com put at ions from t he preceding list m ust perform all desired funct ionalit y from t he preceding list . For inst ance, it is not possible t o use t he exist ing fixed funct ionalit y t o com put e fog but have a fragm ent shader perform specialized t ext ure access and t ext ure applicat ion. The fragm ent shader m ust be writ t en t o perform all t hree funct ions. The fragm ent processor does not replace graphics operat ions t hat require know ledge of several fragm ent s at a t im e. To support parallelism at t he fragm ent - processing level, fragm ent shaders are writ t en in a w ay t hat expresses t he com put at ion required for a single fr agm ent , and access t o neighboring fragm ent s is not allowed. An im plem ent at ion m ay have m ult iple fragm ent processors t hat operat e in parallel. The fragm ent processor can perform operat ions on each fragm ent t hat is generat ed by t he rast erizat ion of point s, lines, polygons, pixel rect angles, and bit m aps. I f im ages are first downloaded int o t ext ure m em ory, t he fragm ent processor can also be used for pixel processing t hat requires access t o a pixel and it s neighbors. A rect angle can be drawn wit h t ext uring enabled, and t he fragm ent processor can read t he im age from t ext ure m em ory and apply it t o t he rect angle while perform ing t radit ional operat ions such as t he following: z

Pixel zoom

z

Scale and bias

z

Color t able lookup

z

Convolut ion

z

Color m at rix

The fragm ent processor does not replace t he fixed funct ionalit y graphics operat ions t hat occur at t he back end of t he OpenGL pixel processing pipeline such as coverage, pixel ownership t est , scissor t est , st ippling, alpha t est , dept h t est , st encil t est , alpha blending, logical operat ions, dit hering, and plane m asking. Figur e 2.3 shows t he values t hat provide input t o t he fragm ent pr ocessor and t he dat a values t hat are produced by t he fragm ent processor.

Figu r e 2 .3 . Fr a gm e n t pr oce ssor in pu t s a n d ou t pu t s

[View full size image]

The pr im ary input s t o t he fragm ent processor are t he int erpolat ed varying variables ( bot h built in and user defined) t hat are t he result s of rast erizat ion. User - defined varying variables m ust be defined in a fr agm ent shader , and t heir t ypes m ust m at ch t hose defined in t he vert ex shader. Values com put ed by fixed funct ionalit y bet ween t he vert ex processor and t he fragm ent processor are m ade available t hrough special input variables. The w indow coor dinat e posit ion of t he fragm ent is com m unicat ed t hr ough t he special input variable gl_FragCoord. An indicat or of whet her t he fragm ent was generat ed by rast erizing a front - facing prim it ive is com m unicat ed t hrough t he special input variable gl_FrontFacing. Just as in t he ver t ex shader , exist ing OpenGL st at e is accessible t o a fragm ent shader t hrough built - in uniform variables. All of t he OpenGL st at e t hat is available t hrough built - in uniform variables is available t o bot h vert ex and fragm ent shaders. This m akes it easy t o im plem ent t radit ional vert ex operat ions such as light ing in a fr agm ent shader. User- defined uniform variables allow t he applicat ion t o pass relat ively infrequent ly changing values t o a fragm ent shader. The sam e uniform variable can be accessed by bot h a vert ex shader and a fragm ent shader if bot h shaders declare t he variable using t he sam e dat a t ype. One of t he biggest advant ages of t he fragm ent processor is t hat it can access t ext ure m em ory an arbit rar y num ber of t im es and com bine in arbit rary ways t he values t hat it reads. A fragm ent shader is free t o read m ult iple values from a single t ext ure or m ult iple values from m ult iple t ext ures. The result of one t ext ure access can be used as t he basis for perform ing anot her t ext ure access ( a DEPENDENT TEXTURE READ ) . There is no inher ent lim it at ion on t he num ber of such dependent reads t hat are possible, so ray - cast ing algorit hm s can be im plem ent ed in a fragm ent shader.

The OpenGL param et ers for t ext ure m aps cont inue t o define t he behavior of t he filt ering operat ion, borders, wrapping, and t ext ure com parison m odes. These operat ions are applied when a t ext ure is accessed from wit hin a shader . The shader is free t o use t he result ing value how ever it chooses. The shader can read m ult iple values from a t ext ure and perform a cust om filt ering operat ion. I t can also use a t ext ure t o perform a lookup t able operat ion. The fragm ent processor defines alm ost all t he capabilit ies necessary t o im plem ent t he fixedfunct ion pixel t ransfer operat ions defined in OpenGL, including t hose in t he im aging subset . This m eans t hat advanced pixel processing is support ed wit h t he fragm ent processor. Lookup t able operat ions can be done wit h 1D t ext ure accesses, allowing applicat ions t o fully cont rol t heir size and form at . Scale and bias operat ions are easily expressed t hrough t he pr ogram m ing language. The color m at rix can be accessed t hrough a built - in uniform variable. Convolut ion and pixel zoom are support ed by accessing a t ext ure m ult iple t im es t o com put e t he proper result . Hist ogram and m inim um / m axim um operat ions are left t o be defined as ext ensions because t hese prove t o be quit e difficult t o support at t he fr agm ent level wit h high degr ees of par allelism . For each fragm ent , t he fragm ent shader m ay com put e color, dept h, and arbit r ary values ( w rit ing t hese values int o t he special out put variables gl_FragColor, gl_FragDepth, and gl_FragData) or com plet ely discard t he fragm ent . I f t he fragm ent is not discarded, t he result s of t he fragm ent shader are sent on for furt her processing. The r em ainder of t he OpenGL pipeline rem ains as defined for fixed- funct ion pr ocessing. Fragm ent s are subm it t ed t o coverage applicat ion, pixel ownership t est ing, scissor t est ing, alpha t est ing, st encil t est ing, dept h t est ing, blending, dit hering, logical operat ions, and m asking before ult im at ely being writ t en int o t he fram e buffer. The back end of t he processing pipeline rem ains as fixed funct ionalit y because it is easy t o im plem ent in nonprogram m able hardware. Making t hese funct ions program m able is m ore com plex because read/ m odify/ w rit e operat ions can int r oduce significant inst ruct ion scheduling issues and pipeline st alls. Most of t hese fixed funct ionalit y operat ions can be disabled, and alt er nat ive oper at ions can be perform ed wit hin a fragm ent shader if desired ( albeit wit h possibly lower perform ance) .

2.4. Language Overview Because of it s success as a st andard, OpenGL has been t he t arget of our effort s t o define an indust ry- st andard, high- level shading language. The shading language t hat has been defined as a result of t he effort s of OpenGL ARB m em bers is called t he OpenGL Shading Language. This language has been designed t o be forward looking and t o event ually support program m abilit y in ot her areas as well. This sect ion pr ovides a br ief overview of t he OpenGL Shading Language. For a com plet e discussion of t he language, see Chapt er 3, Chapt er 4, and Chapt er 5.

2.4.1. Language Design Considerations I n t he past few years, sem iconduct or t echnology has pr ogressed t o t he point at which t he levels of com put at ion t hat can be done per vert ex or per fragm ent have gone beyond what is feasible t o describe by t he t r adit ional OpenGL m echanism s of set t ing st at e t o influence t he act ion of fixed pipeline st ages. A nat ural way of t am ing t his com plexit y and t he proliferat ion of OpenGL ext ensions is t o replace part s of t he pipeline wit h user- progr am m able st ages. This has been done in som e recent OpenGL ext ensions, but t he program m ing is done in assem bly language. I t can be difficult and t im e consum ing t o writ e shaders in such low- level languages, and m aint aining such code can be cost ly. As program m able graphics hardware evolves, t he current crop of shader assem bly languages m ay also prove t o be cum bersom e and inefficient t o support in hardwar e. The ideal solut ion t o t hese issues was t o define a forward- looking, hardware- independent , highlevel language t hat would be easy t o use and powerful enough t o st and t he t est of t im e and t hat would drast ically reduce t he need for ext ensions. These desires were t em pered by t he need for fast im plem ent at ions wit hin a generat ion or t w o of hardware. The following design goals were fundam ent al t o t he design of t he OpenGL Shading Language. D e fin e a la n gu a ge t h a t w or k s w e ll w it h Ope n GL The OpenGL Shading Language is designed specifically for use wit hin t he OpenGL environm ent . I t provides program m able alt ernat ives t o cert ain part s of t he fixed funct ionalit y of OpenGL. Therefore, t he language it self and t he program m able pr ocessors it defines m ust have at least as m uch funct ionalit y as w hat t hey replace. Furt herm ore, by design, it is quit e easy t o refer t o exist ing OpenGL st at e from wit hin a shader. By design, it is also quit e easy t o use fixed funct ionalit y in one part of t he OpenGL processing pipeline and program m able processing in anot her. Ex pose t h e fle x ibilit y of n e a r - fu t u r e h a r dw a r e Graphics hardware has been changing rapidly t o a m odel t hat allows general pr ogram m abilit y for vert ex and fragm ent processing. To expose t his program m abilit y, t he shading language is high level, wit h appr opriat e abst ract ions for t he graphics problem dom ain. The language includes a rich set of built - in funct ions t hat allow expression of operat ions on vect ors as easily as on scalars. Exposing hardware capabilit ies t hrough a high- level progr am m ing language also obviat es t he need for OpenGL ext ensions t hat define sm all changes t o t he fixed funct ionalit y behavior. Exposing an abst ract ion t hat is independent of t he act ual underlying hardw are elim inat es t he plet hora of piecem eal ext ensions t o OpenGL. Pr ovide h a r dw a r e in de pe n de n ce As previously m ent ioned, t he first at t em pt s at exposing t he program m abilit y of graphics hardware focused on assem bly language int erfaces. This was a dangerous direct ion for soft ware developers t o t ake because it result s in soft ware t hat is inherent ly nonport able. The goal of a high- level shading

language is for t he abst ract ion level t o be high enough t hat applicat ion developers can code in a port able way and t hat hardware vendors have plent y of room t o provide innovat ive hardware archit ect ures and com piler t echnology. D e fin e a la n gu a ge t h a t e x pose s t he pe r for m a n ce of t h e un de r lying gr a ph ics ha r dw a r e Today's graphics hardware is based on program m able processor t echnology. I t is an est ablished fact nowadays t hat com piler t echnology can gener at e ext rem ely high perform ance execut able code. Wit h t he com plexit y of t oday's CPUs, it is difficult t o m anually generat e code t hat can surpass t he perform ance of code generat ed by a com piler. I t is t he int ent t hat t he obj ect code generat ed for a shader be independent of ot her OpenGL st at e, so t hat recom piles or m anaging m ult iple copies of obj ect code are not necessary. D e fin e a la n gu a ge t h a t is e a sy t o u se One of t he considerat ions here is t hat writ ing shaders should be sim ple and easy. Since m ost graphics applicat ion progr am m ers are fam iliar w it h C and C+ + , t his led us t o adopt t he salient feat ures of t hese languages as t he basis for t he OpenGL Shading Language. We also believed t hat com pilers, not applicat ion program m ers, should perform difficult t asks. We concluded t hat a single language ( wit h very m inor variat ions) should be t he basis for program m ing all t he pr ogram m able processors t hat we were defining, as well as t hose we envisioned adding in fut ure versions of OpenGL. This allows applicat ion program m ers t o becom e fam iliar wit h t he basic shading language const r uct s and apply t hem t o all program m ing t asks involving t he pr ogram m able processors in OpenGL. D e fin e a la n gu a ge t h a t w ill st a nd t h e t e st of t im e This design considerat ion also led us t o base t he design of t he OpenGL Shading Language on previously successful program m ing languages such as C and RenderMan. Our hope is t hat program s writ t en when t he OpenGL Shading Language was first defined will st ill be valid in 10 years. Longevit y also requires st andardizat ion of som e sort , so we expended a great deal of effort bot h in m aking hardware vendors happy wit h t he final language specificat ion and in pushing t he specificat ion t hrough t he approval process of OpenGL's governing body, t he OpenGL Archit ect ure Review Board ( ARB) . D on 't pr e clu de h igh e r le ve ls of pa r a lle l pr oce ssin g New er gr aphics hardware archit ect ures are providing m ore and m ore parallelism at bot h t he vert ex and t he fragm ent processing levels. So we t ook great care wit h t he definit ion of t he OpenGL Shading Language t o allow for even higher levels of parallel processing. This considerat ion has shaped t he definit ion of t he language in som e subt le but im port ant ways. D on 't in clu de u nn e ce ssa r y la n gu a ge fe a t u r e s Som e feat ures of C have m ade im plem ent ing opt im izing com pilers difficult . Som e OpenGL Shading Language feat ures addr ess t his issue. For exam ple, C allows hidden aliasing of m em ory by using point ers and passing point ers as funct ion argum ent s, which m ay give m ult iple nam es t o t he sam e m em ory. These pot ent ial aliases handicap t he opt im izer, leading t o com plexit y or less opt im ized code. The OpenGL Shading language does not allow point ers, and it calls by value- ret urn t o prevent such aliasing. I n general, aliasing is disallowed, sim plifying t he j ob of t he opt im izer.

2.4.2. C Basis As st at ed previously, t he OpenGL Shading Language is based on t he synt ax of t he ANSI C progr am m ing language, and at first glance, program s writ t en in t his language look very m uch like C pr ogram s. This is int ent ional, t o m ake t he language easier t o use for t hose m ost likely t o be using it , nam ely, t hose developing graphics applicat ions in C or C+ + . The basic st ruct ure of program s writ t en in t he OpenGL Shading Language is t he sam e as it is for

program s writ t en in C. The ent r y point of a set of shaders is t he funct ion void main(); t he body of t his funct ion is delim it ed by curly braces. Const ant s, ident ifiers, oper at ors, expressions, and st at em ent s ar e basically t he sam e for t he OpenGL Shading Language as t hey are for C. Cont rol flow for looping, if- t hen- else, and funct ion calls are virt ually ident ical t o C.

2.4.3. Additions to C The OpenGL Shading Language has a num ber of language feat ures t hat have been added because of it s special- purpose nat ur e as a language for encoding graphics algorit hm s. Here are som e of t he m ain t hings t hat have been added t o t he OpenGL Shading Language t hat are different fr om ANSI C. Vect or t ypes are support ed for float ing- point , int eger, and Boolean values. For float ing- point values, t hese vect or t ypes are referred t o as ve c2 ( t wo float s) , ve c3 ( t hree float s) , and ve c4 ( four float s) . Operat ors w ork as readily on vect or t ypes as t hey do on scalars. To sum vect ors v1 and v2, you sim ply w ould say v1 + v2. I ndividual com ponent s of a vect or can be accessed eit her wit h array synt ax or as fields of a st ruct ure. Color values can be accessed by appending .r t o t he nam e of a vect or var iable t o access t he first com ponent , .g t o access t he second com ponent , .b t o access t he t hird, and .a t o access t he fourt h. Posit ion values can be accessed wit h .x, .y, .z, and .w, and t ext ure values can be accessed wit h .s, .t , .p, and .q. Mult iple com ponent s can be select ed by specificat ion of m ult iple nam es, like .xy. Float ing- point m at rix t ypes are also support ed as basic t ypes. The dat a t ype m a t 2 refer s t o a 2 x 2 m at rix of float ing- point values, m a t 3 refers t o a 3 x 3 m at rix, and m a t 4 refer s t o a 4 x 4 m at r ix. This is a convenient t ype for expressing t he linear t ransform at ions com m on in 3D graphics. Colum ns of a m at rix can be select ed w it h array synt ax, yielding a vect or whose com ponent s can be accessed as j ust described. A set of basic t ypes called SAMPLERS has also been added t o creat e t he m echanism by w hich shaders access t ext ure m em ory. Sam plers are a special t ype of opaque variable t hat access a part icular t ext ure m ap. A variable of t ype sa m ple r 1 D can be used t o access a 1D t ext ure m ap, a variable of t ype sa m ple r 2 D can be used t o access a 2D t ext ure m ap, and so on. Shadow and cube m ap t ext ures are also support ed t hrough t his m echanism . Qualifiers have been added t o m anage t he input and out put of shaders. The a t t r ibu t e , u n ifor m , and va r yin g qualifiers specify what t ype of input or out put a variable serves. At t ribut e variables com m unicat e frequent ly changing values from t he applicat ion t o a vert ex shader, uniform variables com m unicat e infr equent ly changing values from t he applicat ion t o any shader, and varying var iables com m unicat e int erpolat ed values from a vert ex shader t o a fragm ent shader. Shaders writ t en in t he OpenGL Shading Language can use built - in variables t hat begin wit h t he reserved prefix " gl_" in order t o access exist ing OpenGL st at e and t o com m unicat e wit h t he fixed funct ionalit y of OpenGL. For inst ance, bot h vert ex and fragm ent shaders can access built in uniform var iables t hat cont ain st at e values t hat ar e r eadily available wit hin t he cur rent rendering cont ext . Som e exam ples ar e gl_ModelViewMatrix for obt aining t he current m odelview m at r ix, gl_LightSource[i] for obt aining t he current param et ers of t he it h light source, and gl_Fog.color for accessing t he current fog color. The vert ex shader m ust writ e t he special variable gl_Position in order t o provide necessary inform at ion t o t he fixed funct ionalit y st ages bet ween vert ex processing and fragm ent pr ocessing, nam ely, prim it ive assem bly, clipping, culling, and rast erizat ion. A fragm ent shader t ypically writ es int o one or bot h of t he special variables gl_FragColor or gl_FragDepth. These values represent t he com put ed fragm ent color and com put ed fragm ent dept h. These values are subm it t ed t o t he back- end fixed funct ionalit y fragm ent operat ions such as alpha t est ing, st encil t est ing, and dept h t est ing, before reaching t heir ult im at e dest inat ion, t he fram e buffer. A variet y of built - in funct ions is also provided in t he OpenGL Shading Language in order t o m ake coding easier and t o t ake advant age of possible hardware accelerat ion for cert ain

operat ions. The language defines built - in funct ions for a variet y of operat ions: z z

z

z

z

z

Trigonom et ric operat ionssine, cosine, t angent , and so on Exponent ial operat ionspower, exponent ial, logarit hm , square root , and inverse square root Com m on m at h operat ionsabsolut e value, floor, ceiling, fract ional part , m odulus, and so on Geom et ric operat ionslengt h, dist ance, dot pr oduct , cross product , norm alizat ion, and so on Relat ional operat ions based on vect orscom ponent - wise operat ions such as great er t han, less t han, equal t o, and so on Specialized fragm ent shader funct ions for com put ing derivat ives and est im at ing filt er widt hs for ant ialiasing

z

Funct ions for accessing values in t ext ure m em ory

z

Funct ions t hat ret urn noise values for procedural t ext uring effect s

2.4.4. Additions from C++ The OpenGL Shading Language also includes a few not able language feat ures from C+ + . I n part icular, it support s funct ion overloading t o m ake it easy t o define funct ions t hat differ only in t he t ype or num ber of argum ent s being passed. This feat ure is heavily used by t he built - in funct ions. For inst ance, t he dot product funct ion is overloaded t o deal wit h argum ent s t hat are t ypes floa t , ve c2 , ve c3 , and ve c4 . The concept of const ruct ors also com es from C+ + . I nit ializers are done only wit h const r uct ors in t he OpenGL Shading Language. Using const ruct ors allows for m ore t han one w ay of init ializing variables. Anot her feat ur e borrowed from C+ + is t hat variables can be declared w hen t hey ar e needed; t hey do not have t o be declared at t he beginning of a basic block. The basic t ype bool is support ed as in C+ + . As in C+ + , funct ions m ust be declared before being used. This can be accom plished eit her w it h t he funct ion's definit ion ( it s body) or j ust wit h a prot ot ype.

2.4.5. C Features Not Supported Unlike ANSI C, t he OpenGL Shading Language does not support aut om at ic prom ot ion of dat a t ypes. Com piler errors are generat ed if variables used in an expr ession are of different t ypes. For inst ance, an er ror is generat ed for t he st at em ent float f = 0; but not for t he st at em ent float f = 0.0;. This approach m ight seem like a bit of a nuisance, but it sim plifies t he language by elim inat ing t he need for t ype pr om ot ion rules. I t also rem oves a class of confusing m ist akes m ade when argum ent t ype is t he basis for calling a set of over loaded funct ions. The OpenGL Shading Language does not support point ers, st rings, or charact ers, or any operat ions based on t hese. I t is fundam ent ally a language for processing num erical dat a, not for processing charact er or st ring dat a, so t here is no need for t hese feat ures t o com plicat e t he language. To lower t he im plem ent at ion burden ( bot h for t he com piler and for t he graphics hardw are) , t here is no support for double- precision float s; byt e, short , or long int egers; or

unsigned variant s of t hese. A few ot her C language feat ures t hat were elim inat ed from considerat ion in order t o sim plify t he OpenGL Shading Language ( or because t here w as no com pelling need for t hem at t he t im e) are unions, enum erat ed t ypes, bit fields in st ruct ures, and bit wise operat ors. Finally, t he language is not file based, so you won't see any #include direct ives or ot her refer ences t o file nam es.

2.4.6. Other Differences There are a few areas in which t he OpenGL Shading Language provides t he sam e funct ionalit y as C but does so in a different way. One of t hese is t hat const r uct ors, rat her t han t ype cast s, are used for dat a t ype conversion. Const ruct ors, not C- st yle init ializers, are also used for variable init ializat ion. There is no support at all for t ype cast ing wit hout conversion, so const ruct ors keep t he language t ype safe. Const ruct ors use t he synt ax of a funct ion call, where t he funct ion nam e is t he nam e of t he desired t ype and t he argum ent s are t he values t hat will be used t o const ruct t he desired value. Const ruct ors allow a m uch richer set of operat ions t han sim ple t ype cast s or C- st yle init ializers, and t he flexibilit y t hat t his richness provides com es in quit e handy for dealing wit h vect or and m at r ix dat a t ypes. I n addit ion t o convert ing from one scalar t ype t o anot her, const ruct ors can creat e a larger t ype out of a sm aller t ype or reduce a larger t ype t o a sm aller t ype. For inst ance, t he const r uct or vec3(1.0, 2.0, 3.0) const ruct s a ve c3 dat a t ype out of t hree scalar values, and t he const ruct or vec3(myVec4) st rips t he fourt h com ponent from myVec4 t o cr eat e a ve c3 value. The ot her area of difference is t hat , unlike t he call- by- value calling convent ion used by C, t he OpenGL Shading Language uses CALL BY VALUE- RETURN. I nput param et ers are copied int o t he funct ion at call t im e, and out put param et ers are copied back t o t he caller before t he funct ion exit s. Because t he funct ion deals only wit h copies of t he funct ion param et ers, t here are no issues regarding aliasing of variables wit hin a funct ion. Funct ion param et ers are ident ified as input param et ers wit h t he qualifier in , t hey are ident ified as out put param et ers wit h t he qualifier ou t , and t hey are ident ified as bot h input and out put param et ers wit h t he qualifier in out ; if no qualifier is pr esent , t hey are ident ified as input param et ers.

2.5. System Overview We have already described briefly som e of t he pieces t hat provide applicat ions wit h access t o t he pr ogram m abilit y of underlying graphics hardware. This sect ion briefly describes how t hese pieces go t oget her in a w orking syst em .

2.5.1. Driver Model A piece of soft w are t hat cont rols a piece of hardware and m anages shared access t o t hat piece of hardware is com m only called a DRI VER. No m at t er what environm ent OpenGL is im plem ent ed in, it falls int o t he dr iver cat egory because OpenGL m anages shared access t o t he underlying graphics hardware. Som e of it s t asks m ust also be coordinat ed wit h, or supervised by, facilit ies in t he operat ing syst em . Figur e 2.4 illust r at es how OpenGL shaders are handled in t he execut ion environm ent of OpenGL. Applicat ions com m unicat e wit h OpenGL by calling funct ions t hat are part of t he OpenGL API . A new OpenGL funct ion, glCreateShader, allows applicat ions t o allocat e wit hin t he OpenGL driver t he dat a st ruct ures t hat are necessary for st oring an OpenGL shader. These dat a st ruct ures are called SHADER OBJECTS. Aft er a shader obj ect has been creat ed, t he applicat ion can provide t he sour ce code for t he shader by calling glShaderSource. This com m and provides t o OpenGL t he charact er st rings cont aining t he shader source code.

Figu r e 2 .4 . Ex e cu t ion m ode l for Ope n GL sh a de r s

As you can see from Figur e 2.4, t he com piler for t he OpenGL Shading Language is act ually part of t he OpenGL driver environm ent . This is one of t he key differences bet w een t he OpenGL Shading Language and ot her shading language designs, such as t he St anford Shading Language, High- Level Shader Language ( HLSL) from Microsoft , or Cg from NVI DI A. I n t hese ot her languages, t he high- level shading language com piler sit s above t he graphics API and t ranslat es t he high- level shading language int o som et hing t hat can be consum ed by t he underlying graphics API . ( See Chapt er 17 for m ore det ails.) Wit h t he OpenGL Shading Language, t he source code for shaders is passed t o t he OpenGL driver, and in t hat environm ent , t he shaders are com piled t o t he nat ive m achine code as efficient ly as possible. Aft er source code for a shader has been loaded int o a shader obj ect in t he OpenGL driver environm ent , it can be com piled wit h glCompileShader. A PROGRAM OBJECT is an OpenGL- m anaged dat a st ruct ure t hat act s as a cont ainer for shader obj ect s. Applicat ions are required t o at t ach shader obj ect s t o a program obj ect by using t he com m and glAttachShader. When at t ached t o a program obj ect , t he com piled shader obj ect s can be linked wit h glLinkProgram. Support for m ult iple shader obj ect s ( and t he subsequent need for a linker built int o OpenGL) is a key difference bet w een t he OpenGL Shading Language and assem bly - level API s such as t hose provided by t he OpenGL ext ensions ARB_vert ex_program and ARB_fragm ent _program . For m ore com plex shading t asks, separat ely com piled shader obj ect s are a m uch m ore at t r act ive alt ernat ive t han a single, m onolit hic block of assem bly- level code. The link st ep resolves ext ernal references bet ween t he shaders, checks t he com pat ibilit y bet w een t he vert ex shader and t he fragm ent shader, assigns m em ory locat ions t o uniform variables, and so on. The result is one or m ore execut ables t hat can be inst alled wit h glUseProgram as part of OpenGL's current st at e. This com m and inst alls t he execut ables on t he vert ex processor, t he fragm ent processor, or bot h. The inst alled execut ables are responsible for processing all subsequent graphics prim it ives.

2.5.2. OpenGL Shading Language Compiler/Linker The source for a single shader is an array of st rings of charact ers, and a single shader is m ade from t he concat enat ion of t hese st rings. There is no inher ent connect ion bet w een st rings and t he lines of code in a shader. A shader m ay be ent irely represent ed by a single st ring, or each line of shader source code m ay be cont ained in a separat e st ring. Each st ring can cont ain m ult iple lines, separat ed by new- lines. No new- lines need be pr esent in a st ring; a single line can be form ed from m ult iple st rings. No new- lines or ot her charact ers are insert ed by t he OpenGL im plem ent at ion w hen it concat enat es t he st rings t o form a single shader. I t is ent irely up t o t he applicat ion program m er t o provide shader source code t o OpenGL wit h new- lines bet w een each line of source code. Diagnost ic m essages ret urned from com piling a shader m ust ident ify bot h t he line num ber wit hin a st ring and t he sour ce st ring t o w hich t he diagnost ic m essage applies. Source st rings are count ed sequent ially wit h t he first st ring count ed as st ring 0. For source code parsing, t he current line num ber is one m ore t han t he num ber of new - lines t hat have been pr ocessed. The front end of t he OpenGL Shading Language com piler has been released as open source by 3Dlabs and can be used by anyone int erest ed in writ ing his or her own com piler. This publicly available front end perform s lexical analysis of OpenGL Shading Language source code t o produce a t oken st ream and t hen perform s synt act ic and sem ant ic analysis of t his t oken st r eam t o produce a binary, high- level represent at ion of t he language. This fr ont end act s as a reference im plem ent at ion of t he OpenGL Shading Language, and t herefore it goes hand- in- hand wit h t he language specificat ion t o define t he language clearly. Anot her advant age t o using t his publicly available front end in an OpenGL Shading Language com piler im plem ent at ion is t hat t he synt ax and sem ant ics for shaders are checked consist ent ly by all im plem ent at ions t hat use t his fr ont end. More consist ency am ong com piler im plem ent at ions m akes it easier for developers t o writ e shaders t hat work as int ended acr oss a var iet y of im plem ent at ions.

I t is assum ed t hat t he back end of t he OpenGL Shading Language com piler will be im plem ent ed different ly on different plat form s. Each im plem ent at ion m ust t ake t he high- level represent at ion produced by t he publicly available front end and produce opt im ized m achine code for a par t icular hardware t arget . This is an area in which individual hardware vendors can add value t o t heir shading language im plem ent at ion by figuring out ways t o m ap t he high- level represent at ion ont o t he act ual m achine inst ruct ions found in t heir hardware. Likewise, t he linking st age is also highly hardware dependent because it involves operat ions like assigning variables t o act ual m em ory locat ions in t he hardware. A variet y of global opt im izat ions m ay also be perform ed as part of linking. The net result of t his assum pt ion is t hat graphics hardware vendors will im plem ent t he m aj orit y of t he OpenGL Shading Language com piler and linker. Along wit h t he OpenGL driver it self, t his soft ware w ill t ypically be included as part of t he graphics driver inst allat ion package t hat is provided by a graphics hardware vendor.

2.5.3. OpenGL Shading Language API As of OpenGL 2.0, support for t he OpenGL Shading Language is available as part of st andard OpenGL. The follow ing OpenGL ent ry point s support t he OpenGL Shading Language z

glAttachShader At t ach a shader obj ect t o a pr ogram obj ect

z

glBindAttribLocation Specify t he generic vert ex at t ribut e index t o be used for a part icular

user - defined at t ribut e var iable in a ver t ex shader z

glCompileShader Com pile a shader

z

glCreateProgram Creat e a program obj ect

z

glCreateShader Cr eat e a shader obj ect

z

glDeleteProgram Delet e a program obj ect

z

glDeleteShader Delet e a shader obj ect

z

glDetachShader Det ach a shader obj ect from a program obj ect

z

glDisableVertexAttribArray Disable a generic vert ex at t ribut e from being sent t o OpenGL wit h

ver t ex arrays z

glEnableVertexAttribArray Enable a generic vert ex at t ribut e t o be sent t o OpenGL w it h vert ex

arrays z

z

glGetActiveAttrib Obt ain t he nam e, size, and t ype of an act ive at t ribut e variable for a program obj ect glGetActiveUniform Obt ain t he nam e, size, and t ype of an act ive uniform variable for a

program obj ect z

glGetAttachedShaders Get t he list of shader obj ect s at t ached t o a program obj ect

z

glGetAttribLocation Ret urn t he generic vert ex at t ribut e index t hat is bound t o a specified

user - defined at t ribut e var iable z

glGetProgram Query one of t he param et ers of a program obj ect

z

glGetProgramInfoLog Obt ain t he inform at ion log for a program obj ect

z

glGetShader Query one of t he param et ers of a shader obj ect

z

glGetShaderInfoLog Obt ain t he inform at ion log for a shader obj ect

z

glGetShaderSource Get t he source code for a specific shader obj ect

z

glGetUniform Query t he current value of a uniform variable

z

glGetUniformLocation Query t he locat ion assigned t o a uniform variable by t he linker

z

glGetVertexAttrib Ret urn current st at e for t he specified generic vert ex at t ribut e

z

glGetVertexAttribPointer Ret urn t he vert ex array point er value for t he specified generic

vert ex at t ribut e z

glIsProgram Det erm ine if an obj ect nam e corresponds t o a program obj ect

z

glIsShader Det erm ine if an obj ect nam e corresponds t o a shader obj ect

z

glLinkProgram Link a program obj ect t o creat e execut able code

z

glShaderSource Load source code st rings int o a shader obj ect

z

glUniform Set t he value of a uniform variable

z

glUseProgram I nst all a program obj ect 's execut able code as part of current st at e

z

glValidateProgram Ret urn validat ion inform at ion for a program obj ect

z

glVertexAttrib Send generic vert ex at t r ibut es t o OpenGL one vert ex at a t im e

z

glVertexAttribPointer Specify locat ion and organizat ion of generic vert ex at t ribut es t o be sent

t o OpenGL w it h ver t ex arrays These new ent ry point s are all discussed in m ore det ail in Chapt er 7. Reference pages for all of t he OPENGL SHADI NG LANGUAGE API ent ry point s defined by t hese ext ensions are included in Appendix B at t he back of t his book.

2.6. Key Benefits The following key benefit s are derived from t he choices t hat were m ade during t he design of t he OpenGL Shading Language. Tigh t in t e gr a t ion w it h Ope n GL The OpenGL Shading Language was designed for use in OpenGL. I t is designed in such a way t hat an exist ing, w orking OpenGL applicat ion can easily be m odified t o t ake advant age of t he capabilit ies of program m able graphics hardware. Built - in access t o exist ing OpenGL st at e, reuse of API ent ry point s t hat are already fam iliar t o applicat ion developers, and a close coupling wit h t he exist ing archit ect ure of OpenGL are all key benefit s of using t he OpenGL Shading Language for shader developm ent . Ru n t im e com pila t ion Source code st ays as source code, in it s easiest - t o- m aint ain form , for as long as possible. An applicat ion passes source code t o any conform ing OpenGL im plem ent at ion t hat support s t he OpenGL Shading Language, and it will be com piled and execut ed properly. There is no need for a m ult it ude of binaries for a m ult it ude of different plat form s. [ 1] [1] At the time of this writing, the OpenGL ARB is still considering the need for an API that allows shaders to

be specified in a form other than source code. The primary issues are the protection of intellectual property that may be embedded in string-based shader source code and the performance that would be gained by allowing shaders to be at least partially precompiled. When such an API is defined, shader portability may be reduced, but application developers will have the option of getting better code security and better performance.

N o r e lia n ce on cr oss- ve n dor a sse m bly la n gu a ge Bot h Direct X and OpenGL have widespread support for assem bly language int erfaces t o graphics program m abilit y. High- level shading languages could be ( and have been) built on t op of t hese assem bly language int erfaces, and such high- level languages can be t ranslat ed int o t hese assem bly language int erfaces com plet ely out side t he environm ent of OpenGL or Direct X. This does have som e advant ages, but relying on an assem bly language int erface as t he prim ary int erface t o hardware program m abilit y rest rict s innovat ion by graphics hardware designers. Hardware designers have m any m ore choices for accelerat ion of an expressive high- level language t han t hey do for a rest rict ive assem bly language. I t is m uch t oo early in t he developm ent of program m able graphics hardware t echnology t o est ablish an assem bly language st andard for graphics program m abilit y. C, on t he ot her hand, was developed long before any CPU assem bly languages t hat are in exist ence t oday, and it is st ill a viable choice for applicat ion developm ent . Un con st r a in e d oppor t u n it ie s for com pile r opt im iza t ion plu s opt im a l pe r for m a n ce on a w ide r r a n ge of h a r dw a r e As we've learned t hrough experience w it h CPUs, com pilers are m uch bet t er at quickly generat ing efficient code t han hum ans are. By allowing high- level source code t o be com piled wit hin OpenGL, rat her t han out side of OpenGL, individual hardw are vendors have t he best possible opport unit y t o deliver opt im al perform ance on t heir graphics hardware. I n fact , com piler im pr ovem ent s can be m ade wit h each OpenGL driver release, and t he applicat ions w on't need t o change any applicat ion source code, recom pile t he applicat ion, or even relink it . Furt herm ore, m ost of t he current crop of assem bly language int erfaces are st ring based. This m akes t hem inefficient for use as int erm ediat e languages for com pilat ion because t wo st ring t ranslat ions are required. First , t he st ring- based, high- level source m ust be t ranslat ed int o st ring- based assem bly language, and t hen t hat st ring- based assem bly language m ust be passed t o OpenGL and t ranslat ed from st ring- based assem bly language t o m achine code. A t r u ly ope n , cr oss- pla t for m st a n da r d No ot her high- level graphics shading

language has been approved as part of an open, m ult ivendor st andard. Like OpenGL it self, t he OpenGL Shading Language will be im plem ent ed by a variet y of different vendors for a variet y of differ ent environm ent s. On e h igh - le ve l la n gu a ge for a ll pr ogr a m m a ble gr a ph ics pr oce ssin g The OpenGL Shading Language is used t o w rit e shaders for bot h t he vert ex processor and t he fragm ent pr ocessor in OpenGL, wit h very sm all differences in t he language for t he t wo t ypes of shaders. I n t he fut ure, it is int ended t hat t he OpenGL Shading Language will bring program m abilit y t o ot her areas of OpenGL as w ell. Areas t hat have already received som e discussion include program m abilit y for packing/ unpacking arbit rary im age form at s and support for program m able t essellat ion of higher - order surfaces in t he graphics hardware. Su ppor t for m odu la r pr ogr a m m in g By defining com pilat ion and linking as t w o separat e st eps, shader writ ers have a lot m ore flexibilit y in how t hey choose t o im plem ent com plex shading algorit hm s. Rat her t han im plem ent a com plex algor it hm as a single, m onolit hic shader, developers are free t o im plem ent it as a collect ion of shaders t hat can be independent ly com piled and at t ached t o a pr ogram obj ect . Shaders can be designed wit h com m on int erfaces so t hat t hey are int erchangeable, and a link operat ion j oins t hem t o creat e a program . N o a ddit ion a l libr a r ie s or e x e cu t a ble s The OpenGL Shading Language and t he com piler and linker t hat support it are defined as part of OpenGL. Applicat ions need not worry about linking against any addit ional runt im e libraries. Com piler im provem ent s are deliver ed as part of OpenGL driver updat es.

2.7. Summary Here are t he key point s t o underst and about how all t he pieces fit t oget her at execut ion t im e. z

z

z

z

z

z

z

z

z z

z

When inst alled as part of current st at e, t he execut able creat ed for t he vert ex processor is execut ed once for every vert ex provided t o OpenGL. When inst alled as part of current st at e, t he execut able creat ed for t he fragm ent processor is execut ed once for every fragm ent t hat is produced by rast erizat ion. When vert ex or fragm ent shaders are used, t he cor responding fixed funct ionalit y is disabled. Shaders m ust im plem ent such funct ionalit y t hem selves if it is desired. Varying variables defined in a vert ex shader are per- vert ex values t hat are out put from t he vert ex processor. Rast erizat ion is t he process t hat causes t he per- ver t ex values t o be int erpolat ed and per- fragm ent values t o be generat ed. The per- fragm ent values becom e t he input t o t he fragm ent processor and are accessed in t he fragm ent shader wit h t he sam e varying variable nam e as w as used in t he ver t ex shader . An applicat ion can com m unicat e direct ly wit h a vert ex shader in t wo ways: by using at t ribut e variables and by using uniform variables. At t ribut e var iables are expect ed t o change frequent ly and m ay be supplied by t he applicat ion as oft en as every vert ex. Applicat ions can pass arbit rary vert ex dat a t o a vert ex shader w it h user - defined at t ribut e variables. Applicat ions can pass st andard vert ex at t ribut es ( color, norm al, t ext ure coordinat es, posit ion, et c.) t o a vert ex shader wit h built - in at t ribut e variables. An applicat ion com m unicat es direct ly wit h a fragm ent shader wit h uniform variables. Uniform variables are expect ed t o change relat ively infrequent ly ( at a m inim um , t hey are const ant for an ent ire graphics prim it ive) . The com piler and linker for t he language are cont ained wit hin OpenGL, but t ools for com piling, linking, and debugging shaders can exist out side of OpenGL as well.

To sum m arize, t he follow ing are t he m ost im port ant point s about t he OpenGL Shading Language. z

The language is based on t he synt ax of C.

z

Basic st ruct ure and m any keywords are t he sam e as in C.

z

Vect ors and m at rices are included in t he language as basic t ypes.

z

Type qualifiers a t t r ibu t e , u n ifor m , and va r yin g are added t o describe variables t hat m anage shader I / O. {

Variables of t ype a t t r ibu t e allow t he com m unicat ion of frequent ly changing values

from t he applicat ion t o t he vert ex shader. {

{

z z

z z

z

Variables of t ype va r yin g are t he out put from a vert ex shader and t he input t o a fragm ent shader. Variables of t ype u n ifor m allow t he applicat ion t o pr ovide relat ively infrequent ly changing values t o bot h vert ex shaders and fragm ent shaders.

The dat a t ype sa m ple r is added for accessing t ext ures. Built - in variable nam es can be used t o access st andard OpenGL st at e and t o com m unicat e wit h OpenGL fixed funct ionalit y. A variet y of built - in funct ions per form com m on graphics operat ions. Funct ion declarat ions are required, and overloading based on num ber and t ype of argum ent s is support ed as in C+ + . Variables can be declared when needed.

To inst all and use OpenGL shader s, do t he following: 1.

Creat e one or m ore ( em pt y) shader obj ect s by calling glCreateShader.

2.

Provide source code for t hese shaders by calling glShaderSource.

3.

Com pile each of t he shaders by calling glCompileShader.

4.

Creat e a program obj ect by calling glCreateProgram.

5.

At t ach all t he shader obj ect s t o t he program obj ect by calling glAttachShader.

6.

Link t he program obj ect by calling glLinkProgram.

7.

I nst all t he execut able program as part of OpenGL's current st at e by calling glUseProgram.

Aft er t hese st eps, subsequent graphics prim it ives will be drawn wit h t he shaders you've provided rat her t han w it h OpenGL's defined fixed funct ionalit y pipeline.

2.8. Further Information Just keep reading t his book and you'll get t o all of t he really good st uff! I f you really m ust have m ore t echnical det ails, here are point ers t o t he official specificat ion docum ent s. The 3Dlabs Web sit e also has addit ional m at erial, including slide present at ions, dem os, exam ple shaders, and source code. 1 . 3Dlabs developer Web sit e. ht t p: / / developer.3dlabs.com 2 . Kessenich, John, Dave Baldwin, and Randi Rost , The OpenGL Shading Language, Version 1.10, 3Dlabs, April 2004. ht t p: / / w ww .opengl.org/ docum ent at ion/ spec.ht m l 3 . Segal, Mark, and Kurt Akeley, The OpenGL Graphics Syst em : A Specificat ion ( Version 2.0) , Edit or ( v1.1) : Chris Fr azier, ( v1.21.5) : Jon Leech, ( v2.0) : Jon Leech and Pat Brow n, Sept . 2004. ht t p: / / w ww .opengl.org/ docum ent at ion/ spec.ht m l

Chapter 3. Language Definition by John Kessenich I n t his chapt er, we present t he language feat ures of t he OpenGL Shading Language. We st art wit h a sim ple exam ple of a working pair of vert ex and fragm ent shaders t o show t heir basic st ruct ure and int erfaces. Each aspect of t he language is t hen discussed in t urn. The OpenGL Shading Language synt ax com es from t he C fam ily of program m ing languages. Tokens, ident ifiers, sem icolons, nest ing wit h curly braces, cont rol- flow, and m any keyw ords look like C. Bot h com m ent st yles, / / . . . and / * . . . * / , are accept ed. Much is also different t hough, and all im port ant differences from C are discussed. Each shader exam ple is present ed as it m ight appear in a file or onscreen. However, as explained in Chapt er 7, t he OpenGL API passes shaders as st rings, not files, because OpenGL does not consider shaders file based.

3.1. Example Shader Pair A program t ypically cont ains t wo shaders: one vert ex shader and one fragm ent shader. More t han one shader of each t ype can be present , but t here m ust be exact ly one funct ion main bet w een all t he fr agm ent shader s and exact ly one funct ion main bet ween all t he vert ex shaders. Frequent ly, it 's easiest t o j ust have one shader of each t ype. The following is a sim ple vert ex and fragm ent shader pair t hat can sm oot hly express a surface t em perat ure w it h color. The range of t em perat ures and t heir colors are param et erized. First , we show t he vert ex shader. I t is execut ed once for each ver t ex. // uniform qualified variables are changed at most once per primitive uniform float CoolestTemp; uniform float TempRange; // attribute qualified variables are typically changed per vertex attribute float VertexTemp; // varying qualified variables communicate from the vertex shader to // the fragment shader varying float Temperature; void main() { // compute a temperature to be interpolated per fragment, // in the range [0.0, 1.0] Temperature = (VertexTemp - CoolestTemp) / TempRange; /* The vertex position written in the application using glVertex() can be read from the built-in variable gl_Vertex. Use this value and the current model view transformation matrix to tell the rasterizer where this vertex is. */ gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; }

That 's it for t he vert ex shader. Prim it ive assem bly follows t he pr eceding vert ex processing, providing t he rast erizer w it h enough inform at ion t o creat e fragm ent s. The rast erizer int erpolat es t he Temperature values writ t en per vert ex t o creat e values per fragm ent . Each fragm ent is t hen delivered t o a single execut ion of t he fragm ent shader, as follow s: // uniform qualified variables are changed at most once per primitive // by the application, and vec3 declares a vector of three // floating-point numbers uniform vec3 CoolestColor; uniform vec3 HottestColor; // Temperature contains the now interpolated per-fragment // value of temperature set by the vertex shader varying float Temperature; void main() { // get a color between coolest and hottest colors, using // the mix() built-in function vec3 color = mix(CoolestColor, HottestColor, Temperature);

// make a vector of 4 floating-point numbers by appending an // alpha of 1.0, and set this fragment's color gl_FragColor = vec4(color, 1.0); }

Bot h shaders receive user - defined st at e from t he applicat ion t hrough t he declared u n ifor m qualified variables. The vert ex shader get s inform at ion associat ed wit h each vert ex t hrough t he a t t r ibu t e qualified variable. I nform at ion is passed from t he vert ex shader t o t he fragm ent shader t hrough va r yin g qualified variables, whose declarat ions m ust m at ch bet w een t he ver t ex and fragm ent shaders. The fixed funct ionalit y locat ed bet ween t he vert ex and fragm ent processors w ill int erpolat e t he per- vert ex values writ t en t o t his varying variable. When t he fragm ent shader reads t his sam e varying variable, it reads t he value int erpolat ed for t he locat ion of t he fragm ent being processed. Shaders int eract wit h t he fixed funct ionalit y OpenGL pipeline by writ ing built - in variables. OpenGL prefixes built - in variables wit h " gl_" . I n t he preceding exam ples, w rit ing t o gl_Position t ells t he OpenGL pipeline where t he t ransform ed vert ices are locat ed, and writ ing t o gl_FragColor t ells t he OpenGL pipeline what color t o at t ach t o a fragm ent . Execut ion of t he preceding shaders occurs m ult iple t im es t o process a single prim it ive, once per ver t ex for t he vert ex shader and once per fragm ent for t he fr agm ent shader. Many such execut ions of t he sam e shader can happen in parallel. I n general, t here is no direct t ie or ordering bet ween shader execut ions. I nform at ion can be com m unicat ed neit her from vert ex t o vert ex nor from fr agm ent t o fragm ent .

3.2. Data Types We saw vect ors of float ing- point num bers in t he exam ple in t he previous sect ion. Many ot her built - in dat a t ypes are available t o ease t he expression of graphical operat ions. Booleans, int egers, m at rices, vect ors of ot her t ypes, st ruct ures, and arrays are all included. Each is discussed in t he following sect ions. Not ably m issing are st ring and charact er t ypes, since t here is lit t le use for t hem in processing vert ex and fragm ent dat a.

3.2.1. Scalars The scalar t ypes available are floa t

declar es a single float ing- point num ber

in t

declar es a single int eger num ber

bool

declar es a single Boolean num ber

These declare variables, as is fam iliar from C/ C+ + . float f; float g, h = 2.4; int NumTextures = 4; bool skipProcessing;

Unlike t he original C, t he OpenGL Shading Language requires you t o provide t he t ype nam e because t her e are no default t ypes. As in C+ + , declarat ions m ay appear when needed, not j ust aft er an open curly brace ( { ) . Lit eral float ing- point num bers are also specified as in C, except t here are no suffixes t o specify precision since t here is only one float ing- point t ype. 3.14159 3. 0.2 .609 1.5e10 0.4E-4 etc.

I n general, float ing- point values and operat ions act as t hey do in C. I nt egers are not t he sam e as in C. There is no requirem ent t hat t hey appear t o be backed in hardware by a fixed- widt h int eger regist er. Consequent ly, w rapping behavior, w hen arit hm et ic would overflow or underflow a fixed- widt h int eger regist er, is undefined. Bit - wise operat ions like left - shift ( < < ) and bit - wise and ( & ) are also not support ed. What can be said about int egers? They are guarant eed t o have at least 16 bit s of precision; t hey can be posit ive, negat ive, or zero; and int eger arit hm et ic t hat st ays wit hin t his range gives t he expect ed result s. Not e t hat t he pr ecision t ruly is 16 bit s plus t he sign of t he valuet hat is, a full range of [ - 65535,65535] or great er.

Lit eral int egers can be given as decim al values, oct al values, or hexadecim al values, as in C. 42 052 0x2A

// a literal decimal integer // a literal octal integer // a literal hexadecimal integer

Again, t her e are no suffixes t o specify precision since t here is only one int eger t ype. I nt egers are useful as sizes of st ruct ures or arrays and as loop count ers. Graphical t ypes, such as color or posit ion, are best expressed in float ing- point variables wit hin a shader. Boolean variables are as bool in C+ + . They can have only one of t wo values: t rue or false. Lit eral Boolean const ant s t r u e and fa lse are provided. Relat ional operat ors like less- t han ( < ) and logical operat ors like logical and ( & & ) always result in Boolean values. Flow- cont rol const ruct s like if- e lse accept only Boolean- t yped expressions. I n t hese regards, t he OpenGL Shading Language is m ore rest rict ive t han C+ + .

3.2.2. Vectors Vect or s of floa t , in t , or bool are built - in basic t ypes. They can have t wo, t hree, or four com ponent s and are nam ed as follows: ve c2

Vect or of t w o float ing- point num bers

ve c3

Vect or of t hree float ing- point num bers

ve c4

Vect or of four float ing- point num bers

iv e c2

Vect or of t w o int egers

iv e c3

Vect or of t hree int eger s

iv e c4

Vect or of four int egers

bve c2

Vect or of t w o Booleans

bve c3

Vect or of t hree Booleans

bve c4

Vect or of four Booleans

Vect or s are quit e useful. They convenient ly st ore and m anipulat e colors, posit ions, t ext ure coordinat es, and so on. Built - in variables and built - in funct ions m ake heavy use of t hese t ypes. Also, special operat ions are support ed. Finally, hardware is likely t o have vect or- processing capabilit ies t hat m irror vect or expressions in shaders. Not e t hat t he language does not dist inguish bet w een a color vect or and a posit ion vect or or ot her uses of a float ing- point vect or. These are all j ust float ing- point vect ors from t he language's perspect ive. Special feat ures of vect ors include com ponent access t hat can be done eit her t hrough field select ion ( as wit h st ruct ures) or as array accesses. For exam ple, if position is a vec3, it can be considered as t he vect or ( x, y, z) , and position.x will select t he first com ponent of t he vect or. I n all, t he following nam es are available for select ing com ponent s of vect ors:

x, y, z, w

Treat a vect or as a posit ion or direct ion

r, g, b, a

Treat a vect or as a color

s, t , p, q

Treat a vect or as a t ext ure coor dinat e

There is no explicit way of st at ing t hat a vect or is a color, a posit ion, a coordinat e, and so on. Rat her, t hese com ponent select ion nam es are provided sim ply for readabilit y in a shader. The only com pile- t im e checking done is t hat t he vect or is large enough t o provide a specified com ponent . Also, if m ult iple com ponent s are select ed ( swizzling, discussed in Sect ion 3.7.2) , all t he com ponent s are from t he sam e fam ily. Vect ors can also be indexed as a zero- based array t o obt ain com ponent s. For inst ance, position[2] ret urns t he t hird com ponent of position. Variable indices are allowed, m aking it possible t o loop over t he com ponent s of a vect or. Mult iplicat ion t akes on special m eaning when oper at ing on a vect or since linear algebraic m ult iplies wit h m at r ices are underst ood. Swizzling, indexing, and ot her operat ions are discussed in det ail in Sect ion 3.7.

3.2.3. Matrices Built - in t ypes are available for m at rices of float ing- point num bers. There are 2 x 2, 3 x 3, and 4 x 4 sizes. m at2

2 x 2 m at rix of float ing- point num bers

m at3

3 x 3 m at rix of float ing- point num bers

m at4

4 x 4 m at rix of float ing- point num bers

These are useful for st oring linear t ransform s or ot her dat a. They are t reat ed sem ant ically as m at r ices, part icular ly when a vect or and a m at rix are m ult iplied t oget her, in which case t he proper linear - algebr aic com put at ion is perform ed. When relevant , m at rices are organized in colum n m aj or order, as is t he t radit ion in OpenGL. You m ay access a m at rix as an array of colum n vect orst hat is, if transform is a m a t 4 , transform[2] is t he t hird colum n of transform. The result ing t ype of transform[2] is vec4. Colum n 0 is t he first colum n. Because transform[2] is a vect or and you can also t reat vect ors as arrays, transform[3][1] is t he second com ponent of t he vect or form ing t he fourt h colum n of transform. Hence, it ends up looking as if transform is a t wo- dim ensional array. Just rem em ber t hat t he first index select s t he colum n, not t he row, and t he second index select s t he row.

3.2.4. Samplers Text ure lookups requir e som e indicat ion as t o which t ext ure or t ext ure unit will do t he lookup. The OpenGL Shading Language doesn't really care about t he underlying im plem ent at ion of t ext ure unit s or ot her form s of or ganizing t ext ure lookup hardw are. Hence, it provides a sim ple opaque handle t o encapsulat e what t o look up. These handles are called SAMPLERS. The sam pler t ypes available are sa m ple r 1 D

Accesses a one- dim ensional t ext ure

sa m ple r 2 D

Accesses a t w o- dim ensional t ext ure

sa m ple r 3 D

Accesses a t hree- dim ensional t ext ure

sa m ple r Cu be

Accesses a cube- m ap t ext ure

sa m ple r 1 D Sh a dow

Accesses a one- dim ensional dept h t ext ure w it h com parison

sa m ple r 2 D Sh a dow

Accesses a t w o- dim ensional dept h t ext ure w it h com parison

When t he applicat ion init ializes a sam pler, t he OpenGL im plem ent at ion st ores int o it w hat ever infor m at ion is needed t o com m unicat e what t ext ure t o access. Shaders cannot t hem selves init ialize sam plers. They can only receive t hem from t he applicat ion, t hrough a u n ifor m qualified sam pler, or pass t hem on t o user or built - in funct ions. As a funct ion param et er, a sam pler cannot be m odified, so t here is no way for a shader t o change a sam pler's value. For exam ple, a sam pler could be declared as uniform sampler2D Grass;

( Uniform qualifiers are discussed in m ore det ail in Sect ion 3.5.2.) This variable can t hen be passed int o a corresponding t ext ure lookup funct ion t o access a t ext ure: vec4 color = texture2D(Grass, coord);

where coord is a ve c2 holding t he t wo- dim ensional posit ion used t o index t he grass t ext ure, and color is t he result of doing t he t ext ure lookup. Toget her, t he com piler and t he OpenGL driver validat e t hat Grass really references a t wo- dim ensional t ext ure and t hat Grass is passed only int o t w o- dim ensional t ext ure lookups. Shaders m ay not m anipulat e sam pler values. For exam ple, t he expression Grass + 1 is not allowed. I f a shader want s t o com bine m ult iple t ext ures pr ocedurally, an array of sam plers can be used as show n here: const int NumTextures = 4; uniform sampler2D textures[NumTextures];

These can be pr ocessed in a loop: for (int i = 0; i < NumTextures; ++i) . . . = texture2D(textures[i], . . .);

The idiom Grass+1 could t hen becom e som et hing like textures[GrassIndex+1]

which is a valid way of m anipulat ing t he sam pler.

3.2.5. Structures The OpenGL Shading Language provides user- defined st ruct ures sim ilar t o C. For exam ple,

struct light { vec3 position; vec3 color; };

As in C+ + , t he nam e of t he st ruct ure is t he nam e of t his new user- defined t ype. No t y pe de f is needed. I n fact , t he t y pe de f keyword is st ill reserved because t here is not yet a need for it . A variable of t ype light from t he preceding exam ple is sim ply declar ed as light ceilingLight;

Most ot her aspect s of st ruct ures m irror C. They can be em bedded and nest ed. Em bedded st ruct ure t ype nam es have t he sam e scope as t he st ruct ure in which t hey ar e declar ed. However, em bedded st ruct ures m ust be nam ed. St ruct ure m em bers can also be arrays. Finally, each level of st ruct ure has it s own nam e space for it s m em bers' nam es, as is fam iliar. Bit - fields ( t he capabilit y t o declare an int eger wit h a specified num ber of bit s) are not support ed. Curr ent ly, st ruct ures are t he only user- definable t ype. The keywords u n ion , e n u m , and cla ss are reserved for possible fut ure use.

3.2.6. Arrays Ar rays of any t ype can be creat ed. The declarat ion vec4 points[10];

creat es an array of t en ve c4 variables, indexed st art ing wit h zero. There are no point ers; t he only w ay t o declare an array is wit h square bracket s. Declaring an array as a funct ion param et er also requires square bracket s and a size because, current ly, array argum ent s are passed as if t he whole ar ray is a single obj ect , not as if t he argum ent is a point er. Ar rays, unless t hey are funct ion param et ers, do not have t o be declared wit h a size. A declarat ion like vec4 points[];

is allowed, as long as eit her of t he following t wo cases is t rue: 1 . Before t he array is referenced, it is declared again wit h a size, wit h t he sam e t ype as t he first declarat ion. For exam ple, vec4 points[]; vec4 points[10];

// points is an array of unknown size // points is now an array of size 10

This cannot be followed by anot her declarat ion: vec4 vec4 vec4 vec4

points[]; points[10]; points[20]; points[];

// // // //

points is an array of unknown size points is now an array of size 10 this is illegal this is also illegal

2 . All indices t hat st at ically reference t he array are com pile- t im e const ant s. I n t his case, t he com piler w ill m ake t he array large enough t o hold t he largest index it sees used. For exam ple, vec4 points[]; // points is an array of unknown size points[2] = vec4(1.0); // points is now an array of size 3 points[7] = vec4(2.0); // points is now an array of size 8 I n t his case, at runt im e t he array has only one size, det erm ined by t he largest index t he com piler sees. Such aut om at ically sized arrays cannot be passed as funct ion argum ent s. This feat ure is quit e useful for handling t he built - in array of t ext ure coordinat es. I nt ernally, t his array is declar ed as varying vec4 gl_TexCoord[];

I f a pr ogram uses only com pile- t im e const ant indices of 0 and 1, t he array is im plicit ly sized as gl_TexCoord[2]. I f a shader uses a nonconst ant variable t o index t he array, t hat shader m ust explicit ly declare t he array wit h t he desired size. Of course, keeping t he size t o a m inim um is im port ant , especially for varying variables, which are likely a lim it ed hardware resource. Mult iple shaders sharing t he sam e array m ust declare it w it h t he sam e size. The linker verifies t his.

3.2.7. Void The t ype void declares a funct ion t hat ret urns no value. For exam ple, t he funct ion main ret urns no value and m ust be declared as t ype void. void main() { . . . }

Ot her t han for funct ions t hat ret urn not hing, t he void t ype is not useful.

3.2.8. Declarations and Scope Variables are declared quit e sim ilarly t o t he way t hey are declar ed in C+ + . They can be declar ed w here needed and have scope as in C+ + . For exam ple, float f; f = 3.0; vec4 u, v; for (int i = 0; i < 10; ++i) v = f * u + v;

The scope of a variable declared in a for st at em ent ends at t he end of t he loop's subst at em ent . However, variables m ay not be declared in an if st at em ent . This sim plifies im plem ent at ion of scoping across t he e lse subst at em ent , wit h lit t le pract ical cost . As in C, variable nam es are case sensit ive, m ust st art wit h a let t er or underscore ( _) , and

cont ain only let t ers, num bers, and underscores ( _) . Userdefined variables cannot st art wit h t he st ring " gl_" , because t hose nam es are reserved for fut ure use by OpenGL. Nam es cont aining consecut ive underscores ( __) are also reserved.

3.2.9. Type Matching and Promotion The OpenGL Shading Language is st rict wit h t ype m at ching. I n general, t ypes being assigned m ust m at ch, argum ent t ypes passed int o funct ions m ust m at ch form al param et er declarat ions, and t ypes being operat ed on m ust m at ch t he r equirem ent s of t he operat or. There are no aut om at ic prom ot ions from one t ype t o anot her. This m ay occasionally m ake a shader have an ext ra explicit conversion. However, it also sim plifies t he language, prevent ing som e form s of obfuscat ed code and som e classes of defect s. For exam ple, t here are no am biguit ies in w hich overloaded funct ion should be chosen for a given funct ion call.

3.3. Initializers and Constructors A shader variable m ay be init ialized when it is declared. As is fam iliar from C, t he following exam ple init ializes b at declar at ion t im e and leaves a and c undefined: float a, b = 3.0, c;

Const ant qualified variables m ust be init ialized. const int Size = 4;

// initializer is required

At t ribut e, uniform , and varying variables cannot be init ialized when declared. attribute float Temperature;

// no initializer allowed, // the vertex API sets this

uniform int Size;

// no initializer allowed, // the uniform setting API sets this

varying float density;

// no initializer allowed, the vertex // shader must programmatically set this

To init ialize aggr egat e t ypes, at eit her declarat ion t im e or elsew here, CONSTRUCTORS are used. No init ializer uses t he brace synt ax " { . . .} " fr om C. Synt act ically, const ruct ors look like funct ion calls t hat have a t ype nam e where t he funct ion nam e would gofor exam ple, t o init ialize a ve c4 wit h t he values ( 1.0, 2.0, 3.0, 4.0) , use vec4 v = vec4(1.0, 2.0, 3.0, 4.0);

Or, because const r uct or synt ax is t he sam e whet her it 's in an init ializer or not , use vec4 v; v = vec4(1.0, 2.0, 3.0, 4.0);

There are const ruct ors for all t he built - in t ypes ( except sam plers) as well as for st ruct ures. Som e exam ples: vec4 v = vec4(1.0, 2.0, 3.0, 4.0); ivec2 c = ivec2(3, 4); vec3 color = vec3(0.2, 0.5, 0.8); vec4 color4 = vec4(color, 1.0) struct light { vec4 position; struct tLightColor { vec3 color; float intensity; } lightColor; } light1 = light(v, tLightColor(color, 0.9));

For m at rices, t he com ponent s are writ t en in colum n m aj or order . For exam ple, mat2 m = mat2(1.0, 2.0, 3.0, 4.0);

result s in t he following m at rix:

So far, we've only shown const ruct ors t aking one argum ent for each com ponent being const ruct ed. Built - in const r uct ors for vect ors can also t ake a single ar gum ent , which is replicat ed int o each com ponent . vec3 v = vec3(0.6);

is equivalent t o vec3 v = vec3(0.6, 0.6, 0.6);

This is t rue only for vect ors. St ruct ure const ruct ors m ust receive one argum ent per m em ber being const r uct ed. Mat rix const r uct ors also have a single argum ent form , but in t his case it init ializes j ust t he diagonal of t he m at rix. The rem aining com ponent s are init ialized t o 0.0. mat2 m = mat2(1.0);

// makes a 2 x 2 identity matrix

is equivalent t o mat2 m = mat2(1.0, 0.0, 0.0, 1.0);

// makes a 2 x 2 identity matrix

Const ruct ors can also have vect ors and m at rices as argum ent s. However , const ruct ing m at rices from ot her m at r ices is reserved for fut ure definit ion. vec4 v = vec4(1.0); vec2 u = vec2(v); // the first two components of v initialize u mat2 m = mat2(v);

Mat rix com ponent s are read out of argum ent s in colum n m aj or order and writ t en in colum n m aj or order. Ext ra com ponent s wit hin a single const ruct or ar gum ent are silent ly ignored. Norm ally, t his is useful for shrinking a value, like elim inat ing alpha from a color or w from a posit ion. I t is an error t o have com plet ely unused argum ent s passed t o a const ruct or. vec2 t = vec2(1.0, 2.0, 3.0);

// illegal; third argument is unused

3.4. Type Conversions Explicit t ype conversions are perform ed wit h const ruct ors. For exam ple, float f = 2.3; bool b = bool(f);

set s b t o t r u e . This is useful for flow - cont rol const ruct s, like if, which require Boolean values. Boolean const ruct ors convert non- zero num eric values t o t r u e and zero num eric values t o false. The OpenGL Shading Language does not provide C- st yle t ypecast synt ax, which can be am biguous as t o whet her a value is convert ed t o a different t ype or is sim ply reint erpret ed as a different t ype. I n fact , t here is no way of reint erpret ing a value as a different t ype in t he OpenGL Shading Language. There are no point er s, no t ype unions, no im plicit t ype changes, and no reint erpret cast s. I nst ead, const ruct ors perform conversions. The argum ent s t o a const ruct or are convert ed t o t he t ype t hey are const ruct ing. Hence, t he following are allowed: float f = float(3); float g = float(b); vec4 v = vec4(2);

// convert integer 3 to floating-point 3.0 // convert Boolean b to floating point // set all components of v to 2.0

For conversion from a Boolean, t r u e is convert ed t o 1 or 1.0, and fa lse is convert ed t o a zero.

3.5. Qualifiers and Interface to a Shader Qualifiers prefix bot h variables and form al funct ion param et ers. The qualifiers t hat m odify form al funct ion param et ers ( con st , in , ou t , and in out ) are discussed in Sect ion 3.6.2. This sect ion focuses on t he ot her qualifiers, m ost of which form t he int erfaces of t he shaders t o t heir out side world. The following is t he com plet e list of qualifiers ( used out side of for m al funct ion param et ers) . a t t r ibu t e

For frequent ly changing inform at ion, from t he applicat ion t o a vert ex shader

u n ifor m

For infrequent ly changing inform at ion, from t he applicat ion t o eit her a vert ex shader or a fragm ent shader

va r yin g

For int erpolat ed inform at ion passed from a vert ex shader t o a fragm ent shader

con st

For declaring nonwrit able, com pile- t im e const ant variables, as in C

Get t ing inform at ion int o and out of a shader is quit e different from m ore t ypical program m ing environm ent s. I nform at ion is t ransferred t o and from a shader by reading and writ ing built - in variables and user - defined a t t r ibu t e , u n ifor m , and va r yin g variables. The m ost com m on built - in variables were shown in t he exam ple at t he beginning of t his chapt er. They are gl_Position for out put of t he hom ogeneous coordinat es of t he vert ex posit ion and gl_FragColor for out put of t he fr agm ent 's color from a fragm ent shader. The com plet e set of built - in variables is provided in Chapt er 4. Exam ples of a t t r ibu t e , u n ifor m , and va r yin g qualified variables were seen briefly in t he opening exam ple for get t ing ot her inform at ion int o and out of shaders. Each is discussed in t his sect ion. Variables qualified as a t t r ibu t e , u n ifor m , or va r yin g m ust be declared at global scope. This is sensible since t hey are visible out side of shaders and, for a single progr am , t hey all share a single nam e space. Qualifiers are always specified before t he t ype of a variable, and because t here is no default t ype, t he form of a qualified variable declar at ion alw ays includes a t ype. attribute float Temperature; const int NumLights = 3; uniform vec4 LightPosition[NumLights]; varying float LightIntensity;

3.5.1. Attribute Qualifiers At t ribut e- qualified variables ( or at t ribut es) enable an applicat ion t o pass fr equent ly m odified dat a int o a vert ex shader. They can be changed as oft en as once per vert ex, eit her direct ly or indirect ly by t he applicat ion. Built - in at t ribut es, like gl_Vertex and gl_Normal, read t r adit ional OpenGL st at e, and user- defined at t ribut es can be nam ed by t he coder. At t ribut es are lim it ed t o float ing- point scalars, float ing- point vect ors, and m at rices. At t ribut es declared as int egers or Booleans are not allowed, nor are at t ribut es declared as st ruct ur es or arrays. This is, in part , a result of encouraging high- perform ance frequent changing of at t ribut es in hardware im plem ent at ions of t he OpenGL syst em . At t ribut es cannot be m odified by a shader.

At t ribut es cannot be declared in fragm ent shaders.

3.5.2. Uniform Qualifiers Uniform qualified variables ( or uniform s) , like at t ribut es, are set only out side a shader and are int ended for dat a t hat changes less frequent ly. They can be changed at m ost once per prim it ive. All dat a t ypes and arrays of all dat a t ypes are support ed for uniform qualified variables. All t he vert ex and fragm ent shader s form ing a single program share a single global nam e space for uniform s. Hence, uniform s of t he sam e nam e in a vert ex and fr agm ent program will be t he sam e uniform variable. Uniform s cannot be writ t en t o in a shader. This is sensible because an array of pr ocessors m ay be sharing t he sam e resources t o hold uniform s and ot her language sem ant ics break down if uniform s could be m odified. Recall t hat unless a m ust be used when uniform s allows t he t ext ure and t ext ure

sam pler ( e.g., sa m ple r 2 D ) is a funct ion param et er, t he u n ifor m qualifier it is declared. This is because sam plers are opaque, and m aking t hem OpenGL driver t o validat e t hat t he applicat ion init ializes a sam pler wit h a unit consist ent wit h it s use in t he shader.

3.5.3. Varying Qualifiers Varying qualified variables ( or varyings) are t he only way a vert ex shader can com m unicat e result s t o a fragm ent shader. Such variables form t he dynam ic int erface bet ween vert ex and fragm ent shaders. The int ent ion is t hat for a part icular at t ribut e of a drawing prim it ive, each vert ex m ight have a different value and t hese values need t o be int erpolat ed across t he fragm ent s in t he prim it ive. The vert ex shader w rit es t he per- vert ex values int o a varying variable, and when t he fr agm ent shader reads from t his variable, it get s back a value int erpolat ed bet ween t he vert ices. I f som e at t ribut e were t o be t he sam e across a large prim it ive, not requiring int erpolat ion, t he vert ex shader need not com m unicat e it t o t he fragm ent shader at all. I nst ead, t he applicat ion could pass t his value direct ly t o t he fragm ent shader t hrough a uniform qualified variable. The except ion t o using varying variables only for int erpolat ed values is for any value t he applicat ion will change oft en, eit her per t riangle or per som e sm all set of t riangles or vert ices. These values m ay be fast er t o pass as a t t r ibu t e variables and forw arded as va r yin g variables because changing u n ifor m values fr equent ly m ay im pact perform ance. The aut om at ic int erpolat ion of va r yin g qualified variables is done in a perspect ive- correct m anner. This approach is necessary no m at t er what t ype of dat a is being int erpolat ed. Ot herwise, such values would not change sm oot hly across edges int roduced for surface subdivision. The non- perspect ive- correct int er polat ed result would be cont inuous, but it s derivat ive would not be, and t his effect can be quit e visible. A va r yin g qualified variable is writ t en in a ver t ex shader and read in a fragm ent shader. I t is illegal for a fragm ent shader t o w rit e t o a varying variable. How ever, t he vert ex shader m ay read a varying variable, get t ing back what it has j ust writ t en. Reading a varying qualified variable before writ ing it ret urns an undefined value.

3.5.4. Constant Qualifiers Variables qualified as con st ( except for form al funct ion param et ers) are com pile- t im e const ant s and are not visible out side t he shader t hat declares t hem . Bot h scalar and nonscalar const ant s are support ed. St ruct ure fields m ay not be qualified wit h con st , but st ruct ure variables can be declar ed as con st and init ialized wit h a st ruct ure const ruct or. I nit ializers for con st declarat ions m ust be form ed fr om lit eral values, ot her con st qualified variables ( not including funct ion call par am et ers) , or expressions of t hese.

Som e exam ples: const int numIterations = 10; const float pi = 3.14159; const vec2 v = vec2(1.0, 2.0); const vec3 u = vec3(v, pi); const struct light { vec3 position; vec3 color; } fixedLight = light(vec3(1.0, 0.5, 0.5), vec3(0.8, 0.8, 0.5));

All t he preceding variables are com pile- t im e const ant s. The com piler m ay propagat e and fold const ant s at com pile t im e, using t he precision of t he processor execut ing t he com piler, and need not allocat e any runt im e resources t o con st qualified variables.

3.5.5. Absent Qualifier I f no qualifier is specified when a variable ( not a funct ion param et er) is declared, t he variable can be bot h read and writ t en by t he shader. Nonqualified variables declared at global scope can be shared bet w een shaders of t he sam e t ype t hat are linked in t he sam e pr ogram . Vert ex shaders and fragm ent shaders each have t heir own separat e global nam e space for nonqualified globals. However, nonqualified user- defined variables are not visible out side a pr ogram . That privilege is reserved for variables qualified as a t t r ibu t e or u n ifor m and for built - in variables represent ing OpenGL st at e. Unqualified variables have a lifet im e lim it ed t o a single run of a shader. There is also no concept corresponding t o a st a t ic variable in a C funct ion t hat would allow a variable t o be set t o a value and have it s shader ret ain t hat value from one execut ion t o t he next . I m plem ent at ion of such variables is m ade difficult by t he parallel processing nat ur e of t he execut ion environm ent , in w hich m ult iple inst ant iat ions run in par allel, sharing m uch of t he sam e m em ory. I n general, writ able variables m ust have unique inst ances per processor execut ing a shader and t herefore cannot be shared. Because unqualified global variables have a different nam e space for vert ex shaders t han t hat for fragm ent shaders, it is not possible t o share inform at ion t hrough such variables bet w een ver t ex and fr agm ent shader s. Read- only variables can be shared if declared as u n ifor m , and variables writ t en by a vert ex shader can be read by t he fragm ent shader only t hrough t he va r yin g m echanism .

3.6. Flow Control Flow cont rol is very m uch like t hat in C+ + . The ent ry point int o a shader is t he funct ion main. A progr am cont aining bot h ver t ex and fr agm ent shader s has t wo funct ions nam ed main, one for ent ering a vert ex shader t o process each vert ex and one t o ent er a fragm ent shader t o process each fr agm ent . Before main is ent ered, any init ializers for global variable declarat ions are execut ed. Looping can be done w it h for , w h ile , and do- w h ile , j ust as in C+ + . Variables can be declared in for and w h ile st at em ent s, and t heir scope last s unt il t he end of t heir subst at em ent s. The keyw ords br e a k and con t inu e also exist and behave as in C. Select ion can be done wit h if and if- e lse , j ust as in C+ + , wit h t he except ion t hat a variable cannot be declared in t he if st at em ent . Select ion by m eans of t he select ion operat or ( ?:) is also available, wit h t he ext ra const raint t hat t he second and t hir d operands m ust have exact ly t he sam e t ype. The t ype of t he expression provided t o an if st at em ent or a w h ile st at em ent , or t o t erm inat e a for st at em ent , m ust be a scalar Boolean. As in C, t he right - hand operand t o logical and ( & & ) is not evaluat ed ( or at least appears not t o be evaluat ed) if t he left - hand operand evaluat es t o false, and t he right - hand operand t o logical or ( | | ) is not evaluat ed if t he left - hand operand evaluat es t o t rue. Sim ilarly, only one of t he second or t hird operands in t he select ion operat or ( :?) will be evaluat ed. A logical exclusive or ( ^ ^ ) is also pr ovided, for which bot h sides are alw ays evaluat ed. A special branch, disca r d, can prevent a fragm ent from updat ing t he fr am e buffer. When a fragm ent shader execut es t he disca r d keyword, t he fragm ent being processed is m arked t o be discarded. An im plem ent at ion m ight or m ight not cont inue execut ing t he shader, but it is guarant eed t hat t here is no effect on t he fram e buffer. A got o keyword or equivalent is not available, nor are labels. Swit ching wit h sw it ch is also not provided.

3.6.1. Functions Funct ion calls operat e m uch as in C+ + . Funct ion nam es can be overloaded by param et er t ype but not solely by ret urn t ype. Eit her a funct ion definit ion ( body) or declarat ion m ust be in scope befor e a funct ion is called. Param et er t ypes are always checked. This m eans an em pt y par am et er list ( ) in a funct ion declarat ion is not am biguous, as in C, but rat her explicit ly m eans t hat t he funct ion accept s no argum ent s. Also, param et ers m ust have exact m at ches since no aut om at ic prom ot ions are done, so select ion of overloaded funct ions is quit e st raight forward. Exit ing from a funct ion wit h r e t u r n oper at es t he sam e as in C+ + . Funct ions ret urning nonvoid t ypes m ust ret urn values whose t ype m ust exact ly m at ch t he ret urn t ype of t he funct ion. Funct ions m ay not be called recursively, eit her direct ly or indirect ly.

3.6.2. Calling Conventions The OpenGL Shading Language uses call by value- ret urn as it s calling convent ion. The call by value part is fam iliar from C: Param et ers qualified as input param et ers are copied int o t he funct ion and not passed as a reference. Because t here ar e no point ers, a funct ion need not worry about it s param et ers being aliases of som e ot her m em ory. The ret urn part of call by value- ret urn m eans param et ers qualified as out put param et ers are ret urned t o t he caller by

being copied back fr om t he called funct ion t o t he caller when t he funct ion ret urns. To specify w hich param et ers ar e copied when, prefix t hem wit h t he qualifier keywords in , ou t , or in out . For som et hing t hat is j ust copied int o t he funct ion but not ret urned, use in . The in qualifier is also im plied when no qualifiers are specified. To say a param et er is not t o be copied in but is t o be set and copied back on ret urn, use t he qualifier ou t . To say a param et er is copied bot h in and out , use t he qualifier in out . in

Copy in but don't copy back out ; st ill writ able wit hin t he funct ion

ou t

Only copy out ; readable, but undefined at ent ry t o funct ion

in out

Copy in and copy out

The con st qualifier can also be applied t o funct ion param et ers. Here, it does not m ean t he variable is a com pile- t im e const ant , but rat her t hat t he funct ion is not allowed t o writ e it . Not e t hat an ordinary, nonqualified input - only param et er can be writ t en t o; it j ust won't be copied back t o t he caller. Hence, t here is a dist inct ion bet ween a param et er qualified as con st in and one qualified only as in ( or wit h no qualifier) . Of course, ou t and in out param et ers cannot be declar ed as con st . Som e exam ples: void ComputeCoord(in vec3 normal,

// // // vec3 tangent, // inout vec3 coord)//

Parameter 'normal' is copied in, can be written to, but will not be copied back out. Same behavior as if "in" was used. Copied in and copied back out.

Or, vec3 ComputeCoord(const vec3 normal,// normal cannot be written to vec3 tangent, in vec3 coord) //the function will return the result

The following are not legal: void ComputeCoord(const out vec3 normal, //not legal; can't write normal const inout vec3 tang, //not legal; can't write tang in out vec3 coord) //not legal; use inout

St ruct ures and arrays can also be passed as argum ent s t o a funct ion. Keep in m ind, t hough, t hat t hese dat a t ypes are passed by value and t here are no references, so it is possible t o cause som e large copies t o occur at funct ion call t im e. Array param et ers m ust be declared wit h t heir size, and only arrays of m at ching t ype and size can be passed t o an array param et er. The ret urn t ype of a funct ion is not allowed t o be an array. Funct ions can eit her ret urn a value or ret urn not hing. I f a funct ion ret urns not hing, it m ust be declar ed as t ype void. I f a funct ion ret urns a value, t he t ype can be any t ype except an array. However, st ruct ures can be ret urned, and st ruct ures can cont ain arrays.

3.6.3. Built-in Functions

A large set of built - in funct ions is available. Built - in funct ions are docum ent ed in full in Chapt er 5. A shader can override t hese funct ions, providing it s own definit ion. To override a funct ion, provide a pr ot ot ype or definit ion t hat is in scope at call t im e. The com piler or linker t hen looks for a user - defined version of t he funct ion t o resolve t hat call. For exam ple, one of t he built - in sine funct ions is declared as float sin(float x);

I f you want t o experim ent wit h perform ance or accuracy t rade- offs in a sine funct ion or specialize it for a part icular dom ain, you can override t he built - in funct ion w it h your own funct ion. float sin(float x) { return } void main() { // call the sin function above, not the built-in sin function float s = sin(x); }

This is sim ilar t o t he st andard language linking t echniques of using libraries of funct ions and t o having m ore locally scoped funct ion definit ions sat isfy references before t he library is checked. I f t he definit ion is in a different shader, j ust m ake sure a prot ot ype is visible before calling t he funct ion. Ot herwise, t he built - in version is used.

3.7. Operations Table 3.1 includes t he oper at ors, in order of precedence, available in t he OpenGL Shading Language. The precedence and associat ivit y are consist ent wit h C.

Ta ble 3 .1 . Ope r a t or s, in or de r of pr e ce de n ce Ope r a t or

D e scr ipt ion

[ ]

I ndex

.

Mem ber select ion and swizzle

+ + --

Post fix incr em ent / decrem ent

+ + --

Prefix increm ent / decrem ent

- !

Unary negat ion and logical not

* /

Mult iply and divide

+ -

Add and subt ract

< > =

Relat ional

= = !=

Equalit y

&&

Logical and

^^

Logical exclusive or

||

Logical inclusive or

?:

Select ion

= + = -= * = / =

Assignm ent

,

Sequence

3.7.1. Indexing Vect or s, m at rices, and arrays can be indexed wit h t he index operat or ( [ ] ) . All indexing is zero based; t he first elem ent is at index 0. I ndexing an array operat es j ust as in C. I ndexing a vect or ret urns scalar com ponent s. This allows giving com ponent s num erical nam es of 0, 1, . . . and also enables variable select ion of vect or com ponent s, should t hat be needed. For exam ple, vec4 v = vec4(1.0, 2.0, 3.0, 4.0); float f = v[2]; // f takes the value 3.0

Here, v[2] is t he float ing- point scalar 3.0, which is t hen assigned int o f. I ndexing a m at rix ret urns colum ns of t he m at rix as vect ors. For exam ple, mat4 m = mat4(3.0); // initializes the diagonal to all 3.0 vec4 v; v = m[1]; // places the vector (0.0, 3.0, 0.0, 0.0) into v

Here, t he second colum n of m, m[1] is t reat ed as a vect or t hat is copied int o v. Behavior is undefined if an array, vect or, or m at rix is accessed wit h an index t hat is less t han zer o or great er t han or equal t o t he size of t he obj ect .

3.7.2. Swizzling The norm al st ruct ure- m em ber select or ( .) is also used t o SWI ZZLE com ponent s of a vect or t hat is, select or rearrange com ponent s by list ing t heir nam es aft er t he swizzle operat or ( .) . Exam ples: vec4 v4; v4.rgba; v4.rgb; v4.b; v4.xy; v4.xgba;

// // // // // //

is a vec4 and the same as just using v4, is a vec3, is a float, is a vec2, is illegal - the component names do not come from the same set.

The com ponent nam es can be out of order t o r earrange t he com ponent s, or t hey can be replicat ed t o duplicat e t he com ponent s: vec4 pos = vec4(1.0, 2.0, 3.0, 4.0); vec4 swiz = pos.wzyx; // swiz = (4.0, 3.0, 2.0, 1.0) vec4 dup = pos.xxyy; // dup = (1.0, 1.0, 2.0, 2.0)

At m ost , four com ponent nam es can be list ed in a swizzle; ot herwise, t hey would result in a nonexist ent t ype. The rules for swizzling are slight ly different for R- VALUES ( expressions t hat are read from ) and L- VALUES ( expressions t hat say where t o writ e t o) . R- values can have any com binat ion and repet it ion of com ponent s. L- values m ust not have any repet it ion. For exam ple: vec4 pos pos.xw = pos.wx = pos.xx =

= vec4(1.0, 2.0, 3.0, 4.0); vec2(5.0, 6.0); // pos = (5.0, 2.0, 3.0, 6.0) vec2(7.0, 8.0); // pos = (8.0, 2.0, 3.0, 7.0) vec2(3.0, 4.0); // illegal - 'x' used twice

For R- values, t his synt ax can be used on any expression w hose result ant t ype is a vect or. For exam ple, get t ing a t wo- com ponent vect or from a t ext ure lookup can be done as vec2 v = texture1D(sampler, coord).xy;

where t he built - in funct ion texture1D ret urns a ve c4 .

3.7.3. Component-wise Operation Wit h a few im port ant except ions, when an operat or is applied t o a vect or, it behaves as if it were applied independent ly t o each com ponent of t he vect or. We refer t o t his behavior as com ponent - wise for short . For exam ple, vec3 v, u; float f;

v = u + f;

is equivalent t o v.x = u.x + f; v.y = u.y + f; v.z = u.z + f;

And vec3 v, u, w; w = v + u;

is equivalent t o w.x = v.x + u.x; w.y = v.y + u.y; w.z = v.z + u.z;

I f a binary oper at ion operat es on a vect or and a scalar, t he scalar is applied t o each com ponent of t he vect or. I f t wo vect ors are operat ed on, t heir sizes m ust m at ch. Except ions are m ult iplicat ion of a vect or t im es a m at rix and a m at rix t im es a m at rix, which perform st andard linear- algebr aic m ult iplies, not com ponent - wise m ult iplies. I ncrem ent and decrem ent operat ors ( + + and - - ) and unary negat ion ( - ) behave as in C. When applied t o a vect or or m at rix, t hey increm ent or decrem ent each com ponent . They operat e on int eger and float ing- point - based t ypes. Ar it hm et ic operat ors of addit ion ( + ) , subt ract ion ( - ) , m ult iplicat ion ( * ) , and division ( / ) behave as in C, or com ponent - wise, wit h t he previously described except ion of using linear- algebraic m ult iplicat ion on vect ors and m at rices: vec4 v, mat4 m; v * u; v * m; m * v; m * m;

u; // // // //

This This This This

is is is is

a a a a

component-wise multiply linear-algebraic row-vector times matrix multiply linear-algebraic matrix times column-vector multiply linear-algebraic matrix times matrix multiply

All ot her operat ions are per form ed com ponent by com ponent . Logical not ( !) , logical and ( & & ) , logical or ( | | ) , and logical inclusive or ( ^^) operat e only on expressions t hat are t yped as scalar Booleans, and t hey result in a Boolean. These cannot operat e on vect ors. A built - in funct ion, not, com put es t he com ponent - wise logical not of a vect or of Booleans. Relat ional operat ions ( < , > , < = , and > = ) operat e only on float ing- point and int eger scalars and result in a scalar Boolean. Cert ain built - in funct ions, for inst ance, lessThanEqual, com put e a Boolean vect or result of com ponent - wise com parisons of t wo vect ors. The equalit y operat ors ( = = and != ) operat e on all t ypes except arrays. They com pare every com ponent or st ruct ure m em ber across t he operands. This result s in a scalar Boolean,

indicat ing whet her t he t wo operands were equal. For t w o operands t o be equal, t heir t ypes m ust m at ch, and each of t heir com ponent s or m em bers m ust be equal. To com pare t wo vect ors in a com ponent - wise fashion, call t he built - in funct ions equal and notEqual. Scalar Booleans are produced by t he oper at ors equal ( = = ) , not equal ( != ) , r elat ional ( < , > , < = , and > = ) , and logical not ( !) because flow- cont rol const ruct s ( if, for , et c.) require a scalar Boolean. I f built - in funct ions like equal are called t o com put e a vect or of Booleans, such a vect or can be t urned int o a scalar Boolean wit h t he built - in funct ions any or all. For exam ple, t o do som et hing if any com ponent of a vect or is less t han t he corresponding com ponent of anot her vect or, t he code would be vec4 u, v; . . . if (any(lessThan(u, v))) . . .

Assignm ent ( = ) requires exact t ype m at ch bet w een t he left - and right - hand side. Any t ype, except for arrays, can be assigned. Ot her assignm ent operat ors ( + = , - = , * = , and / = ) are sim ilar t o C but m ust m ake sem ant ic sense when expanded, as in a *= b

a = a * b

where t he expression a * b m ust be sem ant ically valid, and t he t ype of t he expression a * b m ust be t he sam e as t he t ype of a. The ot her assignm ent operat ors behave sim ilarly. The t ernary select ion operat or ( ?:) operat es on t hree expr essions: exp1 ? exp2 : exp3. This operat or evaluat es t he first expression, which m ust result in a scalar Boolean. I f t he result is t rue, t he operat or select s t o evaluat e t he second expression; ot herwise, it select s t o evaluat e t he t hird expression. Only one of t he second and t hir d expressions will appear t o be evaluat ed. The second and t hird expressions m ust be t he sam e t ype, but t hey can be of any t ype ot her t han an array. The r esult ing t ype is t he sam e as t he t ype of t he second and t hird expressions. The sequence operat or ( ,) operat es on expressions by ret urning t he t ype and value of t he right m ost expression in a com m a- separat ed list of expressions. All expressions are evaluat ed, in or der, from left t o right .

3.8. Preprocessor The pr eprocessor is m uch like t hat in C. Support for #define #undef #if #ifdef #ifndef #else #elif #endif

as w ell as t he defined oper at or are exact ly as in st andard C. This includes m acros wit h argum ent s and m acro expansion. Built - in m acr os are __LINE__ __FILE__ __VERSION__

__LINE__ subst it ut es a decim al int eger const ant t hat is one m ore t han t he num ber of preceding new- lines in t he current source st ring. __FILE__ subst it ut es a decim al int eger const ant t hat says which source st ring num ber is

current ly being processed. __VERSION__ subst it ut es a decim al int eger reflect ing t he version num ber of t he OpenGL Shading Language. The version of t he shading language described in t his docum ent has __VERSION__

defined as t he decim al int eger 110. Macro nam es cont aining t w o consecut ive underscores ( __) are reserved for fut ure use as predefined m acro nam es, as are all m acro nam es prefixed wit h " GL_" . There is also t he usual support for #error message #line #pragma

#error put s message int o t he shader's inform at ion log. The com piler t hen proceeds as if a

sem ant ic error has been encount ered. #line m ust have, aft er m acro subst it ut ion, one of t he following t w o form s:

#line line #line line source-string-number

where line and source-string-number are const ant int eger expressions. Aft er processing t his direct ive ( including it s new- line) , t he im plem ent at ion behaves as if it is com piling at line num ber line+1 and source st ring num ber source-string-number. Subsequent source st rings are num bered sequent ially unt il anot her #line direct ive overrides t hat num bering.

#pragma is im plem ent at ion dependent . Tokens following #pragma are not subj ect t o pr eprocessor

m acro expansion. I f an im plem ent at ion does not recognize t he t okens specified by t he pragm a, t he pr agm a is ignored. However, t he following pr agm as are defined as part of t he language. #pragma STDGL

The STDGL pragm a reserves pragm as for use by fut ure revisions of t he OpenGL Shading Language. No im plem ent at ion m ay use a pragm a whose first t oken is STDGL. Use t he opt im ize pragm a #pragma optimize(on) #pragma optimize(off)

t o t urn opt im izat ions on or off as an aid in developing and debugging shaders. The opt im ize pragm a can occur only out side funct ion definit ions. By default , opt im izat ion is t urned on for all shaders. The debug pragm a #pragma debug(on) #pragma debug(off)

enables com piling and annot at ing a shader wit h debug inform at ion so t hat it can be used wit h a debugger. The debug pragm a can occur only out side funct ion definit ions. By default , debug is set t o off. Shaders should declare t he version of t he language t o which t hey are writ t en by using #version number

I f t he t arget ed ver sion of t he language is t he version t hat w as approved in conj unct ion wit h OpenGL 2.0, t hen a value of 110 should be used for number. Any value less t han 110 causes an error t o be generat ed. Any value great er t han t he lat est version of t he language support ed by t he com piler also causes an error t o be generat ed. Version 110 of t he language does not require shaders t o include t his direct ive, and shaders wit hout t his direct ive are assum ed t o t arget version 110 of t he OpenGL Shading Language. This direct ive, when present , m ust occur in a shader before anyt hing else except com m ent s and whit e space. By default , com pilers m ust issue com pile- t im e synt act ic, gram m at ical, and sem ant ic errors for shaders t hat do not conform t o t he OpenGL Shading Language specificat ion. Any ext ended behavior m ust first be enabled t hrough a pr eprocessor direct ive. The behavior of t he com piler wit h respect t o ext ensions is declared wit h t he #extension direct ive: #extension extension_name : behavior #extension all : behavior

extension_name is t he nam e of an ext ension. The t oken all m eans t hat t he specified behavior

should apply t o all ext ensions support ed by t he com piler. The possible values for behavior and t heir cor responding effect s are show n in Table 3.2. A shader could check for t he exist ence of a built - in funct ion nam ed foo defined by a language ext ension nam ed GL_ARB_foo in t he following way:

Ta ble 3 .2 . Pe r m it t e d va lu e s for t h e behavior e x pr e ssion in t h e #extension dir e ct ive Va lu e of be h a vior require

Effe ct Behave as specified by t he ext ension extension_name. The com piler r eport s an error on t he #extension direct ive if t he specified ext ension is not support ed or if t he t oken all is used inst ead of

an ext ension nam e. enable

warn

Behave as specified by t he ext ension extension_name. The com piler provides a warning on t he #extension direct ive if t he specified ext ension is not support ed, and it report s an error if t he t oken all is used inst ead of an ext ension nam e. Behave as specified by t he ext ension extension_name, except cause t he com piler t o issue

warnings on any det ect able use of t he specified ext ension, unless such use is support ed by ot her enabled or required ext ensions. I f all is specified, t hen t he com piler warns on all det ect able uses of any ext ension used. disable

Behave ( including errors and w arnings) as if t he ext ension specified by extension_name is not part of t he language definit ion. I f all is specified, t hen behavior m ust revert t o t hat of t he nonext ended version of t he language t hat is being t arget ed. The com piler warns if t he specified ext ension is not support ed.

#ifdef GL_ARB_foo #extension GL_ARB_foo : enable myFoo = foo(); // use the built-in foo() #else // use some other method to compute myFoo #endif

Direct ives t hat occur lat er overr ide t hose t hat occur earlier. The all t oken set s t he behavior for all ext ensions, overriding all pr eviously issued #extension direct ives, but only for behaviors warn and disable. The init ial st at e of t he com piler is as if t he direct ive #extension all : disable

were issued, t elling t he com piler t hat all error and warning report ing m ust be done according t o t he nonext ended version of t he OpenGL Shading Language t hat is being t arget ed ( i.e., all ext ensions are ignored) . Macro expansion is not done on lines cont aining #extension and #version direct ives. The num ber sign ( # ) on a line by it self is ignored. Any direct ive not described in t his sect ion causes t he com piler t o generat e an error m essage. The shader is subsequent ly t r eat ed as illform ed.

3.9. Preprocessor Expressions Preprocessor expressions can cont ain t he operat ors list ed in Table 3.3.

Ta ble 3 .3 . Pr e pr oce ssor ope r a t or s Ope r a t or

D e scr ipt ion

+ - ~ ! de fin e d

unary

* / %

m ult iplicat ive

+ -

addit ive

>

bit - wise shift

< > =

relat ional

= = !=

equalit y

& ^ |

bit - wise

&& | |

logical

Preprocessor expressions have precedence, associat ivit y, and behavior m at ching t he st andard C preprocessor. Preprocessor expressions can be execut ed on t he processor running t he com piler and not on t he graphics processor t hat execut es t he shader. Precision is allowed t o be t his host processor's precision and hence w ill likely be different from t he precision available when expressions are execut ed in t he core language. As wit h t he core language, st ring t ypes and operat ions are not provided. None of t he hashbased operat ors ( # , # # , et c.) are provided, nor is a preprocessor siz e of oper at or.

3.10. Error Handling Com pilers accept som e ill- form ed program s because it is im possible t o det ect all ill- form ed program s. For exam ple, com plet ely accurat e det ect ion of usage of an uninit ialized variable is not possible. Such ill- form ed shaders m ay execut e different ly on different plat form s. Therefore, t he OpenGL Shading Language specificat ion st at es t hat port abilit y is ensured only for wellform ed program s. OpenGL Shading Language com pilers should det ect ill- form ed program s and issue diagnost ic m essages but are not required t o do so for all cases. Com pilers are required t o ret urn m essages regarding shaders t hat are lexically, gram m at ically, or sem ant ically incorrect . Shaders t hat generat e such error m essages cannot be executed. The OpenGL ent ry point s for obt aining any diagnost ic m essages are discussed in Sect ion 7.6.

3.11. Summary The OpenGL Shading Language is a high- level procedural language designed specifically for t he OpenGL environm ent . This language allows applicat ions t o specify t he behavior of program m able, highly parallel graphics hardware. I t cont ains const ruct s t hat allow succinct expression of graphics shading algorit hm s in a way t hat is nat ural for program m ers experienced in C and C+ + . The OpenGL Shading Language includes support for scalar, vect or, and m at rix t ypes; st ruct ures and arrays; sam pler t ypes t hat access t ext ures; dat a t ype qualifiers t hat define shader input and out put ; const ruct ors for init ializat ion and t ype conversion; and operat ors and flow - cont rol st at em ent s like t hose in C and C+ + .

3.12. Further Information The OpenGL Shading Language is defined in The OpenGL Shading Language, Version 1.10, by Kessenich, Baldwin, and Rost ( 2004) . The gr am m ar for t he OpenGL Shading Language is included in it s ent iret y in Appendix A. These t wo docum ent s can be consult ed for addit ional det ails about t he language it self. Addit ional t ut orials, slides, and whit e papers are available at t he 3Dlabs Web sit e. The funct ionalit y of t he OpenGL Shading Language is augm ent ed by t he OpenGL ext ensions t hat w ere designed t o suppor t it . Read t he specificat ions for t hese ext ensions and t he OpenGL specificat ion it self t o gain furt her clarit y on t he behavior of a syst em t hat support s t he OpenGL Shading Language. You can also consult t he OpenGL books referenced at t he conclusion of Chapt er 1 for a bet t er overall underst anding of OpenGL. The st andard reference for t he C program m ing language is The C Program m ing Language by t he designers of t he language, Brian Kernighan and Dennis Rit chie ( 1988) . Likewise, t he st andard for t he C+ + pr ogram m ing language is The C+ + Program m ing Language, writ t en by t he designer of C+ + , Bj arne St roust rup ( 2000) . Num erous ot her books on bot h languages ar e available. 1 . 3Dlabs developer Web sit e. ht t p: / / developer.3dlabs.com / 2 . Kernighan, Brian, and Dennis Rit chie, The C Program m ing Language, Second Edit ion, Prent ice Hall, Englewood Cliffs, New Jersey, 1988. 3 . Kessenich, John, Dave Baldwin, and Randi Rost , The OpenGL Shading Language, Version 1.10, 3Dlabs, April 2004. ht t p: / / w ww .opengl.org/ docum ent at ion/ spec.ht m l 4 . Segal, Mark, and Kurt Akeley, The OpenGL Graphics Syst em : A Specificat ion ( Version 2.0) , Edit or ( v1.1) : Chris Fr azier, ( v1.21.5) : Jon Leech, ( v2.0) : Jon Leech and Pat Brow n, Sept . 2004. ht t p: / / w ww .opengl.org/ docum ent at ion/ spec.ht m l 5 . St roust r up, Bj arne, The C+ + Program m ing Language ( Special 3rd Edit ion) , AddisonWesley, Reading, Massachuset t s, 2000.

Chapter 4. The OpenGL Programmable Pipeline Wit h cont ribut ions by Bart hold Licht enbelt The OpenGL Shading Language is designed specifically for use w it h OpenGL. Vert ex shader and fragm ent shader input and out put are t ied int o t he st andard OpenGL pipeline in a well- defined m anner. The basics of how t he program m able processors fit int o t he OpenGL pipeline w ere cover ed in Sect ion 2.3. This chapt er discusses t he det ails of t hat int egrat ion and t he language m echanism s used t o achieve it . Applicat ions can provide dat a t o shaders wit h user- defined at t ribut e variables and user- defined uniform variables. The OpenGL Shading Language also provides built - in variables t hat can com m unicat e bet ween t he program m able processors and t he surrounding fixed funct ionalit y in t he following ways. z

z

z

z

z

z

St andard OpenGL at t ribut es can be accessed from w it hin a vert ex shader by m eans of built - in at t ribut e variable nam es. A variet y of OpenGL st at e is accessible from eit her vert ex shader s or fr agm ent shaders by m eans of built - in uniform variables. Vert ex shaders com m unicat e t o subsequent processing in OpenGL t hrough t he use of special built - in vert ex shader out put variables and built - in varying variables. Fragm ent shaders obt ain t he result s from t he preceding processing t hrough special built in fragm ent shader input variables and built - in varying variables. Fragm ent shaders com m unicat e result s t o subsequent processing st ages of OpenGL t hrough special fragm ent shader out put var iables. Built - in const ant s are accessible from wit hin bot h t ypes of shaders and define som e of t he sam e im plem ent at ion- dependent const ant s t hat are accessible wit h OpenGL's glGet funct ion.

All t he built - in ident ifiers begin wit h t he reserved pr efix " gl_" t o set t hem apart .

4.1. The Vertex Processor The vert ex processor execut es a vert ex shader and replaces t he fixed funct ionalit y OpenGL perver t ex operat ions. Specifically, w hen t he vert ex processor is execut ing a vert ex shader, t he following fixed funct ionalit y operat ions are affect ed: z

The m odelview m at rix is not applied t o vert ex coordinat es.

z

The pr oj ect ion m at rix is not applied t o vert ex coordinat es.

z

The t ext ure m at r ices are not applied t o t ext ure coordinat es.

z

Norm als are not t ransform ed t o eye coordinat es.

z

Norm als are not rescaled or norm alized.

z

Norm alizat ion of GL_AUTO_NORMAL evaluat ed norm als is not perform ed.

z

Text ure coordinat es are not generat ed aut om at ically.

z

Per- vert ex light ing is not perform ed.

z

Color m at erial com put at ions are not perform ed.

z

Color index light ing is not perform ed.

z

Point size dist ance at t enuat ion is not perform ed.

z

All of t he preceding apply t o set t ing t he current rast er posit ion.

The following fixed funct ionalit y operat ions are applied t o vert ex values t hat are t he result of execut ing t he vert ex shader: z

Color clam ping or m asking ( for built - in varying variables t hat deal wit h color but not for user- defined varying variables)

z

Perspect ive division on clip coordinat es

z

Viewport m apping

z

Dept h range scaling

z

Clipping, including user clipping

z

Front face det erm inat ion

z

Flat - shading

z

Color, t ext ure coordinat e, fog, point size, and user- defined varying clipping

z

Final color processing

The basic operat ion of t he vert ex processor was discussed in Sect ion 2.3.1. As shown in Figur e 2.2, dat a can com e int o t he vert ex shader t hrough at t ribut e variables ( built in or user defined) , uniform variables ( built in or user defined) , or t ext ure m aps ( a vert ex processing capabilit y t hat is new wit h t he OpenGL Shading Language) . Dat a exit s t he vert ex pr ocessor t hrough built - in varying variables, user- defined varying variables, and special vert ex shader out put variables. Built - in const ant s ( described in Sect ion 4.4) are also accessible from w it hin a vert ex shader. A vert ex shader has no knowledge of t he prim it ive t ype for t he vert ex it is working on. OpenGL has a m ode t hat causes color index values t o be produced rat her t han RGBA values. However, t his m ode is not support ed in conj unct ion wit h vert ex shaders. I f t he fram e buffer is configured as a color index buffer, behavior is undefined w hen a vert ex shader is used.

4.1.1. Vertex Attributes To draw t hings wit h OpenGL, applicat ions m ust pr ovide vert ex inform at ion such as norm al, color, t ext ure coordinat es, and so on. These at t ribut es can be specified one vert ex at a t im e wit h OpenGL funct ions such as glNormal, glColor, and glTexCoord. When set wit h t hese funct ion calls, t he at t ribut es becom e part of OpenGL's current st at e. Geom et ry can also be drawn wit h vert ex arrays. Wit h t his m et hod, applicat ions arrange vert ex at t ribut es in separat e arrays cont aining posit ions, norm als, colors, t ext ure coordinat es, and so on. By calling glDrawArrays, applicat ions can send a large num ber of vert ex at t ribut es t o OpenGL in a single funct ion call. Vert ex buffer obj ect s ( i.e., server - side st orage for vert ex arrays) were added in OpenGL 1.5 t o provide even bet t er perform ance for drawing vert ex arrays. Vert ex at t ribut es com e in t wo flavors: st andard and generic. The st andard at t ribut es are t he at t ribut es as defined by OpenGL; t hese are color, secondary color, color index, norm al, vert ex posit ion, t ext ure coordinat es, edge flag, and t he fog coordinat e. The color index at t r ibut e, which set s t he current color index, and t he edge flag at t ribut e are not available t o a vert ex shader ( but t he applicat ion is allowed t o send t he edge flags t o OpenGL while using a vert ex shader) . A vert ex shader accesses t he st andard at t ribut es wit h t he following built - in nam es. A com piler error is generat ed if t hese nam es are used in a fragm ent shader. // // Vertex Attributes // attribute vec4 gl_Color; attribute vec4 gl_SecondaryColor; attribute vec3 gl_Normal; attribute vec4 gl_Vertex; attribute vec4 gl_MultiTexCoord0; attribute vec4 gl_MultiTexCoord1; attribute vec4 gl_MultiTexCoord2; // . . . up to gl_MultiTexCoordN-1 where N = gl_MaxTextureCoords attribute float gl_FogCoord;

Det ails on providing generic vert ex at t ribut es t o a ver t ex shader t hrough t he OpenGL Shading Language API are provided in Sect ion 7.7. Bot h st andard at t ribut es and generic at t r ibut es are part of t he current OpenGL st at e. That m eans t hat t hey ret ain t heir values, once set . An applicat ion is free t o set values for all generic and all st andard at t ribut es and count on OpenGL t o st ore t hem ( except for vert ex posit ion, see Sect ion 7.7) . However, t he num ber of at t ribut es a vert ex shader can use is lim it ed. Typically, t his lim it is sm aller t han t he sum of all t he st andard and generic at t r ibut es. This lim it is im plem ent at ion specific and can be queried wit h glGet wit h t he sym bolic const ant GL_MAX_VERTEX_ATTRI BS. Every OpenGL im plem ent at ion is required t o support at least 16 vert ex at t ribut es in a vert ex shader.

To signal t he end of one vert ex, t he applicat ion can set eit her t he st andard vert ex at t ribut e gl_Vertex or t he generic vert ex at t ribut e wit h index zero. The gl_Vertex at t ribut e is set wit h t he glVertex com m and or one of t he vert ex array com m ands, and t he generic at t ribut e wit h index zer o is set wit h glVertexAttrib w it h an index of zero. These t wo com m ands are equivalent , and eit her one signals t he end of a vert ex.

4.1.2. Uniform Variables Shaders can access current OpenGL st at e t hrough built - in uniform variables cont aining t he reserved prefix " gl_" . For inst ance, t he current m odelview m at rix can be accessed wit h t he built - in variable nam e gl_ModelViewMatrix. Various pr opert ies of a light source can be accessed t hrough t he array cont aining light param et ers as in gl_LightSource[2].spotDirection. Any OpenGL st at e used by t he shader is aut om at ically t racked and m ade available t o t he shader. This aut om at ic st at e- t racking m echanism enables t he applicat ion t o use exist ing OpenGL st at e com m ands for st at e m anagem ent and have t he current values of such st at e aut om at ically available for use in t he shader. OpenGL st at e is accessible t o bot h vert ex shaders and fragm ent shaders by m eans of t he built in uniform variables defined in Sect ion 4.3. Applicat ions can also define t heir own uniform var iables in a ver t ex shader and use OpenGL API calls t o set t heir values ( see Sect ion 7.8 for a com plet e descript ion) . There is an im plem ent at ion- dependent lim it on t he am ount of st orage allowed for uniform variables in a ver t ex shader . The lim it refers t o t he st orage for t he com binat ion of built - in uniform variables and user - defined uniform var iables t hat are act ually used in a vert ex shader. I t is defined in t erm s of com ponent s, where a com ponent is t he size of a floa t . Thus, a ve c2 t akes up t wo com ponent s, a ve c3 t akes t hree, and so on. This value can be queried wit h glGet w it h t he sym bolic const ant GL_MAX_VERTEX_UNI FORM_COMPONENTS.

4.1.3. Special Output Variables Earlier we learned t hat result s from t he vert ex shader ar e sent on for addit ional processing by fixed funct ionalit y wit hin OpenGL, including prim it ive assem bly and rast erizat ion. Several built in variables are defined as part of t he OpenGL Shading Language t o allow t he ver t ex shader t o pass inform at ion t o t hese subsequent processing st ages. The built - in variables discussed in t his sect ion are available only from wit hin a vert ex shader. The variable gl_Position w rit es t he vert ex posit ion in clipping coordinat es aft er it has been com put ed in a vert ex shader. Every execut ion of a w ellform ed vert ex shader m ust wr it e a value int o t his variable. Com pilers m ay generat e an error m essage if t hey det ect t hat gl_Position is not writ t en or read before being writ t en, but not all such cases are det ect able. Result s are undefined if a vert ex shader is execut ed and it does not st or e a value int o gl_Position. The built - in variable gl_PointSize writ es t he size ( diam et er) of a point prim it ive. I t is m easured in pixels. This allows a vert ex shader t o com put e a screen size t hat is relat ed t o t he dist ance t o t he point , for inst ance. Sect ion 4.5.2 provides m ore det ails on using gl_PointSize. I f user clipping is enabled, it occurs as a fixed funct ionalit y operat ion aft er t he vert ex shader has been execut ed. For user clipping t o funct ion properly in conj unct ion wit h t he use of a vert ex shader, t he vert ex shader m ust com put e a vert ex posit ion t hat is relat ive t o t he user - defined clipping planes. This value m ust t hen be st ored in t he built - in variable gl_ClipVertex. I t is up t o t he applicat ion t o ensure t hat t he clip vert ex value com put ed by t he vert ex shader and t he user clipping planes are defined in t he sam e coordinat e space. User clip planes work properly only under linear t ransform . More det ails on using gl_ClipVertex are cont ained in Sect ion 4.5.3. These variables each have global scope. They can be writ t en t o at any t im e during t he execut ion of t he vert ex shader, and t hey can be read back aft er t hey have been writ t en. Reading t hem before writ ing t hem result s in undefined behavior. I f t hey are writ t en m ore t han

once, t he last value writ t en will be t he one t hat is consum ed by t he subsequent operat ions. These variables can be referenced only from wit hin a vert ex shader and are int rinsically declared wit h t he following t ypes: vec4 gl_Position; // must be written to float gl_PointSize; // may be written to vec4 gl_ClipVertex; // may be written to

4.1.4. Built-in Varying Variables As explained previously, varying variables describe at t ribut es t hat vary acr oss a prim it ive. The vert ex shader is responsible for writ ing values t hat need t o be int erpolat ed int o varying variables. The fragm ent shader reads t he int erpolat ed result s from var ying variables and operat es on t hem t o produce a result ing value for each fragm ent . For each user- defined varying variable act ually used by t he fragm ent shader, t here m ust be a m at ching varying variable declar ed in t he vert ex shader; ot herw ise, a link err or occurs. To properly com m unicat e wit h t he fixed funct ionalit y of OpenGL, t he OpenGL Shading Language defines a num ber of built - in varying variables. A vert ex shader can writ e cert ain varying variables t hat ar e not accessible from t he fragm ent shader, and a fragm ent shader can read cert ain varying var iables t hat w ere not accessible from t he vert ex shader. The following built - in varying variables can be writ t en in a vert ex shader. ( Those available from a fragm ent shader are described in Sect ion 4.2.1.) The vert ex shader should w rit e t o t hose t hat are required for t he desired fixed funct ionalit y fragm ent processing ( if no fragm ent shader is t o be used) , or t o t hose required by t he corresponding fragm ent shader. varying varying varying varying varying varying

vec4 vec4 vec4 vec4 vec4 float

gl_FrontColor; gl_BackColor; gl_FrontSecondaryColor; gl_BackSecondaryColor; gl_TexCoord[]; // at most will be gl_MaxTextureCoords gl_FogFragCoord;

Values writ t en t o gl_FrontColor, gl_BackColor, gl_FrontSecondaryColor, and gl_BackSecondaryColor are clam ped t o t he range [ 0,1] by fixed funct ionalit y when t hey exit t he vert ex shader. These four values and t he fixed funct ionalit y t o det erm ine whet her t he prim it ive is front facing or back facing are used t o com put e t he t w o varying variables gl_Color and gl_SecondaryColor t hat are available in t he fragm ent shader. One or m ore set s of t ext ure coordinat es can be passed from a vert ex shader wit h t he gl_TexCoord array. This m akes t he coordinat es available for fixed funct ionalit y processing if no fragm ent shader is present . Alt ernat ively, t hey can be accessed from wit hin a fragm ent shader wit h t he gl_TexCoord varying variable. I ndex values used t o reference t his arr ay m ust be const ant int egr al expressions or t his array m ust be redeclared wit h a size. The m axim um size of t he t ext ure coordinat e array is im plem ent at ion specific and can be queried wit h glGet wit h t he sym bolic const ant GL_MAX_TEXTURE_COORDS. Using array index values near 0 m ay aid t he im plem ent at ion in conserving resources consum ed by varying variables. For gl_FogFragCoord, t he value writ t en should be t he one required by t he current fog coordinat e source as set by a previous call t o glFog. I f t he fog coordinat e source is set t o GL_FRAGMENT_DEPTH, t he value writ t en int o gl_FogFragCoord should be t he dist ance from t he eye t o t he vert ex in eye coordinat es ( where t he eye posit ion is assum ed t o be ( 0, 0, 0, 1) ) . I f t he fog coordinat e source is set t o GL_FOG_COORDI NATE, t he value writ t en int o gl_FogFragCoord should be t he fog coordinat e value t hat is t o be int erpolat ed across t he prim it ive ( i.e., t he built -

in at t ribut e variable gl_FogCoord) .

4.1.5. User-Defined Varying Variables Vert ex shaders can also define varying variables t o pass arbit rary values t o t he fragm ent shader. Such values are not clam ped, but t hey are subj ect ed t o subsequent fixed funct ionalit y processing such as clipping and int erpolat ion. There is an im plem ent at ion- dependent lim it t o t he num ber of float ing- point values t hat can be int erpolat ed. This lim it can be queried wit h glGet wit h t he sym bolic const ant GL_MAX_VARYI NG_FLOATS.

4.2. The Fragment Processor The fragm ent processor execut es a fragm ent shader and replaces t he t ext uring, color sum , and fog fragm ent operat ions. Specifically, when t he fragm ent processor is execut ing a fragm ent shader, t he following fixed funct ionalit y operat ions are affect ed: z

The t ext ure environm ent s and t ext ure funct ions are not applied.

z

Text ure applicat ion is not perform ed.

z

Color sum is not applied.

z

Fog is not applied.

The behavior of t he following operat ions does not change: z

Text ure im age specificat ion

z

Alt ernat e t ext ur e im age specificat ion

z

Com pressed t ext ure im age specificat ion

z

Text ure param et ers t hat behave as specified even w hen a t ext ure is accessed from wit hin a fragm ent shader

z

Text ure st at e and proxy st at e

z

Text ure obj ect specificat ion

z

Text ure com parison m odes

The basic operat ion of t he fragm ent processor was discussed in Sect ion 2.3.2. As shown in Figur e 2.3, dat a can com e int o t he fragm ent shader t hrough varying variables ( built in or user defined) , uniform variables ( built in or user defined) , special input variables, or t ext ure m aps. Dat a exit s t he fragm ent processor t hrough special fragm ent shader out put variables. Built - in const ant s ( described in Sect ion 4.4) are also accessible from w it hin a fragm ent shader. Like vert ex shaders, t he behavior of a fragm ent shader is undefined w hen t he fram e buffer is configured as a color index buffer rat her t han as an RGBA buffer ( i.e., OpenGL is in color index m ode) .

4.2.1. Varying Variables The following built - in varying variables can be read in a fragm ent shader. The gl_Color and gl_SecondaryColor nam es are t he sam e as built - in at t ribut e variable nam es available in t he vert ex shader. However, t he nam es do not conflict because at t ribut es are visible only in vert ex shaders and t he follow ing are only visible in fragm ent shaders: varying varying varying varying

vec4 vec4 vec4 float

gl_Color; gl_SecondaryColor; gl_TexCoord[]; // at most will be gl_MaxTextureCoords gl_FogFragCoord;

The values in gl_Color and gl_SecondaryColor are derived aut om at ically from gl_FrontColor, gl_BackColor, gl_FrontSecondaryColor, and gl_BackSecondaryColor as part of fixed funct ionalit y processing t hat det erm ines whet her t he fragm ent belongs t o a front facing or a back facing prim it ive ( see Sect ion 4.5.1) . I f fixed funct ionalit y is used for vert ex processing, gl_FogFragCoord is eit her t he zcoordinat e of t he fragm ent in eye space or t he int erpolat ed value of t he fog coordinat e, depending on whet her t he fog coordinat e source is current ly set t o GL_FRAGMENT_DEPTH or GL_FOG_COORDI NATE. The gl_TexCoord[] array cont ains eit her t he values of t he int erpolat ed gl_TexCoord[] values fr om a vert ex shader or t he t ext ure coordinat es from t he fixed funct ionalit y vert ex processing. No aut om at ic division of t ext ure coordinat es by t heir q- com ponent is perform ed. When t he fragm ent shader is processing fragm ent s result ing from t he rast erizat ion of a pixel rect angle or bit m ap, result s are undefined if t he fr agm ent shader uses a varying variable t hat is not a built - in varying variable. I n t his case, t he values for t he built - in varying variables are supplied by t he current rast er posit ion and t he values cont ained in t he pixel rect angle or bit m ap because a vert ex shader is not execut ed. Fragm ent shaders also obt ain input dat a from user- defined varying variables. Bot h built - in and user- defined varying variables cont ain t he result of perspect ive- correct int erpolat ion of values t hat are defined at each vert ex.

4.2.2. Uniform Variables As described in Sect ion 4.1.2, OpenGL st at e is available t o bot h vert ex shaders and fragm ent shaders t hrough built - in uniform variables t hat begin wit h t he reserved pr efix " gl_" . The list of uniform variables t hat can be used t o access OpenGL st at e is provided in Sect ion 4.3. User- defined uniform variables can be defined and used wit hin fragm ent shaders in t he sam e m anner as t hey are used wit hin vert ex shaders. OpenGL API calls are provided t o set t heir values ( see Sect ion 7.8 for com plet e det ails) . The im plem ent at ion- dependent lim it t hat defines t he am ount of st orage available for uniform variables in a fragm ent shader can be queried wit h glGet wit h t he sym bolic const ant GL_MAX_FRAGMENT_UNI FORM_COMPONENTS. This lim it refers t o t he st or age for t he com binat ion of built - in uniform variables and user- defined uniform var iables t hat are act ually used in a fragm ent shader. I t is defined in t erm s of com ponent s, where a com ponent is t he size of a floa t .

4.2.3. Special Input Variables The variable gl_FragCoord is available as a read- only variable from w it hin fragm ent shaders, and it holds t he window relat ive coordinat es x, y, z, and 1/ w for t he fragm ent . This window posit ion value is t he result of t he fixed funct ionalit y t hat int erpolat es prim it ives aft er vert ex pr ocessing t o generat e fragm ent s. The z com ponent cont ains t he dept h value as m odified by t he polygon offset calculat ion. This built - in variable allows im plem ent at ion of window posit ion- dependent operat ions such as screen- door t ransparency ( e.g., use disca r d on any fragm ent for which gl_FragCoord.x is odd or gl_FragCoord.y is odd, but not bot h) . The fragm ent shader also has access t o t he read- only built - in variable gl_FrontFacing w hose value is t r ue if t he fragm ent belongs t o a front - facing prim it ive, and false ot herwise. This value can be used t o select bet w een t wo colors calculat ed by t he vert ex shader t o em ulat e t wo- sided light ing, or it can be used t o apply com plet ely different shading effect s t o front and back surfaces. A fragm ent derives it s facing direct ion from t he prim it ive t hat generat es t he fragm ent . All fragm ent s generat ed by prim it ives ot her t han polygons, t riangles, or quadrilat erals are considered t o be fr ont facing. For all ot her fragm ent s ( including fragm ent s result ing fr om polygons drawn wit h a polygon m ode of GL_POI NT or GL_LI NE) , t he det erm inat ion is m ade by exam inat ion of t he sign of t he area of t he prim it ive in window coordinat es. This sign can

possibly be reversed, depending on t he last call t o glFrontFace. I f t he sign is posit ive, t he fragm ent s ar e front facing; ot herwise, t hey are back facing. These special input variables have global scope and can be referenced only from wit hin a fragm ent shader. They are int rinsically declared wit h t he following t ypes: vec4 gl_FragCoord; bool gl_FrontFacing;

4.2.4. Special Output Variables The pr im ary purpose of a fragm ent shader is t o com put e values t hat will ult im at ely be writ t en int o t he fram e buffer. Unless t he keyword disca r d is encount ered, t he out put of t he fragm ent shader goes on t o be processed by t he fixed funct ion operat ions at t he back end of t he OpenGL pipeline. Fragm ent shaders send t heir result s on t o t he back end of t he OpenGL pipeline by using t he built - in variables gl_FragColor, gl_FragData, and gl_FragDepth. These built - in fragm ent shader variables have global scope, and t hey m ay be writ t en m ore t han once by a fragm ent shader. I f t hey are writ t en m ore t han once, t he last value assigned is t he one used in t he subsequent operat ions. They can also be read back aft er t hey have been writ t en. Reading t hem before writ ing t hem result s in undefined behavior. The color value t hat is t o be writ t en int o t he fram e buffer ( assum ing t hat it passes t hrough t he various back- end fragm ent processing st ages unscat hed) is com put ed by t he fragm ent shader and st ored in t he built - in variable gl_FragColor. As it exit s t he fragm ent processor, each com ponent of gl_FragColor is clam ped t o t he range [ 0,1] and convert ed t o fixed point wit h at least as m any bit s as are in t he corresponding color com ponent in t he dest inat ion fram e buffer. Most shaders com put e a value for gl_FragColor, but it is not required t hat t his value be com put ed by all fr agm ent shader s. I t is perfect ly legal for a shader t o com put e values for gl_FragDepth or gl_FragData inst ead. The shader could also use t he disca r d keyword t o m ark t he fragm ent as one t o be discarded rat her t han used t o updat e t he fram e buffer. Not e t hat if subsequent fixed funct ionalit y consum es fragm ent color and an ex ecut ion of a fragm ent shader does not w rit e a value t o gl_FragColor, t he behavior is undefined. I f dept h buffering is enabled and a shader does not writ e gl_FragDepth, t he fixed funct ion value for dept h is used as t he fragm ent 's dept h value. Ot herwise, writ ing t o gl_FragDepth est ablishes t he dept h value for t he fr agm ent being pr ocessed. As it exit s t he fragm ent processor, t his value is clam ped t o t he range [ 0,1] and convert ed t o fixed point wit h at least as m any bit s as are in t he dept h com ponent in t he dest inat ion fr am e buffer. Fragm ent shaders t hat writ e t o gl_FragDepth should t ake care t o w rit e t o it for every execut ion pat h t hrough t he shader. I f it is writ t en in one branch of a condit ional st at em ent but not t he ot her, t he dept h value will be undefined for som e execut ion pat hs. The z com ponent of gl_FragCoord cont ains t he dept h value result ing fr om t he pr eceding fixed funct ion pr ocessing. I t cont ains t he value t hat would be used for t he fragm ent 's dept h if t he shader cont ained no w rit es t o gl_FragDepth. This com ponent can be used t o achieve an invariant result if a fragm ent shader condit ionally com put es gl_FragDepth but ot herwise want s t he fixed funct ionalit y fragm ent dept h. The values w rit t en t o gl_FragColor and gl_FragDepth do not need t o be clam ped wit hin a shader. The fixed funct ionalit y pipeline following t he fr agm ent processor clam ps t hese values, if needed, t o t he range required by t he buffer int o which t he fragm ent will be writ t en. gl_FragData is an array t hat can be assigned values t hat are writ t en int o one or m ore offscr een buffers. The size of t his array is im plem ent at ion dependent and can be queried wit h glGet w it h

t he sym bolic const ant GL_MAX_DRAW_BUFFERS. The offscreen buffers t hat ar e m odified as a result of writ ing values int o gl_FragData w it hin a fragm ent shader ar e specified w it h glDrawBuffers. The value w rit t en int o gl_FragData[0] updat es t he first buffer in t he list specified in t he call t o

glDrawBuffers, t he value writ t en int o gl_FragData[1] updat es t he second buffer in t he list , and so on. I f subsequent fixed funct ion processing consum es a value for gl_FragData[i] but t his value is

never writ t en by t he fragm ent shader, t hen t he dat a consum ed by t he fixed funct ion processing is undefined. A fragm ent shader m ay assign values t o gl_FragColor or gl_FragData but not bot h. I f a shader execut es t he disca r d keyword, t he fragm ent is discarded, no updat e of t he fram e buffer cont ent s is perform ed, and t he values of gl_FragDepth, gl_FragData and gl_FragColor becom e irr elevant . The fragm ent shader out put variables have global scope, can be referenced only fr om wit hin a fragm ent shader, and are int rinsically declared wit h t he following t ypes: vec4 gl_FragColor; vec4 gl_FragData[gl_MaxDrawbuffers]; float gl_FragDepth;

4.3. Built-in Uniform Variables OpenGL was designed as a st at e m achine. I t has a variet y of st at e t hat can be set . At t he t im e graphics prim it ives are provided t o OpenGL for render ing, t he curr ent st at e set t ings affect how t he gr aphics prim it ives are t reat ed and ult im at ely how t hey are rendered int o t he fram e buffer. Som e applicat ions heavily ut ilize t his aspect of OpenGL. Large am ount s of applicat ion code m ight be dedicat ed t o m anipulat ing OpenGL st at e and providing an int erface t o allow t he end user t o change st at e t o produce different rendering effect s. The OpenGL Shading Language m akes it easy for t hese t ypes of applicat ions t o t ake advant age of program m able graphics t echnology. I t cont ains a variet y of built - in uniform variables t hat allow a shader t o access current OpenGL st at e. I n t his way, an applicat ion can cont inue t o use OpenGL as a st at e m anagem ent m achine and st ill provide shaders t hat com bine t hat st at e in ways t hat aren't possible wit h t he OpenGL fixed funct ionalit y pat h. Because t hey are defined as uniform variables, shaders are allowed t o read from t hese built - in variables but not t o writ e t o t hem . The built - in uniform variables in List ing 4.1 allow shaders t o access current OpenGL st at e. Any of t hese variables can be accessed from wit hin eit her vert ex shaders or fragm ent shaders. I f an OpenGL st at e value has not been m odified by an applicat ion, it cont ains t he default value as defined by OpenGL, and t he corresponding built - in uniform variable is also equal t o t hat value.

List in g 4 .1 . Bu ilt - in u n ifor m va r ia ble s // // Matrix state // uniform mat4 gl_ModelViewMatrix; uniform mat4 gl_ProjectionMatrix; uniform mat4 gl_ModelViewProjectionMatrix; uniform mat4 gl_TextureMatrix[gl_MaxTextureCoords]; // // Derived matrix state that provides inverse and transposed versions // of the matrices above. Poorly conditioned matrices may result // in unpredictable values in their inverse forms. // uniform mat3 gl_NormalMatrix; // transpose of the inverse of the upper // leftmost 3x3 of gl_ModelViewMatrix uniform uniform uniform uniform

mat4 mat4 mat4 mat4

gl_ModelViewMatrixInverse; gl_ProjectionMatrixInverse; gl_ModelViewProjectionMatrixInverse; gl_TextureMatrixInverse[gl_MaxTextureCoords];

uniform uniform uniform uniform

mat4 mat4 mat4 mat4

gl_ModelViewMatrixTranspose; gl_ProjectionMatrixTranspose; gl_ModelViewProjectionMatrixTranspose; gl_TextureMatrixTranspose[gl_MaxTextureCoords]

uniform uniform uniform uniform

mat4 mat4 mat4 mat4

gl_ModelViewMatrixInverseTranspose; gl_ProjectionMatrixInverseTranspose; gl_ModelViewProjectionMatrixInverseTranspose; gl_TextureMatrixInverseTranspose[gl_MaxTextureCoords]

//

// Normal scaling // uniform float gl_NormalScale; // // Depth range in window coordinates // struct gl_DepthRangeParameters { float near; // n float far; // f float diff; // f - n }; uniform gl_DepthRangeParameters gl_DepthRange; // // Clip planes // uniform vec4 gl_ClipPlane[gl_MaxClipPlanes]; // // Point Size // struct gl_PointParameters { float size; float sizeMin; float sizeMax; float fadeThresholdSize; float distanceConstantAttenuation; float distanceLinearAttenuation; float distanceQuadraticAttenuation; }; uniform gl_PointParameters gl_Point; // // Material State // struct gl_MaterialParameters { vec4 emission; // Ecm vec4 ambient; // Acm vec4 diffuse; // Dcm vec4 specular; // Scm float shininess; // Srm }; uniform gl_MaterialParameters uniform gl_MaterialParameters // // Light State // struct gl_LightSourceParameters { vec4 ambient; vec4 diffuse; vec4 specular; vec4 position; vec4 halfVector; vec3 spotDirection; float spotExponent; float spotCutoff;

gl_FrontMaterial; gl_BackMaterial;

// // // // // // // //

Acli Dcli Scli Ppli Derived: Hi Sdli Srli Crli

// // // float constantAttenuation; // float linearAttenuation; // float quadraticAttenuation; // float spotCosCutoff;

(range: [0.0,90.0], 180.0) Derived: cos(Crli) (range: [1.0,0.0],-1.0) K0 K1 K2

}; uniform gl_LightSourceParameters

gl_LightSource[gl_MaxLights];

struct gl_LightModelParameters { vec4 ambient; // Acs }; uniform gl_LightModelParameters gl_LightModel; // // Derived state from products of light and material. // struct gl_LightModelProducts { vec4 sceneColor; // Derived. Ecm + Acm * Acs }; uniform gl_LightModelProducts gl_FrontLightModelProduct; uniform gl_LightModelProducts gl_BackLightModelProduct; struct gl_LightProducts { vec4 ambient; // Acm * Acli vec4 diffuse; // Dcm * Dcli vec4 specular; // Scm * Scli }; uniform gl_LightProducts gl_FrontLightProduct[gl_MaxLights]; uniform gl_LightProducts gl_BackLightProduct[gl_MaxLights]; // // Texture Environment and Generation // uniform vec4 gl_TextureEnvColor[gl_MaxTextureUnits]; uniform vec4 gl_EyePlaneS[gl_MaxTextureCoords]; uniform vec4 gl_EyePlaneT[gl_MaxTextureCoords]; uniform vec4 gl_EyePlaneR[gl_MaxTextureCoords]; uniform vec4 gl_EyePlaneQ[gl_MaxTextureCoords]; uniform vec4 gl_ObjectPlaneS[gl_MaxTextureCoords]; uniform vec4 gl_ObjectPlaneT[gl_MaxTextureCoords]; uniform vec4 gl_ObjectPlaneR[gl_MaxTextureCoords]; uniform vec4 gl_ObjectPlaneQ[gl_MaxTextureCoords]; // // Fog // struct gl_FogParameters { vec4 color; float density; float start; float end; float scale; // 1.0 / (gl_Fog.end - gl_Fog.start) };

uniform gl_FogParameters gl_Fog;

As you can see, t hese built - in uniform var iables have been defined so as t o t ake advant age of t he language feat ures w henever possible. St ruct ures are used as cont ainers t o gr oup a collect ion of param et ers such as dept h range param et ers, m at erial param et ers, light source param et ers, and fog param et ers. Arrays define clip planes and light sources. Defining t hese uniform variables in t his way im proves code readabilit y and allows shader s t o t ake advant age of language capabilit ies like looping. The list of built - in uniform variables also includes som e derived st at e. These st at e values are t hings t hat aren't passed in direct ly by t he applicat ion but are derived by t he OpenGL im plem ent at ion fr om values t hat are passed. For various reasons, it 's convenient t o have t he OpenGL im plem ent at ion com put e t hese derived values and allow shaders t o access t hem . The norm al m at rix ( gl_NormalMatrix) is an exam ple of t his. I t is sim ply t he inverse t ranspose of t he upper- left 3 x 3 subset of t he m odelview m at rix. Because it is used so oft en, it wouldn't m ake sense t o require shaders t o com put e t his from t he m odelview m at rix whenever it is needed. I nst ead, t he OpenGL im plem ent at ion is responsible for com put ing t his whenever it is needed, and it is accessible t o shaders t hrough a built - in uniform var iable. Here are som e exam ples of how t hese built - in uniform variables m ight be used. A ver t ex shader can t ransform t he incom ing vert ex posit ion ( gl_Vertex) by OpenGL's curr ent m odelview - proj ect ion m at r ix ( gl_ModelViewProjectionMatrix) wit h t he following line of code: gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

Sim ilarly, if a norm al is needed, it is t ransform ed by t he current norm al m at rix: tnorm = gl_NormalMatrix * gl_Normal;

( The t ransform ed norm al would t ypically also need t o be norm alized in order t o be used in light ing com put at ions. This norm alizat ion can be done wit h t he built - in funct ion normalize, which is discussed in Sect ion 5.4.) Here are som e ot her exam ples of accessing built - in OpenGL st at e: gl_FrontMaterial.emission gl_LightSource[0].ambient gl_ClipPlane[3][0] gl_Fog.color.rgb gl_TextureMatrix[1][2][3]

// // // // // //

emission value for front material ambient term of light source #0 first component of user clip plane #3 r, g, and b components of fog color 3rd column, 4th component of 2nd texture matrix

The m apping of OpenGL st at e values t o t hese built - in variables should be st raight forward, but if you need m ore det ails, see t he OpenGL Shading Language Specificat ion docum ent .

4.4. Built-in Constants The OpenGL Shading Language defines a num ber of built - in const ant s. These values can be accessed from wit hin eit her vert ex shaders or fragm ent shaders. Values for light s, clip planes, and t ext ure unit s ar e values t hat are equivalent t o t hose t hat would be ret urned by OpenGL's glGet funct ion for t he underlying im plem ent at ion. I m plem ent at ion- dependent values t hat are new w it h t he OpenGL Shading Language are t he num ber of float ingpoint values t hat could be st ored as uniform values accessible by t he vert ex shader and by t he fragm ent shader, t he num ber of float ing- point values t hat could be defined as varying variables, t he num ber of t ext ure im age unit s t hat are accessible by t he vert ex pr ocessor and by t he fragm ent pr ocessor, t he t ot al num ber of t ext ure im age unit s available t o t he vert ex processor and t he fragm ent processor com bined, t he num ber of t ext ure coordinat es set s t hat are support ed, and t he num ber of draw buffers t hat are accessible. All t hese new im plem ent at ion- dependent const ant s can also be obt ained in applicat ion code w it h t he OpenGL glGet funct ion ( see Sect ion 7.12) . OpenGL defines m inim um values for each im plem ent at ion- dependent const ant . The m inim um value inform s applicat ion writ ers of t he lowest value t hat is perm issible for a conform ing OpenGL im plem ent at ion. The m inim um value for each of t he built - in const ant s is shown here. // // Implementation dependent constants. The values below // are the minimum values allowed for these constants. // const int gl_MaxLights = 8; const int gl_MaxClipPlanes = 6; const int gl_MaxTextureUnits = 2; const int gl_MaxTextureCoords = 2; const int gl_MaxVertexAttribs = 16; const int gl_MaxVertexUniformComponents = 512; const int gl_MaxVaryingFloats = 32; const int gl_MaxVertexTextureImageUnits = 0; const int gl_MaxTextureImageUnits = 2; const int gl_MaxFragmentUniformComponents = 64; const int gl_MaxCombinedTextureImageUnits = 2; const int gl_MaxDrawBuffers = 1;

These values can occasionally be useful wit hin a shader. For inst ance, a shader m ight include a general- purpose light ing funct ion t hat loops t hrough t he available OpenGL light s and adds cont ribut ions from each enabled light source. The loop can easily be set up wit h t he built - in const ant gl_MaxLight s. More likely, however, is t hat an applicat ion will use OpenGL's glGet funct ion t o obt ain t hese im plem ent at ion- dependent const ant s and decide, based on t hose values, whet her t o even load a shader ( see Sect ion 7.12) .

4.5. Interaction with OpenGL Fixed Functionality This sect ion offers a lit t le m ore det ail t o program m ers who are int im at ely fam iliar wit h OpenGL operat ions and need t o know precisely how t he program m able capabilit ies int r oduced by t he OpenGL Shading Language int eract w it h t he rest of t he OpenGL pipeline. This sect ion is m ore suit able for seasoned OpenGL progr am m ers t han for OpenGL novices.

4.5.1. Two-Sided Color Mode Vert ex shaders can operat e in t wo- sided color m ode. Front and back colors can be com put ed by t he vert ex shader and writ t en t o t he gl_FrontColor, gl_BackColor, gl_FrontSecondaryColor, and gl_BackSecondaryColor out put variables. I f t w o- sided color m ode is enabled aft er vert ex processing, OpenGL fixed funct ionalit y chooses w hich of t he front or back colors t o forward t o t he rest of t he pipeline. Which side OpenGL picks depends on t he prim it ive t ype being rendered and t he sign of t he area of t he prim it ive in window coordinat es ( see t he OpenGL specificat ion for det ails) . I f t wo- sided color m ode is disabled, OpenGL always select s t he fr ont color out put s. Tw o- sided color m ode is enabled and disabled wit h glEnable or glDisable wit h t he sym bolic value GL_VERTEX_PROGRAM_TWO_SI DE. The colors result ing from t his front / back facing select ion st ep are clam ped t o t he range [ 0,1] and convert ed t o a fixed- point represent at ion before being int erpolat ed across t he prim it ive t hat is being rendered. This is norm al OpenGL behavior. When higher precision and dynam ic range colors are required, t he applicat ion should use it s own user- defined varying variables inst ead of t he four built - in gl_Color ones. The front / back facing select ion st ep is t hen skipped. How ever, a built - in variable available in t he fragm ent shader ( gl_FrontFacing) indicat es whet her t he current fragm ent is t he result of rast erizing a front or back facing prim it ive.

4.5.2. Point Size Mode Vert ex shaders can also operat e in point size m ode. A vert ex shader can com put e a point size in pixels and assign it t o t he built - in variable gl_PointSize. I f point size m ode is enabled, t he point size is t aken from t his variable and used in t he rast erizat ion st age; ot herwise, it is t aken from t he value set wit h t he glPointSize com m and. I f gl_PointSize is not writ t en while vert ex shader point size m ode is enabled, t he point size used in t he rast erizat ion st age is undefined. Ver t ex shader point size m ode is enabled and disabled wit h glEnable or glDisable wit h t he sym bolic value GL_VERTEX_PROGRAM_POI NT_SI ZE. This point size enable is convenient for t he m aj orit y of applicat ions t hat do not change t he point size wit hin a vert ex shader. By default , t his m ode is disabled, so m ost vert ex shaders for which point size doesn't m at t er need not w rit e a value t o gl_PointSize. The value set by calls t o glPointSize is always used by t he rast erizat ion st age. I f t he prim it ive is clipped and vert ex shader point size m ode is enabled, t he point size values are also clipped in a m anner analogous t o color clipping. The pot ent ially clipped point size is used by t he fixed funct ionalit y part of t he pipeline as t he derived point size ( t he dist ance at t enuat ed point size) . Thus, if t he applicat ion want s point s fart her away t o be sm aller, it should com put e som e kind of dist ance at t enuat ion in t he vert ex shader and scale t he point size accordingly. I f vert ex shader point size m ode is disabled, t he derived point size is t aken direct ly from t he value set wit h t he glPointSize com m and and no dist ance at t enuat ion is perform ed. The derived point size is t hen used, as usual, opt ionally t o alpha- fade t he point when m ult isam pling is also enabled. Again, see t he OpenGL specificat ion for det ails. Dist ance at t enuat ion should be com put ed in a vert ex shader and cannot be left t o t he fixed funct ionalit y dist ance at t enuat ion algorit hm . This fixed funct ionalit y algorit hm com put es dist ance at t enuat ion as a funct ion of t he dist ance bet ween t he eye at ( 0, 0, 0, 1) and t he vert ex

posit ion, in eye coordinat es. How ever, t he vert ex posit ion com put ed in a vert ex shader m ight not have anyt hing t o do wit h locat ions in eye coordinat es. Therefore, when a vert ex shader is act ive, t his fixed funct ionalit y algorit hm is skipped. A point 's alpha- fade, on t he ot her hand, can be com put ed correct ly only wit h t he knowledge of t he prim it ive t ype. That inform at ion is not available t o a vert ex shader, because it execut es before pr im it ive assem bly. Consider t he case of rendering a t riangle and having t he back polygon m ode set t o GL_POI NT and t he fr ont polygon m ode t o GL_FI LL. The vert ex shader should fade only t he alpha if t he vert ex belongs t o a back facing t riangle. But it cannot do t hat because it does not know t he prim it ive t ype.

4.5.3. Clipping User clipping can be used in conj unct ion w it h a vert ex shader. The user clip planes are specified as usual wit h t he glClipPlane com m and. When specified, t hese clip planes are t ransform ed by t he inverse of t he curr ent m odelview m at rix. The vert ices result ing from t he execut ion of a vert ex shader are evaluat ed against t hese t r ansform ed clip planes. The vert ex shader m ust provide t he posit ion of t he vert ex in t he sam e space as t he user- defined clip planes ( t ypically, eye space) . I t does t hat by writ ing t his locat ion t o t he out put variable gl_ClipVertex. I f gl_ClipVertex is not specified and user clipping is enabled, t he result s are undefined. When a vert ex shader t hat m im ics OpenGL's fixed funct ionalit y is used, t he vert ex shader should com put e t he eye- coordinat e posit ion of t he vert ex and st ore it in gl_ClipVertex. For exam ple, gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;

When you want t o do obj ect space clipping inst ead, keep in m ind t hat t he clip planes are t ransform ed wit h t he inverse of t he m odelview m at rix. For correct obj ect clipping, t he m odelview m at rix needs t o be set t o t he ident it y m at rix when t he clip planes are specified. Aft er user clipping, vert ices are clipped against t he view volum e, as usual. I n t his oper at ion, t he value specified by gl_Position ( i.e., t he hom ogeneous vert ex posit ion in clip space) is evaluat ed against t he view volum e.

4.5.4. Raster Position I f a vert ex shader is act ive when glRasterPos is called, it processes t he coordinat es provided wit h t he glRasterPos com m and j ust as if t hese coordinat es were specified wit h a glVertex com m and. The vert ex shader is responsible for out put t ing t he values necessary t o com put e t he current rast er posit ion dat a. The OpenGL st at e for t he current rast er posit ion consist s of t he following seven it em s: 1 . Window coordinat es com put ed from t he value writ t en t o gl_Position. These coordinat es are t reat ed as if t hey belong t o a point and passed t o t he clipping st age and t hen proj ect ed t o window coor dinat es. 2 . A valid bit indicat ing if t his point was culled. 3 . The rast er dist ance, which is set t o t he vert ex shader varying variable gl_FogFragCoord. 4 . The rast er color, which is set t o eit her t he vert ex shader varying variable gl_FrontColor or gl_BackColor, depending on t he front / back facing select ion process. 5 . The rast er secondary color, which is set t o eit her t he vert ex shader varying variable gl_FrontSecondaryColor or gl_BackSecondaryColor, depending on t he front / back facing select ion process.

6 . One or m ore rast er t ext ure coordinat es. These are set t o t he vert ex shader var ying variable array gl_TexCoord[]. 7 . The rast er color index. Because t he result of a vert ex shader is undefined in color index m ode, t he rast er color index is always set t o 1. I f any of t he out put s necessary t o com put e t he first six it em s are not provided, t he value( s) for t he associat ed it em is undefined.

4.5.5. Position Invariance For m ult ipass rendering, in which a vert ex shader perform s som e passes and ot her passes use t he fixed funct ionalit y pipeline, posit ional invariance is im port ant . This m eans t hat bot h t he ver t ex shader and fixed funct ionalit y com put e t he exact sam e vert ex posit ion in clip coordinat es, given t he sam e vert ex posit ion in obj ect coordinat es and t he sam e m odelview and proj ect ion m at rices. Posit ional invariance can be achieved wit h t he built - in funct ion ftransform in a vert ex shader as follows: gl_Position = ftransform();

I n general, t he vert ex shader code gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex

does not result in posit ional invariance, because of possible com piler opt im izat ions and pot ent ial underlying har dw are differences.

4.5.6. Texturing One of t he m aj or im provem ent s t o OpenGL m ade by t he OpenGL Shading Language is in t he area of t ext uring. For one t hing, t ext uring operat ions can be perform ed in a vert ex shader. But t he fragm ent side of t he pipeline has im proved as w ell. A fragm ent shader can pot ent ially have access t o m ore t ext ure im age unit s t han t he fixed funct ionalit y pipeline does. This m eans t hat m ore t ext ure lookups can be perform ed in a single rendering pass. And wit h program m abilit y, t he result s of all t hose t ext ure lookups can be com bined in any way t he shader w rit er sees fit . The changes t o t he pipeline have result ed in som e clarificat ion t o t he language used t o describe t ext uring capabilit ies in OpenGL. The t erm " t ext ure unit " in OpenGL form erly specified m ore t han one t hing. I t specified t he num ber of t ext ure coordinat es t hat could be at t ached t o a ver t ex ( now called t ext ur e coordinat e set s) as well as t he num ber of hardware unit s t hat could be used sim ult aneously for accessing t ext ure m aps ( now called t ext ure im age unit s) . A t ext ure coordinat e set encom passes vert ex t ext ure coordinat e at t ribut es, as well as t he t ext ure m at rix st ack and t ext ure generat ion st at e. The sym bolic const ant GL_MAX_TEXTURE_UNI TS can be queried wit h glGet t o obt ain a single num ber t hat indicat es t he quant it y of bot h of t hese it em s. For t he im plem ent at ions t hat support t he OpenGL Shading Language, t hese t w o t hings m ight act ually have different values, so t he num ber of available t ext ure coordinat e set s is now decoupled from t he m axim um num ber of t ext ure im age unit s. Typically, t he num ber of available t ext ure coordinat e set s is less t han t he available t ext ure im age unit s. This should not prove t o be a lim it at ion because new t ext ure coordinat es can easily be derived from t he t ext ure coordinat e at t ribut es passed in or t he coordinat es can be ret rieved from a t ext ure m ap. Five different lim it s relat ed t o t ext ure m apping should be t aken int o account . 1 . For a vert ex shader, t he m axim um num ber of available t ext ure im age unit s is given by

GL_MAX_VERTEX_TEXTURE_I MAGE_UNI TS. 2 . For a fr agm ent shader, t he m axim um num ber of available t ext ure im age unit s is given by GL_MAX_TEXTURE_I MAGE_UNI TS. 3 . The com bined num ber of t ext ure im age unit s used in t he ver t ex and t he fragm ent processing part s of OpenGL ( eit her a fragm ent shader or fixed funct ion) cannot exceed t he lim it GL_MAX_COMBI NED_TEXTURE_I MAGE_UNI TS. I f a vert ex shader and t he fragm ent processing part of OpenGL bot h use t he sam e t ext ure im age unit , t hat count s as t w o unit s against t his lim it . This rule exist s because an OpenGL im plem ent at ion m ight have only GL_MAX_COMBI NED_TEXTURE_I MAGE_UNI TS act ual t ext ure im age unit s im plem ent ed, and it m ight share t hose unit s bet w een t he vert ex and fragm ent processing par t s of OpenGL. 4 . When a fr agm ent shader is not act ive, OpenGL can st ill perform m ult i- t ext uring. I n t his case, t he m axim um available m ult it ext ure st ages ar e given by t he st at e variable GL_MAX_TEXTURE_UNI TS. 5 . The num ber of support ed t ext ure coordinat e set s is given by GL_MAX_TEXTURE_COORDS. This lim it applies regardless of w het her a vert ex shader or fixed- funct ion OpenGL perform s vert ex processing. The fixed funct ion hierarchy of t ext ure- enables ( GL_TEXTURE_CUBE_MAP, GL_TEXTURE_3D, GL_TEXTURE_2D, and GL_TEXTURE_1D) is ignored by shaders. For exam ple, even if t he t ext ure t arget GL_TEXTURE_1D is enabled for a t ext ure im age unit , a sam pler can be used t o access t he GL_TEXTURE_2D t arget for t hat t ext ure im age unit . Sam plers of t ype sa m ple r 1 D Sh a dow or sa m ple r 2 D Sh a dow m ust be used t o access dept h t ext ures ( t ext ures wit h a base int ernal form at of GL_DEPTH_COMPONENT) . The t ext ure com parison m ode requires t he shader t o use one of t he variant s of t he shadow1D or shadow2D built - in funct ions for accessing t he t ext ure ( see Sect ion 5.7) . I f t hese built - in funct ions ar e used t o access a t ext ure wit h a base int ernal form at ot her t han GL_DEPTH_COMPONENT, t he result is undefined. Sim ilarly, if a t ext ure access funct ion ot her t han one of t he shadow variant s is used t o access a dept h t ext ure, t he result is undefined. I f a shader uses a sam pler t o reference a t ext ure obj ect t hat is not com plet e ( e.g., one of t he t ext ures in a m ipm ap has a different int ernal for m at or border widt h t han t he ot hers, see t he OpenGL specificat ion for a com plet e list ) , t he t ext ure im age unit ret urns ( R, G, B, A) = ( 0, 0, 0, 1) .

4.6. Summary Tw o new program m able unit s have been added t o OpenGL: t he vert ex processor and t he fragm ent processor. The sam e language, w it h m inor differences, expresses algorit hm s int ended t o run on eit her processor. The vert ex processor replaces t he fixed funct ionalit y vert ex processing of OpenGL, and a shader int ended for execut ion on t his processor is called a vert ex shader. When inst alled as part of current st at e, t he vert ex shader is execut ed once for each vert ex t hat is processed by OpenGL. The fragm ent processor replaces t he fixed funct ionalit y fragm ent processing of OpenGL, and a shader t hat is int ended for execut ion on t his processor is called a fragm ent shader. When inst alled as part of current st at e, t he fragm ent shader is execut ed once for each fr agm ent t hat arises from rast erizat ion. Great care was t aken t o define t he int erfaces bet ween t he program m able st ages of OpenGL and t he int ervening fixed funct ionalit y. As a result , rendering is perm it t ed wit h program m able vert ex processing and fixed funct ionalit y fragm ent processing, or vice versa. Built - in variables allow access t o st andard OpenGL at t ribut es, im plem ent at ion- dependent const ant s, and a variet y of current st at e. They also allow a shader t o com m unicat e wit h t he preceding and following fixed funct ionalit y st ages of t he graphicsprocessing pipeline.

4.7. Further Information The built - in variables defined in t his chapt er are used in various exam ples t hroughout t his book. The OpenGL Shading Language specificat ion and t he OpenGL specificat ion can be consult ed for addit ional det ails. The OpenGL books referenced at t he conclusion of Chapt er 1 can also be consult ed for a bet t er underst anding of t he OpenGL st at e t hat is referenced t hrough built - in variables. Part s of t he paper I nt egrat ing t he OpenGL Shading Language by Bart hold Licht enbelt have been adapt ed for inclusion in t his book. 1 . Kessenich, John, Dave Baldwin, and Randi Rost , The OpenGL Shading Language, Version 1.10, 3Dlabs, April 2004. ht t p: / / w ww .opengl.org/ docum ent at ion/ spec.ht m l 2 . Licht enbelt , Bart hold, I nt egrat ing t he OpenGL Shading Language, 3Dlabs int ernal whit e paper, July 2003. 3 . Segal, Mark, and Kurt Akeley, The OpenGL Graphics Syst em : A Specificat ion ( Version 2.0) , Edit or ( v1.1) : Chris Fr azier, ( v1.21.5) : Jon Leech, ( v2.0) : Jon Leech and Pat Brow n, Sept . 2004. ht t p: / / w ww .opengl.org/ docum ent at ion/ spec.ht m l

Chapter 5. Built-in Functions This chapt er provides t he det ails of t he funct ions t hat are defined as part of t he OpenGL Shading Language. Feel free t o skip ahead t o t he next chapt er if you want t o get down t o t he nit t y- grit t y of w rit ing your ow n shaders. This chapt er can be useful as a refer ence aft er you are well on your way t o writ ing OpenGL shaders for your own applicat ion. The OpenGL Shading Language defines an assort m ent of built - in convenience funct ions for scalar and vect or operat ions. The reasons for providing built - in funct ions for t he OpenGL Language include z z

z

z

Making shaders sim pler t o develop and easier t o underst and and m aint ain. Exposing som e necessary hardware funct ionalit y in a convenient way such as accessing a t ext ure m ap. The language for t hese funct ions cannot be em ulat ed by a shader. Represent ing a t rivial operat ion ( clam p, m ix, et c.) t hat is sim ple for a user t o writ e but t hat is com m on and m ay have direct har dware support . Providing a built - in funct ion m akes it m uch easier for t he com piler t o m ap such expressions t o com plex hardware inst ruct ions. Represent ing an operat ion t hat graphics hardware is likely t o accelerat e at som e point . The t rigonom et ry funct ions fall int o t his cat egory.

Many of t he funct ions are sim ilar t o t he sam e nam ed ones in com m on C libraries, but t hey support vect or input as well as t he m ore t radit ional scalar input . Because t he OpenGL Shading Language support s funct ion overloading, t he built - in funct ions usually have several variant s, all wit h t he sam e nam e. The difference in t he funct ions is in t he t ype of argum ent s and t he t ype of t he value ret urned. Quit e a few of t he built - in funct ions have four variant s: one t hat t akes floa t param et ers and ret urns a floa t , one t hat t akes ve c2 param et ers and ret urns a ve c2 , one t hat t akes ve c3 param et ers and ret urns a ve c3 , and one t hat t akes ve c4 param et ers and ret urns a ve c4 . Whenever possible, you should use t he built - in funct ions rat her t han do t he equivalent com put at ions in your ow n shader code. I t is expect ed t hat t he built - in funct ions will be im plem ent ed in an opt im al way, perhaps even support ed direct ly in hardware. Alm ost all t he built - in funct ions can be used in eit her a vert ex shader or a fragm ent shader, but a few are available only for a specific t ype of shader. You can w rit e a shader t o replace a built - in funct ion wit h your own code sim ply by redeclaring and defining t he sam e funct ion nam e and argum ent list . Graphical represent at ions of som e of t he funct ions are shown for clear illust rat ion. The funct ions are generally sim ple ones, and m ost readers would have no t rouble const ruct ing such diagram s t hem selves. But as we see in lat er chapt ers, m any of t he built - in funct ions can be used in unconvent ional ways t o achieve int er est ing effect s in shader s. When you are developing a shader, it is oft en helpful t o draw a sim ple funct ion diagram t o clearly envision t he value of a variable at a part icular spot in a shader. By seeing a pict orial represent at ion of som e of t hese funct ions, you m ay find it easier t o draw such diagram s yourself and t o gain som e insight about how you m ight use t hem in procedural shaders. Som e com m on uses for t hese funct ions are point ed out along t he way, and som e are illust rat ed by shader exam ples in t he lat er chapt ers of t his book.

5.1. Angle and Trigonometry Functions Trigonom et ry funct ions can be used w it hin eit her vert ex shaders or fragm ent shaders. Funct ion param et ers specified as angle are assum ed t o be in unit s of radians. I n no case do any of t hese funct ions result in a divide- by - zero error. I f t he divisor of a rat io is 0, result s are undefined. These funct ions all operat e com ponent - wise ( see Table 5.1) . The descript ion colum n specifies t he operat ion on each com ponent .

Ta ble 5 .1 . An gle a n d t r igon om e t r y fu n ct ion s Syn t a x

D e scr ipt ion

float vec2 vec3 vec4

radians ( float degrees) radians ( vec2 degrees) radians ( vec3 degrees) radians ( vec4 degrees)

Conver t s degrees t o radians and ret urns t he result , i.e., result = π/ 180 · degrees.

float vec2 vec3 vec4

degrees ( float radians) degrees ( vec2 radians) degrees ( vec3 radians) degrees ( vec4 radians)

Conver t s radians t o degrees and ret urns t he result , i.e., result = 180/ π · radians.

float vec2 vec3 vec4

sin ( float radians) sin ( vec2 radians) sin ( vec3 radians) sin ( vec4 radians)

The st andard t rigonom et ric sine funct ion. The values ret urned by t his funct ion range from [ - 1,1] .

float vec2 vec3 vec4

cos ( float radians) cos ( vec2 radians) cos ( vec3 radians) cos ( vec4 radians)

The st andard t rigonom et ric cosine funct ion. The values ret urned by t his funct ion range from [ - 1,1] .

float vec2 vec3 vec4

tan ( float radians) tan ( vec2 radians) tan ( vec3 radians) tan ( vec4 radians)

The st andard t rigonom et ric t angent funct ion.

float vec2 vec3 vec4

asin ( float x) asin ( vec2 x) asin ( vec3 x) asin ( vec4 x)

Ar c sine. Ret urns an angle whose sine is x. The range of values ret urned by t his funct ion is [ - π/ 2, π/ 2] . Result s are undefined if | x| > 1.

float vec2 vec3 vec4

acos ( float x) acos ( vec2 x) acos ( vec3 x) acos ( vec4 x)

Ar c cosine. Ret urns an angle whose cosine is x. The range of values ret urned by t his funct ion is [ 0, π] . Result s are undefined if | x| > 1.

float vec2 vec3 vec4

atan ( float y, float x) atan ( vec2 y, vec2 x) atan ( vec3 y, vec3 x) atan ( vec4 y, vec4 x)

Ar c t angent . Ret urns an angle whose t angent is y/x. The signs of x and y det erm ine w hat quadrant t he angle is in. The range of values ret urned by t his funct ion is [ - π, π] . Result s are undefined if x and y are bot h 0.

float atan ( float y_over_x) vec2 atan ( vec2 y_over_x) vec3 atan ( vec3 y_over_x)

Ar c t angent . Ret urns an angle whose t angent is y_over_x. The range of values ret urned by t his funct ion is [ - π/ 2, π/ 2] .

vec4 atan ( vec4 y_over_x)

I n addit ion t o t heir usefulness as t rigonom et ric funct ions, sin and cos can be used in a variet y of ways as t he basis for a sm oot hly varying funct ion wit h no cusps or discont inuit ies ( see Figur e 5.1) . Such a funct ion can be used t o m odel waves on t he sur face of an obj ect , t o change periodically bet ween t wo m at erials, t o int roduce a rocking m ot ion t o an obj ect , or t o achieve m any ot her effect s.

Figu r e 5 .1 . Th e sin a n d cos fu n ct ions

5.2. Exponential Functions Exponent ial funct ions can be used wit hin eit her vert ex shaders or fragm ent shaders. These all operat e com ponent - wise ( see Table 5.2) . The descript ion colum n specifies t he operat ion on each com ponent .

Ta ble 5 .2 . Ex pon e n t ia l fu n ct ions Syn t a x

D e scr ipt ion Ret urns x raised t o t he y power, i.e., xy. Result s are undefined if x < 0. Result s are undefined if x = 0 and y = 0.

float vec2 vec3 vec4

pow ( float x, float y) pow ( vec2 x, vec2 y) pow ( vec3 x, vec3 y) pow ( vec4 x, vec4 y)

float vec2 vec3 vec4

exp ( float x) exp ( vec2 x) exp ( vec3 x) exp ( vec4 x)

float vec2 vec3 vec4

log ( float x) log ( vec2 x) log ( vec3 x) log ( vec4 x)

Ret urns t he nat ural logarit hm of x, i.e., ret urns t he value y, which sat isfies t he equat ion x = ey. Result s are undefined if x maxVal.

vec2 clamp ( vec2 x, vec2 minVal, vec2 maxVal) vec3 clamp ( vec3 x, vec3 minVal, vec3 maxVal) vec4 clamp ( vec4 x, vec4 minVal, vec4 maxVal)

Ret urns t he com ponent - wise result of min ( max ( x, minVal) , maxVal) . Result s are undefined if minVal > maxVal.

float a) vec2 a) vec3 a) vec4 a)

mix ( float x, float y, float

vec2 vec2 vec3 vec3 vec4 vec4

mix ( vec2 x, vec2 y, a) mix ( vec3 x, vec3 y, a) mix ( vec4 x, vec4 y, a)

Ret urns t he com ponent - wise result of x * ( 1.0 a) + y * a, i.e., t he linear blend of vect ors x and y using t he vect or a. The value for a is not rest rict ed t o t he

float vec2 vec3 vec4

step ( float edge, float x) step ( vec2 edge, vec2 x) step ( vec3 edge, vec3 x) step ( vec4 edge, vec4 x)

Ret urns 0 if x < edge; ot herwise, it ret urns 1.0.

float float vec2 vec2 vec3 vec3 vec4 vec4

smoothstep ( float edge0, edge1, float x) smoothstep ( vec2 edge0, edge1, vec2 x) smoothstep ( vec3 edge0, edge1, vec3 x) smoothstep ( vec4 edge0, edge1, vec4 x)

Ret urns 0 if x < = edge0 and 1.0 if x > = edge1 and perform s sm oot h Herm it e int erpolat ion bet w een 0 and 1 w hen edge0 < x < edge1. Result s are undefined if edge0 > = edge1.

Ret urns x * ( 1.0 a) + y * a, i.e., t he linear blend of x and y using t he float ing- point value a. The value for mix ( vec2 x, vec2 y, float a is not rest rict ed t o t he range [ 0,1] . mix ( vec3 x, vec3 y, float mix ( vec4 x, vec4 y, float

range [ 0,1] .

Aside fr om t heir gener al usefulness as m at h funct ions, m any of t hese funct ions are useful in creat ing int erest ing shaders, as we see in subsequent chapt ers. The abs funct ion can ensure t hat a part icular funct ion never produces negat ive values. I t can also int roduce a discont inuit y in an ot herw ise sm oot h funct ion. As we see in Sect ion 15.5, t his proper t y of t he abs funct ion is used t o int roduce discont inuit ies in a noise funct ion t o produce an effect t hat looks like t urbulence. A graphical represent at ion of t he abs funct ion is shown in Figur e 5.2.

Figu r e 5 .2 . Th e abs fu n ct ion

The sign funct ion sim ply m aps t he incom ing value t o - 1, 0, or 1, depending on it s sign. This result s in a discont inuous funct ion, as shown in Figur e 5.3.

Figu r e 5 .3 . Th e sign fu n ct ion

The floor funct ion produces a discont inuous st air- st ep pat t ern, as shown in Figur e 5.4. The fract ional part of each incom ing value is dropped, so t he out put value is always t he int eger value t hat is closest t o but less t han or equal t o t he input value.

Figu r e 5 .4 . Th e floor fu n ct ion

The ceil funct ion is alm ost t he sam e as t he floor funct ion, except t hat value ret urned is always t he int eger value t hat is closest t o but great er t han or equal t o t he input value. This funct ion is shown in Figur e 5.5. As you can see, t his funct ion looks t he sam e as Figur e 5.4 except t hat t he out put values are shift ed up by one. ( Alt hough ceil and floor always produce int eger values, t he funct ions are defined t o ret urn float ing- point dat a t ypes.)

Figu r e 5 .5 . Th e ceil fu n ct ion

The fract funct ion produces a discont inuous funct ion where each segm ent has a slope of 1.0 ( see Figur e 5.6) .

Figu r e 5 .6 . Th e fract fu n ct ion

The mod funct ion is very sim ilar t o fract. I n fact , if we divide t he result of mod( x, y) by y, t he result is very nearly t he sam e. The only difference is t he period of t he discont inuous segm ent s ( see Figur e 5.7) .

Figu r e 5 .7 . The pe r iodic fu n ct ion mod( x, y)

The clamp funct ion is useful for m aking sure t hat a value is wit hin a part icular range. A com m on operat ion is clamp(x, 0.0, 1.0);

which clam ps t he variable x t o t he range [ 0,1] . Because t wo com parisons are necessary for t his funct ion, you should use it only w hen t here is a chance t hat t he t est ed value could be out side eit her end of t he specified range. For t he min and max funct ions, only one com parison is necessary. I f you know a value will not be less t han 0, using min(x, 1.0);

will likely be fast er and m ay use fewer m achine inst ruct ions t han clamp(x, 0.0, 1.0);

because t her e is no point in t est ing t o see whet her t he final value is less t han 0. Keep in m ind t hat t here is no need t o clam p t he final color and dept h values com put ed by a fr agm ent shader

because t hey are clam ped aut om at ically by t he back - end fixed funct ionalit y processing. The min, max, and clamp funct ions are shown in Figur e 5.8, Figur e 5.9, and Figure 5.10. The min ( x, y) funct ion has a slope of 1 w here x is less t han y, and a slope of 0 where x is great er t han y. This funct ion is oft en used t o put an upper bound on a value, for inst ance, t o m ake sure t he com put ed r esult never exceeds 1.0.

Figu r e 5 .8 . Th e min fu n ct ion

Figu r e 5 .9 . Th e max fu n ct ion

Figu r e 5 .1 0 . Th e clamp fu n ct ion

The max( x, y) funct ion has a slope of 0 w here x is less t han y, and a slope of 1 where x is great er t han y. This funct ion is oft en used t o put a lower bound on a value, for inst ance, t o m ake sure t he com put ed result never goes below 0. The clamp( x, minVal, maxVal) funct ion has a slope of 0 w here x is less t han minVal and w here x is great er t han maxVal, and it has a slope of 1 in bet ween where x is great er t han minVal and less t han maxVal. I t is funct ionally equivalent t o t he expression min( max( x, minVal) , maxVal) . The step funct ion creat es a discont inuous j um p at an ar bit rary point ( see Figure 5.11) . We use t his funct ion t o creat e a sim ple procedural brick shader in Chapt er 6.

Figu r e 5 .1 1 . Th e step fu n ct ion

The smoothstep funct ion ( see Figure 5.12) is useful in cases in which you want a t hreshold funct ion wit h a sm oot h t ransit ion. For t he case in which t is a floa t , t his is equivalent t o float t; t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0); return t * t * (3.0 - 2.0 * t);

Figu r e 5 .1 2 . Th e smoothstep fu n ct ion

The cases for ve c2 , ve c3 , and ve c4 differ from t he pr eceding exam ple only in t he dat a t ype used t o declare t.

5.4. Geometric Functions Except for ftransform, geom et ric funct ions can be used wit hin eit her vert ex shaders or fragm ent shaders. These funct ions operat e on vect ors as vect ors, not in a com ponent - wise fashion ( see Table 5.4) .

Ta ble 5 .4 . Ge om e t r ic fu n ct ion s Syn t a x

D e scr ipt ion ( float ( vec2 ( vec3 ( vec4

float float float float

length length length length

float float float float

distance distance distance distance

float float float float

dot dot dot dot

( float ( vec2 ( vec3 ( vec4

( float ( vec2 ( vec3 ( vec4

x, x, x, x,

Ret urns t he lengt h of vect or x, i.e., sqrt( x[ 0] * x[ 0] + x[ 1] * x[ 1] + . . .) .

x) x) x) x) p0, p0, p0, p0,

float p1) vec2 p1) vec3 p1) vec4 p1)

float y) vec2 y) vec3 y) vec4 y)

vec3 cross ( vec3 x, vec3 y)

float vec2 vec3 vec4

normalize ( float x) normalize ( vec2 x) normalize ( vec3 x) normalize ( vec4 x)

Ret urns t he dist ance bet w een p0 and p1, i.e., length( p0 - p1) .

Ret urns t he dot product of x and y, i.e., result = x[ 0] * y[ 0] + x[ 1] * y[ 1] + . . ..

Ret urns t he cross result [ 0] = x[ 1] * result [ 1] = x[ 2] * result [ 2] = x[ 0] *

product of y[ 2] - y[ 1] y[ 0] - y[ 2] y[ 1] - y[ 0]

x and y, i.e., * x[ 2] * x[ 0] * x[ 1]

Ret urns a vect or in t he sam e direct ion as x but wit h a lengt h of 1.

vec4 ftransform( )

For vert ex shaders only. This funct ion ensures t hat t he incom ing vert ex posit ion is t ransform ed in a w ay t hat produces exact ly t he sam e result as would be pr oduced by OpenGL's fixed funct ionalit y t ransform . This funct ion t ypically com put es t he value for gl_Position.

float faceforward ( float N, float I, float

I f dot ( Nref, I) < 0.0, ret urn N; ot her wise, ret urn N.

Nref)

vec2 faceforward ( vec2 N, vec2 I, vec2 Nref) vec3 faceforward ( vec3 N, vec3 I, vec3 Nref) vec4 faceforward ( vec4 N, vec4 I, vec4 Nref) float vec2 vec3 vec4

reflect ( float I, float N) reflect ( vec2 I, vec2 N) reflect ( vec3 I, vec3 N) reflect ( vec4 I, vec4 N)

float refract ( float I, float N, float eta) vec2 refract ( vec2 I, vec2 N, float eta)

For t he incident vect or I and sur face orient at ion N, ret urns t he reflect ion direct ion: result = I 2.0 * dot ( N, I) * N N m ust already be norm alized t o achieve t he desired result . I need not be norm alized. For t he incident vect or I and sur face norm al N and t he rat io of indices of refract ion eta, ret urns t he

vec3 refract ( vec3 I, vec3 N, float eta) vec4 refract ( vec4 I, vec4 N, float eta)

refract ion vect or. The r et urned result is com put ed as k = 1.0 - eta * eta * (1.0 - dot (N, I) * dot (N, I)) if (k < 0.0) result = 0.0; // result type is float or vec2/3/4 else result = eta * I(eta * dot (N, I) * sqrt (k)) * N

The input parameters for the incident vector I and surface normal N must already be normalized to achieve the desired result.

The floa t version of t he distance funct ion m ay not seem t erribly useful ( it 's t he sam e as t he absolut e value of t he difference) , but t he vect or form s com put e t he Euclidean dist ance bet ween t w o point s. Sim ilarly, t he floa t version of normalize always ret urns 1, and t he floa t version of length always ret urns t he absolut e value of t he input argum ent as t he result . These scalar form s are useful in t hat t he dat a t ype of t he argum ent can be changed w it hout t he need t o change t he code t hat calls t he built - in funct ion. You can use t he ftransform funct ion t o t ransform t he incom ing vert ex posit ion: gl_Position = ftransform()

I t t ransform s t he value of gl_Vertex by t he current m odelview- proj ect ion m at rix t o produce a value for gl_Position t hat is ident ical t o what would have been com put ed by t he fixed funct ionalit y pipeline. This funct ion should be used, for exam ple, when an applicat ion is rendering t he sam e geom et ry in separat e passes, where one pass uses t he fixed funct ionalit y pat h t o render and anot her pass uses t he program m able processors.

5.5. Matrix Functions Mat rix funct ions can be used wit hin eit her vert ex shaders or fragm ent shaders ( see Table 5.5) .

Ta ble 5 .5 . M a t r ix fu n ct ion s Syn t a x

D e scr ipt ion

m at 2 matrixCompMult ( m at 2 x, m at 2 y) m at 3 matrixCompMult ( m at 3 x, m at 3 y) m at 4 matrixCompMult ( m at 4 x, m at 4 y)

Mult iply m at rix x by m at rix y com ponent - wise, i.e., result[ i] [ j ] is t he scalar product of x[ i] [ j ] and y[ i] [ j] . Not e: To get linear- algebraic m at rix m ult iplicat ion, use t he m ult iply operat or ( * ) .

These funct ions produce t he com ponent - wise m ult iplicat ion of t w o m at rices. For inst ance, t he result of calling matrixCompMult wit h t wo 3D m at rices x and y looks like t his: mat3 x, y, newmat; . . . newmat = matrixCompMult(x, y);

This is not usually what you want if you are using m at rices t o represent t ransform at ion st eps. I n t his case, you would use t he m ult iply operat or ( * ) t o perform t he linear- algebr aic m at rix m ult iplicat ion mat3 x, y, newmat; . . . newmat = x * y;

which perform s t he following operat ion:

5.6. Vector Relational Functions Relat ional and equalit y operat ors ( < , < = , > , > = , = = , != ) are defined t o produce scalar Boolean result s and can be used wit hin eit her vert ex shaders or fragm ent shader s. For vect or result s, use t he built - in funct ions in Table 5.6.

Ta ble 5 .6 . Ve ct or r e la t iona l fu n ct ions Syn t a x

D e scr ipt ion

bvec2 bvec3 bvec4 bvec2 bvec3 bvec4

lessThan( vec2 x, vec2 y) lessThan( vec3 x, vec3 y) lessThan( vec4 x, vec4 y) lessThan( ivec2 x, ivec2 y) lessThan( ivec3 x, ivec3 y) lessThan( ivec4 x, ivec4 y)

Ret urns t he com ponent - wise com pare of x < y.

bvec2 bvec3 bvec4 bvec2 bvec3 bvec4

lessThanEqual( vec2 x, vec2 y) lessThanEqual( vec3 x, vec3 y) lessThanEqual( vec4 x, vec4 y) lessThanEqual( ivec2 x, ivec2 y) lessThanEqual( ivec3 x, ivec3 y) lessThanEqual( ivec4 x, ivec4 y)

Ret urns t he com ponent - wise com pare of x < = y.

bvec2 bvec3 bvec4 bvec2 bvec3 bvec4

greaterThan( vec2 x, vec2 y) greaterThan( vec3 x, vec3 y) greaterThan( vec4 x, vec4 y) greaterThan( ivec2 x, ivec2 y) greaterThan( ivec3 x, ivec3 y) greaterThan( ivec4 x, ivec4 y)

Ret urns t he com ponent - wise com pare of x > y.

bvec2 bvec3 bvec4 bvec2 bvec3 bvec4

greaterThanEqual( vec2 x, vec2 y) greaterThanEqual( vec3 x, vec3 y) greaterThanEqual( vec4 x, vec4 y) greaterThanEqual( ivec2 x, ivec2 y) greaterThanEqual( ivec3 x, ivec3 y) greaterThanEqual( ivec4 x, ivec4 y)

Ret urns t he com ponent - wise com pare of x > = y.

bvec2 bvec3 bvec4 bvec2 bvec3 bvec4 bvec2 bvec3 bvec4

equal( vec2 x, vec2 y) equal( vec3 x, vec3 y) equal( vec4 x, vec4 y) equal( ivec2 x, ivec2 y) equal( ivec3 x, ivec3 y) equal( ivec4 x, ivec4 y) equal( bvec2 x, bvec2 y) equal( bvec3 x, bvec3 y) equal( bvec4 x, bvec4 y)

Ret urns t he com ponent - wise com pare of x = = y.

bvec2 bvec3 bvec4 bvec2 bvec3 bvec4 bvec2 bvec3 bvec4

notEqual( vec2 x, vec2 y) notEqual( vec3 x, vec3 y) notEqual( vec4 x, vec4 y) notEqual( ivec2 x, ivec2 y) notEqual( ivec3 x, ivec3 y) notEqual( ivec4 x, ivec4 y) notEqual( bvec2 x, bvec2 y) notEqual( bvec3 x, bvec3 y) notEqual( bvec4 x, bvec4 y)

Ret urns t he com ponent - wise com pare of x ! = y.

bool any( bvec2 x)

Ret urns t rue if any com ponent of x is

bool any( bvec3 x) bool any( bvec4 x)

true.

bool all( bvec2 x) bool all( bvec3 x) bool all( bvec4 x)

Ret urns t rue only if all com ponent s of x are t r u e .

bvec2 not( bvec2 x bvec3 not( bvec3 x) bvec4 not( bvec4 x)

Ret urns t he com ponent - wise logical com plem ent of x.

5.7. Texture Access Functions Text ure access funct ions are available t o bot h vert ex and fragm ent shaders. Each of t hese funct ions t akes as it s first argum ent a variable of t ype sa m ple r . I f a variable qualified by sa m ple r 1 D is used, t hen t he t ext ure access operat ion reads from t he 1D t ext ure t hat has previously been associat ed wit h t hat sam pler by t he applicat ion. ( I t is an error for t he applicat ion t o associat e a non- 1D t ext ure w it h a sa m ple r 1 D variable.) Sim ilarly, a sa m ple r 2 D variable is used t o access a 2D t ext ure, and so on. The t ext ure precedence rules for OpenGL fixed funct ionalit y are ignored. I t is up t o t he applicat ion t o set up t ext ure st at e before t he shader execut es in order t o get t he expect ed r esult s ( see Sect ion 7.9) . The t ext ur e access funct ions obt ain t ext ure values from eit her m ipm apped or non- m ipm apped t ext ures. How ever, level- of- det ail is not com put ed by fixed funct ionalit y for vert ex shaders, so t here are som e differences in operat ion bet ween vert ex and fragm ent t ext ure access funct ions. Text ure propert ies such as size, pixel form at , num ber of dim ensions, filt ering m et hod, num ber of m ipm ap levels, dept h com parison, and so on are also defined by OpenGL API calls. Such propert ies are t aken int o account as t he t ext ure is accessed t hrough t he built - in funct ions defined in t his sect ion. I n all funct ions t hat follow, t he bias param et er is opt ional for fr agm ent shaders. The bias par am et er is not accept ed in a vert ex shader. For a fr agm ent shader , if bias is present , it is added t o t he calculat ed level of det ail before t he t ext ure access operat ion is perform ed. I f t he bias param et er is not provided, t he im plem ent at ion aut om at ically select s level- of- det ail. For a t ext ure t hat is not m ipm apped, t he t ext ure is used direct ly. I f a m ipm ap t ext ure is accessed from a fr agm ent shader , t he level- of- det ail com put ed by t he im plem ent at ion is used during t he t ext ure lookup. I f a m ipm apped t ext ure is accessed from a vert ex shader, t he base t ext ur e is used. The built - in funct ions suffixed wit h " Lod" are allowed only in a vert ex shader. For t he " Lod" funct ions, lod is direct ly used as t he level- of- det ail. The built - in funct ions suffixed wit h " Proj" can perform proj ect ive t ext uring. This allows a t ext ure t o be proj ect ed ont o an obj ect in m uch t he sam e way t hat a slide proj ect or proj ect s an im age ont o a surface. Funct ions suffixed wit h " Proj" can com put e shadow m aps for rendering shadows, am ong ot her t hings. A num ber of exam ples in lat er sect ions illust r at e t he use of t hese funct ions. Wit h t he program m abilit y available wit h t he OpenGL Shading Language, t ext ure m em ory can st ore m uch m ore t han j ust im age dat a. These t ext ure access funct ions pr ovide fast , flexible access t o such dat a in order t o achieve a w ide variet y of effect s ( see Table 5.7) .

Ta ble 5 .7 . Te x t u r e a cce ss fu n ct ion s Syn t a x

D e scr ipt ion

vec4 texture1D ( sam pler1D sampler, float coord [, float bias] ) vec4 texture1DProj ( sam pler1D sampler, vec2 coord [, float bias] ) vec4 texture1DProj ( sam pler1D sampler, vec4 coord [, float bias] ) vec4 texture1DLod ( sam pler1D sampler, float coord, float lod) vec4 texture1DProjLod ( sam pler1D sampler, vec2 coord, float lod) vec4 texture1DProjLod ( sam pler1D sampler, vec4 coord, float lod)

Use t he t ext ure coor dinat e coord t o access t he 1D t ext ure current ly specified by sampler. For t he proj ect ive ( " Proj" ) versions, t he t ext ure coordinat e coord.s is divided by t he last com ponent of coord. The second and t hird com ponent s of coord are ignored for t he ve c4 coord variant .

vec4 texture2D ( sam pler2D sampler, vec2 coord [ , float bias] ) vec4 texture2DProj ( sam pler2D sampler, vec3 coord [ , float bias] ) vec4 texture2DProj ( sam pler2D sampler, vec4 coord [ , float bias] ) vec4 texture2DLod ( sam pler2D sampler, vec2 coord, float lod) vec4 texture2DProjLod ( sam pler2D sampler, vec3 coord, float lod) vec4 texture2DProjLod ( sam pler2D sampler, vec4 coord, float lod)

Use t he t ext ure coor dinat e coord t o access t he 2D t ext ure current ly specified by sampler. For t he proj ect ive ( " Proj" ) versions, t he t ext ure coordinat e ( coord.s, coord.t) is divided by t he last com ponent of coord. The t hird com ponent of coord is ignored for t he ve c4 coord variant .

vec4 texture3D ( sam pler3D sampler, vec3 coord [ , float bias] ) vec4 texture3DProj ( sam pler3D sampler, vec4 coord [ , float bias] ) vec4 texture3DLod ( sam pler3D sampler, vec3 coord, float lod) vec4 texture3DProjLod ( sam pler3D sampler, vec4 coord, float lod)

Use t he t ext ure coor dinat e coord t o access t he 3D t ext ure current ly specified by sampler. For t he proj ect ive ( " Proj" ) versions, t he t ext ure coordinat e is divided by coord.q.

vec4 textureCube ( sam plerCube sampler, vec3 coord [ , float bias] ) vec4 textureCubeLod ( sam plerCube sampler, vec3 coord, float lod)

Use t he t ext ure coor dinat e coord t o access t he cube m ap t ext ure current ly specified by sampler. The direct ion of coord select s t he face in which t o do a t wo- dim ensional t ext ure lookup.

vec4 shadow1D ( sam pler1DShadow sampler, vec3 coord [ , float bias] ) vec4 shadow2D ( sam pler2DShadow sampler, vec3 coord [ , float bias] ) vec4 shadow1DProj ( sam pler1DShadow sampler, vec4 coord [ , float bias] ) vec4 shadow2DProj ( sam pler2DShadow sampler, vec4 coord [ , float bias] ) vec4 shadow1DLod ( sam pler1DShadow sampler, vec3 coord, float lod) vec4 shadow2DLod ( sam pler2DShadow sampler, vec3 coord, float lod) vec4 shadow1DProjLod ( sam pler1DShadow sampler, vec4 coord, float lod) vec4 shadow2DProjLod ( sam pler2DShadow sampler, vec4 coord, float lod)

Use t ext ure coordinat e coord t o do a dept h com par ison lookup on t he dept h t ext ure specified by sampler. The t hird com ponent of coord ( coord.p) is com pared t o t he value read from t he dept h t ext ure. The t ext ure bound t o sampler m ust be a dept h t ext ure or result s are undefined. For t he pr oj ect ive ( " Proj" ) version of each built - in, t he t ext ure coordinat e is divided by coord.q, giving a dept h value of coord.p/coord.q. The second com ponent of coord is ignored for t he " 1D" var iant s.

Text uring result s are undefined if z

z

z

A t ext ure funct ion ot her t han one of t he shadow variant s is called wit h a sam pler whose t ext ure is a dept h t ext ure wit h dept h com parisons enabled, A shadow t ext ure call is m ade t o a sam pler whose t ext ure is a dept h t ext ure wit h dept h com parisons disabled, or A shadow t ext ure call is m ade t o a sam pler whose t ext ure is not a dept h t ext ure.

5.8. Fragment Processing Functions Fragm ent pr ocessing funct ions are only available in shaders int ended for use on t he fragm ent processor. This cat egory has t hree built - in funct ions. Two obt ain derivat ives and t he ot her est im at es t he filt er widt h used t o ant ialias pr ocedural t ext ures. The derivat ive funct ions, dFdx and dFdy, det erm ine t he rat e of change of an expression. The funct ion dFdx( p) evaluat es t he derivat ive of t he expression p in t he x direct ion in window coordinat es, and t he funct ion dFdy( p) evaluat es t he derivat ive of t he expression p in t he y direct ion in window coordinat es. These values indicat e how fast t he expression is changing in window space, and t his inform at ion can be used t o t ake st eps t o prevent aliasing. For inst ance, if t ext ure coordinat es are changing rapidly, it m ay be bet t er t o set t he result ing color t o t he average color for t he t ext ure in order t o avoid aliasing. I t only m akes sense t o apply t hese funct ions t o expressions t hat vary from one fragm ent t o t he next . Because t he value of a uniform variable does not change from one pixel t o t he next , it s derivat ive in x and in y is alw ays 0. See Table 5.8.

Ta ble 5 .8 . Fr a gm e n t Pr oce ssin g Fu n ct ions Syn t a x

D e scr ipt ion

float vec2 vec3 vec4

dFdx ( float p) dFdx ( vec2 p) dFdx ( vec3 p) dFdx ( vec4 p)

Ret urns t he derivat ive in x for t he input argum ent p.

float vec2 vec3 vec4

dFdy ( float p) dFdy ( vec2 p) dFdy ( vec3 p) dFdy ( vec4 p)

Ret urns t he derivat ive in y for t he input argum ent p.

float vec2 vec3 vec4

fwidth ( float p) fwidth ( vec2 p) fwidth ( vec3 p) fwidth ( vec4 p)

Ret urns t he sum of t he absolut e derivat ive in x and y for t he input argum ent p, i.e., ret urn = abs ( dFdx ( p) ) + abs ( dFdy ( p) ) ;

5.9. Noise Functions Noise funct ions ( see Table 5.9) are available t o bot h fragm ent and vert ex shaders. These st ochast ic funct ions, first described by Ken Perlin, incr ease visual com plexit y. Values ret urned by t he following noise funct ions give t he appearance of random ness, but t hey are not t r uly random . A m ore com plet e descript ion of and m ot ivat ion for t he noise funct ion can be found in Chapt er 15.

Ta ble 5 .9 . N oise Fu n ct ion s Syn t a x

D e scr ipt ion

float float float float

noise1 noise1 noise1 noise1

( float ( vec2 ( vec3 ( vec4

x) x) x) x)

Ret urns a 1D noise value based on t he input value x.

vec2 vec2 vec2 vec2

noise2 noise2 noise2 noise2

( float ( vec2 ( vec3 ( vec4

x) x) x) x)

Ret urns a 2D noise value based on t he input value x.

vec3 vec3 vec3 vec3

noise3 noise3 noise3 noise3

( float ( vec2 ( vec3 ( vec4

x) x) x) x)

Ret urns a 3D noise value based on t he input value x.

vec4 vec4 vec4 vec4

noise4 noise4 noise4 noise4

( float ( vec2 ( vec3 ( vec4

x) x) x) x)

Ret urns a 4D noise value based on t he input value x.

The built - in noise funct ions are defined t o have t he following charact erist ics: z

z z

z

z

z z

z

The ret urn values are alw ays in t he range [ 1,1] and cover at least t he range [ 0.6,0.6] wit h a Gaussian- like dist ribut ion. The ret urn values have an overall average of 0. The funct ions are repeat able, in t hat a part icular input value always produces t he sam e ret urn value. They are st at ist ically invariant under rot at ion; t hat is, no m at t er how t he dom ain is rot at ed, it has t he sam e st at ist ical charact er. They have a st at ist ical invariance under t ranslat ion; t hat is, no m at t er how t he dom ain is t ranslat ed, it has t he sam e st at ist ical charact er. They t ypically give different result s under t ranslat ion. The spat ial frequency is narrowly concent rat ed, cent ered som ewhere bet ween 0.5 and 1.0. They are C1 cont inuous everywhere; t hat is t he first derivat ive is cont inuous.

5.10. Summary The OpenGL Shading Language cont ains a rich set of built - in funct ions. Som e of t hese funct ions are sim ilar t o t hose found in C and C+ + , and ot hers are sim ilar t o t hose found in RenderMan. These funct ions expose hardware funct ionalit y ( e.g., t ext ure access) or support com m on operat ions ( e.g., square root , clam p) , or t hey represent operat ions likely t o be accelerat ed in fut ure generat ions of graphics hardware ( t rigonom et ry funct ions, noise, et c.) . Funct ion overloading is used ext ensively because m any of t hese funct ions operat e on eit her vect ors or scalars. Vendors t hat support t he OpenGL Shading Language are expect ed t o provide opt im al im plem ent at ions of t hese funct ions, so t he built - in funct ions should be used w henever possible. The built - in m at hem at ical funct ions can be used in som e unique and perhaps unexpect ed ways t o creat e procedural t ext ures. Shader exam ples t hroughout t he rest of t his book illust rat e t his. Visualizing t he funct ion needed t o achieve a part icular effect can be a vit al part of t he shader developm ent process.

5.11. Further Information Many of t he built - in funct ions described in t his chapt er are used in exam ple shaders in t he rem ainder of t his book. All you need t o do is keep reading t o see t hem in act ion. Som e addit ional det ail on t he built - in funct ions can be found in t he The OpenGL Shading Language, Version 1.10, by John Kessenich, Dave Baldwin, and Randi Rost ( 2004) . Various OpenGL Shading Language built - in funct ions, including t he derivat ive and filt er widt h funct ions, were inspired by sim ilar funct ions in RenderMan. Mot ivat ion for som e of t hese funct ions is discussed in The Render Man Com panion: A Program m er's Guide t o Realist ic Com put er Graphics by St eve Upst ill ( 1990) and Advanced RenderMan: Creat ing CGI for Mot ion Pict ures by Tony Apodaca and Larry Grit z ( 1999) . For addit ional det ails on noise funct ions, see t he papers by Perlin and t he references provided at t he end of Chapt er 15. 1 . Apodaca, Ant hony A., and Larry Grit z, Advanced RenderMan: Creat ing CGI for Mot ion Pict ures, Morgan Kaufm ann Publishers, San Francisco, 1999. ht t p: / / w ww .r ender m an.org/ RMR/ Books/ arm an/ m at erials.ht m l 2 . Kessenich, John, Dave Baldwin, and Randi Rost , The OpenGL Shading Language, Version 1.10, 3Dlabs, April 2004. ht t p: / / w ww .opengl.org/ docum ent at ion/ spec.ht m l 3 . Perlin, Ken, An I m age Synt hesizer , Com put er Graphics ( SI GGRAPH '85 Proceedings) , pp. 287296, July 1985. 4 . Perlin, Ken, I m proving Noise, Com put er Graphics ( SI GGRAPH 2002 Proceedings) , pp. 681682, July 2002. ht t p: / / m rl.nyu.edu/ perlin/ paper445.pdf 5 . Pixar, The Render Man I nt erface Specificat ion, Version 3.2, Pixar, July 2000. ht t ps: / / renderm an.pixar.com / product s/ rispec/ index.ht m 6 . Segal, Mark, and Kurt Akeley, The OpenGL Graphics Syst em : A Specificat ion ( Version 2.0) , Edit or ( v1.1) : Chris Fr azier, ( v1.21.5) : Jon Leech, ( v2.0) : Jon Leech and Pat Brow n, Sept . 2004. ht t p: / / w ww .opengl.org/ docum ent at ion/ spec.ht m l 7 . Upst ill, St eve, The Render Man Com panion: A Program m er's Guide t o Realist ic Com put er Graphics, Addison- Wesley, Reading, Massachuset t s, 1990. 8 . Zwillinger, Dan, CRC St andard Mat hem at ical Tables and Form ulas, 30t h Edit ion, CRC Press, 1995. ht t p: / / www.geom .uiuc.edu/ docs/ reference/ CRC- form ulas/

Chapter 6. Simple Shading Example Now t hat we've described t he OpenGL Shading Language, let 's look at a sim ple exam ple. I n t his exam ple, we apply a brick pat t ern t o an obj ect . The brick pat t ern is calculat ed ent irely wit hin a fragm ent shader. I f you'd prefer t o skip ahead t o t he next chapt er for a m ore in- dept h discussion of t he API t hat allows shaders t o be defined and m anipulat ed, feel free t o do so. The shader for render ing a procedural brick pat t ern was t he first int erest ing shader ever execut ed by t he OpenGL Shading Language on program m able graphics hardware. I t ran for t he first t im e in March 2002, on t he 3Dlabs Wildcat VP graphics accelerat or. Dave Baldwin published t he first GLSL brick fragm ent shader in a w hit e paper t hat described t he language dest ined t o becom e t he OpenGL Shading Language. His GLSL shader was based on a RenderMan shader by Darwyn Peachey t hat was published in t he book, Text uring and Modeling: A Procedur al Approach. St eve Koren and John Kessenich adapt ed Dave's shader t o get it working on real hardw are for t he first t im e, and it has subsequent ly undergone considerable refinem ent for inclusion in t his book. This exam ple, like m ost of t he ot hers in t his book, consist s of t hree essent ial com ponent s: t he source code for t he vert ex shader, t he source code for t he fragm ent shader, and t he applicat ion code t hat init ializes and uses t hese shader s. This chapt er focuses on t he vert ex and fragm ent shaders. The applicat ion code for using t hese shaders is discussed in Sect ion 7.13, aft er t he det ails of t he OpenGL Shading Language API have been discussed. Wit h t his first exam ple, we t ake a lit t le m ore t im e discussing t he det ails in order t o give you a bet t er grasp of what 's going on. I n exam ples lat er in t he book, we focus m ost ly on t he det ails t hat differ from pr evious exam ples.

6.1. Brick Shader Overview One approach t o writ ing shaders is t o com e up w it h a descript ion of t he effect t hat you're t rying t o achieve and t hen decide which part s of t he shader need t o be im plem ent ed in t he vert ex shader, which need t o be im plem ent ed in t he fragm ent shader, and how t he applicat ion will t ie everyt hing t oget her. I n t his exam ple, we develop a shader t hat applies a com put ed brick pat t ern t o all obj ect s t hat are drawn. We don't at t em pt t he m ost realist ic looking brick shader, but rat her a fairly sim ple one t hat illust rat es m any of t he concept s we int roduced in t he previous chapt ers. We don't use t ext ures for t his brick pat t ern; t he pat t ern it self is generat ed algorit hm ically. We can build a lot of flexibilit y int o t his shader by param et erizing t he different aspect s of our brick algorit hm . Let 's first com e up wit h a descript ion of t he overall effect w e're aft er . We w ant z

A single light source

z

Diffuse and specular reflect ion charact erist ics

z

z z

A brick pat t ern based on t he posit ion in m odeling coordinat es of t he obj ect being renderedwhere t he x coordinat e is relat ed t o t he brick horizont al posit ion and t he y coordinat e is relat ed t o t he brick vert ical posit ion Alt ernat e rows of bricks offset by one- half t he widt h of a single brick Easy- t o- m odify colors and rat ios: brick color, m ort ar color, brick- t o- brick horizont al dist ance, brick - t o- brick vert ical dist ance, brick widt h fract ion ( rat io of t he widt h of a brick t o t he overall horizont al dist ance bet ween t wo adj acent bricks) , and brick height fract ion ( rat io of t he height of a brick t o t he overall vert ical dist ance bet ween t w o adj acent bricks)

The br ick geom et ry param et ers t hat we use t o cont rol geom et ry and color are illust rat ed in Figur e 6.1. Brick size and brick percent age param et ers are bot h st ored in user- defined uniform variables of t ype ve c2 . The horizont al dist ance bet ween t wo bricks, including t he widt h of t he m ort ar, is provided by BrickSize.x. The vert ical dist ance bet ween t wo rows of bricks, including t he height of t he m ort ar, is provided by BrickSize.y. These t wo values are given in unit s of m odeling coordinat es. The fract ion of BrickSize.x repr esent ed by t he brick only is provided by BrickPct.x. The fract ion of BrickSize.y repr esent ed by t he brick only is provided by BrickPct.y. These t wo values are in t he r ange [ 0,1] . Finally, t he brick color and t he m ort ar color are represent ed by t he variables BrickColor and MortarColor.

Figu r e 6 .1 . Pa r a m e t e r s for de fin in g br ick

Now t hat we're arm ed wit h a firm grasp of our desired out com e, we'll design our vert ex shader, t hen our fragm ent shader, and t hen t he applicat ion code t hat will t ie it all t oget her.

6.2. Vertex Shader The vert ex shader em bodies t he operat ions t hat occur on each vert ex t hat is provided t o OpenGL. To define our vert ex shader, we need t o answ er t hree quest ions. 1 . What dat a m ust be passed t o t he vert ex shader for every vert ex ( i.e., at t ribut e variables) ? 2 . What global st at e is required by t he ver t ex shader ( i.e., uniform variables) ? 3 . What values are com put ed by t he vert ex shader ( i.e., varying variables) ? Let 's look at t hese quest ions one at a t im e. We can't draw any geom et ry at all wit hout specifying a value for each vert ex posit ion. Furt herm ore, we can't do any light ing unless we have a surface norm al for each locat ion for which we want t o apply a light ing com put at ion. So at t he very least , w e need a vert ex posit ion and a norm al for ever y incom ing vert ex. These at t ribut es are already defined as part of OpenGL, and t he OpenGL Shading Language provides built - in variables t o refer t o t hem ( gl_Vertex and gl_Normal) . I f we use t he st andard OpenGL ent ry point s for passing vert ex posit ions and norm als, w e don't need any user - defined at t ribut e variables in our vert ex shader. We can access t he cur rent values for vert ex posit ion and norm al sim ply by referring t o gl_Vertex and gl_Normal. We need access t o several pieces of OpenGL stat e for our brick algorit hm . These are available t o our shader as built - in uniform var iables. We need t o access t he current m odelview- proj ect ion m at r ix ( gl_ModelViewProjection-Matrix) in order t o t ransform our vert ex posit ion int o t he clipping coordinat e syst em . We need t o access t he current m odelview m at rix ( gl_ModelViewMatrix) in order t o t ransform t he vert ex posit ion int o eye coordinat es for use in t he light ing com put at ion. And we also need t o t ransform our incom ing norm als int o eye coordinat es by using OpenGL's norm al t ransform at ion m at rix ( gl_NormalMatrix, which is j ust t he inverse t r anspose of t he upper - left 3 x 3 subset of gl_ModelViewMatrix) . I n addit ion, we need t he posit ion of a single light source. We could use t he OpenGL light ing st at e and reference t hat st at e wit hin our vert ex shader, but t o illust rat e t he use of uniform variables, we define t he light source posit ion as a uniform variable like t his: [ 1] [1] The shaders in this book observe the convention of capitalizing the first letter of user-specified uniform, varying, attribute, and nonqualified global variable names to set them apart from local variables.

uniform vec3 LightPosition;

We also need values for t he light ing calculat ion t o represent t he cont ribut ion fr om specular reflect ion and t he cont ribut ion from diffuse reflect ion. We could define t hese as uniform variables so t hat t hey could be changed dynam ically by t he applicat ion, but t o illust rat e som e addit ional feat ures of t he language, we define t hem as const ant s like t his: const float SpecularContribution = 0.3; const float DiffuseContribution = 1.0 - SpecularContribution;

Finally, w e need t o define t he values t hat are passed on t o t he fragm ent shader. Ever y vert ex shader m ust com put e t he hom ogeneous vert ex posit ion and st ore it s value in t he st andard variable gl_Position, so w e know t hat our brick vert ex shader m ust do likewise. On t he fly, we

com put e t he brick pat t ern in t he fragm ent shader as a funct ion of t he incom ing geom et ry's x and y values in m odeling coordinat es, so we define a varying variable called MCposition for t his purpose. To apply t he light ing effect on t op of our brick, we do part of t he light ing com put at ion in t he fragm ent shader and apply t he final light ing effect aft er t he brick/ m ort ar color has been com put ed in t he fragm ent shader. We do m ost of t he light ing com put at ion in t he vert ex shader and sim ply pass t he com put ed light int ensit y t o t he fragm ent shader in a varying variable called LightIntensity. These t wo varying variables are defined like t his: varying float LightIntensity; varying vec2 MCposition;

We're now ready t o get t o t he m eat of our brick vert ex shader. We begin by declaring a m ain funct ion for our vert ex shader and com put ing t he vert ex posit ion in eye coordinat es: void main() { vec3 ecPosition = vec3(gl_ModelViewMatrix * gl_Vertex);

I n t his first line of code, our vert ex shader defines a variable called ecPosition t o hold t he eye coordinat e posit ion of t he incom ing vert ex. We com put e t he eye coor dinat e posit ion by t ransform ing t he vert ex posit ion ( gl_Vertex) by t he current m odelview m at rix ( gl_ModelViewMatrix) . Because one of t he operands is a m at rix and t he ot her is a vect or, t he * operat or perform s a m at r ix m ult iplicat ion operat ion rat her t han a com ponent - wise m ult iplicat ion. The result of t he m at rix m ult iplicat ion is a ve c4 , but ecPosition is defined as a ve c3 . There is no aut om at ic conversion bet w een variables of different t ypes in t he OpenGL Shading Language, so we convert t he result t o a ve c3 by using a const ruct or. This causes t he four t h com ponent of t he result t o be dr opped so t hat t he t wo operands have com pat ible t ypes. ( Const ruct ors provide an operat ion t hat is sim ilar t o t ype cast ing, but it is m uch m ore flexible, as discussed in Sect ion 3.3) . As we'll see, t he eye coor dinat e posit ion is used a couple of t im es in our light ing calculat ion. The light ing com put at ion t hat we perform is a sim ple one. Som e light from t he light source is reflect ed in a diffuse fashion ( i.e., in all direct ions) . Where t he viewing direct ion is very nearly t he sam e as t he reflect ion direct ion from t he light source, we see a specular reflect ion. To com put e t he diffuse reflect ion, we need t o com put e t he angle bet ween t he incom ing light and t he surface norm al. To com put e t he specular reflect ion, w e need t o com put e t he angle bet ween t he reflect ion direct ion and t he viewing direct ion. First , we t ransform t he incom ing norm al: vec3 tnorm

= normalize(gl_NormalMatrix * gl_Normal);

This line defines a new variable called tnorm for st oring t he t ransform ed norm al ( rem em ber, in t he OpenGL Shading Language, variables can be declared w hen needed) . The incom ing surface norm al ( gl_Normal, a built - in variable for accessing t he norm al value supplied t hrough t he st andard OpenGL ent ry point s) is t ransform ed by t he current OpenGL norm al t ransform at ion m at r ix ( gl_NormalMatrix) . The result ing vect or is norm alized ( convert ed t o a vect or of unit lengt h) by t he built - in funct ion normalize, and t he result is st ored in tnorm. Next , w e need t o com put e a vect or from t he current point on t he surface of t he t hreedim ensional obj ect we're rendering t o t he light source posit ion. Bot h of t hese should be in eye coordinat es ( which m eans t hat t he value for our uniform variable LightPosition m ust be provided by t he applicat ion in eye coordinat es) . The light direct ion vect or is com put ed as follows: vec3 lightVec

= normalize(LightPosition - ecPosition);

The obj ect posit ion in eye coordinat es was previously com put ed and st ored in ecPosition. To com put e t he light direct ion vect or, we subt ract t he obj ect posit ion from t he light posit ion. The result ing light direct ion vect or is also norm alized and st ored in t he newly defined local variable lightVec. The calculat ions we've done so far have set t hings up alm ost perfect ly t o call t he built - in funct ion reflect. Using our t ransform ed surface norm al and t he com put ed incident light vect or, we can now com put e a r eflect ion vect or at t he surface of t he obj ect ; how ever, reflect requires t he incident vect or ( t he direct ion from t he light t o t he surface) , and we've com put ed t he direct ion t o t he light source. Negat ing lightVec gives us t he proper vect or: vec3 reflectVec = reflect(-lightVec, tnorm);

Because bot h vect ors used in t his com put at ion were unit vect ors, t he result ing vect or is a unit vect or as well. To com plet e our light ing calculat ion, we need one m ore vect ora unit vect or in t he direct ion of t he view ing posit ion. Because, by definit ion, t he viewing posit ion is at t he origin ( i.e., ( 0,0,0) ) in t he eye coordinat e syst em , we can sim ply negat e and norm alize t he com put ed eye coordinat e posit ion, ecPosition: vec3 viewVec

= normalize(-ecPosition);

Wit h t hese four vect ors, we can perform a per- vert ex light ing com put at ion. The relat ionship of t hese vect or s is shown in Figur e 6.2.

Figu r e 6 .2 . Ve ct or s in volve d in t h e ligh t in g com pu t a t ion for t he br ick ve r t e x sh a de r

The m odeling of diffuse reflect ion is based on t he assum pt ion t hat t he incident light is scat t ered in all direct ions according t o a cosine dist ribut ion funct ion. The reflect ion of light is st rongest when t he light direct ion vect or and t he surface norm al are coincident . As t he difference bet w een t he t w o angles increases t o 90°, t he diffuse reflect ion drops off t o zero. Because bot h vect ors have been norm alized t o pr oduce unit vect ors, we can det erm ine t he cosine of t he angle bet w een lightVec and tnorm by perform ing a dot product operat ion bet ween t hose vect ors. We want t he diffuse cont ribut ion t o be 0 if t he angle bet ween t he light and t he surface norm al is great er t han 90° ( t here should be no diffuse cont ribut ion if t he light is behind t he obj ect ) , and t he max funct ion accom plishes t his: float diffuse = max(dot(lightVec, tnorm), 0.0);

The specular com ponent of t he light int ensit y for t his vert ex is com put ed by float spec = 0.0; if (diffuse > 0.0) { spec = max(dot(reflectVec, viewVec), 0.0); spec = pow(spec, 16.0); }

The variable for t he specular r eflect ion value is defined and init ialized t o 0. We com put e a specular value ot her t han 0 only if t he angle bet w een t he light dir ect ion vect or and t he surface norm al is less t han 90° ( i.e., t h e diffuse value is great er t han 0) because we don't want any specular highlight s if t he light source is behind t he obj ect . Because bot h reflectVec and viewVec are norm alized, com put ing t he dot product of t hese t w o vect ors gives us t he cosine of t he angle bet w een t hem . I f t he angle is near zero ( i.e., t he reflect ion vect or and t he viewing vect or are alm ost t he sam e) , t he result ing value is near 1.0. By raising t he result t o t he 16t h power in t he subsequent line of code, we effect ively " sharpen" t he highlight , ensuring t hat w e have a specular highlight only in t he region w here t he reflect ion vect or and t he view vect or are alm ost t he sam e. The choice of 16 for t he exponent value is arbit rary. Higher values produce m ore concent rat ed specular highlight s, and lower values produce less concent rat ed highlight s. This value could also be passed in as a uniform variable so t hat it can be easily m odified by t he end user. All t hat rem ains is t o m ult iply t he com put ed diffuse and specular reflect ion values by t he diffuseContribution and specularContribution const ant s and sum t he t wo values: LightIntensity = DiffuseContribution * diffuse + SpecularContribution * spec;

This value will be assigned t o t he varying variable LightIntensity and int erpolat ed bet ween vert ices. We also have one ot her varying variable t o com put e, and we can do t hat quit e easily: MCposition = gl_Vertex.xy;

When t he brick pat t ern is applied t o a geom et ric obj ect , we want t he br ick pat t ern t o rem ain const ant wit h respect t o t he surface of t he obj ect , no m at t er how t he obj ect is m oved. We also want t he brick pat t ern t o rem ain const ant wit h respect t o t he surface of t he obj ect , no m at t er what t he viewing posit ion. To generat e t he brick pat t ern algorit hm ically in t he fragm ent shader, we need t o provide a value at each fragm ent t hat repr esent s a locat ion on t he surface. For t his exam ple, we provide t he m odeling coordinat e at each vert ex by set t ing our varying variable MCposition t o t he sam e value as our incom ing vert ex posit ion ( which is, by definit ion, in m odeling coordinat es) .

We don't need t he z or w coordinat e in t he fragm ent shader, so we need a way t o select j ust t he x and y com ponent s of gl_Vertex. We could have used a const ruct or here ( e.g., ve c2 ( gl_Vertex) ) , but t o show off anot her language feat ur e, w e use t he com ponent select or .x y t o select t he first t w o com ponent s of gl_Vertex and st ore t hem in our varying variable MCposition. All t hat rem ains t o be done is what all vert ex shaders m ust do: com put e t he hom ogeneous vert ex posit ion. We do t his by t ransform ing t he incom ing vert ex value by t he current m odelview- proj ect ion m at rix, using t he built - in funct ion ftransform: gl_Position = ftransform(); }

For clarit y, t he code for our vert ex shader is provided in it s ent iret y in List ing 6.1.

List in g 6 .1 . Sou r ce code for br ick ve r t e x sh a de r uniform vec3 LightPosition; const float SpecularContribution = 0.3; const float DiffuseContribution = 1.0 - SpecularContribution; varying float LightIntensity; varying vec2 MCposition; void main() { vec3 ecPosition vec3 tnorm vec3 lightVec vec3 reflectVec vec3 viewVec float diffuse float spec

= = = = = = =

vec3(gl_ModelViewMatrix * gl_Vertex); normalize(gl_NormalMatrix * gl_Normal); normalize(LightPosition - ecPosition); reflect(-lightVec, tnorm); normalize(-ecPosition); max(dot(lightVec, tnorm), 0.0); 0.0;

if (diffuse > 0.0) { spec = max(dot(reflectVec, viewVec), 0.0); spec = pow(spec, 16.0); } LightIntensity = DiffuseContribution * diffuse + SpecularContribution * spec; MCposition gl_Position }

= gl_Vertex.xy; = ftransform();

6.3. Fragment Shader The t ypical purpose of a fragm ent shader is t o com put e t he color t o be applied t o a fragm ent or t o com put e t he dept h value for t he fragm ent or bot h. I n t his case ( and indeed wit h m ost fragm ent shaders) , we're concerned only about t he color of t he fragm ent . We're perfect ly happy using t he dept h value t hat 's been com put ed by t he OpenGL rast erizat ion st age. Therefore, t he ent ire purpose of t his shader is t o com put e t he color of t he curr ent fragm ent . Our brick fragm ent shader st art s off by defining a few m ore uniform variables t han did t he ver t ex shader . The brick pat t er n t hat w ill be rendered on our geom et ry is param et erized t o m ake it easier t o m odify. The param et ers t hat are const ant across an ent ire prim it ive can be st ored as uniform variables and init ialized ( and lat er m odified) by t he applicat ion. This m akes it easy t o expose t hese cont rols t o t he end user for m odificat ion t hrough user int erface elem ent s such as sliders and color pickers. The brick fragm ent shader uses t he param et ers t hat are illust rat ed in Figur e 6.1. These are defined as uniform variables as follows: uniform vec3 uniform vec2 uniform vec2

BrickColor, MortarColor; BrickSize; BrickPct;

We want our brick pat t ern t o be applied consist ent ly t o our geom et ry in order t o have t he obj ect look t he sam e no m at t er where it is placed in t he scene or how it is rot at ed. The key t o det erm ining t he placem ent of t he br ick pat t ern is t he m odeling coordinat e posit ion t hat is com put ed by t he vert ex shader and passed in t he varying variable MCposition: varying vec2 MCposition;

This variable was com put ed at each vert ex by t he vert ex shader in t he previous sect ion, and it is int erpolat ed across t he prim it ive and m ade available t o t he fragm ent shader at each fragm ent locat ion. Our fragm ent shader can use t his inform at ion t o det erm ine where t he fragm ent locat ion is in relat ion t o t he algorit hm ically defined brick pat t ern. The ot her varying variable t hat is provided as input t o t he fragm ent shader is defined as follows: varying float LightIntensity;

This varying variable cont ains t he int erpolat ed value for t he light int ensit y t hat we com put ed at each vert ex in our vert ex shader. Not e t hat bot h of t he varying variables in our fragm ent shader are defined wit h t he sam e t ype t hat was used t o define t hem in our vert ex shader. A link error would be generat ed if t his were not t he case. Wit h our uniform and varying variables defined, we can begin wit h t he act ual code for t he brick fragm ent shader: void main() { vec3 color; vec2 position, useBrick;

I n t his shader, we do t hings m ore like we would in C and define all our local variables before t hey'r e used at t he beginning of our main funct ion. I n som e cases, t his can m ake t he code a lit t le cleaner or easier t o read, but it is m ost ly a m at t er of personal pr eference and coding st yle.

The first act ual line of code in our brick fragm ent shader com put es values for t he local ve c2 variable position: position = MCposition / BrickSize;

This st at em ent divides t he fragm ent 's x posit ion in m odeling coordinat es by t he brick colum n widt h and t he y posit ion in m odeling coordinat es by t he brick row height . This gives us a " brick row num ber" ( position.y) and a " brick num ber" wit hin t hat row ( position.x) . Keep in m ind t hat t hese are signed, float ing- point values, so it is perfect ly reasonable t o have negat ive row and brick num bers as a result of t his com put at ion. Next , we use a condit ional t o det erm ine whet her t he fragm ent is in a row of bricks t hat is offset ( see Figur e 6.3) : if (fract(position.y * 0.5) > 0.5) position.x += 0.5;

Figu r e 6 .3 . A gr a ph of t h e fu n ct ion fract( position.y * 0 .5 ) sh ow s h ow t h e e ve n / odd r ow de t e r m in a t ion is m a de . Th e r e su lt of t h is fu n ct ion is com pa r e d a ga in st 0 .5 . I f t h e va lu e is gr e a t e r t h a n 0 .5 , a va lu e of 0 .5 is a dde d t o position.x; ot h e r w ise , n ot h in g is a dde d. Th e r e su lt is t h a t r ow s w h ose in t e ge r va lu e s a r e 1 , 3 , 5 , . . ., a r e sh ift e d h a lf a br ick posit ion t o t h e r igh t .

The " brick row num ber" ( position.y) is m ult iplied by 0.5, t he int eger part is dropped by t he fract funct ion, and t he result is com pared t o 0.5. Half t he t im e ( or every ot her row) , t his com parison is t r ue, and t he " brick num ber" value ( position.x) is increm ent ed by 0.5 t o offset t he ent ire row by half t he widt h of a brick. This is illust rat ed by t he graph in Figur e 6.3. Following t his, we com put e t he fragm ent 's locat ion wit hin t he current brick: position = fract(position);

This com put at ion gives us t he vert ical and horizont al posit ion wit hin a single brick. This posit ion serves as t he basis for det erm ining whet her t o use t he brick color or t he m ort ar color. Figur e 6.4 shows how we m ight visualize t he result s of t he fragm ent shader t o t his point . I f we

were t o apply t his shader t o a square wit h m odeling coordinat es of ( 1.0, 1.0) at t he lower- left corner and ( 1.0, 1.0) at t he upper right , our part ially com plet ed shader would show t he beginnings of t he brick pat t ern we'r e aft er. Because t he overall widt h of t he square is 2.0 unit s in m odeling coordinat es, our division of MCposition.x by BrickSize.x gives us 2.0 / 0.3 or roughly six and t w o- t hir ds bricks across, as w e see in Figur e 6.4. Sim ilarly t he division of MCposition.y by BrickSize.y gives us 2.0 / 0.15 or roughly t hirt een and t wo- t hir ds rows of bricks from t op t o bot t om . For t his illust rat ion, we shaded each fragm ent by sum m ing t he fract ional part of position.x and position.y, m ult iplying t he result by 0.5, and t hen st oring t his value in t he red, green, and blue com ponent s of gl_FragColor.

Figu r e 6 .4 . I nt e r m e dia t e r e su lt s of br ick fr a gm e n t sh a de r [View full size image]

To com plet e our brick shader, we need a funct ion t hat gives us a value of 1.0 when t he brick color should be used and 0 when t he m ort ar color should be used. I f we can achieve t his, w e can end up wit h a sim ple way t o choose t he appropr iat e color. We know t hat we'r e working wit h a horizont al com ponent of t he brick t ext ure funct ion and a vert ical com ponent . I f w e can creat e t he desired funct ion for t he horizont al com ponent and t he desired funct ion for t he vert ical com ponent , we can j ust m ult iply t he t wo values t oget her t o get our final answer. I f t he result of eit her of t he individual funct ions is 0 ( m ort ar color) , t he m ult iplicat ion causes t he final answer t o be 0; ot herwise, it is 1.0, and t he brick color is used. We use t he step funct ion t o achieve t he desired effect . The step funct ion t akes t wo argum ent s, an edge ( or t hreshold) and a param et er t o t est against t hat edge. I f t he value of t he param et er t o be t est ed is less t han t he edge value, t he funct ion ret urns 0; ot herw ise, it ret ur ns 1.0. ( Refer t o Figure 5.11 for a graph of t his funct ion) . I n t ypical use, t he step funct ion produces a pat t ern of pulses ( i.e., a square wave) whereby t he funct ion st art s at 0 and rises t o 1.0 when t he t hreshold is reached. We can get a funct ion t hat st art s at 1.0 and dr ops t o 0 j ust by reversing t he order of t he t wo argum ent s provided t o t his funct ion: useBrick = step(position, BrickPct);

I n t his line of code, we com put e t wo values t hat t ell us whet her w e are in t he brick or in t he m ort ar in t he horizont al direct ion ( useBrick.x) and in t he vert ical direct ion ( useBrick.y) . The built - in funct ion step produces a value of 0 when BrickPct.x < position.x and a value of 1.0 w hen BrickPct.x > = position.x. Because of t he fract funct ion, we know t hat position.x varies from ( 0,1) . The variable BrickPct is a uniform variable, so it s value is const ant across t he prim it ive. This m eans t hat t he value of useBrick.x is 1.0 when t he brick color should be used and 0 w hen t he m ort ar color should be used as we m ove horizont ally. The sam e t hing is done in t he vert ical direct ion, wit h position.y and BrickPct.y com put ing t he value for useBrick.y. By m ult iplying useBrick.x by useBrick.y, we can get a value of 0 or 1.0 t hat let s us select t he appropriat e color for t he fragm ent . The periodic st ep funct ion for t he horizont al com ponent of t he brick pat t ern is illust r at ed in Figur e 6.5.

Figu r e 6 .5 . The pe r iodic st e p fu n ct ion t h a t pr odu ce s t he h or izon t a l com pon e n t of t h e pr oce du r a l br ick pa t t e r n

The values of BrickPct.x and BrickPct.y can be com put ed by t he applicat ion t o give a uniform m ort ar widt h in bot h direct ions based on t he rat io of colum n widt h t o row height , or t he values can be chosen arbit rarily t o give a m or t ar appearance t hat looks right . All t hat rem ains is t o com put e our final color value and st ore it in t he special variable gl_FragColor: color = mix(MortarColor, BrickColor, useBrick.x * useBrick.y); color *= LightIntensity; gl_FragColor = vec4(color, 1.0); }

Here we com put e t he color of t he fragm ent and st ore it in t he local variable color. We use t he built - in funct ion mix t o choose t he brick color or t he m ort ar color, depending on t he value of useBrick.x * useBrick.y. Because useBrick.x and useBrick.y can have values of only 0 ( m ort ar) or 1.0 ( brick) , w e choose t he brick color only if bot h values are 1.0; ot herwise, w e choose t he m ort ar color . The result ing value is t hen m ult iplied by t he light int ensit y, and t hat result is st ored in t he local variable color. This local variable is a ve c3 , and gl_FragColor is defined as a ve c4 , so we creat e our final color value by using a const ruct or t o add a four t h com ponent ( alpha) equal t o 1.0 and assign t he result t o t he built - in variable gl_FragColor.

The source code for t he com plet e fragm ent shader is shown in List ing 6.2.

List in g 6 .2 . Sou r ce code for br ick fr a gm e n t sh a de r uniform vec3 uniform vec2 uniform vec2

BrickColor, MortarColor; BrickSize; BrickPct;

varying vec2 MCposition; varying float LightIntensity; void main() { vec3 color; vec2 position, useBrick; position = MCposition / BrickSize; if (fract(position.y * 0.5) > 0.5) position.x += 0.5; position = fract(position); useBrick = step(position, BrickPct); color = mix(MortarColor, BrickColor, useBrick.x * useBrick.y); color *= LightIntensity; gl_FragColor = vec4(color, 1.0); }

When com paring t his shader t o t he vert ex shader in t he previous exam ple, w e not ice one of t he key feat ures of t he OpenGL Shading Language, nam ely, t hat t he language used t o writ e t hese t w o shaders is alm ost ident ical. Bot h shaders have a m ain funct ion, som e uniform variables, and som e local variables; expressions are t he sam e; built - in funct ions are called in t he sam e w ay; const ruct ors are used in t he sam e w ay; and so on. The only percept ible differences exhibit ed by t hese t wo shaders are ( A) t he vert ex shader accesses built - in at t ribut e variables, such as gl_Vertex and gl_Normal, ( B) t he vert ex shader writ es t o t he built - in variable gl_Position, whereas t he fr agm ent shader w rit es t o t he built - in variable gl_FragColor, and ( C) t he varying variables are writ t en by t he vert ex shader and are read by t he fragm ent shader. The applicat ion code t o creat e and use t hese shaders is shown in Sect ion 7.13, aft er t he OpenGL Shading Language API has been present ed. The result of rendering som e sim ple obj ect s wit h t hese shaders is shown in Figur e 6.6. A color version of t he result is shown in Color Plat e 35.

Figur e 6 .6 . A fla t poly gon, a sph e r e , a n d a t or us r e n de r e d w it h t h e br ick sh a de r s

6.4. Observations A couple of problem s wit h our shader m ake it unfit for anyt hing but t he sim plest cases. Because t he br ick pat t ern is com put ed wit h t he m odeling coordinat es of t he incom ing obj ect , t he apparent size of t he bricks depends on t he size of t he obj ect in m odeling coordinat es. The brick pat t ern m ight look fine wit h som e obj ect s, but t he bricks m ay t urn out m uch t oo sm all or m uch t oo large on ot her obj ect s. At t he very least , w e should probably have a uniform variable in t he vert ex shader t o scale t he m odeling coordinat es. The applicat ion could allow t he end user t o adj ust t he scale fact or t o m ake t he br ick pat t ern look good on t he obj ect being rendered. Anot her pot ent ial issue is t hat we've chosen t o base t he brick pat t ern on t he obj ect 's x and y coordinat es in m odeling space. This can result in som e unrealist ic- looking effect s on obj ect s t hat aren't as regular as t he obj ect s shown in Figur e 6.6. By using only t he x and y coordinat es of t he obj ect , we end up m odeling bricks t hat are infinit ely deep. The brick pat t ern looks fine when viewed from t he front of t he obj ect , but when you look at it from t he side, you'll be able t o see how t he brick ext ends in dept h. To get a t ruly t hree- dim ensional brick shader, we'd need t o add a t hird dim ension t o our procedural t ext ure calculat ion and use t he z com ponent of t he posit ion in m odeling coordinat es t o det erm ine whet her w e w ere in brick or m ort ar in t he z dim ension as well ( see if you can m odify t he shaders t o do t his) . I f we look closely at our brick pat t ern, we also not ice aliasing art ifact s ( j aggies) along t he t ransit ion from brick color t o m ort ar color. These art ifact s are due t o t he step funct ion causing an inst ant aneous change from 0 t o 1.0 ( or fr om 1.0 t o 0) w hen we cross t he t ransit ion point bet w een brick color and m or t ar color. Our shader has no alt ernat ive but t o pick one color or t he ot her for each fragm ent , and, because we cannot sam ple at a high enough frequency t o represent t his inst ant aneous change at t he brick/ m ort ar border, aliasing art ifact s occur. I nst ead of using t he step funct ion, we could have used t he built - in smoothstep funct ion. This funct ion is like t he step funct ion, except t hat it defines t w o edges and a sm oot h int erpolat ion bet ween 0 and 1.0 bet w een t hose t w o edges. This w ould have t he effect of blurr ing t he t ransit ion bet ween t he brick color and t he m ort ar color, t hus m aking t he aliasing art ifact s m uch less not iceable. A m et hod for analyt ically ant ialiasing t he procedural brick t ext ure is described in Sect ion 17.4.5. Despit e t hese short com ings, our brick shaders are perfect ly good exam ples of a working OpenGL shader. Toget her, our brick vert ex and fragm ent shader s illust rat e a num ber of t he int erest ing feat ures of t he OpenGL Shading Language.

6.5. Summary This chapt er has applied t he language concept s from previous chapt ers t o t he developm ent of working shaders t hat creat e a procedurally defined br ick pat t ern. The vert ex shader is responsible for t ransform ing t he vert ex posit ion, passing along t he m odeling coordinat e posit ion of t he vert ex, and com put ing a light int ensit y value at each vert ex, using a single sim ulat ed light source. The fragm ent shader is responsible for det erm ining whet her each fr agm ent should be brick color or m ort ar color. Once t his det erm inat ion is m ade, t he light int ensit y value is applied t o t he chosen color, and t he final color value is passed from t he fragm ent shader so t hat it can ult im at ely be writ t en in t he fram e buffer. The source code for t hese t wo shaders was discussed line by line t o explain clearly how t hey work. This pair of shaders illust rat es m any of t he feat ures of t he OpenGL Shading Language and can be used as a springboard for doing bigger and bet t er t hings wit h t he language.

6.6. Further Information This shader and ot hers are available from t he 3Dlabs developer Web sit e. Source code for get t ing st ar t ed wit h OpenGL shaders is also available. 1 . 3Dlabs developer Web sit e. ht t p: / / developer.3dlabs.com / 2 . Baldwin, Dave, OpenGL 2.0 Shading Language Whit e Paper, Version 1.0, 3Dlabs, Oct ober, 2001. 3 . Ebert , David S., John Hart , Bill Mark, F. Kent on Musgrave, Darwyn Peachey, Ken Perlin, and St even Worley, Text uring and Modeling: A Procedural Approach, Thir d Edit ion, Morgan Kaufm ann Publishers, San Francisco, 2002. ht t p: / / w ww .t ext uringandm odeling.com 4 . Kessenich, John, Dave Baldwin, and Randi Rost , The OpenGL Shading Language, Version 1.10, 3Dlabs, April 2004. ht t p: / / w ww .opengl.org/ docum ent at ion/ spec.ht m l 5 . Segal, Mark, and Kurt Akeley, The OpenGL Graphics Syst em : A Specificat ion ( Version 2.0) , Edit or ( v1.1) : Chris Fr azier, ( v1.21.5) : Jon Leech, ( v2.0) : Jon Leech and Pat Brow n, Sept . 2004. ht t p: / / w ww .opengl.org/ docum ent at ion/ spec.ht m l

Chapter 7. OpenGL Shading Language API I n support of t he OpenGL Shading Language, m ore t han 30 new ent ry point s were added t o OpenGL in version 2.0. This set of API calls is referred t o t hroughout t his book as t he OPENGL SHADI NG LANGUAGE API . I n t his chapt er, we look at t he OpenGL ent r y point s t hat have been added t o creat e, load, com pile, and link shaders, as well as t he ent ry point s t hat have been added for passing generic vert ex at t ribut es and uniform variables t o shaders. Reference pages for all of t he OpenGL Shading Language API ent r y point s are found in Appendix B. At t he end of t his chapt er, we discuss t he applicat ion code t hat is needed t o creat e and use t he brick shader present ed in Chapt er 6. I f you j ust can't wait , go ahead and sneak a peek at Sect ion 7.13, and t hen com e back here t o learn t he det ails of t he API . Here is an overview of creat ing and using OpenGL shaders: 1.

Creat e one or m ore ( em pt y) shader obj ect s wit h glCreateShader.

2.

Provide source code for t hese shaders wit h glShaderSource.

3.

Com pile each of t he shaders wit h glCompileShader.

4.

Creat e a program obj ect wit h glCreateProgram.

5.

At t ach all t he shader obj ect s t o t he program obj ect wit h glAttachShader.

6.

Link t he program obj ect wit h glLinkProgram.

7.

I nst all t he execut able program as part of OpenGL's current st at e w it h glUseProgram.

8.

I f t he shaders use user - defined uniform variables, query t he locat ions of t hese variables wit h glGetUniformLocation and t hen set t heir values wit h glUniform.

I f t he vert ex shader uses user - defined at t ribut e variables, t he applicat ion m ust provide values for t hem , using OpenGL API calls t hat place at t ribut e values in generic, num bered vert ex at t ribut e locat ions. Before such at t ribut e dat a is passed t o t he shader, t he index of t he generic vert ex at t ribut e should be associat ed w it h an at t ribut e variable in a vert ex shader in one of t wo ways. Applicat ions can creat e t his associat ion explicit ly by calling glBindAttribLocation before linking. Alt ernat ively, if no explicit associat ion is m ade, OpenGL m akes t hese associat ions aut om at ically during linking. An applicat ion can query t he assignm ent t hat was m ade wit h glGetAttribLocation. Thereaft er, generic vert ex at t ribut es can be passed t o a vert ex shader wit h glVertexAttrib or wit h glVertexAttribPointer and glEnableVertexArrayPointer in conj unct ion wit h st andard OpenGL com m ands t o draw vert ex arrays.

7.1. Obtaining Version Information Wit h t he addit ion of t he OpenGL Shading Language, t he OpenGL version num ber was changed from 1.5 t o 2.0. The num ber before t he period is referred t o as t he m aj or ver sion num ber and t he num ber aft er t he period is referr ed t o as t he m inor version num ber. This did not reflect a change in com pat ibilit y, as is oft en t he case when a product 's m aj or version num ber is changed. I nst ead, t he OpenGL ARB believed t hat inclusion of a high- level shading language was a m aj or addit ion t o OpenGL. To call at t ent ion t o t his im port ant capabilit y, t he com m it t ee decided t hat a change t o OpenGL's m aj or version num ber was war rant ed. This caused som e incom pat ibilit y wit h applicat ions t hat were writ t en assum ing t hat OpenGL would never have a m aj or version num ber gr eat er t han 1. The OpenGL Shading Language also has a version num ber since it is expect ed t hat it t oo w ill have addit ional feat ures added over t im e. Bot h of t hese values can be queried wit h t he OpenGL funct ion glGetString. To writ e applicat ions t hat will work properly in a variet y of OpenGL environm ent s and t hat w ill st and t he t est of t im e, be sure t o properly query and parse t he OpenGL and OpenGL Shading Language version st rings. Bot h st rings ar e defined as < version num ber> < space> < vendor- specific inform at ion> The version num ber is defined t o be eit her m aj orVersionNum ber.m inorVersionNum ber or m aj orVersionNum ber.m inorVersionNum ber.releaseNum ber where each com ponent cont ains one or m ore digit s. The vendor specificat ion inform at ion and t he release num ber are opt ional and m ight not appear in t he version st ring. The version num ber is not a float ing- point num ber, but a series of int egers separat ed by periods. To det erm ine t he OpenGL version num ber, call glGetString wit h t he sym bolic const ant GL_VERSI ON. To det erm ine t he OpenGL Shading Language version, call glGetString w it h t he sym bolic const ant GL_SHADI NG_LANGUAGE_VERSI ON. The shading language version t hat was approved at t he t im e OpenGL 2.0 was approved was 1.10. List ing 7.1 cont ains code for C funct ions t hat query and parse t he OpenGL and OpenGL Shading Language version st rings. Bot h funct ions assum e t hat a valid OpenGL cont ext already exist s, and bot h ret urn 0 for t he m aj or and m inor num ber if an er ror is encount ered. Values ret urned by t hese funct ions can be t est ed t o see if t he underlying im plem ent at ion provides t he necessary support .

List in g 7 .1 . C fu n ct ions t o obt a in Ope n GL a n d Ope n GL Sh a din g La n gu a ge ve r sion in for m a t ion void getGlVersion(int *major, int *minor) { const char *verstr = (const char *) glGetString(GL_VERSION); if ((verstr == NULL) || (sscanf(verstr,"%d.%d", major, minor) != 2)) { *major = *minor = 0; fprintf(stderr, "Invalid GL_VERSION format!!!\n");

} } void getGlslVersion(int *major, int *minor) { int gl_major, gl_minor; getGlVersion(&gl_major, &gl_minor); *major = *minor = 0; if(gl_major == 1) { /* GL v1.x can only provide GLSL v1.00 as an extension */ const char *extstr = (const char *) glGetString(GL_EXTENSIONS); if ((extstr != NULL) && (strstr(extstr, "GL_ARB_shading_language_100") != NULL)) { *major = 1; *minor = 0; } } else if (gl_major >= 2) { /* GL v2.0 and greater must parse the version string */ const char *verstr = (const char *) glGetString(GL_SHADING_LANGUAGE_VERSION); if((verstr == NULL) || (sscanf(verstr, "%d.%d", major, minor) != 2)) { *major = *minor = 0; fprintf(stderr, "Invalid GL_SHADING_LANGUAGE_VERSION format!!!\n"); } } }

7.2. Creating Shader Objects The design of t he OpenGL Shading Language API m im ics t he process of developing a C or C+ + applicat ion. The first st ep is t o creat e t he source code. The source code m ust t hen be com piled, t he various com piled m odules m ust be linked, and finally t he result ing code can be execut ed by t he t ar get processor. To support t he concept of a high- level shading language wit hin OpenGL, t he design m ust provide st orage for source code, com piled code, and execut able code. The solut ion t o t his problem is t o define t wo new OpenGL- m anaged dat a st ruct ures, or obj ect s. These obj ect s provide t he necessary st orage, and operat ions on t hese obj ect s have been defined t o provide funct ionalit y for specifying source code and t hen com piling, linking, and execut ing t he result ing code. When one of t hese obj ect s is cr eat ed, OpenGL ret urns a unique ident ifier for it . This ident ifier can be used t o m anipulat e t he obj ect and t o set or query t he param et ers of t he obj ect . The first st ep t oward ut ilizing program m able graphics hardware is t o creat e a shader obj ect . This creat es an OpenGL- m anaged dat a st ruct ure t hat can st ore t he shader's source code. The com m and t o creat e a shader is GLuint glCreateShader( GLenum shaderType) Creat es an em pt y shader obj ect and ret urns a non- zero value by which it can be referenced. A shader obj ect m aint ains t he source code st rings t hat define a shader. shaderType specifies t he t ype of shader t o be creat ed. Tw o t ypes of shaders are support ed. A shader of t ype GL_VERTEX_SHADER is a shader t hat runs on t he program m able vert ex processor; it replaces t he fixed funct ionalit y vert ex processing in OpenGL. A shader of t ype GL_FRAGMENT_SHADER is a shader t hat runs on t he program m able fragm ent processor; it replaces t he fixed funct ionalit y fragm ent processing in OpenGL. When creat ed, a shader obj ect 's GL_SHADER_TYPE param et er is set t o eit her GL_VERTEX_SHADER or GL_FRAGMENT_SHADER, depending on t he value of shaderType.

Aft er a shader obj ect is creat ed, st rings t hat define t he shader's source code m ust be provided. The source code for a shader is provided as an array of st rings. The com m and for defining a shader's source code is void glShaderSource( GLuint shader, GLsizei count, const GLchar * * string, const GLint * length) Set s t he sour ce code in shader t o t he source code in t he array of st rings specified by string. Any source code pr eviously st ored in t he shader obj ect is com plet ely replaced. The num ber of st rings in t he array is specified by count. I f length is NULL, t hen each st ring is assum ed t o be null t erm inat ed. I f length is a value ot her t han NULL, it point s t o an ar ray cont aining a st ring lengt h for each of t he corr esponding elem ent s of string. Each elem ent in t he length array can cont ain t he lengt h of t he corresponding st ring ( t he null charact er is not count ed as part of t he st ring lengt h) or a value less t han 0 t o indicat e t hat t he st ring is null t erm inat ed. The source

code st rings are not scanned or parsed at t his t im e; t hey are sim ply copied int o t he specified shader obj ect . An applicat ion can m odify or free it s copy of t he source code st rings im m ediat ely aft er t he funct ion ret urns.

The m ult iple st rings int erface provides a num ber of benefit s, including z

A way t o organize com m on pieces of source code ( for inst ance, t he varying variable definit ions t hat are shared bet ween a vert ex shader and a fragm ent shader)

z

A way t o share prefix st rings ( analogous t o header files) bet ween shaders

z

A w ay t o share # de fin e values t o cont rol t he com pilat ion pr ocess

z

A way t o include user- defined or t hird- part y library funct ions

7.3. Compiling Shader Objects Aft er t he source code st rings have been loaded int o a shader obj ect , t he source code m ust be com piled t o check it s validit y. The result of com pilat ion rem ains as part of t he shader obj ect unt il anot her com pilat ion operat ion occurs or unt il t he shader obj ect it self is delet ed. The com m and t o com pile a shader obj ect is void glCompileShader( GLuint shader) Com piles t he source code st rings t hat have been st ored in t he shader obj ect specified by shader. The com pilat ion st at us is st ored as part of t he shader obj ect 's st at e. This value is set t o GL_TRUE if t he shader was com piled wit hout errors and is ready for use, and GL_FALSE ot herwise. I t can be queried by calling glGetShader wit h argum ent s shader and GL_COMPI LE_STATUS. A shader will fail t o com pile if it is lexically, gram m at ically, or sem ant ically incorrect . Whet her or not t he com pilat ion was successful, infor m at ion about t he com pilat ion can be obt ained from t he shader obj ect 's inform at ion log wit h glGetShaderInfoLog.

The OpenGL Shading Language has com pilat ion rules t hat are slight ly different depending on t he t ype of shader being com piled, and so t he com pilat ion t akes int o considerat ion whet her t he shader is a vert ex shader or a fragm ent shader. I nform at ion about t he com pile operat ion can be obt ained by calling glGetShaderInfoLog ( described in Sect ion 7.6) wit h shader, but t he inform at ion log should not be used as an indicat ion of whet her t he com pilat ion was successful. I f t he shader obj ect w as com piled successfully, eit her t he inform at ion log is an em pt y st ring or it cont ains inform at ion about t he com pile operat ion. I f t he shader obj ect was not com piled successfully, t he inform at ion log cont ains inform at ion about any lexical, gram m at ical, or sem ant ic errors t hat occurred, along w it h w arning m essages and any ot her inform at ion t he com piler deem s pert inent .

7.4. Linking and Using Shaders Each shader obj ect is com piled independent ly. To creat e a program , applicat ions need a m echanism for specifying a list of shader obj ect s t o be linked. You can specify t he list of shaders obj ect s t o be linked by creat ing a program obj ect and at t aching t o it all t he shader obj ect s needed t o creat e t he progr am . To creat e a program obj ect , use t he following com m and: GLuint glCreateProgram( void) Creat es an em pt y program obj ect and ret urns a non- zer o value by w hich it can be referenced. A program obj ect is an obj ect t o which shader obj ect s can be at t ached. This provides a m echanism t o specify t he shader obj ect s t hat will be linked t o creat e a pr ogram . I t also provides a m eans for checking t he com pat ibilit y bet ween shaders t hat will be used t o creat e a program ( for inst ance, checking t he com pat ibilit y bet ween a vert ex shader and a fragm ent shader) . When no longer needed as part of a program obj ect , shader obj ect s can be det ached.

Aft er t he program obj ect has been defined, shader obj ect s can be at t ached t o it . At t aching sim ply m eans creat ing a reference t o t he shader obj ect so t hat it will be included when an at t em pt t o link a program obj ect is m ade. This is t he applicat ion's way of describing t he recipe for creat ing a program . The com m and t o at t ach a shader obj ect t o a pr ogram obj ect is

void glAttachShader( GLuint program, GLuint shader) At t aches t he shader obj ect specified by shader t o t he pr ogram obj ect specified by program. This indicat es t hat shader will be included in link operat ions t hat are perform ed on program.

There is no inher ent lim it on t he num ber of shader obj ect s t hat can be at t ached t o a program obj ect . All operat ions t hat can be perform ed on a shader obj ect are valid whet her or not t he shader obj ect is at t ached t o a program obj ect . I t is perm issible t o at t ach a shader obj ect t o a program obj ect before source code has been loaded int o t he shader obj ect or before t he shader obj ect has been com piled. I t is also perm issible t o at t ach a shader obj ect t o m ore t han one program obj ect . I n ot her words, glAttachShader sim ply specifies t he set of shader obj ect s t o be linked. To creat e a valid program , all t he shader obj ect s at t ached t o a program obj ect m ust be com piled and t he program obj ect it self m ust be linked. The link operat ion assigns locat ions for uniform variables, init ializes user- defined uniform variables, resolves references bet ween independent ly com piled shader obj ect s, and checks t o m ake sure t he vert ex and fragm ent shaders are com pat ible wit h one anot her. To link a pr ogram obj ect , use t he com m and void glLinkProgram( GLuint program) Links t he program obj ect specified by program. I f any shader obj ect s of t ype GL_VERTEX_SHADER are at t ached t o program, t hey are used t o creat e an execut able t hat w ill run on t he pr ogram m able vert ex processor.

I f any shader obj ect s of t ype GL_FRAGMENT_SHADER are at t ached t o program, t hey are used t o creat e an execut able t hat will run on t he

progr am m able fragm ent pr ocessor. The st at us of t he link operat ion is st ored as part of t he program obj ect 's st at e. This value is set t o GL_TRUE if t he program obj ect was linked wit hout errors and is ready for use and set t o GL_FALSE ot herwise. I t can be queried by calling glGetProgram wit h argum ent s program and GL_LI NK_STATUS. As a result of a successful link operat ion, all act ive user- defined uniform variables ( see Sect ion 7.8) belonging t o program are init ialized t o 0, and each of t he program obj ect 's act ive uniform variables is assigned a locat ion t hat can be queried wit h glGetUniformLocation. Also, any act ive user - defined at t ribut e var iables ( see Sect ion 7.7) t hat have not been bound t o a generic vert ex at t ribut e index are bound t o one at t his t im e. I f program cont ains shader obj ect s of t ype GL_VERTEX_SHADER but it does not cont ain shader obj ect s of t ype GL_FRAGMENT_SHADER, t he vert ex shader is linked t o t he im plicit int erface for fixed funct ionalit y fragm ent processing. Sim ilarly, if program cont ains shader obj ect s of t ype GL_FRAGMENT_SHADER but it does not cont ain shader obj ect s of t ype GL_VERTEX_SHADER, t he fragm ent shader is linked t o t he im plicit int erface for fixed funct ionalit y vert ex processing. glLinkProgram also inst alls t he generat ed execut ables as part of t he current

rendering st at e if t he link operat ion was successful and t he specified program obj ect is already current ly in use as a result of a previous call t o glUseProgram. I f t he program obj ect current ly in use is relinked unsuccessfully, it s link st at us is set t o GL_FALSE, but t he pr eviously gener at ed execut ables and associat ed st at e rem ain part of t he curr ent st at e unt il a subsequent call t o glUseProgram rem oves t hem . Aft er t hey are rem oved, t hey cannot be m ade part of curr ent st at e unt il t he program obj ect has been successfully relinked.

Linking of a program obj ect can fail for a num ber of reasons. z

z

z z

The num ber of act ive at t r ibut e variables support ed by t he im plem ent at ion has been exceeded. The num ber of act ive uniform variables support ed by t he im plem ent at ion has been exceeded. The main funct ion is m issing for t he vert ex shader or t he fragm ent shader. A varying variable act ually used in t he fragm ent shader is not declared wit h t he sam e t ype ( or is not declared at all) in t he vert ex shader.

z

A reference t o a funct ion or variable nam e is unresolved.

z

A shared global is declared wit h t w o different t ypes or t w o different init ial values.

z

One or m ore of t he at t ached shader obj ect s has not been successfully com piled.

z

Binding a generic at t ribut e m at rix caused som e rows of t he m at rix t o fall out side t he

allowed m axim um of GL_MAX_VERTEX_ATTRI BS. z

Not enough cont iguous vert ex at t ribut e slot s could be found t o bind at t ribut e m at rices.

The pr ogram obj ect 's inform at ion log is updat ed at t he t im e of t he link operat ion. I f t he link operat ion is successful, a program is generat ed. I t m ay cont ain an execut able for t he vert ex processor, an execut able for t he fragm ent processor, or bot h. Whet her t he link operat ion succeeds or fails, t he inform at ion and execut ables from t he previous link operat ion will be lost . Aft er t he link oper at ion, applicat ions are free t o m odify at t ached shader obj ect s, com pile at t ached shader obj ect s, det ach shader obj ect s, and at t ach addit ional shader obj ect s. None of t hese operat ions affect t he inform at ion log or t he program t hat is part of t he program obj ect unt il t he next link operat ion on t he program obj ect . I nform at ion about t he link operat ion can be obt ained by calling glGetProgramInfoLog ( described in Sect ion 7.6) wit h program. I f t he program obj ect was linked successfully, t he inform at ion log is eit her an em pt y st ring or cont ains infor m at ion about t he link operat ion. I f t he program obj ect was not linked successfully, t he inform at ion log cont ains inform at ion about any link er rors t hat occurred, along wit h warning m essages and any ot her inform at ion t he linker chooses t o provide. When t he link operat ion has com plet ed successfully, t he program it cont ains can be inst alled as part of t he current rendering st at e. The com m and t o inst all t he program as part of t he rendering st at e is void glUseProgram( GLuint program) I nst alls t he program obj ect specified by program as part of current rendering st at e. A program obj ect cont ains an execut able t hat will run on t he vert ex processor if it cont ains one or m ore shader obj ect s of t ype GL_VERTEX_SHADER t hat have been successfully com piled and linked. Sim ilarly, a pr ogram obj ect cont ains an execut able t hat w ill run on t he fragm ent processor if it cont ains one or m ore shader obj ect s of subt ype GL_FRAGMENT_SHADER t hat have been successfully com piled and linked. I f program cont ains shader obj ect s of t ype GL_VERTEX_SHADER but it does not cont ain shader obj ect s of t ype GL_FRAGMENT_SHADER, an execut able is inst alled on t he vert ex pr ocessor but fixed funct ionalit y is used for fragm ent processing. Sim ilarly, if program cont ains shader obj ect s of t ype GL_FRAGMENT_SHADER but it does not cont ain shader obj ect s of t ype GL_VERTEX_SHADER, an execut able is inst alled on t he fragm ent processor but fixed funct ionalit y is used for vert ex processing. I f program is 0, t he program m able processors are disabled, and fixed funct ionalit y is used for bot h vert ex and fragm ent processing.

Successfully inst alling an execut able on a program m able processor causes t he corresponding fixed funct ionalit y of OpenGL t o be disabled. Specifically, if an execut able is inst alled on t he vert ex processor, t he OpenGL fixed funct ionalit y is disabled as described in Sect ion 4.1. Sim ilarly, if an execut able is inst alled on t he fragm ent processor, t he OpenGL fixed funct ionalit y is disabled as described in Sect ion 4.2. While a program obj ect is in use, applicat ions are free t o m odify at t ached shader obj ect s, com pile at t ached shader obj ect s, at t ach addit ional shader obj ect s, det ach shader obj ect s, delet e any shader obj ect s at t ached, or delet e t he program obj ect it self. None of t hese operat ions affect t he execut ables t hat are part of t he current st at e. However, relinking t he program obj ect t hat is current ly in use inst alls t he program as part of t he current rendering st at e if t he link operat ion was successful. While a program obj ect is in use, t he st at e t hat cont rols t he disabled fixed funct ionalit y can also be updat ed wit h t he norm al OpenGL calls.

7.5. Cleaning Up Obj ect s should be delet ed when t hey are no longer needed, and delet ion can be accom plished wit h t he following com m ands void glDeleteShader( GLuint shader) Frees t he m em ory and invalidat es t he nam e associat ed wit h t he shader obj ect specified by shader. This com m and effect ively undoes t he effect s of a call t o glCreateShader. I f a shader obj ect t o be delet ed is at t ached t o a program obj ect , it will be flagged for delet ion, but it will not be delet ed unt il it is no longer at t ached t o any program obj ect for any rendering cont ext ( i.e., it m ust be det ached from w her ever it was at t ached before it can be delet ed) . A value of 0 for shader is silent ly ignored. To det erm ine whet her a shader obj ect has been flagged for delet ion, call glGetShader wit h argum ent s shader and GL_DELETE_STATUS.

void glDeleteProgram( GLuint program) Frees t he m em ory and invalidat es t he nam e associat ed wit h t he program obj ect specified by program. This com m and effect ively undoes t he effect s of a call t o glCreateProgram. I f a pr ogram obj ect is in use as part of a current rendering st at e, it will be flagged for delet ion, but it will not be delet ed unt il it is no longer part of current st at e for any rendering cont ext . I f a program obj ect t o be delet ed has shader obj ect s at t ached t o it , t hose shader obj ect s are aut om at ically det ached but not delet ed unless t hey have already been flagged for delet ion by a previous call t o glDeleteShader. To det erm ine whet her a program obj ect has been flagged for delet ion, call glGetProgram wit h argum ent s program and GL_DELETE_STATUS.

When a shader obj ect no longer needs t o be at t ached t o a program obj ect , it can be det ached wit h t he com m and void glDetachShader( GLuint program, GLuint shader) Det aches t he shader obj ect specified by shader from t he program obj ect specified by program. This com m and undoes t he effect of t he com m and glAttachShader. I f shader has already been flagged for delet ion by a call t o glDeleteShader and it is not at t ached t o any ot her program obj ect , it is delet ed aft er it has been det ached.

A program m ing t ip t hat m ight be useful in keeping t hings orderly is t o delet e shader obj ect s as soon as t hey have been at t ached t o a program obj ect . They won't be delet ed at t his t im e, but

t hey will be flagged for delet ion when t hey are no longer r eferenced. To clean up lat er, t he applicat ion only needs t o delet e t he program obj ect . All t he at t ached shader obj ect s will be aut om at ically det ached, and, because t hey are flagged for delet ion, t hey will be aut om at ically delet ed at t hat t im e as w ell.

7.6. Query Functions The OpenGL Shading Language API cont ains several funct ions for querying obj ect st at e. To obt ain inform at ion about a shader obj ect , use t he follow ing com m and: void glGetShaderiv( GLuint shader, GLenum pname, GLint * params) Ret urns in params t he value of a param et er for a specific shader obj ect . This funct ion ret urns inform at ion about a shader obj ect . Perm it t ed param et ers and t heir m eanings are described in Table 7.1. I n t his t able, t he value for pname is shown on t he left , and t he operat ion perform ed is show n on t he right .

Ta ble 7 .1 . Qu e r ia ble sh a de r obj e ct pa r a m e t e r s Pa r a m e t e r

Ope r a t ion

GL_SHADER_TYPE

params ret urns a value of eit her

GL_VERTEX_SHADER or GL_FRAGMENT_SHADER, depending on whet her shader is t he nam e of a vert ex shader obj ect or a fragm ent shader obj ect . GL_DELETE_STATUS

params ret urns GL_TRUE if shader is

current ly flagged for delet ion, and GL_FALSE ot herwise. GL_COMPI LE_STATUS

params ret urns GL_TRUE if t he last com pile operat ion on shader w as

successful, and GL_FALSE ot herwise. GL_I NFO_LOG_LENGTH

params ret urns t he num ber of charact ers in t he inform at ion log for shader, including

t he null t erm inat ion char act er. I f t he obj ect has no inform at ion log, a value of 0 is ret urned. GL_SHADER_SOURCE_LENGTH params ret urns t he lengt h of t he concat enat ion of t he source st rings t hat m ake up t he shader source for shader, including t he null t erm inat ion charact er. I f no source code exist s, 0 is ret urned.

A sim ilar funct ion is pr ovided for querying t he st at e of a program obj ect : t he st at us of an operat ion on a program obj ect , t he num ber of at t ached shader obj ect s, t he num ber of act ive at t ribut es ( see Sect ion 7.7) , t he num ber of act ive uniform variables ( see Sect ion 7.8) , or t he lengt h of any of t he st rings m aint ained by a program obj ect . The com m and t o obt ain infor m at ion about a program obj ect is void glGetProgramiv( GLuint program,

GLenum pname, GLint * params) Ret urns in params t he value of a param et er for a part icular program obj ect . This funct ion ret urns inform at ion about a program obj ect . Perm it t ed param et ers and t heir m eanings are described in Table 7.2. I n t his t able, t he value for pname is shown on t he left , and t he operat ion perform ed is shown on t he right .

Ta ble 7 .2 . Qu e r ia ble pr ogr a m obj e ct pa r a m e t e r s Pa r a m e t e r

Ope r a t ion

GL_DELETE_STATUS

params ret urns GL_TRUE if program

is current ly flagged for delet ion, and GL_FALSE ot herwise. GL_LI NK_STATUS

params ret urns GL_TRUE if t he last link operat ion on program w as

successful, and GL_FALSE ot herw ise. GL_VALI DATE_STATUS

params ret urns GL_TRUE if t he last validat ion operat ion on program

was successful, and GL_FALSE ot herw ise. GL_I NFO_LOG_LENGTH

params ret urns t he num ber of

charact ers in t he inform at ion log for program, including t he null t erm inat ion charact er. I f t he obj ect has no inform at ion log, a value of 0 is ret urned. GL_ATTACHED_SHADERS

params ret urns t he num ber of

shader obj ect s at t ached t o program.

GL_ACTI VE_ATTRI BUTES

params ret urns t he num ber of

act ive at t ribut e variables for program.

GL_ACTI VE_ATTRI BUTE_MAX_LENGTH params ret urns t he lengt h of t he longest act ive at t ribut e variable nam e for program, including t he null t erm inat ion charact er. I f no act ive at t ribut e variables exist , 0 is ret urned. GL_ACTI VE_UNI FORMS

params ret urns t he num ber of

act ive uniform variables for program.

GL_ACTI VE_UNI FORM_MAX_LENGTH

params ret urns t he lengt h of t he

longest act ive uniform variable nam e for program, including t he null t erm inat ion charact er. I f no act ive uniform variables exist , 0 is ret urned.

The com m and t o obt ain t he current shader st ring from a shader obj ect is void glGetShaderSource( GLuint shader GLsizei bufSize, GLsizei * length, GLchar * source) Ret urns a concat enat ion of t he source code st rings from t he shader obj ect specified by shader. The source code st rings for a shader obj ect are t he result of a previous call t o glShaderSource. The st ring ret urned by t he funct ion is null t erm inat ed. glGetShaderSource ret urns in source as m uch of t he source code st ring as it can, up t o a m axim um of bufSize charact ers. The num ber of charact ers

act ually ret urned, excluding t he null t erm inat ion charact er, is specified by length. I f t he lengt h of t he ret urned st ring is not required, a value of NULL can be passed in t he length argum ent . The size of t he buffer required t o

st ore t he ret urned source code st ring can be obt ained by calling glGetShader wit h t he value GL_SHADER_SOURCE_LENGTH.

I nform at ion about t he com pilat ion operat ion is st ored in t he inform at ion log for a shader obj ect . Sim ilarly, inform at ion about t he link and validat ion operat ions is st ored in t he inform at ion log for a program obj ect . The inform at ion log is a st ring t hat cont ains diagnost ic m essages and warnings. The inform at ion log m ay cont ain inform at ion useful during applicat ion developm ent even if t he com pilat ion or link operat ion was successful. The inform at ion log is t ypically only useful during applicat ion developm ent , and an applicat ion should not expect different OpenGL im plem ent at ions t o produce ident ical descript ions of er ror. To obt ain t he inform at ion log for a shader obj ect , call void glGetShaderInfoLog( GLuint shader, GLsizei maxLength, GLsizei * length, GLchar * infoLog) Ret urns t he inform at ion log for t he specified shader obj ect . The infor m at ion log for a shader obj ect is m odified when t he shader is com piled. The st ring t hat is ret urned is null t erm inat ed. glGetShaderInfoLog ret urns in infoLog as m uch of t he inform at ion log as it can, up t o a m axim um of maxLength charact ers. The num ber of charact ers

act ually ret urned, excluding t he null t erm inat ion charact er, is specified by length. I f t he lengt h of t he ret urned st ring is not required, a value of NULL can be passed in t he length argum ent . The size of t he buffer required t o st ore t he ret urned inform at ion log can be obt ained by calling glGetShader

wit h t he value GL_I NFO_LOG_LENGTH. The inform at ion log for a shader obj ect is a st ring t hat m ay cont ain diagnost ic m essages, warning m essages, and ot her inform at ion about t he last com pile operat ion. When a shader obj ect is creat ed, it s inform at ion log is a st ring of lengt h 0.

To obt ain t he inform at ion log for a program obj ect , call void glGetProgramInfoLog( GLuint program,

GLsizei maxLength, GLsizei * length, GLchar * infoLog) Ret urns t he inform at ion log for t he specified program obj ect . The infor m at ion log for a program obj ect is m odified w hen t he pr ogram obj ect is linked or validat ed. The st ring t hat is ret urned is null t erm inat ed. glGetProgramInfoLog ret urns in infoLog as m uch of t he inform at ion log as it can, up t o a m axim um of maxLength charact ers. The num ber of charact ers

act ually ret urned, excluding t he null t erm inat ion charact er, is specified by length. I f t he lengt h of t he ret urned st ring is not required, a value of NULL can be passed in t he length argum ent . The size of t he buffer required t o st ore t he ret urned inform at ion log can be obt ained by calling glGetProgram

wit h t he value GL_I NFO_LOG_LENGTH. The inform at ion log for a program obj ect is an em pt y st ring, a st ring cont aining inform at ion about t he last link oper at ion, or a st ring cont aining infor m at ion about t he last validat ion operat ion. I t m ay cont ain diagnost ic m essages, warning m essages, and ot her inform at ion. When a program obj ect is cr eat ed, it s inform at ion log is a st ring of lengt h 0.

The way t he API is set up, you first need t o perform a query t o find out t he lengt h of t he t he infor m at ion log ( num ber of char act ers in t he st ring) . Aft er allocat ing a buffer of t he appropriat e size, you can call glGetShaderInfoLog or glGetProgramInfoLog t o put t he inform at ion log st ring int o t he allocat ed buffer. You can t hen print it if you want t o do so. List ing 7.2 show s a C funct ion t hat does all t his for a shader obj ect . The code for obt aining t he inform at ion log for a program obj ect is alm ost ident ical.

List in g 7 .2 . C fu n ct ion t o pr in t t h e in for m a t ion log for a n obj e ct void printShaderInfoLog(GLuint shader) { int infologLen = 0; int charsWritten = 0; GLchar *infoLog; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infologLen); printOpenGLError(); // Check for OpenGL errors if (infologLen > 0) { infoLog = (GLchar*) malloc(infologLen); if (infoLog == NULL) { printf("ERROR: Could not allocate InfoLog buffer\n"); exit(1); } glGetShaderInfoLog(shader, infologLen, &charsWritten, infoLog); printf("InfoLog:\n%s\n\n", infoLog); free(infoLog); } printOpenGLError(); // Check for OpenGL errors }

You can obt ain t he program obj ect t hat is current ly in use by calling glGet wit h t he sym bolic

const ant GL_CURRENT_PROGRAM. The com m and t o query a list of shader obj ect s at t ached t o a part icular pr ogram obj ect is void glGetAttachedShaders( GLuint program, GLsizei maxCount, GLsizei * count, GLuint * shaders) Ret urns t he handles of t he shader obj ect s at t ached t o program. I t ret urns in shaders as m any of t he handles of t hese shader obj ect s as it can, up t o a m axim um of maxCount. The num ber of handles act ually ret urned is specified by count. I f t he num ber of handles act ually ret urned is not required ( for inst ance, if it has j ust been obt ained w it h glGetProgram) , a value of NULL m ay be passed for count. I f no shader obj ect s are at t ached t o program, a value of 0 is ret urned in count. The act ual num ber of at t ached shaders can be obt ained by calling glGetProgram wit h t he value GL_ATTACHED_SHADERS.

Tw o new funct ions have been added t o det erm ine whet her an obj ect is a shader obj ect or a program obj ect . These funct ions m ay be useful if you have t o process an obj ect ( for inst ance, t o print it s inform at ion log) wit hout knowing whet her it is a valid shader or program obj ect . These t w o funct ions ar e defined as GLboolean glIsShader( GLuint shader) Ret urns GL_TRUE if shader is t he nam e of a shader obj ect . I f shader is zero or a non- zero value t hat is not t he nam e of a shader obj ect , glIsShader ret urns GL_FALSE.

GLboolean glIsProgram( GLuint program) Ret urns GL_TRUE if program is t he nam e of a program obj ect . I f program is zer o or a non- zer o value t hat is not t he nam e of a program obj ect , glIsProgram ret urns GL_FALSE.

7.7. Specifying Vertex Attributes One way you can pass vert ex dat a t o OpenGL is by calling glBegin, followed by som e sequence of glColor/ glNormal/ glVertex/ et c. A call t o glEnd t erm inat es t his m et hod of specifying vert ex dat a. These calls cont inue t o work in t he OpenGL program m able environm ent . As before, a call t o glVertex indicat es t hat t he dat a for an individual vert ex is com plet e and should be pr ocessed. However, if a valid vert ex shader has been inst alled wit h glUseProgram, t he vert ex dat a is processed by t hat vert ex shader inst ead of by t he usual fixed funct ionalit y of OpenGL. A vert ex shader can use t he following built - in variables t o access t he st andard t ypes of vert ex dat a passed t o OpenGL: attribute attribute attribute attribute attribute attribute attribute . . . attribute

vec4 vec4 vec3 vec4 vec4 vec4 vec4

gl_Color; gl_SecondaryColor; gl_Normal; gl_Vertex; gl_MultiTexCoord0; gl_MultiTexCoord1; gl_MultiTexCoord2;

vec4 gl_FogCoord;

OpenGL's vert ex- at - a- t im e int erface is sim ple and powerful, but on t oday's syst em s it is definit ely not t he highest - perform ance way of t ransferring vert ex dat a t o t he graphics accelerat or. Whenever possible, applicat ions should use t he vert ex array int erface inst ead. This int erface allow s you t o st ore vert ex dat a in arrays and set point ers t o t hose arrays. I nst ead of sending one vert ex at a t im e t o OpenGL, you can send a whole set of prim it ives at a t im e. Wit h vert ex buffer obj ect s, it is even possible t hat vert ex arrays are st ored in m em ory on t he graphics board t o exact m axim um perform ance. The vert ex array int erface also works t he sam e way in t he OpenGL program m able environm ent as it did previously. When a vert ex array is sent t o OpenGL, t he vert ex dat a in t he vert ex array is processed one vert ex at a t im e, j ust like t he vert ex- at - a- t im e int erface. I f a vert ex shader is act ive, each vert ex is processed by t he vert ex shader rat her t han by t he fixed funct ionalit y of OpenGL. However, t he brave new world of program m abilit y m eans t hat applicat ions no longer need t o be lim it ed t o t he st andard at t ribut es defined by OpenGL. There are m any addit ional per - ver t ex at t ribut es t hat applicat ions m ight like t o pass int o a vert ex shader. I t is easy t o im agine t hat applicat ions will want t o specify per- vert ex dat a such as t angent s, t em perat ure, pressure, and who know s w hat else. How do w e allow applicat ions t o pass nont radit ional at t ribut es t o OpenGL and operat e on t hem in vert ex shaders? The answer is t hat OpenGL provides a sm all num ber of generic locat ions for passing in vert ex at t ribut es. Each locat ion is num bered and has room t o st ore up t o four float ing- point com ponent s ( i.e., it is a ve c4 ) . An im plem ent at ion t hat support s 16 at t ribut e locat ions will have t hem num bered fr om 0 t o 15. An applicat ion can pass a vert ex at t ribut e int o any of t he generic num bered slot s by using one of t he following funct ions: void glVertexAttrib{1|2|3|4}{s|f|d}( GLuint index, TYPE v) void glVertexAttrib{1|2|3}{s|f|d}v( GLuint index, const TYPE * v) void glVertexAttrib4{b|s|i|f|d|ub|us|ui}v( GLuint index, const TYPE * v) Set s t he generic vert ex at t ribut e specified by index t o t he value specified by v. This com m and can have up t o t hree suffixes t hat different iat e

variat ions of t he param et ers accept ed. The first suffix can be 1, 2, 3, or 4 t o specify w het her v cont ains 1, 2, 3, or 4 com ponent s. I f t he second and t hir d com ponent s are not provided, t hey are assum ed t o be 0, and if t he fourt h com ponent is not provided, it is assum ed t o be 1. The second suffix indicat es t he dat a t ype of v and m ay specify byt e ( b) , short ( s) , int ( i) , float ( f) , double ( d) , unsigned byt e ( ub) , unsigned short ( us) , or unsigned int ( ui) . The t hir d suffix is an opt ional v m eaning t hat v is a point er t o an array of values of t he specified dat a t ype.

This set of com m ands has a cert ain set of rules for convert ing dat a t o t he float ing- point int ernal represent at ion specified by OpenGL. Float s and doubles are m apped int o OpenGL int ernal float ing- point values as you would expect , and int eger values are convert ed t o float s by a decim al point added t o t he right of t he value provided. Thus, a value of 27 for a byt e, int , short , unsigned byt e, unsigned int , or unsigned short becom es a value of 27.0 for com put at ion wit hin OpenGL. Anot her set of ent ry point s support s t he passing of norm alized values as generic vert ex at t ribut es: void glVertexAttrib4Nub( GLuint index, TYPE v) void glVertexAttrib4N{b|s|i|f|d|ub|us|ui}v( GLuint index, const TYPE * v) Set s t he generic vert ex at t ribut e specified by index t o t he norm alized value specified by v. I n addit ion t o N ( t o indicat e norm alized values) , t his com m and can have t wo suffixes t hat differ ent iat e variat ions of t he param et ers accept ed. The first suffix indicat es t he dat a t ype of v and specifies byt e ( b) , short ( s) , int ( i) , float ( f) , double ( d) , unsigned byt e ( ub) , unsigned short ( us) , or unsigned int ( ui) . The second suffix is an opt ional v m eaning t hat v is a point er t o an array of values of t he specified dat a t ype.

N in a com m and nam e indicat es t hat , for dat a t ypes ot her t han float or double, t he ar gum ent s

will be linearly m apped t o a norm alized range in t he sam e way as dat a provided t o t he int eger variant s of glColor or glNormalt hat is, for signed int eger variant s of t he funct ions, t he m ost posit ive, represent able value m aps t o 1.0, and t he m ost negat ive represent able value m aps t o 1.0. For t he unsigned int eger variant s, t he largest r epresent able value m aps t o 1.0, and t he sm allest represent able value m aps t o 0. At t ribut e variables are allowed t o be of t ype m a t 2 , m a t 3 , or m a t 4 . At t ribut es of t hese t ypes can be loaded wit h t he glVertexAttrib ent ry point s. Mat rices m ust be loaded int o successive generic at t ribut e slot s in colum n m aj or order, wit h one colum n of t he m at rix in each generic at t ribut e slot . Thus, t o load a m a t 4 at t ribut e, you would load t he first colum n in generic at t ribut e slot i, t he second in slot i + 1, t he t hird in slot i + 2, and t he fourt h in slot i + 3. Wit h one except ion, generic vert ex at t ribut es are j ust t hat generic. They pass addit ional color values, t angent s, binorm als, dept h values, or anyt hing. The except ion is t hat t he generic vert ex at t ribut e wit h index 0 indicat es t he com plet ion of a vert ex j ust like a call t o glVertex. A glVertex2, glVertex3, or glVertex4 com m and is com plet ely equivalent t o t he corresponding glVertexAttrib com m and w it h an index argum ent of 0. There are no current values for generic vert ex at t ribut e 0 ( an error is generat ed if you at t em pt t o query it s current value) . This is t he only generic ver t ex at t ribut e w it h t his pr opert y; calls t o set ot her st andard vert ex at t r ibut es can be freely m ixed wit h calls t o set any of t he ot her gener ic vert ex at t ribut es. You are also free t o m ix calls t o glVertex and glVertexAttrib w it h index 0.

The vert ex array API has been sim ilarly ext ended t o allow generic vert ex at t ribut es t o be specified as vert ex arrays. The following call est ablishes t he vert ex array point er for a generic vert ex at t ribut e: void glVertexAttribPointer( GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid * pointer) Specifies t he locat ion and dat a form at of an array of generic vert ex at t ribut e values t o use w hen rendering. The generic vert ex at t r ibut e array t o be specified is indicat ed by index. size specifies t he num ber of com ponent s per at t r ibut e and m ust be 1, 2, 3, or 4. type specifies t he dat a t ype of each com ponent ( GL_BYTE, GL_UNSI GNED_BYTE, GL_SHORT, GL_UNSI GNED_SHORT, GL_I NT, GL_UNSI GNED_I NT, GL_FLOAT, or GL_DOUBLE) . stride specifies t he byt e st ride from one at t ribut e t o t he next , allowing at t ribut e values t o be int erm ixed wit h ot her at t ribut e values or st ored in a separat e array. A value of 0 for stride m eans t hat t he values ar e st ored sequent ially in m em ory wit h no gaps bet ween successive elem ent s. I f set t o GL_TRUE, normalize specifies t hat values st ored in an int eger form at are t o be m apped t o t he range [ 1.0,1.0] ( for signed values) or [ 0.0,1.0] ( for unsigned values) when t hey are accessed and convert ed t o float ing point . Ot herwise, values are convert ed t o float s direct ly wit hout norm alizat ion. pointer is t he m em ory addr ess of t he first gener ic vert ex at t ribut e in t he ver t ex array.

Aft er t he vert ex arr ay inform at ion has been specified for a generic vert ex at t ribut e array, t he array needs t o be enabled. When enabled, t he generic vert ex at t ribut e dat a in t he specified array is provided along wit h ot her enabled vert ex array dat a when vert ex array draw ing com m ands such as glDrawArrays are called. To enable or disable a generic vert ex at t ribut e array, use t he com m ands void glEnableVertexAttribArray( GLuint index) void glDisableVertexAttribArray( GLuint index) Enables or disables t he generic vert ex at t ribut e array specified by index. By default , all client - side capabilit ies are disabled, including all generic ver t ex at t ribut e arr ays. I f enabled, t he values in t he generic vert ex at t ribut e array are accessed and used for rendering when calls are m ade t o vert ex array com m ands such as glArrayElement, glDrawArrays, glDrawElements, glDrawRangeElements, glMultiDrawArrays, or glMultiDrawElements.

This solves t he quest ion of how generic vert ex dat a is passed int o OpenGL, but how do we access t hat dat a from wit hin a vert ex shader? We don't want t o refer t o t hese num bered locat ions in our shader, because t his approach is not very descript ive and is pr one t o errors. The OpenGL Shading Language API provides t wo ways for associat ing generic vert ex indices wit h ver t ex shader at t ribut e variables. The first way is t o let t he linker assign t he bindings aut om at ically. I n t his case, t he applicat ion would need t o query OpenGL aft er linking t o det erm ine t he generic vert ex indices t hat were assigned and t hen would use t hese indices w hen passing t he at t r ibut es t o OpenGL. The second way is for t he applicat ion t o choose t he index value of t he generic vert ex at t r ibut e t o be used and explicit ly bind it t o a specific at t r ibut e variable in t he ver t ex shader by using t he

following funct ion before linking occurs: void glBindAttribLocation( GLuint program, GLuint index, const GLchar * name) Associat es a user - defined at t ribut e var iable in t he program obj ect specified by program wit h a generic vert ex at t ribut e index. The nam e of t he user- defined at t ribut e variable is passed as a null t erm inat ed st ring in name. I f name was bound previously, t hat inform at ion is lost . Thus, you cannot bind one user- defined at t ribut e variable t o m ult iple indices, but you can bind m ult iple user- defined at t ribut e variables t o t he sam e index. The generic vert ex at t ribut e index t o be bound t o t his variable is specified by index. When program is m ade part of cur rent st at e, values provided t hrough t he generic vert ex at t ribut e index m odify t he value of t he user defined at t ribut e variable specified by name. I f name refers t o a m at rix at t ribut e variable, index refer s t o t he first colum n of t he m at rix. Ot her m at rix colum ns are t hen aut om at ically bound t o locat ions index+1 for a m at rix of t ype mat2; index+1 and index+2 for a m at rix of t ype mat3; and index+1, index+2, and index+3 for a m at rix of t ype mat4. Applicat ions are not allowed t o bind any of t he st andard OpenGL vert ex at t ribut es wit h t his com m and because t hey are bound aut om at ically when needed. Any at t ribut e binding t hat occurs aft er t he pr ogram obj ect has been linked does not t ake effect unt il t he next t im e t he program obj ect is linked.

glBindAttribLocation can be called before any vert ex shader obj ect s are at t ached t o t he specified

program obj ect . I t is also perm issible t o bind an at t ribut e variable nam e t hat is never used in a vert ex shader t o a generic at t ribut e index. Applicat ions are allowed t o bind m ore t han one vert ex shader at t ribut e nam e t o t he sam e generic vert ex at t ribut e index. This is called ATTRI BUTE ALI ASI NG, and it is allowed only if j ust one of t he aliased at t ribut es is act ive in t he execut able program or if no pat h t hrough t he shader consum es m ore t han one at t ribut e of a set of at t ribut es aliased t o t he sam e locat ion. Anot her way of saying t his is t hat m ore t han one at t ribut e nam e m ay be bound t o a generic at t ribut e index if, in t he end, only one nam e is used t o access t he generic at t ribut e in t he vert ex shader. The com piler and linker are allowed t o assum e t hat no aliasing is done and are fr ee t o em ploy opt im izat ions t hat work only in t he absence of aliasing. OpenGL im plem ent at ions are not required t o do error checking t o det ect at t ribut e aliasing. Because t here is no w ay t o bind st andard at t ribut es, it is not possible t o alias generic at t ribut es wit h convent ional ones. The binding bet ween an at t ribut e variable nam e and a generic at t ribut e index can be specified at any t im e w it h glBindAttribLocation. At t ribut e bindings do not go int o effect unt il glLinkProgram is called, so any at t r ibut e variables t hat need t o be bound explicit ly for a part icular use of a shader should be bound before t he link operat ion occurs. Aft er a program obj ect has been linked successfully, t he index values for at t ribut e variables rem ain fixed ( and t heir values can be queried) unt il t he next link com m and occurs. To query t he at t ribut e binding for a nam ed ver t ex shader at t ribut e variable, use glGetAttribLocation. I t ret urns t he binding t hat act ually went int o effect t he last t im e glLinkProgram was called for t he specified program obj ect . At t ribut e bindings t hat have been specified since t he last link operat ion are not ret urned by glGetAttribLocation. GLint glGetAttribLocation( GLuint program, const GLchar * name)

Queries t he previously linked program obj ect specified by program for t he at t ribut e variable specified by name and ret urns t he index of t he generic vert ex at t ribut e t hat is bound t o t hat at t ribut e variable. I f name is a m at rix at t ribut e variable, t he index of t he first colum n of t he m at rix is ret urned. I f t he nam ed at t ribut e variable is not an act ive at t ribut e in t he specified program obj ect or if name st art s wit h t he reserved prefix " gl_" , a value of 1 is ret urned.

Using t hese funct ions, we can creat e a vert ex shader t hat cont ains a user- defined at t ribut e variable nam ed Opacity t hat is used direct ly in t he light ing calculat ions. We can decide t hat we want t o pass per- vert ex opacit y values in generic at t ribut e locat ion 1 and set up t he pr oper binding wit h t he following line of code: glBindAttribLocation(myProgram, 1, "Opacity");

Subsequent ly, w e can call glVertexAttrib t o pass an opacit y value at every vert ex: glVertexAttrib1f(1, opacity);

The glVertexAttrib calls are all designed for use bet ween glBegin and glEnd. As such, t hey offer replacem ent s for t he st andard OpenGL calls such as glColor, glNormal, and so on. But as we have already point ed out , vert ex arrays should be used if graphics perform ance is a concern. The j argon in t his sect ion can get a lit t le confusing, so let 's look at a diagr am t o m ake sure w e have t hings st raight . Figur e 7.1 illust r at es how com m ands t o set st andard vert ex at t ribut es m odify t he values of built - in at t ribut e variables defined by t he OpenGL Shading Language. The m appings bet ween com m ands t o set st andard at t ribut es ( color, norm al, vert ex, et c.) and t he built - in at t ribut e variables ( gl_Color, gl_Normal, gl_Vertex, et c.) are done aut om at ically, and t hey are done in a way t hat doesn't conflict wit h t he use of any generic at t ribut e locat ion t hat will be used. Each of t hese calls except glVertex also set s t he current st at e for t hat at t ribut e. ( The value provided in a call t o glVertex is never saved as part of current st at e.) The value for a built - in at t ribut e variable is aut om at ically updat ed when a call is m ade t o set t he value of t he corresponding st andard vert ex at t ribut e.

Figu r e 7 .1 . M a ppin g of st a n da r d ve r t e x a t t r ibu t e com m a n ds t o bu ilt - in a t t r ibu t e va r ia ble s [View full size image]

Now let 's look at t he case of generic vert ex at t ribut es as illust rat ed in Figur e 7.2. A user- defined at t ribut e variable m ust be bound t o a generic vert ex at t ribut e index. This binding can be done wit h glBindAttribLocation, or it can happen im plicit ly at link t im e.

Figu r e 7 .2 . M a ppin g of ge n e r ic ve r t e x a t t r ibu t e com m a n ds t o u se r de fin e d a t t r ibu t e va r ia ble s

Let 's assum e we have a vert ex shader t hat uses t hree user- defined at t ribut e variables: Opacity, Binormal, and MyData. These are shown on t he right side of Figur e 7.2. These user- defined at t ribut e variables can each be bound t o a generic vert ex at t ribut e index as follows: glBindAttribLocation(myProgram, 1, "Opacity"); glBindAttribLocation(myProgram, 2, "Binormal"); glBindAttribLocation(myProgram, 3, "MyData");

This set s up t he m apping so t hat values writ t en int o generic vert ex at t ribut e locat ions 1, 2, and 3 will m odify t he values of t he at t ribut e variables Opacity, Binormal, and MyData in t he vert ex shader. Generic vert ex at t ribut e 0 can be bound t o a user- defined at t ribut e variable, or it s value can be obt ained t hrough t he built - in at t ribut e variable gl_Vertex. The diagram shows t hat generic

vert ex at t ribut e index N is not current ly bound t o any user- defined at t ribut e variable. As m ent ioned, each of t he generic at t ribut e locat ions has enough room for four float ing- point com ponent s. Applicat ions are perm it t ed t o st ore 1, 2, 3, or 4 com ponent s in each locat ion. A vert ex shader m ay access a single locat ion by using a user- defined at t ribut e var iable t hat is a floa t , a ve c2 , a ve c3 , or a ve c4 . I t m ay access t wo consecut ive locat ions by using a userdefined at t ribut e variable t hat is a m a t 2 , t hree using a m a t 3 , and four using a m a t 4 . The bindings bet ween generic at t ribut e index values and user- defined at t ribut e variables ( i.e., t he arrows on t he right side of Figur e 7.2) are part of t he st at e m aint ained wit hin a program obj ect , whereas t he cont ent s of t he at t ribut e array it self is considered current at t ribut e st at e ( except for t he generic vert ex at t ribut e wit h index 0) . The applicat ion can provide a different program obj ect and specify different nam es and m appings for at t ribut e variables in t he vert ex shader, and if no calls have been m ade t o updat e t he at t r ibut e values in t he int erim , t he at t ribut e variables in t he new vert ex shader get t he values left behind by t he previous one. At t ribut e variables t hat can be accessed when a vert ex shader is execut ed are called ACTI VE To obt ain inform at ion about an act ive at t ribut e, use t he following com m and:

ATTRI BUTES.

void glGetActiveAttrib( GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, GLchar * name) Ret urns inform at ion about an act ive at t ribut e variable in t he program obj ect specified by program. The num ber of act ive at t ribut es in a program obj ect can be obt ained by calling glGetProgram wit h t he value GL_ACTI VE_ATTRI BUTES. A value of 0 for index causes inform at ion about t he first act ive at t ribut e variable t o be ret urned. Perm issible values for index range from 0 t o t he num ber of act ive at t ribut es m inus 1. A vert ex shader can use built - in at t ribut e var iables, user - defined at t ribut e variables, or bot h. Built - in at t ribut e variables have a prefix of " gl_" and reference convent ional OpenGL vert ex at t r ibut es ( e.g., gl_Vertex, gl_Normal, et c.; see Sect ion 4.1.1 for a com plet e list .) User- defined at t ribut e variables have arbit r ary nam es and obt ain t heir values t hrough num bered generic vert ex at t ribut es. An at t ribut e variable ( eit her built - in or userdefined) is considered act ive if it is det erm ined during t he link operat ion t hat it can be accessed during program execut ion. Therefore, program should have previously been t he t arget of a call t o glLinkProgram, but it is not necessary for it t o have been linked successfully. The size of t he charact er buffer needed t o st ore t he longest at t ribut e variable nam e in program can be obt ained by calling glGetProgram w it h t he value GL_ACTI VE_ATTRI BUTE_MAX_LENGTH. This value should be used t o allocat e a buffer of sufficient size t o st ore t he ret urned at t ribut e nam e. The size of t his charact er buffer is passed in bufSize, and a point er t o t his charact er buffer is passed in name. glGetActiveAttrib ret urns t he nam e of t he at t r ibut e variable indicat ed by index, st oring it in t he charact er buffer specified by name. The st ring

ret urned is null t erm inat ed. The act ual num ber of charact ers writ t en int o t his buffer is ret urned in length, and t his count does not include t he null t erm inat ion charact er. I f t he lengt h of t he ret urned st ring is not required, a value of NULL can be passed in t he length argum ent .

The type argum ent ret urns a point er t o t he at t ribut e variable's dat a t ype. The sym bolic const ant s GL_FLOAT, GL_FLOAT_VEC2, GL_FLOAT_VEC3, GL_FLOAT_VEC4, GL_FLOAT_MAT2, GL_FLOAT_MAT3, and GL_FLOAT_MAT4 m ay be ret urned. The size argum ent ret urns t he size of t he at t ribut e in unit s of t he t ype ret urned in type. The list of act ive at t ribut e variables m ay include bot h built - in at t ribut e variables ( w hich begin wit h t he prefix " gl_" ) as well as user- defined at t ribut e variable nam es. This funct ion ret urns as m uch inform at ion as it can about t he specified act ive at t ribut e variable. I f no infor m at ion is available, length is 0 and name is an em pt y st ring. This sit uat ion could occur if t his funct ion is called aft er a link operat ion t hat failed. I f an error occurs, t he ret urn values length, size, type, and name are unm odified.

The glGetActiveAttrib com m and can be useful in an environm ent in w hich shader developm ent occurs separat ely fr om applicat ion developm ent . I f som e at t ribut e- nam ing convent ions are agr eed t o bet ween t he shader writ ers and t he applicat ion developers, t he lat t er could query t he program obj ect at runt im e t o det erm ine t he at t ribut es t hat are act ually needed and could pass t hose down. This approach can provide m ore flexibilit y in t he shader developm ent process. To query t he st at e of a part icular generic vert ex at t ribut e, call one of t he following com m ands: void glGetVertexAttribfv( GLuint index, GLenum pname, GLfloat * params) void glGetVertexAttribiv( GLuint index, GLenum pname, GLint * params) void glGetVertexAttribdv( GLuint index, GLenum pname, GLdouble * params) Ret urns in params t he value of a generic vert ex at t ribut e param et er. The generic vert ex at t ribut e t o be queried is specified by index, and t he param et er t o be queried is specified by pname. Param et ers and ret urn values ar e sum m arized in Table 7.3. All t he param et ers except GL_CURRENT_VERTEX_ATTRI B represent client - side st at e.

Ta ble 7 .3 . Ge n e r ic ve r t e x a t t r ibu t e pa r a m e t e r s Pa r a m e t e r

Ope r a t ion

GL_VERTEX_ATTRI B_ARRAY_ENABLED

params ret urns a single value

t hat is non- zero ( t rue) if t he vert ex at t ribut e array for index is enabled and 0 ( false) if it is disabled. The init ial value is GL_FALSE. GL_VERTEX_ATTRI B_ARRAY_SI ZE

params ret urns a single value,

t he size of t he vert ex at t ribut e array for index. The size is t he num ber of values for each elem ent of t he ver t ex at t ribut e arr ay, and it

is 1, 2, 3, or 4. The init ial value is 4. GL_VERTEX_ATTRI B_ARRAY_STRI DE

params ret urns a single value,

t he array st ride ( num ber of byt es bet w een successive elem ent s) for t he vert ex at t ribut e array for index. A value of 0 indicat es t hat t he array elem ent s are st ored sequent ially in m em ory. The init ial value is 0. GL_VERTEX_ATTRI B_ARRAY_TYPE

params ret urns a single value,

a sym bolic const ant indicat ing t he array t ype for t he vert ex at t r ibut e ar ray for index. Possible values are GL_BYTE, GL_UNSI GNED_BYTE, GL_SHORT, GL_UNSI GNED_SHORT, GL_I NT, GL_UNSI GNED_I NT, GL_FLOAT, and GL_DOUBLE. The init ial value is GL_FLOAT. GL_VERTEX_ATTRI B_ARRAY_NORMALI ZED params ret urns a single value t hat is nonzero ( t rue) if fixed- point dat a t ypes for t he vert ex at t ribut e array indicat ed by index are norm alized w hen t hey are convert ed t o float ing point and 0 ( false) ot her wise. The init ial value is GL_FALSE. GL_CURRENT_VERTEX_ATTRI B

params ret urns four values

t hat represent t he current value for t he generic vert ex at t ribut e specified by index. Generic vert ex at t ribut e 0 is unique in t hat it has no current st at e, so an error is gener at ed if index is 0. The init ial value for all ot her gener ic vert ex at t ribut es is ( 0, 0, 0, 1) .

void glGetVertexAttribPointerv( GLuint index, GLenum pname, GLvoid * * pointer) Ret urns point er inform at ion. index is t he generic vert ex at t ribut e t o be queried, pname is a sym bolic const ant specifying t he point er t o be

ret urned, and params is a point er t o a locat ion in which t o place t he ret urned dat a. The only accept ed value for pname is GL_VERTEX_ATTRI B_ARRAY_POI NTER. This causes params t o ret urn a single value t hat is a point er t o t he vert ex at t ribut e array for t he generic vert ex at t ribut e specified by index.

7.8. Specifying Uniform Variables As described in t he previous sect ion, at t ribut e variables provide frequent ly m odified dat a t o t he vert ex shader. Less frequent ly changing dat a can be specified using uniform variables. Uniform variables are declared wit hin a shader and can be loaded direct ly by t he applicat ion. This let s applicat ions provide any t ype of arbit rary dat a t o a shader . Applicat ions can m odify t hese values as oft en as every prim it ive in order t o m odify t he behavior of t he shader ( alt hough perform ance m ay suffer if t his is done) . Typically, uniform variables are used t o supply st at e t hat st ays const ant for m any prim it ives. The OpenGL Shading Language also defines a num ber of built - in variables t hat t rack OpenGL st at e. Applicat ions can cont inue using OpenGL t o m anage st at e t hrough exist ing OpenGL calls and can use t hese built - in uniform variables in cust om shaders. Of course, if you want som et hing t hat isn't already support ed direct ly by OpenGL, it is a sim ple m at t er t o define your own uniform variable and supply t he value t o your shader. When a program obj ect is m ade current , built - in uniform variables t hat t rack OpenGL st at e ar e init ialized t o t he current value of t hat OpenGL st at e. Subsequent calls t hat m odify an OpenGL st at e value cause t he built - in uniform var iable t hat t racks t hat st at e value t o be updat ed as well. The basic m odel for specifying uniform variables is different from t he m odel for specifying at t ribut e variables. As discussed in t he preceding sect ion, for at t ribut e variables, t he applicat ion can specify t he at t ribut e locat ion before linking occurs. I n cont rast , t he locat ions of uniform variables cannot be specified by t he applicat ion. I nst ead, t hey are always det erm ined by OpenGL at link t im e. As a result , applicat ions always need t o query t he uniform locat ion aft er linking occurs. To updat e t he value of a user- defined uniform variable, an applicat ion needs t o det erm ine it s locat ion and t hen specify it s value. The locat ions of uniform variables are assigned at link t im e and do not change unt il t he next link operat ion occurs. Each t im e linking occurs, t he locat ions of uniform variables m ay change, and so t he applicat ion m ust query t hem again before set t ing t hem . The locat ions of t he user - defined uniform variables in a program obj ect can be queried wit h t he following com m and:

GLint glGetUniformLocation( GLuint program, const GLchar * name) Ret urns an int eger t hat represent s t he locat ion of a specific uniform variable wit hin a program obj ect . name m ust be a null t erm inat ed st ring t hat cont ains no whit e space. name m ust be an act ive uniform variable nam e in program t hat is not a st ruct ure, an array of st ruct ures, or a subcom ponent of a vect or or a m at r ix. This funct ion ret urns 1 if name does not correspond t o an act ive uniform variable in program or if name st art s wit h t he reserved prefix " gl_" . Uniform variables t hat are st ruct ur es or arrays of st ruct ures can be queried wit h glGetUniformLocation for each field wit hin t he st ruct ure. The array elem ent operat or " [ ] " and t he st ruct ure field operat or " ." can be used in name t o select elem ent s w it hin an array or fields wit hin a st ruct ure. The r esult of using t hese operat ors is not allowed t o be anot her st ruct ure, an array of st ruct ures, or a subcom ponent of a vect or or a m at r ix. Except if t he last part of name indicat es a uniform variable array, t he locat ion of t he first elem ent of an array can be ret rieved wit h t he

nam e of t he array or wit h t he nam e appended by " [ 0] " . The act ual locat ions assigned t o uniform variables are not known unt il t he program obj ect is linked successfully. Aft er linking has occurred, t he com m and glGetUniformLocation can obt ain t he locat ion of a uniform variable. This locat ion value can t hen be passed t o glUniform t o set t he value of t he uniform variable or t o glGetUniform in order t o query t he current value of t he uniform variable. Aft er a program obj ect has been linked successfully, t he index values for uniform variables rem ain fixed unt il t he next link com m and occurs. Uniform variable locat ions and values can only be queried aft er a link if t he link was successful.

Loading of user- defined uniform values is only possible for t he program obj ect t hat is current ly in use. All user- defined uniform variables ar e init ialized t o 0 when a pr ogram obj ect is successfully linked. User- defined uniform values are part of t he st at e of a program obj ect . Their values can be m odified only when t he program obj ect is part of current rendering st at e, but t he values of uniform variables are preserved as t he program obj ect is swapped in and out of current st at e. The following com m ands load uniform variables int o t he program obj ect t hat is current ly in use: void glUniform{1|2|3|4}{f|i}( GLint location, TYPE v) Set s t he user- defined uniform variable or uniform variable array specified by location t o t he value specified by v. The suffix 1, 2, 3, or 4 indicat es whet her v cont ains 1, 2, 3, or 4 com ponent s. This value should m at ch t he num ber of com ponent s in t he dat a t ype of t he specified uniform variable ( e.g., 1 for floa t , in t , bool; 2 for ve c2 , iv e c2 , bve c2 , et c.) . The suffix f indicat es t hat float ing- point values are being passed, and t he suffix i indicat es t hat int eger values are being passed; t his t ype should also m at ch t he dat a t ype of t he specified uniform variable. The i variant s of t his funct ion should be used t o provide values for uniform variables defined as in t , iv e c2 , iv e c3 , and iv e c4 , or arrays of t hese. The f variant s should be used t o provide values for uniform variables of t ype floa t , ve c2 , ve c3 , or ve c4 , or arrays of t hese. Eit her t he i or t he f variant s can be used t o provide values for uniform variables of t ype bool, bve c2 , bve c3 , and bve c4 or arrays of t hese. The uniform variable is set t o fa lse if t he input value is 0 or 0.0f, and it is set t o t r u e ot herwise.

void glUniform{1|2|3|4}{f|i}v( GLint location, GLuint count, const TYPE v) Set s t he user- defined uniform variable or uniform variable array specified by location t o t he values specified by v. These com m ands pass a count and a point er t o t he values t o be loaded int o a uniform variable or a uniform variable array. A count of 1 should be used for m odifying t he value of a single uniform variable, and a count of 1 or great er can be used t o m odify an array. The num ber specified in t he nam e of t he com m and specifies t he num ber of com ponent s for each elem ent in v, and it should m at ch t he num ber of com ponent s in t he dat a t ype of t he specified uniform variable ( e.g., 1 for floa t , in t , bool; 2 for ve c2 , iv e c2 , bve c2 , et c.) . The v in t he com m and nam e indicat es t hat a point er t o a vect or of values is being passed. The f and i suffixes are defined in t he sam e way as for t he nonvect or variant s of glUniform.

For uniform variable arrays, each elem ent of t he array is considered t o be of t he t ype indicat ed in t he nam e of t he com m and ( e.g., glUniform3f or glUniform3fv can be used t o load a uniform variable ar ray of t ype ve c3 ) . The num ber of elem ent s of t he uniform variable array t o be m odified is specified by count.

void glUniformMatrix{2|3|4}fv( GLint location, GLuint count, GLboolean transpose, const GLfloat * v) Set s t he user- defined uniform m at rix variable or uniform m at rix array variable specified by location t o t he values specified by v. The num ber in t he com m and nam e is int erpret ed as t he dim ensionalit y of t he m at r ix. The num ber 2 indicat es a 2 x 2 m at rix ( i.e., 4 values) , t he num ber 3 indicat es a 3 x 3 m at rix ( i.e., 9 values) , and t he num ber 4 indicat es a 4 x 4 m at rix ( i.e., 16 values) . I f transpose is GL_FALSE, each m at rix is assum ed t o be supplied in colum n m aj or order. I f t ranspose is GL_TRUE, each m at r ix is assum ed t o be supplied in row m aj or order. The count argum ent specifies t he num ber of m at rices t o be passed. A count of 1 should be used for m odifying t he value of a single m at rix, and a count great er t han 1 can be used t o m odify an array of m at r ices.

glUniform1i and glUniform1iv are t he only t wo funct ions t hat can be used t o load uniform variables defined as sam pler t ypes ( see Sect ion 7.9) . At t em pt ing t o load a sam pler wit h any ot her funct ion result s in an error.

Errors can also be generat ed by glUniform for any of t he follow ing r easons: z

I f t here is no current progr am obj ect

z

I f location is an invalid uniform variable locat ion for t he current program obj ect

z

z

I f t he num ber of values specified by count would exceed t he declared ext ent of t he indicat ed uniform variable or uniform variable array Ot her t han t he preceding except ions not ed, if t he t ype and size of t he uniform var iable as defined in t he shader do not m at ch t he t ype and size specified in t he nam e of t he com m and used t o load it s value

I n all of t hese cases, t he indicat ed uniform variable will not be m odified. When t he locat ion of a user- defined uniform variable has been det erm ined, t he following com m and can be used t o query it s current value: void glGetUniformfv( GLuint program, GLint location, GLfloat * params) void glGetUniformiv( GLuint program, GLint location, GLint * params) Ret urn in params t he value( s) of t he specified uniform variable. The t ype of t he uniform variable specified by location det erm ines t he num ber of values

ret urned. I f t he uniform variable is defined in t he shader as a bool, in t , or floa t , a single value is ret urned. I f it is defined as a ve c2 , iv e c2 , or bve c2 , t w o values are ret urned. I f it is defined as a ve c3 , iv e c3 , or bve c3 , t hree values are ret urned, and so on. To query values st ored in uniform variables declared as arrays, call glGetUniform for each elem ent of t he array. To query values st ored in uniform variables declared as st ruct ures, call glGetUniform for each field in t he st ruct ure. The values for uniform variables declared as a m at rix are ret urned in colum n m aj or order. The locat ions assigned t o uniform variables are not know n unt il t he program obj ect is linked. Aft er linking has occurred, t he com m and glGetUniformLocation can obt ain t he locat ion of a uniform variable. This locat ion value can t hen be passed t o glGetUniform t o query t he current value of t he uniform variable. Aft er a program obj ect has been linked successfully, t he index values for uniform variables rem ain fixed unt il t he next link com m and occurs. The uniform variable values can only be queried aft er a link if t he link was successful.

The locat ion of a uniform variable cannot be used for anyt hing ot her t han specifying or quer ying t hat part icular uniform variable. Say you declare a uniform variable as a st ruct ure t hat has t hree fields in succession t hat are defined as float s. I f you call glGetUniformLocation t o det erm ine t hat t he first of t hose t hree float s is at locat ion n, do not assum e t hat t he next one is at locat ion n + 1. I t is possible t o query t he locat ion of t he it h elem ent in an array. That value can t hen be passed t o glUniform t o load one or m ore values int o t he ar ray, st art ing at t he it h elem ent of t he array. I t is not possible t o t ake i and add an int eger N and use t he result t o t r y t o m odify elem ent i + N in t he array. The locat ion of array elem ent i + N should be queried specifically before any at t em pt t o set it s value. These locat ion values do not necessarily represent real m em ory locat ions. Applicat ions t hat assum e ot herwise will not work. For exam ple, consider t he follow ing st ruct ure defined wit hin a shader: uniform struct { struct { float a; float b[10]; } c[2]; vec2 d; } e;

and consider t he API calls t hat at t em pt t o det erm ine locat ions wit hin t hat st ruct ure: loc1 loc2 loc3 loc4

= = = =

glGetUniformLocation(progObj, glGetUniformLocation(progObj, glGetUniformLocation(progObj, glGetUniformLocation(progObj,

"e.d"); "e.c[0]"); "e.c[0].b") ; "e.c[0].b[2]");

// // // //

is is is is

valid not valid valid valid

The locat ion loc2 cannot be ret rieved because e.c[0] refer ences a st ruct ure. Now consider t he com m ands t o set part s of t he uniform variable: glUniform2f(loc1, 1.0f, 2.0f); glUniform2i(loc1, 1, 2);

// is valid // is not valid

glUniform1f(loc1, 1.0f); glUniform1fv(loc3, 10, floatPtr); glUniform1fv(loc4, 10, floatPtr); glUniform1fv(loc4, 8, floatPtr);

// // // //

is is is is

not valid valid not valid valid

The second com m and in t he preceding list is invalid because loc1 refer ences a uniform variable of t ype ve c2 , not iv e c2 . The t hird com m and is invalid because loc1 refer ences a ve c2 , not a floa t . The fift h com m and in t he preceding list is invalid because it at t em pt s t o set values t hat will exceed t he lengt h of t he array. Uniform variables ( eit her built in or user defined) t hat can be accessed when a shader is execut ed are called ACTI VE UNI FORMS. You can t hink of t his as t hough t he process of com piling and linking is capable of deact ivat ing uniform variables t hat are declared but never used. This provides m ore flexibilit y in coding st ylem odular code can define lot s of uniform variables, and t hose t hat can be det erm ined t o be unused are t ypically opt im ized away. To obt ain t he list of act ive uniform variables from a pr ogram obj ect , use glGetActiveUniform. This com m and can be used by an applicat ion t o query t he uniform variables in a program obj ect and set up user int erface elem ent s t o allow direct m anipulat ion of all t he user - defined uniform values. void glGetActiveUniform( GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, GLchar * name) Ret urns inform at ion about an act ive uniform variable in t he program obj ect specified by program . The num ber of act ive uniform var iables can be obt ained by calling glGetProgram wit h t he value GL_ACTI VE_UNI FORMS. A value of 0 for index select s t he first act ive uniform variable. Perm issible values for index range from 0 t o t he num ber of act ive uniform variables m inus 1. Shaders m ay use built - in uniform variables, user- defined uniform variables, or bot h. Built - in uniform var iables have a prefix of " gl_" and reference exist ing OpenGL st at e or values derived from such st at e ( e.g., gl_Fog, gl_ModelViewMatrix, et c., see Sect ion 4.3 for a com plet e list .) Userdefined uniform variables have arbit rary nam es and obt ain t heir values from t he applicat ion t hrough calls t o glUniform. A uniform variable ( eit her built in or user defined) is considered act ive if it is det erm ined during t he link operat ion t hat it can be accessed during program execut ion. Therefore, program should have previously been t he t arget of a call t o glLinkProgram, but it is not necessary for it t o have been linked successfully. The size of t he charact er buffer requir ed t o st ore t he longest uniform variable nam e in program can be obt ained by calling glGetProgram w it h t he value GL_ACTI VE_UNI FORM_MAX_LENGTH. This value should be used t o allocat e a buffer of sufficient size t o st ore t he ret urned uniform variable nam e. The size of t his charact er buffer is passed in bufSize, and a point er t o t his charact er buffer is passed in name. glGetActiveUniform ret urns t he nam e of t he uniform variable indicat ed by index, st oring it in t he charact er buffer specified by name. The st ring

ret urned is null t erm inat ed. The act ual num ber of charact ers writ t en int o t his buffer is ret urned in length, and t his count does not include t he null t erm inat ion charact er. I f t he lengt h of t he ret urned st ring is not required, a value of NULL can be passed in t he length argum ent . The type argum ent ret urns a point er t o t he uniform variable's dat a t ype. One of t he following sym bolic const ant s m ay be ret urned: GL_FLOAT, GL_FLOAT_VEC2, GL_FLOAT_VEC3, GL_FLOAT_VEC4, GL_I NT, GL_I NT_VEC2, GL_I NT_VEC3, GL_I NT_VEC4, GL_BOOL, GL_BOOL_VEC2, GL_BOOL_VEC3, GL_BOOL_VEC4, GL_FLOAT_MAT2, GL_FLOAT_MAT3, GL_FLOAT_MAT4, GL_SAMPLER_1D, GL_SAMPLER_2D, GL_SAMPLER_3D, GL_SAMPLER_CUBE, GL_SAMPLER_1D_SHADOW, or GL_SAMPLER_2D_SHADOW. I f one or m ore elem ent s of an array ar e act ive, t he nam e of t he ar ray is ret urned in name, t he t ype is ret urned in type, and t he size param et er ret urns t he highest array elem ent index used, plus one, as det erm ined by t he com piler and linker. Only one act ive uniform variable will be report ed for a uniform array. Uniform variables t hat are declared as st ruct ures or arrays of st ruct ures are not ret urned direct ly by t his funct ion. I nst ead, each of t hese uniform variables is reduced t o it s fundam ent al com ponent s cont aining t he " ." and " [ ] " operat ors such t hat each of t he nam es is valid as an argum ent t o glGetUniformLocation. Each of t hese reduced uniform variables is count ed as one act ive uniform variable and is assigned an index. A valid nam e cannot be a st ruct ure, an array of st ruct ures, or a subcom ponent of a vect or or m at rix. The size of t he uniform variable is ret urned in size. Uniform variables ot her t han arrays have a size of 1. St ruct ures and arrays of st ruct ures are reduced as described earlier, such t hat each of t he nam es ret urned will be a dat a t ype in t he earlier list . I f t his reduct ion result s in an array, t he size ret urned is as described for uniform arrays; ot herwise, t he size ret urned is 1. The list of act ive uniform variables m ay include bot h built - in uniform variables ( w hich begin wit h t he prefix " gl_" ) as well as user- defined uniform variable nam es. This funct ion ret urns as m uch inform at ion as it can about t he specified act ive uniform variable. I f no infor m at ion is available, length is 0, and name is an em pt y st ring. This sit uat ion could occur if t his funct ion is called aft er a link operat ion t hat failed. I f an error occurs, t he ret urn values length, size, type, and name are unm odified.

Using glGetActiveUniform, t he applicat ion developer can program m at ically query t he uniform variables act ually used in a shader and aut om at ically creat e a user int erface t hat allows t he end user t o m odify t hose uniform variables. I f am ong t he shader w rit ers t here were som e convent ion concerning t he nam es of uniform variables, t he user int erface could be even m ore specific. For inst ance, any uniform variable nam e t hat ended wit h " Color" would be edit ed wit h t he color select ion t ool. This funct ion can also be useful when m ixing and m at ching a set of ver t ex and fr agm ent shader s designed t o play well wit h each ot her, using a subset of known uniform variables. I t can be m uch safer and less t edious t o program m at ically det erm ine which uniform variables t o send down t han t o hardcode all t he com binat ions.

7.9. Samplers glUniform1i and glUniform1iv load uniform variables defined as sam pler t ypes ( i.e., uniform

variables of t ype sa m ple r 1 D , sa m ple r 2 D , sa m ple 3 D , sa m ple r Cu be , sa m ple r 1 D Sh a dow , or sa m ple r 2 D Sh a dow ) . They m ay be declar ed w it hin eit her vert ex shaders or fragm ent shaders. The value cont ained in a sam pler is used wit hin a shader t o access a par t icular t ext ure m ap. The value loaded int o t he sam pler by t he applicat ion should be t he num ber of t he t ext ure unit t o be used t o access t he t ext ure. For vert ex shaders, t his value should be less t han t he im plem ent at iondependent const ant GL_MAX_VERTEX_TEXTURE_I MAGE_UNI TS, which can be queried wit h glGet. For fragm ent shaders, t his value should be less t han t he im plem ent at iondependent const ant GL_MAX_TEXTURE_I MAGE_UNI TS. The suffix on t he sam pler t ype indicat es t he t ext ure t ype t o be accessed: 1D, 2D, 3D, cube m ap, 1D shadow , or 2D shadow . I n OpenGL, a t ext ure obj ect of each of t he first four t ext ur e t ypes can be bound t o a single t ext ure unit , and t his suffix allows t he desired t ext ure obj ect t o be chosen. A 1D shadow sam pler is used t o access t he 1D t ext ure when dept h com parisons are enabled, and a 2D shadow sam pler is used t o access t he 2D t ext ure when dept h com parisons are enabled. I f t wo uniform variables of different sam pler t ypes cont ain t he sam e value, an error is generat ed when t he next rendering com m and is issued. At t em pt ing t o load a sam pler wit h any com m and ot her t han glUniform1i or glUniform1iv result s in an error being generat ed. From wit hin a shader, sam plers should be considered an opaque dat a t ype. The current API provides a way of specifying an int eger represent ing t he t ext ure im age unit t o be used. I n t he fut ure, t he API m ay be ext ended t o allow a sam pler t o refer direct ly t o a t ext ure obj ect . Sam plers t hat can be accessed when a program is execut ed are called ACTI VE SAMPLERS. The link operat ion fails if it det erm ines t hat t he num ber of act ive sam plers exceeds t he m axim um allowable lim it s. The num ber of act ive sam plers perm it t ed on t he vert ex processor is specified by GL_MAX_VERTEX_TEXTURE_I MAGE_UNI TS, t he num ber of act ive sam plers perm it t ed on t he fragm ent processor is specified by GL_MAX_TEXTURE_I MAGE_UNI TS, and t he num ber of act ive sam plers perm it t ed on bot h pr ocessors com bined is GL_COMBI NED_TEXTURE_I MAGE_UNI TS. More det ail on using sam plers wit hin a shader is provided in Sect ion 10.1.

7.10. Multiple Render Targets Anot her feat ure added t o OpenGL in version 2.0 was t he abilit y t o render int o m ult iple buffers sim ult aneously. The OpenGL Shading Language m akes provisions for t his capabilit y by including a fragm ent shader out put variable defined as an ar ray called gl_FragData. The size of t his array is im plem ent at ion dependent , but m ust be at least 1. The elem ent s of t his array are defined t o be of t ype ve c4 . Wit h t his capabilit y, applicat ions can develop fragm ent shaders t hat com put e m ult iple values for each fr agm ent and st ore t hem in offscreen m em ory. These values can be accessed during a fut ure rendering pass. Am ong ot her t hings, t his let s applicat ions im plem ent com plex m ult ipass algorit hm s and use t he graphics hardware for general- purpose com put at ion. To set up OpenGL for rendering int o m ult iple t arget buffers, use void glDrawBuffers( GLsizei n, const GLenum * bufs) Defines an array of buffers int o which fr agm ent color values or fragm ent dat a will be writ t en. I f no fragm ent shader is act ive, rendering operat ions generat e only one fragm ent color per fragm ent and it is writ t en int o each of t he buffers specified by bufs. I f a fragm ent shader is act ive and it writ es a value t o t he out put variable gl_FragColor, t hen t hat value is writ t en int o each of t he buffers specified by bufs. I f a fr agm ent shader is act ive and it w rit es a value t o one or m ore elem ent s of t he out put array variable gl_FragData[], t hen t he value of gl_FragData[0] is writ t en int o t he first buffer specified by bufs, t he value of gl_FragData[1] is writ t en int o t he second buffer specified by bufs, and so on up t o gl_FragData[n-1]. The draw buffer used for gl_FragData[n] and beyond is im plicit ly set t o be GL_NONE. The sym bolic const ant s cont ained in bufs are defined in Table 7.4. Except for GL_NONE, none of t he sym bolic const ant s m ay appear m ore t han once in bufs. The m axim um num ber of draw buffers support ed is im plem ent at ion dependent and can be queried by calling glGet wit h t he argum ent GL_MAX_DRAW_BUFFERS. The num ber of auxiliary buffers can be queried by calling glGet wit h t he argum ent GL_AUX_BUFFERS.

Ta ble 7 .4 . Bu ffe r n a m e s for use w it h t he glDrawBuffers ca ll Pa r a m e t e r

Ope r a t ion

GL_NONE

The fragm ent color / dat a value is not writ t en int o any color buffer.

GL_FRONT_LEFT

The fragm ent color/ dat a value is writ t en int o t he front - left color buffer.

GL_FRONT_RI GHT

The fragm ent color/ dat a value is writ t en int o t he front - right color buffer.

GL_BACK_LEFT

The fragm ent color/ dat a value is writ t en int o t he back - left color buffer.

GL_BACK_RI GHT

The fragm ent color/ dat a value is writ t en int o t he back - right color buffer.

GL_AUXi

The fragm ent color/ dat a value is writ t en int o auxiliary buffer i.

An error is generat ed if glDrawBuffers specifies a buffer t hat does not exist in t he current GL cont ext . I f m ore t han one buffer is select ed for drawing, blending and logical operat ions are com put ed and applied independent ly for each elem ent of gl_FragData and it s corresponding buffer. Furt herm ore, t he alpha value ( i.e., t he fourt h com ponent ) of gl_FragData[0] is used t o det erm ine t he result of t he alpha t est . Operat ions such as scissor, dept h, and st encil t est s ( if enabled) m ay cause t he ent ire fragm ent ( including all of t he values in t he gl_FragData array) t o be discarded wit hout any updat es t o t he fram ebuffer.

7.11. Development Aids A sit uat ion t hat can be difficult t o diagnose is one in w hich a program m ay fail t o execut e because of t he value of a sam pler variable. These variables can be changed anyt im e bet ween linking and program execut ion. To ensure robust behavior, OpenGL im plem ent at ions m ust do som e runt im e checking j ust before t he shader is execut ed ( i.e., w hen a rendering operat ion is about t o occur) . At t his point , t he only way t o report an er ror is t o set t he OpenGL error flag, and t his is not usually som et hing t hat applicat ions check at t his perform ance- crit ical j unct ure. To provide m ore inform at ion when t hese sit uat ions occur, t he OpenGL Shading Language API defines a new funct ion t hat can be called t o perform t his runt im e check explicit ly and provide diagnost ic inform at ion. void glValidateProgram( GLuint program) Checks whet her t he execut ables cont ained in program can execut e given t he current OpenGL st at e. The inform at ion generat ed by t he validat ion process is st ored in program's inform at ion log. The validat ion inform at ion m ay consist of an em pt y st ring, or it m ay be a st ring cont aining inform at ion about how t he current program obj ect int eract s wit h t he rest of current OpenGL st at e. This funct ion provides a w ay for OpenGL im plem ent ors t o convey m ore inform at ion about why t he current program is inefficient , subopt im al, failing t o execut e, and so on. The st at us of t he validat ion operat ion is st or ed as part of t he program obj ect 's st at e. This value is set t o GL_TRUE if t he validat ion succeeded and GL_FALSE ot herwise. I t can be queried by calling glGetProgram w it h argum ent s program and GL_VALI DATE_STATUS. I f validat ion is successful, program is guarant eed t o execut e given t he current st at e. Ot herw ise, program is guarant eed t o not execut e. This funct ion is t ypically useful only during applicat ion developm ent . The inform at ional st ring st ored in t he inform at ion log is com plet ely im plem ent at ion- dependent . Therefore, an applicat ion should not expect different OpenGL im plem ent at ions t o produce ident ical inform at ion st rings.

Because t he operat ions described in t his sect ion can severely hinder perform ance, t hey should be used only during applicat ion developm ent and rem oved before shipm ent of t he product ion version of t he applicat ion.

7.12. Implementation-Dependent API Values Som e of t he feat ures we've described in pr evious sect ions have im plem ent at ion- dependent lim it s. All of t he im plem ent at ion- dependent values in t he OpenGL Shading Language API are defined in t he list t hat follows, and all of t hem can be queried wit h glGet. GL_MAX_COMBI NED_TEXTURE_I MAGE_UNI TSDefines t he t ot al num ber of hardware unit s t hat can be used t o access t ext ure m aps from t he vert ex processor and t he fragm ent processor com bined. The m inim um legal value is 2. GL_MAX_DRAW_BUFFERSDefines t he m axim um num ber of buffers t hat can be sim ult aneously writ t en int o from wit hin a fragm ent shader using t he special out put variable gl_FragData. This const ant effect ively defines t he size of t he gl_FragData array. The m inim um legal value is 1. GL_MAX_FRAGMENT_UNI FORM_COMPONENTSDefines t he num ber of com ponent s ( i.e., float ing- point values) t hat are available for fr agm ent shader uniform variables. The m inim um legal value is 64. GL_MAX_TEXTURE_COORDSDefines t he num ber of t ext ure coordinat e set s t hat are available. The m inim um legal value is 2. GL_MAX_TEXTURE_I MAGE_UNI TSDefines t he t ot al num ber of hardware unit s t hat can be used t o access t ext ure m aps fr om t he fragm ent processor. The m inim um legal value is 2. GL_MAX_VARYI NG_FLOATSDefines t he num ber of float ing- point variables available for varying variables. The m inim um legal value is 32. GL_MAX_VERTEX_ATTRI BSDefines t he num ber of act ive vert ex at t ribut es t hat ar e available. The m inim um legal value is 16. GL_MAX_VERTEX_TEXTURE_I MAGE_UNI TSDefines t he num ber of hardw are unit s t hat can be used t o access t ext ure m aps from t he vert ex processor. The m inim um legal value is 0. GL_MAX_VERTEX_UNI FORM_COMPONENTSDefines t he num ber of com ponent s ( i.e., float ing- point values) t hat are available for vert ex shader uniform variables. The m inim um legal value is 512.

7.13. Application Code for Brick Shaders Each shader is going t o be a lit t le bit different. Each vert ex shader m ay use a differ ent set of at t ribut e variables or different uniform variables, at t ribut e variables m ay be bound t o different gener ic vert ex at t ribut e index values, and so on. One of t he dem o program s whose source code is available for download from t he 3Dlabs Web sit e is called ogl2brick. I t is a sm all, clear exam ple of how t o creat e and use a vert ex shader and a fragm ent shader. The code in ogl2brick w as derived from an earlier dem o program called ogl2demo, writ t en prim arily by Bart hold Licht enbelt wit h cont ribut ions from several ot hers. I n ogl2brick an " inst all" funct ion inst alls t he br ick shaders t hat were present ed in Chapt er 6. We discuss t hat shader inst allat ion funct ion, but first we define a sim ple funct ion t hat m ake it a lit t le easier t o set t he values of uniform variables. GLint getUniLoc(GLuint program, const GLchar *name) { GLint loc; loc = glGetUniformLocation(program, name); if (loc == -1) printf("No such uniform named \"%s\"\n", name); printOpenGLError(); return loc;

// Check for OpenGL errors

}

Shaders are passed t o OpenGL as st rings. For our shader inst allat ion funct ion, w e assum e t hat each of t he shaders has been defined as a single st ring, and point ers t o t hose st rings are passed t o t he following funct ion. This funct ion does all t he work t o load, com pile, link, and inst all our brick shaders. The funct ion definit ion and local variables for t his funct ion are declared as follows: int installBrickShaders(const GLchar *brickVertex, const GLchar *brickFragment) { GLuint brickVS, brickFS, brickProg; // handles to objects GLint vertCompiled, fragCompiled; // status values GLint linked;

The argum ent brickVertex cont ains a point er t o t he st ring cont aining t he source code for t he brick ver t ex shader , and t he argum ent brickFragment cont ains a point er t o t he source code for t he brick fragm ent shader. Next , w e declare variables t o refer t o t hree OpenGL obj ect s: a shader obj ect t hat st ores and com piles t he brick vert ex shader, a second shader obj ect t hat st ores and com piles t he brick fr agm ent shader, and a progr am obj ect t o which t he shader obj ect s will be at t ached. Flags t o indicat e t he st at us of t he com pile and link operat ions are defined next . The first st ep is t o creat e t wo em pt y shader obj ect s, one for t he vert ex shader and one for t he fragm ent shader: brickVS = glCreateShader(GL_VERTEX_SHADER); brickFS = glCreateShader(GL_FRAGMENT_SHADER);

Source code can be loaded int o t he shader obj ect s aft er t hey have been creat ed. The shader obj ect s are em pt y, and w e have a single null t erm inat ed st ring cont aining t he source code for each shader, so we can call glShaderSource as follow s:

glShaderSource(brickVS, 1, &brickVertex, NULL); glShaderSource(brickFS, 1, &brickFragment, NULL);

The shaders are now ready t o be com piled. For each shader, we call glCompileShader and t hen call glGetShader t o see what t ranspired. glCompileShader set s t he shader obj ect 's GL_COMPI LE_STATUS param et er t o GL_TRUE if it succeeded and GL_FALSE ot herwise. Regardless of whet her t he com pilat ion succeeded or failed, we print t he inform at ion log for t he shader. I f t he com pilat ion was unsuccessful, t his log will have inform at ion about t he com pilat ion errors. I f t he com pilat ion was successful, t his log m ay st ill have useful inform at ion t hat w ould help us im pr ove t he shader in som e way. You would t ypically check t he info log only during applicat ion developm ent or aft er running a shader for t he first t im e on a new plat form . The funct ion exit s if t he com pilat ion of eit her shader fails. glCompileShader(brickVS); printOpenGLError(); // Check for OpenGL errors glGetShaderiv(brickVS, GL_COMPILE_STATUS, &vertCompiled); printShaderInfoLog(brickVS); glCompileShader(brickFS); printOpenGLError(); // Check for OpenGL errors glGetShaderiv(brickFS, GL_COMPILE_STATUS, &fragCompiled); printShaderInfoLog(brickFS); if (!vertCompiled || !fragCompiled) return 0;

This sect ion of code uses t he printShaderInfoLog funct ion t hat we defined previously. At t his point , t he shaders have been com piled successfully, and we're alm ost ready t o t ry t hem out . First , t he shader obj ect s need t o be at t ached t o a program obj ect so t hat t hey can be linked. brickProg = glCreateProgram(); glAttachShader(brickProg, brickVS); glAttachShader(brickProg, brickFS);

The pr ogram obj ect is linked wit h glLinkProgram. Again, w e look at t he inform at ion log of t he progr am obj ect regardless of w het her t he link succeeded or failed. There m ay be useful infor m at ion for us if we've never t ried t his shader befor e. glLinkProgram(brickProg); printOpenGLError(); // Check for OpenGL errors glGetProgramiv(brickProg, GL_LINK_STATUS, &linked); printProgramInfoLog(brickProg); if (!linked) return 0;

I f we m ake it t o t he end of t his code, we have a valid program t hat can becom e part of current st at e sim ply by calling glUseProgram: glUseProgram(brickProg);

Before ret ur ning from t his funct ion, w e also w ant t o init ialize t he values of t he uniform variables

used in t he t w o shaders. To obt ain t he locat ion t hat was assigned by t he linker, we query t he uniform variable by nam e, using t he getUniLoc funct ion defined previously. Then we use t hat locat ion t o im m ediat ely set t he init ial value of t he uniform variable. glUniform3f(getUniLoc(brickProg, glUniform3f(getUniLoc(brickProg, glUniform2f(getUniLoc(brickProg, glUniform2f(getUniLoc(brickProg, glUniform3f(getUniLoc(brickProg,

"BrickColor"), 1.0, 0.3, 0.2); "MortarColor"), 0.85, 0.86, 0.84); "BrickSize"), 0.30, 0.15); "BrickPct"), 0.90, 0.85); "LightPosition"), 0.0, 0.0, 4.0);

return 1; }

When t his funct ion ret urns, t he applicat ion is ready t o draw geom et ry t hat will be rendered wit h our brick shaders. The result of rendering som e sim ple obj ect s wit h t his applicat ion code and t he shaders described in Chapt er 6 is shown in Figur e 6.6. The com plet e C funct ion is shown in List ing 7.3.

List in g 7 .3 . C fu n ct ion for in st a llin g br ick sh a de r s

int installBrickShaders(const GLchar *brickVertex, const GLchar *brickFragment) { GLuint brickVS, brickFS, brickProg; // handles to objects GLint vertCompiled, fragCompiled; // status values GLint linked; // Create a vertex shader object and a fragment shader object brickVS = glCreateShader(GL_VERTEX_SHADER); brickFS = glCreateShader(GL_FRAGMENT_SHADER); // Load source code strings into shaders glShaderSource(brickVS, 1, &brickVertex, NULL); glShaderSource(brickFS, 1, &brickFragment, NULL); // Compile the brick vertex shader and print out // the compiler log file. glCompileShader(brickVS); printOpenGLError(); // Check for OpenGL errors glGetShaderiv(brickVS, GL_COMPILE_STATUS, &vertCompiled); printShaderInfoLog(brickVS); // Compile the brick fragment shader and print out // the compiler log file. glCompileShader(brickFS); printOpenGLError(); // Check for OpenGL errors glGetShaderiv(brickFS, GL_COMPILE_STATUS, &fragCompiled); printShaderInfoLog(brickFS); if (!vertCompiled || !fragCompiled) return 0; // Create a program object and attach the two compiled shaders brickProg = glCreateProgram(); glAttachShader(brickProg, brickVS);

glAttachShader(brickProg, brickFS); // Link the program object and print out the info log glLinkProgram(brickProg); printOpenGLError(); // Check for OpenGL errors glGetProgramiv(brickProg, GL_LINK_STATUS, &linked); printProgramInfoLog(brickProg); if (!linked) return 0; // Install program object as part of current state glUseProgram(brickProg); // Set up initial uniform values glUniform3f(getUniLoc(brickProg, glUniform3f(getUniLoc(brickProg, glUniform2f(getUniLoc(brickProg, glUniform2f(getUniLoc(brickProg, glUniform3f(getUniLoc(brickProg, return 1; }

"BrickColor"), 1.0, 0.3, 0.2); "MortarColor"), 0.85, 0.86, 0.84); "BrickSize"), 0.30, 0.15); "BrickPct"), 0.90, 0.85); "LightPosition"), 0.0, 0.0, 4.0);

7.14. Summary The set of funct ion calls added t o OpenGL t o creat e and m anipulat e shaders is act ually quit e sm all. The int erface m im ics t he soft ware developm ent process followed by a C/ C+ + program m er. To inst all and use OpenGL shaders, do t he following: 1.

Creat e one or m ore ( em pt y) shader obj ect s wit h glCreateShader.

2.

Provide source code for t hese shaders wit h glShaderSource.

3.

Com pile each of t he shaders wit h glCompileShader.

4.

Creat e a program obj ect wit h glCreateProgram.

5.

At t ach all t he shader obj ect s t o t he program obj ect wit h glAttachShader.

6.

Link t he program obj ect wit h glLinkProgram.

7.

I nst all t he execut able program as part of OpenGL's current st at e w it h glUseProgram.

8.

I f t he shaders use user - defined uniform variables, query t he locat ions of t hese variables wit h glGetUniformLocation and t hen set t heir values wit h glUniform.

User- defined at t ribut e variables can be explicit ly associat ed wit h a generic vert ex at t ribut e index w it h glBindAttribLocation, or such associat ions can be assigned im plicit ly at link t im e and queried wit h glGetAttribLocation. Generic vert ex at t ribut e values can t hen be supplied by t he applicat ion a vert ex at a t im e w it h one of t he variant s of glVertexAttrib or as vert ex arrays by using glVertexAttribPointer and glEnableVertexArrayPointer in conj unct ion wit h st andard OpenGL com m ands t o draw vert ex arrays. A num ber of query funct ions obt ain inform at ion about shader and program obj ect s.

7.15. Further Information Reference pages for t he OpenGL Shading Language API can be found in Appendix B. Source code for t he exam ple in t his chapt er can be found at t he 3Dlabs developers Web sit e. More com plex source code exam ples and a variet y of shaders can be found t here as well. 1 . 3Dlabs developer Web sit e. ht t p: / / developer.3dlabs.com . 2 . Ebert , David S., John Hart , Bill Mark, F. Kent on Musgrave, Darwyn Peachey, Ken Perlin, and St even Worley, Text uring and Modeling: A Procedural Approach, Thir d Edit ion, Morgan Kaufm ann Publishers, San Francisco, 2002. ht t p: / / w ww .t ext uringandm odeling.com 3 . Kessenich, John, Dave Baldwin, and Randi Rost , The OpenGL Shading Language, Version 1.10, 3Dlabs, April 2004. ht t p: / / w ww .opengl.org/ docum ent at ion/ spec.ht m l 4 . OpenGL Archit ect ure Review Board, Dave Shreiner, J. Neider, T. Davis, and M. Woo, OpenGL Program m ing Guide, Fift h Edit ion: The Official Guide t o Learning OpenGL, Version 2, Addison- Wesley, Reading, Massachuset t s, 2005. 5 . OpenGL Archit ect ure Review Board, OpenGL Reference Manual, Fourt h Edit ion: The Official Reference t o OpenGL, Version 1.4, Edit or: Dave Shreiner, Addison- Wesley, Reading, Massachuset t s, 2004. 6 . Segal, Mark, and Kurt Akeley, The OpenGL Graphics Syst em : A Specificat ion ( Version 2.0) , Edit or ( v1.1) : Chris Fr azier, ( v1.21.5) : Jon Leech, ( v2.0) : Jon Leech and Pat Brow n, Sept . 2004. ht t p: / / w ww .opengl.org/ docum ent at ion/ spec.ht m l

Chapter 8. Shader Development At t he t im e of t his writ ing, shader developm ent t ools for t he OpenGL Shading Language are in t heir infancy. Alt hough som e t ools for shader developm ent do exist ( not ably, ATI 's RenderMonkey) , t ools for debugging or profiling shaders are only st art ing t o em erge. This sit uat ion is expect ed t o im prove rapidly as hardware and soft ware com panies develop t ools for use in shader developm ent . This chapt er set s fort h som e ideas on t he shader developm ent process and describes t he t ools t hat are current ly available. Bot h general soft w are developm ent t echniques and t echniques t hat are unique t o shader developm ent are discussed. I n all likelihood, w e w ill soon see soft w are developers st ep int o t he void wit h product s t o assist shader developm ent , and a whole ecosyst em of t ools for shader developm ent will event ually arise.

8.1. General Principles Shader developm ent can be t hought of as anot her form of soft ware engineering; t herefore, exist ing soft war e engineering principles and pract ices should be brought int o play when you are developing shaders. Spend som e t im e designing t he shader before writ ing any code. The design should aim t o keep t hings as sim ple as possible while st ill get t ing t he j ob done. I f t he shader is part of a larger shader developm ent effort , t ake care t o design t he shader for reliabilit y and reuse. I n short , you should t reat shader developm ent t he sam e as you would any ot her soft ware developm ent t asks, allocat ing appropriat e am ount s of t im e for design, im plem ent at ion, t est ing, and docum ent at ion. Here are a few m ore useful t hought s for developing shaders. Consider t hese t o be friendly advice and not m andat es. There will be sit uat ions in which som e of t hese shader developm ent suggest ions m ake sense and ot hers in which t hey do not .

8.1.1. Understand the Problem I t is wort h rem inding yourself periodically t hat you will be m ost successful at developing shaders if you underst and t he problem before you writ e any of t he shader code. The first st ep is t o m ake sure you underst and t he rendering algorit hm you plan on im plem ent ing. I f your aim is t o develop a shader for bum p- m apping, m ake sure you underst and t he necessary m at hem at ics before plunging int o coding. I t is usually easier t o t hink t hings t hrough wit h a pencil and paper and get t he det ails st raight in your m ind before you begin t o writ e code. Because t he t ools for developing shaders are current ly less powerful t han t hose for developing code int ended t o run on t he CPU, you m ight consider im plem ent ing a sim ulat ion of your algorit hm on t he CPU before coding it in t he OpenGL Shading Language. Doing t his will let you use t he powerful debugging t ools available for t ypical soft ware developm ent , single- st ep t hrough source code, set br eakpoint s, and really wat ch your code in act ion. Of course, t ools should soon be available t o let you do t hese t hings direct ly on t he graphics hardware as well.

8.1.2. Add Complexity Progressively Many shaders depend on a com binat ion of det ails t o achieve t he desired effect . Develop your shader in such a way t hat you im plem ent and t est t he largest and m ost im port ant det ails first and add progressive com plexit y aft er t he basic shader is w orking. For inst ance, you m ay want t o develop a shader t hat com bines effect s from noise wit h values read from several t ext ure m aps and t hen perform s som e unique light ing effect s. You can approach t his t ask in a couple of different ways. One way would be t o get your unique light ing effect s working first wit h a sim ple shading m odel. Aft er t est ing t his part of t he shader, you can add t he effect s from reading t he t ext ure m aps and t horoughly t est again. Aft er t his, you can add t he noise effect s, again, t est ing as you proceed. I n t his w ay, you have reduced a large developm ent t ask int o several sm aller ones. Aft er a t ask has been successfully com plet ed and t est ed, m ove on t o t he next t ask.

8.1.3. Test and Iterate Som et im es it is im possible t o visualize ahead of t im e t he effect a shader will have. This is part icularly t rue when you are dealing wit h m at hem at ical funct ions t hat are com plex or hard t o visualize, such as noise. I n t his case, you m ay want t o param et erize your algorit hm and m odify t he param et ers syst em at ically. You can t ake not es as you m odify t he param et ers and observe

t he effect . These observat ions w ill be useful com m ent s in t he shader source, providing insight for som eone who m ight com e along lat er and want t o t w eak t he shader in a different dir ect ion. Aft er you have found a set of param et ers t hat gives you t he desired effect , you can consider sim plifying t he shader by rem oving som e of t he " t weakable" param et er s and replacing t hem wit h const ant s. This m ay m ake your shader less flexible, but it m ay m ake it easier for som eone com ing along lat er t o underst and.

8.1.4. Strive for Simplicity There's a lot t o be said for sim plicit y. Sim ple shaders are easier t o underst and and easier t o m aint ain. There's oft en m ore t han one algorit hm for achieving t he effect you w ant . Have you chosen t he sim plest one? There's oft en m ore t han one way t o im plem ent a part icular algorit hm . Have you chosen t he language feat ures t hat let you expr ess t he algorit hm in t he sim plest way possible?

8.1.5. Exploit Modularity The OpenGL Shading Language and it s API support m odular shaders, so t ake advant age of t his capabilit y. Use t he principle of " divide and conquer" t o develop sm all, sim ple m odules t hat are designed t o work t oget her. Your light ing m odules m ight all be int erchangeable and offer support for st andard light source t ypes as well as cust om light ing m odules. You m ay also have fog m odules t hat offer a variet y of fog effect s. I f you do t hings right , you can m ix and m at ch any of your light ing m odules wit h any of your fog m odules. You can apply t his principle t o ot her aspect s of shader com put at ion, bot h for vert ex shaders and for fragm ent shaders.

8.2. Performance Considerations Aft er you have done all t he right t hings from a soft ware engineering st andpoint , your shader m ay or m ay not have accept able perform ance. Here are som e ideas for eking out bet t er perform ance from your carefully craft ed shader.

8.2.1. Consider Computational Frequency Shading com put at ions can occur in t hree areas: on t he CPU, on t he ver t ex processor, and on t he fragm ent processor. I t is t em pt ing t o put m ost of your shader com put at ion in t he fragm ent shader because t his is execut ed for every pixel t hat is drawn, and you will, t herefore, get t he highest - qualit y im age. But if perform ance is a concern, you m ay be able t o ident ify com put at ions t hat can be done wit h accept able qualit y per vert ex inst ead of per fragm ent . By m oving t he com put at ion t o t he vert ex shader, you can m ake your fr agm ent shader fast er. I n som e cases, t here m ay be no visible difference bet ween doing t he com put at ion in t he vert ex shader versus doing it in t he fragm ent shader. This m ight be t he case wit h fog com put at ions, for exam ple. One way t o t hink about t he problem is t o im plem ent rapidly changing charact erist ics in t he fragm ent shader and t o im plem ent charact erist ics t hat don't change as rapidly in t he vert ex shader. For inst ance, diffuse light ing effect s change slowly over a surface and so can usually be com put ed w it h sufficient qualit y in t he vert ex shader. Specular light ing effect s m ight need t o be im plem ent ed in t he fragm ent shader t o achieve high qualit y. I f a part icular value changes linearly across an obj ect 's surface, you can get t he sam e result by com put ing t he value per vert ex and using a varying variable t o int erpolat e it as you would by com put ing t he value at each fr agm ent . I n t his case, you m ay as well have t he vert ex shader do t he com put at ion. Unless you are rendering very sm all t riangles, your fragm ent shader w ill execut e far m ore t im es t han your vert ex shader will, so it is m ore efficient t o do t he com put at ion in t he vert ex shader. Sim ilarly, you m ay be able t o find com put at ions t hat can be done once on t he CPU and rem ain const ant for a gr eat m any execut ions of your vert ex shader or fragm ent shader. You can oft en save shader inst ruct ion space or im prove shader perform ance ( or bot h) by precom put ing values in your applicat ion code and passing t hem t o your shader as uniform variables. Som et im es you can spot t hese t hings by analyzing your shader code. I f you pass length in as a uniform variable and your shader always com put es sqrt( length) , you'r e bet t er off doing t he com put at ion once on t he host CPU and passing t hat value t o your shader rat her t han com put ing t he value for every execut ion of your shader. I f your shader needs bot h length and sqrt( length) , you can pass bot h values in as uniform variables. Deciding where t o perform com put at ion also involves know ing w here t he com put at ional bot t leneck occurs for a part icular rendering operat ion. You j ust need t o speed up t he slowest part of t he syst em t o see an im provem ent in perform ance. Conversely, you shouldn't spend t im e im proving t he perform ance of som et hing t hat isn't a bot t leneck, because you won't see t he gain in perform ance anyway.

8.2.2. Analyze Your Algorithm You can oft en m ake your shader m ore efficient j ust by underst anding t he m at h it uses. For inst ance, you m ight want t o lim it t he range of t he variable finalcolor t o [ 0,1] . But if you know t hat you are only adding values t o com put e t his variable and t he values t hat you're adding are alw ays posit ive, t here's really no need t o check t he result against 0. An inst ruct ion like min ( finalcolor, 1.0) clam ps t he result at 1.0, and t his inst ruct ion likely has higher perform ance t han an inst r uct ion like clamp( finalcolor, 0.0, 1.0) because it needs only t o com pare values against one num ber inst ead of t w o. I f you define t he valid range of all t he variables in your shader, you can m ore easily see t he boundary condit ions t hat you need t o handle.

8.2.3. Use the Built-in Functions Whenever possible, use t he built - in funct ions t o im plem ent t he effect t hat you're t rying t o achieve. Built - in funct ions are int ended t o be im plem ent ed in an opt im al way by t he graphics hardw are vendor. I f your shader hand- codes t he sam e effect as a built - in funct ion, t here's lit t le chance t hat it will be fast er t han t he built - in funct ion but a good chance t hat it will be slower.

8.2.4. Use Vectors The OpenGL Shading Language let s you express vect or com put at ions nat ur ally, and underlying graphics hardware is oft en built t o operat e sim ult aneously on a vect or of values. Therefore, you should t ake advant age of t his and use vect ors for calculat ions w henever possible. On t he ot her hand, you shouldn't use vect ors t hat are bigger t han t he com put at ions require. Such use can wast e regist er s, hardw are int erpolat ors ( in t he case of varying variables) , processing bandwidt h, or m em ory bandwidt h.

8.2.5. Use Textures to Encode Complex Functions Because fragm ent processing is now program m able, t ext ures can be used for a lot m ore t han j ust im age dat a. You m ight want t o consider st oring a com plex funct ion in a t ext ure and doing a single lookup rat her t han a com plex com put at ion wit hin t he fragm ent shader. This is illust rat ed in Chapt er 15, in which we encode a noise funct ion as a 3D t ext ure. This approach t akes advant age of t he specialized high- perform ance hardware t hat perform s t ext ure access, and it can also t ake advant age of t ext ur e filt ering hardware t o int erpolat e bet ween values encoded in t he t ext ur e.

8.2.6. Review the Information Logs One of t he m ain ways t hat an OpenGL im plem ent at ion can provide feedback t o an applicat ion developer is t hrough t he shader obj ect and program obj ect inform at ion logs ( see Sect ion 7.6) . Dur ing shader developm ent , you should r eview t he m essages in t he inform at ion logs for com piler and linker errors, but you should also review t hem t o see if t hey include any perform ance or funct ionalit y w arnings or ot her descript ive m essages. These inform at ion logs are one of t he pr im ary ways for OpenGL im plem ent at ions t o convey im plem ent at ion- dependent infor m at ion about perfor m ance, resource lim it at ions, and so on.

8.3. Shader Debugging Shader developm ent t ools are in t heir infancy, so debugging shaders can be a difficult t ask. Here are a few pract ical t ips t hat m ay be helpful as you t ry t o debug your shaders.

8.3.1. Use the Vertex Shader Output To det erm ine whet her vert ex shader code is behaving as expect ed, you can use condit ionals t o t est int erm ediat e values t o see if a value is som et hing unexpect ed. I f it is, you can m odify one of t he shader's out put values so t hat a visually dist inct change occurs. For inst ance, if you t hink t hat t he value foo should never be great er t han 5.0, you can set t he color values t hat are being passed t o t he fragm ent shader t o black or pink or neon green if t he value of foo exceeds 5.0. I f t hat 's not dist inct ive enough and you've already com put ed t he t ransform ed hom ogeneous posit ion, you can do som et hing like t his: if (foo > 5.0) gl_Position += 1.0;

This code adds 1 t o each com ponent of t he t ransform ed posit ion for which foo was great er t han 5. When it is execut ed, you should see t he obj ect shift on t he screen. Wit h t his appr oach, you can syst em at ically check your assum pt ions about t he int erm ediat e values being generat ed by t he vert ex shader.

8.3.2. Use the Fragment Shader Output Fragm ent shaders can produce a fr agm ent color, a fragm ent dept h, or an arr ay of fragm ent dat a values. You can use t he disca r d keyword t o prevent t he com put ed fragm ent value from updat ing t he fram e buffer. The dept h value m ay not be helpful during debugging, but you can eit her color- code your fragm ent colors or use t he disca r d keyword t o discard fragm ent s wit h cert ain qualit ies. These t echniques provide you w it h visual feedback about what 's going on wit hin t he shader . For inst ance, if you're not quit e sure if your 2D t ext ure coordinat es span t he whole range from 0 t o 1.0, you could put an if t est in t he shader and discard fragm ent s wit h cert ain qualit ies. You can discard all t he fragm ent s for which bot h s and t t ext ure coordinat es are great er t han 0.5 or for which eit her coordinat e is great er t han 0.99, and so on. The m odel will be drawn wit h " m issing" pixels where fragm ent s were discarded. The disca r d keyword is quit e useful because it can appear anywhere in a fragm ent shader. You can put t he discard st at em ent near t he beginning of a com plex fragm ent shader and gradually m ove it down in t he code as you verify t hat t hings are working properly. Sim ilarly, you can assign values t o gl_FragColor t hat convey debugging inform at ion. I f you have a m at hem at ical funct ion in your shader t hat is expect ed t o range fr om [ 0,1] and average 0.5, you can assign solid green t o gl_FragColor if t he value is less t han 0, solid red if it is bet w een 0 and 0.5, solid blue if it is bet ween 0.5 and 1.0, and solid whit e if it is great er t han 1.0. This kind of debugging inform at ion can quickly t ell you whet her a cert ain com put at ion is going ast ray.

8.3.3. Use Simple Geometry For debugging t ext ure com put at ions, it m ay be useful t o render a single lar ge rect angle w it h ident it y m at rices for t he m odeling, viewing, and pr oj ect ion m at rices and t o look carefully at what is occurring. Use a dist inct t ext ure im age, for exam ple, color bars or a grayscale ram p, so t hat you can visually verify t hat t he t ext uring operat ion is occurring as you expect it t o.

8.4. Shader Development Tools I n com ing years, we should see som e excit ing advances in t he area of t ools for shader developm ent . This sect ion describes shader developm ent t ools available at t he t im e of t his writ ing.

8.4.1. RenderMonkey As t he era of program m able graphics hardware has unfolded, we've learned t hat t here is m ore t o developing shaders t han j ust developing t he code for t he shaders t hem selves. Shaders can be highly cust om ized t o t he point t hat t hey m ay work as int ended only on a single m odel. Shader sour ce code, t ext ures, geom et ry, and init ial values for uniform variables are all im port ant part s of a product ion- qualit y shader. Shader developm ent t ools m ust capt ure all t he essent ial elem ent s of a shader and allow t hese elem ent s t o easily be m odified and m aint ained. Anot her fact or in shader developm ent is t hat t he person writ ing t he shader is not necessarily t he sam e person developing t he applicat ion code t hat deploys t he shader. Oft en, an art ist will be em ployed t o design t ext ures and t o cont ribut e t o or even t o cont rol t he shader developm ent process. The collaborat ion bet w een t he art ist and program m er is an im port ant one for ent ert ainm ent - based applicat ions and m ust be support ed by shader developm ent t ools. An int egrat ed developm ent environm ent ( I DE) allows program m ers and art ist s t o develop and experim ent wit h shaders out side t he environm ent of t he applicat ion. This reduces t he com plexit y of t he shader developm ent t ask and encourages rapid prot ot yping and experim ent at ion. Finished shaders are a form of int ellect ual propert y, and m aint enance, port abilit y, and easy deploym ent t o a variet y of plat form s are essent ial t o m axim izing t he benefit of t his t ype of com pany asset . The idea behind an I DE is t hat all t he essent ial elem ent s of t he finished shader can be encapsulat ed, m anaged, shared, and export ed for use in t he final applicat ion. ATI first released an I DE called RenderMonkey in 2002. I n it s init ial release, RenderMonkey support ed shader developm ent for Direct X vert ex shaders and pixel shader s. How ever, RenderMonkey was archit ect ed in such a way t hat it could easily be ext ended t o support ot her shader program m ing languages. I n 2004, ATI and 3Dlabs collaborat ed t o produce a version of RenderMonkey t hat cont ains support for high- level shader developm ent in OpenGL wit h t he OpenGL Shading Language in addit ion t o t he support for Direct X shader developm ent . The RenderMonkey I DE is current ly available for free from bot h com panies' Web sit es ( ht t p: / / developer.3dlabs.com and ht t p: / / w ww .at i.com / developer) . RenderMonkey was designed for ext ensibilit y. At it s core is a flexible fram ework t hat allows easy incorporat ion of shading languages. I t is an environm ent t hat is language agnost ic, allowing any high- level shading language t o be support ed by m eans of plug- ins. I t current ly support s t he pixel shaders and vert ex shaders defined in Microsoft 's Direct X 8.1 and 9.0, t he High- Level Shader Language ( HLSL) defined in Direct X 9.0, and t he OpenGL Shading Language. I n RenderMonkey, t he encapsulat ion of all t he inform at ion necessary t o re- creat e a shading effect is called an effect workspace. An effect workspace consist s of effect s group nodes, variable nodes, and st ream m apping nodes. Each effect s group is m ade up of one or m ore effect nodes, and each effect node is m ade up of one or m ore r ender ing passes. Each rendering pass m ay cont ain rendering st at e, source code for a vert ex shader and a fragm ent shader, geom et ry, and t ext ures. All t he effect dat a is organized int o a t ree hierarchy t hat is visible in t he workspace view er. Effect s group nodes collect relat ed effect s int o a single cont ainer. This is som et im es handy for t am ing t he com plexit y of dealing wit h lot s of different effect s. You m ight also use an effect s

group as a cont ainer for several sim ilar effect s wit h different perform ance charact erist ics ( for inst ance, " best qualit y," " fast ," and " fast est " ) . The crit eria for grouping t hings wit hin effect s groups is ent irely up t o you. Effect nodes encom pass all t he inform at ion needed t o im plem ent a r eal- t im e visual effect . The effect m ay be com posed of m ult iple passes. St art ing st at e is inherit ed from a default effect t o provide a known st art ing st at e for all effect s. The default effect can st ore effect dat a t hat is com m on t o all shading effect s. Pass nodes define a drawing operat ion ( i.e., a rendering pass) . Each pass inherit s dat a from previous passes wit hin t he effect , and t he first pass inherit s fr om t he default effect . A t ypical pass cont ains a ver t ex shader and fragm ent shader pair, a render st at e block, t ext ures, geom et ry, and nodes of ot her t ypes ( for exam ple, variable nodes) . Different geom et ry can be used in each pass t o render t hings like fur. Variable nodes define t he param et ers t hat are available from w it hin a shader. For t he OpenGL Shading Language, variable nodes are t he m echanism s for defining uniform variables. I nt uit ive nam es and t ypes can be assigned t o variable nodes, and t he cont ent s of a variable node can be m anipulat ed wit h a GUI widget . RenderMonkey is built com plet ely out of plug- ins. Sour ce code for som e plug- ins is available, and you are encouraged t o w rit e your ow n plug- ins t o perform t asks necessary for your work flow or t o support im port ing and export ing your dat a wit h propriet ary for m at s. Exist ing Render Monkey m odules are list ed here. z

z

z

z

z

z

Shader edit orsThese are m odeled on t he int erface of Microsoft 's Visual St udio t o provide an int uit ive int erface; t hey support edit ing of vert ex and fragm ent shaders; synt ax color ing; creat ion of OpenGL, HLSL, and assem bly language shaders. Variable edit orsShader param et ers can be edit ed wit h GUI widget s t hat " know" t he underlying dat a t ype for edit ing; edit ors exist for colors, vect ors, m at rices, scalars; cust om widget s can be cr eat ed. Ar t ist edit orShader param et ers relevant t o t he art designer can be present ed in an art ist friendly fashion so t hat t hey can be viewed and m odified; program m ers can select which param et ers are art ist - edit able; changes can be seen in real t im e. Preview ersThese allow real- t im e viewing of t he shading effect ; changes t o t he shader source code or it s param et ers are im m ediat ely reflect ed in t he preview window; view set t ings are cust om izable; views ( front , back, side, et c.) are preset ; Direct X 9.0 and OpenGL Shading Language/ OpenGL previews are available. Export erEveryt hing required t o recreat e a shading effect is encapsulat ed and writ t en int o a single XML file. I m port erEver yt hing required t o recreat e a shading effect is read back from an XML file.

The XML file form at was chosen as t he basis for encapsulat ing shader inform at ion in RenderMonkey because it is an indust ry st andard, it has a user- readable file form at , it is user ext ensible, and it wor ks wit h t he m any fr ee parsers t hat are available. I t is relat ively easy t o adapt an exist ing XML parser for your own use or t o writ e a new one. The XML file t hat encapsulat es a shader effect cont ains all shader source code, all render st at es, all m odels, and all t ext ure inform at ion. This m akes it st raight forward t o cr eat e, m anage, and share shader asset s.

8.4.2. OpenGL Shading Language Compiler Front End

I n June 2003, 3Dlabs released an open source version of it s lexical analyzer, parser, and sem ant ic checker ( i.e., an OpenGL Shading Language COMPI LER FRONT END ) . This code reads an OpenGL shader and t urns it int o a t oken st ream . This process is called LEXI CAL ANALYSI S. The t oken st ream is t hen processed t o ensure t hat t he program consist s of valid st at em ent s. This process is referred t o as SYNTACTI C ANALYSI S, or parsing. SEMANTI C ANALYSI S is t hen perform ed t o det erm ine w het her t he shader conform s t o t he sem ant ic rules defined or im plied by t he OpenGL Shading Language specificat ion. The result of t his processing is t urned int o a high- level represent at ion of t he original source code. This high- level int erm ediat e language ( HI L) is a binary repr esent at ion of t he original source code t hat can be furt her processed by a t arget specific back end t o provide m achine code for a part icular t ype of graphics hardware. I t is ant icipat ed t hat individual hardware vendors w ill im plem ent t he back end needed for t heir part icular hardware. The com piler back end will t ypically include int ellect ual propert y and hardw are- specific inform at ion t hat is propriet ary t o t he graphics hardware vendor. I t is not ant icipat ed t hat 3Dlabs or ot her hardware vendors will m ake public t he source code for t heir com piler back ends. St ill, t he com piler front end provided by 3Dlabs has been, and will cont inue t o be, a useful t ool for t he developm ent of t he OpenGL Shading Language, and it will be useful for ot her organizat ions t hat want t o develop an OpenGL Shading Language com piler or t ools for shader developm ent . As t he language specificat ion was nearing com plet ion, t he com piler front end was being developed. Except for t he pr eprocessor ( which w as derived from anot her open source preprocessor) , it was im plem ent ed from scrat ch wit h t he publicly available syst em ut ilit ies flex and bison. I t was not derived from exist ing code. This m ade it a clean way t o double- check t he specificat ion and discover language flaws before t he specificat ion w as released. I ndeed, a num ber of such flaws were discovered t hrough t his effort , and, as a result , t he specificat ion was im proved before it s release. Because of it s clean im plem ent at ion, t he OpenGL Shading Language com piler front end also serves as addit ional t echnical docum ent at ion about t he language. The specificat ion should be your first st op, but if you really want t o know t he det ails of what 's allowed in t he language and what 's not , st udying t he com piler front end will provide a definit ive answ er. OpenGL im plem ent ors t hat base t heir com piler on t he com piler fr ont end fr om 3Dlabs will also be doing a big favor t o t heir end users: The sem ant ics of t he OpenGL Shading Language will be checked in t he sam e way for all im plem ent at ions t hat use t his front end. This will benefit developers as t hey encount er consist ent error- checking bet w een different im plem ent at ions. Alt hough few readers of t his book will likely end up developing an OpenGL Shading Language com piler , t his resource is nevert heless a useful one t o know about . The source code for t he com piler front end is available for download at t he 3Dlabs Web sit e ( ht t p: / / developer.3dlabs.com ) . Using t he GLSL com piler front end, 3Dlabs has also writ t en a t ool called GLSLvalidat e. This t ool reads a file cont aining a shader and uses t he com piler front - end t o parse it . Errors are report ed in t he out put window. This t ool can be execut ed on any plat form ; an OpenGL 2.0 driver is not required. This t ool is pr ovided as open source by 3Dlabs. Anot her t ool from 3Dlabs, GLSLParserTest , det er m ines whet her your OpenGL im plem ent at ion properly support s t he OpenGL Shading Language specificat ion. I t at t em pt s t o com pile som e 200 shaders and com pares t he result s against t he reference com piler. Som e shaders should com pile and som e should not . Result s are print ed, and t he inform at ion log for any shader can be exam ined. Again, t his t ool is provided as open sour ce ( see ht t p: / / developer.3dlabs.com ) .

8.5. Scene Graphs by Mike Weiblen A SCENE GRAPH is a hierarchical dat a st ruct ure cont aining a descript ion of a scene t o be rendered. Rat her t han explicit ly coding a scene t o be rendered as OpenGL API calls, an applicat ion builds a scene gr aph, t hen calls t he scene graph rendering engine t o do t he act ual rendering by t raver sing t he dat a st ruct ure. I n t his way, a scene graph allows a developer t o focus on what t o draw, rat her t han on t he det ails of how t o draw. I n t ypical t erm inology, t he t erm scene graph is oft en used t o describe t he t oolkit for bot h t he dat a st ruct ure it self and t he rendering engine t hat t raverses t he dat a st ruct ure t o render t he scene. Scene graphs m ake it possible for a developer of visualizat ion applicat ions t o leverage t he perform ance of OpenGL wit hout necessarily being an expert in all t he det ails of OpenGL; t he scene graph it self encapsulat es OpenGL best pract ices. Because a scene graph is a t oolkit layer on t op of OpenGL, it raises t he program m ing abst ract ions closer t o t he applicat ion dom ain. As a t ree, a scene graph consist s of nodes t hat have one or m ore children. Since OpenGL st at e oft en has a hierarchical nat ure ( such as t he m odel- view m at rix st ack) , t hat st at e can easily be m apped t o nodes in t he t ree. Som e of t he at t ribut es and benefit s of scene gr aphs: z

z

z

z

z

z

z

Encapsulat ion of best pract ices for rendering OpenGL, such as opt im ized GL st at e cont rol; opt im ized int ernal dat a represent at ions; and m inim al geom et ry sent for rendering based on cam era visibilit y. I m plem ent at ion of sophist icat ed rendering archit ect ures for perform ance, for exam ple, pervasive m ult it hreading, m ult i- CPU, m ult igraphics pipe, or synchronized m ult isyst em clust ering. Definit ion of t he out put viewport s: For com plex display syst em s such as m ult iproj ect or dom es, t he scene gr aph can provide support for nonlinear dist ort ion com pensat ion. Hierarchical in- m em ory represent at ion, for exam ple, a t r ee of nodes wit h child nodes or a direct ed acyclic graph ( DAG) . OpenGL st at e cont rol: By associat ing GL st at e wit h nodes in t he gr aph, t he scene graph renderer collect s t hose st at e request s and applies t hem efficient ly t o t he OpenGL pipeline. The scene graph can im plem ent a form of lazy st at e applicat ion, by which it avoids forcing st at e changes down t he pipe if no geom et ry act ually requires it for rendering. St at e can be inherit ed from parent s down t o children. View culling, by which t he spat ial posit ion of scene gr aph nodes are t est ed against t he posit ion of a cam era's view volum e; only if a node will act ually cont ribut e t o visible pixels will it s geom et ry be sent t o t he pipe for rendering. ( There is no reason t o send vert ices t o t he pipe for geom et ry t hat is behind t he eyepoint .) I nst ancing of asset s: one m odel of a t ire can be referenced four t im es on a single car; a single car can be inst anced m any t im es t o cr eat e a parking lot full of cars.

The t ypical applicat ion code for a scene graph- based rendering applicat ion is concept ually not m uch m ore t han

at startup, build the scenegraph (loading files from disc, etc) do forever { update the camera position and other time-varying entities in the scene (such as vehicles or particle effects) draw the scene }

Alt hough a scene graph allows a visualizat ion developer t o focus on what t o draw rat her t han on t he det ails of how t o draw it , t hat does not m ean t he developer is isolat ed from direct OpenGL cont rol: not at allt he developer could define cust om rendering m et hods. But for m any com m on rendering t asks, t he scene graph renderer already provides a com plet e solut ion and act s as a reusable t oolkit for leveraging t hat capabilit y. As expect ed from a well- designed t oolkit , t here are no inviolat e rules; if you as t he developer really need t o do som et hing out of t he ordinary, t he t oolkit provides t he avenues necessary. The palet t e of nodes available for const ruct ing t he scene graph provides ways t o apply at t ribut es t o be inherit ed by t he children of t hat node. Here are som e exam ples ( cert ainly not an exhaust ive list ) of scene graph nodes. z

Parent nodeMult iple child nodes can be at t ached.

z

Transform nodesThe children are t ransform ed by t he parent 's t ransform at ion m at rix.

z

z

z z

Sw it ch nodesOnly one child of t he parent will be rendered, governed by a swit ching condit ion. Level- of- det ail node ( a specialized swit ch node) Only one child is rendered, according t o t he dist ance of t he node from t he cam era. Billboard nodeI t s children are aut om at ically orient ed t oward t he cam era. Light nodeOt her nodes in t he scene are illum inat ed by light s at t he posit ion and wit h t he at t ribut es cont ained here.

By helping t he developer focus on " what " rat her t han " how ," a scene graph can sim plify t he use of shader s. For exam ple, using t he hier archical nat ure of a scene gr aph, a developer can com pose a scene t hat has a shader wit h default values for uniform variables near t he root of t he scene graph, so it affect s m uch of t he scene. Alt ernat ive values for uniform variables at t ached at lower nodes can specialize t he shader for a part icular piece of geom et ry. The scene graph rendering engine can t ake over t he t asks of det erm ining if or when t o com pile or link t he com ponent s of t he shader and when t o act ually send updat es for uniform variables t o t he pipeline, depending on visibilit y. Several OpenGL scene graph product s are current ly available. OpenGL Perform er ( ht t p: / / w ww .sgi.com / product s/ soft w are/ perform er/ ) , a com m ercial product available fr om SGI , has recent ly included support for OpenGL 2.0 and t he OpenGL Shading Language. OpenSceneGraph ( or OSG, ht t p: / / w ww .openscenegraph.org/ ) is an open source proj ect t hat also has recent ly included support for OpenGL 2.0 and t he OpenGL Shading Language. OpenSG ( ht t p: / / www.opensg.org) is anot her open source OpenGL scene graph. Depending on your applicat ion, any one of t hese could save you a great deal of t im e and applicat ion developm ent effort .

8.6. Summary Writ ing shaders is sim ilar in m any ways t o ot her soft ware engineering t asks. A good dose of com m on sense can go a long way. Soft ware engineer ing principles should be applied j ust as for any ot her soft ware engineering t ask. This is especially t rue in t hese early generat ions of program m able graphics hardware. Shader developm ent is m ore challenging because ear ly OpenGL Shading Language im plem ent at ions m ight be incom plet e in som e ways, com pilers will be im m at ure, perform ance charact erist ics m ay differ widely bet ween vendors, and t ools t o aid shader developm ent are in t heir infancy. RenderMonkey is one shader developm ent t ool t hat is available now; hopefully ot hers will rapidly follow. On t he ot her hand, w rit ing shaders for program m able graphics hardware pr esent s som e unique challenges. Good decisions need t o be m ade about how t o split t he com put at ion bet w een t he CPU, t he vert ex processor, and t he fragm ent processor. I t is useful t o have a solid foundat ion in m at hem at ics and com put er gr aphics before at t em pt ing t o writ e shaders. Thorough knowledge of how OpenGL works is also a key asset , and having som e underst anding of t he underlying graphics hardware can be helpful. I t oft en pays t o collaborat e wit h an art ist when developing a shader. This can help you develop a shader t hat is param et erized in such a way t hat it can be put t o a variet y of uses in t he final applicat ion.

8.7. Further Information Num erous books describe sound soft ware engineering principles and pract ices. Two t hat describe t act ics specific t o developing shaders are Text uring and Modeling: A Procedur al Approach by Ebert et al. ( 2002) and Advanced RenderMan: Creat ing CGI for Mot ion Pict ures by Apodaca and Grit z ( 1999) . Som e of t he shader developm ent discussion in t hese books is specific t o RenderMan, but m any of t he principles are also relevant t o developing shader s w it h t he OpenGL Shading Language. For perform ance t uning, t he best advice I have right now is t o becom e good friends wit h t he developer r elat ions st aff at your favorit e graphics hardware com pany ( or com panies) . These are t he people t hat can provide you wit h addit ional insight or inform at ion about t he underlying graphics hardware archit ect ure and t he relat ive perform ance of various aspect s of t he hardw are. Unt il we go t hrough anot her generat ion or t wo of program m able gr aphics hardware developm ent ( and perhaps even longer) , perform ance differences bet ween various hardware archit ect ures will depend on t he t r ade- offs m ade by t he hardware archit ect s and t he driver developers. Scour t he Web sit es of t hese com panies, at t end t heir present at ions at t r ade shows, and ask lot s of quest ions. The ATI developer Web sit e cont ains a num ber of present at ions on RenderMonkey. The RenderMonkey I DE and docum ent at ion can be dow nloaded from eit her t he ATI Web sit e or t he 3Dlabs Web sit e. The 3Dlabs Web sit e cont ains t he open source GLSL com piler front - end, t he GLSLvalidat e t ool, and ot her useful t ools and exam ples. 1 . 3Dlabs developer Web sit e. ht t p: / / developer.3dlabs.com 2 . Apodaca, Ant hony A., and Larry Grit z, Advanced RenderMan: Creat ing CGI for Mot ion Pict ures, Morgan Kaufm ann Publishers, San Francisco, 1999. ht t p: / / w ww .r ender m an.org/ RMR/ Books/ arm an/ m at erials.ht m l 3 . ATI developer Web sit e. ht t p: / / w ww .at i.com / developer 4 . Ebert , David S., John Hart , Bill Mark, F. Kent on Musgrave, Darwyn Peachey, Ken Perlin, and St even Worley, Text uring and Modeling: A Procedural Approach, Thir d Edit ion, Morgan Kaufm ann Publishers, San Francisco, 2002. ht t p: / / w ww .t ext uringandm odeling.com 5 . NVI DI A developer Web sit e. ht t p: / / developer.nvidia.com 6 . OpenGL Perform er Web sit e. ht t p: / / w ww .sgi.com / product s/ soft w are/ perform er/ 7 . OpenSceneGraph Web sit e. ht t p: / / w ww .openscenegraph.org/ 8 . OpenSG Web sit e. ht t p: / / www.opensg.org

Chapter 9. Emulating OpenGL Fixed Functionality The pr ogram m abilit y of OpenGL opens m any new possibilit ies for never- before- seen rendering effect s. Program m able shaders can provide result s t hat are superior t o OpenGL fixed funct ionalit y, especially in t he area of realism . Nevert heless, it can st ill be inst ruct ive t o exam ine how som e of OpenGL's fixed funct ionalit y rendering st eps could be im plem ent ed wit h OpenGL shaders. While sim plist ic, t hese code snippet s m ay be useful as st epping st ones t o bigger and bet t er t hings. This chapt er describes OpenGL shader code t hat m im ics t he behavior of t he OpenGL fixed funct ionalit y vert ex and fragm ent processing. The shader code snippet s are derived from t he Full OpenGL Pipeline and Pixel Pipeline shaders developed by Dave Baldwin for inclusion in t he whit e paper OpenGL 2.0 Shading Language. Furt her refinem ent of t his shader code occurr ed for t he first edit ion of t his book. These code snippet s were t hen verified and finalized wit h a t ool called Sh a de r Ge n t hat t akes a descript ion of OpenGL's fixed funct ionalit y st at e and aut om at ically generat es t he equivalent shaders. Sh a de r Ge n was im plem ent ed by I nderaj Bains and Joshua Doss and is available from t he 3Dlabs Web sit e. The goal of t he shader code in t his chapt er is t o fait hfully represent OpenGL fixed funct ionalit y. The code exam ples in t his chapt er reference exist ing OpenGL st at e w herever possible t hrough built - in variables. I n your own shaders, feel free t o provide t hese values as user- defined uniform variables rat her t han accessing exist ing OpenGL st at e. By doing t his, you will be prepared t o t hrow off t he shackles of t he OpenGL st at e m achine and ext end your shaders in excit ing and different new ways. But don't get t oo enam ored wit h t he shader s present ed in t his chapt er. I n lat er chapt ers of t his book, we explore a variet y of shaders t hat provide bet t er result s t han t hose discussed in t his chapt er.

9.1. Transformation The feat ures of t he OpenGL Shading Language m ake it very easy t o express t ransform at ions bet w een t he coordinat e spaces defined by OpenGL. We've already seen t he t ransform at ion t hat will be used by alm ost every vert ex shader. The incom ing vert ex posit ion m ust be t ransform ed int o clipping coordinat es for use by t he fixed funct ionalit y st ages t hat occur aft er vert ex processing. This is done in one of t w o ways, eit her t his: // Transform vertex to clip space gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

or t his: gl_Position = ftransform();

The only difference bet ween t hese t wo m et hods is t hat t he second case is guarant eed t o com put e t he t ransform ed posit ion in exact ly t he sam e way as t he fixed funct ionalit y m et hod. Som e im plem ent at ions m ay have different hardware pat hs t hat result in sm all differences bet w een t he t ransform ed posit ion as com put ed by t he first m et hod and as com put ed by fixed funct ionalit y. This can cause problem s in r ender ing if a m ult ipass algorit hm is used t o render t he sam e geom et ry m ore t han once. I n t his case, t he second m et hod is preferred because it produces t he sam e t r ansform ed posit ion as t he fixed funct ionalit y. OpenGL specifies t hat light posit ions are t ransform ed by t he m odelview m at rix w hen t hey ar e provided t o OpenGL. This m eans t hat t hey are st ored in eye coordinat es. I t is oft en convenient t o perform light ing com put at ions in eye space, so it is oft en necessary t o t ransform t he incom ing vert ex posit ion int o eye coordinat es as shown in List ing 9.1.

List in g 9 .1 . Com pu t a t ion of e ye coor din a t e posit ion vec4 ecPosition; vec3 ecPosition3;

// in 3 space

// Transform vertex to eye coordinates if (NeedEyePosition) { ecPosition = gl_ModelViewMatrix * gl_Vertex; ecPosition3 = (vec3(ecPosition)) / ecPosition.w; }

This snippet of code com put es t he hom ogeneous point in eye space ( a ve c4 ) as w ell as t he nonhom ogeneous point ( a ve c3 ) . Bot h values are useful as w e shall see. To perform light ing calculat ions in eye space, incom ing surface norm als m ust also be t ransform ed. A built - in uniform variable is available t o access t he norm al t r ansform at ion m at rix, as shown in List ing 9.2.

List in g 9 .2 . Tr a n sfor m a t ion of n or m a l normal = gl_NormalMatrix * gl_Normal;

I n m any cases, t he applicat ion m ay not know anyt hing about t he char act erist ics of t he surface norm als t hat ar e being provided. For t he light ing com put at ions t o w ork correct ly, each incom ing norm al m ust be norm alized so t hat it is unit lengt h. For OpenGL fixed funct ionalit y, norm alizat ion is a m ode in OpenGL t hat we can cont rol by providing t he sym bolic const ant GL_NORMALI ZE t o glEnable or glDisable. I n an OpenGL shader, if norm alizat ion is required, we do it as shown in List ing 9.3.

List in g 9 .3 . N or m a liza t ion of n or m a l normal = normalize(normal);

Som et im es an applicat ion will always be sending norm als t hat are unit lengt h and t he m odelview m at rix is always one t hat does uniform scaling. I n t his case, rescaling can be used t o avoid t he possibly expensive square root operat ion t hat is a necessary part of norm alizat ion. I f t he rescaling fact or is supplied by t he applicat ion t hr ough t he OpenGL API , t he norm al can be rescaled as shown in List ing 9.4.

List in g 9 .4 . N or m a l r e sca lin g normal = normal * gl_NormalScale;

The rescaling fact or is st ored as st at e wit hin OpenGL and can be accessed from wit hin a shader by t he built - in uniform variable gl_NormalScale. Text ure coordinat es can also be t ransform ed. A t ext ure m at rix is defined for each t ext ure coordinat e set in OpenGL and can be accessed wit h t he built - in uniform m at rix array variable gl_TextureMatrix. I ncom ing t ext ure coordinat es can be t ransform ed in t he sam e m anner as vert ex posit ions, as shown in List ing 9.5.

List in g 9 .5 . Te x t u r e coor din a t e t r a n sfor m a t ion gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;

9.2. Light Sources The light ing com put at ions defined by OpenGL are som ewhat involved. Let 's st art by defining a funct ion for each of t he t ypes of light sources defined by OpenGL: direct ional light s, point light s, and spot light s. We pass in variables t hat st ore t he t ot al am bient , diffuse, and specular cont ribut ions from all light sources. These m ust be init ialized t o 0 before any of t he light source com put at ion rout ines are called.

9.2.1. Directional Lights A direct ional light is assum ed t o be at an infinit e dist ance from t he obj ect s being lit . According t o t his assum pt ion, all light rays fr om t he light source are parallel when t hey reach t he scene. Therefore a single direct ion vect or can be used for every point in t he scene. This assum pt ion sim plifies t he m at h, so t he code t o im plem ent a direct ional light source is sim pler and t ypically runs fast er t han t he code for ot her t ypes of light s. Because t he light source is assum ed t o be infinit ely far away, t he direct ion of m axim um highlight s is t he sam e for every point in t he scene. This direct ion vect or can be com put ed ahead of t im e for each light source i and st ored in gl_LightSource[i].halfVector. This t ype of light source is useful for m im icking t he effect s of a light source like t he sun. The direct ional light funct ion shown in List ing 9.6 com put es t he cosine of t he angle bet ween t he surface norm al and t he light direct ion, as well as t he cosine of t he angle bet ween t he surface norm al and t he half angle bet ween t he light direct ion and t he view ing direct ion. The form er value is m ult iplied by t he light 's diffuse color t o com put e t he diffuse com ponent fr om t he light . The lat t er value is raised t o t he power indicat ed by gl_FrontMaterial.shininess before being m ult iplied by t he light 's specular color.

List in g 9 .6 . D ir e ct ion a l ligh t sou r ce com pu t a t ion void DirectionalLight(in int i, in vec3 normal, inout vec4 ambient, inout vec4 diffuse, inout vec4 specular) { float nDotVP; // normal . light direction float nDotHV; // normal . light half vector float pf; // power factor nDotVP = max(0.0, dot(normal, normalize(vec3(gl_LightSource[i].position)))); nDotHV = max(0.0, dot(normal, vec3(gl_LightSource[i].halfVector))); if (nDotVP == 0.0) pf = 0.0; else pf = pow(nDotHV, gl_FrontMaterial.shininess); ambient += gl_LightSource[i].ambient; diffuse += gl_LightSource[i].diffuse * nDotVP; specular += gl_LightSource[i].specular * pf; }

The only w ay eit her a diffuse reflect ion com ponent or a specular reflect ion com ponent can be

present is if t he angle bet ween t he light source direct ion and t he surface norm al is in t he range [ - 90°, 90°] . We det erm ine t he angle by exam ining nDotVP. This value is set t o t he great er of 0 and t he cosine of t he angle bet ween t he light source direct ion and t he surface norm al. I f t his value ends up being 0, t he value t hat det erm ines t he am ount of specular reflect ion is set t o 0 as well. Our direct ional light funct ion assum es t hat t he vect ors of int erest are norm alized, so t he dot product bet w een t wo vect ors result s in t he cosine of t he angle bet ween t hem .

9.2.2. Point Lights Point light s m im ic light s t hat are near t he scene or wit hin t he scene, such as lam ps or ceiling light s or st reet light s. There are t wo m ain differences bet ween point light s and direct ional light s. First , wit h a point light source, t he direct ion of m axim um highlight s m ust be com put ed at each vert ex rat her t han wit h t he precom put ed value fr om gl_LightSource[i].halfVector. Second, light received at t he surface is expect ed t o decrease as t he point light source get s fart her and fart her away. This is called ATTENUATI ON. Each light source has const ant , linear, and quadrat ic at t enuat ion fact ors t hat are t aken int o account when t he light ing cont ribut ion from a point light is com put ed. These differences show up in t he first few lines of t he point light funct ion ( see List ing 9.7) . The first st ep is t o com put e t he vect or from t he surface t o t he light posit ion. We com put e t his dist ance by using t he lengt h funct ion. Next , we norm alize VP so t hat we can use it in a dot product oper at ion t o com put e a pr oper cosine value. We t hen com put e t he at t enuat ion fact or and t he direct ion of m axim um highlight s as required. The rem aining code is t he sam e as for our direct ional light funct ion except t hat t he am bient , diffuse, and specular t erm s ar e m ult iplied by t he at t enuat ion fact or.

List in g 9 .7 . Poin t ligh t sou r ce com pu t a t ion void PointLight(in int i, in vec3 eye, in vec3 ecPosition3, in vec3 normal, inout vec4 ambient, inout vec4 diffuse, inout vec4 specular) { float nDotVP; // normal . light direction float nDotHV; // normal . light half vector float pf; // power factor float attenuation; // computed attenuation factor float d; // distance from surface to light source vec3 VP; // direction from surface to light position vec3 halfVector; // direction of maximum highlights // Compute vector from surface to light position VP = vec3(gl_LightSource[i].position) - ecPosition3; // Compute distance between surface and light position d = length(VP); // Normalize the vector from surface to light position VP = normalize(VP); // Compute attenuation attenuation = 1.0 / (gl_LightSource[i].constantAttenuation + gl_LightSource[i].linearAttenuation * d + gl_LightSource[i].quadraticAttenuation * d * d); halfVector = normalize(VP + eye);

nDotVP = max(0.0, dot(normal, VP)); nDotHV = max(0.0, dot(normal, halfVector)); if (nDotVP == 0.0) pf = 0.0; else pf = pow(nDotHV, gl_FrontMaterial.shininess); ambient += gl_LightSource[i].ambient * attenuation; diffuse += gl_LightSource[i].diffuse * nDotVP * attenuation; specular += gl_LightSource[i].specular * pf * attenuation; }

One opt im izat ion t hat we could m ake is t o have t wo point light funct ions, one t hat com put es t he at t enuat ion fact or and one t hat does not . I f t he values for t he const ant , linear, and quadrat ic at t enuat ion fact ors are ( 1, 0, 0) ( t he default values) , we could use t he funct ion t hat does not com put e at t enuat ion and get bet t er perform ance.

9.2.3. Spotlights I n st age and cinem a, spot light s proj ect a st rong beam of light t hat illum inat es a well- defined area. The illum inat ed area can be furt her shaped t hrough t he use of flaps or shut t ers on t he sides of t he light . OpenGL includes light at t ribut es t hat sim ulat e a sim ple t ype of spot light . Whereas point light s are m odeled as sending light equally in all direct ions, OpenGL m odels spot light s as light sources t hat are rest rict ed t o producing a cone of light in a part icular direct ion. The first and last part s of our spot light funct ion ( see List ing 9.8) look t he sam e as our point light funct ion ( see List ing 9.7) . The differences occur in t he m iddle of t he funct ion. A spot light has a focus direct ion ( gl_LightSource[i].spotDirection) , and t his direct ion is dot t ed wit h t he vect or from t he light posit ion t o t he surface ( VP) . The result ing cosine value is com pared t o t he precom put ed cosine cut off value ( gl_LightSource[i].spotCosCutoff) t o det erm ine whet her t he posit ion on t he surface is inside or out side t he spot light 's cone of illum inat ion. I f it is out side, t he spot light at t enuat ion is set t o 0; ot herwise, t his value is raised t o a power specified by gl_LightSource[i].spotExponent. The result ing spot light at t enuat ion fact or is m ult iplied by t he previously com put ed at t enuat ion fact or t o give t he overall at t enuat ion fact or. The rem aining lines of code are t he sam e as t hey were for point light s.

List in g 9 .8 . Spot ligh t com pu t a t ion

void SpotLight(in int i, in vec3 eye, in vec3 ecPosition3, in vec3 normal, inout vec4 ambient, inout vec4 diffuse, inout vec4 specular) { float nDotVP; // normal . light direction float nDotHV; // normal . light half vector float pf; // power factor float spotDot; // cosine of angle between spotlight float spotAttenuation; // spotlight attenuation factor float attenuation; // computed attenuation factor float d; // distance from surface to light source vec3 VP; // direction from surface to light position

vec3 halfVector;

// direction of maximum highlights

// Compute vector from surface to light position VP = vec3(gl_LightSource[i].position) - ecPosition3; // Compute distance between surface and light position d = length(VP); // Normalize the vector from surface to light position VP = normalize(VP); // Compute attenuation attenuation = 1.0 / (gl_LightSource[i].constantAttenuation + gl_LightSource[i].linearAttenuation * d + gl_LightSource[i].quadraticAttenuation * d * d); // See if point on surface is inside cone of illumination spotDot = dot(-VP, normalize(gl_LightSource[i].spotDirection)); if (spotDot < gl_LightSource[i].spotCosCutoff) spotAttenuation = 0.0; // light adds no contribution else spotAttenuation = pow(spotDot, gl_LightSource[i].spotExponent); // Combine the spotlight and distance attenuation. attenuation *= spotAttenuation; halfVector = normalize(VP + eye); nDotVP = max(0.0, dot(normal, VP)); nDotHV = max(0.0, dot(normal, halfVector)); if (nDotVP == 0.0) pf = 0.0; else pf = pow(nDotHV, gl_FrontMaterial.shininess); ambient += gl_LightSource[i].ambient * attenuation; diffuse += gl_LightSource[i].diffuse * nDotVP * attenuation; specular += gl_LightSource[i].specular * pf * attenuation; }

9.3. Material Properties and Lighting OpenGL light ing calculat ions require knowing t he viewing direct ion in t he eye coordinat e syst em in or der t o com put e specular reflect ion t erm s. By default , t he view direct ion is assum ed t o be parallel t o and in t he direct ion of t he z axis. OpenGL also has a m ode t hat requires t he view ing direct ion t o be com put ed from t he origin of t he eye coordinat e syst em ( local view er) . To com put e t his, we can t ransform t he incom ing vert ex int o eye space by using t he current m odelview m at rix. The x, y, and z coordinat es of t his point are divided by t he hom ogeneous coordinat e w t o get a ve c3 value t hat can be used direct ly in t he light ing calculat ions. The com put at ion of t his eye coordinat e posit ion ( ecPosition3) was illust rat ed in Sect ion 9.1. To get a unit vect or corresponding t o t he viewing direct ion, we norm alize and negat e t he eye space posit ion. Shader code t o im plem ent t hese com put at ions is shown in List ing 9.9.

List in g 9 .9 . Loca l vie w e r com pu t a t ion if (LocalViewer) eye = -normalize(ecPosition3); else eye = vec3(0.0, 0.0, 1.0);

Wit h t he viewing direct ion calculat ed, we can init ialize t he variables t hat accum ulat e t he am bient , diffuse, and specular light ing cont ribut ions from all t he light sources in t he scene. We can t hen call t he funct ions defined in t he previous sect ion t o com put e t he cont ribut ions from each light source. I n t he code in List ing 9.10, we assum e t hat all light s wit h an index less t han t he const ant N u m En a ble d Light s are enabled. Direct ional light s are dist inguished by having a posit ion param et er wit h a hom ogeneous ( w ) coordinat e equal t o 0 at t he t im e t hey were provided t o OpenGL. ( These posit ions are t ransform ed by t he m odelview m at rix when t he light is specified, so t he w coordinat e rem ains 0 aft er t ransform at ion if t he last colum n of t he m odelview m at rix is t he t ypical ( 0 0 0 1) ) . Point light s are dist inguished by having a spot light cut off angle equal t o 180.

List in g 9 .1 0 . Loop t o com pu t e con t r ibu t ion s fr om a ll e n a ble d ligh t sou r ce s // Clear the light intensity accumulators amb = vec4(0.0); diff = vec4(0.0); spec = vec4(0.0); // Loop through enabled lights, compute contribution from each for (i = 0; i < NumEnabledLights; i++) { if (gl_LightSource[i].position.w == 0.0) DirectionalLight(i, normal, amb, diff, spec); else if (gl_LightSource[i].spotCutoff == 180.0) PointLight(i, eye, ecPosition3, normal, amb, diff, spec); else SpotLight(i, eye, ecPosition3, normal, amb, diff, spec); }

One of t he changes m ade t o OpenGL in version 1.2 was t o add funct ionalit y t o com put e t he color at a vert ex in t w o part s: a prim ary color t hat cont ains t he com binat ion of t he em issive, am bient , and diffuse t erm s as com put ed by t he usual light ing equat ions; and a secondary color t hat cont ains j ust t he specular t erm as com put ed by t he usual light ing equat ions. I f t his m ode is not enabled ( t he default case) , t he prim ary color is com put ed wit h t he com binat ion of em issive, am bient , diffuse, and specular t erm s. Com put ing t he specular cont ribut ion separat ely allows specular highlight s t o be applied aft er t ext uring has occurred. The specular value is added t o t he com put ed color aft er t ext uring has occurred, t o allow t he specular highlight s t o be t he color of t he light sour ce rat her t han t he color of t he surface. List ing 9.11 shows how t o com put e t he surface color ( according t o OpenGL rules) w it h everyt hing but t he specular cont ribut ion:

List in g 9 .1 1 . Su r fa ce color com pu t a t ion , om it t in g t h e spe cu la r cont r ibut ion color = gl_FrontLightModelProduct.sceneColor + amb * gl_FrontMaterial.ambient + diff * gl_FrontMaterial.diffuse;

The OpenGL Shading Language convenient ly provides us a built - in variable ( gl_FrontLightModelProduct.sceneColor) t hat cont ains t he em issive m at erial propert y for front facing surfaces plus t he product of t he am bient m at erial propert y for front - facing surfaces and t he global am bient light for t he scene ( i.e., gl_FrontMaterial.emission + gl_FrontMaterial.ambient * gl_LightModel.ambient) . We can add t his t oget her wit h t he int ensit y of reflect ed am bient light and t he int ensit y of reflect ed diffuse light . Next , w e can do t he appropriat e com put at ions, depending on whet her t he separat e specular color m ode is indicat ed, as shown in List ing 9.12.

List in g 9 .1 2 . Fin a l su r fa ce color com pu t a t ion if (SeparateSpecular) gl_FrontSecondaryColor = vec4(spec * gl_FrontMaterial.specular, 1.0); else color += spec * gl_FrontMaterial.specular; gl_FrontColor = color;

There is no need t o perform clam ping on t he values assigned t o gl_Front-SecondaryColor and gl_FrontColor because t hese are aut om at ically clam ped by definit ion.

9.4. Two-Sided Lighting To m im ic OpenGL's t wo- sided light ing behavior, you need t o invert t he surface norm al and perform t he sam e com put at ions as defined in t he preceding sect ion, using t he back- facing m at erial propert ies. You can probably do it m ore cleverly t han t his, but it m ight look like List ing 9.13. The funct ions DirectionalLight, PointLight, and SpotLight t hat are referenced in t his code segm ent are ident ical t o t he funct ions described in Sect ion 9.2 except t hat t he value glBackMaterial.shininess is used in t he com put at ions inst ead of t he value glFrontMaterial.shininess.

List in g 9 .1 3 . Tw o- side d ligh t in g com pu t a t ion normal = -normal; // Clear the light intensity accumulators amb = vec4(0.0); diff = vec4(0.0); spec = vec4(0.0); // Loop through enabled lights, compute contribution from each for (i = 0; i < NumEnabledLights; i++) { if (gl_LightSource[i].position.w == 0.0) DirectionalLight(i, normal, amb, diff, spec); else if (gl_LightSource[i].spotCutoff == 180.0) PointLight(i, eye, ecPosition3, normal, amb, diff, spec); else SpotLight(i, eye, ecPosition3, normal, amb, diff, spec); } color = gl_BackLightModelProduct.sceneColor + amb * gl_BackMaterial.ambient + diff * gl_BackMaterial.diffuse; if (SeparateSpecular) gl_BackSecondaryColor = vec4(spec * gl_BackMaterial.specular, 1.0); else color += spec * gl_BackMaterial.specular; gl_BackColor = color;

There is no need t o perform clam ping on t he values assigned t o gl_BackSecondaryColor and gl_BackColor because t hese are aut om at ically clam ped by definit ion.

9.5. No Lighting I f no enabled light s are in t he scene, it is a sim ple m at t er t o pass t he pervert ex color and secondary color for furt her processing wit h t he com m ands shown in List ing 9.14.

List in g 9 .1 4 . Se t t in g fin a l color va lu e s w it h n o ligh t in g if (SecondaryColor) gl_FrontSecondaryColor = gl_SecondaryColor; // gl_FrontColor will be clamped automatically by OpenGL gl_FrontColor = gl_Color;

9.6. Fog I n OpenGL, DEPTH - CUI NG and fog effect s are cont rolled by fog param et ers. A fog fact or is com put ed accor ding t o one of t hree equat ions, and t his fog fact or perform s a linear blend bet w een t he fog color and t he com put ed color for t he fragm ent . The dept h value t o be used in t he fog equat ion can be eit her t he fog coordinat e passed in as a st andard vert ex at t ribut e ( gl_FogCoord) or t he eye- coordinat e dist ance from t he eye. I n t he lat t er case, it is usually sufficient t o approxim at e t he dept h value as t he absolut e value of t he z- coordinat e in eye space ( i.e., abs( ecPosition.z) ) . When t here is a w ide angle of view, t his appr oxim at ion m ay cause a not iceable art ifact ( t oo lit t le fog) near t he edges. I f t his is t he case, you could com put e z as t he t rue dist ance from t he eye t o t he fragm ent wit h length( ecPosition) . ( This m et hod involves a square root com put at ion, so t he code m ay run slower as a result .) The choice of which dept h value t o use would norm ally be done in t he vert ex shader as follows: if (UseFogCoordinate) gl_FogFragCoord = gl_FogCoord; else gl_FogFragCoord = abs(ecPosition.z);

A linear com put at ion ( which corresponds t o t he t radit ional com put er graphics operat ion of dept h- cuing) can be select ed in OpenGL wit h t he sym bolic const ant GL_LI NEAR. For t his case, t he fog fact or f is com put ed wit h t he following equat ion:

start, end, and z are all dist ances in eye coordinat es. start is t he dist ance t o t he st art of t he fog effect , end is t he dist ance t o t he end of t he effect , and z is t he value st ored in gl_FogFragCoord. We can explicit ly provide t he st art and end posit ions as uniform variables, or we can access t he current values in OpenGL st at e by using t he built - in variables gl_Fog.start and gl_Fog.end. The shader code t o com put e t he fog fact or wit h t he built - in variables for accessing OpenGL st at e is shown in List ing 9.15.

List in g 9 .1 5 . GL_ LI N EAR fog com pu t a t ion fog = (gl_Fog.end - gl_FogFragCoord)) * gl_Fog.scale;

Because 1.0 / ( gl_Fog.end gl_Fog.start) doesn't depend on any per- vert ex or per- fragm ent st at e, t his value is precom put ed and m ade available as t he built - in variable gl_Fog.scale. We can achieve a m or e r ealist ic fog effect wit h an exponent ial funct ion. Wit h a negat ive exponent value, t he exponent ial funct ion will m odel t he dim inishing of t he original color as a funct ion of dist ance. A sim ple exponent ial fog funct ion can be select ed in OpenGL wit h t he sym bolic const ant GL_EXP. The form ula corresponding t o t his fog funct ion is f = e( density .z)

The z value is com put ed as described for t he previous funct ion, and density is a value t hat represent s t he densit y of t he fog. density can be provided as a uniform variable, or t he built - in

variable gl_Fog.density can be used t o obt ain t he current value from OpenGL st at e. The larger t his value becom es, t he " t hicker" t he fog becom es. For t his funct ion t o work as int ended, density m ust be great er t han or equal t o 0. The OpenGL Shading Language has a built - in e x p ( base e) funct ion t hat w e can use t o perform t his calculat ion. Our OpenGL shader code t o com put e t he preceding equat ion is shown in List ing 9.16.

List in g 9 .1 6 . GL_ EXP fog com pu t a t ion fog = exp(-gl_Fog.density * gl_FogFragCoord);

The final fog funct ion defined by OpenGL is select ed wit h t he sym bolic const ant GL_EXP2 and is defined as f = e( density .z) 2

This funct ion changes t he slope of t he exponent ial decay funct ion by squaring t he exponent . The OpenGL shader code t o im plem ent it is sim ilar t o t he previous funct ion ( see List ing 9.17) .

List in g 9 .1 7 . GL_ EXP2 fog com pu t a t ion fog = exp(-gl_Fog.density * gl_Fog.density * gl_FogFragCoord * gl_FogFragCoord);

OpenGL also r equires t he final value for t he fog fact or t o be lim it ed t o t he range [ 0,1] . We can accom plish t his wit h t he st at em ent in List ing 9.18.

List in g 9 .1 8 . Cla m pin g t h e fog fa ct or fog = clamp(fog, 0.0, 1.0);

Any of t hese t hree fog funct ions can be com put ed in eit her a vert ex shader or a fragm ent shader. Unless you have very large polygons in your scene, you probably won't see any difference if t he fog fact or is com put ed in t he vert ex shader and passed t o t he fragm ent shader as a varying variable. This w ill probably also give you bet t er perform ance overall, so it 's generally t he pr eferred approach. I n t he fr agm ent shader, when t he ( alm ost ) final color is com put ed, t he fog fact or can be used t o com put e a linear blend bet ween t he fog color and t he ( alm ost ) final fragm ent color. The OpenGL shader code in List ing 9.19 does t he t rick by using t he fog color saved as part of current OpenGL st at e.

List in g 9 .1 9 . Applyin g fog t o com pu t e fin a l color va lue color = mix(vec3(gl_Fog.color), color, fog); The code present ed in t his sect ion achieves t he sam e result s as OpenGL's fixed funct ionalit y. But wit h program m abilit y, you are free t o use a com plet ely different approach t o com put e fog effect s.

9.7. Texture Coordinate Generation OpenGL can be set up t o com put e t ext ure coordinat es aut om at ically, based only on t he incom ing vert ex posit ions. Five m et hods are defined, and each can be useful for cert ain purposes. The t ext ure generat ion m ode specified by GL_OBJECT_LI NEAR is useful for cases in which a t ext ure is t o rem ain fixed t o a geom et ric m odel, such as in a t errain m odeling applicat ion. GL_EYE_LI NEAR is useful for pr oducing dynam ic cont our lines on an obj ect . Exam ples of t his usage include a scient ist st udying isosurfaces or a geologist int erpret ing seism ic dat a. GL_SPHERE_MAP can generat e t ext ure coordinat es for sim ple environm ent m apping. GL_REFLECTI ON_MAP and GL_NORMAL_MAP can work in conj unct ion wit h cube m ap t ext ures. GL_REFLECTI ON_MAP passes t he reflect ion vect or as t he t ext ure coordinat e. GL_NORMAL_MAP sim ply passes t he com put ed eye space nor m al as t he t ext ure coordinat e. A funct ion t hat generat es sphere m ap coordinat es according t o t he OpenGL specificat ion is shown in List ing 9.20.

List in g 9 .2 0 . GL_ SPH ERE_ M AP com pu t a t ion vec2 SphereMap(in vec3 ecPosition3, in vec3 normal) { float m; vec3 r, u; u = normalize(ecPosition3); r = reflect(u, normal); m = 2.0 * sqrt(r.x * r.x + r.y * r.y + (r.z + 1.0) * (r.z + 1.0)); return vec2(r.x / m + 0.5, r.y / m + 0.5); }

A funct ion t hat generat es reflect ion m ap coordinat es according t o t he OpenGL specificat ion looks alm ost ident ical t o t he funct ion shown in List ing 9.20. The difference is t hat it ret urns t he reflect ion vect or as it s result ( see List ing 9.21) .

List in g 9 .2 1 . GL_ REFLECTI ON _ M AP com pu t a t ion vec3 ReflectionMap(in vec3 ecPosition3, in vec3 normal) { float NdotU, m; vec3 u; u = normalize(ecPosition3); return (reflect(u, normal)); }

List ing 9.22 shows t he code for select ing bet w een t he five t ext ure generat ion m et hods and com put ing t he appropriat e t ext ure coordinat e values.

List in g 9 .2 2 . Te x t u r e coor din a t e ge n e r a t ion com pu t a t ion // Compute sphere map coordinates if needed if (TexGenSphere)

sphereMap = SphereMap(ecposition3, normal); // Compute reflection map coordinates if needed if (TexGenReflection) reflection = ReflectionMap(ecposition3, normal); // Compute texture coordinate for each enabled texture unit for (i = 0; i < NumEnabledTextureUnits; i++) { if (TexGenObject) { gl_TexCoord[i].s = dot(gl_Vertex, gl_ObjectPlaneS[i]); gl_TexCoord[i].t = dot(gl_Vertex, gl_ObjectPlaneT[i]); gl_TexCoord[i].p = dot(gl_Vertex, gl_ObjectPlaneR[i]); gl_TexCoord[i].q = dot(gl_Vertex, gl_ObjectPlaneQ[i]); } if (TexGenEye) { gl_TexCoord[i].s gl_TexCoord[i].t gl_TexCoord[i].p gl_TexCoord[i].q }

= = = =

dot(ecPosition, dot(ecPosition, dot(ecPosition, dot(ecPosition,

gl_EyePlaneS[i]); gl_EyePlaneT[i]); gl_EyePlaneR[i]); gl_EyePlaneQ[i]);

if (TexGenSphere) gl_TexCoord[i] = vec4(sphereMap, 0.0, 1.0); if (TexGenReflection) gl_TexCoord[i] = vec4(reflection, 1.0); if (TexGenNormal) gl_TexCoord[i] = vec4(normal, 1.0); }

I n t his code, we assum e t hat each t ext ure unit less t han NumEnabledTexture-Units is enabled. I f t his value is 0, t he whole loop is skipped. Ot herwise, each t ext ure coordinat e t hat is needed is com put ed in t he loop. Because t he sphere m ap and reflect ion com put at ions do not depend on any of t he t ext ure unit st at e, t hey can be perform ed once and t he result is used for all t ext ure unit s. For t he GL_OBJECT_LI NEAR and GL_EYE_LI NEAR m et hods, t here is a plane equat ion for each com ponent of each set of t ext ure coordinat es. For t he form er case, we generat e t he com ponent s of gl_TexCoord[0] by m ult iplying t he plane equat ion coefficient s for t he specified com ponent by t he incom ing vert ex posit ion. For t he lat t er case, we com put e t he com ponent s of gl_TexCoord[0] by m ult iplying t he plane equat ion coefficient s by t he eye coordinat e posit ion of t he vert ex. Depending on what t ype of t ext ure access is done during fragm ent pr ocessing, it m ay not be necessary t o com put e t he t , p, or q t ext ure com ponent , [ 1] so t hese com put at ions could be elim inat ed. [1] For historical reasons, the OpenGL texture coordinate components are named s, t, r, and q. Because of the desire to have single-letter, component-selection names in the OpenGL Shading Language, components for textures are named s, t, p, and q. This lets us avoid using r, which is needed for selecting color components as r, g, b, and a.

9.8. User Clipping To t ake advant age of OpenGL's user clipping ( w hich rem ains as fixed funct ionalit y bet ween vert ex processing and fragm ent pr ocessing in program m able OpenGL) , a vert ex shader m ust t ransform t he incom ing vert ex posit ion int o t he sam e coordinat e space as t hat in which t he user clip planes ar e st ored. The usual case is t hat t he user clip planes are st ored in eye space coordinat es, so t he OpenGL shader code shown in List ing 9.23 can provide t he t ransform ed ver t ex posit ion.

List in g 9 .2 3 . Use r - clippin g com pu t a t ion gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;

9.9. Texture Application The built - in t ext ure funct ions read values from t ext ur e m em ory. The values read from t ext ure m em ory are used in a variet y of ways. OpenGL fixed funct ionalit y includes support for t ext ure applicat ion form ulas enabled wit h t he sym bolic const ant s GL_REPLACE, GL_MODULATE, GL_DECAL, GL_BLEND, and GL_ADD. These m odes operat e different ly, depending on t he form at of t he t ext ure being accessed. The following code illust rat es t he case in which an RGBA t ext ure is accessed wit h t he sam pler tex0. The variable color is init ialized t o be gl_Color and t hen m odified as needed so t hat it cont ains t he color value t hat result s from t ext ure applicat ion. GL_REPLACE is t he sim plest t ext ure applicat ion m ode of all. I t sim ply replaces t he curr ent fragm ent color wit h t he value read from t ext ure m em ory. See List ing 9.24.

List in g 9 .2 4 . GL_ REPLACE com pu t a t ion color = texture2D(tex0, gl_TexCoord[0].xy);

GL_MODULATE causes t he incom ing fragm ent color t o be m ult iplied by t he value ret rieved from t ext ure m em ory. This is a good t ext ure funct ion t o use if light ing is com put ed before t ext uring ( e.g., t he vert ex shader perform s t he light ing com put at ion, and t he fragm ent shader does t he t ext uring) . Whit e can be used as t he base color for an obj ect rendered wit h t his t echnique, and t he t ext ure t hen provides t he diffuse color. This t echnique is illust r at ed wit h t he OpenGL shader code in List ing 9.25.

List in g 9 .2 5 . GL_ M OD ULATE com pu t a t ion color *= texture2D(tex0, gl_TexCoord[0].xy);

GL_DECAL is useful for applying an opaque im age t o a por t ion of an obj ect . For inst ance, you m ight want t o apply a num ber and com pany logos t o t he surfaces of a race car or t at t oos t o t he skin of a charact er in a gam e. When an RGBA t ext ure is accessed, t he alpha value at each t exel linearly int erpolat es bet ween t he incom ing fragm ent 's RGB value and t he t ext ure's RGB value. The incom ing fragm ent 's alpha value is used as is. The code for im plem ent ing t his m ode is in List ing 9.26.

List in g 9 .2 6 . GL_ D ECAL com pu t a t ion vec4 texture = texture2D(tex0, gl_TexCoord[0].xy); vec3 col = mix(color.rgb, texture.rgb, texture.a); color = vec4(col, color.a);

GL_BLEND is t he only t ext ure applicat ion m ode t hat t akes t he current t ext ure environm ent color int o account . The RGB values read from t he t ext ure linearly int erpolat e bet ween t he RGB values of t he incom ing fr agm ent and t he t ext ure environm ent color. We com put e t he new alpha value by m ult iplying t he alpha of t he incom ing fragm ent by t he alpha read from t he t ext ure.

The OpenGL shader code is shown in List ing 9.27.

List in g 9 .2 7 . GL_ BLEN D com pu t a t ion vec4 texture = texture2D(tex0, gl_TexCoord[0].xy); vec3 col = mix(color.rgb, gl_TextureEnvColor[0].rgb, texture.rgb); color = vec4(col, color.a * texture.a);

GL_ADD com put es t he sum of t he incom ing fragm ent color and t he value read from t he t ext ure. The t w o alpha values are m ult iplied t oget her t o com put e t he new alpha value. This is t he only t radit ional t ext ure applicat ion m ode for which t he result ing values can exceed t he range [ 0,1] , so w e clam p t he final result ( see List ing 9.28) .

List in g 9 .2 8 . GL_ AD D com pu t a t ion vec4 texture = texture2D(tex0, gl_TexCoord[0].xy); color.rgb += texture.rgb; color.a *= texture.a; color = clamp(color, 0.0, 1.0);

The t ext ur e- com bine environm ent m ode t hat was added in OpenGL 1.3 and ext ended in OpenGL 1.4 defines a large num ber of addit ional sim ple ways t o perform t ext ure applicat ion. A variet y of new form ulas, source values, and operands were defined. The m apping of t hese addit ional m odes int o OpenGL shader code is st raight forward but t iresom e, so it is om it t ed here.

9.10. Summary The rendering form ulas specified by OpenGL have been r easonable ones t o im plem ent in fixed funct ionalit y hardware for t he past decade or so, but t hey are not necessarily t he best ones t o use in your shaders. We look at bet t er- perform ing and m ore realist ic shaders for light ing and reflect ion in subsequent chapt ers. St ill, it can be inst ruct ive t o see how t hese form ulas can be expressed in shaders writ t en in t he OpenGL Shading Language. The shader exam ples present ed in t his chapt er dem onst rat e t he expression of t hese fixed funct ionalit y rendering form ulas, but t hey should not be considered opt im al im plem ent at ions. Take t he ideas and t he shading code illust rat ed in t his chapt er and adapt t hem t o your own needs.

9.11. Further Information 3Dlabs has m ade available a nift y t ool for com paring fixed funct ionalit y behavior wit h equivalent shaders. Wit h t his applicat ion, called ShaderGen, you can set up OpenGL st at e and view fixed funct ionalit y behavior, and t hen, wit h a single m ouse click, cause t he applicat ion t o aut om at ically generat e equivalent GLSL shaders. You can t hen exam ine, edit , com pile, and link t he generat ed shaders. You can easily swit ch bet ween fixed funct ionalit y m ode and program m able shader m ode and com pare result s. Through t he graphical user int erface, you can also m odify t he st at e t hat affect s rendering. Full source code for t his applicat ion is also available. The OpenGL Pr ogram m ing Guide, Fift h Edit ion, by t he OpenGL Archit ect ure Review Board, Woo, Neider , Davis, and Shr einer ( 2005) , cont ains m ore com plet e descript ions of t he various form ulas present ed in t his chapt er. The funct ionalit y is defined in t he OpenGL specificat ion, The OpenGL Graphics Syst em : A Specificat ion, ( Version 2.0) , by Mar k Segal and Kur t Akeley, edit ed by Jon Leech and Pat Brow n ( 2004) . Basic graphics concept s like t ransform at ion, light ing, fog, and t ext uring are also covered in st andard graphics t ext s such as I nt roduct ion t o Com put er Graphics by Foley, van Dam , et al., ( 1994) . Real- Tim e Rendering, by Akenine- Möller and Haines ( 2002) , also cont ains good descript ions of t hese basic t opics. 1 . 3Dlabs developer Web sit e. ht t p: / / developer.3dlabs.com 2 . Akenine- Möller, Tom as, E. Haines, Real- Tim e Rendering, Second Edit ion, A K Pet ers, Lt d., Nat ick, Massachuset t s, 2002. ht t p: / / w ww .realt im erendering.com 3 . Baldwin, Dave, OpenGL 2.0 Shading Language Whit e Paper, Version 1.0, 3Dlabs, Oct ober, 2001. 4 . Foley, J.D., A. van Dam , S.K. Feiner, J.H. Hughes, and R.L. Philips, I nt roduct ion t o Com put er Graphics, Addison- Wesley, Reading, Massachuset t s, 1994. 5 . Foley, J.D., A. van Dam , S.K. Feiner, and J.H. Hughes, Com put er Graphics: Principles and Pract ice, Second Edit ion in C, Second Edit ion, Addison- Wesley, Reading, Massachuset t s, 1996. 6 . OpenGL Archit ect ure Review Board, Dave Shreiner, J. Neider, T. Davis, and M. Woo, OpenGL Program m ing Guide, Fift h Edit ion: The Official Guide t o Learning OpenGL, Version 2, Addison- Wesley, Reading, Massachuset t s, 2005. 7 . OpenGL Archit ect ure Review Board, OpenGL Reference Manual, Fourt h Edit ion: The Official Reference t o OpenGL, Version 1.4, Edit or: Dave Shreiner, Addison- Wesley, Reading, Massachuset t s, 2004. 8 . Segal, Mark, and Kurt Akeley, The OpenGL Graphics Syst em : A Specificat ion ( Version 2.0) , Edit or ( v1.1) : Chris Fr azier, ( v1.21.5) : Jon Leech, ( v2.0) : Jon Leech and Pat Brow n, Sept . 2004. ht t p: / / w ww .opengl.org/ docum ent at ion/ spec.ht m l

Chapter 10. Stored Texture Shaders Text ure m apping is a powerful m echanism built int o OpenGL. At t he t im e OpenGL was init ially defined ( 1992) , t ext ure- m apping hardware was j ust st art ing t o be available on com m ercial product s. Nowadays, t ext ure m apping is available on graphics hardware at all price point s, even ent ry- level consum er graphics boards. When OpenGL 1.0 was defined, t ext ure m apping had a fairly narrow definit ion. I t was sim ply a way t o apply an im age t o t he surface of an obj ect . Since t hen, hardware has becom e capable of doing m uch m ore in t his area, and researchers have com e up wit h a lot of int erest ing t hings t o do wit h t ext ures ot her t han j ust plast ering im ages on surfaces. The scope of t ext ure m apping has also been ext ended in OpenGL. Text ur e obj ect s w ere one of t he key addit ions in OpenGL 1.1. Three- dim ensional t ext ures were m ade par t of t he st andard in OpenGL 1.2. The capabilit y of har dw are t o access t wo or m ore t ext ures sim ult aneously was exposed in OpenGL 1.3, along wit h cube m ap t ext ures and a fr am ework for support ing com pressed t ext ures form at s. OpenGL 1.4 added support for dept h t ext ures and shadows, aut om at ic m ipm ap generat ion, and anot her t ext ure w rap m ode ( m irrored repeat ) . I f you need a quick review of how t ext uring works in OpenGL, refer t o Sect ion 1.10. The pr ogram m abilit y int roduced wit h t he OpenGL Shading Language allows for a m uch broader definit ion of t ext ure m apping. Wit h program m able shaders, an applicat ion can read values from any num ber of t ext ur es and use t hem in any way t hat m akes sense. This includes support ing sophist icat ed algorit hm s t hat use t he result s of one t ext ure access t o define t he param et ers of anot her t ext ure access. Text ures can also st ore int erm ediat e rendering result s; t hey can serve as lookup t ables for com plex funct ions; t hey can st ore norm als, norm al pert urbat ion fact ors, gloss values, visibilit y inform at ion, and polynom ial coefficient s; and do m any ot her t hings. These t hings could not be done nearly as easily, if at all, in unext ended OpenGL, and t his flexibilit y m eans t hat t ext ure m aps are com ing closer t o being general- purpose m em ory t hat can be used for arbit r ary purposes. ( Filt ering and wrapping behavior st ill different iat e t ext urem ap access from norm al m em ory access operat ions.) This chapt er describes several shaders t hat , at t heir core, rely on looking up values in t ext ure m em ory and using t hose values t o achieve int erest ing effect s. We st art by t alking a lit t le bit about how t ext ures are accessed from wit hin a shader, and t hen we look at several exam ples of shaders t hat access t ext ure m em ory for various purposes ot her t han j ust t he st r aight forw ard applicat ion of an im age t o t he surface of a 3D obj ect .

10.1. Access to Texture Maps from a Shader Applicat ions are required t o set up and init ialize t ext uring st at e properly before execut ing a shader t hat accesses t ext ure m em ory. An applicat ion m ust perform t he following st eps t o set up a t ext ure for use wit hin a shader: 1.

Select a specific t ext ure unit , and m ake it act ive by calling glActiveTexture.

2.

Creat e a t ext ure obj ect , and bind it t o t he act ive t ext ure unit by calling glBindTexture.

3.

Set various param et ers ( wrapping, filt ering, et c.) of t he t ext ure obj ect by calling glTexParameter.

4.

Define t he t ext ure by calling glTexImage.

I f fixed funct ionalit y is used, t he applicat ion m ust perform t w o addit ional st eps: enabling t he desired t ext ure on t he t ext ure unit by calling glEnable and set t ing t he t ext ure funct ion for t he t ext ure unit ( m odulat e, decal, replace, et c.) by calling glTexEnv. ( These st eps are not required when an OpenGL shader is used, because t he fixed funct ionalit y hierarchy of t ext ure enables is ignored and t he t ext ure funct ion is expressed wit hin t he shader code.) When t hese st eps have been com plet ed, t he t ext ure is ready for use by an OpenGL shader. I t is quit e st raight forward t o access t ext ures from wit hin a shader aft er t ext ure st at e has been set up properly by t he applicat ion. The OpenGL Shading Language has built - in dat a t ypes ( see Sect ion 3.2.4) and built - in funct ions ( see Sect ion 5.7) t o accom plish t his t ask. A uniform variable of t ype sa m ple r m ust be used t o access a t ext ure from wit hin a shader. Wit hin a shader, a sam pler is considered an opaque dat a t ype cont aining a value t hat can access a part icular t ext ure. The shader is responsible for declaring such a uniform variable for each t ext ure t hat it want s t o access. The applicat ion m ust provide a value for t he sam pler before execut ion of t he shader, as described in Sect ion 7.9. The t ype of t he sam pler indicat es t he t ype of t ext ure t hat is t o be accessed. A variable of t ype sa m ple r 1 D accesses a 1D t ext ure; a variable of t ype sa m ple r 2 D accesses a 2D t ext ure; a variable of t ype sa m ple r 3 D accesses a 3D t ext ure; a variable of t ype sa m ple r Cu be accesses a cube m ap t ext ure; and variables of t ype sa m ple r Sh a dow 1 D and sa m ple r Sh a dow 2 D access 1D and 2D dept h t ext ures. For inst ance, if t he applicat ion int ends t o use t ext ure unit 4 t o st ore a 2D t ext ure, t he shader m ust declare a uniform variable of t ype sa m ple r 2 D , and t he applicat ion m ust load a value of 4 int o t his variable before execut ing t he shader . The built - in funct ions texture1D, texture2D, texture3D, textureCube, shadow1D, and so on, perform t ext ure access wit hin a shader. The first argum ent in each of t hese built - in funct ions is a sam pler, and t he t ype of t he sam pler m ust correspond t o t he nam e of t he funct ion. For inst ance, a sam pler of t ype sa m ple r 1 D m ust be t he first argum ent t o texture1D, a sam pler of t ype sa m ple r 2 D m ust be t he first argum ent t o texture2D, and so on. Mism at ches cause a com piler er ror t o occur. Each of t hese built - in t ext ure- access funct ions also t akes a t ext ure coor dinat e as an argum ent . Hardware uses t his t ext ure coordinat e t o det erm ine which locat ions in t he t ext ure m ap are t o be accessed. A 1D t ext ure is accessed wit h a single float ing- point t ext ure coordinat e. A 2D t ext ure is accessed wit h a ve c2 , and a 3D t ext ure is accessed w it h a ve c3 . Proj ect ive versions of t he t ext ure access funct ions are also provided. I n t hese funct ions, t he individual com ponent s of t he t ext ure coordinat e are divided by t he last com ponent of t he t ext ure coordinat e, and t he

result is used in t he t ext ur e access operat ion. There are som e differences bet ween accessing a t ext ure from a ver t ex shader and accessing a t ext ure from a fragm ent shader ( t he OpenGL Shading Language allows bot h) . The level of det ail t o be used for accessing a m ipm ap t ext ure is calculat ed by fixed funct ionalit y in bet w een t he vert ex processor and t he fr agm ent processor. Therefore, t his value is known wit hin t he fragm ent processor but not wit hin t he vert ex processor. For t his reason, t he OpenGL Shading Language includes special built - in funct ions t hat can be used only in a vert ex shader t hat allow s t he level of det ail t o be expressed direct ly as a funct ion argum ent . The OpenGL Shading Language also includes built - in funct ions t hat can be used only in a fragm ent shader t hat allows a level- of- det ail bias t o be passed in. This bias value is added t o t he m echanically com put ed level- of- det ail value. I n t his way, a shader writ er can add a lit t le ext ra sharpness or blurriness t o t he t ext ure m apping funct ion, depending on t he sit uat ion. I f any of t hese funct ions is used wit h a t ext ure t hat is not a m ipm ap t ext ure, t he level- of- det ail bias value is ignored. The built - in funct ions t o access cube m aps ( textureCube and textureCubeLod) operat e in t he sam e way as defined for fixed funct ionalit y. The t ext ure coordinat e t hat is pr ovided is t reat ed as a direct ion vect or t hat em anat es from t he cent er of a cube. This value select s one of t he cube m ap's 2D t ext ures, based on t he coordinat e wit h t he largest m agnit ude. The ot her t wo coordinat es are divided by t he absolut e value of t his coordinat e and scaled and biased t o calculat e a 2D coordinat e t hat will be used t o access t he chosen face of t he cube m ap. The built - in funct ions t o access dept h t ext ures ( shadow1D, shadow2D, et c.) also operat e in t he sam e way as defined for fixed funct ionalit y. The t ext ure accessed by one of t hese funct ions m ust have a base int ernal form at of GL_DEPTH_COMPONENT. The value t hat is ret urned when t his t ype of t ext ure is accessed depends on t he t ext ur e- com parison m ode, t he t ext urecom parison funct ion, and t he dept h t ext ure m ode. Each of t hese values can be set wit h glTexParameter. The built - in t ext ure access funct ions operat e according t o t he current st at e of t he t ext ure unit t hat is being accessed and according t o t he param et ers of t he t ext ure obj ect t hat is bound t o t hat t ext ure unit . I n ot her w ords, t he value ret urned by t he built - in t ext ure access funct ions t ake int o considerat ion t he t ext uring st at e t hat has already been est ablished for t he t ext ur e unit and t he t ext ure obj ect , including wrap m ode, m inificat ion filt er, m agnificat ion filt er, border color, m inim um / m axim um level of det ail, t ext ure com parison m ode, and so on.

10.2. Simple Texturing Example Wit h t hese built - in funct ions for accessing t ext ures, it 's easy t o writ e a sim ple shader t hat does t ext ure m apping. Our goal is t o creat e a t ext ure- m apped sphere by using a realist ic t ext ure of t he eart h's surface. Applicat ion code described in t his chapt er cam e from ogl2demo, writ t en prim arily by Bart hold Licht enbelt . Sim ilar code is available in GLSLdemo, writ t en by Philip Rideout and available for download from t he 3Dlabs Web sit e. To achieve good result s, it helps t o st art wit h excellent t ext ures. Color Plat e 3 shows an exam ple of a t wo- dim ensional t ext ure m ap, a cylindrical proj ect ion of t he eart h's surface, including clouds. This im age, and ot her im ages in t his sect ion, were obt ained fr om t he NASA Web sit e and were creat ed by Ret o St öckli of t he NASA/ Goddard Space Flight Cent er. These im ages of Eart h are part of a series of consist ent ly processed dat a set s ( land, sea ice, and clouds) fr om NASA's rem ot e sensing sat ellit e, t he Moderat e Resolut ion I m aging Spect roradiom et er, or MODI S. Dat a from t his sat ellit e was com bined wit h ot her relat ed dat a set s ( t opography, land cover, and cit y light s) , all at 1 kilom et er resolut ion. The result ing series of im ages is ext r em ely high resolut ion ( 43200 x 21600 pixels) . For our purposes, we can get by wit h a m uch sm aller t ext ure, so we use versions t hat have been sam pled down t o 2048 x 1024.

10.2.1. Application Setup We assum e t hat t he im age dat a has been read int o our applicat ion and t hat t he im age widt h, im age height , a point er t o t he im age dat a, and a t ext ure nam e generat ed by OpenGL can be passed t o our t ext ure init ializat ion funct ion: init2DTexture(GLint texName, GLint texWidth, GLint texHeight, GLubyte *texPtr) { glBindTexture(GL_TEXTURE_2D, texName); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texWidth, texHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, texPtr); }

This init ializat ion funct ion cr eat es a t ext ure obj ect nam ed texName. Calls t o glTexParameter set t he wrapping behavior and filt ering m odes. We've chosen t o use repeat as our wr apping behavior and t o do linear filt ering. We specify t he dat a for t he t ext ure by calling glTexImage2D ( t he values passed t o t his funct ion depend on how t he im age dat a has been st ored in m em ory) . When w e're ready t o use t his t ext ure, we can use t he following OpenGL calls: glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, earthTexName);

This sequence of calls set s t he act ive t ext ure unit t o t ext ure unit 0, binds our eart h t ext ure t o t his t ext ure unit , and m akes it act ive. We need t o pr ovide t he values for t wo uniform variables. The vert ex shader needs t o know t he light posit ion, and t he fragm ent shader needs t o know t he t ext ure unit t hat is t o be accessed. We define t he light posit ion as a ve c3 in t he vert ex shader nam ed lightPosition and t he t ext ure unit as a sa m ple r 2 D in t he fragm ent shader nam ed EarthTexture. Our applicat ion code needs t o det erm ine t he locat ion of t hese uniform variables and t hen provide appropriat e values. We assum e t hat our shaders have been com piled, linked using

a program obj ect whose handle is programObj, and inst alled as part of current st at e. We can m ake t he following calls t o init ialize t he uniform variables: lightLoc = glGetUniformLocation(programObj, "LightPosition"); glUniform3f(lightLoc, 0.0, 0.0, 4.0); texLoc = glGetUniformLocation(programObj, "EarthTexture"); glUniform1i(texLoc, 0);

The light source posit ion is set t o a point right in front of t he obj ect along t he viewing axis. We plan t o use t ext ure unit 0 for our eart h t ext ur e, so t hat is t he value loaded int o our sam pler variable. The applicat ion can now m ake appr opriat e OpenGL calls t o draw a sphere, and t he eart h t ext ure will be applied. A surface norm al, a 2D t ext ure coordinat e, and a vert ex posit ion m ust be specified for each vert ex.

10.2.2. Vertex Shader The vert ex shader for our sim ple t ext uring exam ple is sim ilar t o t he sim ple brick vert ex shader described in Sect ion 6.2. The m ain difference is t hat a t ext ure coordinat e is passed in as a vert ex at t ribut e, and it is passed on as a varying variable wit h t he built - in variable nam e gl_TexCoord[0] ( see List ing 10.1) .

List in g 1 0 .1 . Ve r t e x sh a de r for sim ple t e x t ur ing varying float LightIntensity; uniform vec3 LightPosition; const float specularContribution = 0.1; const float diffuseContribution = 1.0 - specularContribution; void main() { vec3 ecPosition vec3 tnorm vec3 lightVec vec3 reflectVec vec3 viewVec

= = = = =

vec3(gl_ModelViewMatrix * gl_Vertex); normalize(gl_NormalMatrix * gl_Normal); normalize(LightPosition - ecPosition); reflect(-lightVec, tnorm); normalize(-ecPosition);

float spec spec

= clamp(dot(reflectVec, viewVec), 0.0, 1.0); = pow(spec, 16.0);

LightIntensity

= diffuseContribution * max(dot(lightVec, tnorm), 0.0) + specularContribution * spec;

gl_TexCoord[0] gl_Position

= gl_MultiTexCoord0; = ftransform();

}

10.2.3. Fragment Shader The fragm ent shader show n in List ing 10.2 applies t he eart h t ext ure t o t he incom ing geom et ry. So, for inst ance, if w e define a sphere where t he s t ext ure coordinat es are relat ed t o longit ude ( e.g., 0° longit ude is s = 0, and 360° longit ude is s = 1.0) and t t ext ure coordinat es are relat ed t o lat it ude ( 90° sout h lat it ude is t = 0.0, and 90° nort h lat it ude is t = 1.0) , t hen we can apply

t he t ext ur e m ap t o t he sphere's geom et ry as shown in Color Plat e 6. I n t he follow ing fragm ent shader, t he incom ing s and t t ext ure coordinat e values ( part of t he built - in varying variable gl_TexCoord0) are used t o look up a value from t he t ext ure curr ent ly bound t o t ext ure unit 0. The result ing value is m ult iplied by t he light int ensit y com put ed by t he ver t ex shader and passed as a varying variable. The color is t hen clam ped, and an alpha value of 1.0 is added t o creat e t he final fragm ent color, which is sent on for furt her processing, including dept h t est ing. The result ing im age as m apped ont o a sphere is shown in Color Plat e 6.

List in g 1 0 .2 . Fr a gm e n t sh a de r for sim ple t e x t u r e m a ppin g e x a m ple varying float LightIntensity; uniform sampler2D EarthTexture; void main() { vec3 lightColor = vec3(texture2D(EarthTexture, gl_TexCoord[0].st)); gl_FragColor = vec4(lightColor * LightIntensity, 1.0); }

10.3. Multitexturing Example The result ing im age looks pret t y good, but wit h a lit t le m ore effort we can get it looking even bet t er . For one t hing, w e know t hat t here are lot s of m anm ade light s on our planet , so w hen it 's night t im e, m aj or t owns and cit ies can be seen as specks of light , even from space. So we use t he angle bet ween t he light direct ion and t he norm al at each surface locat ion t o det erm ine whet her t hat locat ion is in " dayt im e" or " night t im e." For point s t hat are in dayt im e, we access t he t ext ure m ap t hat cont ains daylight colors and do an appropriat e light ing calculat ion. For point s in t he night t im e region of t he planet , we do no light ing and access a t ext ure t hat shows t he eart h as illum inat ed at night . The dayt im e and night t im e t ext ures are shown in Color Plat e 4 and Color Plat e 5. Anot her som ewhat unrealist ic aspect t o our sim ple approach is t he reflect ion of sunlight off t he surface of oceans and large lakes. Wat er is a very good reflect ive surface, and w hen our viewpoint is nearly t he sam e as t he reflect ion angle for t he light source, we should see a specular reflect ion. But we know t hat desert , grass, and t rees don't have t his sam e kind of reflect ive pr opert y, so how can we get a nice specular highlight on t he wat er but not on t he land? The answer is a t echnique called a GLOSS MAP. We m ake a single channel ( i.e., grayscale) version of our original t ext ure and assign values of 1.0 for areas t hat represent wat er and 0 for everyt hing else. At each fragm ent , w e r ead t his gloss t ext ure and m ult iply it s value by t he specular illum inat ion port ion of our light ing equat ion. I t 's fairly sim ple t o creat e t he gloss m ap in an im age edit ing program . The easiest way t o do t his is by edit ing t he red channel of t he cloudless dayt im e im age. I n t his channel, all t he wat er areas appear black or nearly black because t hey cont ain very lit t le red inform at ion. We use a select ion t ool t o select all t he black ( w at er) ar eas and t hen fill t he select ed area ( w at er regions) wit h whit e. We invert t he select ion and fill t he land areas wit h black. The result is a t ext ure t hat cont ains a value of 1.0 ( whit e) for areas in which we want a specular highlight , and a value of 0 ( black) for areas in which we don't . We use t his " gloss" value as a m ult iplier in our specular reflect ion calculat ion, so areas t hat represent wat er include a specular reflect ion t erm , and areas t hat represent land don't . Our gloss m ap is shown in Figure 10.1.

Figu r e 1 0 .1 . Gloss m a p u se d t o cr e a t e spe cu la r r e fle ct ions fr om w a t e r su r fa ce s

As you saw in Color Plat e 4 and Color Plat e 5, our dayt im e and night t im e t ext ures no longer include cloud cover. So we st ore our cloud t ext ure as a single channel ( i.e., grayscale) t ext ure as shown in Figure 10.2. By doing t his, we have m ore flexibilit y about how we com bine t he cloud im age wit h t he im ages of t he Eart h's surface. For dayt im e views, we want t he clouds t o

have diffuse reflect ion but no specular reflect ion. Furt herm ore, clouds obscure t he surface, so a value of 1.0 for t he cloud cover indicat es t hat t he eart h's surface at t hat locat ion is com plet ely obscured by clouds. For night t im e views, we don't want any light reflect ing from t he clouds, but we do w ant t hem t o obscure t he surface below . For convenience, w e've st ored our single channel cloud im age int o t he red channel of an RGB t ext ure, and we've st ored our gloss m ap as t he gr een channel. The blue channel is unused. ( Anot her choice would be t o st ore t he gloss m ap as t he alpha channel for our dayt im e im age and t he cloud t ext ure as t he alpha channel in our night t im e im age.)

Figu r e 1 0 .2 . Te x t u r e m a p sh ow in g clou d cove r ( Blu e M a r ble im a ge by Re t o St öck li, N ASA Godda r d Spa ce Fligh t Ce n t e r )

10.3.1. Application Setup The set up required for m ult it ext uring is about t he sam e as it was for t he sim ple t ext uring exam ple, except t hat we need t o set up t hree t ext ures inst ead of one. We can call t he init2Dtexture funct ion described in Sect ion 10.2.1 t hree t im es, once each for t he dayt im e eart h t ext ure, t he night t im e eart h t ext ure, and t he cloud/ gloss t ext ure. We can act ivat e t hese t ext ures wit h t he following OpenGL calls: glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, earthDayTexName); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, earthNightTexName); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, earthCloudsTexName);

The necessar y uniform variables can be init ialized as follows: lightLoc = glGetUniformLocation(programObj, glUniform3f(lightLoc, 0.0, 0.0, 4.0); texLoc = glGetUniformLocation(programObj, glUniform1i(texLoc, 0); texLoc = glGetUniformLocation(programObj, glUniform1i(texLoc, 1); texLoc = glGetUniformLocation(programObj, glUniform1i(texLoc, 2);

"LightPosition"); "EarthDay"); "EarthNight"); "EarthCloudGloss");

The applicat ion can now m ake appropriat e OpenGL calls t o draw a sphere. A surface norm al, a

2D t ext ure coordinat e, and a vert ex posit ion m ust be specified for each vert ex.

10.3.2. Vertex Shader The vert ex shader for t his m ult it ext uring exam ple is sim ilar t o t he one described for t he sim ple t ext uring exam ple in Sect ion 10.2.2, except t hat t he diffuse and specular fact ors are com put ed by t he vert ex shader and passed as separat e varying variables t o t he fragm ent shader. The com put ed specular value is m ult iplied by t he const ant vect or ( 1.0, 0.941, 0.898) t o approxim at e t he color of sunlight ( see List ing 10.3) .

List in g 1 0 .3 . Ve r t e x sh a de r for m ult it e x t ur ing varying float Diffuse; varying vec3 Specular; varying vec2 TexCoord; uniform vec3 LightPosition; void main() { vec3 ecPosition vec3 tnorm vec3 lightVec vec3 reflectVec vec3 viewVec

= = = = =

vec3(gl_ModelViewMatrix * gl_Vertex); normalize(gl_NormalMatrix * gl_Normal); normalize(LightPosition - ecPosition); reflect(-lightVec, tnorm); normalize(-ecPosition);

float spec spec Specular

= clamp(dot(reflectVec, viewVec), 0.0, 1.0); = pow(spec, 8.0); = vec3(spec) * vec3(1.0, 0.941, 0.898) * 0.3;

Diffuse

= max(dot(lightVec, tnorm), 0.0);

TexCoord gl_Position

= gl_MultiTexCoord0.st; = ftransform();

}

10.3.3. Fragment Shader The fragm ent shader t hat perform s t he desired m ult it ext uring is shown in List ing 10.4. The applicat ion has loaded t he dayt im e t ext ure in t he t ext ure unit specified by EarthDay, t he night t im e t ext ure int o t he t ext ure unit specified by EarthNight, and t he cloud/ gloss t ext ure int o t he t ext ur e unit specified by EarthCloudGloss. The light ing com put at ion is done in a vert ex shader t hat com put es diffuse and specular reflect ion fact ors and passes t hem t o t he fragm ent shader independent ly. The t ext ure coordinat es supplied by t he applicat ion are also passed t o t he fragm ent shader and form t he basis of our t ext ure lookup operat ion. I n our fragm ent shader, t he first t hing we do is access our cloud/ gloss t ext ure because it s values w ill be used in t he com put at ions t hat follow . Next , we look up t he value from our dayt im e t ext ure, m ult iply it by our diffuse light ing fact or, and add t o it t he specular light ing fact or m ult iplied by t he gloss value. I f t he fragm ent is unobscured by clouds, our com put at ion gives us t he desired effect of diffuse light ing over t he whole surface of t he Ear t h w it h specular highlight s from wat er surfaces. This value is m ult iplied by 1.0 m inus t he cloudiness fact or. Finally, we add t he cloud effect by m ult iplying our cloudiness fact or by t he diffuse light ing value and adding t his t o our previous result . The night t im e calculat ion is sim pler. Here, we j ust look up t he value from our night t im e t ext ure

and m ult iply t hat result by 1.0 m inus t he cloudiness fact or. Because t his fragm ent will be in shadow, t he diffuse and specular com ponent s are not used. Wit h t hese values com put ed, w e can det erm ine t he value t o be used for each fragm ent . The key is our diffuse light ing fact or, which is great er t han zero for areas in sunlight , equal t o zero for areas in shadow , and near zero for areas near t he t erm inat or. The color value ends up being t he com put ed daytime value in t he sunlit areas, t he com put ed nighttime value in t he areas in shadow, and a m ix of t he t wo values t o m ake a gradual t ransit ion near t he t erm inat or. An alpha value of 1.0 is added t o produce our final fragm ent color. Several views fr om t he final shader are shown in Color Plat e 7. You can see t he nice specular highlight off t he Gulf of Mexico in t he first im age. I f you look closely at t he t hird ( night t im e) im age, you can see t he clouds obscuring t he cent ral part of t he east coast of t he Unit ed St at es and t he nor t hwest ern par t of Brazil. I t is wort h point ing out t hat t his shader should not be considered a general- purpose shader because it has som e built - in assum pt ions about t he t ype of geom et ry t hat will be drawn. I t will only look " right " w hen used w it h a sphere wit h proper t ext ure coordinat es. More can be done t o m ake t he shader even m or e r ealist ic. The color of t he at m osphere act ually varies, depending on t he view ing posit ion and t he posit ion of t he sun. I t is redder when near t he shadow boundary, a fact t hat we oft en not ice near sunr ise and sunset . See t he references at t he end of t he chapt er for m ore inform at ion about achieving realist ic effect s such as Rayleigh scat t ering.

List in g 1 0 .4 . " As t he w or ld t u r n s" fr a gm e n t sh a de r uniform sampler2D EarthDay; uniform sampler2D EarthNight; uniform sampler2D EarthCloudGloss; varying float Diffuse; varying vec3 Specular; varying vec2 TexCoord; void main() { // Monochrome cloud cover value will be in clouds.r // Gloss value will be in clouds.g // clouds.b will be unused vec2 clouds vec3 daytime

= texture2D(EarthCloudGloss, TexCoord).rg; = (texture2D(EarthDay, TexCoord).rgb * Diffuse + Specular * clouds.g) * (1.0 - clouds.r) + clouds.r * Diffuse; vec3 nighttime = texture2D(EarthNight, TexCoord).rgb * (1.0 - clouds.r) * 2.0; vec3 color = daytime; if (Diffuse < 0.1) color = mix(nighttime, daytime, (Diffuse + 0.1) * 5.0); gl_FragColor = vec4(color, 1.0); }

10.4. Cube Mapping Example A t echnique called ENVI RONMENT MAPPI NG m odels reflect ions in a com plex environm ent wit hout resort ing t o ray- t racing. I n t his t echnique, one or m ore t ext ure m aps sim ulat e t he environm ent 's reflect ions. This t echnique is best used for rendering obj ect s t hat have som e m irrorlike qualit ies. The fundam ent al idea behind environm ent m apping is t hat we use t he reflect ion vect or from t he surface of an obj ect t o look up t he reflect ion color fr om an " envir onm ent " t hat is st or ed in a t ext ure m ap. I f environm ent m apping is done pr operly, t he result looks as if t he obj ect being rendered is shiny and is reflect ing it s environm ent . There are several ways t o do environm ent m apping, including SPHERE MAPPI NG and CUBE MAPPI NG, bot h of which are support ed in st andard OpenGL. An exam ple cube m ap is shown in Color Plat e 10. I n t his sect ion, we describe OpenGL shaders t hat use a cube m ap t o perform environm ent m apping on an obj ect . The obj ect is assum ed t o have an underlying layer t hat act s as a diffuse reflect or. The result from t he diffuse port ion is com bined w it h t he environm ent reflect ion t o produce a final value at each pixel. A cube m ap is a t ext ure t hat has six 2D t ext ures t hat are organized t o represent t he faces of a cube. Cube m aps are accessed wit h t hree t ext ure coordinat es t hat are t reat ed as a direct ion vect or em anat ing from t he cent er of t he cube. The cube m ap faces are different iat ed by t he sign along each of t he t hree m aj or axis direct ions. Think of t he faces t his way: The posit ive and negat ive x faces are t he right and left sides of t he cube; posit ive and negat ive y faces are t he t op and bot t om sides of t he cube; and posit ive and negat ive z faces are t he back and front sides of t he cube. Graphics hardware can use t he t hree t ext ure coordinat es as a direct ion vect or and aut om at ically select t he proper face and ret urn a t exel value where t he direct ion vect or int ersect s t hat face of t he cube m ap.

10.4.1. Application Setup The applicat ion needs t o do very lit t le t o set up t his shader. We use a sim ple light ing m odel, so t he only light ing st at e t hat we need t o pass in is a single light source posit ion. We access t he cube m ap t hrough t ext ure unit 4. baseColor defines t he color of t he diffuse underlayer of our obj ect , and mixRatio set s t he rat io of base color t o environm ent m ap reflect ion. Here are t he definit ions for t he uniform variables t hat we use: LightPos

0.0, 0.0, 4.0

BaseColor

0.4, 0.4, 1.0

MixRatio

0.8

EnvMap

4

Aft er t he shader s have been inst alled and t he uniform variables have been provided, t he applicat ion is expect ed t o send a norm al and t he vert ex posit ion for each vert ex t hat is t o be drawn. The current values for t he m odelview m at rix, t he m odelview- proj ect ion m at rix, and t he norm al m at rix are all accessed from wit hin t he vert ex shader.

10.4.2. Vertex Shader List ing 10.5 com prises t he vert ex shader t hat is used t o do environm ent m apping wit h a cube

m ap.

List in g 1 0 .5 . Ve r t e x sh a de r u se d for e n vir on m e n t m a ppin g w it h a cu be m ap varying vec3 ReflectDir; varying float LightIntensity; uniform vec3

LightPos;

void main() { gl_Position vec3 normal vec4 pos vec3 eyeDir ReflectDir LightIntensity }

= = = = = =

ftransform(); normalize(gl_NormalMatrix * gl_Normal); gl_ModelViewMatrix * gl_Vertex; pos.xyz; reflect(eyeDir, normal); max(dot(normalize(LightPos - eyeDir), normal),0.0);

The goal of t his vert ex shader is t o produce t wo values t hat will be int erpolat ed across each prim it ive: a diffuse light ing value and a reflect ion direct ion. The reflect ion direct ion is used as t he t ext ure coordinat e for accessing t he cube m ap in t he fragm ent shader. We com put e t he t ransform ed posit ion of t he vert ex in t he first line of t he program in t he usual way. We t ransform and norm alize t he incom ing nor m al, and t hen w e com put e t he eye direct ion, based on t he current m odelview m at rix and t he incom ing vert ex value. We pass t hese t w o values t o t he built - in funct ion reflect t o com put e t he reflect ion direct ion vect or. Finally, we com put e a diffuse light ing value in t he sam e m anner t hat w e've done in previous exam ples.

10.4.3. Fragment Shader List ing 10.6 cont ains t he fragm ent shader t hat perform s environm ent m apping wit h a cube m ap.

List in g 1 0 .6 . Fr a gm e n t sh a de r for doin g e n vir on m e n t m a ppin g w it h a cu be m a p uniform vec3 BaseColor; uniform float MixRatio; uniform samplerCube EnvMap; varying vec3 ReflectDir; varying float LightIntensity; void main() { // Look up environment map value in cube map vec3 envColor = vec3(textureCube(EnvMap, ReflectDir)); // Add lighting to base color and mix vec3 base = LightIntensity * BaseColor; envColor = mix(envColor, base, MixRatio);

gl_FragColor = vec4(envColor, 1.0); }

The fragm ent shader for cube m ap environm ent m apping does t hree t hings. First , t he com put ed and int erpolat ed varying variable ReflectDir is used t o access our cube m ap t ext ure and ret urn t he t exel value t hat is used t o sim ulat e t he reflect ion from a shiny surface. Second, t he base color of t he obj ect is m odulat ed by t he int erpolat ed light int ensit y value. Finally, t hese t wo values ar e com bined in t he r at io defined by t he uniform variable MixRatio. This uniform variable can be m odified by t he user t o m ake t he obj ect vary bet ween com plet ely shiny and com plet ely diffuse.

10.5. Another Environment Mapping Example Anot her opt ion for environm ent m apping is t o use phot ographic m et hods t o creat e a single 2D t ext ure m ap, called an EQUI RECTANGULAR TEXTURE MAP or a LAT- LONG TEXTURE MAP. This t ype of t ext ur e can be obt ained from a realworld environm ent by phot ography t echniques, or it can be creat ed t o represent a synt het ic environm ent . An exam ple is shown in Color Plat e 9. What ever m eans are used t o obt ain an im age, t he result is a single im age t hat spans 360° horizont ally and 180° vert ically. The im age is also dist ort ed as you m ove up or down from t he cent er of t he im age. This dist ort ion is done deliberat ely so t hat you w ill see a reasonable represent at ion of t he environm ent if you " shrink- wrap" t his t ext ur e around t he obj ect t hat you're rendering. The key t o using an equirect angular t ext ure as t he environm ent m ap is t o produce a pair of angles t hat index int o t he t ext ure. We com put e an alt it ude angle by det erm ining t he angle bet w een t he reflect ion direct ion and t he XZ plane. This alt it ude angle varies from 90° ( reflec t ion is st raight up) t o 90° ( reflect ion is st raight down ) . The sine of t his angle varies from 1.0 t o 1.0, and we use t his fact t o get a t ext ure coordinat e in t he range of [ 0,1] . We det erm ine an azim ut h angle by proj ect ing t he reflect ion direct ion ont o t he XZ plane. The azim ut h angle varies from 0° t o 360°, and t his gives us t he key t o get a second t ext ure coordinat e in t he range of [ 0,1] . The following OpenGL shaders work t oget her t o perform environm ent m apping on an obj ect by using an equirect angular t ext ur e m ap. These shaders are derived from a " bum py/ shiner" shader pair t hat was developed wit h John Kessenich and present ed at SI GGRAPH 2002. The alt it ude and azim ut h angles are com put ed t o det erm ine s and t values for indexing int o our 2D environm ent t ext ure. This t ext ur e's wrapping behavior is set so t hat it wraps in bot h s and t . ( This support s a lit t le t rick t hat we do in t he fragm ent shader.) Ot herwise, t he init ial condit ions are t he sam e as described for t he cube m ap environm ent m apping exam ple.

10.5.1. Vertex Shader List ing 10.7 com prises t he vert ex shader t hat does environm ent m apping wit h an equirect angular t ext ure m ap. The only r eal differ ence bet w een t his shader and t he one described in Sect ion 10.4.2 is t hat t his one com put es Normal and EyeDir and passes t hem t o t he fragm ent shader as varying variables so t hat t he reflect ion vect or can be com put ed in t he fragm ent shader.

List in g 1 0 .7 . Ve r t e x sh a de r u se d for e n vir on m e n t m a ppin g varying vec3 Normal; varying vec3 EyeDir; varying float LightIntensity; uniform vec3

LightPos;

void main() { gl_Position Normal vec4 pos EyeDir LightIntensity }

= = = = =

ftransform(); normalize(gl_NormalMatrix * gl_Normal); gl_ModelViewMatrix * gl_Vertex; pos.xyz; max(dot(normalize(LightPos - EyeDir), Normal), 0.0);

10.5.2. Fragment Shader List ing 10.8 cont ains t he fragm ent shader t hat does environm ent m apping by using an equirect angular t ext ure m ap.

List in g 1 0 .8 . Fr a gm e n t sh a de r for doin g e n vir on m e n t m a ppin g w it h a n e qu ir e ct a n gu la r t e x t u r e m a p const vec3 Xunitvec = vec3(1.0, 0.0, 0.0); const vec3 Yunitvec = vec3(0.0, 1.0, 0.0); uniform vec3 BaseColor; uniform float MixRatio; uniform sampler2D EnvMap; // = 4 varying vec3 Normal; varying vec3 EyeDir; varying float LightIntensity; void main() { // Compute reflection vector vec3 reflectDir = reflect(EyeDir, Normal); // Compute altitude and azimuth angles vec2 index; index.t = dot(normalize(reflectDir), Yunitvec); reflectDir.y = 0.0; index.s = dot(normalize(reflectDir), Xunitvec) * 0.5; // Translate index values into proper range if (reflectDir.z >= 0.0) index = (index + 1.0) * 0.5; else { index.t = (index.t + 1.0) * 0.5; index.s = (-index.s) * 0.5 + 1.0; } // if reflectDir.z >= 0.0, s will go from 0.25 to 0.75 // if reflectDir.z < 0.0, s will go from 0.75 to 1.25, and // that's OK, because we've set the texture to wrap. // Do a lookup into the environment map. vec3 envColor = vec3(texture2D(EnvMap, index)); // Add lighting to base color and mix vec3 base = LightIntensity * BaseColor; envColor = mix(envColor, base, MixRatio);

gl_FragColor = vec4(envColor, 1.0); }

The varying variables Normal and EyeDir are t he values generat ed by t he vert ex shader and t hen int erpolat ed across t he prim it ive. To get t ruly precise result s, t hese values should be norm alized again in t he fragm ent shader. However , for t his shader, skipping t he norm alizat ion gives us a lit t le bet t er perform ance, and t he qualit y is accept able for cert ain obj ect s. The const ant s Xunitvec and Yunitvec have been set up wit h t he proper values for com put ing our alt it ude and azim ut h angles. First , we com put e our alt it ude angle by norm alizing t he reflectionDir vect or and perform ing a dot product wit h t he Yunitvec const ant . Because bot h vect ors are unit vect ors, t his dot product com put at ion gives us a cosine value for t he desired angle t hat ranges from [ 1,1] . Set t ing t he y com ponent of our r eflect ion vect or t o 0 causes it t o be proj ect ed ont o t he XZ plane. We norm alize t his new vect or t o get t he cosine of our azim ut h angle. Again, t his value r anges from [ 1,1] . Because t he horizont al direct ion of our environm ent t ext ure spans 360°, we m ult iply by 0.5 so t hat we get a valu e t hat m aps int o half of our environm ent m ap. Then we need t o do a lit t le m ore work t o det erm ine which half t his is. I f t he z port ion of our reflect ion direct ion is posit ive, we know t hat t he reflect ion direct ion is " t oward t he front " and we use t he com put ed t ext ure m ap indices direct ly. The index values are scaled and biased so t hat when we access t he environm ent m ap t ext ure, w e get s values t hat range from [ 0.25,0.75] and t values t hat r ange from [ 0,1] . I f z is negat ive, we do our calculat ions a lit t le different ly. The t value is st ill com put ed t he sam e way, but t he s value is scaled and biased so t hat it ranges from [ 0.75,1.25] . We can use t hese values direct ly because we've set our t ext ure wrap m odes t o GL_REPEAT. s values bet ween 1.0 and 1.25 will m ap t o s values fr om 0 t o 0.25 in our act ual t ext ure ( t he t rick alluded t o earlier) . I n t his way, we can properly access t he ent ire environm ent t ext ure, depending on t he reflect ion direct ion. We could com pare s t o 1.0 and subt ract 1.0 if it s value is great er t han 1.0, but t his would end up requir ing addit ional inst ruct ions in t he m achine code and hence t he perform ance would be reduced. By using t he repeat m ode t rick, we get t he hardware t o t ake care of t his for free. Wit h our index values set , all we need t o do is look up t he value in t he t ext ure m ap. We com put e a diffusely lit base color value by m ult iplying our incom ing light int ensit y by BaseColor. We m ix t his value wit h our environm ent m ap value t o creat e a ceram ic effect . We t hen creat e a ve c4 by adding an alpha value of 1.0 and send t he final fr agm ent color on for furt her processing. The final result is shown in Color Plat e 11A. You can see t he branches from t he t ree in t he environm ent on t he back and rear of t he t ricer at ops. For t his exam ple, we used a color of ( 0.4, 0.4, 1.0) ( i.e., light blue) and a m ix rat io of 0.8 ( i.e., 80% diffuse color, 20% environm ent m ap value) . An exam ple of environm ent m apping t hat assum es a m irror like surface and adds procedural bum ps is shown in Color Plat e 11B.

10.6. Glyph Bombing I n t his sect ion, we develop a shader t hat dem onst rat es a couple of different uses for t ext ures. I n Text uring and Modeling: A Procedur al Approach, Darwyn Peachy described a process called TEXTURE BOMBI NG t hat creat es an irregular t ext ure pat t ern. The idea is t o divide a surface int o a grid, and t hen draw a decorat ive elem ent or im age ( e.g., a st ar , a polka dot , or som e ot her shape) wit hin each cell. By applying som e random ness t o t he placem ent , scaling, or rot at ion of each t ext ure elem ent , you can easily creat e an int erest ing pat t ern t hat is suit able for obj ect s such as wallpaper, gift wrap, clot hing, and t he like. Peachey described a RenderMan shader t o perform t ext ure bom bing, and in GPU Gem s, St eve Glanville described a m et hod for t ext ur e bom bing in Cg. The basic concept of t ext ure bom bing can be t aken a bit furt her. Joshua Doss developed a GLSL shader t hat random ly select s from several collect ions of relat ed charact er glyphs. Two t ext ures are used for t he so- called GLYPH BOMBI NG shadera single t ext ure t hat st ores charact er glyphs and a t ext ure t hat st ores random values. Let 's exam ine how t his shader works.

10.6.1. Application Setup The first st ep is t o creat e a 2D t ext ure t hat cont ains t he glyphs t hat will be used. To set t his up, you j ust need t o carefully dr aw charact ers on a 10 x 10 grid, using a 2D im age edit ing program like Phot oshop. Each row should have a com m on t hem e like t he im age shown in Figure 10.3. A single uniform variable ( ColAdjust) is used t o select t he row t o be accessed. Wit hin t his row, a glyph is chosen at random , and w hen it is drawn, it can also be opt ionally scaled and rot at ed. Thus, we can easily choose a pat t ern from a collect ion snowflakes, m usical sym bols, anim al silhouet t es, flower dingbat s, and so on. Applying a random color and placing t he glyph random ly wit hin t he cell add even m ore irregularit y and int erest t o t he final result .

Figu r e 1 0 .3 . Te x t u r e m a p sh ow in g a colle ct ion of ch a r a ct e r glyph s t h a t a r e u se d w it h t h e glyph bom bin g sh a de r

The second t ext ure t hat t his shader uses cont ains random values in t he range of [ 0,1.0] for each com ponent . We access t his t ext ure t o obt ain a ve c4 cont aining random num bers and use t hese values t o apply random ness t o sever al com put at ions wit hin t he fragm ent shader. Just like t he brick shader discussed in Chapt er 6, t his shader needs a fram e of reference for creat ing t he cells in which we draw our glyphs. I n t his case, we use t he obj ect 's t ext ure coordinat es t o est ablish t he reference fram e. We can scale t he t ext ure coordinat es w it h a uniform variable ( ScaleFactor) t o m ake t he cells lar ger or sm aller. Our glyph t ext ure m ap cont ains only levels of gray. We use t he value obt ained from t he glyph t ext ure m ap t o linearly int erpolat e bet w een a default obj ect color ( ModelColor) and a random color t hat is gener at ed when a glyph is draw n. Because w e are allowing random offset s and random r ot at ion, we need t o t ake care of som e com plicat ions in our shader. Each of t hese effect s can cause t he obj ect we are drawing t o ext end int o neighboring cells. Let 's first consider t he case of random offset s. When each glyph is dr awn, our shader offset s t he glyph by adding a value in t he range [ 0,1.0] for each of x and y. This m eans t hat t he glyph can be shift ed over and up by som e am ount , possibly cont ribut ing t o t he cont ent s of pixel locat ions in t hree neighboring cells t o t he right and above. Figure 10.4 illust r at es t he possibilit ies.

Figu r e 1 0 .4 . D e pe n din g on t h e r a n dom offse t for a pa r t icu la r ce ll, a glyph m a y con t r ibu t e t o a n y on e of fou r ce lls.

Consequent ly, as we consider how t o com put e t he value at one part icular pixel locat ion, we m ust consider t he possibilit y t hat t he glyphs t o be drawn in cells t o t he left and below t he current cell m ay be cont ribut ing t o t he fragm ent . For inst ance, t he spot m arked by t he x in

Figure 10.4 m ight act ually have cont ribut ions from t he glyphs in cells ( m, n) , ( m+ 1, n) , and ( m, n+ 1) in addit ion t o t he glyph cont ained in t he cell ( m+ 1, n+ 1) . Things get even m ore int erest ing when we allow for a random angle of rot at ion. Now t he offset com bined wit h rot at ion can cause our glyph t o ext end int o any of nine cells, as shown in Figur e 10.5. For t his case, as we render fragm ent s we m ust consider all eight surrounding cells in addit ion t o t he cell cont aining t he fragm ent being rendered. We use a Boolean uniform variable, RandomRotate, t o det erm ine whet her we need t o loop over four cells or nine.

Figu r e 1 0 .5 . D e pe n din g on a r a n dom offse t a n d a r a n dom a n gle of r ot a t ion , a glyph m a y con t r ibu t e t o fr a gm e n t s in a n y of n in e a dj a ce n t ce lls [View full size image]

We use a few addit ional uniform var iables t o offer m ore cont rol over t he num ber of glyphs and t heir placem ent and t o give an even great er appearance of random ness t o t he final pat t ern. RandomScale is a Boolean value t hat causes t he size of t he glyph t o be scaled in bot h x and y by random values in t he range [ 0,1.0] . ( This has no effect on t he cells t hat are affect ed, because t he glyph can only be m ade sm aller by t his operat ion.) Anot her uniform variable, Percentage, indicat es t he probabilit y t hat a glyph will be drawn in each cell. Lowering t his value increases t he num ber of em pt y cells in t he final im age. We can even include a loop in t he shader so t hat we can apply m ore t han one glyph per cell. The num ber of glyphs draw n per cell is set w it h SamplesPerCell. Set t ing t his value t o increasingly higher values will bring any graphics hardware t o it s knees. I f random rot at ion is enabled, t he

fragm ent shader will need t o it erat e over nine cells and wit hin each of t hese cells loop SamplesPerCell t im es in order t o draw all t he glyphs. This is a lot of com put at ion at every fragm ent ! The uniform variables for t his shader and t heir init ial values are SpecularContribution

0.2

LightPosition

4.0, 14.0, 4.0

ScaleFactor

10.0

ModelColor

1.0, 1.0, 1.0, 1.0

GlyphTex

0

RandomTex

1

ColAdjust

0.75

Percentage

1.0

SamplesPerCell

1.0

R01

0.29

RandomScale

false

RandomRotate

false

10.6.2. Vertex Shader List ing 10.9 cont ains t he vert ex shader for glyph bom bing. The only differences bet ween t his shader and t he vert ex shader for bricks discussed in Chapt er 6 are t hat t he diffuse fact or is m ult iplied by a som ewhat arbit rary fact or of t wo and t hat t he scaled t ext ure coordinat es are passed t o t he fragm ent shader t o form t he fr am e of refer ence for defining t he cells int o w hich glyphs will be drawn.

List in g 1 0 .9 . Ve r t e x sh a de r for doin g glyph bom bin g uniform float SpecularContribution; uniform vec3 LightPosition; uniform float ScaleFactor; varying float LightIntensity; varying vec2 TexCoord;

void main() { vec3 ecPosition vec3 tnorm vec3 lightVec vec3 reflectVec vec3 viewVec float diffuse float spec

= = = = = = =

vec3(gl_ModelViewMatrix * gl_Vertex); normalize(gl_NormalMatrix * gl_Normal); normalize(LightPosition - ecPosition); reflect(-lightVec, tnorm); normalize(-ecPosition); max(dot(lightVec, tnorm), 0.0); 0.0;

if(diffuse > 0.0) { spec = max(dot(reflectVec, viewVec), 0.0); spec = pow(spec, 16.0); } float diffusecontribution = 1.0 - SpecularContribution; LightIntensity = diffusecontribution * diffuse * 2.0 + SpecularContribution * spec; TexCoord = gl_MultiTexCoord0.st * ScaleFactor; gl_Position = ftransform(); }

10.6.3. Fragment Shader List ing 10.10 cont ains t he fragm ent shader for glyph bom bing. As you can see, t his shader m akes heavy use of looping. The first st ep is t o assign t he base color for t he fragm ent , and t hen com put e t he fragm ent 's cell and posit ion w it hin t he cell. As w e it erat e t hrough t he loops, t he value for color accum ulat es t he color for t he current fr agm ent , w hich m ay be covered by m ult iple glyphs of different colors. A double for- next loop let s us it erat e across four cells if RandomRotate is false ( 0) and across nine cells if it is t rue ( 1) . This double loop det erm ines whet her any of t he neighboring cells cont ain a glyph t hat cont ribut es t o t he fragm ent current ly being com put ed. For each it erat ion of t he inner loop, we need t o det erm ine whet her t he glyph in t he neighboring cell affect s t he fragm ent t hat is being rendered. This requires t hat we com put e t he cell num ber for each neighboring cell as well t he offset from t he low er- left corner of t he neighboring cell t o t he current fragm ent . We use t he cell value t o com put e t he init ial index value used t o access our random num ber t ext ure. This provides t he beginning of a repeat able sequence of random num ber s used for t he calculat ions wit hin t hat cell. This m eans t hat w henever we consider t he cont ent s of t his cell, w e alw ays com put e t he sam e random glyph, t he sam e random offset , and so on. To st art t he random num ber sequence in a different locat ion for each of t he cells, during each loop it erat ion we com put e t he index int o our random t ext ure by m ult iplying t he current cell value by a uniform variable ( RO1) t hat a user can adj ust t o achieve pleasing result s. At t his point , we ent er yet anot her loop. This loop it erat es over t he num ber of sam ples per cell. Wit hin t his loop, t he first t hing we do is access our random num ber t ext ure t o obt ain four random num bers in t he range [ 0,1.0] . The result of t his operat ion is a variable ( random) t hat w e use in perform ing a num ber of com put at ions t hat require an elem ent of random ness. To avoid using t he sam e random num ber for each it erat ion of t his loop, we add t he t hird and fourt h com ponent s of t he r andom num ber t o our random t ext ure index. We use t his value t o access t he t ext ure in t he next it erat ion of t he loop. Now we get t o t he heart of t he glyph bom bing algorit hm . I f t he first com ponent of t he random num ber w e've obt ained is great er t han or equal t o Percentage, we exit t he loop, use t he color value com put ed t hus far as t he value for t he fr agm ent , and are done wit h t he com put at ion concerning t his part icular cell. Ot herwise, we m ust generat e a value t hat can index int o our glyph t ext ure. The first st eps are t o use ColAdjust t o select t he row of our glyph t ext ure ( index.t) and t hen select a random glyph wit hin t hat row ( index.s) . Mult iplying by 10 and using t he floor funct ion divides t he t ext ure int o 10 sect ions in each direct ion. This gives us access t o t he 100 separat e glyphs.

The next t hing we need t o do is com put e a value t hat can access t he proper t exel in t he glyph for t his part icular cell ( glyphIndex) . Here t he offset , rot at ion, and scaling fact ors com e int o play. I f RandomRotate is t rue, w e gener at e a random angle of rot at ion, com put e t he corresponding rot at ion m at rix, and use t his m at rix t o t r ansform t he t ext ure coordinat es for accessing t he glyph. This value is t hen com bined wit h t he random offset for t he glyph. I f we're not doing rot at ion, we j ust apply t he random offset . ( I nt erest ingly, t he fragm ent shader for drawing glyphs never act ually has t o add t he random offset s for dr awing glyphs. I nst ead, t he fragm ent shader assum es t hat t he random offset s have been added and com put es whet her a glyph in a neighboring cell cont ribut es t o t he current fragm ent by subt ract ing t he random offset and t hen doing a t ext ure lookup for t he glyph in t he neighboring cell. This is an exam ple of t he t ype of logic t hat is som et im es needed t o convert a rendering algorit hm int o a fragm ent shader.) The next st ep is t o apply random scaling t o t he t ext ure coordinat es. random.r is a value in t he range [ 0, 1.0] . I f we divide our glyph index by t his value, t he glyph index values ( i.e., t he coordinat es used t o access t he glyph) get larger. And if t he coordinat es used t o access t he glyph get larger, t he apparent size of t he glyph t hat is dr awn get s sm aller. By m ult iplying random.r by 0.5 and adding 0.5, we const rain t he random scaling t o be bet w een 50% and 100% of t he original size. The result ing t ext ure coordinat es are clam ped t o t he range [ 0,1.0] , added t o t he index of t he glyph t hat is rendered, divided by 10, and t hen used t o access t he glyph t ext ure. All t he glyphs in our glyph t ext ure have at least one pixel of whit e along each edge. By clam ping t he values t o t he range [ 0,1.0] w e effect ively say " no cont ribut ion for t his glyph" whenever t he glyph index values exceed t he range [ 0,1.0] . I f t he glyph value obt ained is a color ot her t han w hit e, w e use t he result ing t ext ure value t o linearly int erpolat e bet ween t he color value com put ed t hus far and a random color. Because t he glyph t ext ure cont ains only levels of gray, t he com par ison is only t rue for t exels ot her t han pure whit e. The mix funct ion gives us a sm oot hly ant ialiased edge when t he glyph is drawn, and it allows us t o properly layer m ult iple glyphs of different colors, one on t op of t he ot her.

List in g 1 0 .1 0 . Fr a gm e n t sh a de r for doin g glyph bom bin g #define TWO_PI 6.28318 uniform vec4

ModelColor;

uniform sampler2D GlyphTex; uniform sampler2D RandomTex; uniform uniform uniform uniform uniform

float float float float float

ColAdjust; ScaleFactor; Percentage; SamplesPerCell; RO1;

uniform bool uniform bool

RandomScale; RandomRotate;

varying vec2 varying float

TexCoord; LightIntensity;

void main() { vec4 color = ModelColor; vec2 cell = floor(TexCoord); vec2 offset = TexCoord - cell; for (int i = -1; i 1.0 float a = (lambda-ultraviolet) / (infrared-ultraviolet); // bump function for a quick/simple rainbow map const float C = 7.0; // controls width of bump vec3 b = vec3(a) - vec3(0.75, 0.5, 0.25); return max((1.0 - C * b * b), 0.0); } void main() { // extract positions from input uniforms vec3 lightPosition = gl_LightSource[0].position.xyz; vec3 eyePosition = -osg_ViewMatrix[3].xyz / osg_ViewMatrix[3].w; // H vec3 vec3 vec3 vec3

= P L V H

halfway vector between light and viewer from vertex = vec3(gl_ModelViewMatrix * gl_Vertex); = normalize(lightPosition - P); = normalize(eyePosition - P); = L + V;

// accumulate contributions from constructive interference // over several spectral orders. vec3 T = gl_NormalMatrix * Tangent; float u = abs(dot(T, H)); vec3 diffColor = vec3(0.0);

const int numSpectralOrders = 3; for (int m = 1; m = 0.0) { vert = gl_Vertex + vec4(Velocity * t, 0.0); vert.y -= 4.9 * t * t; Color = gl_Color; } else { vert = gl_Vertex; // Initial position Color = Background; // "pre-birth" color } gl_Position = gl_ModelViewProjectionMatrix * vert; }

The value com put ed by t he vert ex shader is sim ply passed t hrough t he fragm ent shader t o becom e t he final color of t he fragm ent t o be render ed. Som e fram es from t he confet t i cannon anim at ion sequence are shown in Figure 16.1.

Figu r e 1 6 .1 . Se ve r a l fr a m e s fr om t h e a n im a t e d se qu e n ce pr odu ce d by t h e pa r t icle syst e m sh a de r . I n t h is a n im a t ion , t h e pa r t icle syst e m con t a in s 1 0 ,0 0 0 poin t s w it h r a n dom ly a ssign e d in it ia l ve locit ie s a n d st a r t t im e s. Th e posit ion of t h e pa r t icle a t e a ch fr a m e is com pu t e d e n t ir e ly in t he ve r t e x sha de r a ccor din g t o a for m u la t ha t sim u la t e s t h e e ffe ct s of gr a vit y. ( 3 D la bs, I n c.)

16.7.3. Further Enhancements There's a lot t hat you can do t o m ake t his shader m ore int erest ing. You m ight pass t he t value from t he vert ex shader t o t he fragm ent shader as suggest ed earlier and m ake t he color of t he part icle change over t im e. For inst ance, you could m ake t he color change from yellow t o red t o black t o sim ulat e an explosion. You could reduce t he alpha value over t im e t o m ake t he part icle fade out . You m ight also provide a " t im e of deat h" and ext inguish t he part icle com plet ely at a cert ain t im e or when a cert ain dist ance from t he origin is reached. I nst ead of drawing t he part icles as point s, you m ight dr aw t hem as short lines so t hat you could blur t he m ot ion of each part icle. You could also vary t he size of t he point ( or line) over t im e t o creat e part icles t hat grow or shrink. You can m ake t he physics m odel a lot m ore sophist icat ed t han t he one illust rat ed. To m ake t he part icles look bet t er, you could render t hem as point sprit es, anot her new feat ure in OpenGL 2.0. ( A point sprit e is a point t hat is rendered as a t ext ured quadrilat eral t hat always faces t he viewer.) The real beaut y in doing part icle syst em s wit hin a shader is t hat t he com put at ion is done com plet ely in graphics hardware rat her t han on t he host CPU. I f t he part icle syst em dat a is st ored in a vert ex buffer obj ect , t here's a good chance t hat it will be st ored in t he on- board m em ory of t he graphics hardware, so you won't even be using up any I / O bus bandwidt h as you render t he part icle syst em each fr am e. Wit h t he OpenGL Shading Language, t he equat ion for updat ing each part icle can be arbit rarily com plex. And, because t he part icle syst em is rendered like any ot her 3D obj ect , you can rot at e it around and view it from any angle w hile it is anim at ing. There's really no end t o t he effect s ( and t he fun! ) t hat you can have wit h part icle syst em s.

16.8. Wobble The pr evious t hree exam ples discussed anim at ing t he geom et r y of an obj ect and used t he vert ex processor t o achieve t his anim at ion ( because t he geom et ry of an obj ect cannot be m odified by t he fragm ent processor) . The fragm ent processor can also creat e anim at ion effect s. The m ain purpose of m ost fragm ent shaders is t o com put e t he fragm ent color, and any of t he fact ors t hat affect t his com put at ion can be varied over t im e. I n t his sect ion, we look at a shader t hat pert urbs t he t ext ure coordinat es in a t im e- varying way t o achieve an oscillat ing or wobbling effect . Wit h t he right t ext ure, t his effect can m ake it very sim ple t o produce an anim at ed effect t o sim ulat e a gelat inous surface or a " dancing" logo. This shader was developed t o m im ic t he wobbly 2D effect s dem onst rat ed in som e of t he realt im e graphics dem os t hat are available on t he Web ( see ht t p: / / www.scene.org for som e exam ples) . I t s aut hor, Ant onio Tej ada, want ed t o use t he OpenGL Shading Language t o creat e a sim ilar effect . The cent ral prem ise of t he shader is t hat a sine funct ion is used in t he fragm ent shader t o pert urb t he t ext ure coordinat es before t he t ext ure lookup operat ion. The am ount and frequency of t he pert urbat ion can be cont rolled t hrough uniform variables sent by t he applicat ion. Because t he goal of t he shader was t o produce an effect t hat looked good, t he accuracy of t he sine com put at ion was not crit ical. For t his reason and because t he sine funct ion had not been im plem ent ed at t he t im e he wrot e t his shader, Ant onio chose t o approxim at e t he sine value by using t he first t wo t erm s of t he Taylor series for sine. The fragm ent shader would have been sim pler if t he built - in sin funct ion had been used, but t his approach dem onst rat es t hat num erical m et hods can be used as needed wit hin a shader . ( As t o whet her using t wo t erm s of t he Taylor series would result in bet t er perform ance t han using t he built - in sin funct ion, it 's hard t o say. I t probably varies from one graphics hardw are vendor t o t he next , depending on how t he sin funct ion is im plem ent ed.) For t his shader t o work properly, t he applicat ion m ust provide t he frequency and am plit ude of t he wobbles, as well as a light posit ion. I n addit ion, t he applicat ion incr em ent s a uniform variable called StartRad at each fr am e. This value is used as t he basis for t he pert urbat ion calculat ion in t he fragm ent shader. By increm ent ing t he value at each fram e, we anim at e t he wobble effect . The applicat ion m ust provide t he vert ex posit ion, t he surface norm al, and t he t ext ure coordinat e at each vert ex of t he obj ect t o be rendered. The vert ex shader for t he wobble effect is responsible for a sim ple light ing com put at ion based on t he surface norm al and t he light posit ion provided by t he applicat ion. I t passes along t he t ext ure coordinat e wit hout m odificat ion. This is exact ly t he sam e as t he funct ionalit y of t he Eart h vert ex shader described in Sect ion 10.2.2, so we can sim ply use t hat vert ex shader. The fragm ent shader t o achieve t he wobbling effect is shown in List ing 16.8. I t receives as input t he varying variable LightIntensity as com put ed by t he vert ex shader. This variable is used at t he very end t o apply a light ing effect t o t he fr agm ent . The uniform variable StartRad provides t he st art ing point for t he pert urbat ion com put at ion in radians, and it is increm ent ed by t he applicat ion at each fram e t o anim at e t he wobble effect . We can m ake t he w obble effect go fast er by using a larger increm ent value, and we can m ake it go slower by using a sm aller increm ent am ount . We found t hat an increm ent value of about 1° gave visually pleasing result s. The frequency and am plit ude of t he wobbles can be adj ust ed by t he applicat ion wit h t he uniform variables Freq and Amplitude. These are defined as ve c2 variables so t hat t he x and y com ponent s can be adj ust ed independent ly. The final uniform variable defined by t his fragm ent shader is WobbleTex, which specifies t he t ext ure unit t o be used for accessing t he 2D t ext ure t hat is t o be wobbled. For t he Taylor series approxim at ion for sine t o give m ore precise result s, it is necessary t o

ensure t hat t he value for which sine is com put ed is in t he range [ π/ 2,π/ 2] . The const ant s C_PI ( π) , C_2PI ( 2π) , C_2PI _I ( 1/ 2π) , and C_PI _2 ( π/ 2) are defined t o assist in t his process. The first half of t he fragm ent shader com put es a pert urbat ion fact or for t he x direct ion. We want t o end up wit h a pert urbat ion fact or t hat depends on bot h t he s and t he t com ponent s of t he t ext ure coordinat e. To t his end, t he local variable rad is com put ed as a linear funct ion of t he s and t values of t he t ext ure coordinat e. ( A sim ilar but different expression com put es t he y pert urbat ion fact or in t he second half of t he shader.) The current value of StartRad is added. Finally, t he x com ponent of Freq is used t o scale t he result . The value for rad increases as t he value for StartRad increases. As t he scaling fact or Freq.x increases, t he frequency of t he wobbles also increases. The scaling fact or should be increased as t he size of t he t ext ure increases on t he screen t o keep t he apparent frequency of t he wobbles t he sam e at different scales. You can t hink of t he Freq uniform variable as t he Richt er scale for w obbles. A value of 0 r esult s in no wobbles what soever. A value of 1.0 result s in gent le rocking, a value of 2.0 causes j iggling, a value of 4.0 result s in wobbling, and a value of 8.0 result s in m agnit ude 8.0 eart hquake- like effect s. The next seven lines of t he shader bring t he value of rad int o t he range [ π/ 2,π/ 2] . When t his is accom plished, we can com put e sin ( rad) by using t he fir st t w o t erm s of t he Taylor series for sine, which is j ust x x3 / 3! The result of t his com put at ion is m ult iplied by t he x com ponent of Amplitude. The value for t he com put ed sine value w ill be in t he range [ - 1,1] . I f we j ust add t his value t o t he t ext ure coordinat e as t he pert urbat ion fact or, it will really pert urb t he t ext ure coordinat e. We want a wobble, not an explosion! Mult iplying t he com put ed sine value by a value of 0.05 result s in reasonably sized wobbles. I ncreasing t his scale fact or m akes t he wobbles bigger, and decr easing it m akes t hem sm aller. You can t hink of t his as how far t he t ext ure coordinat e is st ret ched from it s original value. Using a value of 0.05 m eans t hat t he pert urbat ion alt ers t he original t ext ure coordinat e by no m ore t han ± 0.05. A value of 0.5 m eans t hat t he pert urbat ion alt ers t he original t ext ure coordinat e by no m ore t han ± 0.5. Wit h t he x pert urbat ion fact or com put ed, t he whole process is repeat ed t o com put e t he y pert urbat ion fact or. This com put at ion is also based on a linear funct ion of t he s and t t ext ure coordinat e values, but it differs from t hat used for t he x pert urbat ion fact or. Com put ing t he y pert urbat ion value different ly avoids sym m et ries bet ween t he x and y pert urbat ion fact ors in t he final wobbling effect , w hich doesn't look as good w hen anim at ed. Wit h t he pert urbat ion fact ors com put ed, we can finally do our ( pert urbed) t ext ure access. The color value t hat is ret rieved from t he t ext ure m ap is m ult iplied by LightIntensity t o com put e t he final color value for t he fragm ent . Several fram es from t he anim at ion produced by t his shader are show n in Color Plat e 29. These fram es show t he shader applied t o a logo t o illust r at e t he pert urbat ion effect s m ore clearly in st at ic im ages. But t he anim at ion effect is also quit e st riking when t he t ext ure used looks like t he surface of wat er, lava, slim e, or even anim al/ m onst er skin.

List in g 1 6 .8 . Fr a gm e n t sh a de r for w obble e ffe ct

// Constants const float C_PI const float C_2PI const float C_2PI_I const float C_PI_2

= = = =

3.1415; 2.0 * C_PI; 1.0 / (2.0 * C_PI); C_PI / 2.0;

varying float LightIntensity; uniform float StartRad; uniform vec2 Freq; uniform vec2 Amplitude; uniform sampler2D WobbleTex;

void main() { vec2 perturb; float rad; vec3 color; // Compute a perturbation factor for the x-direction rad = (gl_TexCoord[0].s + gl_TexCoord[0].t - 1.0 + StartRad) * Freq.x; // Wrap to -2.0*PI, 2*PI rad = rad * C_2PI_I; rad = fract(rad); rad = rad * C_2PI; // Center in -PI, PI if (rad > C_PI) rad = rad - C_2PI; if (rad < -C_PI) rad = rad + C_2PI; // Center in -PI/2, PI/2 if (rad > C_PI_2) rad = C_PI - rad; if (rad < -C_PI_2) rad = -C_PI - rad; perturb.x = (rad - (rad * rad * rad / 6.0)) * Amplitude.x; // Now compute a perturbation factor for the y-direction rad = (gl_TexCoord[0].s - gl_TexCoord[0].t + StartRad) * Freq.y; // Wrap to -2*PI, 2*PI rad = rad * C_2PI_I; rad = fract(rad); rad = rad * C_2PI; // Center in -PI, PI if (rad > C_PI) rad = rad - C_2PI; if (rad < -C_PI) rad = rad + C_2PI; // Center in -PI/2, PI/2 if (rad > C_PI_2) rad = C_PI - rad; if (rad < -C_PI_2) rad = -C_PI - rad; perturb.y = (rad - (rad * rad * rad / 6.0)) * Amplitude.y; color = vec3(texture2D(WobbleTex, perturb + gl_TexCoord[0].st)); gl_FragColor = vec4(color * LightIntensity, 1.0); }

16.9. Summary Wit h t he fixed funct ionalit y in previous versions of OpenGL, anim at ion effect s were st rict ly in t he dom ain of t he applicat ion and had t o be com put ed on t he host CPU. Wit h program m abilit y, it has becom e easy t o specify anim at ion effect s wit hin a shader and let t he graphics har dw are do t his work. Just about any aspect of a shaderposit ion, shape, color, t ext ure coordinat es, and light ing, t o nam e j ust a fewcan be varied according t o a global definit ion of current t im e. When you develop a shader for an obj ect t hat will be in m ot ion, you should also consider how m uch of t he anim at ion effect you can encode w it hin t he shader. Encoding anim at ion effect s wit hin a shader can offload t he CPU and sim plify t he code in t he applicat ion. This chapt er described som e sim ple ways for doing t his. On and off, scrolling, and t hreshold effect s are quit e easy t o do wit hin a shader. Key- fram e int erpolat ion can be support ed in a sim ple way t hrough t he power of program m abilit y. Part icles can be anim at ed, including t heir posit ion, color, velocit y, and any ot her im port ant at t ribut es. Obj ect s and t ext ures can be m ade t o oscillat e, m ove, grow , or change based on m at hem at ical expressions. Anim at ion is a power ful t ool for conveying inform at ion, and t he OpenGL Shading Language provides anot her avenue for expressing anim at ion effect s.

16.10. Further Information I f you're serious about anim at ed effect s, you really should read Disney Anim at ion: The I llusion of Life, by t wo of t he " Nine Old Men" of Disney anim at ion fam e, Fr ank Thom as and Ollie Johnst on ( 1981) . This book is loaded wit h color im ages and insight int o t he developm ent of t he anim at ion art form at Disney St udios. I t cont ains several decades wort h of inform at ion about m aking great anim at ed film s. I f you can, t ry t o find a used copy of t he original print ing from Abbeville Press rat her t han t he reprint by Hyperion. A soft cover version was also print ed by Abbeville, but t his version elim inat es m uch of t he hist ory of Disney St udios. A brief encapsulat ion of som e of t he m at erial in t his book can be found in t he 1987 SI GGRAPH paper, Principles of Tradit ional Anim at ion Applied t o 3D Com put er Anim at ion, by John Lasset er. Rick Parent 's 2001 book, Com put er Anim at ion: Algorit hm s and Techniques, cont ains descript ions of a variet y of algorit hm s for com put er anim at ion. The book Gam e Program m ing Gem s, edit ed by Mark DeLour a ( 2000) , also has several pert inent sect ions on anim at ion. Part icle syst em s were first described by Bill Reeves in his 1983 SI GGRAPH paper, Part icle Syst em sA Technique for Modeling a Class of Fuzzy Obj ect s. I n 1998, Jeff Lander wrot e an easyt o- follow descript ion of part icle syst em s, t it led " The Ocean Spray in Your Face," in his colum n for Gam e Developer Magazine. He also m ade source code available for a sim ple OpenGL- based part icle syst em dem onst rat ion program t hat he wrot e. 1 . DeLoura, Mark, ed., Gam e Program m ing Gem s, Charles River Media, Hingham , Massachuset t s, 2000. 2 . Lander, Jeff, The Ocean Spray in Your Face, Gam e Developer Magazine, vol. 5, no. 7, pp. 1319, July 1998. ht t p: / / www.darwin3d.com / gdm 1998.ht m 3 . Lasset er, John, Principles of Tradit ional Anim at ion Applied t o 3D Com put er Anim at ion, Com put er Graphics, ( SI GGRAPH '87 Proceedings) , pp. 3544, July 1987. 4 . Parent , Rick, Com put er Anim at ion: Algorit hm s and Techniques, Morgan Kaufm ann Publishers, San Francisco, 2001. 5 . Reeves, William T., Part icle Syst em sA Technique for Modeling a Class of Fuzzy Obj ect s, ACM Transact ions on Graphics, vol. 2, no. 2, pp. 91108, April 1983. 6 . Reeves, William T., and Ricki Blau, Approxim at e and Probabilist ic Algorit hm s for Shading and Render ing St ruct ured Part icle Syst em s, Com put er Graphics ( SI GGRAPH '85 Proceedings) , pp. 313322, July 1985. 7 . Thom as, Frank, and Ollie Johnst on, Disney Anim at ionThe I llusion of Life, Abbeville Press, New York, 1981. 8 . Thom as, Frank, and Ollie Johnst on, The I llusion of LifeDisney Anim at ion, Revised Edit ion, Hyperion, 1995. 9 . Wat t , Alan H., and Mark Wat t , Advanced Anim at ion and Rendering Techniques: Theory and Pract ice, Addison- Wesley, Reading, Massachuset t s, 1992.

Chapter 17. Antialiasing Procedural Textures Jaggies, popping, sparkling, st air st eps, st robing, and m arching ant s. They're all nam es used t o describe t he anat hem a of com put er graphicsALI ASI NG. Anyone w ho has used a com put er has seen it . For st ill im ages, it 's not always t hat not iceable or obj ect ionable. But as soon as you put an obj ect in m ot ion, t he m ovem ent of t he j agged edges cat ches your eye and dist ract s you. From t he early days of com put er gr aphics, t he fight t o elim inat e t hese nast y art ifact s has been called ANTI ALI ASI NG. This chapt er does not cont ain a t horough descript ion of t he causes of aliasing, nor t he m et hods used t o com bat it . But it does int roduce t he reasons t he problem occurs and t he facilit ies wit hin t he OpenGL Shading Language for ant ialiasing. Arm ed wit h t his knowledge, you should be well on your way t o fight ing t he j aggies in your own shaders.

17.1. Sources of Aliasing The hum an eye is ext rem ely good at not icing edges. This is how we com prehend shape and form and how we recognize let t ers and words. Our eye is nat urally good at it , and we spend our whole lives pract icing it , so nat urally it is som et hing we do very, very well. A com put er display is lim it ed in it s capabilit y t o present an im age. The display is m ade up of a finit e num ber of discret e elem ent s called pixels. At a given t im e, each pixel can produce only one color. This m akes it im possible for a com put er display t o accurat ely represent det ail t hat is sm aller t han one pixel in screen space, such as an edge. When you com bine t hese t wo t hings, t he hum an eye's abilit y t o discern edges and t he com put er graphics display's lim it at ions in replicat ing t hem , you have a problem , and t his problem is known as aliasing. I n a nut shell, aliasing occurs when we t ry t o reproduce a signal wit h an insufficient sam pling frequency. Wit h a com put er gr aphics display, w e'll always have a fixed num ber of sam ples ( pixels) wit h which t o reconst ruct our im age, and t his will always be insufficient t o provide adequat e sam pling, so we will always have aliasing. We can reduce it t o t he point t hat it 's not not iceable, or we can t ransform it int o som e ot her problem t hat is less obj ect ionable, like blurriness or noise. The pr oblem is illust rat ed in Figure 17.1. I n t his diagram , we show t he result s of t rying t o draw a gray obj ect . The int ended shape is show n in Figure 17.1 ( A) . The com put er graphics display lim it s us t o a discret e sam pling grid. I f we choose only one locat ion wit hin each grid square ( usually t he cent er) and det erm ine t he color t o be used by sam pling t he desired im age at t hat point , we see som e apparent art ifact s. This is called POI NT SAMPLI NG and is illust rat ed in Figur e 17.1 ( B) . The result is ugly aliasing art ifact s for edges t hat don't line up nat urally wit h t he sam pling grid ( see Figure 17.1 ( C) ) . ( The drawing is idealized because pixels on a st andard CRT do not produce light in t he shape of a square, but t he art ifact s are obvious even when t he sam pled point s are reconst ruct ed as overlapping circles on t he com put er display.)

Figu r e 1 7 .1 . Alia sin g a r t ifa ct s ca u se d by point sa m plin g. The gr a y r e gion r e pr e se n t s t h e sh a pe of t h e obj e ct t o be r e n de r e d ( A) . Th e com pu t e r gr a ph ics displa y pr e se n t s u s w it h a lim it e d sa m plin g gr id ( B) . Th e r e su lt of ch oosing t o dr a w or n ot dr a w gr a y a t e a ch pix e l r e su lt s in j a ggie s, or a lia sin g a r t ifa ct s ( C) .

Aliasing t akes on ot her form s as well. I f you ar e developing a sequence of im ages for an anim at ion and you don't properly sam ple obj ect s t hat are in m ot ion, you m ight not ice TEMPORAL ALI ASI NG. This is caused by obj ect s t hat are m oving t oo rapidly for t he sam pling frequency being used. Obj ect s m ay appear t o st ut t er as t hey m ove or blink on and off. The classic exam ple of t em poral aliasing com es from t he m ovies: A vehicle ( car, t ruck, or covered wagon) in m ot ion is going forward, but t he spokes of it s wheels appear t o be rot at ing backwards. This effect is caused when t he sam pling r at e ( m ovie fram es per second) is t oo low relat ive t o t he m ot ion of t he wheel spokes. I n realit y, t he wheel m ay be rot at ing t wo- and t hree- quart er revolut ions per

fram e, but on film it looks like it 's rot at ing one- quart er revolut ion backw ards each fram e. To render im ages t hat look t ruly realist ic rat her t han com put er generat ed, we need t o develop t echniques for overcom ing t he inherent lim it at ions of t he graphics display.

17.2. Avoiding Aliasing One way t o achieve good result s wit hout aliasing is t o avoid sit uat ions in which aliasing occurs. For inst ance, if you know t hat a part icular obj ect will always be a cert ain size in t he final rendered im age, you can design a shader t hat looks good while rendering t hat obj ect at t hat size. This is t he assum pt ion behind som e of t he shader s present ed previously in t his book. The smoothstep, mix, and clamp funct ions are handy funct ions t o use t o avoid sharp t ransit ions and t o m ake a procedural t ext ure look good at a part icular scale. Aliasing is oft en a problem when you are rendering an obj ect at different sizes. Mipm ap t ext ures address t his very issue, and you can do som et hing sim ilar wit h shaders. I f you know t hat a part icular obj ect m ust appear at differ ent sizes in t he final rendering, you can design a shader for each different size. Each of t hese shader s would provide an appropriat e level of det ail and avoid aliasing for an obj ect of t hat size. For t his t o work, t he applicat ion m ust det erm ine t he approxim at e size of t he final rendered obj ect before it is dr awn and t hen inst all t he appr opriat e shader. I n addit ion, if a cont inuous zoom ( in or out ) is applied t o a single obj ect , som e " popping" will occur when t he level of det ail changes. You can avoid aliasing in som e sit uat ions by using a t ext ure inst ead of com put ing som et hing procedurally. This let s you t ake advant age of t he FI LTERI NG ( i.e., ant ialiasing) support t hat is built int o t he t ext ure- m apping hardware. However, t here ar e issues w it h using st ored t ext ures as opposed t o doing t hings pr ocedurally, as discussed in Chapt er 11.

17.3. Increasing Resolution The effect s of aliasing can be reduced t hrough a brut e force m et hod called SUPERSAMPLI NG t hat perform s sam pling at several locat ions wit hin a pixel and aver ages t he r esult of t hose sam ples. This is exact ly t he approach support ed in t oday's graphics hardware wit h t he m ult isam ple buffer. This m et hod of ant ialiasing replaces a single point sam pling operat ion wit h several, so it doesn't act ually elim inat e aliasing, but it can reduce aliasing t o t he point t hat it is no longer obj ect ionable. You m ay be able t o ignore t he issue of aliasing if your shaders will always be used in conj unct ion wit h a m ult isam ple buffer. But t his approach does use up hardware resources ( graphics board m em ory for st oring t he m ult isam ple buffer) , and even w it h hardware accelerat ion, it st ill m ay be slower t han perform ing t he ant ialiasing as part of t he procedural t ext ur e- gener at ion algorit hm . And, because t his approach doesn't elim inat e aliasing, your t ext ure is st ill apt t o exhibit signs of aliasing, albeit at a higher frequency t han before. Supersam pling is illust rat ed in Figure 17.2. Each of t he pixels is rendered by sam pling at four locat ions rat her t han at one. The average of t he four sam ples is used as t he value for t he pixel. This averaging provides a bet t er result , but it is not sufficient t o elim inat e aliasing because high- frequency com ponent s can st ill be m isr epresent ed.

Figu r e 1 7 .2 . Su pe r sa m pling w it h four sa m ple s pe r pix e l yie lds a be t t e r r e su lt , bu t a lia sing a r t ifa ct s a r e st ill pr e se n t . Th e sh a pe of t h e obj e ct t o be r e n de r e d is sh ow n in ( A) . Sa m plin g occu r s a t fou r loca t ions w it h in e a ch pix e l a s sh ow n in ( B) . The r e su lt s a r e a ve r a ge d t o pr odu ce t h e fin a l pix e l va lue a s show n in ( C) . Som e sa m ple s t ha t a r e a lm ost h a lf cove r e d w e r e sa m ple d w it h j u st on e su pe r sa m ple poin t in st e a d of t w o, a n d on e pix e l con t a in s im a ge da t a t ha t w a s m isse d e n t ir e ly, e ve n w it h su pe r sa m plin g.

Supersam pling can also be im plem ent ed wit hin a fragm ent shader. The code t hat is used t o produce t he fr agm ent color can be const ruct ed as a funct ion, and t his funct ion can be called several t im es from w it hin t he m ain funct ion of t he fragm ent shader t o sam ple t he funct ion at several discret e locat ions. The ret ur ned values can be averaged t o creat e t he final value for t he fragm ent . Result s are im proved if t he sam ple posit ions are varied st ochast ically rat her t han spaced on a regular grid. Supersam pling wit hin a fragm ent shader has t he obvious downside of requiring N t im es as m uch pr ocessing per fragm ent , where N is t he num ber of sam ples com put ed at each fragm ent . There will be t im es when aliasing is unavoidable and supersam pling is infeasible. I f you want t o perform procedural t ext ur ing and you w ant a single shader t hat is useful at a variet y of scales, t here's lit t le choice but t o address t he aliasing issue and t ake st eps t o count eract aliasing in your shaders.

17.4. Antialiased Stripe Example Aliasing does not occur unt il we at t em pt t o represent a cont inuous im age in screen space. This conversion occurs during rast erizat ion; t herefore, our at t em pt s t o m it igat e it s effect s always occur in t he fragm ent shader. The OpenGL Shading Language has several funct ions for t his purpose t hat ar e available only t o fragm ent shaders. To help explain t he m ot ivat ion for som e of t he language facilit ies for filt er est im at ion, we develop a " worst case" scenarioalt ernat ing black and whit e st ripes drawn on a sphere. Developing a fragm ent shader t hat perform s ant ialiasing enables us t o furt her illust rat e t he aliasing problem and t he m et hods for reducing aliasing art ifact s. Bert Fr eudenberg developed t he first version of t he GLSL shaders discussed in t his sect ion during t he process of creat ing t he ant ialiased hat ching shader described in Sect ion 18.1.

17.4.1. Generating Stripes The ant ialiasing fragm ent shader det er m ines whet her each fragm ent is t o be drawn as whit e or black t o creat e lines on t he surface of an obj ect . The first st ep is t o det erm ine t he m et hod t o be used for drawing lines. We use a single param et er as t he basis for our st ripe pat t ern. For illust rat ion, let 's assum e t hat t he param et er is t he s coordinat e of t he obj ect 's t ext ure coordinat e. We have t he vert ex shader pass t his value t o us as a float ing- point varying variable nam ed V, event ually giving us a m et hod for creat ing vert ical st ripes on a sphere. Figure 17.3 ( A) shows t he result of using t he s t ext ure coordinat e direct ly as t he int ensit y ( grayscale) value on t he surface of t he sphere. The viewing posit ion is slight ly above t he sphere, so we are looking down at t he " nort h pole." The s t ext ure coordinat e st art s off at 0 ( black) and incr eases t o 1 ( w hit e) as it goes around t he sphere. The edge where black m eet s whit e can be seen at t he pole, and it runs down t he back side of t he sphere. The front side of t he sphere looks m ost ly gray, but increases from left t o right .

Figu r e 1 7 .3 . Usin g t h e s t e x t u r e coor din a t e t o cr e a t e st r ipe s on a sph e r e . I n ( A) , t h e s t e x t u r e coor din a t e is u se d dir e ct ly a s t he int e n sit y ( gr a y) va lu e . I n ( B) , a m odulus funct ion cr e a t e s a sa w t oot h fu n ct ion . I n ( C) , t h e a bsolut e va lue fun ct ion t u r n s t h e sa w t oot h fu n ct ion int o a t r ia n gle fu n ct ion . ( Cour t e sy of Be r t Fr e u den be r g, Un ive r sit y of M a gde bu r g, 2 0 0 2 )

We creat e a sawt oot h wave by m ult iplying t he s t ext ure coordinat e by 16 and t aking t he fract ional part ( see Figure 17.3 ( B) ) . This causes t he int ensit y value t o st art at 0, rise quickly t o 1, and t hen drop back down t o 0. ( To get a feel for what a sawt oot h wave looks like, see t he illust rat ions for t he built - in funct ions fract ( refer t o Figur e 5.6) and mod ( refer t o Figur e 5.7) ) . This sequence is repeat ed 16 t im es. The OpenGL shader code t o im plem ent t his is float sawtooth = fract(V * 16.0);

This isn't quit e t he st ripe pat t ern we'r e aft er. To get closer, we em ploy t he absolut e value funct ion ( see Figure 17.3 ( C) ) . By m ult iplying t he value of sawtooth by 2 and subt ract ing 1, we get a funct ion t hat varies fr om [ 1,1] . Taking t he absolut e value of t his funct ion result s in a funct ion t hat goes from 1 down t o 0 and t hen back t o 1 ( i.e., a triangle wave) . The line of code t o do t his is float triangle = abs(2.0 * sawtooth - 1.0);

A st ripe pat t ern is st art ing t o appear, but eit her it 's t oo blurry or our glasses need adj ust m ent . We m ake t he st ripes pure black and whit e by using t he step funct ion. When w e com pare our t riangle variable t o 0.5, t his funct ion ret urns 0 whenever triangle is less t han or equal t o 0.5, and 1 w henever triangle is great er t han 0.5. This could be writ t en as float square = step(0.5, triangle);

This effect ively produces a square wave, and t he result is illust rat ed in Figure 17.4 ( A) . We can m odify t he relat ive size of t he alt ernat ing st ripes by adj ust ing t he t hreshold value provided in t he step funct ion.

Figu r e 1 7 .4 . An t ia lia sing t h e st r ipe pa t t e r n . W e ca n se e t h a t t h e squ a r e w a ve pr odu ce d by t h e step fu n ct ion pr odu ce s a lia sin g a r t ifa ct s ( A) . Th e smoothstep funct ion w it h a fix e d- w idt h filt e r pr odu ce s t oo m u ch blu r r in g n e a r t h e e qu a t or bu t n ot e n ou gh a t t h e pole ( B) . An a da pt ive a ppr oa ch pr ovide s r e a son a ble a n t ia lia sin g in bot h r e gion s ( C) . ( Cour t e sy of Be r t Fr e u de n be r g, Un ive r sit y of M a gde bu r g, 2 0 0 2 )

17.4.2. Analytic Prefiltering I n Figure 17.4 ( A) , we see t hat t he st ripes are now dist inct , but aliasing has reared it s ugly head. The step funct ion ret urns values t hat are eit her 0 or 1, w it h not hing in bet w een, so t he j agged edges in t he t ransit ions bet ween whit e and black are easy t o spot . They will not go away if we increase t he resolut ion of t he im age; t hey'll j ust be sm aller. The problem is caused by t he fact t hat t he step funct ion int roduced an im m ediat e t ransit ion from whit e t o black or an edge wit h infinit e frequency ( see Figure 5.11) . There is no w ay t o sam ple t his t r ansit ion at a high enough fr equency t o elim inat e t he aliasing art ifact s. To get good result s, we need t o t ake st eps wit hin our shader t o rem ove such high frequencies. A variet y of ant ialiasing t echniques rely on elim inat ing ext rem ely high frequencies before sam pling. This is called LOW - PASS FI LTERI NG because low frequencies are passed t hrough unm odified, whereas high frequencies are elim inated. The visual effect of low- pass filt ering is t hat t he result ing im age is blurred.

To elim inat e t he high frequencies from t he st ripe pat t ern, w e use t he smoothstep funct ion. We know t hat t his funct ion produces a sm oot h t r ansit ion bet w een whit e and black. I t requires t hat we specify t wo edges, and a sm oot h t ransit ion occurs bet w een t hose t w o edges. Figure 17.4 ( B) illust rat es t he result from t he following line of code: float square = smoothstep(0.4, 0.6, triangle);

17.4.3. Adaptive Analytic Prefiltering Analyt ic prefilt ering produces accept able result s in som e regions of t he sphere but not in ot hers. The size of t he sm oot hing filt er ( 0.2) is defined in param et er space. But t he param et er does not vary at a const ant rat e in screen space. I n t his case, t he s t ext ure coordinat e varies quit e rapidly in screen space near t he poles and less rapidly at t he equat or. Our fixed- widt h filt er produces blurring across several pixels at t he equat or and very lit t le effect at t he poles. What we need is a way t o det erm ine t he size of t he sm oot hing filt er adapt ively so t hat t ransit ion can be appropriat e at all scales in screen space. This requires a m easurem ent of how rapidly t he funct ion we're int erest ed in is changing at a part icular posit ion in screen space. For t unat ely, t he OpenGL Shading Language provides a built - in funct ion t hat can give us t he rat e of change ( der ivat ive) of any param et er in screen space. The funct ion dFdx gives t he rat e of change in screen coordinat es in t he x direct ion, and dFdy gives t he rat e of change in t he y direct ion. Because t hese funct ions deal wit h screen space, t hey are available only in a fragm ent shader. These t w o funct ions can pr ovide t he inform at ion needed t o com put e a GRADI ENT VECTOR for t he posit ion of int erest . Given a funct ion f( x,y) , t he gr adient of f at t he posit ion ( x, y) is defined as t he vect or

I n English, t he gradient vect or com prises t he part ial derivat ive of funct ion f w it h respect t o x ( i.e., t he m easure of how rapidly f is changing in t he x direct ion) and t he part ial derivat ive of t he funct ion f w it h respect t o y ( i.e., t he m easure of how rapidly f is changing in t he y direct ion) . The im port ant propert ies of t he gradient vect or are t hat it point s in t he direct ion of t he m axim um rat e of increase of t he funct ion f( x,y) ( t he gr adient direct ion) and t hat t he m agnit ude of t his vect or equals t he m axim um rat e of incr ease of f( x,y) in t he gradient direct ion. ( These propert ies are useful for im age processing t oo, as w e see lat er.) The built - in funct ions dFdx and dFdy give us exact ly what w e need t o define t he gradient vect or for funct ions used in fragm ent shaders. The m agnit ude of t he gradient vect or for t he funct ion f( x,y) is com m only called t he t he funct ion f( x,y) . I t is defined as mag[ G[ f( x,y) ] ] = sqrt( (

f/

x) 2 + (

f/

GRADI ENT

of

x) 2 )

I n pract ice, it is not always necessary t o perform t he ( possibly cost ly) square root operat ion. The gr adient can be approxim at ed wit h absolut e values: mag[ G[ f( x,y) ] ]

abs( f( x,y) - f( x + 1, y) ) + abs( f( x,y) - f( x,y + 1) )

This is exact ly what is ret urned by t he built - in funct ion fwidth. The sum of t he absolut e values is an upper bound on t he widt h of t he sam pling filt er needed t o elim inat e aliasing. I f it is t oo large, t he result ing im age looks som ew hat m ore blurry t han it should, but t his is usually accept able. The t w o m et hods of com put ing t he gradient are com pared in Figure 17.5. As you can see, t here is lit t le visible difference. Because t he value of t he gradient was quit e sm all for t he funct ion being evaluat ed on t his obj ect , t he values were scaled so t hat t hey would be visible.

Figu r e 1 7 .5 . Visu a lizing t h e gr a die n t . I n ( A) , t h e m a gn it u de of t h e gr a die n t ve ct or is u se d a s t h e in t e n sit y ( gr a y) va lu e . I n ( B) , t he gr a die n t is a ppr ox im a t e d w it h a bsolu t e va lu e s. ( Act u a l gr a die n t va lu e s a r e sca le d for visu a liza t ion .) ( Cou r t e sy of Be r t Fr e u de n be rg, Un ive r sit y of M a gde bu r g, 2 0 0 2 )

To com put e t he act ual gradient for a varying variable V w it hin a fragm ent shader, we use float width = length(vec2(dFdx(V), dFdy(V)));

To approxim at e it , we use t he pot ent ially higher per form ance calculat ion: float width = fwidth(V);

We t hen use t he filt er widt h wit hin our call t o smoothstep as follow s: float edge = width * 32.0; float square = smoothstep(0.5 - edge, 0.5 + edge, triangle);

I f we put t his all t oget her in a fragm ent shader, w e get List ing 17.1.

List in g 1 7 .1 . Fr a gm e n t sh a de r for a da pt ive a n a lyt ic a n t ia lia sin g

varying float V; varying float LightIntensity;

// generic varying

uniform float Frequency;

// Stripe frequency = 6

void main()

{ float sawtooth = fract(V * Frequency); float triangle = abs(2.0 * sawtooth - 1.0); float dp = length(vec2(dFdx(V), dFdy(V))); float edge = dp * Frequency * 2.0; float square = smoothstep(0.5 - edge, 0.5 + edge, triangle); gl_FragColor = vec4(vec3(square), 1.0); }

I f we scale t he fr equency of our t ext ure, w e m ust also increase t he filt er widt h accordingly. Aft er t he value of t he funct ion is com put ed, it is replicat ed across t he red, green, and blue com ponent s of a ve c3 and used as t he color of t he fragm ent . The result s of t his adapt ive ant ialiasing approach are shown in Figure 17.4 ( C) . The result s are m uch m ore consist ent across t he surface of t he sphere. A sim ple light ing com put at ion is added, and t he result ing shader is applied t o t he t eapot in Figure 17.6.

Figu r e 1 7 .6 . Effe ct of a da pt ive a n a lyt ica l a n t ia lia sin g on st r ipe d t e a pot s. On t h e le ft , t he t e a pot is dr a w n w it h n o a n t ia lia sin g. On t h e r igh t , t h e a da pt ive a n t ia lia sin g sh a de r is u se d. A sm a ll por t ion of t h e st r ipe d su r fa ce is m a gnifie d 2 0 0 % t o m a k e it e a sie r t o se e t h e diffe r e nce .

This approach t o ant ialiasing works well unt il t he filt er widt h get s larger t han t he fr equency. This is t he sit uat ion t hat occurs at t he nort h pole of t he sphere. The st ripes very close t o t he pole are m uch t hinner t han one pixel, so no st ep funct ion will produce t he correct gray value here. I n such regions, you need t o swit ch t o int egrat ion or frequency clam ping, bot h of which are discussed in subsequent sect ions.

17.4.4. Analytic Integration The weight ed average of a funct ion over a specified int erval is called a CONVOLUTI ON. The values t hat do t he weight ing are called t he CONVOLUTI ON KERNEL or t he CONVOLUTI ON FI LTER. I n som e cases, we can reduce or elim inat e aliasing by det erm ining t he convolut ion of a funct ion ahead of t im e and t hen sam pling t he convolved funct ion rat her t han t he original funct ion. The convolut ion can be perform ed over a fixed int erval in a com put at ion t hat is equivalent t o convolving t he input funct ion wit h a box filt er. A box filt er is far from ideal, but it is sim ple and easy t o com put e and oft en good enough. This m et hod corresponds t o t he not ion of ant ialiasing by AREA SAMPLI NG. I t is different from point sam pling or supersam pling in t hat w e at t em pt t o calculat e t he area of t he obj ect being render ed relat ive t o t he sam pling region. Referring t o Figure 17.2, if we used an ar ea sam pling t echnique, we w ould get m or e accurat e values for each of t he pixels, and we wouldn't m iss t hat pixel t hat j ust had a sliver of coverage.

I n Advanced RenderMan: Creat ing CGI for Mot ion Pict ures, Apodaca and Grit z ( 1999) explain how t o perform analyt ic ant ialiasing of a periodic st ep funct ion, som et im es called a PULSE TRAI N. Darwyn Peachey described how t o apply t his m et hod t o his procedural br ick Render Man shader in Text uring and Modeling: A Procedur al Approach, and Dave Baldwin published a GLSL version of t his shader in t he original paper on t he OpenGL Shading Language. We use t his t echnique t o analyt ically ant ialias t he procedural br ick GLSL shader w e descr ibed back in Chapt er 6. Recall t hat t he sim ple brick exam ple used t he step funct ion t o pr oduce t he periodic brick pat t ern. The funct ion t hat creat es t he brick pat t ern in t he horizont al direct ion is illust rat ed in Figure 17.7. From 0 t o BrickPct.x ( t he brick widt h fract ion) , t he funct ion is 1.0. At t he value of BrickPct.x, t here is an edge wit h infinit e slope as t he funct ion dr ops t o 0. At t he value 1, t he funct ion j um ps back up t o 1.0, and t he process is repeat ed for t he next brick.

Figu r e 1 7 .7 . Th e pe r iodic st e p fu nct ion, or pulse t r a in, t h a t de fin e s t he h or izon t a l com pone n t of t h e pr oce du r a l br ick t e x t u r e

The key t o ant ialiasing t his funct ion is t o com put e it s int egral, or accum ulat ed, value. We have t o consider t he possibilit y t hat , in areas of high com plexit y, t he filt er widt h t hat is com put ed by fwidth w ill cover several of t hese pulses. By sam pling t he int egral rat her t han t he funct ion it self, we get a properly w eight ed average and avoid t he high frequencies caused by point sam pling t hat w ould produce aliasing art ifact s. So what is t he int egral of t his funct ion? I t is illust rat ed in Figure 17.8. From 0 t o BrickPct.x, t he funct ion value is 1, so t he int egral incr eases wit h a slope of 1. From BrickPct.x t o 1.0, t he funct ion has a value of 0, so t he int egral st ays const ant in t his region. At 1, t he funct ion j um ps back t o 1.0, so t he int egral increases unt il t he funct ion reaches BrickPct.x + 1. At t his point , t he int egr al changes t o a slope of 0 again, and t his pat t ern of ram ps and plat eaus cont inues.

Figu r e 1 7 .8 . Pe r iodic st e p fu n ct ion ( pulse t r a in) a n d it s in t e gr a l

We perform ant ialiasing by det erm ining t he value of t he int egral over t he area of t he filt er, and we do t hat by evaluat ing t he int egral at t he edges of t he filt er and subt ract ing t he t wo values. The int egral for t his funct ion consist s of t w o part s: t he sum of t he area for all t he pulses t hat have been fully com plet ed before t he edge we are considering and t he area of t he possibly part ially com plet ed pulse for t he edge we ar e considering. For our procedural brick shader, we use t he variable position.x as t he basis for generat ing t he pulse funct ion in t he horizont al direct ion. So t he num ber of fully com plet ed pulses is j ust floor ( position.x) . Because t he height of each pulse is 1.0, t he area of each fully com plet ed pulse is j ust BrickPct.x. Mult iplying floor( position.x) by BrickPct.x gives t he area for all t he fully com plet ed pulses. The edge t hat w e're considering m ay be in t he part of t he funct ion t hat is equal t o 0, or it m ay be in t he part of t he funct ion t hat is equal t o 1. We can find out by com put ing fract( position.x) ( 1.0 BrickPct.x). I f t he result of t his subt ract ion is less t han 0, we were in t he part of t he funct ion t hat ret urns 0, so not hing m ore needs t o be done. But if t he value is great er t han zero, we are par t w ay int o a region of t he funct ion t hat is equal t o 1. Because t he height of t he pulse is 1, t he area of t his part ial pulse is fract( position.x) ( 1.0 BrickPct.x). Therefore, t he second part of our int egral is t he expression max( fract( position.x) ( 1.0 BrickPct.x), 0.0) . We use t his int egral for bot h t he horizont al and vert ical com ponent s of our procedural brick pat t ern. Because t he applicat ion knows t he brick widt h and height fract ions ( BrickPct.x and BrickPct.y) , it can easily com put e 1.0 BrickPct.x and 1.0 BrickPct.y and provide t hem t o our fragm ent shader as well. This keeps us from unnecessarily com put ing t hese values several t im es for every fragm ent t hat is rendered. We call t hese values t he m ort ar percent age. Because w e evaluat e t his expression t wice wit h different argum ent s, we define it as a m acro or a funct ion for convenience: #define Integral(x, p, notp) ((floor(x)*(p)) + max(fract(x)-(notp), 0.0))

The param et er p indicat es t he value t hat is part of t he pulse ( i.e., when t he funct ion is 1.0) , and notp indicat es t he value t hat is not part of t he pulse ( i.e., when t he funct ion is 0) . Using t his m acro, w e can writ e t he code t o com put e t he value of t he int egr al over t he widt h of t he filt er as

follows: vec2 fw, useBrick; fw = fwidth(position); useBrick = (Integral(position + fw, BrickPct, MortarPct) Integral(position, BrickPct, MortarPct)) / fw;

The result is divided by t he area of t he filt er ( a box filt er is assum ed in t his case) t o obt ain t he average value for t he funct ion in t he select ed int erval.

17.4.5. Antialiased Brick Fragment Shader Now we can put all t his t o work t o build bet t er bricks. We replace t he sim ple point sam pling t echnique used in t he exam ple in Chapt er 6 wit h analyt ic int egrat ion. The result ing shader is shown in List ing 17.2. The difference bet w een t he aliased and ant ialiased brick shaders is shown in Color Plat e 35.

List in g 1 7 .2 . Sou r ce code for a n a n t ia lia se d br ick fr a gm e n t sh a de r uniform uniform uniform uniform

vec3 vec2 vec2 vec2

BrickColor, MortarColor; BrickSize; BrickPct; MortarPct;

varying vec2 MCposition; varying float LightIntensity; #define Integral(x, p, notp) ((floor(x)*(p)) + max(fract(x)-(notp), 0.0)) void main() { vec2 position, fw, useBrick; vec3 color; // Determine position within the brick pattern position = MCposition / BrickSize; // Adjust every other row by an offset of half a brick if (fract(position.y * 0.5) > 0.5) position.x += 0.5; // Calculate filter size fw = fwidth(position); // Perform filtering by integrating the 2D pulse made by the // brick pattern over the filter width and height useBrick = (Integral(position + fw, BrickPct, MortarPct) Integral(position, BrickPct, MortarPct)) / fw; // Determine final color color = mix(MortarColor, BrickColor, useBrick.x * useBrick.y); color *= LightIntensity; gl_FragColor = vec4(color, 1.0); }

17.5. Frequency Clamping Cert ain funct ions do not have an analyt ic solut ion, or t hey are j ust t oo difficult t o solve. I f t his is t he case, you m ight t ry a t echnique called frequency clam ping. I n t his t echnique, t he average value of t he funct ion replaces t he act ual value of t he funct ion when t he filt er widt h is t oo large. This is convenient for funct ions such as sine and noise w hose average is known.

17.5.1. Antialiased Checkerboard Fragment Shader The checkerboard pat t ern is t he st andard m easure of t he qualit y of an ant ialiasing t echnique ( see Figure 17.9) . Larry Grit z wr ot e a checkerboard RenderMan shader t hat perform s ant ialiasing by frequency sam pling, and Dave Baldwin t ranslat ed t his shader t o GLSL. List ing 17.3 shows a fragm ent shader t hat produces a procedurally generat ed, ant ialiased checkerboard pat t er n. The vert ex shader t ransform s t he vert ex posit ion and passes along t he t ext ure coordinat e, not hing m ore. The applicat ion provides values for t he t wo colors of t he checkerboard pat t er n, t he aver age of t hese t wo colors ( t he applicat ion can com put e t his and provide it t hrough a uniform variable, rat her t han having t he fragm ent shader com put e it for every fragm ent ) , and t he frequency of t he checkerboard pat t ern.

Figu r e 1 7 .9 . Ch e ck e r boa r d pa t t e r n r e n de r e d w it h t h e a n t ia lia se d ch e ck e r boa r d sh a de r . On t h e le ft , t h e filt e r w idt h is se t t o 0 , so a lia sing occu r s. On t h e r igh t , t h e filt e r w idt h is com pu t e d u sin g t h e fwidth fu n ct ion .

The fragm ent shader com put es t he appropriat e size of t he filt er and uses it t o perform sm oot h int erpolat ion bet w een adj oining checkerboard squares. I f t he filt er is t oo wide ( i.e., t he varying param et er is changing t oo quickly for proper filt ering) , t he average color is subst it ut ed. Even t hough t his fragm ent shader uses a condit ional st at em ent , care is t aken t o avoid aliasing. I n t he t ransit ion zone bet w een t he if clause and t he else clause, a sm oot h int erpolat ion is

perform ed bet w een t he com put ed color and t he average color.

List in g 1 7 .3 . Sou r ce code for a n a n t ia lia se d ch e ck e r boa r d fr a gm e n t sh a de r uniform uniform uniform uniform

vec3 vec3 vec3 float

varying vec2

Color1; Color2; AvgColor; Frequency; TexCoord;

void main() { vec3 color; // Determine the width of the projection of one pixel into s-t space vec2 fw = fwidth(TexCoord); // Determine the amount of fuzziness vec2 fuzz = fw * Frequency * 2.0; float fuzzMax = max(fuzz.s, fuzz.t); // Determine the position in the checkerboard pattern vec2 checkPos = fract(TexCoord * Frequency); if (fuzzMax < 0.5) { // If the filter width is small enough, compute the pattern color vec2 p = smoothstep(vec2(0.5), fuzz + vec2(0.5), checkPos) + (1.0 - smoothstep(vec2(0.0), fuzz, checkPos)); color = mix(Color1, Color2, p.x * p.y + (1.0 - p.x) * (1.0 - p.y)); // Fade in the average color when we get close to the limit color = mix(color, AvgColor, smoothstep(0.125, 0.5, FuzzMax)); } else { // Otherwise, use only the average color color = AvgColor; } gl_FragColor = vec4(color, 1.0); }

17.6. Summary Wit h increased freedom com es increased responsibilit y. The OpenGL Shading Language perm it s t he com put at ion of procedural t ext ures wit hout rest rict ion. I t is quit e easy t o writ e a shader t hat exhibit s unsight ly aliasing art ifact s ( using a condit ional or a st ep funct ion is all it t akes) , and it can be difficult t o elim inat e t hese art ifact s. Aft er describing t he aliasing problem in general t erm s, t his chapt er explored several opt ions for ant ialiasing procedural t ext ures. Facilit ies in t he language, such as t he built - in funct ions for sm oot h int erpolat ion ( smoothstep) , for det erm ining derivat ives in screen space ( dFdx, dFdy) , and for est im at ing filt er widt h ( fwidth) can assist in t he fight against j aggies. These funct ions w ere fundam ent al com ponent s of shaders t hat were present ed t o perform ant ialiasing by prefilt ering, adapt ive prefilt ering, int egrat ion, and frequency clam ping.

17.7. Further Information Most signal processing and im age processing books cont ain a discussion of t he concept s of sam pling, reconst ruct ion, and aliasing. Books by Glassner, Wolberg, and Gonzalez and Woods can be consult ed for addit ional inform at ion on t hese t opics. Technical m em os by Alvy Ray Sm it h address t he issues of aliasing in com put er graphics direct ly. The book Advanced RenderMan: Creat ing CGI for Mot ion Pict ures by Tony Apodaca and Larry Grit z ( 1999) cont ains a chapt er t hat describes shader ant ialiasing in t erm s of t he RenderMan shading language, and m uch of t he discussion is germ ane t o t he OpenGL Shading Language as well. Darwyn Peachey has a sim ilar discussion in Text uring & Modeling: A Procedural Approach, Thir d Edit ion by David Ebert et al. ( 2002) . Bert Freudenberg developed an OpenGL shader t o do adapt ive ant ialiasing and present ed t his work at t he SI GGRAPH 2002 in San Ant onio, Texas. I n t his chapt er, I 've recreat ed t he im ages Bert used in his t alk, but he deserves t he cr edit for or iginally developing t he im ages and t he shaders t o illust rat e som e of t he t opics I 've covered. This subj ect is also covered in his Ph.D. t hesis, Real- Tim e St roke- based Halft oning. 1 . 3Dlabs developer Web sit e. ht t p: / / developer.3dlabs.com / 2 . Apodaca, Ant hony A., and Larry Grit z, Advanced RenderMan: Creat ing CGI for Mot ion Pict ures, Morgan Kaufm ann Publishers, San Francisco, 1999. ht t p: / / w ww .r ender m an.org/ RMR/ Books/ arm an/ m at erials.ht m l 3 . Baldwin, Dave, OpenGL 2.0 Shading Language Whit e Paper, Version 1.0, 3Dlabs, Oct ober, 2001. 4 . Cook, Robert L., St ochast ic Sam pling in Com put er Graphics, ACM Transact ions on Graphics, vol. 5, no. 1, pp. 5172, January 1986. 5 . Crow , Franklin C., The Aliasing Problem in Com put er - Generat ed Shaded I m ages, Com m unicat ions of t he ACM, 20( 11) , pp. 799805, Novem ber 1977. 6 . Crow , Franklin C., Sum m ed- Area Tables for Text ure Mapping, Com put er Graphics ( SI GGRAPH '84 Proceedings) , pp. 207212, July 1984. 7 . Dippé, Mark A. Z., and Erling Henry Wold, Ant ialiasing Through St ochast ic Sam pling, Com put er Graphics ( SI GGRAPH '85 Proceedings) , pp. 6978, July 1985. 8 . Ebert , David S., John Hart , Bill Mark, F. Kent on Musgrave, Darwyn Peachey, Ken Perlin, and St even Worley, Text uring and Modeling: A Procedural Approach, Thir d Edit ion, Morgan Kaufm ann Publishers, San Francisco, 2002. ht t p: / / w ww .t ext uringandm odeling.com 9 . Freudenberg, Bert , A Non- Phot or ealist ic Fragm ent Shader in OpenGL 2.0, Present ed at t he SI GGRAPH 2002 Exhibit ion in San Ant onio, July 2002. ht t p: / / isgwww.cs.unim agdeburg.de/ ~ bert / publicat ions 1 0 . Freudenberg, Bert , Real- Tim e St roke- based Halft oning, Ph.D. t hesis, Universit y of Magdeburg, subm it t ed in 2003. 1 1 . Glassner, Andrew S., Principles of Digit al I m age Synt hesis, Vol. 1, Morgan Kaufm ann Publishers, San Francisco, 1995.

1 2 . Glassner, Andrew S., Principles of Digit al I m age Synt hesis, Vol. 2, Morgan Kaufm ann Publishers, San Francisco, 1995. 1 3 . Gonzalez, Rafael C., and Richard E. Woods, Digit al I m age Processing, Second Edit ion, Prent ice Hall, Upper Saddle River, New Jersey, 2002. 1 4 . Grit z, Larry, LGAnt ialiasedChecks.sl, RenderMan Reposit ory Web sit e. ht t p: / / w ww .r ender m an.org/ RMR/ Shaders/ LGShaders/ index.ht m l 1 5 . Sm it h, Alvy Ray, Digit al Filt ering Tut orial for Com put er Gr aphics, Lucasfilm Technical Mem o 27, revised March 1983. ht t p: / / www.alvyray.com / m em os/ default .ht m 1 6 . Sm it h, Alvy Ray, Digit al Filt ering Tut orial, Part I I , Lucasfilm Technical Mem o 27, revised March 1983. ht t p: / / www.alvyray.com / m em os/ default .ht m 1 7 . Sm it h, Alvy Ray, A Pixel I s Not a Lit t le Square, a Pixel I s Not a Lit t le Square, a Pixel I s Not a Lit t le Square! ( And a Voxel I s Not a Lit t le Cube) , Technical Mem o 6, Microsoft Research, July 1995. ht t p: / / www.alvyray.com / m em os/ default .ht m 1 8 . Wolber g, George, Digit al I m age Warping, Wiley- I EEE Press, 2002.

Chapter 18. Non-Photorealistic Shaders A significant am ount of com put er graphics resear ch has been aim ed at achieving m or e and m ore realist ic rendit ions of synt het ic scenes. A longt im e goal has been t o render a scene so perfect ly t hat it is indist inguishable from a phot ograph of t he real scene, hence t he t erm PHOTOREALI SM. Wit h t he lat est graphics hardware, som e phot orealist ic effect s are becom ing possible in real- t im e rendering. This quest for realism is also reflect ed in graphics API s such as OpenGL. The OpenGL specificat ion defines specific form ulas for calculat ing effect s such as illum inat ion fr om light sources, m at erial propert ies, and fog. These form ulas at t em pt t o define effect s as realist ically as possible while rem aining relat ively easy t o im plem ent in hardware, and t hey have duly been cast int o silicon by int repid graphics hardware designers. But t he collect ion of hum an art and lit erat ure shows us t hat phot orealism is not t he only im port ant st yle for creat ing im ages. The availabilit y of low- cost program m able graphics hardware has sparked t he grow t h of an area called NON- PHOTOREALI STI C RENDERI NG, or NPR. Researchers and pract it ioners in t his field are at t em pt ing t o use com put er graphics t o produce a wide range of art ist ic effect s ot her t han phot orealism . I n t his chapt er, we look at a few exam ples of shaders whose m ain focus is som et hing ot her t han generat ing result s t hat ar e as realist ic as possible.

18.1. Hatching Example Bert Freudenberg of t he Universit y of Magdeburg in Germ any w as one of t he first people out side 3Dlabs t o com e up wit h a unique OpenGL shader. His area of research has been t o use program m able hardware t o produce real- t im e NPR effect s such as hat ching and half- t oning. He experim ent ed wit h a prot ot ype im plem ent at ion of t he OpenGL Shading Language in t he sum m er of 2002 and produced a hat ching shader t hat he agreed t o share wit h us for t his book. This shader has a few unique feat ures, and t he st eps involved in designing t his shader are described in Bert 's Ph.D. t hesis, Real- Tim e St roke- based Halft oning ( 2003) . Bert 's hat ching shader is based on a woodblock print ing shader by Scot t Johnst on t hat is discussed in Advanced Render Man: Creat ing CGI for Mot ion Pict ures by Tony Apodaca and Larry Grit z ( 1999) . The goal in a hat ching shader is t o render an obj ect in a way t hat m akes it look hand- drawn, for inst ance wit h st rokes t hat look like t hey m ay have been drawn wit h pen and ink. Each st roke cont ribut es t o t he viewer's abilit y t o com prehend t he t one, t ext ur e, and shape of t he obj ect being viewed. The effect being sought in t his shader is t hat of a w oodcut print . I n a woodcut , a wooden block carved wit h sm all grooves is covered wit h ink and pr essed ont o a surface. The im age left on t he surface is t he m irror im age of t he im age carved int o t he wood block. No ink is left w here t he grooves are cut , only where t he wood is left uncut . Light ing is sim ulat ed by varying t he widt h of t he grooves according t o light int ensit y. We face a num ber of challenges in developing a shader t hat sim ulat es t he look of a woodcut print . The first t hing we need is a way of generat ing st ripes t hat defines t he t one and t ext ure of t he obj ect . Alt ernat ing whit e and black lines provides t he highest cont rast edges and t hus represent s a worst - case scenario for aliasing ar t ifact s; t hus ant ialiasing is a prim e considerat ion. We also want our lines t o " st ay put " on t he obj ect so t hat we can use t he obj ect in an anim at ion sequence. Finally, t he lines in a woodcut print are not always perfect ly st raight and uniform as t hough t hey were drawn by a com put er. They are cut int o t he wood by a hum an art ist , so t hey have som e charact er. We'd like t he lines t hat our shader generat es t o have som e charact er as well.

18.1.1. Application Setup The applicat ion needs t o send vert ex posit ions, norm als, and a single set of t ext ure coordinat es t o t he hat ching shader. The norm als are used in a sim ple light ing form ula, and t he t ext ure coordinat es are used as t he base for pr ocedurally defining t he hat ching pat t ern. The light posit ion is passed in as a uniform variable, and t he applicat ion also updat es t he value of t he Time uniform variable at each fram e so t hat t he behavior of t he shader can be m odified slight ly each fram e. What do you suppose w e use t o give our lines som e charact er? You guessed it t he noise funct ion. I n t his case, we have t he applicat ion generat e t he noise values t hat ar e needed and st ore t he result s in a 3D t ext ure. For t his reason, t he value for a uniform variable of t ype sampler3D is provided by t he applicat ion t o inform t he fragm ent shader which t ext ure unit should be accessed t o obt ain t he noise values.

18.1.2. Vertex Shader The hat ch vert ex shader is show n in List ing 18.1. The first line is t he only line t hat looks different fr om shaders we've discussed previously. The varying variable ObjPos is t he basis for our hat ching st roke com put at ion in t he fragm ent shader. To anim at e t he w iggle of t he lines, t he vert ex shader adds t he uniform variable Time t o t he z coordinat e of t he incom ing vert ex posit ion. This m akes it appear as t hough t he wiggles are " flowing" along t he z- axis. A scaling value is also used t o m ake t he hat ching st rokes m at ch t he scale of t he obj ect being rendered. ( To accom m odat e a variet y of obj ect s, we should probably replace t his value wit h a uniform variable.) The rem ainder of t he vert ex shader perform s a sim ple diffuse light ing equat ion,

copies t he t coordinat e of t he incom ing t ext ure coordinat e int o t he varying variable V, and com put es t he value of t he built - in variable gl_Position.

List in g 1 8 .1 . Ve r t e x sh a de r for h a t ch in g uniform vec3 LightPosition; uniform float Time; varying vec3 ObjPos; varying float V; varying float LightIntensity; void main() { ObjPos

= (vec3(gl_Vertex) + vec3(0.0, 0.0, Time)) * 0.2;

vec3 pos vec3 tnorm vec3 lightVec

= vec3(gl_ModelViewMatrix * gl_Vertex); = normalize(gl_NormalMatrix * gl_Normal); = normalize(LightPosition - pos);

LightIntensity

= max(dot(lightVec, tnorm), 0.0);

V = gl_MultiTexCoord0.t;

// try .s for vertical stripes

gl_Position = ftransform(); }

18.1.3. Generating Hatching Strokes The purpose of our fragm ent shader is t o det erm ine whet her each fr agm ent is t o be drawn as whit e or black in order t o creat e lines on t he sur face of t he obj ect . As w e m ent ioned, t here are som e challenges along t he way. To prepare for t he full- blow n hat ching shader, w e develop som e of t he t echniques we need and illust rat e t hem on a sim ple obj ect : a sphere. We st art wit h t he sam e code t hat was present ed in Sect ion 17.4.1 for generat ing vert ical st ripes, nam ely, float sawtooth = fract(V * 16.0); float triangle = abs(2.0 * sawtooth - 1.0); float square = step(0.5, triangle);

Recall t hat V was a varying variable passed from t he vert ex shader. I t w as equal t o t he s t ext ure coordinat e if we want ed t o generat e vert ical st ripes and equal t o t he t t ext ure coordinat e if we want ed t o generat e horizont al st ripes. We chose t he num ber 16 t o give us 16 whit e st ripes and 16 black st ripes. The result of t his code is illust rat ed in Figure 18.1. We can m odify t he relat ive size of t he whit e and black st ripes by adj ust ing t he t hreshold value provided in t he step funct ion.

Figu r e 1 8 .1 . A sph e r e w it h a st r ipe pa t t e r n ge n e r a t e d pr oce du r a lly ba se d on t h e s t e x t u r e coor din a t e ( Cou r t e sy of Be r t Fr e u de n be r g, Un ive r sit y of M a gde bu r g, 2 0 0 2 )

18.1.4. Obtaining Uniform Line Density We now have reasonable- looking st ripes, but t hey aren't of uniform widt h. They appear fat t er along t he equat or and pinched in at t he pole. We'd like t o end up wit h lines t hat are of roughly equal widt h in screen space. This requires t he use of t he dFdx and dFdy funct ions: float dp = length(vec2(dFdx(V), dFdy(V)));

As we learned in Sect ion 17.4.3, t his com put at ion provides us wit h t he gradient ( i.e., how rapidly V is changing at t his point on t he surface) . We can use t his value t o adj ust t he densit y of lines in screen space. Com put ing t he act ual gr adient wit h t he length funct ion involves a pot ent ially cost ly square root operat ion. Why not use t he approxim at ion t o t he gradient discussed in Sect ion 17.4.3? I n t his case we m ust com put e t he act ual gradient because t he approxim at ion t o t he gradient isn't quit e good enough for our purposes. We're not using t his value t o est im at e t he filt er widt h for ant ialiasing; inst ead we're using it t o com put e t he st ripe fr equency. This com put at ion needs t o be rot at ionally invariant so t hat our st ripes don't j um p around j ust because we rot at e t he obj ect . For t his reason, w e need t o com put e t he act ual lengt h of t he gradient vect or, not j ust t he sum of t he absolut e values of t he t wo com ponent s of t he gradient vect or. So, we use t he base 2 logarit hm of t his value ( shown applied t o t he sphere in Figure 18.2 ( A) ) t o adj ust t he densit y in discret e st epseach t im e dp doubles, t he num ber of lines doubles unless we do som et hing about it . The st ripes get t oo t hin and t oo dense if doubling occurs. To count er act t his effect ( because w e are int erest ed in get t ing a const ant line densit y in scr een space) , w e decrease t he num ber of st ripes when t he densit y get s t oo high. We do t his by negat ing t he logarit hm .

Figu r e 1 8 .2 . Adj u st in g t h e st r ipe fr e qu e n cy. Th e in t e ge r pa r t of t h e loga r it h m of t h e gr a die n t ( A) is t h e ba sis for de t e r m in in g st r ipe fr e qu e n cy. Fir st , t h e sph e r e is sh ow n w it h a h ighe r fr e que ncy of st r ipe s ( B) . Th e in t e ge r pa r t of t h e loga r it h m t h e n a dj u st s t h e st r ipe fr e qu e n cy in ( C) , a n d t h e e ffe ct of t a pe r in g t he e n ds is sh ow n in ( D ) . ( Cour t e sy of Be r t Fr e u de n be r g, Un ive r sit y of M a gde bu r g, 2 0 0 2 )

float float float float

logdp ilogdp frequency sawtooth

= = = =

-log2(dp); floor(logdp); exp2(ilogdp); fract(V * 16.0 * frequency);

A sphere wit h a higher st r ipe frequency is show n in Figure 18.2 ( B) . As you can see, t he lines look reasonable in t he low er part of t he sphere, but t here are t oo m any at t he pole. By applying t he st ripe fr equency adj ust m ent , we end up wit h st ripes of roughly equal widt h across t he sphere ( see Figure 18.2 ( C) ) . Not ice t he correlat ion bet ween Figure 18.2 ( A) and Figure 18.2 ( C) . The next issue t o addr ess is t he abrupt changes t hat occur as we j um p fr om one st roke frequency t o t he next . Our eyes det ect a dist inct edge along t hese t ransit ions, and we need t o t ake st eps t o soft en t his edge so t hat it is less dist ract ing. We can accom plish t his by using t he fract ional part of logdp t o do a sm oot h blend bet ween t wo frequencies of t he t riangle wave. This value is 0 at t he st ar t of one frequency, and it increases t o 1.0 at t he point where t he j um p t o t he next frequency occurs. float transition = logdp - ilogdp;

As we saw earlier, w e can gener at e a t riangle wave wit h fr equency double t hat of a t r iangle wave wit h frequency t by t aking abs ( 2.0 * t 1.0) . We can use t he value of transition t o linearly int erpolat e bet w een t and abs ( 2.0 * t 1.0) by com put ing ( 1.0 transition) * t + transition * abs ( 2.0 * t 1.0) . This is exact ly t he sam e as if we did mix ( abs ( 2.0 * t 1.0) , t, transition) . But inst ead of using mix, we not e t hat t his is equivalent t o abs ( ( 1.0 transition) * t - transition) . Using t he previously com put ed value for our base frequency ( triangle) , we end up wit h t he following code: triangle = abs((1.0 - transition) * triangle - transition);

The result of drawing t he sphere wit h uniform st ripe densit y and t apered ends is shown in Figure 18.2 ( D) .

18.1.5. Simulating Lighting To sim ulat e t he effect of light ing, we'd like t o m ake t he dark st ripes m ore prom inent in regions t hat are in shadow and t he whit e st ripes m or e prom inent in regions t hat are lit . We can do t his by using t he com put ed light int ensit y t o m odify t he t hreshold value used in t he step funct ion. I n regions t hat are lit , t he t hreshold value is decr eased so t hat black st ripes get t hinner . I n regions t hat are in shadow, t he t hr eshold value is increased so t hat t he black st ripes get wider. const float edgew = 0.2;

// width of smooth step

float edge0 = clamp(LightIntensity - edgew, 0.0, 1.0); float edge1 = clamp(LightIntensity, 0.0, 1.0); float square = 1.0 - smoothstep(edge0, edge1, triangle);

Once again, we use t he smoothstep funct ion t o ant ialias t he t ransit ion. Because our st ripe pat t ern is a ( roughly) const ant widt h in screen space, we can use a const ant filt er widt h r at her t han an adapt ive one. The result s of t he light ing effect can be seen in Figure 18.3.

Figu r e 1 8 .3 . Applyin g light in g t o t h e sph e r e . I n ( A) , t h e sph e r e is lit w it h a sim ple ligh t in g m ode l a n d n o st r ipe s. I n ( B) , t h e ligh t in t e n sit y m odu la t e s t h e w idt h of t h e st r ipe s t o sim u la t e t h e e ffe ct of ligh t in g. ( Cou r t e sy of Be r t Fr e u de n be r g, Un ive r sit y of M a gde bu r g, 2 0 0 2 )

18.1.6. Adding Character I f a woodcut block is m ade by a hum an art ist and not by a m achine, t he cut s in t he wood aren't perfect in t hickness and spacing. How do we add som e im perfect ions int o our m at hem at ically perfect descript ion of hat ching lines? Wit h noise ( see Chapt er 15) . For t his shader, we don't need anyt hing fancy; we j ust want t o add som e " wiggle" t o our ot herwise perfect lines or perhaps som e " pat chiness" t o our sim ple light ing equat ion. We can use a t ileable 3D t ext ure cont aining Perlin noise in t he sam e w ay for t his shader as for t he shaders in Chapt er 15. To add wiggle t o our lines, we m odify t he saw t oot h generat ion funct ion: float sawtooth = fract((V + noise * 0.1) * frequency * stripes);

The result of noise added t o our st ripe pat t ern is illust rat ed in Figure 18.4.

Figu r e 1 8 .4 . Addin g n oise t o t h e h a t ch in g a lgor it hm . I n ( A) , t h e Pe r lin noise fu nct ion is a pplie d dir e ct ly t o t h e sph e r e 's su r fa ce . I n ( B) , it m odu la t e s t h e pa r a m e t e r t h a t de fin e s t h e fr e qu e n cy of t h e h a t ch in g st r ok e s. ( Cou r t e sy of Be r t Fr e u de n be rg, Un ive r sit y of M a gde bu r g, 2002)

18.1.7. Hatching Fragment Shader The pieces described in t he preceding sect ions are put t oget her in t he general- purpose hat ching shader show n in List ing 18.2. I t bases it s hat ching st roke com put at ion on t he t t ext ure coordinat e, so t he result is horizont al st ripes rat her t han vert ical ones. The result s of applying t his shader t o t he t eapot m odel are shown in Figure 18.5.

Figu r e 1 8 .5 . W oodcu t - st yle t e a pot r e n de r e d w it h t h e h a t ch in g sh a de r ( Cou r t e sy of Be r t Fr e u de n be r g, Un ive r sit y of M a gde bu r g, 2 0 0 2 )

List in g 1 8 .2 . Fr a gm e n t sh a de r for w oodcu t - st yle r e n de r in g const float frequency = 1.0; varying vec3 ObjPos; varying float V; varying float LightIntensity;

// object space coord (noisy) // generic varying

uniform sampler3D Noise;

// value of Noise = 3;

void main() { float dp float logdp float ilogdp float stripes float noise

= = = =

length(vec2(dFdx(V), dFdy(V))); -log2(dp * 8.0); floor(logdp); exp2(ilogdp);

= texture3D(Noise, ObjPos).x;

float sawtooth = fract((V + noise * 0.1) * frequency * stripes); float triangle = abs(2.0 * sawtooth - 1.0); // adjust line width float transition = logdp - ilogdp; // taper ends triangle = abs((1.0 + transition) * triangle - transition); const float edgew = 0.3;

// width of smooth step

float edge0 = clamp(LightIntensity - edgew, 0.0, 1.0); float edge1 = clamp(LightIntensity, 0.0, 1.0); float square = 1.0 - smoothstep(edge0, edge1, triangle); gl_FragColor = vec4(vec3(square), 1.0); }

18.2. Technical Illustration Example Pick up j ust about any inst ruct ion m anual, t echnical book, or encyclopedia and you w ill see a variet y of illust rat ions ot her t han phot ographs or phot orealist ic graphics. Technical illust rat ors have learned various t echniques over t he years t o convey r elevant infor m at ion as sim ply and as clearly as possible. Det ails t hat do not cont ribut e t o underst anding are om it t ed, and det ails t hat are crucial t o underst anding are clear and st raight forward. This st yle of illust rat ion differs from m ainst ream com put er graphics for w hich an enorm ous am ount of det ail m ay be pr esent ed in an im age t o m ake it look m ore realist ic. The effort t o convey inform at ion as succinct ly as possible in a t echnical illust rat ion is sum m ed up by a st rat egy referred t o by Edward Tuft e ( 1997) as " t he sm allest effect ive difference." I n his book, Visual Explanat ions, Tuft e says, " Make all visual dist inct ions as subt le as possible, but st ill clear and effect ive." Various NPR pract it ioners are at t em pt ing t o develop algorit hm s t o creat e t echnical illust r at ions. The goal is t o sim plify or even aut om at e t he t ask of creat ing high- qualit y t echnical illust rat ions according t o t im e- honored illust rat ion t echniques. Much of our com prehension about an obj ect 's shape com es from light ing. Yet t he t radit ional light ing equat ion is deficient at conveying shape infor m at ion in areas t hat are not lit direct ly, because t hese areas appear flat . The only light ing in t hese areas com es from t he am bient t erm , which is const ant . Technical illust rat ions also highlight im port ant edges in black so t hat t hey are dist inct and clearly convey t he shape of t he obj ect . I f a sm all am bient t erm is used in t he t radit ional light ing m odel, black edge highlight s t ypically are indist inguishable from unlit regions of t he obj ect , which ar e also very near black. I n 1998, Bruce and Am y Gooch, Pet er Shirley, and Elaine Cohen surveyed illust rat ions and cam e up wit h a list of com m on charact erist ics for color illust rat ions done wit h airbrush and pen. z

z z

z

z

z

Surface boundaries, silhouet t e edges, and discont inuit ies in t he surface of an obj ect are usually draw n wit h black curves. A single light source is used, and it produces a whit e highlight on obj ect s. The light source is usually posit ioned above t he obj ect so t hat t he diffuse reflect ion t erm varies from [ 0,1] across t he visible port ion of t he obj ect . Effect s t hat add com plexit y ( realism ) such as shadows, reflect ions, and m ult iple light sources are not shown. Mat t e obj ect s are shaded wit h int ensit ies far from whit e and black so as t o be clearly dist inct from ( black) edges and ( whit e) highlight s. The warm t h or coolness of t he color indicat es t he surface norm al ( and hence t he curvat ure of t he surface) .

These charact erist ics were incorporat ed int o a " low dynam ic range art ist ic t one algorit hm " t hat we now refer t o as GOOCH SHADI NG. One of t he im port ant aspect s of Gooch shading is t he generat ion of black curves t hat represent im port ant edges. There are a num ber of t echniques for rendering such edges. Perhaps t he best m et hod is t o have t hem ident ified during t he m odeling process by t he person designing t he m odel. I n t his case, t he edges can be rendered as ant ialiased black lines t hat are drawn on t op of t he obj ect it self, t hat is, in a second rendering pass t hat draws t he edges aft er t he obj ect s in t he scene have been com plet ely rendered. I f im port ant edges have not been ident ified during t he m odeling process, several m et hods can

generat e t hem aut om at ically. Qualit y of result s varies according t o t he m et hod used and t he charact erist ics of t he obj ect s in t he scene. I nt erior boundary or crease edges should also be ident ified, and t hese are som et im es cr it ical t o com prehension. A t echnique t hat ident ifies boundary or crease edges as well as silhouet t e edges involves using vert ex and fragm ent shaders t o w rit e w orld- space norm als and dept h values int o t he fram ebuffer. The result is st ored as a t ext ure, and a subsequent rendering pass wit h different vert ex and fragm ent shaders can use an edge det ect ion algorit hm on t his " im age" t o det ect discont inuit ies ( i.e., edges) in t he scene ( Jason Mit chell ( 2002) ) . A t echnique for drawing silhouet t e edges for sim ple obj ect s, described by Jeff Lander ( 2000) in Under t he Shade of t he Rendering Tree, requires drawing t he geom et ry t wice. First , we dr aw j ust t he front - facing polygons using filled polygons and t he dept h com parison m ode set t o GL_LESS. The Gooch shaders are act ive when we do t his. Then, we draw t he back- facing polygons as lines wit h t he dept h com parison m ode set t o GL_LEQUAL. This has t he effect of drawing lines such t hat a front - facing polygon shares an edge wit h a back - facing polygon. We draw t hese lines in black, using fixed funct ionalit y OpenGL wit h polygon m ode set so t hat backfacing polygons are drawn as lines. The OpenGL calls t o do t his are shown in List ing 18.3.

List in g 1 8 .3 . C code for dr a w in g silh ou e t t e e dge s on sim ple obj e ct s // Enable culling glEnable(GL_CULL_FACE); // Draw front-facing polygons as filled using the Gooch shader glPolygonMode(GL_FRONT, GL_FILL); glDepthFunc(GL_LESS); glCullFace(GL_BACK); glUseProgramObjectARB(ProgramObject); drawSphere(0.6f, 64); // Draw back-facing polygons as black lines using standard OpenGL glLineWidth(5.0); glPolygonMode(GL_BACK, GL_LINE); glDepthFunc(GL_LEQUAL); glCullFace(GL_FRONT); glColor3f(0.0, 0.0, 0.0); glUseProgramObjectARB(0); drawSphere(0.6f, 64);

A second aspect of Gooch shading is t hat specular highlight s are com put ed wit h t he exponent ial specular t erm of t he Phong light ing m odel and are rendered in whit e. Highlight s convey infor m at ion about t he curvat ure of t he surface, and choosing whit e as t he highlight color ensures t hat highlight s are dist inct from edges ( which are black) and from t he colors shading t he obj ect ( which are chosen t o be visually dist inct from whit e or black) . A t hird aspect of t he algorit hm is t hat a lim it ed range of lum inance values is used t o convey infor m at ion about t he curvat ure of t he surfaces t hat are being rendered. This part of t he shading uses t he color of t he obj ect , which is t ypically chosen t o be an int erm ediat e value t hat doesn't int er fer e visually w it h w hit e or black. Because t he range of lum inance values is lim it ed, a warm - t o- cool color gradient is also added t o convey m ore inform at ion about t he obj ect 's surface. Art ist s use " warm " colors ( yellow, red, and orange) and " cool" color s ( blue, violet , and green) t o com m unicat e a sense of dept h. Warm colors, which appear t o advance, indicat e obj ect s t hat are closer. Cool colors, which appear t o recede, indicat e obj ect s t hat are fart her away. The act ual shading of t he obj ect depends on t wo fact ors. The diffuse reflect ion fact or generat es

lum inance values in a lim it ed range t o provide one part of t he shading. A color ram p t hat blends bet w een t w o colors provides t he ot her part of t he shading. One of t he t wo colors is chosen t o be a cool ( recessive) color, such as blue, t o indicat e surfaces t hat are angled away fr om t he light source. The ot her color is chosen t o be a warm ( advancing) color, such as yellow , t o indicat e surfaces facing t oward t he light source. The blue- t o- yellow ram p provides an undert one t hat ensures a cool- t o- warm t ransit ion regardless of t he diffuse obj ect color t hat is chosen. The form ulas used t o com put e t he colors used for Gooch shading are as follows:

k cool is t he color for t he areas t hat are not illum inat ed by t he light source. We com put e t his

value by adding t he blue undert one color and t he diffuse color of t he obj ect , k diffuse . The value α

is a variable t hat defines how m uch of t he obj ect 's diffuse color will be added t o t he blue undert one color. k warm is t he color for t he areas t hat are fully illum inat ed by t he light source. This value is com put ed as t he sum of t he yellow undert one color and t he obj ect 's diffuse color m ult iplied by a scale fact or,β. The final color is j ust a linear blend bet w een t he colors k cool and k warm based on t he diffuse reflect ion t erm N · L, where N is t he norm alized surface norm al and L is t he unit vect or in t he direct ion of t he light source. Since N · L can vary from [ 1,1] , we add 1 and divide t he result by 2 t o get a value in t he range [ 0,1] . This value det erm ines t he rat io of k cool and k warm t o pr oduce t he final color value.

18.2.1. Application Setup We im plem ent t his shading algorit hm in t wo passes ( i.e., we draw t he geom et ry t wice) . We use t he Lander t echnique t o render silhouet t e edges in black. I n t he first pass, we cull back- facing polygons and render t he front - facing polygons wit h t he Gooch shader. I n t he second pass, we cull all t he front - facing polygons and use OpenGL fixed funct ionalit y t o render t he edges of t he back - facing polygons in black. We draw t he edges wit h a line widt h great er t han one pixel so t hat t hey can be seen out side t he obj ect . For t his shader t o work properly, only vert ex posit ions and norm als need t o be passed t o t he vert ex shader.

18.2.2. Vertex Shader The goals of t he Gooch vert ex shader are t o produce a value for t he ( 1 + N · L) / 2 t erm in t he previous equat ions, and t o pass on t he reflect ion vect or and t he view vect or so t hat t he specular reflect ion can be com put ed in t he fr agm ent shader ( see List ing 18.4) . Ot her elem ent s of t he shader are ident ical t o shaders discussed earlier.

List in g 1 8 .4 . Ve r t e x sh a de r for Gooch m a t t e sh a din g

uniform vec3

LightPosition;

varying float NdotL; varying vec3 ReflectVec;

// (0.0, 10.0, 4.0)

varying vec3

ViewVec;

void main() { vec3 ecPos vec3 tnorm vec3 lightVec ReflectVec ViewVec NdotL gl_Position }

= = = = = = =

vec3(gl_ModelViewMatrix * gl_Vertex); normalize(gl_NormalMatrix * gl_Normal); normalize(LightPosition - ecPos); normalize(reflect(-lightVec, tnorm)); normalize(-ecPos); (dot(lightVec, tnorm) + 1.0) * 0.5; ftransform();

18.2.3. Fragment Shader The fragm ent shader im plem ent s t he t one- based shading port ion of t he Gooch shading algorit hm and adds t he specular reflect ion com ponent ( see List ing 18.5) . The color s and rat ios are defined as uniform variables so t hat t hey can be easily m odified by t he applicat ion. The reflect ion and view vect ors ar e norm alized in t he fragm ent shader because int erpolat ion m ay have caused t hem t o have a lengt h ot her t han 1.0. The result of rendering wit h t he Gooch shader and t he silhouet t e edge algorit hm described by Lander is shown in Color Plat e 28.

List in g 1 8 .5 . Fr a gm e n t sh a de r for Gooch m a t t e sh a din g uniform uniform uniform uniform uniform

vec3 vec3 vec3 float float

SurfaceColor; WarmColor; CoolColor; DiffuseWarm; DiffuseCool;

// // // // //

(0.75, 0.75, 0.75) (0.6, 0.6, 0.0) (0.0, 0.0, 0.6) 0.45 0.45

varying float NdotL; varying vec3 ReflectVec; varying vec3 ViewVec; void main() { vec3 kcool vec3 kwarm vec3 kfinal

= min(CoolColor + DiffuseCool * SurfaceColor, 1.0); = min(WarmColor + DiffuseWarm * SurfaceColor, 1.0); = mix(kcool, kwarm, NdotL);

vec3 nreflect = normalize(ReflectVec); vec3 nview = normalize(ViewVec);

}

float spec spec

= max(dot(nreflect, nview), 0.0); = pow(spec, 32.0);

gl_FragColor

= vec4(min(kfinal + spec, 1.0), 1.0);

18.3. Mandelbrot Example C'm on, now , what kind of a book on graphics program m ing would t his be wit hout an exam ple of drawing t he Mandelbrot set ? Our last shader of t he chapt er doesn't fall int o t he cat egory of at t em pt ing t o achieve an art ist ic or paint erly effect , but it 's an exam ple of perform ing a t ype of general- purpose com put at ion on t he gr aphics hardware for scient ific visualizat ion. I n t his case, t he graphics hardware enables us t o do real- t im e explorat ion of a fam ous m at hem at ical funct ion t hat com put es t he Mandelbrot set . I n 1998, Michael Rivero creat ed a RenderMan shader t hat creat es t he Mandelbr ot set as a t ext ure. Subsequent ly, Dave Baldw in adapt ed t his shader for GLSL, St eve Koren t hen m ade som e m odificat ions t o it t o get it working on program m able hardware for t he fir st t im e, and I 've adapt ed t his shader furt her for inclusion in t his book. The point of including t his shader is t o em phasize t he fact t hat wit h t he OpenGL Shading Language, com put at ions t hat w ere previously possible only in t he realm of t he CPU can now be execut ed on t he graphics hardware. Perform ing t he com put at ions com plet ely on t he graphics hardw are is a big perform ance win because t he com put at ions can be carried out on m any pixels in parallel. Visualizat ion of a com plex m at hem at ical funct ion such as t he Mandelbrot set barely begins t o t ap t he pot ent ial for using program m able shader t echnology for scient ific visualizat ion.

18.3.1. About the Mandelbrot Set To underst and t he Mandelbrot set , we m ust first recall a few t hings from our high school m at hem at ics days. No real num ber, when m ult iplied by it self, yields a negat ive value. But t he im aginary num ber called i is defined t o be equal t o t he square root of 1. Wit h i, t he square root of any negat ive num ber can easily be described. For inst ance, 3i squared is 9, and conversely t he square root of 9 is 3i. Num bers t hat consist of a real num ber and an im aginary num ber, such as 6 + 4i, are called com plex num bers. Arit hm et ic operat ions can be perform ed on com plex num bers j ust as on real num bers. The result of m ult iplying t w o com plex num bers is as follows: x = a + bi y = c + di xy = ac + adi + cbi - bd = ( ac - bd) + ( ad + bc) i

Because com plex num bers cont ain t w o part s, t he set of com plex num bers is t w o- dim ensional. Com plex num bers can be plot t ed on t he com plex num ber plane, which uses t he horizont al axis t o represent t he real part and t he vert ical axis t o represent t he im aginary part ( see Figur e 18.6) .

Figu r e 1 8 .6 . A por t ion of t h e com ple x n u m be r pla n e

I n Figure 18.6, we see t hree sym bols plot t ed on t he com plex num ber plane. A sm all square is plot t ed at t he com plex num ber 2 + i, a sm all circle is plot t ed at 1 + 2i, and a t riangle is plot t ed at 1.5 0.5i. Wit h t he assist ance of 1970s com put er t echnology ( quit e inferior by t oday's consum er PC st andards) , a m at hem at ician nam ed Benoit Mandelbrot began st udying a recursive funct ion involving com plex num bers:

I n t his funct ion, t he value of Z is init ialized t o c, t he value of t he com plex num ber being t est ed. For each it erat ion, t he value of Z is squared and added t o c t o det erm ine a new value for Z. This am azingly sim ple it erat ive form ula produces w hat has been called t he m ost com plex obj ect in m at hem at ics, and perhaps t he m ost com plex st ruct ure ever seen! I t t urns out t hat for som e values of c, t he funct ion event ually approaches infinit y, and for ot her values it does not . Quit e sim ply, values of c t hat go off t o infinit y are not part of t he Mandelbrot set , and t he rest ar e. I f w e use a com put er ( or an OpenGL Shading Language- capable graphics accelerat or! ) t o t est t housands of point s on t he com plex num ber plane and assign a gray level t o t hose t hat go off t o infinit y and black t o t hose t hat don't , we see t he following fam iliar cardioid/ prickly pear shape st art t o appear ( see Figure 18.7) .

Figu r e 1 8 .7 . Sim ple plot of t h e M a n de lbr ot se t

How exact ly do w e t est whet her t hese values go off t o infinit y? Well, Mandelbrot helped us out a bit here. He showed t hat if t he m agnit ude of Z ( it s dist ance from t he origin) was great er t han 2, t he value of t he funct ion would go t o infinit y. To encode t his funct ion in a program m ing language, all we need t o do is st op it erat ing when t he m agnit ude of Z surpasses 2. Even easier, because we'r e always dealing wit h Z2 , we can sim ply check t o see if Z2 is great er t han 4. The values inside t he black region of Figure 18.7 do not go off t o infinit y in any reasonable num ber of it erat ions. How do we deal wit h t hese? To prevent our com put er or graphics hardware from locking up in an infinit e loop, we need t o decide on t he m axim um num ber of it erat ions t o allow before we give up and assum e t he point is inside t he Mandelbrot set . Wit h t hese t w o exit crit er ia, we can w rit e a sim ple loop t hat com put es t he Mandelbrot set . The beaut y of t he Mandelbrot set can be enhanced if we color code t he num ber of it erat ions needed t o det erm ine w het her a part icular point is inside t he set . Values det erm ined t o be out side t he set on t he first it erat ion are given one color value, values det erm ined t o be out side t he set on t he second it erat ion are given anot her color value, and so on. I n Figure 18.7, I 've used gr ay levels t o indicat e t he num ber of it erat ions. The m edium gray on t he out side represent s values t hat are ident ified as out side t he Mandelbrot set on t he very first it erat ion. Values in w hit e along t he edge t ook 20 it erat ions t o be ident ified as being out side t he Mandelbrot set . The edges of t he Mandelbrot set hold an infinit e am ount of self- sim ilar variet y. By cont inuing t o zoom in on t he edge det ail, you can find com plex num bers w hose m agnit ude st ayed below 2 for hundreds or even t housands of it er at ions of t he funct ion before finally exceeding t he t hreshold and zoom ing off t o infinit y. Here are a few ot her deep t hought s t hat you can use t o am aze and am use your friends: z

The lengt h of t he border for t he Mandelbrot set is infinit e.

z

All t he regions inside t he Mandelbr ot set ( i.e., t he black regions) are connect ed.

z

z

There is exact ly one band surrounding t he Mandelbrot set for each it erat ion value ( e.g., a band t hat exceeded t he t hreshold on t he first it erat ion, a band t hat exceeded on t he second it er at ion, and so on) . The it erat ion bands go com plet ely around t he Mandelbrot set , do not break, and do not cross each ot her . When you've zoom ed in t o explore an edge region wit h am azing com plexit y, t his is pret t y ast onishing. There are an infinit e num ber of " m ini- Mandelbrot s" ( regions t hat look like warped or t ransform ed versions of t he full Mandelbrot set ) wit hin t he original.

18.3.2. Vertex Shader

The vert ex shader for t he Mandelbrot set ( see List ing 18.6) is alm ost exact ly t he sam e as t he vert ex shader for t he sim ple brick exam ple t hat was described in Sect ion 6.2. The only difference is t hat we assum e t hat t ext ure coordinat es will be provided in t he range of [ 0,1] for bot h s and t , and we m ap t hese values int o t he range [ - 2.5, 2.5] and st ore t he result int o a varying variable nam ed Position. This enables t he fragm ent shader t o plot values direct ly ont o a coordinat e syst em t hat is j ust t he right size for plot t ing t he Mandelbrot set , and it has t he point ( 0,0) in t he m iddle. I f t he applicat ion dr aws a single polygon t hat is a screen- aligned square and has t ext ure coordinat e ( 0,0) in t he lower- left corner and ( 1,1) in t he upper right , t he result is a st andard repr esent at ion of t he Mandelbrot set . Of course, w it h our OpenGL Mandelbrot shader, t he Mandelbr ot set can be " t ext ured" ont o any geom et ry and we even apply a sim ple light ing m odel as an added bonus.

List in g 1 8 .6 . Ve r t e x sh a de r for dr a w in g t h e M a n de lbr ot se t uniform uniform uniform uniform

vec3 LightPosition; float SpecularContribution; float DiffuseContribution; float Shininess;

varying float LightIntensity; varying vec3 Position; void main() { vec3 ecPosition vec3 tnorm vec3 lightVec vec3 reflectVec vec3 viewVec float spec spec LightIntensity

Position gl_Position

= = = = = = = =

vec3(gl_ModelViewMatrix * gl_Vertex); normalize(gl_NormalMatrix * gl_Normal); normalize(LightPosition - ecPosition); reflect(-lightVec, tnorm); normalize(-ecPosition); max(dot(reflectVec, viewVec), 0.0); pow(spec, Shininess); DiffuseContribution * max(dot(lightVec, tnorm), 0.0) + SpecularContribution * spec; = vec3(gl_MultiTexCoord0 - 0.5) * 5.0; = ftransform();

}

18.3.3. Fragment Shader The fragm ent shader im plem ent s t he algorit hm described in t he previous sect ion. Uniform variables est ablish t he m axim um num ber of it erat ions and t he st art ing point for viewing t he Mandelbrot set ( cent er value and zoom fact or) . The applicat ion is given art ist ic license t o use uniform variables t o set one color for point s inside t he set and t wo colors t o use for point s out side t he set . For values out side t he set , t he color gradient from OuterColor1 t o OuterColor2 is broken int o 20 separat e bands, and t he cycle is repeat ed if t he num ber of it erat ions goes above 20. I t is r epeat ed again if t he num ber of it erat ions goes above 40, and so on. This shader m aps t he x coordinat e of t he com put ed posit ion in t he com plex num ber plane ( i.e., t he value in Position.x) t o t he real num ber in t he it erat ive funct ion, and t he y coordinat e t o t he im aginary num ber. Aft er t he init ial condit ions have been est ablished, t he shader ent ers a loop wit h t wo exit crit eriaif we reach t he m axim um num ber of it erat ions allowed or if t he point proves t o be out side t he set . Wit hin t he loop, t he funct ion Z2 + c is com put ed for use in t he next it erat ion. Aft er t he loop is exited, we com put e t he color of t he fragm ent . I f w e're inside t he set , we use t he inside color. I f w e're on t he edge or out side, we blend t he edge color and t he out er color, depending on t he num ber of it erat ions t hat have occurred.

The com plet e fragm ent shader is shown in List ing 18.7.

List in g 1 8 .7 . Fr a gm e n t sh a de r for com put ing t h e M a n de lbr ot se t varying vec3 Position; varying float LightIntensity; uniform uniform uniform uniform uniform uniform uniform

float float float float vec3 vec3 vec3

void main() { float float float float

MaxIterations; Zoom; Xcenter; Ycenter; InnerColor; OuterColor1; OuterColor2;

real imag Creal Cimag

= = = =

Position.x Position.y real; // imag; //

* Zoom + Xcenter; * Zoom + Ycenter; Change this line. . . . . .and this one to get a Julia set

float r2 = 0.0; float iter; for (iter = 0.0; iter < MaxIterations && r2 < 4.0; ++iter) { float tempreal = real; real = (tempreal * tempreal) - (imag * imag) + Creal; imag = 2.0 * tempreal * imag + Cimag; r2 = (real * real) + (imag * imag); } // Base the color on the number of iterations vec3 color; if (r2 < 4.0) color = InnerColor; else color = mix(OuterColor1, OuterColor2, fract(iter * 0.05)); color *= LightIntensity; gl_FragColor = vec4(color, 1.0); }

There is obviously room for im provem ent in t his shader. One t hing you m ight do is im prove t he color select ion algorit hm . One possibilit y is t o use a 1D t ext ure t o st ore a color lookup t able. The num ber of it erat ions could be used t o index int o t his t able t o obt ain t he color for drawing t he fragm ent . Aft er you've invent ed a pleasing coloring schem e, you can explore som e of t he popular Mandelbrot " t ourist locat ions." Various books and Web sit es have published t he coordinat es of int erest ing locat ions in t he Mandelbrot set , and t hese shaders are set up so t hat you can plug t hose coordinat es in direct ly and zoom in and see for yourself. Figure 18.8 shows a few t hat I explored.

Figu r e 1 8 .8 . Re su lt s fr om t h e M a n de lbr ot sh a de r

18.3.4. Julia Sets Julia set s are relat ed t o t he Mandelbrot set . Each point in t he Mandelbrot set can be used t o gener at e a Julia set , and t hese are j ust as m uch fun t o explore as t he Mandelbrot set . The only difference is t hat t he const ant c in t he equat ion t er m Z2 + c is init ialized t o t he value of a point in t he Mandelbrot set ot her t han t he one current ly being plot t ed. To change t he Mandelbrot shader int o a fragm ent shader for doing Julia set s, change t he t wo lines of code t hat init ialize t he value of c: float float

Creal = -1.36; Cimag = 0.11;

// Now we'll see an interesting Julia set

Figure 18.9 shows a few exam ples of t he Julia set s t hat can be rendered w it h t his shader . You m ight want t o change t his shader so t hat t he values for Creal and Cimag can be passed in as uniform variables when you w ant t o draw a Julia set . The num bers are no longer im aginary. Now w e can do real- t im e explorat ion of t he m at hem at ical universe t hrough t he OpenGL Shading Language!

Figu r e 1 8 .9 . Som e Ju lia se t s r e n de r e d w it h t h e M a n de lbr ot sh a de r r e a l = 0 .7 6 5 im a g = 0 .1 1 r e a l = 1 .5 im a g = 0 .0 r e a l = 0 .3 2 im a g = 0 .0 4 3

18.4. Summary Realism is no longer t he goal for all applicat ions of int eract ive com put er graphics. Because of t he flexibilit y of program m able graphics hardware, we no longer have t o set t le for t he classic " look" of com put er graphics. A high- level procedural language such as t he OpenGL Shading Language enables art ist s and pract it ioners t o express algorit hm s for rendering in m ore art ist ic st yles such as pen- and- ink, woodcut , and paint s. A procedural hat ching shader was present ed and described t o illust rat e how such rendering can be accom plished. Various st yles of t echnical illust rat ion can be done int eract ively, as shown by t he Gooch shader described in t his chapt er. I t is also possible t o writ e shaders t hat assist in t he visualizat ion of m at hem at ical funct ions, as dem onst rat ed by t he Mandelbrot and Julia set shaders. The hist ory of hum an art shows t hat t here is an endless variet y of ar t ist ic st yles. The OpenGL Shading Language can be used t o cr eat e shaders t hat em ulat e som e of t hese st yles and perhaps t o invent new ones.

18.5. Further Information Books devot ed t o t he t opic of non- phot orealist ic rendering include Non- Phot orealist ic Rendering by Am y Gooch and Bruce Gooch ( 2001) and Non- Phot or ealist ic Com put er Gr aphics by Thom as St rot hot t e and St efan Schlecht weg ( 2002) . The Gooch shading algorit hm is defined and described in t he SI GGRAPH 1998 paper, A NonPhot orealist ic Light ing Model for Aut om at ic Technical I llust rat ion, by Am y Gooch, Bruce Gooch, Pet er Shirley, and Elaine Cohen. This paper draws on concept s present ed by Edward Tuft e in Visual Explanat ions ( 1997) . A short discussion of NPR can be found in Real- Tim e Rendering, Second Edit ion, by Tom as Akenine- Möller and Eric Haines ( 2002) . I 've also included a lot of references t o NPR resources in t he m ain bibliography at t he end of t his book. The classic t ext on fract als and t he Mandelbrot set is, of course, The Fract al Geom et ry of Nat ure, Updat ed and Augm ent ed, by Benoit Mandelbrot ( 1983) . I n 1986, Heinz- Ot t o Peit gen and Pet er Richt er wrot e The Beaut y of Fract als, anot her book you can enj oy looking at as well as reading. Peit gen and Diet m er Saupe ( 1988) edit ed a book called The Science of Fract al I m ages, which cont ains num erous exam ples and algorit hm s and addit ional m at erial by Mandelbrot , Richard Voss, and ot hers. A couple of t he Mandelbrot " t ourist dest inat ions" t hat I 've list ed were described by Paul Derbyshire on t he now defunct Web sit e, PGD's Quick Guide t o t he Mandelbrot Set . 1 . Akenine- Möller, Tom as, E. Haines, Real- Tim e Rendering, Second Edit ion, AK Pet ers, Lt d., Nat ick, Massachuset t s, 2002. ht t p: / / w ww .realt im erendering.com 2 . Baldwin, Dave, OpenGL 2.0 Shading Language Whit e Paper, Version 1.0, 3Dlabs, Oct ober, 2001. 3 . Derbyshire, Paul, PGD's Quick Guide t o t he Mandelbrot Set , personal Web sit e. ht t p: / / w ww .globalserve.net / ~ derbyshir e/ m anguide.ht m l ( defunct ) 4 . Freudenberg, Bert , Maic Masuch, and Thom as St rot hot t e, Walk- Through I llust rat ions: Fram e- Coherent Pen- and- I nk St yle in a Gam e Engine, Com put er Graphics Forum , Volum e 20 ( 2001) , Num ber 3, Manchest er, U.K. ht t p: / / isgwww.cs.uni- m agdeburg.de/ ~ bert / publicat ions 5 . Freudenberg, Bert , Maic Masuch, and Thom as St rot hot t e, Real- Tim e Halft oning: A Prim it ive For Non- Phot orealist ic Shading, Rendering Techniques 2002, Proceedings 13t h Eurogr aphics Workshop, pp. 227231, 2002. ht t p: / / isgwww.cs.uni- m agdeburg.de/ ~ bert / publicat ions 6 . Freudenberg, Bert , and Maic Masuch, Non- Phot orealist ic Shading in an Educat ional Gam e Engine, SI GGRAPH and Eurographics Cam pfire, Snowbird, Ut ah, June 1June 4, 2002. ht t p: / / isgwww.cs.uni- m agdeburg.de/ ~ bert / publicat ions 7 . Freudenberg, Bert , Real- Tim e St roke- based Halft oning, Ph.D. t hesis, Universit y of Magdeburg, subm it t ed in 2003. 8 . Gooch, Am y, I nt eract ive Non- Phot orealist ic Technical I llust rat ion, Mast er's t hesis, Universit y of Ut ah, Decem ber 1998. ht t p: / / www.cs.ut ah.edu/ ~ gooch/ publicat ion.ht m l 9 . Gooch, Am y, Bruce Gooch, Pet er Shirley, and Elaine Cohen, A Non- Phot orealist ic Light ing Model for Aut om at ic Technical I llust rat ion, Com put er Graphics ( SI GGRAPH '98 Proceedings) , pp. 447452, July 1998. ht t p: / / www.cs.ut ah.edu/ ~ gooch/ publicat ion.ht m l

1 0 . Gooch, Bruce, Pet er- Pike J. Sloan, Am y Gooch, Pet er Shirley, and Richard Riesenfeld, I nt eract ive Technical I llust rat ion, Proceedings 1999 Sym posium on I nt eract ive 3D Graphics, pp. 3138, April 1999. ht t p: / / www.cs.ut ah.edu/ ~ gooch/ publicat ion.ht m l 1 1 . Gooch, Bruce, and Am y Gooch, Non- Phot orealist ic Rendering, AK Pet ers Lt d., Nat ick, Massachuset t s, 2001. ht t p: / / www.cs.ut ah.edu/ ~ gooch/ book.ht m l 1 2 . Lander, Jeff, Under t he Shade of t he Rendering Tree, Gam e Developer Magazine, vol. 7, no. 2, pp. 1721, Feb. 2000. ht t p: / / www.darwin3d.com / gdm 2000.ht m 1 3 . Mandelbrot , Benoit B., The Fract al Geom et ry of Nat ure, Updat ed and Augm ent ed, W. H. Freem an and Com pany, New York, 1983. 1 4 . Mit chell, Jason L., I m age Processing wit h Pixel Shaders in Direct 3D, in Engel, Wolfgang, ed., ShaderX, Wordware, May 2002. ht t p: / / www.pixelm aven.com / j ason 1 5 . Peit gen, Heinz- Ot t o, and P. H. Richt er, The Beaut y of Fract als, I m ages of Com plex Dynam ical Syst em s, Springer Verlag, Berlin Heidelberg, 1986. 1 6 . Peit gen, Heinz- Ot t o, D. Saupe, M. F. Barnsley, R. L. Devaney, B. B. Mandelbrot , R. F. Voss, The Science of Fract al I m ages, Springer Verlag, New York, 1988. 1 7 . St rot hot t e, Thom as, and S. Schlect weg, Non- Phot orealist ic Com put er Graphics, Modeling, Render ing, and Anim at ion, Morgan Kaufm ann Publishers, San Francisco, 2002. 1 8 . Tuft e, Edward, Visual Explanat ions, Graphics Press, Cheshire, Connect icut , 1997.

Chapter 19. Shaders for Imaging One of t he longt im e st rengt hs of OpenGL relat ive t o ot her graphics API s is t hat it has always included facilit ies for bot h im aging and 3D rendering operat ions. Applicat ions can t ake advant age of bot h capabilit ies as needed. For inst ance, a video effect s applicat ion m ight exploit OpenGL's im aging capabilit ies t o send a sequence of im ages ( i.e., a video st ream ) t o OpenGL and have t he im ages t ext ure- m apped ont o a t hree- dim ensional obj ect . Color space conversion or color correct ion can be applied t o t he im ages as t hey are sent t o OpenGL. Tradit ional graphics rendering effect s such as light ing and fog can also be applied t o t he obj ect . The init ial release of t he OpenGL Shading Language focused prim arily on providing support for 3D rendering operat ions. Addit ional im aging capabilit ies are planned for a fut ure version. Nonet heless, m any useful im aging operat ions can st ill be done w it h shaders, as we shall see. I n t his chapt er, we describe shaders whose prim ary funct ion is t o operat e on t wo- dim ensional im ages rat her t han on t hree- dim ensional geom et ric prim it ives. The rast erizat ion st age in OpenGL can be split int o five different unit s, depending on t he prim it ive t ype being rast erized: point rast erizat ion, line rast erizat ion, polygon rast erizat ion, pixel rect angle rast erizat ion, and bit m ap rast erizat ion. The out put of each of t hese five rast erizat ion unit s can be t he input t o a fragm ent shader. This m akes it possible t o perform progr am m able operat ions not only on geom et ry dat a, but also on im age dat a, m aking OpenGL an ext rem ely pow erful and flexible render ing engine. A fragm ent shader can be used eit her t o process each fragm ent t hat is generat ed wit h glBitmap or glDrawPixels or t o process t ext ure values read from a t ext ure m ap. We can divide im aging operat ions int o t wo broad cat egories: t hose t hat requir e access t o a single pixel at a t im e and t hose t hat require access t o m ult iple pixels at a t im e. Wit h t he OpenGL Shading Language, you can easily im plem ent in a fragm ent shader t he im aging operat ions t hat require access t o only a single pixel at a t im e. And wit hin t he fragm ent shader, you can r ead t he varying variable gl_Color t o obt ain t he color value for fragm ent s t hat were generat ed wit h glBitmap or glDrawPixels. Operat ions t hat require access t o m ult iple pixels at a t im e require t hat t he im age first be st ored in t ext ure m em ory. You can t hen access t he im age m ult iple t im es from wit hin a fragm ent shader t o achieve t he desired result . An OpenGL shader t ypically can perform im aging operat ions m uch fast er on t he graphics hardw are t han on t he CPU because of t he highly parallel nat ur e of t he graphics hardware. So we let t he fragm ent shader handle t he t ask. This approach also fr ees t he CPU t o perform ot her useful t asks. I f t he im age t o be m odified is st ored as a t ext ure on t he graphics accelerat or, t he user can int eract wit h it in real t im e t o correct color, r em ove noise, sharpen an im age, and do ot her such operat ions, and all t he work can be done on t he graphics board, wit h very lit t le t raffic on t he I / O bus.

19.1. Geometric Image Transforms As part of it s fixed funct ionalit y, OpenGL defines only one operat ion t hat m odifies t he geom et ric propert ies of an im age: pixel zoom . This operat ion scales an im age as it is sent t o t he display. I f you want t o rot at e an im age, t he t radit ional response has always been " Load t he im age int o t ext ure m em ory, use it t o draw a t ext ured rect angle, and t ransform t he rect angle." Alt hough t his approach does require an ext ra read and w rit e of t he im age w it hin t he gr aphics syst em t he im age m ust be writ t en int o t ext ure m em ory and t hen read as t he rect angle is draw nt he speed and bandwidt h of t oday's graphics accelerat ors m ake t his an accept able approach for all but t he m ost dem anding applicat ions. Wit h t he OpenGL Shading Language, you can even pr ovide t he sam e rect angle coordinat es every t im e you draw t he im age and let t he vert ex shader do t he scaling, t ranslat ion, or rot at ion of t he rect angle. You can perform im age w arping by t ext uring a polygon m esh inst ead of a single rect angle. Hardware support for t ext ure filt ering can produce high- qualit y result s for any of t hese operat ions.

19.2. Mathematical Mappings A com m on im aging operat ion support ed by OpenGL fixed funct ionalit y is scale- and- bias. I n t his operat ion, each incom ing color com ponent is m ult iplied by a scale fact or, and a bias value is added. You can use t he result t o m ap color values from one linear range t o anot her. This is st raight forward in t he OpenGL Shading Language wit h t he use of t he st andard m at h operat ors. You can do m ore com plex m at hem at ical m appings on pixel values wit h built - in funct ions such as pow, exp2, and log2. The built - in dot pr oduct funct ion ( dot) can produce a single int ensit y value from a color value. The following code com put es a CI E lum inance value from linear RGB values defined according t o I TU- R Recom m endat ion BT.709 ( t he HDTV color st andard) : float luminance = dot(vec3(0.2125, 0.7154, 0.0721), rgbColor);

This lum inance m apping funct ion is t he st andard used in m anufact uring cont em porary m onit ors, and it defines a linear RGB color space. The coefficient s 0.299, 0.587, and 0.114 are oft en used t o convert an RGB value t o a lum inance value. How ever, t hese values w ere est ablished wit h t he incept ion of t he NTSC st andard in 1953 t o com put e lum inance for t he m onit ors of t hat t im e, and t hey ar e used t o conver t nonlinear RGB values t o lum inance values. They do not accurat ely calculat e lum inance for t oday's CRT m onit ors, but t hey are st ill appropriat e for com put ing nonlinear video lum a from nonlinear RGB input values as follows: float luma = dot(vec3(0.299, 0.587, 0.114), rgbColor);

19.3. Lookup Table Operations OpenGL defines a num ber of lookup t ables as part of it s fixed funct ionalit y. Several are defined as part of t he im aging subset . Lookup t ables are sim ply a way of m apping an input value t o one or m ore out put values. This operat ion provides a level of indirect ion t hat is oft en useful for processing color inform at ion. The fact t hat OpenGL has program m able processors m eans t hat you can com put e t he input values as part of a shader and use t he out put value as par t of furt her com put at ion wit hin t he shader. This cr eat es a lot of new possibilit ies for lookup t ables. A flexible and efficient way t o perform lookup t able operat ions w it h an OpenGL shader is t o use a 1D t ext ure m ap. The lookup t able can be an arbit rary size ( t hus overcom ing a com m on gripe about OpenGL lookup t ables oft en being lim it ed by im plem ent at ions t o 256 ent ries) . You can use t he lookup t able t o m ap a single input value t o a single out put value or t o a t wo- , t hree- , or four- com ponent value. I f you want t he values ret urned t o be discret e values, set t he 1D t ext ure's filt ering m odes t o GL_NEAREST. I f you want int erpolat ion t o occur bet ween neighbor ing lookup t able values, use GL_LI NEAR. You can use an int ensit y value in t he range [ 0,1] as t he t ext ure coordinat e for a 1D t ext ure access. The built - in t ext ure funct ions always ret urn an RGBA value. I f a t ext ure wit h a single channel has been bound t o t he t ext ure unit specified by t he sam pler, t he value of t hat t ext ure is cont ained in each of t he red, green, and blue channels, so you can pick any of t hem : float color = texture1D(lut, intensity).r; // GL_PIXEL_MAP_I_TO_I

You can perform an int ensit y- t o- RGBA lookup w it h a single t ext ure access: vec4 color = texture1D(lut, intensity);

// GL_PIXEL_MAP_I_TO_R,G,B,A

An RGBA- t o- RGBA lookup operat ion r equires four t ext ure accesses: vec4 colorOut; colorOut.r = texture1D(lut, colorOut.g = texture1D(lut, colorOut.b = texture1D(lut, colorOut.a = texture1D(lut,

colorIn.r).r; colorIn.g).g; colorIn.b).b; colorIn.a).a;

// // // //

GL_PIXEL_MAP_R_TO_R GL_PIXEL_MAP_G_TO_G GL_PIXEL_MAP_B_TO_B GL_PIXEL_MAP_A_TO_A

However, if you don't need alpha and you are willing t o use a 3D t ext ure t o st ore t he color t able, you can do an RGB- t o- RGB lookup wit h a single t ext ure access: colorOut.rgb = texture3D(lut, colorIn.rgb).rgb;

I n t his case, t he variable lut m ust be defined as a sa m ple r 3 d, whereas in t he previous cases it needed t o be defined as a sa m ple r 1 d.

19.4. Color Space Conversions A variet y of color space conversions can be im plem ent ed in OpenGL shaders. I n t his sect ion, we look at convert ing CI E colors t o RGB, and vice versa. Conversions bet ween ot her color spaces can be done sim ilarly. The CI E syst em was defined in 1931 by t he Com m it t ee I nt ernat ionale de L'Éclairage ( CI E) . I t defines a device- independent color space based on t he charact erist ics of hum an color percept ion. The CI E set up a hypot het ical set of prim aries, XYZ, t hat correspond t o t he way t he eye's ret ina behaves. Aft er experim ent s based on color m at ching by hum an obser vers, t he CI E defined t he pr im aries so t hat all visible light m aps int o a posit ive m ixt ure of X, Y, and Z and so t hat Y correlat es approxim at ely t o t he apparent light ness of a color. The CI E syst em precisely defines any color. Wit h t his as a st andard reference, colors can be t ransform ed from t he nat ive ( device- dependent ) color space of one device t o t he nat ive color space of anot her device. A m at rix form ulat ion is convenient for perform ing such conversions. The HDTV st andard as defined in I TU- R Recom m endat ion BT.709 ( 1990) has t he following CI E XYZ pr im aries and uses t he D 65 ( nat ural sunlight ) whit e point : R

G

B

w hit e

x

0.640

0.300

0.150

0.3127

y

0.330

0.600

0.060

0.3290

z

0.030

0.100

0.790

0.3582

List ing 19.1 shows t he OpenGL shader code t hat t r ansform s CI E color values t o HDTV st andard RGB values by using t he D 65 whit e point , and List ing 19.2 shows t he reverse t ransform at ion. The m at rices look like t hey are t ransposed com pared t o t he colorim et ry lit erat ure because in t he OpenGL Shading Language, m at r ix values ar e provided in colum n m aj or order.

List in g 1 9 .1 . Ope n GL sh a de r code t o t r a n sfor m CI E va lue s t o RGB const mat3 CIEtoRGBmat = mat3(3.240479, -0.969256, 0.055648, -1.537150, 1.875992, -0.204043, -0.498535, 0.041556, 1.057311); vec3 rgbColor = cieColor * CIEtoRGBmat;

List in g 1 9 .2 . Ope n GL sh a de r code t o t r a n sfor m RGB va lu e s t o CI E const mat3 RGBtoCIEmat = mat3(0.412453, 0.212671, 0.019334, 0.357580, 0.715160, 0.119193, 0.180423, 0.072169, 0.950227); vec3 cieColor = rgbColor * RGBtoCIEmat;

19.5. Image Interpolation and Extrapolation I n 1994, Paul Haeberli and Douglas Voorhies published an int erest ing paper t hat described im aging operat ions t hat could be perform ed wit h int erpolat ion and ext rapolat ion operat ions. These operat ions could act ually be program m ed on t he high- end graphics syst em s of t hat t im e; t oday, t hanks t o t he OpenGL Shading Language, t hey can be done quit e easily on consum er graphics hardware. The t echnique is quit e sim ple. The idea is t o det erm ine a t arget im age t hat can be used t oget her wit h t he source im age t o perform int erpolat ion and ext rapolat ion. The equat ion is set up as a sim ple linear int erpolat ion t hat blends t w o im ages: I m age out = ( 1α) .I m age t arget + α .I m age source The t ar get im age is act ually an im age t hat you want t o int erpolat e or ext rapolat e away from . Values of alpha bet ween 0 and 1 int erpolat e bet ween t he t wo im ages, and values great er t han 1 ext rapolat e bet ween t he t wo im ages. For inst ance, t o adj ust bright ness, t he t arget im age is one in which every pixel is black. When alpha is 1, t he result is t he source im age. When alpha is 0, t he result is t hat all pixels are black. When alpha is bet w een 0 and 1, t he result is a linear blend of t he source im age and t he black im age, effect ively darkening t he im age. When alpha is great er t han 1, t he im age is bright ened. Such operat ions can be applied t o im ages ( pixel rect angles in OpenGL j argon) wit h a fragm ent shader as t hey are being sent t o t he display. I n cases in which a t arget im age is really needed ( in m any cases, it is not needed, as we shall see) , it can be st ored in a t ext ure and accessed by t he fragm ent shader. I f t he source and t arget im ages are downloaded int o m em ory on t he graphics card ( i.e., st ored as t ext ures) , t hese operat ions can be blazingly fast , lim it ed only by t he m em ory speed and t he fill rat e of t he graphics hardware. This should be m uch fast er t han perform ing t he sam e operat ions on t he CPU and downloading t he im age across t he I / O bus every t im e it 's m odified.

19.5.1. Brightness Bright ness is t he easiest exam ple. The t arget im age is com posed ent irely of black pixels ( e.g., pixel values ( 0,0,0) ) . Ther efore, t he first half of t he int erpolat ion equat ion goes t o zero, and t he equat ion reduces t o a sim ple scaling of t he source pixel values. This is im plem ent ed wit h t he fragm ent shader in List ing 19.3, and t he result s for several values of alpha are shown in Color Plat e 30.

List in g 1 9 .3 . Fr a gm e n t sh a de r for a dj u st ing br igh t n e ss u n ifor m floa t Alph a ; void main() { gl_FragColor = gl_Color * Alpha; }

19.5.2. Contrast A som ewhat m ore int erest ing exam ple is cont rast ( see List ing 19.4) . Here t he t arget im age is chosen t o be a const ant gray im age wit h each pixel cont aining a value equal t o t he average

lum inance of t he im age. This value and t he alpha value are assum ed t o be com put ed by t he applicat ion and sent t o t he shader as unifor m variables. The result s of t he cont rast shader are shown in Color Plat e 31.

List in g 1 9 .4 . Fr a gm e n t sh a de r for a dj u st in g con t r a st uniform vec3 AvgLuminance; uniform float Alpha; void main() { vec3 color gl_FragColor }

= mix(AvgLuminance, gl_Color, Alpha); = vec4(color, 1.0);

19.5.3. Saturation The t ar get im age for a sat urat ion adj ust m ent is an im age cont aining only lum inance inform at ion ( i.e., a gr ayscale version of t he source im age) . This im age can be com put ed pixel- by - pixel by ext ract ion of t he lum inance value from each RGB value. The proper com put at ion depends on knowing t he color space in which t he RGB values are specified. For RGB values specified according t o t he HDTV color st andard, you could use t he coefficient s shown in t he shader in List ing 19.5. Result s of t his shader are shown in Color Plat e 32. As you can see, ext r apolat ion can pr ovide useful result s for values t hat are well above 1.0.

List in g 1 9 .5 . Fr a gm e n t sh a de r for a dj u st ing sa t ur a t ion const vec3 lumCoeff = vec3(0.2125, 0.7154, 0.0721); uniform float Alpha; void main() { vec3 intensity = vec3(dot(gl_Color.rgb, lumCoeff)); vec3 color = mix(intensity, gl_Color.rgb, Alpha); gl_FragColor = vec4(color, 1.0); }

19.5.4. Sharpness Rem arkably, t his t echnique also lends it self t o adj ust ing any im age conv olut ion oper at ion ( see List ing 19.6) . For inst ance, you can const ruct a t arget im age by blurring t he original im age. I nt erpolat ion fr om t he source im age t o t he blurred im age reduces high frequencies, and ext rapolat ion ( alpha great er t han 1) increases t hem . The result is im age sharpening t hrough UNSHARP MASKI NG. The result s of t he sharpness fragm ent shader are show n in Color Plat e 33.

List in g 1 9 .6 . Fr a gm e n t sh a de r for a dj u st in g sh a r pn e ss

uniform sampler2D Blurry; uniform float Alpha; void main()

{ vec3 blurred vec3 color gl_FragColor

= vec3(texture2D(Blurry, gl_TexCoord[0].st)); = gl_Color.rgb * Alpha + blurred * (1.0 - Alpha); = vec4(color, 1.0);

}

These exam ples showed t he sim ple case in which t he ent ire im age is m odified wit h a single alpha value. More com plex processing is possible. The alpha value could be a funct ion of ot her variables. A cont rol t ext ure could define a com plex shape t hat indicat es t he port ion of t he im age t o be m odified. A brush pat t ern could apply t he operat ion select ively t o sm all regions of t he im age. The operat ion could be applied select ively t o pixels wit h a cert ain lum inance range ( e.g., shadows, highlight s, or m idt ones) . Fragm ent shaders can also int erpolat e bet ween m ore t han t wo im ages, and t he int erpolat ion need not be linear. I nt erpolat ion can be done along several axes sim ult aneously wit h a single t arget im age. A blurry, desat urat ed version of t he source im age can be used wit h t he source im age t o produce a sharpened, sat urat ed version in a single operat ion.

19.6. Blend Modes Wit h t he expressiveness of a high- level language, it is easy t o com bine, or blend, t w o im ages in a variet y of w ays. Bot h im ages can be st ored in t ext ure m em ory, or one can be in t ext ur e m em ory and one can be downloaded by t he applicat ion wit h glDrawPixels. For exam ple, here's a fragm ent shader t hat adds t oget her t wo im ages: uniform sampler2D BaseImage; uniform sampler2D BlendImage; uniform float Opacity; void main (void) { vec4 base = texture2D(BaseImage, gl_TexCoord[0].xy); vec4 blend = texture2D(BlendImage, gl_TexCoord[0].xy); vec4 result = blend + base; result = clamp(result, 0.0, 1.0); gl_FragColor = mix(base, result, Opacity); }

The following sect ions cont ain snippet s of OpenGL shader code t hat perform pixel- by - pixel blending for som e of t he com m on blend m odes. I n each case, z

base is a ve c4 cont aining t he RGBA color value from t he base ( original) im age.

z

blend is a ve c4 cont aining t he RGBA color value from t he im age t hat is being blended int o

t he base im age. z

result is a ve c4 cont aining t he RGBA color t hat result s from t he blending operat ion.

z

I f it 's needed in t he com put at ion, white is a ve c4 cont aining ( 1.0, 1.0, 1.0, 1.0) .

z

z

I f it 's needed in t he com put at ion, lumCoeff is a ve c4 cont aining ( 0.2125, 0.7154, 0.0721, 1.0) . As a final st ep, base and result are com bined by use of a float ing- point value called Opacity, which det erm ines t he cont ribut ion of each.

There is no guarant ee t hat t he result s of t he code snippet s provided here will produce result s ident ical t o t hose of your favorit e im age edit ing program , but t he effect s should be sim ilar. The OpenGL shader code for t he various blend m odes is based on inform at ion published by Jens Gruschel in his art icle Blend Modes, available at ht t p: / / www.pegt op.net / delphi/ blendm odes. Unless ot herwise not ed, t he blend operat ions are not com m ut at ive ( you will get different result s if you swap t he base and blend im ages) . Result s of t he blend m ode shaders are shown in Color Plat e 34.

19.6.1. Normal NORMAL is oft en used as t he default blending m ode. The blend im age is placed over t he base im age. The result ing im age equals t he blend im age when t he opacit y is 1.0 ( i.e., t he base im age is com plet ely covered) . For opacit ies ot her t han 1.0, t he result is a linear blend of t he

t w o im ages based on Opacity. result = blend;

19.6.2. Average The AVERAGE blend m ode adds t he t wo im ages and divides by t wo. The result is t he sam e as NORMAL when t he opacit y is set t o 0.5. This operat ion is com m ut at ive. result = (base + blend) * 0.5;

19.6.3. Dissolve I n t he DI SSOLVE m ode, eit her blend or base is chosen random ly at every pixel. The value of Opacity is used as a probabilit y fact or for choosing t he blend value. Thus, as t he opacit y get s closer t o 1.0, t he blend value is m ore likely t o be chosen t han t he base value. I f we draw t he im age as a t ext ur e on a r ect angular polygon, w e can use t he t ext ure coordinat e values as t he argum ent t o noise1D t o pr ovide a value wit h which we can select in a pseudorandom , but repeat able, way. We can apply a scale fact or t o t he t ext ure coordinat es t o obt ain noise of a higher frequency and give t he appearance of random ness. The value r et urned by t he noise funct ion is in t he range [ - 1,1] so we add 1 and m ult iply by 0.5 t o get it in t he range [ 0,1] . float noise = (noise1(vec2(gl_TexCoord[0] * noiseScale)) + 1.0) * 0.5; result = (noise < Opacity) ? blend : base;

19.6.4. Behind BEHI ND chooses t he blend value only where t he base im age is com plet ely t ransparent ( i.e., base.a = 0.0) . You can t hink of t he base im age as a piece of clear acet at e, and t he effect of t his m ode is as if you were paint ing t he blend im age on t he back of t he acet at eonly t he areas paint ed behind t ransparent pixels are visible. result = (base.a == 0.0) ? blend : base;

19.6.5. Clear CLEAR always uses t he blend value, and t he alpha value of result is set t o 0 ( t ransparent ) . This blend m ode is m ore apt t o be used wit h dr awing t ools t han on com plet e im ages. result.rgb = blend.rgb; result.a = 0.0;

19.6.6. Darken I n DARKEN m ode, t he t wo values are com pared, and t he m inim um value is chosen for each com ponent . This operat ion m akes im ages darker because t he blend im age can do not hing except m ake t he base im age darker. A blend im age t hat is com plet ely whit e ( RGB = 1.0, 1.0, 1.0) does not alt er t he base im age. Regions of black ( 0, 0, 0) in eit her im age cause t he result t o be black. I t is com m ut at ivet he result is t he sam e if t he blend im age and t he base im age are sw apped.

result = min(blend, base);

19.6.7. Lighten LI GHTEN can be considered t he opposit e of DARKEN. I nst ead of t aking t he m inim um of each com ponent , we t ake t he m axim um . The blend im age can t herefore never do anyt hing but m ake t he result light er. A blend im age t hat is com plet ely black ( RGB = 0, 0, 0) does not alt er t he base im age. Regions of whit e ( 1.0, 1.0, 1.0) in eit her im age cause t he result t o be whit e. The operat ion is com m ut at ive because swapping t he t wo im ages does not change t he result . result = max(blend, base);

19.6.8. Multiply I n MULTI PLY m ode, t he t wo values are m ult iplied t oget her. This produces a darker result in all areas in which neit her im age is com plet ely whit e. Whit e is effect ively an ident it y ( or t ransparency) operat or because any color m ult iplied by whit e will be t he original color. Regions of black ( 0, 0, 0) in eit her im age cause t he result t o be black. The result is sim ilar t o t he effect of st acking t w o color t ransparencies on an overhead proj ect or. This operat ion is com m ut at ive. result = blend * base;

19.6.9. Screen SCREEN can be t hought of as t he opposit e of MULTI PLY because it m ult iplies t he inverse of t he t w o input values. The result of t his m ult iplicat ion is t hen invert ed t o produce t he final result . Black is effect ively an ident it y ( or t r ansparency) operat or because any color m ult iplied by t he inverse of black ( i.e., whit e) will be t he original color. This blend m ode is com m ut at ive. result = white - ((white - blend) * (white - base));

19.6.10. Color Burn COLOR BURN darkens t he base color as indicat ed by t he blend color by decreasing lum inance. There is no effect if t he blend value is whit e. This com put at ion can result in som e values less t han 0, so t runcat ion m ay occur when t he result ing color is clam ped. result = white - (white - base) / blend;

19.6.11. Color Dodge COLOR DODGE bright ens t he base color as indicat ed by t he blend color by increasing lum inance. There is no effect if t he blend value is black. This com put at ion can result in som e values great er t han 1, so t runcat ion m ay occur when t he result is clam ped. result = base / (white - blend);

19.6.12. Overlay

OVERLAY first com put es t he lum inance of t he base value. I f t he lum inance value is less t han 0.5, t he blend and base values are m ult iplied t oget her. I f t he lum inance value is gr eat er t han 0.5, a screen operat ion is per form ed. The effect is t hat t he base value is m ixed wit h t he blend value, rat her t han being replaced. This allows pat t erns and colors t o overlay t he base im age, but shadows and highlight s in t he base im age are preserved. A discont inuit y occurs where lum inance = 0.5. To provide a sm oot h t ransit ion, we act ually do a linear blend of t he t w o equat ions for lum inance in t he range [ 0.45,0.55] . float luminance = dot(base, lumCoeff); if (luminance < 0.45) result = 2.0 * blend * base; else if (luminance > 0.55) result = white - 2.0 * (white - blend) * (white - base); else { vec4 result1 = 2.0 * blend * base; vec4 result2 = white - 2.0 * (white - blend) * (white - base); result = mix(result1, result2, (luminance - 0.45) * 10.0); }

19.6.13. Soft Light SOFT LI GHT produces an effect sim ilar t o a soft ( diffuse) light shining t hrough t he blend im age and ont o t he base im age. The result ing im age is essent ially a m ut ed com binat ion of t he t wo im ages. result = 2.0 * base * blend + base * base - 2.0 * base * base * blend;

19.6.14. Hard Light HARD LI GHT m ode is ident ical t o OVERLAY m ode, except t hat t he lum inance value is com put ed wit h t he blend value rat her t han t he base value. The effect is sim ilar t o shining a harsh light t hrough t he blend im age and ont o t he base im age. Pixels in t he blend im age wit h a lum inance of 0.5 have no effect on t he base im age. This m ode is oft en used t o produce em bossing effect s. The mix funct ion provides a linear blend bet ween t he t wo funct ions for lum inance in t he r ange [ 0.45,0.55] . float luminance = dot(blend, lumCoeff); if (luminance < 0.45) result = 2.0 * blend * base; else if (luminance > 0.55) result = white - 2.0 * (white - blend) * (white - base); else { vec4 result1 = 2.0 * blend * base; vec4 result2 = white - 2.0 * (white - blend) * (white - base); result = mix(result1, result2, (luminance - 0.45) * 10.0); }

19.6.15. Add I n t he ADD m ode, t he result is t he sum of t he blend im age and t he base im age. Tr uncat ion m ay occur because result ing values can exceed 1.0. The blend and base im ages can be swapped, and t he result will be t he sam e. result = blend + base;

19.6.16. Subtract SUBTRACT subt ract s t he blend im age from t he base im age. Truncat ion m ay occur because result ing values m ay be less t han 0. result = base - blend;

19.6.17. Difference I n t he DI FFERENCE m ode, t he result is t he absolut e value of t he difference bet ween t he blend value and t he base value. A result of black m eans t he t wo init ial values were equal. A result of whit e m eans t hey were opposit e. This m ode can be useful for com paring im ages because ident ical im ages produce a com plet ely black result . An all- whit e blend im age can be used t o invert t he base im age. Blending wit h black produces no change. Because of t he absolut e value operat ion, t his blend m ode is com m ut at ive. result = abs(blend - base);

19.6.18. Inverse Difference The I NVERSE DI FFERENCE blend m ode perform s t he " opposit e" of DI FFERENCE. Blend values of whit e and black produce t he sam e result s as for DI FFERENCE ( whit e invert s and black has no effect ) , but colors in bet ween whit e and black becom e light er inst ead of darker. This operat ion is com m ut at ive. result = white - abs(white - base - blend);

19.6.19. Exclusion EXCLUSI ON is sim ilar t o DI FFERENCE, but it produces an effect t hat is low er in cont rast ( soft er) . The effect for t his m ode is in bet ween t he effect s of t he DI FFERENCE and I NVERSE DI FFERENCE m odes. Blending wit h whit e invert s t he base im age, blending wit h black has no effect , and colors in bet w een becom e gray. This is also a com m ut at ive blend m ode. result = base + blend - (2.0 * base * blend);

19.6.20. Opacity I n OPACI TY m ode, an opacit y value in t he range [ 0,1] can also specify t he relat ive cont ribut ion of t he base im age and t he com put ed result . The result value from any of t he preceding form ulas can be furt her m odified t o com put e t he effect of t he opacity value as follows: finalColor = mix(base, result, Opacity);

19.7. Convolution CONVOLUTI ON is a com m on im age processing oper at ion t hat filt ers an im age by com put ing t he sum of product s bet w een t he source im age and a sm aller im age called t he CONVOLUTI ON KERNEL or t he CONVOLUTI ON FI LTER. Depending on t he choice of values in t he convolut ion kernel, a convolut ion operat ion can perform blurring, sharpening, noise reduct ion, edge det ect ion, and ot her useful im aging operat ions. Mat hem at ically, t he discret e 2D convolut ion operat ion is defined as

I n t his equat ion, t he funct ion F repr esent s t he base im age, and G repr esent s t he convolut ion ker nel. The double sum m at ion is based on t he widt h and height of t he convolut ion kernel. We com put e t he value for a part icular pixel in t he out put im age by aligning t he cent er of t he convolut ion kernel wit h t he pixel at t he sam e posit ion in t he base im age, m ult iplying t he values of t he base im age pixels covered by t he convolut ion kernel by t he values in t he corresponding locat ions in t he convolut ion kernel, and t hen sum m ing t he result s. The im aging subset of OpenGL 2.0 cont ains support for a fixed funct ionalit y convolut ion operat ion, but im plem ent at ions of t his funct ionalit y always have lim it at ions in t he size of t he kernel support ed ( t ypical m axim um size is 3 x 3) and in t he precision of t he int erm ediat e calculat ions. The flexibilit y of t he OpenGL Shading Language enables convolut ion operat ions wit h arbit rary - sized kernels and full float ing- point precision. Furt herm ore, t he convolut ion operat ion can be writ t en in an OpenGL shader such t hat t he m inim um num ber of m ult iplicat ion operat ions is act ually perform ed ( i.e., kernel values equal t o 0 do not need t o be st ored or used in t he convolut ion com put at ion) . But t here are a couple of hurdles t o overcom e. First , t his operat ion seem s nat urally suit ed t o im plem ent at ion as a fragm ent shader, but t he fragm ent shader is not allowed t o access t he values of any neighboring fragm ent s. How can we perform a neighborhood operat ion such as convolut ion wit hout access t o t he " neighborhood" ? The answer t o t his dilem m a is t hat we st ore t he base im age in t ext ure m em ory and access it as a t ext ure. We can draw a screen- aligned rect angle t hat 's t he sam e size on t he screen as t he base im age and enable t ext uring t o render t he im age perfect ly. We can int r oduce a fragm ent shader int o t his process, and inst ead of sam pling t he im age j ust once during t he t ext uring process, we can access each of t he values under t he convolut ion kernel and com put e t he convolut ion result at every pixel. A second hurdle is t hat , alt hough t he OpenGL Shading Language support s loops, even nest ed loops, it does not current ly support t wo- dim ensional arrays. We can easily overcom e t his by " unrolling" t he convolut ion kernel and st oring it as a one- dim ensional array. Each locat ion in t his array st ores an x - and y - offset from t he cent er of t he convolut ion kernel and t he value of t he convolut ion kernel at t hat posit ion. I n t he fragm ent shader, we pr ocess t his array in a single loop, adding t he specified offset s t o t he current t ext ure locat ion, accessing t he base im age, and m ult iplying t he ret rieved pixel value by t he convolut ion kernel value. St oring t he convolut ion ker nel t his w ay m eans t hat w e can st ore t he values in row m aj or order, colum n m aj or order, backwards, or all m ixed up. We don't even need t o include convolut ion kernel values t hat are zero, because t hey do not cont ribut e t o t he convolved im age.

The int erest ing work for perform ing convolut ion is done wit h fragm ent shaders. The vert ex shader is required t o perform an ident it y m apping of t he input geom et ry ( a screen- aligned rect angle t hat is t he size of t he base im age) , and it is required t o pass on t ext ure coordinat es. The t ext ure coordinat e ( 0,0) should be assigned t o t he lower- left corner of t he rect angle, and t he t ext ure coordinat e ( 1,1) should be assigned t o t he upper- right corner of t he rect angle. One addit ional issue wit h convolut ion operat ions is deciding what t o do w hen t he convolut ion ker nel ext ends beyond t he edges of t he base im age. A convenient side effect of using OpenGL t ext ure operat ions t o perform t he convolut ion is t hat t he t ext ure- wrapping m odes defined by OpenGL m ap nicely t o t he com m on m et hods of t reat ing convolut ion borders. Thus, z

z

z

To achieve t he sam e effect as t he GL_CONSTANT_BORDER, set t he GL_TEXTURE_WRAP_S and GL_TEXTURE_WRAP_T param et ers of t he t ext ure cont aining t he base im age t o GL_CLAMP_TO_BORDER. This m et hod uses t he border color w hen t he convolut ion kernel ext ends past t he im age boundary. I f t he desired behavior is t he sam e as GL_REPLI CATE_BORDER, set t he GL_TEXTURE_WRAP_S and GL_TEXTURE_WRAP_T param et ers of t he t ext ure cont aining t he base im age t o GL_CLAMP_TO_EDGE. This m et hod uses t he pixel value at t he edge of t he im age w hen t he convolut ion kernel ext ends past t he im age boundary. I f you want t o m im ic t he GL_REDUCE convolution border m ode, draw a rect angle t hat is sm aller t han t he im age t o be convolved. For a 3 x 3 convolut ion kernel, t he rect angle should be sm aller by t wo pixels in width and t wo pixels in height. I n t his case, t he t ext ure coordinat e of t he lower- left corner is ( 1/ width, 1/ height) and t he t ext ure coordinat e of t he upper- right corner is ( 1 1/ width, 1 1/ height) .

The t ext ure filt ering m odes should be set t o GL_NEAREST t o avoid unint ended int erpolat ion.

19.7.1. Smoothing I m age sm oot hing operat ions can at t enuat e high frequencies in an im age. A com m on im age sm oot hing operat ion is know n as NEI GHBORHOOD AVERAGI NG. This m et hod uses a convolut ion kernel t hat cont ains a weight ing of 1.0 in each locat ion. The final sum is divided by a value equal t o t he num ber of locat ions in t he convolut ion kernel. For inst ance, a 3 x 3 neighborhood averaging convolut ion filt er would look like t his: 1

1

1

1

1

1

1

1

1

The result ing sum would be divided by 9 ( or m ult iplied by 1/ 9) . Neighborhood averaging, as t he nam e im plies, has t he effect of averaging all t he pixels in a region wit h equal weight ing. I t effect ively sm ears t he value of each pixel t o it s neighbors, result ing in a blur ry version of t he original im age. Because all t he elem ent s of t he convolut ion kernel are equal t o 1, we can w rit e a sim plified fragm ent shader t o im plem ent neighborhood averaging ( see List ing 19.7) . This shader can be used for neighborhood averaging for any kernel size where width * height is less t han or equal t o 25 ( i.e., up t o 5 x 5) . The result s of t his operat ion ar e shown in Figure 19.1 ( B) .

Figu r e 1 9 .1 . Re su lt s of va r iou s convolu t ion ope r a t ion s

List in g 1 9 .7 . Fr a gm e n t sh a de r for t h e n e igh bor h ood a ve r a gin g con volu t ion ope r a t ion // maximum size supported by this shader const int MaxKernelSize = 25; // array of offsets for accessing the base image uniform vec2 Offset[MaxKernelSize]; // size of kernel (width * height) for this execution uniform int KernelSize; // final scaling value uniform vec4 ScaleFactor; // image to be convolved uniform sampler2D BaseImage; void main() { int i; vec4 sum = vec4(0.0); for (i = 0; i < KernelSize; i++) sum += texture2D(BaseImage, gl_TexCoord[0].st + Offset[i]); gl_FragColor = sum * ScaleFactor; }

I m age sm oot hing by m eans of convolut ion is oft en used t o reduce noise. This works well in regions of solid color or int ensit y, but it has t he side effect of blurring high frequencies ( edges) . A convolut ion filt er t hat applies higher w eight s t o values nearer t he cent er can do a bet t er j ob of elim inat ing noise while preserving edge det ail. Such a filt er is t he Gaussian filt er, which can be encoded in a convolut ion kernel as follows: 1/ 273

4/ 273

7/ 273

4/ 273

1/ 273

4/ 273

16/ 273

26/ 273

16/ 273

4/ 273

7/ 273

26/ 273

41/ 273

26/ 273

7/ 273

4/ 273

16/ 273

26/ 273

16/ 273

4/ 273

1/ 273

4/ 273

7/ 273

4/ 273

1/ 273

List ing 19.8 cont ains t he code for a m or e gener al convolut ion shader. This shader can handle convolut ion kernels cont aining up t o 25 ent r ies. I n t his shader, each convolut ion kernel ent ry is expect ed t o have been m ult iplied by t he final scale fact or, so t here is no need t o scale t he final sum .

List in g 1 9 .8 . Fr a gm e n t sh a de r ge n e r a l con volu t ion com pu t a t ion // maximum size supported by this shader const int MaxKernelSize = 25; // array of offsets for accessing the base image uniform vec2 Offset[MaxKernelSize]; // size of kernel (width * height) for this execution uniform int KernelSize; // value for each location in the convolution kernel uniform vec4 KernelValue[MaxKernelSize]; // image to be convolved uniform sampler2D BaseImage; void main() { int i; vec4 sum = vec4(0.0); for (i = 0; i < KernelSize; i++) { vec4 tmp = texture2D(BaseImage, gl_TexCoord[0].st + Offset[i]); sum += tmp * KernelValue[i]; } gl_FragColor = sum; }

The original im age in Figure 19.1 ( A) has had uniform noise added t o it t o creat e t he im age in Figure 19.1 ( C) . The Gaussian sm oot hing filt er is t hen applied t o t his im age t o rem ove noise, and t he result is shown in Figure 19.1 ( D) . Not ice in part icular t hat t he noise has been significant ly reduced in areas of nearly const ant int ensit y. As t he size of t he convolut ion kernel goes up, t he num ber of t ext ure reads t hat is required

increases as t he square of t he kernel size. For larger kernels, t his can becom e t he lim it ing fact or for perform ance. Som e kernels, including t he Gaussian kernel j ust described, are said t o be separable because t he convolut ion operat ion wit h a width x height kernel can be perform ed as t w o passes, wit h one- dim ensional convolut ions of size width x 1 and 1 x height. Wit h t his approach, t here is an ext ra writ e for each pixel ( t he result of t he first pass) , but t he num ber of t ext ure reads is reduced fr om width x height t o width + height.

19.7.2. Edge Detection Anot her com m on use for t he convolut ion operat ion is edge det ect ion. This operat ion is useful for det ect ing m eaningful discont inuit ies in int ensit y level. The result ing im age can aid in im age com prehension or can enhance t he im age in ot her ways. One m et hod for det ect ing edges involves t he Laplacian operat or. 0

1

0

1

-4

1

0

1

0

We can plug t he Laplacian convolut ion kernel int o t he fragm ent shader shown in List ing 19.8. This result s in t he im age shown in Figure 19.2.

Figu r e 1 9 .2 . Edge de t e ct ion w it h t h e La pla cia n con volu t ion k e r ne l ( im a ge sca le d for displa y)

19.7.3. Sharpening A com m on m et hod of im age shar pening is t o add t he result s of an edge det ect ion filt er back ont o t he original im age. To cont rol t he degree of sharpening, a scaling fact or scales t he edge im age as it is added. One way t o sharpen an im age is wit h t he negat ive Laplacian operat or. This convolut ion filt er is defined as 0

-1

0

-1

4

-1

0

-1

0

The fragm ent shader t hat im plem ent s im age sharpening in t his fashion is alm ost ident ical t o t he general convolut ion shader shown in t he pr evious sect ion ( see List ing 19.9) . The only difference is t hat t he result of t he convolut ion operat ion is added t o t he original im age. Before it is added, t he convolut ion result is scaled by a scale fact or provided by t he applicat ion t hrough a uniform variable. The result s of unsharp m asking are shown in Figure 19.4 and Figure 19.3.

Figu r e 1 9 .3 . Re su lt s of t h e u n sh a r p m a sk in g sh a de r . Or igin a l im a ge is on t h e le ft , sh a r pe n e d im a ge on t h e r igh t . [View full size image]

Figu r e 1 9 .4 . Re su lt s of t h e u n sh a r p m a sk in g sha de r . ( La pla cia n im a ge in ce n t e r is sca le d for displa y.) Zoom e d vie w s of t h e or igin a l a n d r e su lt ing im a ge s a r e show n in Figu r e 1 9 .3 .

List in g 1 9 .9 . Fr a gm e n t sh a de r for u n sh a r p m a sk in g // maximum size supported by this shader const int MaxKernelSize = 25; // array of offsets for accessing the base image uniform vec2 Offset[MaxKernelSize]; // size of kernel (width * height) for this execution uniform int KernelSize; // value for each location in the convolution kernel uniform vec4 KernelValue[MaxKernelSize]; // scaling factor for edge image uniform vec4 ScaleFactor;

// image to be convolved uniform sampler2D BaseImage; void main() { int i; vec4 sum = vec4(0.0); for (i = 0; i < KernelSize; i++) { vec4 tmp = texture2D(BaseImage, gl_TexCoord[0].st + Offset[i]); sum += tmp * KernelValue[i]; } vec4 baseColor = texture2D(BaseImage, vec2(gl_TexCoord[0])); gl_FragColor = ScaleFactor * sum + baseColor; }

19.8. Summary I n addit ion t o support for rendering 3D geom et ry, OpenGL also cont ains a great deal of support for rendering im ages. The OpenGL Shading Language augm ent s fixed funct ionalit y OpenGL im aging capabilit ies by allowing fully program m able processing of im ages. Wit h t his program m abilit y and t he parallel processing nat ure of t he underlying graphics hardw are, im age processing operat ions can be perform ed orders- of- m agnit ude fast er on t he graphics accelerat or t han on t he CPU. This program m abilit y can be used t o im plem ent t radit ional im age processing operat ions such as im age blurr ing, shar pening, and noise rem oval; high- qualit y color correct ion; bright ness, sat urat ion, and cont rast adj ust m ent ; geom et ric t ransform at ions such as rot at ion and warping; blending; and m any ot her im age processing operat ions. Furt herm ore, applicat ions no longer need t o be const rained t o m anipulat ing m onochrom e or color im ages. Mult ispect ral processing and analysis are also possible. The world of digit al im agery is exploding as a result of t he rapid developm ent and accept ance of consum er product s for digit al phot ography and digit al video. The OpenGL Shading Language will undoubt edly be at t he heart of m any t ools t hat support t his revolut ion in t he fut ure.

19.9. Further Information The OpenGL lit erat ure doesn't always do j ust ice t o t he im aging capabilit ies of OpenGL. I n 1996, I wrot e a paper called Using OpenGL for I m aging t hat at t em pt ed t o describe and highlight clearly t he fixed funct ionalit y im aging capabilit ies of OpenGL, including t he capabilit ies of several pert inent im aging ext ensions. This paper was published as part of t he SPI E Medical I m aging '96 I m age Display Conference in Newport Beach, CA, and is available on t his book's com panion Web sit e at ht t p: / / 3dshaders.com / pubs. Anot her good resource for underst anding how t o use OpenGL for im aging is t he course not es for t he SI GGRAPH '99 course, Advanced Graphics Program m ing Techniques Using OpenGL by Tom McReynolds and David Blyt he. These can be found online at ht t p: / / w ww .opengl.org/ resources/ t ut orials/ sig99/ advanced99/ not es/ not es.ht m l. This m at er ial has also been published in a recent book by Morgan Kaufm ann. Char les Poynt on ( 1997) is one of t he lum inaries ( pun int ended) of t he color t echnology field, and his Frequent ly Asked Quest ions about Color and Frequent ly Asked Quest ions about Gam m a are inform at ive and approachable t reat m ent s of a variet y of t opics relat ing t o color and im aging. I found t hese on t he Web on Charles's hom e page at ht t p: / / w ww .poynt on.com / Poynt on- color .ht m l. The CI E color syst em is defined in Publicat ion CI E 17.4 - 1987, I nt ernat ional Light ing Vocabulary, Vienna, Aust ria, Cent ral Bureau of t he Com m it t ee I nt ernat ionale de L'Éclairage, current ly in it s fourt h edit ion. The HDTV color st andard is defined in I TU- R BT.709- 2 Param et er Values for t he HDTV St andards for Product ion and I nt ernat ional Program m e Exchange, Geneva: I TU, 1990. The paper I m age Processing by I nt erpolat ion and Ext rapolat ion by Paul Haeberli and Douglas Voorhies appeared in I RI S Universe Magazine in 1994. A slight ly short er version of t his paper is available online at ht t p: / / w ww .sgi.com / grafica/ int erp. A classic t ext book on im age pr ocessing is Digit al I m age Processing, Second Edit ion, by Rafael C. Gonzalez and Richard E. Woods, Addison- Wesley, 2002. An am azing lit t le book ( lit erally am azing, and lit erally lit t le) is t he Pocket Handbook of I m age Processing Algorit hm s in C by Harley Myler and Art hur Weeks ( 1993) . 1 . Gonzalez, Rafael C., and Richard E. Woods, Digit al I m age Processing, Second Edit ion, Prent ice Hall, Upper Saddle River, New Jersey, 2002. 2 . Gruschel, Jens, Blend Modes, Pegt op Soft ware Web sit e. ht t p: / / www.pegt op.net / delphi/ blendm odes 3 . Haeberli, Paul, and Douglas Voorhies, I m age Processing by I nt erpolat ion and Ext rapolat ion, I RI S Universe Magazine No. 28, Silicon Graphics, August , 1994. ht t p: / www.sgi.com / grafica/ int erp 4 . Hall, Roy, I llum inat ion and Color in Com put er Generat ed I m agery, Springer- Verlag, New York, 1989. 5 . I nt ernat ional Light ing Vocabulary, Publicat ion CI E No. 17.4, Joint publicat ion I EC ( I nt ernat ional Elect rot echnical Com m ission) and CI E ( Com m it t ee I nt ernat ionale de L'Éclairage) , Geneva, 1987. ht t p: / / www.cie.co.at / fram epublicat ions.ht m l 6 . I TU- R Recom m endat ion BT.709, Basic Param et er Values for t he HDTV St andard for t he St udio and for I nt ernat ional Program m e Exchange, [ form erly CCI R Rec. 709] , Geneva, I TU, 1990.

7 . Lindbloom , Bruce J., Accurat e Color Reproduct ion for Com put er Graphics Applicat ions, Com put er Graphics ( SI GGRAPH '89 Proceedings) , pp. 117126, July 1989. 8 . Lindbloom , Bruce J., personal Web sit e, 2003. ht t p: / / www.brucelindbloom .com / 9 . McReynolds, Tom , David Blyt he, Brad Gr ant ham , and Scot t Nelson, Advanced Graphics Program m ing Techniques Using OpenGL, SI GGRAPH '99 course not es, 1999. ht t p: / / w ww .opengl.org/ resources/ t ut orials/ sig99/ advanced99/ not es/ not es.ht m l 1 0 . McReynolds, Tom , and David Blyt he, Advanced Graphics Program m ing Techniques Using OpenGL, Morgan Kaufm ann, 2005. 1 1 . Myler, Harley R., and Art hur R. Weeks, The Pocket Handbook of I m age Processing Algorit hm s in C, Prent ice Hall, Upper Saddle River, NJ, 1993. 1 2 . Poynt on, Charles A., A Technical I nt roduct ion t o Digit al Video, John Wiley & Sons, New York, 1996. 1 3 . Poynt on, Charles A., Frequent ly Asked Quest ions about Color, 1997. ht t p: / / w ww .poynt on.com / Poynt on- color .ht m l 1 4 . Poynt on, Charles A., Frequent ly Asked Quest ions about Gam m a, 1997. ht t p: / / w ww .poynt on.com / Poynt on- color .ht m l 1 5 . Rost , Randi, Using OpenGL for I m aging, SPI E Medical I m aging '96 I m age Display Conference, February 1996. ht t p: / / 3dshaders.com / pubs 1 6 . Wolber g, George, Digit al I m age Warping, Wiley- I EEE Press, 2002.

Chapter 20. RealWorldz by Hugh Malan I n 2004, as graphics hardware and OpenGL Shading Language com pilers becam e capable of handling significant ly com plex shading t asks, 3Dlabs com m issioned Pandrom eda t o develop a dem o t hat would push t he envelope of what was possible. The result was a dem o called RealWorldz, where ent ire planet s and everyt hing on t hem w ere m odeled m at hem at ically and synt hesized on- t he- fly wit h OpenGL shaders. Even t he shader source code was generat ed program m at ically in t his dem o. Rat her t han look at t he act ual shader code, t his chapt er focuses m ore on t he archit ect ure, t he algorit hm s, and t he concept s t hat went int o t he RealWorldz dem o.

20.1. Features RealWorldz was conceived t o be a real- t im e dem onst rat ion of t he st at e of t he art in OpenGL shader t echnology, capabilit ies, and perform ance. Through t he use of fract al algorit hm s and com plex m at hem at ics, dynam ic and changeable world landscapes are com piled and com put ed at runt im e alm ost ent irely on t he graphics card and displayed at int eract ive rat es. Every fram e t hat is displayed is calculat ed on- t he- fly; not hing is pr erendered. This is not t o say t hat RealWorldz does not use t ext ures. On t he cont rary, t ext ures provide t he basic building blocks for m any of t he feat ures available in RealWorldz: noise, sky color, at m ospheric densit y, planet ary t ext ure, and m uch m ore. But t hese t ext ures are quit e basic by design and are used quit e different ly from t radit ional t ext ures. I t is up t o program m able shading t echnology t o t ransform and am plify t he basic building blocks t o t he point t hat t hey becom e believable planet ary landscapes. Because t hese planet ary landscapes are procedurally generat ed and rendered except for t he t ext ures used as t he basis for t he m at hem at ics, no fixed dat a set or dat abase is used t o creat e t hem . Such dat abases would require t erabyt es of dat a t o produce t he sam e effect . I nst ead, all rendered feat ures are generat ed according t o m at hem at ical m odels wit h adj ust able param et ers and init ial condit ions. Som e of t hese param et ers can be adj ust ed int eract ively t hrough a graphical user int erface. The planet ary and t errain feat ures include z

Moving cloud layers wit h condensing and evaporat ing clouds

z

Ocean levels

z

At m ospheric densit y

z

Accurat e sun halos and cloud light diffusion

z

Part icles in valleys t o produce perspect ive haze

z

Darkening and flat t ening of t he landscape cont rast wit h dist ance

z

Scat t ering of light in high at m osphere at t he day/ night t erm inat or line

z

Caust ic reflect ions in wat er

z

Plant s wit h growt h cycles

z

Navigabilit y anywhere on t he world

20.2. RealWorldz Internals Have you ever w ant ed t o creat e your ow n personal planet ? How would you go about t his t ask? I n t his sect ion, we go inside RealWorldz t o exam ine t he process of creat ing planet s procedurally. We discuss t he t errain- rendering st ruct ure, light ing and shadowing, fract al t errain gener at ion, noise t ext ures, t ile set noise, surface norm als, and height fields t hat allow for overhanging t errain. These concept s form t he basis of t he RealWorldz planet ar y rendering engine.

20.2.1. Terrain-Rendering Structure RealWorldz uses a quadt ree st ruct ure. Each node of t he quadt ree corresponds t o a square pat ch of t errain and cont ains a vert ex buffer obj ect ( VBO) and t ext ure m ap for t hat pat ch. The four children of a node each cover one quart er of t heir parent 's pat ch. Rendering t he planet is st raight forwardt he t ree is walked, wit h a level- of- det ail ( LOD) check m ade at each node. I f a part icular node would look polygonal when rendered, recursion cont inues t o t hat node's children if possible. This LOD t est det erm ines which nodes should be subdivided t o increase t he t errain resolut ion in t hat ar ea and which nodes are unnecessar y and can be culled. When a new node is creat ed, t he graphics accelerat or gener at es t he t ext ure while t he CPU gener at es t he vert ex dat a ( in t he fut ure it is int ended for t he graphics hardw are t o generat e t he vert ex dat a as well) . To generat e t he t ext ure for a new t err ain node, t he gr aphics hardware renders t o t he node's t ext ure m ap using a specially const ruct ed fragm ent shader. This fr agm ent shader com put es t he fr act al m at h needed t o calculat e t he height and color of t he t errain and carry out t he light ing calculat ions, and it t hen out put s t he final shaded color. The CPU and graphics hardware m ust carry out precisely t he sam e calculat ions t o com put e t he height and slope of each t errain point if t here's any difference, t he t errain t ext ure m ap will not follow t he feat ures of t he t errain geom et ry. I m agine a planet wit h snow above a cert ain height . I f t he calculat ions t o generat e t he t ext ure m ap com put e height in a different way from t he calculat ions for t he geom et ry, t he snow line will obviously vary in height when t he t ext ured t errain is rendered.

20.2.2. Shading No light ing is done when rendering t errainall light ing and shadowing is baked int o t he t errain t ext ure m ap. This approach has several advant ages: First , t he fill rat e for rendering t errain is im proved because fewer calculat ions are done for each pixel, and only one t ext ure m ap is read from ( color) inst ead of t wo ( color + norm al) . Second, t his appr oach allows m ore com plex light ing calculat ions since t he light ing calculat ions are per form ed only once per t exel, so t hey're not speed crit ical. Thir d, because t he shading is com plet ely separat ed from t he geom et ry, t he light ing does not change when t he resolut ion of t errain geom et ry changes, t hat is, when t err ain nodes are subdivided or collapsed. Therefore, t he t ransit ion is less not iceable. Most significant ly, t his approach capt ures det ails at higher resolut ion t han t he geom et ry. ( This idea is sim ilar in spirit t o norm al m aps.) However, t he downside t o t he approach is t hat it cannot capt ure view- dependent light ing effect s, such as specular highlight s. But since t errain shading is diffuse rat her t han specular, t his rest rict ion is not an issue. So, t he fragm ent shader t hat generat es t he t errain t ext ure m aps calculat es t he color and surface norm al for each t exel, carries out t he light ing calculat ions, and writ es t he result ing color t o t he t ext ure m ap. When rendered, t he color read from t he t ext ure m ap is affect ed only by at m ospheric effect s such as haze and fog.

20.2.3. Fractal Terrains

Fract al t errains are built by t he com binat ion of fract al funct ions, which t hem selves are built out of noise funct ions, such as t hose discussed in Chapt er 15. The Perlin and Vor onoi noise funct ions are part icular ly useful for creat ing fract al t errains. Perlin noise was described in Chapt er 15. Voronoi noise ( som et im es called cellular noise) is com put ed w it h t he dist ance from point s scat t er ed random ly in space. This funct ion produces a ridge along t he line m idway bet w een t w o neighboring point s. A noise funct ion is a funct ion t hat is st at ist ically invar iant under t ranslat ion and rot at ion and t hat has a reasonably nar row frequency range. A m ult ifract al is com put ed by com bining noise funct ions sam pled at several different scales. The m et hod of com bining t he noise funct ion sam ples is what dist inguishes one m ult ifract al from anot her . For inst ance, t he value of a m onofract al wit h n oct aves, wit h a given lacunarit y L ( a m easure of how m uch t he scale is changed for each successive noise funct ion) , offset , and roughness at t he point x is defined as

Ot her m ult ifract al t ypes com m only used t o define t errains are het erofract al and m ount ainfr act al. They differ from m onofract als in t hat t he various noise sam ples are added or m ult iplied t oget her in different ways. The cr eat ion of int erest ing t errain is an art ist ic rat her t han m at hem at ical process. Pandrom eda's Moj oWorld applicat ion is t he m ost advanced t ool for fract al planet generat ion available and produces com pelling landscapes. The landscapes in t he im ages found on t he Moj oWorld gallery ( ht t p: / / www.pandrom eda.com / gallery) are creat ed by t he com binat ion of several m ult ifract als, wit h t he param et ers of each m ult ifract al carefully adj ust ed. The t er rain shape is only a sm all part of t he process: The t errain m ust also be colored, and t he pr opert ies of t he at m osphere, fog, clouds, wat er, st ars, and sun edit ed t o fit t he art ist ic st yle of t he t errain. The downside of having all t his power available is t hat t hese im ages t ake hours t o render. Moj oWorld includes a wide range of t ools for const ruct ing fract al planet s, but only t he ones t hat are t he m ost useful and best suit ed t ools for real- t im e use ar e im plem ent ed in RealWorldz. Such t ools can com bine m ult ifract als by m eans of various m at hem at ical operat ions ( + , - , * , average) and can use one m ult ifract al funct ion t o pert urb t he param et ers fed int o anot her. I n RealWorldz, t he planet art ist const ruct s a funct ion t ree t o define t he t errain. For inst ance, Figure 20.1 illust r at es t he funct ion t ree for t he Ring world. This t ree specifies a Voronoi m ount ainfr act al dist ort ed by t he sine funct ion, added t o anot her dist ort ed Voronoi m ult ifract al, added t o a Perlin het erofr act al dist ort ed by a m onofract al.

Figu r e 2 0 .1 . Fu n ct ion t r e e for t h e Rin g w or ld [View full size image]

The following node t ypes are available for nodes in t he RealWorldz funct ion t ree: 1 . Mat hPossible operat ions are addit ion, average, or m ult iplicat ion of child nodes. 2 . Mult ifract alMonofract al, het erofract al, and m ount ainfract al t ypes are available. This node could have a " dist ort ion" child node t oo: in t his case, t he child node is evaluat ed and t he result is used t o pert urb t he param et er before t he m ult ifract al is evaluat ed. 3 . DLUArbit rary 2D funct ion. This node has t wo child nodes and an im age. The t w o child nodes are evaluat ed, and t he values are int erpret ed as coordinat es t o sam ple t he im age. The value r ead from t he im age lookup is t he result for t he node. ( This is not im plem ent ed in Moj oWorld; it is a generalizat ion of a sim ple way t o generat e long- period noise in a real- t im e fragm ent shader.)

20.2.4. Fractal Terrains in RealWorldz Fract al t errains rely on noise funct ions; it 's not unusual for planet s in Moj oWorld t o m ake use of a hundr ed oct aves of noise. The speed of t he noise funct ion is t herefore crit ical. I t is st raight forward t o im plem ent Perlin noise in t he OpenGL Shading Language, but a naive im plem ent at ion will require at least eight t ext ure reads. Voronoi noise is subst ant ially m ore com plex t han Perlin noiseand t her efore slower. Even if ar t ist s w ere expect ed t o lim it t hem selves t o 50 oct aves of noise for a planet , and use only Perlin noise, over 400 t ext ure lookups would be required for each evaluat ion of t he t errain funct ion, which would be im possibly slow. The solut ion t aken for RealWorldz is t o use 2D inst ead of 3D noise, and inst ead of evaluat ing a 2D noise funct ion, t o use a t ext ure m ap cont aining a periodic im age of Perlin/ Voronoi/ Sine or like noise. These t ext ure m aps are called noise t ext ures. Therefore, inst ead of t he Perlin noise funct ion being evaluat ed wit h param et ers ( x, y) , a noise t ext ure im age is sam pled at posit ion ( fract( x/ k) , fract( y/ k) ) , w her e t he noise t ext ure is defined over t he unit square. k is a fact or t o account for t he scale of t he noise t ext ureit m easures t he size of t he region t o which t he noise t ext ure corr esponds, w het her t he noise t ext ure appears t o be a 5 x 5 area of Perlin noise or a 50 x 50 area. When im plem ent ed as a fragm ent shader, t he fract operat ion is unnecessary if t he t ext ure wrap m ode is set t o GL_REPEAT. I t is easy t o see t he repeat ing pat t ern if a noise t ext ure has only a handful of feat ures, but wit h t en or m ore feat ures along an axis, t he repeat ing pat t ern is far m ore difficult t o det ect . On t op of t his, several noise t ext ures of different periods will be com bined in com plex ways cont ribut ing t o t he shape of t he t errain, obscuring t he pat t ern even furt her.

20.2.5. Noise Texture Creation The st andard noise funct ions are Perlin, Voronoi, and Sine. Sine is periodic, so it is t r ivial t o find a per iodic 2D im age of it . A ridged version of a noise funct ion is creat ed from t he absolut e value of t he funct ion t o int roduce ridges or is creat ed from point s at which t he funct ion folds back on it self ( Perlin called t his TURBULENCE) . I n a nut shell, 2D Perlin noise is defined by int erpolat ion bet w een " hash values" given at int eger coordinat es. The value of Perlin noise at ( 3.6, 9.2) is found in t his way: t he hash funct ion is evaluat ed at ( 3.0, 9.0) , ( 4.0, 9.0) , ( 3.0, 10.0) and ( 4.0, 10.0) , and t he four result ing values are com bined. Creat ing Perlin- esque periodic noise of period k is done wit h t he param et ers t o t he hash funct ion t aken m odulo k. All t he different Perlin noise variant sgradient Perlin noise, valuegradient Perlin noise, ridged gradient Perlincan be handled t his way. The various Vor onoi noise variant s ar e built around a fixed pseudorandom scat t ering of key

point s on t he plane. Basic Voronoi noise is defined as t he dist ance t o t he closest key point . Ot her variant s are t he dist ance t o t he second closest key point , t he t hird closest key point , t he difference bet ween t he closest and second- closest key point , and so on. Making t he dist ribut ion of t he key point s periodic wit h period k also m akes t he result ing Voronoi noise periodic.

20.2.6. Tile Set Noise The noise t ext ure pat t ern can be obscur ed even m ore wit h t iling. I nst ead of a single periodic im age of noise, a set of noise t iles t hat have an ident ical boundary can be generat ed. A set of four such t iles is shown in Figure 20.2. These t iles can t hen be ar ranged random ly on t he plane; t he result m ight look like Figure 20.3. Each t ile occupies t he region on t he plane fr om ( u, v) t o ( u+ 1, v+ 1) for som e int eger u, v.

Figu r e 2 0 .2 . Fou r n oise t ile s w it h ide n t ica l bou n da r ie s

Figu r e 2 0 .3 . Ar r a n gin g m u lt iple n oise t ile s r a n dom ly t o cr e a t e a t ile se t

Sam pling t he noise funct ion is now a t wo- st age process. Our goal is t o find t he appropriat e noise value for t he point ( x, y) . To accom plish t his, we m ust first find t he cont aining t ile, t hen we m ust find t he locat ion t o sam ple wit hin t hat t ile. z

z

The cont aining t ile is locat ed by first t aking t he int eger part of x and y. Because t iles cover t he region ( u, v) t o ( u+ 1, v+ 1) for int eger u, v, t he values u and v are found by rounding x and y down t o int egers. These values are hashed and t he result is t aken m odulo t he num ber of t iles. The result is t he noise t ile t o be accessed. Once t he appropriat e t ile has been found, t he address wit hin t he t ile is p, q w here p = x u, q = y v.

Aft er t hese st eps, we sam ple t he appropriat e t ile and ret ur n t he result . The im plem ent at ion in a fragm ent shader is m ore efficient t han t his process m ight im ply; it is described lat er.

The t ile set can be generat ed wit h an ext ension of t he m et hod used t o creat e periodic t iles. For t he Perlin noise variant s, t he boundary hash point s are fixed, whereas t he int erior hash point s vary from t ile t o t ile wit hin t he set . That is, for a region of period k, t he hash point ( 0, 0) t akes t he sam e value for all t iles in t he set ; t he hash point ( 1, 0) t akes t he sam e value for all t iles in t he set , . . ., t he hash point ( k, 0) t akes t he sam e value for all t iles in t he set . Sim ilarly, t he hash point s ( z, k) , ( 0, z) , and ( k, z) t ake t he sam e value for all t iles in t he set , for any int eger z in [ 0, k] . For t he t iles t o be periodic, t he left and right edges of t he t iles m ust m at ch, as m ust t he t op and bot t om edges. That is, t he hashed values of t he point s ( 0, z) and ( k, z) m ust be ident ical, as m ust t he hashed values for t he point s ( z, 0) and ( z, k) , for 0 z k. Tile set s for t he Voronoi noise variant s can be generat ed sim ilarly. The dist ribut ion of key point s wit hin a border region rem ains fixed for each t ile in t he set , while t he dist ribut ion of key point s in t he rest of t he t ile varies from t ile t o t ile. ( This region in which t he arrangem ent of key point s changes from t ile t o t ile is called t he int erior region.) The border region is found experim ent ally, by finding t he sm allest region such t hat t he key point s in t he int erior region of one t ile have no effect on t he noise funct ion wit hin a neighboring t ile. For inst ance, if t here are 33 key point s wit hin each t ile, t he border region is defined t o be t he region wit hin 15% of t he t ile boundary. I n ot her words: I f t he t ile was unit sized, t hen t he int erior region is t he point s ( x, y) for w hich x, y are in [ 0.15, 0.85) , and t he border region is t he set of point s ( x, y) in t he t ile for which x or y is in [ 0, 0.15) [ 0.85, 1.0) . For 100 point s, t he fixed border size is 10% .

20.2.7. Surface Normals The easiest w ay t o com put e surface norm als of fract al t errains is num erically. Find t he neighbor point s of t he point in quest ion, t hen use t hat inform at ion t o est im at e t he shape of t he surface and t o est ablish a surface norm al. I n pract ice, t he surface is oft en evaluat ed wit h a grid of point s in param et er space, so surface norm als can be found by t aking t he cr oss- product of t he vect ors bet ween t he four neighbors. I n a fragm ent shader, it is not possible t o find t he posit ion of neighboring point st he environm ent is int ent ionally designed t o allow fr agm ent shader s for different fr agm ent s t o execut e in parallel. Also, t he graphics card precision is 32- bit float ing- point , and surface norm als com put ed by subt ract ion of 32- bit float ing- point posit ions have very not iceable banding pat t erns because work done in t he range of m agnit udes needed for large- scale t errain is im precise. The solut ion is t o com put e t he surface norm al analyt ically. I n addit ion t o st oring a funct ion value, noise t ext ures also st ore t he part ial derivat ives. The part ial derivat ives are t hen com put ed alongside t he t errain height , and a surface norm al is reconst ruct ed as needed for light ing calculat ions. For inst ance, a m onofract al com put ed as described in Sect ion 20.2.3 w ould have t he 2D vect or represent ing it s part ial derivat ive calculat ed as follows: [View full size image]

NoiseFunct ionDerivat ive ret urns a 2D vect or, where t he x com ponent is t he part ial derivat ive of t he noise funct ion wit h respect t o x, and t he y com ponent is t he part ial derivat ive of t he noise funct ion wit h respect t o y.

20.2.8. Overhanging Terrain

Som e planet s in RealWorldz have overhanging t errain, for inst ance, t he AlienRockArt w orld as shown in Color Plat e 36E. The m et hod used t o produce overhanging t errain addresses a m ore general problem : t ext ure st ret ching on st eep slopes of height field t errain. I t is nat ural t o t ext ure- m ap a height field wit h a planar m apping; but on st eep slopes t he t ext ure becom es very dist ort ed. Figure 20.4 dem onst rat es t he problem . The cross m arks on t he graph are at evenly spaced param et er values. To put it anot her way, if t his curve were a cross- sect ion of som e t errain t hat had been t ext ure- m apped wit h planar m apping, t hen t he crosses would correspond t o evenly spaced point s on t he t ext ure m ap. I f t he spacing bet ween t he crosses is reasonably const ant , t he t ext ure m ap is st ret ched evenly across t he t errain. I f t he spacing bet w een t he crosses varies, t he t ext ure is st ret ched unevenly.

Figu r e 2 0 .4 . A t e x t u r e a pplie d t o a st e e p h e igh t fie ld w ill be st r e t ch e d u n e ve n ly

I n Figure 20.4, t he dist ance bet w een t he crosses varies subst ant iallyt he crosses on t he st eep par t s are quit e far apart com pared t o how close t hey are on t he flat part s, which m eans t hat t he t ext ur e w ill be quit e dist ort ed. The effect is t hat t he st eep part s of t he t errain will seem t o be quit e blurry, while t he flat part s of t he t errain will have m uch a m uch sharper and cleaner appearance w it h m ore det ail. The goal is t o produce st eep t errain wit hout t ext ure dist ort ion, t hat is, wit h a reasonably even spacing bet ween crosses. RealWorldz achieves t he goal by post processing t he height field t errain, m aking t he t errain st eeper. This st ep is called t he " m ushr oom t ransform at ion." The t w o im ages in Figure 20.5 show t he effect . The left im age show s what could be t he cross- sect ion of a m oderat ely st eep hill. The right - hand im age shows t he vert ices in t he upper half of t he hill pushed out ward and t he vert ices in t he bot t om half pulled inward.

Figu r e 2 0 .5 . Th e " m u sh r oom t r a n sfor m a t ion " a pplie d t o a h e igh t fie ld [View full size image]

More precisely, t he t ransform at ion act s as follows. The t errain is defined as a height field: z = f ( x, y) . The t errain is m ade up of t he set of point s ( x, y, f( x, y) ) . The part ial derivat ives df/ dx and df/ dy are known, as are t he m axim um and m inim um values of z: zm in and zm ax. The point ( x, y, f( x, y) ) is offset by

where k is a const ant specifying t he degree of offset : 0 m eans no change. A larger value produced t he right - hand im age in Figure 20.5. I ncreasing t he value st ill furt her gives a " m ushroom look," so t he const ant k is called t he " m ushroom fact or." This equat ion is sim pler t han it appears. The part ial derivat ive is convert ed int o t he vect or ( df/ dx, df/ dy, 0) ; t he rest of t he equat ion m aps t he z value from t he range [ zm in,zm ax] t o [ 0,2π] and t akes t he sine of t hat value. This sine value is responsible for pushing vert ices out on t he upper half ( w here t he sine funct ion is negat ive) , and pulling vert ices in on t he lower half ( w here t he sine funct ion is posit ive) . Vert ices at t he t op, m iddle, and bot t om ( i.e., zm in, ( zm in+ zm ax) * 0.5, and zm ax ) are not m oved. Figure 20.6 shows t he effect of increasing values.

Figu r e 2 0 .6 . Va r yin g t he t e r r a in by a lt e r in g t h e " m u sh r oom fa ct or "

The dist ance bet ween successive cr osses is reasonably const ant , so t he t ext ure m apping is good. I n pract ice, when t his t ransform at ion is applied t o a com plex t errain, problem s arise. I f t he t errain has high- frequency feat ures, t he derivat ives vary considerably, and applying t he m ushroom t ransform at ion creat es unrealist ic horizont al spikes. The t op of each hill won't achieve zm ax , and t he bot t om of each valley w on't reach zm in. For best result s, t he t errain should have a narrow frequency range. The solut ion is t o separat e t he t errain int o t wo part st wo separat e t errain funct ion t rees. The first com ponent produces t errain wit hout high frequencies and wit hout large low- frequency feat ures eit her, so t he m ushroom t ransform at ion can be applied. The second com ponent is added t o t he first and does not have t he m ushroom t ransform at ion applied, so it can cont ain high- and low- frequency effect s. The Meran w orld ( Color Plat e 36C) is a good dem onst rat ion of how t he t w o com ponent s are used. The shape of t he st one lum ps is defined by t he first com ponent , which has t he m ushroom t ransform at ion applied t o give t he bulblike shape. The second com ponent of t he t errain cont ribut es everyt hing else: t he sm all ridges and wrinkles of t he st one bulbs, and also t he m ount ain r anges. The m ushroom effect is used on m ost of t he worlds in a m ore subt le way, t o produce st eep slopes wit hout t ext ure dist ort ion.

20.3. Implementation Now t hat we have discussed t he int ernal design of RealWorldz, we can look m ore closely at som e of t he im plem ent at ion det ails. This sect ion covers a lot of ground: noise values and derivat ives, t ile set s, funct ion t rees, t errain coloring, alt it ude and gr adient m aps, light ing, and perform ance considerat ions. To fully explain t he concept s, w e look at specific t ext ure exam ples used by som e RealWorldz planet s and describe som e of t he shader code t hat im plem ent s t hese concept s.

20.3.1. Noise Values and Derivatives Noise t ext ures are st ored as 8- bit per- channel RGB t ext ures, wit h t he funct ion value packed int o t he R channel, and t he part ial derivat ives packed int o t he G and B channels. When a t ext ure is read, t he color com ponent s are in t he range [ 0,1] . Noise funct ions range in value from - 1 t o 1, so unpacking t he R channel from a [ 0,1] range t o a [ - 1,1] range funct ion value is done by subt ract ing 0.5 and t hen scaling by 2.0. The range of part ial derivat ives varies from noise t ext ure t o noise t ext ure, depending on t he scale of t he noise t ext ur e. The part ial der ivat ives of Voronoi noise t ext ures oft en have a relat ively large range; linearly packing t he part ial derivat ives causes visible art ifact s on t he t errain because part ial derivat ives of sm all m agnit ude lack precision. The work- around is t o t ake t he cube root of t he part ial derivat ives before t hey are packed. This m eans t hat t here is less precision loss when part ial derivat ives of sm all m agnit ude are st ored, and m ore precision loss for large derivat ivesbut visually, it is a great im provem ent . The derivat ives are unpacked by cubing, which is efficient and doesn't require branching. So m apping from a [ 0,1] range t o a [ r,+ r] range is done by subt ract ing 0.5, scaling, and cubing. Som e graphics hardware can operat e on vect ors at t he sam e speed as float ing- point values, so it m akes sense t o pack t he funct ion value and derivat ives int o a vect or. The funct ion value is st ored as t he x com ponent , wit h t he derivat ives being t he y and z com ponent s. Unpacking a noise t ext ure sam ple int o funct ion value and derivat ives can t hen be done in a shader as follows: // // // //

Initially, the vector "noise" holds a color sampled from a noise texture. All components are in the range [0, 1]. The color has been implicitly converted to a vector with red being X; green being Y; and blue being Z.

// Subtracting 0.5 is the first step in unpacking both // value and derivative noise.xyz -= vec3(0.5, 0.5, 0.5); // Component-wise multiply. Unpack the value (x) by scaling // by 2.0. Unpack the derivatives (yz) by scaling by a // noise texture-dependent value. noise.xyz *= vec3(2.0, 4.566148, 4.566148); // Component-wise multiply. Cube the y and z values to complete // the unpacking of the partial derivatives. noise.yz = noise.yz * noise.yz * noise.yz;

Graphics hardware t hat operat es on vect ors can perform t his unpacking wit h one add and t hree m ult iplies.

St oring t he value and derivat ives as a vect or has som e useful advant ages. First , scaling a funct ion value by v m eans scaling t he part ial derivat ives by v as well. This can be done by scaling t he ent ire vect or by v since t he value and derivat ives are st ored as com ponent s of a vect or. Second, adding t wo values t oget her m eans adding t he part ial derivat ives as well. This can be done sim ply by adding t he vect ors t oget her.

20.3.2. Tile Sets A t ile set reduces t he appearance of repeat ing pat t erns by pregenerat ing a set of n 1 x 1 t iles and select ing a random t ile from t hat set t o cover each region ( u, v) ( u+ 1, v+ 1) on t he plane, where u and v are int egers. This can be im plem ent ed in a fragm ent shader in t he following way. First , t he t ile set is packed int o a t ext ure m ap ( see Color Plat e 26A) . Four t iles can be packed int o a 2 x 2 arrangem ent ; eight int o a 4 x 2 arrangem ent any num ber t hat 's t he product of t w o powers- of- t w o is possible. Let t his t ext ure m ap be scaled up and t ranslat ed so each of t he t iles covers a unit square on t he planet hat is, t he region ( u, v) ( u+ 1, v+ 1) for int egers u and v. The pseudorandom select ion of a t ile for each unit square is done as follows. Anot her t ext ure m ap is em ployed, filled wit h random values; it is called t he " offset " t ext ure ( see Color Plat e 26B) . I t is sam pled in nearest - neighbor m ode and scaled up so each t exel exact ly overlaps a t ile from t he t ile set t ext ure m ap. The values read from t he offset t ext ure will be const ant over t he region of a t ile; it is discont inuous only on t he boundaries bet ween t iles. As t he nam e im plies, t he value read from t he offset t ext ure is used t o offset t he locat ion at which t he t ext ure m ap cont aining all t he t iles is sam pled. The offset am ount is an exact m ult iple of t he t ile size: for inst ance, if t he t iles were packed int o t he t ext ure m ap in a 4 x 4 arr angem ent , t hen t he offset of each coordinat e could be 0.0, 0.25, 0.5, 0.75,. . .. I n pseudocode, it works as follows. ( Det ails of scaling and t ranslat ing t he offset and t ile set t ext ure reads so t he t ext ure m aps are aligned as described above have been om it t ed.) 1 . Let ( p x , p y ) be t he point on t he plane at which t he noise t ext ure t ile set is required. 2 . Read a value ( r, g, b) fr om t he offset t ext ure at ( p x , p y ) . Scale t his value, or alt er t he t ext ure read m ode so r, g, and b are guarant eed t o be int egers. 3 . t x = p x + ( r / n x ) , w here n x is t he num ber of t iles across t he widt h of t he t ile set t ext ure m ap. 4 . t y = p y + ( g / n y) , w here n y is t he num ber of t iles down t he lengt h of t he t ile set t ext ure m ap. 5 . Read from t he t ile set t ext ure m ap at locat ion ( t x , t y ) . Color Plat e 26 illust rat es t his process. Color Plat e 26A shows t he t ile set im age covering t he plane, wit h t ile edges em phasized. Color Plat e 26B show s t he offset t ext ure, scaled up so t hat each t exel exact ly covers a t ile. Color Plat e 26C show s t he t ile set overlaid wit h t he offset t ext ure. The result of adding t he t ile set and t he offset t ext ure is shown in Color Plat e 26Dt iles pseudorandom ly scat t er ed.

20.3.3. The Function Tree The fragm ent shader code t o evaluat e t he fract al t errain is pr ogram m at ically generat ed from t he t errain funct ion t ree. Each node in t he t errain funct ion t ree becom es a procedure. A m at h node t hat sum s, averages, or m ult iplies t he values of it s child nodes becom es a procedure t hat calls t he pr ocedures for each child, t hen com bines t hose result s. A dist ort ed m ult ifract al evaluat es it s child node ( which defines t he dist ort ion) and applies t he result ing offset t o t he

param et er before evaluat ing t he m ult ifract al. I n RealWorldz, t he planet art ist specifies t he num ber of oct aves of noise a m ult ifract al should use. This is different from t he st andard pract ice, where sm aller and sm aller oct aves of noise are evaluat ed unt il t hey have no effect on t he rendered im age. Because t he m ult ifract al uses a fixed num ber of oct aves, t he code for evaluat ing m ult ifract als can have t he sum m at ion loop unrolled. This allows alm ost all t he coefficient s in t he evaluat ion code t o be precom put ed, which is a great advant age since it avoids calls t o pot ent ially expensive funct ions ( such as pow) in t he fragm ent shader. Anot her benefit is t hat t he code m akes no use of branches or loops. For inst ance, here is fragm ent shader code for evaluat ing a t wo- oct ave m onofr act al. Not e t he " Oct ave 0" and " Oct ave 1" com m ent st hey indicat e each sect ion of t he unrolled m ult ifract al evaluat ion loop. I f t he user specified a t hree- oct ave m onofr act al, anot her block of code t o evaluat e t he t hird oct ave would be insert ed im m ediat ely before t he " Final scale and offset " com m ent . The variable currHdH is a vect or st oring height and t he t wo part ial derivat ives of height , as t he x, y, and z com ponent s, respect ively. The eight een- digit num bers are precalculat ed values, writ t en t o 18 decim al places for precision. ( Current graphics hardware support s single- precision float ing- point calculat ions at m ost , but t here m ay com e a day when double precision is support ed as well. I t is needed t o support t he dynam ic range necessary for m odeling on a planet ary scale.) vec2 vec3

texCoord; currHdH = vec3(0,0,0);

vec2 vec3 float float vec3 float

distParam = param; noise; signal; increment; newHdH; mfOffset= -0.200000000000000010;

// Octave 0 texCoord = (distParam * 0.005000000000000000) + vec2(1.090196078431372700, -0.588235294117647190);

// Sample noise texture 0 at parameter "texCoord"; // put the result into "noise" texNT(noise, NT0, texCoord, 256); noise

-= vec3(0.5, 0.5, 0.5);

noise.xyz *= vec3(2.0, 4.566148, 4.566148); noise.yz = noise.yz * noise.yz * noise.yz; increment = (noise.x - mfOffset) * 1.000000000000000000; newHdH.x = currHdH.x + increment; newHdH.yz = currHdH.yz + (noise.yz * 0.005000000000000000); currHdH = newHdH; // Octave 1 texCoord = (distParam * 0.010000000000000000) + vec2 (0.949019607843137440, -0.964705882352941300); // Sample noise texture 0 at parameter "texCoord"; // put the result into "noise" texNT(noise, NT0, texCoord, 256); noise -

= vec3(0.5, 0.5, 0.5);

noise.xyz *= vec3 2.0, 4.566148, 4.566148); noise.yz = noise.yz * noise.yz * noise.yz; increment = (noise.x - mfOffset) * 0.435275281648062060; newHdH.x = currHdH.x + increment; newHdH.yz = currHdH.yz + (noise.yz * 0.004352752816480621); currHdH = newHdH; // Final scale and offset float heightScale = 1.000000000000000000; float heightOffset = 0.000000000000000000; HdH = currHdH * heightScale; HdH.x += heightOffset;

All t he exponent iat ions have been precalculat ed, reducing t he m at hem at ics t o m ult iplies and addst his is t rue for t he ot her m ult ifract als ( het erofract al and m ount ainfract al) as well as for t he m onofract al used here. The texNT funct ion does a bilinearly filt ered t ext ure read fr om t he appropriat e noise t ext ure and handles t he addit ional work if a t ile set is in uset hat is, an addit ional t ext ure read, m ult iply, and add. So, t he process of evaluat ing a m ult ifract al has been reduced t o operat ions for which graphics hardw are is designed: 2D t ext ur e r eads, m ult iplies, and adds. No branches are requir ed, no slow or higher - order com put at ions are done; and only one t ext ure read is required per oct ave.

20.3.4. Terrain Color I n t he preceding sect ions, t he process for calculat ing t he height and slope of t he t errain has been described. The next st ep is t o color and illum inat e t he t errain. The st andard way t o color fract al t errain is t o creat e a funct ion involving t he t errain height and slope, t hen add t ext ure wit h m ult ifract als. A m ore hardw are- friendly appr oach was t aken for RealWorldz. Here, a 3D t ext ure is used, where each slice is a differ ent surface t ypefor exam ple, sand, grass, snow, rock, or eart h. The alt it ude and gr adient ar e looked up in a 2D t ext ure m ap called t he " alt grad" m ap; it select s which slice from t he 3D t ext ure t o use. Terrain wit h t ext ure based on height or slope alone is very obvious; t he idea behind t he alt grad im age was t o com plicat e t hings so t he t ext ure t ransit ions had a less obvious pat t ern, and t o do so in a way t hat could be cont rolled by t he planet art ist . For accessing t he alt grad m ap, height is Y and gradient is X. So a low point on t he t errain m eans a low Y; m ount aint ops have a high Y; a perfect ly level area has X = 0; a st eep slope has high X. The color obt ained from t he alt grad m ap is used as t he Z com ponent for accessing t he 3D t ext ure.

20.3.5. AltGrad Map for Snow The alt grad m ap used for t he Snow planet is shown as t he second im age in Color Plat e 36A, and im ages of t he planet are shown in Color Plat e 36F, Color Plat e 37E, and Color Plat e 38A. The 3D t ext ur e has only t wo slices; one is snow , t he ot her gray rock. The light gray in t he alt grad im age select s t he snowy slice; t he dark gray select s t he gray rock t ext ure slice. The light gray is rest rict ed t o t he left - hand side of t he im age, w hich corresponds t o flat ar eas. The widt h of t he light gray area does vary slight ly, but on t he whole t he effect is t hat flat t errain has snow , and areas t hat are t oo st eep have bare rock. The abrupt t ransit ion bet ween colors in t he alt grad m ap m eans t hat t here will be an abrupt change in t ext ure.

20.3.6. AltGrad Map for AlienRockArt The first im age in Color Plat e 36A is t he alt grad t ext ure used for t he AlienRockArt planet , and Color Plat e 36E is an im age of t he planet showing t he rock art . The AlienRockArt alt grad t ext ure is t he m eans by which t he orange rock art is cr eat ed. The alt grad im age has t hree colors: very dark gray, which select s t he orange slice of t he 3D t ext ure; m id- gray, which select s t he whit e lim est one t ext ure, and light gr ay, which select s t he brown burned- grass t ext ure. A point on t he t errain is colored orange if in t his alt grad m ap t he height and slope correspond t o a point t hat is darkest gray. The darkest gray in t he alt grad m ap is deliberat ely confined t o t he bot t om right - hand part of t he alt grad m ap, rest rict ing it t o lowish and st eepish t errain, but t he shape of t he dark gray color is deliberat ely com plex so t hat t he result ing com binat ions of height and slope t hat yield t he orange color will be t oo com plex for a pat t ern t o be evident . The ot her deliberat e choice m ade for paint ing t he alt grad m ap was t o m ake a hard edge bet ween t he darkest gray and m id- gray colors t o creat e a sharp division bet w een t he lim est one t ext ure and t he orange t ext ure. The AlienRockArt planet st art ed life as an experim ent t o reduce t he repeat ing pat t ern of t he lim est one t ext ur e. Two different lim est one t ext ures were creat ed, assigned t o different slices of t he 3D t ext ure, and t he alt grad m ap was edit ed so t hat t here would be frequent t r ansit ions bet w een t w o t ext urest he idea being t hat t he t ransit ions would obscure t he periodic feat ures. To clarify where t he t ransit ions were, one of t he lim est one t ext ures was colored orange, and t he alien rock art pat t ern em erged. The light gray region is rest rict ed t o t he t riangle in t he upper left , indicat ing flat and high areas. Low areas have t o be fair ly flat for t here t o be br own grass on t hem ; but as t he t errain get s higher, t he brown grass appears on progressively st eeper t errain. The gent le t ransit ion from m id- gray t o light gray m eans t hat t here is a sm oot h cross- fade bet ween t he lim est one and t he brown grass. The t w o m id- gray st rokes cut int o t he light - gray region are responsible for t he t hin pat hs t hat can be seen at t he boundaries of t he grass.

20.3.7. AltGrad Map for DragonRidges The alt grad m ap for t he DragonRidges planet is t he t hird im age in Color Plat e 36A, and an im age of t he planet is show n in Color Plat e 36D. Four t ext ur e slices from t his planet ar e shown in Color Plat e 36B. From left t o right , t hey are select ed by t he darkest gray t o t he light est gray in t he alt grad m ap. The four t ext ure slices cont ain a carefully paint ed t ransit ion from bare rock t o grass. The bare rock im age has subt le darkenings due t o t he cracks in t he second t ext ure m ap, and t he grassy areas in t he t hir d im age follow t he cracks t oo, so feat ures can be followed across t he t ransit ions bet w een t he different t ext ure m aps. Even t he gr ass in t he t hird t ext ure m at ches t he t ext ure of t he gr ass in t he fourt h t ext ure. The first t ext ure slice has only subt le feat ureslight ing and shadowing due t o t errain shape overpowers t he m inor feat ures of t he t ext ure, so it is difficult t o see a repeat ing pat t ern when it is used. However, t he ot her t hree t ext ure slices have m ore obvious feat ures, and so t he repeat ing t ext ure pat t ern is visible when t he slices are used across a large area. The alt gr ad im age t hat cont rols t heir use has been car efully paint ed so t hese t ext ures don't cover areas large enough for t he repeat ing pat t ern t o be obvious. The im age of DragonRidges ( Color Plat e 36D) show s t he com plex dist ribut ion of t he grass and rock. The gr ass is affect ed by t he shape of t he t errain: Pat ches of grass are bounded by changes from flat t o slope, or ot her t err ain feat ures. The rock changes from cracked t o sm oot h depending on exposure. These effect s result from t he use of sm all pat ches of color in t he alt grad m ap: anyt hing m ore t han a m inor change t o height or slope m oves t he sam ple point out

of t he color pat ch, m eaning t hat t he t ext ure of t he ground changes in response t o t hose m inor changes in height and slope.

20.3.8. Lighting The fragm ent shader has now calculat ed t he t errain color and t he part ial derivat ives fr om which t he surface norm al is calculat ed. Since t he fragm ent shader for doing all t his w ork is program m at ically generat ed, it is st raight forward t o allow t he planet art ist t o writ e cust om light ing calculat ion code and for t his code t o be insert ed int o t he fr agm ent shader code when it is generat ed. The default light ing code im plem ent s t he Phong light ing equat ion, but since t he code is specific t o each planet , cust om light ing effect s are possible. For inst ance, t he light ing code for t he Cerber us planet ( Color Plat e 38B) light ens and reddens t he ground color so t hat low- lying areas glow whit e- hot . The light ing code for t he Tar planet adds back - light ing, t o give t he w hit ish color t o t he shaded sides of t errain. For t he Meran planet ( Color Plat e 36C and Color Plat e 38D) , t he gouges in t he boulders are darkened. The light ing code for t he Ring planet goes beyond j ust applying light effect s and also calculat es t he base color, using t he 3D t ext ure slice as a source of noise. Allowing users t o supply t heir own light ing code was relat ively easy t o im plem ent , but t urned out t o be a powerful and useful t ool.

20.3.9. Performance Considerations RealWorldz has t o render t errain wit h a high fram e rat e in addit ion t o generat ing t he new t errain t ext ure m aps. Even w it h each oct ave requiring j ust one t ext ure read and som e sim ple m at hem at ics and planet s pared t o t he bare m inim um num ber of oct aves, t he fragm ent shader t akes over a t hirt iet h of a second t o generat e a new 256 x 256 t ext ure m ap. A period t his long is unaccept able for real- t im e rendering. The solut ion is t o spread t he work of generat ing t he new t ext ure m ap across several fram es by generat ing a subset of t he new t ext ure m ap during each fr am e. The m ore fram es across w hich t he work is split , t he sm aller t he drop in fram e rat ebut t aking longer t o generat e m eans t hat it will t ake longer before low- resolut ion t errain is replaced wit h higher- resolut ion t errain. I n RealWorldz, t he generat ion of each 256 x 256 t ext ure m ap was spread across six fram es.

20.4. Atmospheric Effects At m ospheric effect s are vit al for giving pict ures of t errain t heir sense of scale. This sect ion describes t he at m ospheric effect s of aerial perspect ive and sky shading.

20.4.1. Aerial Perspective The change in appearance of obj ect s wit h dist ance is called " aerial perspect ive." Briefly, t he Eart h's at m osphere scat t ers blue light m ore t han red light , so a dist ant obj ect affords m ore opport unit ies for blue light t o be scat t ered in t he direct ion of t he view erso t he obj ect t urns slight ly blue, for t he sam e reason t hat t he sky is blue. Dist ant obj ect s also t end t o be darkert heir reflect ed light is m ore likely t o be blocked by part icles in t he at m osphere. The t ext book m et hod for calculat ing at m ospheric scat t ering is described in t he paper Display of The Eart h Taking int o Account At m ospheric Scat t ering, by T. Nishit a, T. Shirai, K. Tadam ura, E. Nakam ae, in t he SI GGRAPH '93 proceedings. The st andard way t o calculat e a dist ant obj ect 's change in color due t o at m ospheric effect s is as follows. The change is split int o " inscat t ering" and " ext inct ion." I nscat t ering is t he scat t ering of light int o t he line from obj ect t o eyet his is an addit ion in t he light int ensit y. Ext inct ion refers t o t he absorpt ion of light t his is a scaling of t he light int ensit y by som e fact or. I f Lo is t he radiance of t he dist ant obj ect and Ls is t he radiance of t he ray at t he viewer, t hen Ls = Ce Lo + Ci w here Ce is t he ext inct ion fact or, and Ci is t he inscat t ered light . I n principle, t his calculat ion should be done for each frequency of t he light , but in pract ice it is accept able t o calculat e t he effect on only t hree w avelengt hst he st andard red, green, and blue com ponent s. The ext inct ion fact or is calculat ed as Ce = exp( I · E · D) where I is t he int egral along t he line from eye t o obj ect , E is t he ext inct ion rat io per unit lengt h, and D is t he densit y rat io. For a planet 's at m osphere, t he int egrand is a spherically sym m et ric funct ion. The calculat ion of Ci has a sim ilar form t he inscat t ering at each point along t he obj ect - eye line is int egrat ed. The inscat t er for a given point is a funct ion of t he angle bet w een t he sunlight and t he line from t he obj ect t o t he eye, t he densit y of t he at m osphere, and t he int ensit y of t he sunlight r eaching t hat point . Leaving t he m at hem at ics at t hat point , we can see t he ext inct ion and inscat t ering cont ribut ions in Color Plat e 37A, B, and C. Previous work on real- t im e at m ospherics have focused on height fields rat her t han full spherical planet s; see, for inst ance, Render ing Out door Light Scat t ering in Real Tim e by Hoffm an and Preet ham . Aft er several different at t em pt s t o find appr oxim at ions of t he required int egrals for spherical at m ospheres failed, we fell back t o a sim ple but effect ive m odel t hat has lit t le relat ion t o t he m at hem at ics but is fast t o com put e and good enough t o fool t he eye. A diagram illust rat ing our approach and t he arrangem ent of t he relevant obj ect s is shown in Figure 20.7.

Figu r e 2 0 .7 . Ele m e n t s of t h e a t m osph e r ic sh e ll m ode l u se d t o com pu t e a e r ia l pe r spe ct ive

This funct ion we use is an approxim at ion t o 1.0 exp( I ) , w here I is t he int egral t hrough a dist ribut ion from t he viewer ( denot ed by v) t o t he point x. This funct ion t akes t he value 0 if v and x are coincident and rises t o 1.0 if t he line from v t o x passes t hrough high- valued regions of t he dist ribut ion. The funct ion is m ade up of t wo com ponent s. The m ain t erm t he " at m ospheric shell" follows t he shape of t he planet and provides a height - dependent effect , wit h dist ant obj ect s m ore affect ed t han close ones. The ot her t erm is a correct ion for t he region near t he view er. The planet is cent ered at t he point p. The radius of t he highest point on t he t errain is found and est ablishes a bounding sphere for t he planet . The posit ion of t he view er, t he point p, and t he point q are collinear. A funct ion called t he at m ospheric shell is defined wit h cent er at t he point q. I t s value is a funct ion of radius, t aking t he value 0 on t he sphere m arked " out er shell" and t aking 1.0 on t he " inner shell" sphere. Each shell's radius is fixed; t he point q is chosen so t hat t he out er shell is exact ly t angent t o t he bounding sphere of t he planet . The posit ion of t he point q is a funct ion of viewer posit ion. The radii of t he inner and out er shell affect t he dist ribut ion of t he at m osphere; t hey are chosen by t he planet art ist . ( They are exaggerat ed in Figure 20.7; in pract ice, t he out er shell radius is usually not m uch m ore t han t he radius of t he planet 's bounding sphere.) The value of t he at m ospheric shell funct ion F1 for a point x is F1 = ( a ·| x - q| 2 ) + b

where a and b are const ant s; t hey are chosen so t he funct ion t akes t he value 0 and 1.0 on t he inner and out er shells, respect ively. I f r o is t he radius of t he out er shell, and r i is t he radius of t he inner shell, t hen

As described earlier, t his funct ion cont rols t he am ount by which t he color is darkened and shift ed t o blue. A value of 0 causes no color changes; larger values cause a m ore pronounced color shift . This funct ion em ulat es t he at m ospheric color shift , decreasing wit h height and increasing wit h dist ance. Since t he shell radii are larger t han t he planet radius, dist ant m ount ains are m ore affect ed by t he color shift t han are closer m ount ains. ( I t is possible t o choose shell radii so t hat t he shell funct ion value does not m onot onically decrease wit h dist ance fr om t he viewer; t his problem is usually because t he radii are t oo sm all.) But if t he viewer approaches som e t errain closely, t hen t here should be no color shift ; t his funct ion does not provide t his effect , and so a second t erm was added t o handle t his case. The second t erm is a value proport ional t o exp( dist ance 2 ) : F2 = c · exp ( | x - v| 2 ) · d The second t erm is subt ract ed from t he first t o provide t he final value. The full fog calculat ion for a point x is as follows: Ffinal = ( a ·| x - q| 2 ) + b - ( c · exp ( | x - v| 2 ) · d where q is t he cent er of t he at m ospheric shell funct ion, a and b are calculat ed from t he inner and out er shell radii wit h t he form ula given described above, v is t he viewer posit ion, and c and d are const ant s det erm ining t he shape of t he local visibilit y correct ion. As a final st ep, t he com put ed value is clam ped t o t he range [ 0,1] . This approxim at ion is valid only for point s wit hin t he planet bounding sphere. Point s out side t his sphere can be handled by being proj ect ed ont o a sphere cent ered at t he viewer whose radius is such t hat it int ersect s t he planet bounding sphere at t he horizon. We t ried several ot her at m ospheric appr oxim at ions wit hout success. One com m on problem was t hat t he value for a point on t he t errain would change unrealist ically as t he viewer m ovedit did not m onot onically increase or decrease as t he viewer m oved t oward or away from t he point ; or t he value did not m onot onically decrease wit h t errain height . The at m ospheric shell approxim at ion described here is sim ply a fast fu nct ion t hat displays t he obvious charact erist ics a viewer expect s, rat her t han an at t em pt t o creat e a m at hem at ically correct appr oxim at ion. The effect of t he at m ospherics is m ost clearly seen on t he Snow planet , on which t he at m osphere param et ers have been pushed t o an ext rem e t o produce dense low- lying fog inst ead of subt le haze and color shift ( see Color Plat e 37E) . The t ransit ion from dense fog t o clear air happens over a ver y short dist ance, so any problem s wit h t he at m ospheric appr oxim at ion funct ion are m ore apparent . There are no ar t ifact s or visible problem s: The fog increases m onot onically wit h height and wit h dist ance. There are no discont inuit ies, and t he fog correct ly follows t he shape of t he planet . Also, t here are no t em poral problem s as t he cam era is m oved.

The at m ospheric appr oxim at ion is not m at hem at ically correct , but it is st able, fast , easy t o im plem ent , reasonably int uit ive t o work wit h, and good enough t o fool t he eye.

20.4.2. Sky Shading The color of t he sky is m ore com plex and is shaded by m eans of a com plet ely different t echnique. I n RealWorldz, t he approxim at ion is m ade t hat sky color is a funct ion of opt ical dept h and t he angle bet w een sun and view direct ion. The funct ion is expressed as a lookup t able ( t ext ure m ap) . Som e im ages of t he sky from t he DragonRidges w orld are shown in Color Plat e 37MT. The sky color t ext ure for t his planet is shown in Color Plat e 37I , and it s at m ospheric densit y t ext ure is shown in Color Plat e 37J. The sky color lookup t able for DragonRidges produces a whit e sun, a blue sky, and a red sunset . The color of a pixel in a given direct ion, wit h a given opt ical dept h is read fr om t he sky color t ext ure m ap. The y coordinat e for t he t ext ure access is exp( O) , w here O is t he opt ical dept h. The result ing value is 1.0 for zero opt ical dept h, and t he funct ion approaches zero as opt ical dept h increases. The x coordinat e for t he t ext ure access is t he angle bet w een t he vect or t o t he sun and t he direct ion for t he fragm ent in quest ion, scaled t o [ 0,1] . I f t he direct ion is exact ly t oward t he sun, x is 0; if it is exact ly away from t he sun, x is 1.0. The whit e vert ical bar on t he left - hand side of t he DragonRidges sky color lookup t able corresponds t o low anglesdirect ions nearly point ing t o t he sun. This provides t he sun glare. The t op of t he im age fades t o black, corresponding t o t he at m osphere fading out as it get s t hinner. The right - hand side of t he im age corresponds t o direct ions away from t he sun; it is shades of blue t hat are darker for lower opt ical dept h and br ight er for higher opt ical dept h. The reds and oranges in t he lower left give t he sunset effect s for vect ors t hat are som ewhat in t he sun's direct ion and t ravel t hrough high- densit y at m osphere. The alpha channel det erm ines t he blend bet ween t he cubem ap wit h t he st ars and nebula and t he at m osphere color. Whit e m eans t hat t he result is equal t o t he sky color; black m eans t hat t he result is equal t o t he cubem ap color. Grays indicat e t he different degrees of blend. This m ap is m uch t he sam e for all t he different at m ospheres: whit e for t he m ost part , w it h a sm oot h gradient est ablishing a t ransit ion t o t he st ar cubem ap as opt ical dept h decreases. A whit e bar runs t he w hole way up t he left - hand side of t he im age so t hat t he sun appears regardless of opt ical dept h. The calculat ion of opt ical dept h is expensive, so t he sky is rendered by m eans of a sphere cent ered on t he viewer, t essellat ed int o rings of fixed lat it ude, and rot at ed so t hat t he axis is in line wit h t he planet cent er. This arrangem ent is chosen specifically so t hat for a given lat it ude, t he opt ical dept h for any ray is t he sam e. That way, t he opt ical dept h needs t o be calculat ed once for each lat it ude. For each vert ex, exp( O) and direct ion are calculat ed. For t he sky color t ext ure m ap lookup in t he fragm ent shader, t w o quant it ies are needed: t he angle bet ween t he sun and t he current direct ion for t he x com ponent , and exp( O) for t he y com ponent . I t is sufficient t o use t he int erpolat ed value provided by t he vert ex shader for t he y com ponent . Since finding t he exact angle bet ween t w o vect ors wit h t he acos funct ion was deem ed t oo slow, t he x com ponent is calculat ed as 0.25·| sd| 2 , where s is t he norm alized sun direct ion vect or and d is t he norm alized current direct ion. ( For inst ance, if s and d are parallel, t he result is zero; when t he t wo are ant iparallel, t he lengt h of t heir difference squared is 4.0, so t he result ing x com ponent is 1.0.) This calculat ion is fast , but it yields a funct ion t hat is quit e dissim ilar t o t he act ual angle bet w een t w o vect ors. However, it is a m onot onically increasing funct ion of angle, so t he inverse funct ion can dist ort t he t ext ure m ap t o com pensat e. For inst ance, t he sit uat ion in which t he sun and view direct ion are 18° apart corresponds t o x = 18/ 180 = 0.1 in t he above colorm ap. However, t he x com ponent calculat ion according t o t he new form ula gives 0.09788. Therefore, t he colum n of pixels at x = 0.1 is m oved t o x = 0.09788 t o com pensat e. This resam pling leads t o a loss of det ail in regions of low x; t his loss is reduced when t he correct ed t ext ure m ap is

m ade t w ice t he widt h of t he source. The body of t he fragm ent shader is as follows: // Vertex shader calculates s - d, and outputs deltaSD float u = dot(deltaSD, deltaSD); // expInvOpticalDepth = exp(-optical depth); this is the // value calculated by the CPU described above float v = expInvOpticalDepth; // Sample the sky color texture map vec4 atmosC = texture2D(skyColorTexturemap, vec2(u, v)); // Sample the star cubemap vec4 starC = textureCube(starCubemap, worldDir); // // // // //

The blend between the sampled atmosphere color and the cubemap color is actually more sophisticated than a simple lerp: the star cubemap stores alpha as a measure of brightness, where 0.0 is very bright and 1.0 is dark. This code causes bright stars and moons to show through the atmosphere.

vec4 color = atmosC + (1.0 - (atmosC.a * starC.a)) * starC; // colExtinction and colInscatter are due to atmospherics, and // are calculated in the vertex shader gl_FragColor = (color * colExtinction) + colInscatter;

The sky color t ext ure m aps could be procedurally generat ed, but since t he lookup t able is an im age, it is nat ural t o work on it wit h a paint pr ogram . Act ions such as changing t he color of t he sky in som e way ( reddening, light ening, reducing cont rast , et c.) can be done by applicat ion of t hat oper at ion t o t he whole sky color t ext ure m ap, which is m uch m ore int uit ive t han t w eaking t he param et ers of a procedural m odel. Som e of t he sky color t ext ure m aps in RealWorldz w ere st art ed by back- proj ect ion of reference phot os of skies or sunset scalculat ing t he m apping from sky color t ext ure m ap t o screen, m at ching a sunset phot o ( for inst ance) and reversing t he m apping t o build t he sky color t ext ure m ap t hat gives t he sunset im age. Thus was defined t he cont ent of a sm all region of t he t ext ure m ap, which was t hen ext ended out ward by being paint ed. Paint ing t he sky color t ext ure m ap is very powerful, but it is not int uit ive and has som e pit falls. For inst ance, finding t he region of t he t ext ure m ap t hat cont rols t he color of a part icular piece of sky is not easy, so changing t he color of one part of t he sky w it hout affect ing anyt hing else is difficult . One relat ed problem is t hat t he sky shader effect ively dist ort s and sm ears t he t ext ur e m ap t o render t he sky, so any sharp color changes in t he t ext ur e cause very obvious lines in t he sky. All such discont inuit ies have t o be rem oved, but finding t he problem area on t he t ext ure m ap is oft en t he m ost t im e- consum ing part of t he process. One exam ple of an art ist ic effect t hat would be subst ant ially m ore difficult t o produce wit h a physically based at m osphere m odel is t he halo around t he sun on t he Snow planet , as show n in Color Plat e 37K. The r ainbow around t he sun w as paint ed ont o t he t ext ure; it is t he subt le vert ical rainbow visible on t he left - hand side of t he sky color t ext ure m ap shown in Color Plat e 37L.

20.5. Ocean The reflect ive ocean is render ed in t wo st eps. The im age of t he reflect ed t errain and sky is rendered ( Color Plat e 37U) , reflect ed ( Color Plat e 37V) , and t hen com posit ed t o creat e t he final im age ( Color Plat e 37W) . The reflect ion im age cont ains only t he t errain and sky.

20.5.1. Reflections Because t he ocean is a sphere, t he reflect ion m ust be spherical. Figure 20.8 shows a screenshot of t he AlienRockArt planet wit h a high wat er level: You can see t hat t he t errain on different sides of t he planet is reflect ed in different direct ions. This effect cannot be achieved wit h sim ple planar reflect ion. Rendering t he reflect ion im age m eans drawing t he t errain reflect ed in t he sphere. Figure 20.9 shows t he requirem ent s.

Figu r e 2 0 .8 . Re fle ct ion s fr om a sph e r ica l su r fa ce r e fle ct e d in diffe r e n t dir e ct ion s, a s sh ow n in t h e cir cle d r e gion s

Figur e 2 0 .9 . The ge om e t r y of r e fle ct ions on a sph e r ica l obj e ct

Given t he eye and obj ect posit ion, t he point R m ust be found such t hat t he angle of incidence equals t he angle of reflect ion. ( These t wo angles are t he arcs on t he diagram .) Once R is found, t he reflect ed point is be such t hat t he line from it t o t he eye passes t hrough R. ( The locat ion of t he reflect ed point is not exact ly defined, since for rendering a real- t im e reflect ion, t he only const raint is t hat obj ect order is preserved so t hat obj ect s occlude each ot her properly. For inst ance, if a second obj ect lies bet ween R and t he obj ect , it would occlude t he first obj ect and so it s reflect ed point m ust be closer t o t he eye t han t he fir st obj ect 's reflect ed point .) Finding t he point R exact ly involves solving a fourt h- order polynom ial; see Reflect ions on Spheres and Cylinders of Revolut ion by Georg Glaeser. Once again, t his is a com put at ion t hat would be pr ohibit ively cost ly. For RealWorldz, t he reflect ion needs only t o be good enough t o fool t he hum an eye, so m at hem at ical precision is unnecessary. A viewer would expect reflect ions t o have t he following propert ies: z z

z

When an obj ect t ouches t he reflect or, it s reflect ion m ust m eet it . When t he viewer is close t o t he sphere, t he local region is approxim at ely planar, so t he reflect ions of local obj ect s should be sim ilar t o a plane. I f an obj ect appears j ust above t he horizon, it m ust t ouch it s r eflect ion even if t he obj ect is far beyond t he horizon ( grazing reflect ion) . For inst ance, a m oon t hat appears j ust above t he horizon should have a reflect ion.

For t he t errain, it is only necessary t o consider point s t hat are close t o t he planet surface. The sky is handled in a different way alt oget her, described in t he next sect ion. One com plicat ion is t hat t he t errain is rendered wit h t riangles, so som e t riangles will have ver t ices in regions hidden from t he view er. For inst ance, a t r iangle t hat penet rat es t he reflect or will have a vert ex inside t he sphere. For t he reflect ed t riangle t o be rendered correct ly, t hese hidden vert ices m ust be " reflect ed" t o an appropriat e posit ion. Figure 20.10 shows t he elem ent s of a m et hod t hat m eet s t hese crit eria.

Figu r e 2 0 .1 0 . Appr ox im a t in g r e fle ct ions on a sph e r ica l obj e ct

The view shown in Figure 20.10 is a cross- sect ion of t he sit uat ion for a given eye posit ion. The reflect or is cent ered at C, and t he point H is on t he horizon. That is, t he point H is on t he reflect or sphere, and t he line from H t o t he eye is at right angles t o t he line from H t o C. The dark line is roughly t he line in which point s are reflect ed. Tw o infinit e cones are defined. The " divider" cone has it s t ip at t he point C, wit h it s axis lying on t he line from t he eye t o t he point C. The surface of t he cone passes t hrough H. I t is t he shaded area in Figure 20.10B. The second cone, t he " horizon" cone, has it s t ip at t he point E, and it s axis also lies on t he line from t he eye t o t he point C. Again, t he surface of t he cone passes t hrough H. I t is t he shaded area in Figure 20.10C. The divider cone det erm ines t he m et hod for reflect ing a given point . I f t he point is wit hin t he cone, t hen it s reflect ion is it s inversion in t he reflect or sphere ( t he curved sect ion of t he bold line) ; if t he point is out side t he cone, t hen it s reflect ion is it s inversion in t he horizon cone ( represent ed by t he st raight sect ions of t he bold line) . By " invert ing t he point x in a surface S" , w e m ean finding a point p on S w it h a surface norm al n, such t hat p + kn = x, for som e real k. Then t he invert ed locat ion r is defined t o be r = s kn. ( Applying t his definit ion t o a plane surface gives t he expect ed reflect ion t ransform at ion, t hat is, m irroring t he point s in t he plane.) This m et hod for finding reflect ed point s fulfills t he crit eria given above. The inversion in a sphere t akes care of t he first t wo requirem ent s; t he horizon cone inversion case was added for t he pr ocedure t o fulfill t he last requirem ent . Alt hough not m at hem at ically correct , in pract ice it produces convincing spherical reflect ions.

20.5.2. Reflected Sky Render ing t he reflect ion of t he sky is m uch less com plex. The sphere of t he sky is considered t o be at infinit y, which great ly sim plifies t he m at hem at ics. As described in t he pr evious sect ion, t he sky is rendered as a sphere t essellat ed wit h const ant - lat it ude rings. The const ant - lat it ude ring and spherical reflect or are invariant under r ot at ion about t he polar axis, so t he reflect ion calculat ions can be so set up t hat t hey need only be done once per lat it ude.

20.5.3. Rendering the Ocean The final st ep is t o com posit e t he reflect ion im age ont o t he scene. The wat er effect s sim ulat ed are reflect ion, warping of reflect ion due t o waves, underwat er caust ics, and wat er t ransparency. Underwat er caust ics are flickering light pat t erns on underwat er surfacest hey are oft en seen at t he bot t om of swim m ing pools. They are due t o t he ripples and waves causing t he light t o refract in different direct ions. As a result , t he light is not dist ribut ed evenly on t he underwat er surfaces; it is concent rat ed in som e areas, which are t he bright spot s. I n RealWorldz, t he caust ic effect s are sim ulat ed wit h an anim at ed t ext ure m ap. Anot her applicat ion generat ed t he anim at ed t ext ure m ap by defining a wat er surface wit h a periodic wave pat t ern and sim ulat ing t he pat hs of m illions of phot ons refract ed by t he surface. This produced a sequence of t ileable t ext ure m aps t hat m ake up t he anim at ion. When t he ocean is enabled, t he caust ic t ext ure m ap is drawn on underwat er t errain as t he t errain is rendered; it fades out as t he wat er dept h decreases. This shader also set s t he alpha com ponent t o indicat e how m uch t hat pixel is occluded by t he wat er. I f t he point is above wat er, t he alpha is 0. The alpha value increases wit h dept h and dist ance from t he viewer, w it h 1.0 indicat ing t hat t he pixel is com plet ely obscured by t he ocean. When t he ocean is drawn, t his

alpha value cont rols t he blend bet ween t he reflect ive ocean and t he underlying t errain. Anot her com plicat ion is t hat t he ocean is drawn by re- rendering of t he t errain and use of t he vert ex shader t o pr oj ect all t he vert ices ont o t he ocean sphere. Since t he t errain pat ches overlap, som e ocean pixels are drawn t wice or m ore. Since t he wat er is part ially t ransparent , pixels t hat are draw n t w ice have t he t ransparency effect applied t wice, m eaning t hat t he ocean looks different in overlap regions. The solut ion was t o use t he OpenGL blend m ode GL_ONE_MI NUS_DEST_ALPHA, GL_DST_ALPHA. The source alpha value is always 1.0, so t he blend funct ion sim plifies t o t he following: finalColor.rgb = source.rgb * (1-dest.a) + dest.rgb * dest.a; finalColor.a = 1.0;

where source is t he RGBA value out put by t he fragm ent shader t hat render s t he ocean; dest is t he RGBA value present ly in t he fram ebuffer. Aft er a pixel is rendered, t he alpha value in t he fram ebuffer is set t o 1.0. When t he alpha com ponent of a pixel in t he fram ebuffer is 1.0, no furt her changes are m ade t o t hat pixel. This solves t he overdraw problem s due t o t he overlap areas, since only one change will be m ade t o each pixel. The wat er ripples are produced by 2D warping of t he reflect ion t ext ure m ap. For each pixel, a " ripple" t ext ure m ap is sam pled; t he R and G com ponent s of t he sam pled color pert urb t he read int o t he reflect ion t ext ure m ap, giving t he appearance of wat er ripples. At t he edges of t he screen, t his could lead t o t he sam ples m ade off t he edge of t he reflect ion t ext ur e m ap. Clam ping t he pert urbed t ext ure coordinat es t o [ 0,1] fixes t hat problem but sm ears effect s at t he edge of t he screen. A bet t er solut ion is t o render a reflect ion t ext ure m ap corresponding t o an area slight ly larger t han t he visible screen area. This provides a border region, so t he ripple offset is unlikely t o result in a t ext ure coordinat e out side t he [ 0,1] range, t hereby fixing t he sm earing problem .

20.6. Clouds Cloud light ing is dom inat ed by scat t ering t hat is sim ilar t o at m ospheric scat t ering, but m uch m ore com plex. Light is scat t ered by t he wat er vapor wit hin t he cloud. Low- densit y regions let m ost light t hrough; high- densit y regions absorb or scat t er m ost of t he light t hat passes t hrough. Som e real clouds are shown in t he phot o in Color Plat e 37D. These clouds are lit by vert ical sunlight . I n sim plist ic t erm s, t he light ing effect s can be explained as follows. Phot ons ent er t he cloud, and if t hey hit a wat er vapor m olecule, t hey are scat t ered in a random direct ion. Therefore, part s of cloud t hat are direct ly illum inat ed by t he sun are bright lot s of sunlight reaches t hem , so proport ionally m ore light is scat t ered t oward t he viewer. However, t he clouds are dense and so light cannot penet rat e far int o t he body of t he cloud; lit t le or no light reaches t he bot t om of t he clouds and so t hey are dark. For t he sam e reason, light from bright regions on t he far side of t he cloud body is blocked. At t he fr inges of t he clouds, t he clouds are less dense. So, sunlight scat t ered from t hose regions t oward t he eye is not com plet ely blocked. For t his reason, t he edges of clouds t end t o be bright . Figure 20.11 illust r at es t his effect . The cloud edge is light gray where t he sunlight st rikes; t hese are t he bright areas. Light is scat t ered in all direct ions but is absorbed by t he cloud body, depending how far it t ravels t hrough t he cloud and how dense t he cloud is.

Figu r e 2 0 .1 1 . Su n ligh t st r ik in g a clou d

The clouds in RealWorldz sim ulat e som e of t hese effect s. Color Plat e 37G dem onst rat es t he selfshadowingt he darkening is m uch m ore subt le t han it is in t he phot ograph of r eal clouds. Color Plat e 37H dem onst rat es t he edge light ing. I n RealWorldz, t he clouds and sm oke are render ed w it h a collect ion of 16 different billboard im ages generat ed by ray- m arching a 3D m onofract al. For each t exel of t he billboard im age, an opacit y and surface norm al were generat ed. The alpha and color channels for a single billboard

im age ar e shown in Color Plat e 37F. The upper im age is t he alpha channel; it st or es t he opacit y. Black is 0, indicat ing com plet e t ransparency; whit e is 1.0, indicat ing com plet e opacit y. The lower im age is t he RGB color channel holding t he packed norm al. The norm al is unpacked in t he usual waysubt ract ion of 0.5 and m ult iplicat ion by 2.0. The opacit y was calculat ed by num erical int egrat ion of t he ray t hrough t he 3D m onofract al. The surface norm al was est ablished by det erm inat ion of t he point at which t he ray int egral rose above a cert ain ( sm all) value; corresponding point s were found for rays in slight ly different direct ions and a plane fit t ed t o t hose point s. The surface norm al was defined t o be norm al t o t hat plane. The surface norm al is used t o est im at e whet her t he pixel is facing t he sun; t his provides t he bright ening of regions facing t he sun and t he self- shadowing effect . The opacit y det erm ines how m uch t he cloudlet occludes obj ect s behind it t he cloudlet s are draw n in far - t o- near order, so near cloudlet s occlude m ore dist ant cloudlet s. The fragm ent shader code t o calculat e t he color and alpha of t he cloudlet is given here. cloudletNormal is t he unpacked norm al vect or; cloudletOpacity is t he opacit y. cloudletLightDir is t he sunlight vect or, t ransform ed int o t he space in which t he cloudlet norm als are st ored. alphaScalar is a value in t he range [ 0,1] provided by t he vert ex shader: Norm ally it is 1.0, but 0 m akes t he cloudlet com plet ely t ransparent . float d = 0.95 +(dot(cloudletLightDir, screenLightDir) * 0.3 * cloudletOpacity); vec3 baseCloudColor = vec3(1.0, 0.93, 0.9); gl_FragColor.rgb = d * baseCloudColor; gl_FragColor.a = cloudletOpacity * alphaScalar;

Cloudlet s t hat are t oo near or t oo far from t he viewer are not drawn. So t hat cloudlet s do not abrupt ly disappear when t hey leave t he visible range, t hey becom e progressively m ore t ransparent as t hey near t he boundar ies of t he visible region. This fadeout is im plem ent ed by t he vert ex shader calculat ing t he cloudlet dist ance; alphaScalar t akes t he value 0 if t he cloudlet is at t he boundaries of t he visible region, rising t o 1.0 in t he int erior of t he visible region.

20.7. Summary The RealWorldz proj ect allowed us t o push t he st at e- of- t he- art for cont rolling graphics hardw are t hrough a high- level shading language. RealWorldz was dem onst rat ed at SI GGRAPH 2004, running at int eract ive rat es on 3Dlabs Wildcat Realizm hardware wit h all t he feat ures described in t his chapt er. Fut ure hardware will m ake possible im proved fr am e rat es and increasingly com plex effect s. Text ures are heavily used in RealWorldz, but t hey are used in unique ways as t he basis for t he m at hem at ics necessary t o achieve a variet y of effect s. They also provide an avenue for t he inclusion of art ist s in t he planet design process. A planet m ay be defined by 50100 m egabyt es of t hese basis t ext ures. This dat a is am plified procedurally at runt im e t o t he point t hat several t erabyt es of dat a would be required t o prerender t he planet . Every aspect of a planet can be m odified, wit h real- t im e cont rols for waves, plant s, clouds, at m ospheric densit y, and sea level. Light ing calculat ions are done per pixel in real t im e. Planet s are rendered w it h 20 or m ore shaders, w hich m ay have m ore t han a hundred uniform variables. Som e of t hese shaders are several hundred source lines long, yet st ill run wit h accept able perform ance. The RealWorldz dem o w as m ade possible by t he advent of high- perform ance program m able graphics hardware w hich has, quit e lit erally, opened up new worlds for us t o explore.

20.8. Further Information The RealWorldz dem o is available upon request from 3Dlabs. The Pandrom eda Web sit e cont ains a large gallery of im ages and m ovies m ade wit h Moj oWorld, a progr am t hat facilit at es t he cr eat ion and explorat ion of very high qualit y fract al worlds. A free t rial version of Moj oWorld is available. Ken Musgrave discusses som e of t he concept s behind Moj oWorld in Text uring and Modeling: A Procedural Approach. Voronoi ( cellular) noise is described by St even Worley in his 1996 SI GGRAPH paper, A Cellular Text ure Basis Funct ion. See also t he references at t he end of Chapt er 15 for m ore inform at ion about noise funct ions. 1 . 3Dlabs developer Web sit e. ht t p: / / developer.3dlabs.com 2 . Ebert , David S., John Hart , Bill Mark, F. Kent on Musgrave, Darwyn Peachey, Ken Perlin, and St even Worley, Text uring and Modeling: A Procedural Approach, Thir d Edit ion, Morgan Kaufm ann Publishers, San Francisco, 2002. ht t p: / / w ww .t ext uringandm odeling.com 3 . Glaeser, Georg, Reflect ions on Spheres and Cylinders of Revolut ion, Journal for Geom et ry and Graphics, Volum e 3 ( 1999) , No. 2, pp. 121139. ht t p: / / w ww .helderm annverlag.de/ j gg/ j gg01_05/ j gg0312.pdf 4 . Hoffm an, Nat haniel, and A. Preet ham , Render ing Out door Light Scat t ering in Real Tim e, Gam e Developers Conference 2002. ht t p: / / w ww .at i.com / developer/ dx9/ ATI Light Scat t ering.pdf 5 . Nishit a, Tom oyuki, Takao Sirai, Kat sum i Tadam ura, and Eihachir o Nakam ae, Display of t he Eart h Taking int o Account At m ospheric Scat t ering, Com put er Graphics ( SI GGRAPH '93 Proceedings) , pp. 175182, August 1993. ht t p: / / nis- lab.is.s.ut okyo.ac.j p/ ~ nis/ abs_sig.ht m l# sig93 6 . Pandrom eda Web sit e. ht t p: / / www.pandrom eda.com 7 . Worley, St even, A Cellular Text ure Basis Funct ion, Com put er Graphics ( SI GGRAPH '96 Proceedings) , pp. 291294, August 1996.

Chapter 21. Language Comparison The OpenGL Shading Language is by no m eans t he first gr aphics shading language ever defined. Here are a few ot her not able shading languages and a lit t le about how each one com pares t o t he OpenGL Shading Language. Com pare t he diagram s in t his chapt er w it h t he OpenGL Shading Language execut ion m odel in Figur e 2.4 for a visual sum m ary.

21.1. Chronology of Shading Languages Rob Cook and Ken Perlin are usually credit ed wit h being t he first t o develop languages t o describe shading calculat ions. Bot h of t hese effort s t arget ed offline ( nonint eract ive) rendering syst em s. Perlin's w ork included t he definit ion of t he noise funct ion and t he int roduct ion of cont rol const ruct s. Cook's work on shade t rees at Lucasfilm ( lat er Pixar) int roduced t he classificat ion of shaders as surface shaders, light shaders, at m osphere shaders, and so on, and t he abilit y t o describe t he operat ion of each t hrough an expression. This work evolved int o t he effort t o develop a full- feat ured language for describing shading calculat ions, which was t aken up by Pat Hanrahan and culm inat ed in t he 1988 release of t he first version of t he Render Man I nt erface Specificat ion by Pixar. Subsequent ly, RenderMan becam e t he de fact o indust ryst andard shading language for offline rendering syst em s for t he ent ert ainm ent indust ry. I t rem ains in widespread use t oday. The first int eract ive shading language was dem onst rat ed at t he Universit y of Nort h Car olina on a m assively parallel graphics archit ect ure called PixelFlow t hat was developed over t he decade of t he 1990s. The shading language used on PixelFlow could render scenes wit h procedural shading at 30 fram es per second or m or e. The shading language com ponent of t his syst em w as described by Marc Olano in 1998. Aft er leaving UNC, Olano j oined a t eam at SGI t hat was defining and im plem ent ing an int eract ive shading language t hat would run on t op of OpenGL and use m ult ipass rendering m et hods t o execut e t he shaders. This work culm inat ed in t he release in 2000 of a product from SGI called OpenGL Shader, t he first com m ercially available real- t im e, high- level shading language. I n June 1999, t he Com put er Graphics Laborat ory at St anford em barked on an effort t o define a real- t im e shading language t hat could be accelerat ed by exist ing consum er graphics hardware. This language was called t he St anford Real- Tim e Shading Language. Result s of t his syst em were dem onst rat ed in 2001. The OpenGL Shading Language, Microsoft 's HLSL, and NVI DI A's Cg are all effort s t o define a com m ercially viable, real- t im e, high- level shading language. The whit e paper t hat first described t he shading language t hat would becom e t he OpenGL Shading Language was published in Oct ober 2001 by Dave Baldwin of 3Dlabs. NVI DI A's Cg specificat ion was published in June of 2002, and Microsoft 's HLSL specificat ion was published in Novem ber 2002, as part of t he bet a release of t he Direct X 9.0 Soft ware Developm ent Kit . Som e cross- pollinat ion of ideas occurred am ong t hese t hree effort s because of t he int errelat ionships of t he com panies involved. I n subsequent sect ions, we com pare t he OpenGL Shading Language wit h ot her com m ercially available high- level shading languages.

21.2. RenderMan I n 1988, aft er several years of developm ent , Pixar published t he Render Man I nt erface Specificat ion. This was an int erface int ended t o define t he com m unicat ions pr ot ocol bet ween m odeling program s and rendering program s aim ed at producing im ages of phot orealist ic qualit y. The original t arget audience for t his int erface was anim at ion product ion, and t he int erface has proved t o be very successful for t his m arket . I t has been used as t he int erface for producing com put er graphics special effect s for film s such as Jurassic Park, St ar Wars Episode 1: The Phant om Menace, The Lord of t he Rings: The Tw o Tow ers, and ot her s. I t has also been used for film s t hat have been done ent irely wit h com put er graphics such as Finding Nem o, Toy St ory, A Bug's Life, and Monst er s, I nc. One of t he m ain differences bet w een t he OpenGL Shading Language and RenderMan is t hat RenderMan at t em pt s t o define t he ent ire int erface bet ween m odeling program s and rendering program s. I t provides an ent ire graphics pr ocessing pipeline of it s own t hat has no relat ionship t o OpenGL. Alt hough a hardware im plem ent at ion was envisioned at t he t im e RenderMan was first defined, it was prim arily designed as a high- qualit y, realist ic rendering int erface; t herefore, it pr ovides no com prom ises for int eract ivit y or direct hardware im plem ent at ion on t oday's graphics hardware. RenderMan includes support for describing geom et r ic prim it ives, hierarchical m odeling, st acking geom et ric t ransform at ions, cam era at t ribut es, shading at t ribut es, and const ruct ive solid geom et ry. OpenGL already pr ovides m any of t hese capabilit ies; t herefore, t hey need not be addressed in t he OpenGL Shading Language.

Figu r e 2 1 .1 . Re n de r M a n e x e cu t ion e n vir on m e n t

Of part icular int erest , how ever, is t he port ion of RenderMan called t he RenderMan Shading Language. This language com plet ely describes ar bit rary shaders t hat can be passed t o a renderer t hrough t he RenderMan int erface. This language was also based on C, and as such, it bears som e resem blance t o t he OpenGL Shading Language. I n a general way, t he RenderMan int erface is sim ilar t o OpenGL, and t he RenderMan Shading Language is sim ilar t o t he OpenGL Shading Language. The RenderMan int erface and OpenGL bot h let you define t he charact erist ics of a scene ( viewing param et ers, pr im it ives t o be render ed, et c.) . Bot h shading languages com put e t he color, posit ion, opacit y, and ot her charact erist ics of a point in t he scene. One of t he m ain differences bet w een t he OpenGL Shading Language and t he RenderMan Shading Language is in t he abst ract ion of t he shading problem . The OpenGL Shading Language closely m aps ont o t oday's com m ercial graphics hardware and has abst ract ed t w o t ypes of shaders so far: ver t ex shader s and fragm ent shaders. The RenderMan Shading Language has alw ays had uncom prom ising im age qualit y as it s fundam ent al goal, and it abst ract s five shader t ypes: light shaders, displacem ent shaders, surface shaders, volum e shaders, and im ager shaders. The RenderMan shader t ypes lend t hem selves t o t he im plem ent at ion of high- qualit y soft ware rendering im plem ent at ions, but t hey do not m at ch up as well wit h hardware t hat has been designed t o support int eract ive rendering wit h OpenGL. As a result , RenderMan im plem ent at ions have t ypically been soft ware based, but at t em pt s t o accelerat e it in hardware have been m ade ( read I nt eract ive Mult i- Pass Program m able Shading by Peercy, Olano, Airey, and Ungar, 2000) . The OpenGL Shading Language was designed from t he beginning for accelerat ion by com m odit y graphics hardware. There are som e differences in t he dat a t ypes support ed by t he t wo languages. RenderMan support s nat ive t ypes t hat repr esent colors, point s, and norm als, whereas t he OpenGL Shading Language includes t he m or e gener ic vect ors of 1, 2, 3, or 4 float ing- point values t hat can support any of t hose. RenderMan goes a bit furt her in m aking t he language graphics- specific by including built - in support for coordinat e spaces nam ed obj ect , world, cam era, NDC, rast er , and screen. Render Man support s a num ber of predefined surface shader variables, light source variables, volum e shader variables, displacem ent shader variables, and im ager shader variables. The OpenGL Shading Language cont ains built - in variables t hat are specific t o OpenGL st at e values, som e of which are sim ilar t o t he RenderMan predefined variables. Because it is aim ed at producing anim at ion, RenderMan also has built - in variables t o represent t im e. The OpenGL Shading Language does not , but such values can be passed t o shaders t hrough uniform variables t o accom plish t he sam e t hing. On t he ot her hand, t he t w o languages have m uch in com m on. I n a very real sense, t he OpenGL Shading Language can be t hought of as a descendant of t he RenderMan Shading Language. The dat a t ype qualifiers u n ifor m and va r yin g were invent ed in RenderMan and have been carr ied forw ard t o m ean t he sam e t hings in t he OpenGL Shading Language. Expressions and precedence of operat ors in bot h languages are very m uch like C. Keywords such as if , e lse , w h ile , for , br e a k , and r e t u r n are t he sam e in bot h languages. The list of built - in m at h funct ions for t he OpenGL Shading Language is largely sim ilar t o t he list of built - in m at h funct ions for t he RenderMan Shading Language.

21.3. OpenGL Shader (ISL) OpenGL Shader was a soft ware package developed by SGI and released in 2000. I t was available as a com m ercial product for several years, but is no longer available. OpenGL Shader defined bot h a shading language ( I nt eract ive Shading Language, or I SL) and a set of API calls t hat defined shaders and used t hem in t he rendering process. The fundam ent al prem ise of OpenGL Shader w as t hat t he OpenGL API could be used as an assem bly language for execut ing program m able shaders ( see Figure 21.2) . Hardwar e w it h m ore feat ures ( e.g., m ult it ext ure and fragm ent program m abilit y) could be viewed as having a m ore powerful assem bly language. A sequence of st at em ent s in an I SL shader could end up being t ranslat ed int o one or m ore rendering passes. Each pass could be a geom et ry pass ( geom et ry is drawn t o use vert ex, rast erizat ion, and fr agm ent operat ions) , a copy pass ( a region of t he fram ebuffer is copied back int o t he sam e place in t he fram ebuffer t o use pixel, rast erizat ion, and fragm ent operat ions) , or a copy t ext ure pass ( a region of t he fram ebuffer is copied t o a t ext ure t o use pixel operat ions) . Com piler opt im izat ion t echnology det erm ined t he t ype of pass required t o execut e a sequence of source code inst ruct ions and, if possible, t o reduce t he num ber of passes needed overall. The final version of OpenGL Shader was opt im ized for m ult iple hardware back ends and could exploit t he feat ures exposed on a part icular plat form t o reduce t he num ber of passes requir ed.

Figu r e 2 1 .2 . Ope n GL Sh a de r ( I SL) e x e cu t ion e n vir on m e n t

Like every ot her shading language w ort h it s salt , I SL is based on C. However, because of it s fundam ent al prem ise, I SL shaders end up looking quit e different from OpenGL shaders. Many of t he inst ruct ions in an I SL shader end up look like direct ives t o perform a rendering pass. For exam ple, consider t he follow ing I SL source code: varying color b; FB = diffuse(); FB *= color(.5, .2, 0, 1); b = FB; FB = specular(30.0); FB += b;

The ident ifier FB specifies a result t o be st ored in t he fram e buffer. This sequence of operat ions first calls a subshader t hat execut es a light shader t o com put e a diffuse color for t he geom et ry being rendered. This value is m ult iplied by t he color value ( .5, .2, 0, 1) , and t he result is t hen st ored in a region of t ext ure m em ory called b. A specular reflect ion calculat ion is perform ed next , and finally t he diffuse com ponent and specular com ponent s are added t oget her. Alt hough it has t he appearance of requiring m ult iple passes, t his sequence of inst ruct ions can act ually be execut ed in a single pass on a num ber of different graphics accelerat ors.

I SL support s surface and light shaders, which are m erged and com piled. I n t his regard, it is m ore sim ilar t o t he RenderMan way of doing t hings t han it is t o t he OpenGL dist inct ion of vert ex and fragm ent shaders. Anot her difference bet ween t he OpenGL Shading Language and I SL is t hat I SL was designed t o provide port abilit y for int eract ive shading by m eans of t he OpenGL capabilit ies of bot h past and current hardware, whereas t he OpenGL Shading Language was designed t o expose t he program m abilit y of current and fut ure hardw are. The OpenGL Shading Language is not int ended for hardware w it hout a significant degree of program m abilit y, but I SL execut es shaders wit h t he ident ical visual effect on a variet y of hardware, including hardware wit h lit t le or no explicit support for pr ogram m abilit y. Yet anot her difference bet w een I SL and t he OpenGL Shading Language is t hat I SL was designed wit h t he const raint s of using t he OpenGL API as an assem bly language, wit hout requir ing any changes in t he underlying hardware. The OpenGL Shading Language was designed t o define new capabilit ies for t he underlying hardware, and so it support s a m ore nat ural synt ax for expressing graphics algorit hm s. The high- level language defined by t he OpenGL Shading Language can be t ranslat ed int o t he m achine code nat ive t o t he graphics hardware wit h an opt im izing com piler writ t en by t he graphics hardware vendor.

21.4. HLSL HLSL st ands for High- Level Shader Language, and it was defined by Microsoft and int roduced wit h Direct X 9 in 2002. I n t erm s of it s synt ax and funct ionalit y, HLSL is m uch closer t o t he OpenGL Shading Language t han eit her RenderMan or I SL. HLSL support s t he paradigm of program m abilit y at t he vert ex level and at t he fragm ent level j ust as in t he OpenGL Shading Language. An HLSL vert ex shader corresponds t o an OpenGL vert ex shader, and an HLSL pixel shader corresponds t o an OpenGL fragm ent shader. One of t he m ain differences bet w een t he OpenGL Shading Language and HLSL is in t he execut ion environm ent ( see Figure 21.3) . The HLSL com piler is really a t ranslat or t hat lives out side Direct X in t he sense t hat HLSL pr ogram s are never sent direct ly t o t he Direct X 9 API for execut ion. I nst ead, t he HLSL com piler t ranslat es HLSL source int o assem bly- level source or binary program s called vert ex shaders and pixel shaders ( in Microsoft Direct X parlance) . Various levels of funct ionalit y have been defined for t hese assem bly level shaders, and t hey are different iat ed by a version num ber ( e.g., Vert ex Shader 1.0, 2.0, 3.0; Pixel Shader 1.1, 1.4, 2.0, 3.0) .

Figu r e 2 1 .3 . Ex e cu t ion e n vir on m e n t for M icr osoft 's H LSL

One advant age of t his appr oach is t hat HLSL program s can be t ranslat ed offline, or long before t he applicat ion is act ually execut ed. However, t he t ranslat ion is done t o a binary represent at ion of assem bly code. This binary represent at ion m ay st ill need t o be t ranslat ed t o nat ive m achine code at execut ion t im e. This is in cont rast t o t he OpenGL Shading Language m odel, in which t he com piler is part of t he driver, and t he graphics har dw are vendor w rit es t he com piler. Giving t he graphics hardware vendor t he responsibilit y of t ranslat ing fr om high- level shading language source t o m achine code grant s t hese vendors a lot of room for shader opt im izat ion and archit ect ural innovat ion. HLSL is designed t o m ake it easier for applicat ion developers t o deal wit h t he various levels of funct ionalit y found in t hese assem bly- level shaders. Using HLSL and t he support environm ent t hat has been built around it , applicat ion developers can writ e shaders in a high- level shading language and be reasonably confident t hat t heir shaders w ill run on hardw are wit h widely varying capabilit ies. However, because HLSL is m ore expressive t han t he capabilit ies of graphics hardware t hat exist s t oday and m uch m ore expressive t han hardware shipped in t he past , HLSL shader s are not guarant eed t o run on every plat form . Shader writ ers have t w o choices: They can writ e t heir

shader for t he lowest com m on denom inat or ( i.e., hardware w it h very lit t le program m abilit y) , or t hey can t arget t heir shader at a cert ain class of hardw are by using a language feat ure called profiles. Microsoft provides support ing soft ware called t he Direct X Effect s Fr am ework t o help developers or ganize and deploy a set of shaders t hat do t he sam e t hing for hardware wit h differing capabilit ies. The fundam ent al dat a t ypes in HLSL are t he sam e as t hose in t he OpenGL Shading Language except for slight nam ing differences. HLSL also support s half- and double- precision float s. Like t he OpenGL Shading Language, HLSL accom m odat es vect ors, m at rices, st ruct ures, and arrays. Expr essions in HLSL are as in C/ C+ + . User- defined funct ions and condit ionals are support ed in t he sam e m anner as in t he OpenGL Shading Language. Looping const ruct s ( for , do, and w h ile ) are defined in HLSL, but t he current docum ent at ion st at es t hat t hey are not yet im plem ent ed. HLSL has a longer list of built - in funct ions t han does t he OpenGL Shading Language, but t hose t hat are in bot h languages are very sim ilar or ident ical. One area of difference is t he way in w hich values are passed bet w een vert ex shaders and pixel ( HLSL) or fragm ent ( OpenGL Shading Language) shaders. HLSL defines bot h input sem ant ics and out put sem ant ics ( annot at ions t hat ident ify dat a usage) for bot h vert ex shader s and pixel shaders. This provides t he sam e funct ionalit y as t he OpenGL Shading Language varying and built - in variables. You are allowed t o pass arbit r ary dat a int o and out of vert ex and pixel shaders, but you m ust do so in nam ed locat ions such as POSITION, COLOR[i], TEXCOORD[i], and so on. This requirem ent m eans t hat you m ay have t o pass your light direct ion variable lightdir in a sem ant ic slot nam ed TEXCOORD[i], for inst ancea curious feat ure for a high- level language. The OpenGL Shading Language let s you use arbit rary nam es for passing values bet w een vert ex shaders and fragm ent shaders. Anot her obvious difference bet w een HLSL and t he OpenGL Shading Language is t hat HLSL was designed for Direct X, Microsoft 's propriet ary graphics API , and t he OpenGL Shading Language was designed for OpenGL. Microsoft can add t o and change Direct X, whereas OpenGL is an open, cr oss- plat form st andard t hat changes m ore slowly but ret ains com pat ibilit y wit h previous ver sions.

21.5. Cg Cg is a high- level shading language t hat is sim ilar t o HLSL. Cg has been defined, im plem ent ed, and support ed by NVI DI A. Com paring Cg t o t he OpenGL Shading Language is virt ually t he sam e as com paring HLSL t o t he OpenGL Shading Language. There ar e a few m inor differences bet w een Cg and HLSL ( for inst ance, HLSL has a double dat a t ype but Cg does not ) , but Cg and HLSL were developed by Microsoft and NVI DI A wor king t oget her , so t heir r esult ing product s are ver y sim ilar. One advant age t hat Cg has over bot h HLSL and t he OpenGL Shading Language is t hat t he Cg t ranslat or can generat e eit her Direct X vert ex shader/ pixel shader assem bly code or OpenGL vert ex/ fragm ent program ( assem bly- level) code. This provides t he pot ent ial for using Cg shaders in eit her t he Direct X environm ent or t he OpenGL environm ent ( see Figure 21.4) . However, it also requires t he applicat ion t o m ake calls t o a library pr ovided by NVI DI A t hat sit s bet w een t he applicat ion and t he underlying graphics API ( eit her OpenGL or Direct X) . This library is called t he Cg Runt im e library. For sim ple applicat ions, it can be a help in covering up t he lim it at ions of t he underlying driver ( for inst ance, it can cover up t he fact t hat a Direct X driver support s m ult iple versions of vert ex and pixel shaders and aut om at ically select s t he m ost appropriat e version t o use) . But t his int ervening layer can also com plicat e t hings for m ore com plicat ed applicat ions because it covers up det ails of shader m anagem ent .

Figu r e 2 1 .4 . Th e Cg e x e cu t ion e n vir on m e n t

NVI DI A has it s own version of t he fram ewor k t hat surrounds t he shading language. CgFX is a shader specificat ion and int erchange for m at w hose file form at is t he sam e as t hat support ed by t he .fx Effect form at for Direct X 9. The CgFX runt im e library, like t he Cg runt im e library, support s bot h OpenGL and Direct X, so in t his way t he Microsoft and NVI DI A product s differ. Because it is so sim ilar t o HLSL, t he advant ages and disadvant ages of Cg wit h respect t o t he OpenGL Shading Language are also sim ilar: propriet ary versus st andard ( t hus earlier t o m arket ) , support for less capable hardw are at t he cost of hardware dependencies in shader source code, t ranslat ion from high- level shading language t o " st andard" assem bly int erface offline versus a com piler em bedded in t he driver, a m ore com plet e shader developm ent syst em but wit h t he requirem ent of ext ra runt im e librar ies, and so on.

21.6. Summary Shading languages have been around for som e t im e now. The first shading languages were non- real- t im e languages aim ed at producing phot orealist ic im agery. Graphics hardware capable of support ing an int eract ive shading language showed up in research labs in t he 1990s, and t oday, t his t ype of program m able graphics hardware is available at consum er price point s. This has led t o t he developm ent of several com m ercially available shading languages, not ably, I SL, t he OpenGL Shading Language, HLSL, and Cg. I n t he spect r um of program m ing languages, t he last t hree are ext rem ely sim ilar. Each was designed t o provide funct ionalit y available in RenderMan by t he use of C/ C+ + as t he basis for t he language synt ax. The result is t hat all t hree languages are sim ilar in t erm s of synt ax and capabilit y. The single biggest t echnical difference is t hat HLSL and Cg sit on t op of st andard int erfaces such as Direct X and OpenGL and t ranslat e high- level source code t o assem bly out side t hose API s. The OpenGL Shading Language, on t he ot her hand, t ranslat es high- level sour ce code t o m achine code wit hin t he OpenGL driver. As far as nont echnical differences, t he HLSL and CG specificat ions are cont rolled by Microsoft and NVI DI A, respect ively. The OpenGL Shading Language is cont rolled by t he OpenGL ARB, a st andards body m ade up of represent at ives from a variet y of graphics hardw are and com put er m anufact urers. HLSL is designed for use in Microsoft 's Direct X environm ent , and t he OpenGL Shading Language is designed for use wit h OpenGL in a variet y of operat ing environm ent s. Cg is designed t o be used in eit her Direct X or OpenGL environm ent s.

21.7. Further Information The RenderMan Shading Language is specified in Pixar's The Render Man I nt erface Specificat ion ( 2000) , and it s use is described in t he books The Render Man Com panion: A Program m er's Guide t o Realist ic Com put er Graphics ( Upst ill 1990) and Advanced RenderMan: Creat ing CGI for Mot ion Pict ures ( Apodaca and Grit z 1999) . OpenGL Shader and I SL are described in t he SI GGRAPH 2000 paper I nt eract ive Mult i- Pass Program m able Shading. The book Real- Tim e Shading by Olano, Har t , Heidrich, and McCool ( 2002) cont ains chapt ers describing various shading languages, including RenderMan, I SL, and shading languages defined and im plem ent ed by researchers at t he Universit y of Nort h Carolina, St anford, and t he Universit y of Wat erloo. The St anford Real- Tim e Shading Language is described in t he SI GGRAPH 2001 paper, A RealTim e Procedural Shading Syst em for Program m able Graphics Hardware, and in t he course not es for Real- Tim e Shading, Course 24, SI GGRAPH 2001. There are sure t o be books out t hat describe Microsoft 's HLSL, but at t he t im e of t his writ ing, t he only docum ent at ion I could find is available from Microsoft on t he Direct X 9 page of it s Web sit e, ht t p: / / w ww .m icrosoft .com / direct x. A good st art ing point is I nt roduct ion t o t he Direct X 9 High- Level Shader Language by Craig Peeper and Jason Mit chell. This paper also appears as a chapt er in t he book ShaderX2: Shader Program m ing Tips and Tricks w it h Direct X 9.0 by Wolfgang Engel. Cg is described in docum ent at ion from NVI DI A in t he book The Cg Tut orial: The Definit ive Guide t o Program m able Real- Tim e Graphics by Fernando and Kilgard ( 2003) and in t he SI GGRAPH 2003 paper Cg: A Syst em for Program m ing Graphics Hardware in a C- like Language. The bibliography at t he end of t his book cont ains references t o ot her not able noncom m ercial shading languages. 1 . Apodaca, Ant hony A., and Larry Grit z, Advanced RenderMan: Creat ing CGI for Mot ion Pict ures, Morgan Kaufm ann Publishers, San Francisco, 1999. ht t p: / / w ww .r ender m an.org/ RMR/ Books/ arm an/ m at erials.ht m l 2 . Baldwin, Dave, OpenGL 2.0 Shading Language Whit e Paper, Version 1.0, 3Dlabs, Oct ober, 2001. 3 . Cook, Robert L., Shade Trees, Com put er Graphics ( SI GGRAPH '84 Proceedings) , pp. 223231, July 1984. 4 . Fernando, Randim a, and Mark Kilgard, The Cg Tut orial, t he Definit ive Guide t o Program m able Real- Tim e Graphics, Addison- Wesley, Bost on, Massachuset t s, 2003. 5 . Kessenich, John, Dave Baldwin, and Randi Rost , The OpenGL Shading Language, Version 1.10, 3Dlabs, April 2004. ht t p: / / w ww .opengl.org/ docum ent at ion/ spec.ht m l 6 . Mark, William R., Real- Tim e Shading: St anford Real- Tim e Procedural Shading Syst em , SI GGRAPH 2001, Course 24, course not es, 2001. ht t p: / / graphics.st anford.edu/ proj ect s/ shading/ pubs/ sigcourse2001.pdf 7 . Mark, William R., R. St even Glanville, Kurt Akeley, and Mark Kilgard, Cg: A Syst em for Program m ing Graphics Hardw are in a C- like Language, Com put er Graphics ( SI GGRAPH 2003 Proceedings) , pp. 896907, July 2003. ht t p: / / www.cs.ut exas.edu/ users/ billm ark/ papers/ Cg

8 . Microsoft , Direct X 9.0 SDK, 2003. ht t p: / / m sdn.m icrosoft .com / direct x 9 . NVI DI A Corporat ion, Cg Toolkit , Release 1.4, soft w are and docum ent at ion. ht t p: / / developer.nvidia.com / obj ect / cg_t oolkit .ht m l 1 0 . Olano, Marc, and Anselm o Last ra, A Shading Language on Gr aphics Har dw are: The PixelFlow Shading Syst em , Com put er Graphics ( SI GGRAPH '98 Proceedings) , pp. 159168, July 1998. ht t p: / / www.csee.um bc.edu/ ~ olano/ papers 1 1 . Olano, Marc, John Hart , Wolfgang Heidrich, and Michael McCool, Real- Tim e Shading, AK Pet ers, Lt d., Nat ick, Massachuset t s, 2002. 1 2 . Peeper, Craig, and Jason Mit chell, I nt roduct ion t o t he Direct X 9 High- Level Shader Language, in ShaderX2 : Shader Program m ing Tips and Tricks wit h Direct X 9.0, Edit or: Wolfgang Engel, Wordware Publishing, 2003. ht t p: / / www.at i.com / developer/ ShaderX2_I nt roduct ionToHLSL.pdf 1 3 . Peercy, Mark S., Marc Olano, John Airey, and P. Jeffrey Ungar, I nt eract ive Mult i- Pass Program m able Shading, Com put er Graphics ( SI GGRAPH 2000 Proceedings) , pp. 425432, July 2000. ht t p: / / www.csee.um bc.edu/ ~ olano/ papers 1 4 . Perlin, Ken, An I m age Synt hesizer , Com put er Graphics ( SI GGRAPH '85 Proceedings) , pp. 287296, July 1985. 1 5 . Pixar, The Render Man I nt erface Specificat ion, Version 3.2, Pixar, July 2000. ht t ps: / / renderm an.pixar.com / product s/ rispec/ index.ht m 1 6 . Proudfoot , Kekoa, William R. Mark, Sv et oslav Tzvet kov, and Pat Hanrahan, A Real- Tim e Procedural Shading Syst em for Pr ogram m able Graphics Hardware, Com put er Graphics ( SI GGRAPH 2001 Proceedings) , pp. 159170, August 2001. ht t p: / / graphics.st anford.edu/ proj ect s/ shading/ pubs/ sig2001 1 7 . SGI OpenGL Shader Web sit e. ht t p: / / www.sgi.com / soft ware/ shader ( defunct ) 1 8 . ShaderX2 : Shader Program m ing Tips and Tricks wit h Direct X 9.0, Edit or: Wolfgang Engel, Wordware Publishing, 2003. ht t p: / / w ww .shaderx2.com 1 9 . Upst ill, St eve, The Render Man Com panion: A Program m er's Guide t o Realist ic Com put er Graphics, Addison- Wesley, Reading, Massachuset t s, 1990.

Appendix A. Language Grammar The gr am m ar is fed from t he out put of lexical analysis. The t okens ret urned from lexical analysis are ATTRIBUTE CONST BOOL FLOAT INT BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 VEC2 VEC3 VEC4 MAT2 MAT3 MAT4 IN OUT INOUT UNIFORM VARYING SAMPLER1D SAMPLER2D SAMPLER3D SAMPLERCUBE SAMPLER1DSHADOW SAMPLER2DSHADOW STRUCT VOID WHILE IDENTIFIER TYPE_NAME FLOATCONSTANT INTCONSTANT BOOLCONSTANT FIELD_SELECTION LEFT_OP RIGHT_OP INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN MOD_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN SUB_ASSIGN LEFT_PAREN RIGHT_PAREN LEFT_BRACKET RIGHT_BRACKET LEFT_BRACE RIGHT_BRACE DOT COMMA COLON EQUAL SEMICOLON BANG DASH TILDE PLUS STAR SLASH PERCENT LEFT_ANGLE RIGHT_ANGLE VERTICAL_BAR CARET AMPERSAND QUESTION

The following describes t he gram m ar for t he OpenGL Shading Language in t erm s of t he preceding t okens. variable_ident ifier: I DENTI FI ER prim ary_expression: variable_ident ifier I NTCONSTANT FLOATCONSTANT BOOLCONSTANT LEFT_PAREN expression RI GHT_PAREN post fix_expression: prim ary_expression post fix_expression LEFT_BRACKET int eger_expr ession RI GHT_BRACKET funct ion_call post fix_expression DOT FI ELD_SELECTI ON

post fix_expression I NC_OP post fix_expression DEC_OP int eger_expression: expression funct ion_call: funct ion_call_generic funct ion_call_generic: funct ion_call_header_wit h_param et ers RI GHT_PAREN funct ion_call_header_no_param et ers RI GHT_PAREN funct ion_call_header_no_param et ers: funct ion_call_header VOI D funct ion_call_header funct ion_call_header_wit h_param et ers: funct ion_call_header assignm ent _expression funct ion_call_header_wit h_param et ers COMMA assignm ent _expression funct ion_call_header: funct ion_ident ifier LEFT_PAREN funct ion_ident ifier: const ruct or_ident ifier I DENTI FI ER / / Gram m ar Not e: Const ruct ors look like funct ions, but lexical analysis recognized m ost of t hem as keywords. const ruct or_ident ifier: FLOAT I NT BOOL VEC2 VEC3

VEC4 BVEC2 BVEC3 BVEC4 I VEC2 I VEC3 I VEC4 MAT2 MAT3 MAT4 TYPE_NAME unary_expression: post fix_expression I NC_OP unary_expression DEC_OP unary_expression unary_oper at or unary_expression / / Gram m ar Not e: No t radit ional st yle t ype cast s. unary_oper at or: PLUS DASH BANG TI LDE / / reser ved / / Gram m ar Not e: No '* ' or '&' unary ops. Point ers are not support ed. m ult iplicat ive_expression: unary_expression m ult iplicat ive_expression STAR unary_expression m ult iplicat ive_expression SLASH unary_expression m ult iplicat ive_expression PERCENT unary_expression / / reserved

addit ive_expression: m ult iplicat ive_expression addit ive_expression PLUS m ult iplicat ive_expression addit ive_expression DASH m ult iplicat ive_expression shift _expression: addit ive_expression shift _expression LEFT_OP addit ive_expression / / reserved shift _expression RI GHT_OP addit ive_expression / / reserved relat ional_expression: shift _expression relat ional_expression LEFT_ANGLE shift _expression relat ional_expression RI GHT_ANGLE shift _expression relat ional_expression LE_OP shift _expr ession relat ional_expression GE_OP shift _expression equalit y_expression: relat ional_expression equalit y_expression EQ_OP relat ional_expression equalit y_expression NE_OP relat ional_expression and_expression: equalit y_expression and_expression AMPERSAND equalit y_expression / / reserved exclusive_or_expression: and_expression exclusive_or_expression CARET and_expression / / reserved inclusive_or_expression: exclusive_or_expression inclusive_or_expression VERTI CAL_BAR exclusive_or_expression / / reserved logical_and_expression:

inclusive_or_expression logical_and_expression AND_OP inclusive_or_expression logical_xor_expression: logical_and_expression logical_xor_expression XOR_OP logical_and_expression logical_or_expression: logical_xor_expression logical_or_expression OR_OP logical_xor_expression condit ional_expr ession: logical_or_expression logical_or_expression QUESTI ON expression COLON assignm ent _expression assignm ent _expression: condit ional_expr ession unary_expression assignm ent _operat or assignm ent _expression assignm ent _operat or: EQUAL MUL_ASSI GN DI V_ASSI GN MOD_ASSI GN / / reserved ADD_ASSI GN SUB_ASSI GN LEFT_ASSI GN / / reserved RI GHT_ASSI GN / / reserved AND_ASSI GN / / reserved XOR_ASSI GN / / reserved OR_ASSI GN / / reserved expression: assignm ent _expression

expression COMMA assignm ent _expression const ant _expression: condit ional_expr ession declar at ion: funct ion_prot ot ype SEMI COLON init _declarat or_list SEMI COLON funct ion_prot ot ype: funct ion_declarat or RI GHT_PAREN funct ion_declarat or: funct ion_header funct ion_header_wit h_param et ers funct ion_header_wit h_param et ers: funct ion_header param et er_declarat ion funct ion_header_wit h_param et ers COMMA param et er_declarat ion funct ion_header: fully_specified_t ype I DENTI FI ER LEFT_PAREN par am et er_declarat or : t ype_specifier I DENTI FI ER t ype_specifier I DENTI FI ER LEFT_BRACKET const ant _expression RI GHT_BRACKET par am et er_declarat ion: t ype_qualifier param et er_qualifier param et er_declarat or param et er_qualifier param et er_declarat or t ype_qualifier param et er_qualifier param et er_t ype_specifier param et er_qualifier param et er_t ype_specifier par am et er_qualifier: / * em pt y * / IN OUT

I NOUT par am et er_t ype_specifier: t ype_specifier t ype_specifier LEFT_BRACKET const ant _expression RI GHT_BRACKET init _declarat or_list : single_declarat ion init _declarat or_list COMMA I DENTI FI ER init _declarat or_list COMMA I DENTI FI ER LEFT_BRACKET RI GHT_BRACKET init _declarat or_list COMMA I DENTI FI ER LEFT_BRACKET const ant _expression RI GHT_BRACKET init _declarat or_list COMMA I DENTI FI ER EQUAL init ializer single_declarat ion: fully_specified_t ype fully_specified_t ype I DENTI FI ER fully_specified_t ype I DENTI FI ER LEFT_BRACKET RI GHT_BRACKET fully_specified_t ype I DENTI FI ER LEFT_BRACKET const ant _expression RI GHT_BRACKET fully_specified_t ype I DENTI FI ER EQUAL init ializer / / Gram m ar Not e: No 'enum ' or 't ypedef'. fully_specified_t ype: t ype_specifier t ype_qualifier t ype_specifier t ype_qualifier: CONST ATTRI BUTE / / Vert ex only. VARYI NG UNI FORM t ype_specifier: VOI D

FLOAT I NT BOOL VEC2 VEC3 VEC4 BVEC2 BVEC3 BVEC4 I VEC2 I VEC3 I VEC4 MAT2 MAT3 MAT4 SAMPLER1D SAMPLER2D SAMPLER3D SAMPLERCUBE SAMPLER1DSHADOW SAMPLER2DSHADOW st ruct _specifier TYPE_NAME st ruct _specifier: STRUCT I DENTI FI ER LEFT_BRACE st ruct _declarat ion_list RI GHT_BRACE STRUCT LEFT_BRACE st ruct _declarat ion_list RI GHT_BRACE st ruct _declarat ion_list : st ruct _declarat ion

st ruct _declarat ion_list st ruct _declarat ion st ruct _declarat ion: t ype_specifier st ruct _declarat or_list SEMI COLON st ruct _declarat or_list : st ruct _declarat or st ruct _declarat or_list COMMA st ruct _declarat or st ruct _declarat or: I DENTI FI ER I DENTI FI ER LEFT_BRACKET const ant _expression RI GHT_BRACKET init ializer: assignm ent _expression declar at ion_st at em ent : declar at ion st at em ent : com pound_st at em ent sim ple_st at em ent / / Gram m ar Not e: No labeled st at em ent s; 'got o' is not support ed. sim ple_st at em ent : declar at ion_st at em ent expression_st at em ent select ion_st at em ent it erat ion_st at em ent j um p_st at em ent com pound_st at em ent : LEFT_BRACE RI GHT_BRACE LEFT_BRACE st at em ent _list RI GHT_BRACE st at em ent _no_new _scope: com pound_st at em ent _no_new_scope

sim ple_st at em ent com pound_st at em ent _no_new_scope: LEFT_BRACE RI GHT_BRACE LEFT_BRACE st at em ent _list RI GHT_BRACE st at em ent _list : st at em ent st at em ent _list st at em ent expression_st at em ent : SEMI COLON expression SEMI COLON select ion_st at em ent : I F LEFT_PAREN expression RI GHT_PAREN select ion_rest _st at em ent select ion_rest _st at em ent : st at em ent ELSE st at em ent st at em ent / / Gram m ar Not e: No 'swit ch'. Swit ch st at em ent s not support ed. condit ion: expression fully_specified_t ype I DENTI FI ER EQUAL init ializer it erat ion_st at em ent : WHI LE LEFT_PAREN condit ion RI GHT_PAREN st at em ent _no_new_scope DO st at em ent WHI LE LEFT_PAREN expression RI GHT_PAREN SEMI COLON FOR LEFT_PAREN for_init _st at em ent for_rest _st at em ent RI GHT_PAREN st at em ent _no_new _scope for_init _st at em ent : expression_st at em ent declar at ion_st at em ent condit ionopt :

condit ion / * em pt y * / for_rest _st at em ent : condit ionopt SEMI COLON condit ionopt SEMI COLON expression j um p_st at em ent : CONTI NUE SEMI COLON BREAK SEMI COLON RETURN SEMI COLON RETURN expression SEMI COLON DI SCARD SEMI COLON / / Fr agm ent shader only. / / Gram m ar Not e: No 'got o'. Got os are not support ed. t ranslat ion_unit : ext er nal_declarat ion t ranslat ion_unit ext ernal_declarat ion ext er nal_declarat ion: funct ion_definit ion declar at ion funct ion_definit ion: funct ion_prot ot ype com pound_st at em ent _no_new_scope

Appendix B. API Function Reference This sect ion cont ains det ailed inform at ion on t he OpenGL com m ands t hat support t he creat ion, com pilat ion, linking, and usage of shaders w rit t en in t he OpenGL Shading Language, as well as t he OpenGL com m ands added t o provide generic vert ex at t ribut es and user - defined uniform variables t o such shaders. The reference pages in t his sect ion are copyright ed by 3Dlabs I nc., Lt d. © 20032005 and are reprint ed wit h perm ission.

Implementation-Dependent API Values for GLSL A num ber of new im plem ent at ion- dependent values have been defined in OpenGL 2.0 t o support t he requirem ent s of t he OpenGL Shading Language. Each value can be queried wit h one of t he variant s of glGet. GL_MAX_COMBI NED_TEXTURE_I MAGE_UNI TS Defines t he t ot al num ber of hardware unit s t hat can access t ext ure m aps from t he vert ex processor and t he fr agm ent processor com bined. The m inim um legal value is 2. GL_MAX_DRAW_BUFFERS Defines t he m axim um num ber of buffers t hat can be sim ult aneously writ t en int o from w it hin a fragm ent shader using t he special out put variable array gl_FragData. This const ant effect ively defines t he size of t he gl_FragData array. GL_MAX_FRAGMENT_UNI FORM_COMPONENTS Defines t he num ber of com ponent s ( i.e., float ing- point values) t hat are available for fragm ent shader uniform variables. The m inim um legal value is 64. GL_MAX_TEXTURE_COORDS Defines t he num ber of t ext ure coordinat e set s t hat are available. The m inim um legal value is 2. GL_MAX_TEXTURE_I MAGE_UNI TS Defines t he t ot al num ber of hardware unit s t hat can access t ext ure m aps from t he fragm ent processor. The m inim um legal value is 2. GL_MAX_VARYI NG_FLOATS Defines t he num ber of float ing- point variables available for varying variables. The m inim um legal value is 32. GL_MAX_VERTEX_ATTRI BS Defines t he num ber of act ive vert ex at t ribut es t hat are available. The m inim um legal value is 16. GL_MAX_VERTEX_TEXTURE_I MAGE_UNI TS Defines t he num ber of hardwar e unit s t hat can access t ext ure m aps from t he vert ex processor. The m inim um legal value is 0. GL_MAX_VERTEX_UNI FORM_COMPONENTS Defines t he num ber of com ponent s ( i.e., float ing- point values) t hat are available for vert ex shader uniform variables. The m inim um legal value is 512.

Other Queriable Values for GLSL GL_CURRENT_PROGRAM Cont ains t he nam e of t he program obj ect t hat is current ly inst alled as part of current st at e. I f no program obj ect is act ive, t his value is 0. This value can be obt ained w it h one of t he variant s of glGet. GL_SHADI NG_LANGUAGE_VERSI ON Cont ains t he OpenGL Shading Language version t hat is support ed by t he im plem ent at ion. I t is organized as a dot - delim it ed sequence of m ult idigit int egers. This value can be obt ained w it h glGetString.

glAttachShader Name glAttachShader At t aches a shader obj ect t o a program obj ect

C Specification void glAttachShader(GLuint program, GLuint shader)

Parameters program

Specifies t he program obj ect t o w hich a shader obj ect w ill be at t ached.

shader

Specifies t he shader obj ect t hat is t o be at t ached.

Description For an execut able t o be cr eat ed, t here m ust be a way t o specify t he list of t hings t hat will be linked. Program obj ect s provide t his m echanism . Shaders t hat are t o be linked in a program obj ect m ust first be at t ached t o t hat program obj ect . glAttachShader at t aches t he shader obj ect specified by shader t o t he pr ogram obj ect specified by program. This signifies t hat shader will be included in link operat ions t hat will be perform ed on program. All operat ions t hat can be perform ed on a shader obj ect ar e valid w het her or not t he shader obj ect is at t ached t o a program obj ect . I t is perm issible t o at t ach a shader obj ect t o a program obj ect before source code has been loaded int o t he shader obj ect or befor e t he shader obj ect has been com piled. I t is perm issible t o at t ach m ult iple shader obj ect s of t he sam e t ype because each m ay cont ain a port ion of t he com plet e shader. I t is also perm issible t o at t ach a shader obj ect t o m ore t han one program obj ect . I f a shader obj ect is delet ed while it is at t ached t o a program obj ect , it is flagged for delet ion, and delet ion does not occur unt il glDetachShader is called t o det ach it from all program obj ect s t o which it is at t ached.

Notes glAttachShader is available only if t he GL version is 2.0 or great er.

Errors GL_I NVALI D_VALUE is generat ed if eit her program or shader is not a value generat ed by OpenGL. GL_I NVALI D_OPERATI ON is generat ed if program is not of t ype GL_PROGRAM_OBJECT. GL_I NVALI D_OPERATI ON is generat ed if shader is not of t ype GL_SHADER_OBJECT. GL_I NVALI D_OPERATI ON is generat ed if shader is already at t ached t o program. GL_I NVALI D_OPERATI ON is generat ed if glAttachShader is execut ed bet w een t he execut ion of

glBegin and t he corresponding execut ion of glEnd.

Associated Gets glGetAttachedShaders wit h t he handle of a valid pr ogram obj ect glIsProgram glIsShader

See Also glCompileShader, glDetachShader, glLinkProgram, glShaderSource

glBindAttribLocation Name glBindAttribLocation Associat es a generic vert ex at t r ibut e index wit h a nam ed at t ribut e variable

C Specification void glBindAttribLocation(GLuint program, GLuint index, const GLchar *name)

Parameters program

Specifies t he handle of t he program obj ect in which t he associat ion is t o be m ade.

index

Specifies t he index of t he generic vert ex at t ribut e t o be bound.

name

Specifies a null t erm inat ed st ring cont aining t he nam e of t he vert ex shader at t ribut e variable t o which index is t o be bound.

Description glBindAttribLocation associat es a user - defined at t ribut e variable in t he program obj ect specified by program wit h a generic vert ex at t ribut e index. The nam e of t he user- defined at t ribut e variable is passed as a null t erm inat ed st ring in name. The generic vert ex at t ribut e index t o be bound t o t his variable is specified by index. When program is m ade part of cur rent st at e, values provided t hrough t he generic vert ex at t ribut e index m odify t he value of t he user- defined at t ribut e var iable specified by name.

I f name refers t o a m at rix at t ribut e variable, index refers t o t he first colum n of t he m at rix. Ot her m at r ix colum ns are t hen aut om at ically bound t o locat ions index+1 for a m at rix of t ype m at 2; index+1 and index+2 for a m at rix of t ype m at 3; and index+1, index+2, and index+3 for a m at rix of t ype m at 4. This com m and m akes it possible for vert ex shaders t o use descript ive nam es for at t ribut e variables rat her t han generic variables t hat are num bered fr om 0 t o GL_MAX_VERTEX_ATTRI BS1. The values sent t o each generic at t ribut e index are part of current st at e, j ust like st andard vert ex at t ribut es such as color, norm al, and vert ex posit ion. I f a different program obj ect is m ade current by calling glUseProgram, t he generic vert ex at t ribut es are t racked in such a way t hat t he sam e values will be observed by at t ribut es in t he new program obj ect t hat are also bound t o index. At t ribut e var iable nam e- t o- gener ic at t ribut e index bindings for a program obj ect can be explicit ly assigned at any t im e wit h glBindAttribLocation. At t ribut e bindings do not go int o effect unt il glLinkProgram is called. Aft er a program obj ect has been linked successfully, t he index values for generic at t ribut es rem ain fixed ( and t heir values can be queried) unt il t he next link com m and occurs.

Applicat ions are not allowed t o bind any of t he st andard OpenGL vert ex at t ribut es wit h t his com m and, because t hey are bound aut om at ically when needed. Any at t ribut e binding t hat occurs aft er t he program obj ect has been linked does not t ake effect unt il t he next t im e t he program obj ect is linked.

Notes glBindAttribLocation is available only if t he GL version is 2.0 or great er. glBindAttribLocation can be called before any vert ex shader obj ect s are bound t o t he specified

program obj ect . I t is also perm issible t o bind a generic at t ribut e index t o an at t ribut e variable nam e t hat is never used in a vert ex shader. I f name was bound previously, t hat inform at ion is lost . Thus, you cannot bind one user - defined at t ribut e variable t o m ult iple indices, but you can bind m ult iple user- defined at t ribut e variables t o t he sam e index. Applicat ions are allowed t o bind m ore t han one user - defined at t ribut e var iable t o t he sam e generic vert ex at t ribut e index. This is called aliasing, and it is allowed only if j ust one of t he aliased at t r ibut es is act ive in t he execut able program , or if no pat h t hrough t he shader consum es m ore t han one at t ribut e of a set of at t ribut es aliased t o t he sam e locat ion. The com piler and linker are allowed t o assum e t hat no aliasing is done and are fr ee t o em ploy opt im izat ions t hat work only in t he absence of aliasing. OpenGL im plem ent at ions are not required t o do error checking t o det ect aliasing. Because t here is no way t o bind st andard at t ribut es, it is not possible t o alias generic at t ribut es wit h convent ional ones ( except for generic at t ribut e 0) . Act ive at t ribut es t hat are not explicit ly bound are bound by t he linker when glLinkProgram is called. The locat ions assigned can be queried wit h glGetAttribLocation. OpenGL copies t he name st ring when glBindAttribLocation is called, so an applicat ion can free it s copy of t he name st ring im m ediat ely aft er t he funct ion ret urns.

Errors GL_I NVALI D_VALUE is generat ed if index is great er t han or equal t o GL_MAX_VERTEX_ATTRI BS. GL_I NVALI D_OPERATI ON is generat ed if name st art s wit h t he reserved prefix " gl_" . GL_I NVALI D_VALUE is generat ed if program is not a value generat ed by OpenGL. GL_I NVALI D_OPERATI ON is generat ed if program is not of t ype GL_PROGRAM_OBJECT. GL_I NVALI D_OPERATI ON is generat ed if glBindAttribLocation is execut ed bet w een t he execut ion of glBegin and t he corresponding execut ion of glEnd.

Associated Gets glGet wit h argum ent GL_MAX_VERTEX_ATTRI BS glGetActiveAttrib wit h argum ent program glGetAttribLocation wit h argum ent s program and name glIsProgram

See Also glDisableVertexAttribArray, glEnableVertexAttribArray, glUseProgram, glVertex-Attrib, glVertexAttribPointer

glCompileShader Name glCompileShader Com piles a shader obj ect

C Specification void glCompileShader(GLuint shader)

Parameters shader

Specifies t he shader obj ect t o be com piled.

Description glCompileShader com piles t he source code st rings t hat have been st ored in t he shader obj ect specified by shader.

The com pilat ion st at us is st ored as part of t he shader obj ect 's st at e. This value is set t o GL_TRUE if t he shader was com piled wit hout errors and is ready for use, and GL_FALSE ot herwise. I t can be queried by calling glGetShader wit h argum ent s shader and GL_COMPI LE_STATUS. Com pilat ion of a shader can fail for a num ber of reasons, as specified by t he OpenGL Shading Language Specificat ion. Whet her or not t he com pilat ion was successful, inform at ion about t he com pilat ion can be obt ained from t he shader obj ect 's inform at ion log by calling glGetShaderInfoLog.

Notes glCompileShader is available only if t he GL version is 2.0 or great er.

Errors GL_I NVALI D_VALUE is generat ed if shader is not a value generat ed by OpenGL. GL_I NVALI D_OPERATI ON is generat ed if shader is not of t ype GL_SHADER_OBJECT. GL_I NVALI D_OPERATI ON is generat ed if glCompileShader is execut ed bet w een t he execut ion of glBegin and t he corresponding execut ion of glEnd.

Associated Gets glGetShaderInfoLog wit h argum ent shader glGetShader wit h argum ent s shader and GL_COMPI LE_STATUS glIsShader

See Also glCreateShader, glLinkProgram, glShaderSource

glCreateProgram Name glCreateProgram Creat es a pr ogram obj ect

C Specification GLuint glCreateProgram(void)

Description glCreateProgram creat es an em pt y program obj ect and ret urns a non- zero value by which it can be referenced. A program obj ect is an obj ect t o which shader obj ect s can be at t ached. This provides a m echanism t o specify t he shader obj ect s t hat will be linked t o creat e a pr ogram . I t also provides a m eans for checking t he com pat ibilit y of t he shaders t hat will be used t o creat e a program ( for inst ance, checking t he com pat ibilit y bet w een a vert ex shader and a fragm ent shader) . When no longer needed as part of a program obj ect , shader obj ect s can be det ached.

One or m ore execut ables are creat ed in a program obj ect by t hese act ions: successfully at t aching shader obj ect s t o t he program obj ect wit h glAttachShader, successfully com piling t he shader obj ect s wit h glCompileShader, and successfully linking t he program obj ect wit h glLinkProgram. These execut ables are m ade part of current st at e when glUseProgram is called. Program obj ect s can be delet ed wit h glDeleteProgram. The m em ory associat ed wit h t he program obj ect is delet ed when it is no longer part of cur rent rendering st at e for any cont ext .

Notes glCreateProgram is available only if t he GL version is 2.0 or great er.

Like display list s and t ext ure obj ect s, t he nam e space for program obj ect s m ay be shared acr oss a set of cont ext s, as long as t he server sides of t he cont ext s share t he sam e address space. I f t he nam e space is shared across cont ext s, any at t ached obj ect s and t he dat a associat ed wit h t hose at t ached obj ect s are shared as well. Applicat ions are responsible for synchronizing across API calls when obj ect s are accessed from different execut ion t hreads.

Errors This funct ion ret urns 0 if an error occurs creat ing t he pr ogram obj ect . GL_I NVALI D_OPERATI ON is generat ed if glCreateProgram is execut ed bet w een t he execut ion of glBegin and t he corresponding execut ion of glEnd.

Associated Gets glGet wit h t he argum ent GL_CURRENT_PROGRAM glGetActiveAttrib wit h a valid pr ogram obj ect and t he index of an act ive at t ribut e variable

glGetActiveUniform wit h a valid pr ogram obj ect and t he index of an act ive uniform variable glGetAttachedShaders wit h a valid pr ogram obj ect glGetAttribLocation wit h a valid pr ogram obj ect and t he nam e of an at t ribut e variable glGetProgram wit h a valid pr ogram obj ect and t he param et er t o be queried glGetProgramInfoLog wit h a valid pr ogram obj ect glGetUniform wit h a valid pr ogram obj ect and t he locat ion of a uniform variable glGetUniformLocation wit h a valid pr ogram obj ect and t he nam e of a uniform variable glIsProgram

See Also glAttachShader, glBindAttribLocation, glCreateShader, glDeleteProgram, glDetachShader, glLinkProgram, glUniform, glUseProgram, glValidateProgram

glCreateShader Name glCreateShader Creat es a shader obj ect

C Specification GLuint glCreateShader(GLenum shaderType)

Parameters shaderType

Specifies t he t ype of shader t o be creat ed. Must be eit her GL_VERTEX_SHADER or GL_FRAGMENT_SHADER.

Description glCreateShader creat es an em pt y shader obj ect and ret urns a non- zero value by which it can be referenced. A shader obj ect m aint ains t he source code st rings t hat define a shader. shaderType specifies t he t ype of shader t o be creat ed. Two t ypes of shaders ar e support ed. A shader of t ype GL_VERTEX_SHADER is a shader t hat is int ended t o run on t he pr ogram m able vert ex processor and replace t he fixed funct ionalit y vert ex processing in OpenGL. A shader of t ype GL_FRAGMENT_SHADER is a shader t hat is int ended t o run on t he program m able fragm ent processor and replace t he fixed funct ionalit y fragm ent processing in OpenGL.

When creat ed, a shader obj ect 's GL_SHADER_TYPE param et er is set t o eit her GL_VERTEX_SHADER or GL_FRAGMENT_SHADER, depending on t he value of shaderType.

Notes glCreateShader is available only if t he GL version is 2.0 or great er.

Like display list s and t ext ure obj ect s, t he nam e space for shader obj ect s m ay be shared across a set of cont ext s, as long as t he server sides of t he cont ext s share t he sam e addr ess space. I f t he nam e space is shared across cont ext s, any at t ached obj ect s and t he dat a associat ed wit h t hose at t ached obj ect s are shared as w ell. Applicat ions are responsible for providing t he synchronizat ion across API calls when obj ect s are accessed from different execut ion t hreads.

Errors This funct ion ret urns 0 if an error occurs creat ing t he shader obj ect . GL_I NVALI D_ENUM is generat ed if shaderType is not an accept ed value. GL_I NVALI D_OPERATI ON is generat ed if glCreateShader is execut ed bet w een t he execut ion of glBegin and t he corresponding execut ion of glEnd.

Associated Gets glGetShader wit h a valid shader obj ect and t he param et er t o be queried glGetShaderInfoLog wit h a valid shader obj ect glGetShaderSource wit h a valid shader obj ect glIsShader

See Also glAttachShader, glCompileShader, glCreateProgram, glDeleteShader, glDetachShader, glShaderSource

glDeleteProgram Name glDeleteProgram Delet es a pr ogram obj ect

C Specification void glDeleteProgram(GLuint program)

Parameters program

Specifies t he program obj ect t o be delet ed.

Description glDeleteProgram frees t he m em ory and invalidat es t he nam e associat ed wit h t he program obj ect specified by program. This com m and effect ively undoes t he effect s of a call t o glCreateProgram.

I f a pr ogram obj ect is in use as part of curr ent rendering st at e, it is flagged for delet ion but is not delet ed unt il it is no longer part of t he current st at e for any rendering cont ext . I f a program obj ect t o be delet ed has shader obj ect s at t ached t o it , t hose shader obj ect s are aut om at ically det ached but not delet ed unless t hey have already been flagged for delet ion by a previous call t o glDeleteShader. A value of 0 for program is silent ly ignored. To det erm ine whet her a program obj ect has been flagged for delet ion, call glGetProgram w it h argum ent s program and GL_DELETE_STATUS.

Notes glDeleteProgram is available only if t he GL version is 2.0 or great er.

Errors GL_I NVALI D_VALUE is generat ed if program is not a value generat ed by OpenGL. GL_I NVALI D_OPERATI ON is generat ed if glDeleteProgram is execut ed bet w een t he execut ion of glBegin and t he corresponding execut ion of glEnd.

Associated Gets glGet wit h argum ent GL_CURRENT_PROGRAM glGetProgram wit h argum ent s program and GL_DELETE_STATUS glIsProgram

See Also glCreateProgram, glCreateShader, glDetachShader, glUseProgram

glDeleteShader Name glDeleteShader Delet es a shader obj ect

C Specification void glDeleteShader(GLuint shader)

Parameters shader

Specifies t he shader obj ect t o be delet ed.

Description glDeleteShader frees t he m em ory and invalidat es t he nam e associat ed wit h t he shader obj ect specified by shader. This com m and effect ively undoes t he effect s of a call t o glCreateShader.

I f a shader obj ect t o be delet ed is at t ached t o a program obj ect , it is flagged for delet ion but is not delet ed unt il it is no longer at t ached t o any program obj ect , for any rendering cont ext ( i.e., it m ust be det ached from wherever it was at t ached before it can be delet ed) . A value of 0 for shader is silent ly ignored. To det erm ine whet her an obj ect has been flagged for delet ion, call glGetShader wit h argum ent s shader and GL_DELETE_STATUS.

Notes glDeleteShader is available only if t he GL version is 2.0 or great er.

Errors GL_I NVALI D_VALUE is generat ed if shader is not a value generat ed by OpenGL. GL_I NVALI D_OPERATI ON is generat ed if glDeleteShader is execut ed bet w een t he execut ion of glBegin and t he corresponding execut ion of glEnd.

Associated Gets glGetAttachedShaders wit h t he program obj ect t o be queried glGetShader wit h argum ent s shader and GL_DELETE_STATUS glIsShader

See Also glCreateProgram, glCreateShader, glDetachShader, glUseProgram

glDetachShader Name glDetachShader Det aches a shader obj ect from a program obj ect t o which it is at t ached

C Specification void glDetachShader(GLuint program, GLuint shader)

Parameters program

Specifies t he program obj ect from which t o det ach t he shader obj ect .

shader

Specifies t he shader obj ect t o be det ached.

Description glDetachShader det aches t he shader obj ect specified by shader from t he program obj ect specified by program. This com m and undoes t he effect of t he com m and glAttachShader.

I f shader has already been flagged for delet ion by a call t o glDeleteShader and it is not at t ached t o any ot her program obj ect , it is delet ed aft er it has been det ached.

Notes glDetachShader is available only if t he GL version is 2.0 or great er.

Errors GL_I NVALI D_VALUE is generat ed if eit her program or shader is a value t hat was not generat ed by OpenGL. GL_I NVALI D_OPERATI ON is generat ed if program is not a program obj ect . GL_I NVALI D_OPERATI ON is generat ed if shader is not a shader obj ect . GL_I NVALI D_OPERATI ON is generat ed if shader is not at t ached t o program. GL_I NVALI D_OPERATI ON is generat ed if glDetachShader is execut ed bet w een t he execut ion of glBegin and t he corresponding execut ion of glEnd.

Associated Gets glGetAttachedShaders wit h t he handle of a valid pr ogram obj ect glGetShader wit h argum ent s shader and GL_DELETE_STATUS

glIsProgram glIsShader

See Also glAttachShader

glDrawBuffers Name glDrawBuffers Specifies a list of color buffers t o be drawn int o

C Specification void glDrawBuffers(GLsizei n, const GLenum *bufs)

Parameters n

Specifies t he num ber of buffers in bufs.

bufs

Point s t o an array of sym bolic const ant s specifying t he buffers int o which fragm ent colors or dat a values will be writ t en.

Description glDrawBuffers defines an array of buffers int o which fr agm ent color values or fragm ent dat a will be writ t en. I f no fragm ent shader is act ive, rendering operat ions generat e only one fragm ent color per fragm ent and t hat fragm ent is writ t en int o each of t he buffers specified by bufs. I f a fragm ent shader is act ive and it w rit es a value t o t he out put variable gl_FragColor, t hen t hat value is writ t en int o each of t he buffers specified by bufs. I f a fr agm ent shader is act ive and it writ es a value t o one or m ore elem ent s of t he out put array var iable gl_FragData[], t hen t he value of gl_FragData[0] is writ t en int o t he first buffer specified by bufs, t he value of gl_FragData[1] is writ t en int o t he second buffer specified by bufs, and so on up t o gl_FragData[n-1]. The draw buffer used for gl_FragData[n] and beyond is im plicit ly set t o be GL_NONE.

The sym bolic const ant s cont ained in bufs m ay be any of t he following: GL_NONE The fragm ent color/ dat a value is not writ t en int o any color buffer. GL_FRONT_LEFT The fragm ent color/ dat a value is writ t en int o t he front - left color buffer. GL_FRONT_RI GHT The fragm ent color/ dat a value is writ t en int o t he front - right color buffer. GL_BACK_LEFT The fragm ent color/ dat a value is writ t en int o t he back- left color buffer. GL_BACK_RI GHT

The fragm ent color/ dat a value is writ t en int o t he back- right color buffer. GL_AUXi The fragm ent color/ dat a value is writ t en int o auxiliary buffer i. Except for GL_NONE, t he preceding sym bolic const ant s m ay not appear m ore t han once in bufs. The m axim um num ber of draw buffers support ed is im plem ent at ion dependent and can be queried by calling glGet wit h t he argum ent GL_MAX_DRAW_BUFFERS. The num ber of auxiliary buffers can be queried by calling glGet wit h t he argum ent GL_AUX_BUFFERS.

Notes glDrawBuffers is available only if t he GL version is 2.0 or great er.

I t is always t he case t hat GL_AUXi = GL_AUX0 + i. The sym bolic const ant s GL_FRONT, GL_BACK, GL_LEFT, GL_RI GHT, and GL_FRONT_AND_BACK are not allowed in t he bufs array since t hey m ay refer t o m ult iple buffers. I f a fragm ent shader writ es t o neit her gl_FragColor nor gl_FragData, t he values of t he fragm ent color s follow ing shader execut ion are undefined. For each fr agm ent generat ed in t his sit uat ion, a different value m ay be writ t en int o each of t he buffers specified by bufs.

Errors GL_I NVALI D_ENUM is generat ed if one of t he values in bufs is not an accept ed value. GL_I NVALI D_ENUM is generat ed if n is less t han 0. GL_I NVALI D_OPERATI ON is generat ed if a sym bolic const ant ot her t han GL_NONE appears m ore t han once in bufs. GL_I NVALI D_OPERATI ON is generat ed if any ent ry in bufs ( ot her t han GL_NONE) indicat es a color buffer t hat does not exist in t he current GL cont ext . GL_I NVALI D_VALUE is generat ed if n is great er t han GL_MAX_DRAW_BUFFERS. GL_I NVALI D_OPERATI ON is generat ed if glDrawBuffers is execut ed bet w een t he execut ion of glBegin and t he corresponding execut ion of glEnd.

Associated Gets glGet wit h argum ent GL_MAX_DRAW_BUFFERS glGet wit h argum ent GL_DRAW_BUFFERSi where i indicat es t he num ber of t he draw buffer

whose value is t o be queried

See Also glBlendFunc, glColorMask, glDrawBuffer, glIndexMask, glLogicOp, glReadBuffer

glEnableVertexAttribArray Name glEnableVertexAttribArray, glDisableVertexAttribArray Enable or disable a generic vert ex at t ribut e array

C Specification void glEnableVertexAttribArray(GLuint index) void glDisableVertexAttribArray(GLuint index)

Parameters index

Specifies t he index of t he generic vert ex at t ribut e t o be enabled or disabled.

Description glEnableVertexAttribArray enables t he gener ic vert ex at t ribut e array specified by index. glDisableVertexAttribArray disables t he generic vert ex at t r ibut e arr ay specified by index. By default ,

all client - side capabilit ies are disabled, including all generic vert ex at t r ibut e ar rays. I f enabled, t he values in t he generic vert ex at t r ibut e array are accessed and used for rendering w hen calls are m ade t o vert ex array com m ands such as glDrawArrays, glDrawElements, glDrawRangeElements, glArrayElement, glMultiDrawElements, or glMultiDrawArrays.

Notes glEnableVertexAttribArray and glDisableVertexAttribArray are available only if t he GL version is 2.0 or great er.

Errors GL_I NVALI D_VALUE is generat ed if index is great er t han or equal t o GL_MAX_VERTEX_ATTRI BS. GL_I NVALI D_OPERATI ON is generat ed if eit her glEnableVertexAttribArray or glDisableVertexAttribArray is execut ed bet ween t he execut ion of glBegin and t he corresponding execut ion of glEnd.

Associated Gets glGet wit h argum ent GL_MAX_VERTEX_ATTRI BS glGetVertexAttrib wit h argum ent s index and GL_VERTEX_ATTRI B_ARRAY_ENABLED glGetVertexAttribPointer wit h argum ent s index and GL_VERTEX_ATTRI B_ARRAY_POI NTER

See Also glArrayElement, glBindAttribLocation, glDrawArrays, glDrawElements, glDrawRangeElements, glMultiDrawArrays, glMultiDrawElements, glPopClientAttrib, glPushClientAttrib, glVertexAttrib, glVertexAttribPointer

glGetActiveAttrib Name glGetActiveAttrib Ret urns inform at ion about an act ive at t ribut e variable for t he specified program

obj ect

C Specification void glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)

Parameters program

Specifies t he program obj ect t o be queried.

index

Specifies t he index of t he at t ribut e variable t o be queried.

bufSize

Specifies t he m axim um num ber of charact ers OpenGL is allowed t o writ e in t he charact er buffer indicat ed by name.

length

Ret urns t he num ber of charact ers act ually writ t en by OpenGL in t he st ring indicat ed by name ( excluding t he null t erm inat or) if a value ot her t han NULL is passed.

size

Ret urns t he size of t he at t ribut e variable.

type

Ret urns t he dat a t ype of t he at t r ibut e variable.

name

Ret urns a null t erm inat ed st r ing cont aining t he nam e of t he at t ribut e variable.

Description glGetActiveAttrib ret urns inform at ion about an act ive at t r ibut e variable in t he progr am obj ect specified by program. The num ber of act ive at t ribut es can be obt ained by calling glGetProgram w it h t he value GL_ACTI VE_ATTRI BUTES. A value of 0 for index select s t he first act ive at t ribut e variable. Perm issible values for index range from 0 t o t he num ber of act ive at t ribut e variables

m inus 1. A vert ex shader m ay use built - in at t ribut e variables, user- defined at t ribut e variables, or bot h. Built - in at t ribut e variables have a prefix of " gl_" and reference convent ional OpenGL vert ex at t ribut es ( e.g., gl_Vertex, gl_Normal; see t he OpenGL Shading Language specificat ion for a com plet e list .) Userdefined at t ribut e variables have arbit rary nam es and obt ain t heir values t hrough num bered generic vert ex at t ribut es. An at t ribut e variable ( eit her built - in or userdefined) is considered act ive if during t he link operat ion, t he det erm inat ion is m ade t hat t he at t ribut e variable can be accessed during program execut ion. Therefore, program should have previously been t he t arget of a call t o glLinkProgram, but it is not necessary for it t o have been linked successfully.

The size of t he charact er buffer requir ed t o st ore t he longest at t ribut e var iable nam e in program can be obt ained by calling glGetProgram wit h t he value GL_ACTI VE_ATTRI BUTE_MAX_LENGTH. This value should be used t o allocat e a buffer of sufficient size t o st ore t he ret urned at t ribut e nam e. The size of t his charact er buffer is passed in bufSize, and a point er t o t his charact er buffer is passed in name. glGetActiveAttrib ret urns t he nam e of t he at t r ibut e variable indicat ed by index, st oring it in t he charact er buffer specified by name. The st ring ret urned is null t erm inat ed. The act ual num ber of charact ers writ t en int o t his buffer is ret urned in length, and t his count does not include t he null

t erm inat ion charact er. I f t he lengt h of t he ret ur ned st ring is not required, a value of NULL can be passed in t he length argum ent . The type argum ent ret ur ns a point er t o t he at t ribut e variable's dat a t ype. The sym bolic const ant s GL_FLOAT, GL_FLOAT_VEC2, GL_FLOAT_VEC3, GL_FLOAT_VEC4, GL_FLOAT_MAT2, GL_FLOAT_MAT3, GL_FLOAT_MAT4 m ay be ret urned. The size argum ent ret urns t he size of t he at t ribut e, in unit s of t he t ype ret urned in type. The list of act ive at t ribut e variables m ay include bot h built - in at t ribut e variables ( which begin wit h t he pr efix " gl_" ) as well as user - defined at t ribut e var iable nam es. This funct ion ret urns as m uch inform at ion as it can about t he specified act ive at t ribut e variable. I f no inform at ion is available, length is 0, and name is an em pt y st ring. This sit uat ion could occur if t his funct ion is called aft er a link operat ion t hat failed. I f an err or occurs, t he ret urn values length, size, type, and name are unm odified.

Notes glGetActiveAttrib is available only if t he GL version is 2.0 or great er.

Errors GL_I NVALI D_VALUE is generat ed if program is not a value generat ed by OpenGL. GL_I NVALI D_OPERATI ON is generat ed if program is not a program obj ect . GL_I NVALI D_VALUE is generat ed if index is great er t han or equal t o t he num ber of act ive at t ribut e variables in program. GL_I NVALI D_OPERATI ON is generat ed if glGetActiveAttrib is execut ed bet w een t he execut ion of glBegin and t he corresponding execut ion of glEnd. GL_I NVALI D_VALUE is generat ed if bufSize is less t han 0.

Associated Gets glGet wit h argum ent GL_MAX_VERTEX_ATTRI BS glGetProgram wit h argum ent GL_ACTI VE_ATTRI BUTES or GL_ACTI VE_ATTRI BUTE_MAX_LENGTH glIsProgram

See Also glBindAttribLocation, glLinkProgram, glVertexAttrib, glVertexAttribPointer

glGetActiveUniform Name glGetActiveUniform Ret urns inform at ion about an act ive uniform variable for t he specified program

obj ect

C Specification void glGetActiveUniform(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)

Parameters program

Specifies t he program obj ect t o be queried.

index

Specifies t he index of t he uniform variable t o be queried.

bufSize

Specifies t he m axim um num ber of charact ers OpenGL is allowed t o writ e in t he charact er buffer indicat ed by name.

length

Ret urns t he num ber of charact ers act ually writ t en by OpenGL in t he st ring indicat ed by name ( excluding t he null t erm inat or) if a value ot her t han NULL is passed.

size

Ret urns t he size of t he uniform variable.

type

Ret urns t he dat a t ype of t he uniform variable.

name

Ret urns a null t erm inat ed st r ing cont aining t he nam e of t he uniform variable.

Description glGetActiveUniform ret urns inform at ion about an act ive uniform variable in t he program obj ect specified by program. The num ber of act ive uniform variables can be obt ained by calling glGetProgram wit h t he value GL_ACTI VE_UNI FORMS. A value of 0 for index select s t he first act ive uniform variable. Perm issible values for index range from 0 t o t he num ber of act ive uniform

variables m inus 1. Shaders m ay use built - in uniform variables, user- defined uniform variables, or bot h. Built - in uniform variables have a prefix of " gl_" and reference exist ing OpenGL st at e or values derived from such st at e ( e.g., gl_Fog, gl_ModelViewMatrix; see t he OpenGL Shading Language specificat ion for a com plet e list .) User- defined uniform variables have arbit rary nam es and obt ain t heir values from t he applicat ion t hrough calls t o glUniform. A uniform variable ( eit her built - in or user defined) is considered act ive if during t he link operat ion, a det erm inat ion is m ade t hat t he uniform variable can be accessed during program execut ion. Therefore, program should have previously been t he t arget of a call t o glLinkProgram, but it is not necessary for it t o have been linked successfully.

The size of t he charact er buffer requir ed t o st ore t he longest uniform var iable nam e in program can be obt ained by calling glGetProgram w it h t he value GL_ACTI VE_UNI FORM_MAX_LENGTH. This value should be used t o allocat e a buffer of sufficient size t o st ore t he ret urned uniform variable nam e. The size of t his charact er buffer is passed in bufSize, and a point er t o t his charact er buffer is passed in name. glGetActiveUniform ret urns t he nam e of t he uniform variable indicat ed by index, st oring it in t he charact er buffer specified by name. The st ring ret urned is null t erm inat ed. The act ual num ber of charact ers writ t en int o t his buffer is ret urned in length, and t his count does not include t he null

t erm inat ion charact er. I f t he lengt h of t he ret ur ned st ring is not required, a value of NULL can be passed in t he length argum ent . The type argum ent ret urns a point er t o t he uniform variable's dat a t ype. The sym bolic const ant s GL_FLOAT, GL_FLOAT_VEC2, GL_FLOAT_VEC3, GL_FLOAT_VEC4, GL_I NT, GL_I NT_VEC2, GL_I NT_VEC3, GL_I NT_VEC4, GL_BOOL, GL_BOOL_VEC2, GL_BOOL_VEC3, GL_BOOL_VEC4, GL_FLOAT_MAT2, GL_FLOAT_MAT3, GL_FLOAT_MAT4, GL_SAMPLER_1D, GL_SAMPLER_2D, GL_SAMPLER_3D, GL_SAMPLER_CUBE, GL_SAMPLER_1D_SHADOW, or GL_SAMPLER_2D_SHADOW m ay be ret urned. I f one or m ore elem ent s of an array ar e act ive, t he nam e of t he array is ret urned in name, t he t ype is ret urned in type, and t he size param et er ret urns t he highest array elem ent index used, plus one, as det erm ined by t he com piler and/ or linker. Only one act ive uniform variable is report ed for a uniform array. Uniform variables t hat are declared as st ruct ures or arrays of st ruct ures are not ret urned direct ly by t his funct ion. I nst ead, each of t hese uniform variables is reduced t o it s fundam ent al com ponent s cont aining t he " ." and " [ ] " operat ors such t hat each of t he nam es is valid as an argum ent t o glGetUniformLocation. Each of t hese reduced uniform variables is count ed as one act ive uniform variable and is assigned an index. A valid nam e cannot be a st ruct ure, an array of st ruct ures, or a subcom ponent of a vect or or m at rix. The size of t he uniform variable is ret urned in size. Uniform variables ot her t han arrays have a size of 1. St ruct ur es and arrays of st ruct ures are reduced as descr ibed ear lier, such t hat each of t he nam es ret urned is a dat a t ype in t he earlier list . I f t his reduct ion result s in an array, t he size ret urned is as described for uniform arrays; ot herwise, t he size ret urned is 1. The list of act ive uniform variables m ay include bot h built - in uniform var iables ( which begin wit h t he pr efix " gl_" ) as well as user- defined uniform variable nam es. This funct ion ret urns as m uch inform at ion as it can about t he specified act ive uniform variable. I f no inform at ion is available, length is 0, and name is an em pt y st ring. This sit uat ion could occur if t his funct ion is called aft er a link operat ion t hat failed. I f an err or occurs, t he ret urn values length, size, type, and name are unm odified.

Notes glGetActiveUniform is available only if t he GL version is 2.0 or great er.

Errors GL_I NVALI D_VALUE is generat ed if program is not a value generat ed by OpenGL. GL_I NVALI D_OPERATI ON is generat ed if program is not a program obj ect . GL_I NVALI D_VALUE is generat ed if index is great er t han or equal t o t he num ber of act ive uniform variables in program.

GL_I NVALI D_OPERATI ON is generat ed if glGetActiveUniform is execut ed bet w een t he execut ion of glBegin and t he corresponding execut ion of glEnd. GL_I NVALI D_VALUE is generat ed if bufSize is less t han 0.

Associated Gets glGet wit h argum ent GL_MAX_VERTEX_UNI FORM_COMPONENTS or GL_MAX_FRAGMENT_UNI FORM_COMPONENTS glGetProgram wit h argum ent GL_ACTI VE_UNI FORMS or GL_ACTI VE_UNI FORM_MAX_LENGTH glIsProgram

See Also glGetUniform, glGetUniformLocation, glLinkProgram, glUniform, glUseProgram

glGetAttachedShaders Name glGetAttachedShaders Ret urns t he handles of t he shader obj ect s at t ached t o a program obj ect

C Specification void glGetAttachedShaders(GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders)

Parameters program

Specifies t he program obj ect t o be queried.

maxCount

Specifies t he size of t he array for st oring t he ret urned obj ect nam es.

count

Ret urns t he num ber of nam es act ually ret urned in objects.

shaders

Specifies an array t hat is used t o ret urn t he nam es of at t ached shader obj ect s.

Description glGetAttachedShaders ret urns t he nam es of t he shader obj ect s at t ached t o program. The nam es of shader obj ect s t hat are at t ached t o program are ret urned in shaders. The act ual num ber of shader nam es writ t en int o shaders is ret urned in count. I f no shader obj ect s are at t ached t o program, count is set t o 0. The m axim um num ber of shader nam es t hat m ay be ret urned in shaders is specified by maxCount.

I f t he num ber of nam es act ually ret ur ned is not requir ed ( for inst ance, if it has j ust been obt ained w it h glGetProgram) , a value of NULL m ay be passed for count . I f no shader obj ect s are at t ached t o program, a value of 0 is ret urned in count. The act ual num ber of at t ached shaders can be obt ained by calling glGetProgram wit h t he value GL_ATTACHED_SHADERS.

Notes glGetAttachedShaders is available only if t he GL version is 2.0 or great er.

Errors GL_I NVALI D_VALUE is generat ed if program is not a value generat ed by OpenGL. GL_I NVALI D_OPERATI ON is generat ed if program is not a program obj ect . GL_I NVALI D_VALUE is generat ed if maxCount is less t han 0. GL_I NVALI D_OPERATI ON is generat ed if glGetAttachedShaders is execut ed bet w een t he execut ion

of glBegin and t he corresponding execut ion of glEnd.

Associated Gets glGetProgram wit h argum ent GL_ATTACHED_SHADERS glIsProgram

See Also glAttachShader, glDetachShader

glGetAttribLocation Name glGetAttribLocation Ret urns t he locat ion of an at t ribut e variable

C Specification GLint glGetAttribLocation(GLuint program, const GLchar *name)

Parameters program

Specifies t he program obj ect t o be queried.

name

Point s t o a null t erm inat ed st ring cont aining t he nam e of t he at t ribut e variable whose locat ion is t o be queried.

Description glGetAttribLocation queries t he previously linked program obj ect specified by program for t he at t ribut e variable specified by name and ret urns t he index of t he generic vert ex at t ribut e t hat is bound t o t hat at t r ibut e variable. I f name is a m at rix at t ribut e variable, t he index of t he first colum n of t he m at rix is ret urned. I f t he nam ed at t ribut e variable is not an act ive at t ribut e in t he specified program obj ect or if name st art s wit h t he reserved prefix " gl_" , a value of - 1 is ret urned.

The associat ion bet ween an at t ribut e variable nam e and a generic at t ribut e index can be specified at any t im e wit h glBindAttribLocation. At t r ibut e bindings do not t ake effect unt il glLinkProgram is called. Aft er a program obj ect has been linked successfully, t he index values for at t ribut e variables rem ain fixed unt il t he next link com m and occurs. The at t ribut e bindings can be queried only aft er a link if t he link was successful. glGetAttribLocation ret urns t he binding t hat act ually went int o effect t he last t im e glLinkProgram was called for t he specified program obj ect . At t ribut e bindings t hat have been specified since t he last link operat ion are not ret urned by glGetAttribLocation.

Notes glGetAttribLocation is available only if t he GL version is 2.0 or great er.

Errors GL_I NVALI D_OPERATI ON is generat ed if program is not a value generat ed by OpenGL. GL_I NVALI D_OPERATI ON is generat ed if program is not a program obj ect . GL_I NVALI D_OPERATI ON is generat ed if program has not been successfully linked. GL_I NVALI D_OPERATI ON is generat ed if glGetAttribLocation is execut ed bet w een t he execut ion of glBegin and t he corresponding execut ion of glEnd.

Associated Gets glGetActiveAttrib wit h argum ent program and t he index of an act ive at t ribut e glIsProgram

See Also glBindAttribLocation, glLinkProgram, glVertexAttrib, glVertexAttribPointer

glGetProgram Name glGetProgramiv Ret urns a param et er from a program obj ect

C Specification void glGetProgramiv(GLuint program, GLenum pname, GLint *params)

Parameters program

Specifies t he program obj ect t o be queried.

pname

Specifies t he obj ect param et er. Accept ed sym bolic nam es are GL_DELETE_STATUS, GL_LI NK_STATUS, GL_VALI DATE_STATUS, GL_I NFO_LOG_LENGTH, GL_ATTACHED_SHADERS, GL_ACTI VE_ATTRI BUTES, GL_ACTI VE_ATTRI BUTE_MAX_LENGTH, GL_ACTI VE_UNI FORMS, GL_ACTI VE_UNI FORM_MAX_LENGTH.

params

Ret urns t he request ed obj ect param et er.

Description glGetProgram ret urns in params t he value of a param et er for a specific program obj ect . The

following param et ers ar e defined: GL_DELETE_STATUS params ret urns GL_TRUE if program is current ly flagged for delet ion, and GL_FALSE

ot herw ise. GL_LI NK_STATUS params ret urns GL_TRUE if t he last link operat ion on program was successful, and

GL_FALSE ot herwise. GL_VALI DATE_STATUS params ret urns GL_TRUE or if t he last validat ion operat ion on program was successful,

and GL_FALSE ot herwise. GL_I NFO_LOG_LENGTH params ret urns t he num ber of charact ers in t he inform at ion log for program including t he null t erm inat ion char act er ( i.e., t he size of t he charact er buffer required t o st ore t he inform at ion log) . I f program has no inform at ion log, a value of 0 is ret urned.

GL_ATTACHED_SHADERS params ret urns t he num ber of shader obj ect s at t ached t o program.

GL_ACTI VE_ATTRI BUTES params ret urns t he num ber of act ive at t ribut e variables for program.

GL_ACTI VE_ATTRI BUTE_MAX_LENGTH params ret urns t he lengt h of t he longest act ive at t ribut e nam e for program, including

t he null t erm inat ion char act er ( i.e., t he size of t he charact er buffer required t o st ore t he longest at t ribut e nam e) . I f no act ive at t ribut es exist , 0 is ret urned. GL_ACTI VE_UNI FORMS params ret urns t he num ber of act ive uniform variables for program.

GL_ACTI VE_UNI FORM_MAX_LENGTH params ret urns t he lengt h of t he longest act ive uniform variable nam e for program, including t he null t erm inat ion charact er ( i.e., t he size of t he charact er buffer required t o st ore t he longest uniform variable nam e) . I f no act ive uniform variables exist , 0 is ret urned.

Notes glGetProgram is available only if t he GL version is 2.0 or great er.

I f an error is generat ed, no change is m ade t o t he cont ent s of params.

Errors GL_I NVALI D_VALUE is generat ed if program is not a value generat ed by OpenGL. GL_I NVALI D_OPERATI ON is generat ed if program does not refer t o a program obj ect . GL_I NVALI D_ENUM is generat ed if pname is not an accept ed value. GL_I NVALI D_OPERATI ON is generat ed if glGetProgram is execut ed bet w een t he execut ion of glBegin and t he corresponding execut ion of glEnd.

ASSOCIATED GETS glGetActiveAttrib wit h argum ent program glGetActiveUniform wit h argum ent program glGetAttachedShaders wit h argum ent program glGetProgramInfoLog wit h argum ent program glsProgram

See Also glAttachShader, glCreateProgram, glDeleteProgram, glGetShader, glLinkProgram, glValidateProgram

glGetProgramInfoLog Name glGetProgramInfoLog Ret urns t he inform at ion log for a program obj ect

C Specification void glGetProgramInfoLog(GLuint program, GLsizei maxLength, GLsizei *length, GLchar *infoLog)

Parameters program

Specifies t he program obj ect whose inform at ion log is t o be queried.

maxLength

Specifies t he size of t he charact er buffer for st oring t he ret urned infor m at ion log.

length

Ret urns t he lengt h of t he st ring ret urned in infoLog ( excluding t he null t erm inat or) .

infoLog

Specifies an array of charact ers t hat is used t o ret urn t he infor m at ion log.

Description glGetProgramInfoLog ret urns t he inform at ion log for t he specified pr ogram obj ect . The inform at ion log for a program obj ect is m odified when t he pr ogram obj ect is linked or validat ed. The st ring t hat is ret urned is null t erm inat ed. glGetProgramInfoLog ret urns in infoLog as m uch of t he inform at ion log as it can, up t o a m axim um of maxLength charact ers. The num ber of charact ers act ually ret urned, excluding t he null t erm inat ion charact er, is specified by length. I f t he lengt h of t he ret urned st ring is not required, a value of NULL can be passed in t he length argum ent . The size of t he buffer required t o st ore t he ret urned inform at ion log can be obt ained by calling glGetProgram wit h t he value

GL_I NFO_LOG_LENGTH. The inform at ion log for a program obj ect is eit her an em pt y st ring, a st ring cont aining infor m at ion about t he last link operat ion, or a st ring cont aining inform at ion about t he last validat ion operat ion. I t m ay cont ain diagnost ic m essages, warning m essages, and ot her inform at ion. When a pr ogram obj ect is cr eat ed, it s inform at ion log is a st ring of lengt h 0.

Notes glGetProgramInfoLog is available only if t he GL version is 2.0 or great er.

The inform at ion log for a program obj ect is t he OpenGL im plem ent or's prim ary m echanism for conveying inform at ion about linking and validat ing. Therefore, t he infor m at ion log can be helpful t o applicat ion developers during t he developm ent process, even when t hese operat ions

are successful. Applicat ion developers should not expect different OpenGL im plem ent at ions t o produce ident ical inform at ion logs.

Errors GL_I NVALI D_VALUE is generat ed if program is not a value generat ed by OpenGL. GL_I NVALI D_OPERATI ON is generat ed if program is not a program obj ect . GL_I NVALI D_VALUE is generat ed if maxLength is less t han 0. GL_I NVALI D_OPERATI ON is generat ed if glGetProgramInfoLog is execut ed bet w een t he execut ion of glBegin and t he corresponding execut ion of glEnd.

Associated Gets glGetProgram wit h argum ent GL_I NFO_LOG_LENGTH glsProgram

See Also glCompileShader, glGetShaderInfoLog, glLinkProgram, glValidateProgram

glGetShader Name glGetShaderiv Ret urns a param et er from a shader obj ect

C Specification void glGetShaderiv(GLuint shader, GLenum pname, GLint *params)

Parameters shader

Specifies t he shader obj ect t o be queried.

pname

Specifies t he obj ect param et er. Accept ed sym bolic nam es are GL_SHADER_TYPE, GL_DELETE_STATUS, GL_COMPI LE_STATUS, GL_I NFO_LOG_LENGTH, GL_SHADER_SOURCE_LENGTH.

params

Ret urns t he request ed obj ect param et er.

Description glGetShader ret urns in params t he value of a param et er for a specific shader obj ect . The following param et ers are defined:

GL_SHADER_TYPE params ret urns GL_VERTEX_SHADER if shader is a vert ex shader obj ect , and GL_FRAGMENT_SHADER if shader is a fragm ent shader obj ect .

GL_DELETE_STATUS params ret urns GL_TRUE if shader is current ly flagged for delet ion, and GL_FALSE

ot herw ise. GL_COMPI LE_STATUS params ret urns GL_TRUE if t he last com pile operat ion on shader was successful, and GL_FALSE ot herwise.

GL_I NFO_LOG_LENGTH params ret urns t he num ber of charact ers in t he inform at ion log for shader including t he null t erm inat ion charact er ( i.e., t he size of t he charact er buffer required t o st ore t he infor m at ion log) . I f shader has no inform at ion log, a value of 0 is ret urned.

GL_SHADER_SOURCE_LENGTH

params ret urns t he lengt h of t he concat enat ion of t he source st rings t hat m ake up t he shader sour ce for t he shader, including t he null t erm inat ion charact er ( i.e., t he

size of t he charact er buffer requir ed t o st or e t he shader sour ce) . I f no source code exist s, 0 is ret urned.

Notes glGetShader is available only if t he GL version is 2.0 or great er.

I f an error is generat ed, no change is m ade t o t he cont ent s of params.

Errors GL_I NVALI D_VALUE is generat ed if shader is not a value generat ed by OpenGL. GL_I NVALI D_OPERATI ON is generat ed if shader does not refer t o a shader obj ect . GL_I NVALI D_ENUM is generat ed if pname is not an accept ed value. GL_I NVALI D_OPERATI ON is generat ed if glGetShader is execut ed bet w een t he execut ion of glBegin and t he corresponding execut ion of glEnd.

Associated Gets glGetShaderInfoLog wit h argum ent shader glGetShaderSource wit h argum ent shader glsShader

See Also glCompileShader, glCreateShader, glDeleteShader, glGetProgram, glShaderSource

glGetShaderInfoLog Name glGetShaderInfoLog Ret urns t he inform at ion log for a shader obj ect

C Specification void glGetShaderInfoLog(GLuint shader, GLsizei maxLength, GLsizei *length, GLchar *infoLog)

Parameters shader

Specifies t he shader obj ect whose inform at ion log is t o be queried.

maxLength

Specifies t he size of t he charact er buffer for st oring t he ret urned infor m at ion log.

length

Ret urns t he lengt h of t he st ring ret urned in infoLog ( excluding t he null t erm inat or) .

infoLog

Specifies an array of charact ers t hat ret urns t he infor m at ion log.

Description glGetShaderInfoLog ret urns t he inform at ion log for t he specified shader obj ect . The infor m at ion log

for a shader obj ect is m odified w hen t he shader is com piled. The st ring t hat is ret urned is null t erm inat ed. glGetShaderInfoLog ret urns in infoLog as m uch of t he inform at ion log as it can, up t o a m axim um of maxLength charact ers. The num ber of charact ers act ually ret urned, excluding t he null t erm inat ion charact er, is specified by length. I f t he lengt h of t he ret urned st ring is not required, a value of NULL can be passed in t he length argum ent . The size of t he buffer required t o st ore t he ret urned infor m at ion log can be obt ained by calling glGetShader wit h t he value GL_I NFO_LOG_LENGTH.

The inform at ion log for a shader obj ect is a st ring t hat m ay cont ain diagnost ic m essages, warning m essages, and ot her inform at ion about t he last com pile operat ion. When a shader obj ect is cr eat ed, it s inform at ion log is a st ring of lengt h 0.

Notes glGetShaderInfoLog is available only if t he GL version is 2.0 or great er.

The inform at ion log for a shader obj ect is t he OpenGL im plem ent or's prim ary m echanism for conveying inform at ion about t he com pilat ion process. Ther efore, t he infor m at ion log can be helpful t o applicat ion developers during t he developm ent process, even when com pilat ion is successful. Applicat ion developers should not expect different OpenGL im plem ent at ions t o produce ident ical inform at ion logs.

Errors GL_I NVALI D_VALUE is generat ed if shader is not a value generat ed by OpenGL. GL_I NVALI D_OPERATI ON is generat ed if shader is not a shader obj ect . GL_I NVALI D_VALUE is generat ed if maxLength is less t han 0. GL_I NVALI D_OPERATI ON is generat ed if glGetShaderInfoLog is execut ed bet w een t he execut ion of glBegin and t he corresponding execut ion of glEnd.

Associated Gets glGetShader wit h argum ent GL_I NFO_LOG_LENGTH glsShader

See Also glCompileShader, glGetProgramInfoLog, glLinkProgram, glValidateProgram

glGetShaderSource Name glGetShaderSource Ret urns t he source code st ring from a shader obj ect

C Specification void glGetShaderSource(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source)

Parameters shader

Specifies t he shader obj ect t o be queried.

bufSize

Specifies t he size of t he charact er buffer for st oring t he ret urned source code st ring.

length

Ret urns t he lengt h of t he st ring ret urned in source ( excluding t he null t erm inat or) .

source

Specifies an array of charact ers t hat is used t o ret urn t he source code st ring.

Description glGetShaderSource ret urns t he concat enat ion of t he source code st rings from t he shader obj ect specified by shader. The source code st rings for a shader obj ect are t he result of a previous call t o glShaderSource. The st ring ret urned by t he funct ion is null t erm inat ed. glGetShaderSource ret urns in source as m uch of t he source code st ring as it can, up t o a m axim um of bufSize charact ers. The num ber of charact ers act ually ret urned, excluding t he null t erm inat ion charact er, is specified by length. I f t he lengt h of t he ret urned st ring is not required, a value of NULL can be passed in t he length argum ent . The size of t he buffer required t o st ore t he ret urned source code st ring can be obt ained by calling glGetShader w it h t he value

GL_SHADER_SOURCE_LENGTH.

Notes glGetShaderSource is available only if t he GL version is 2.0 or great er.

Errors GL_I NVALI D_VALUE is generat ed if shader is not a value generat ed by OpenGL. GL_I NVALI D_OPERATI ON is generat ed if shader is not a shader obj ect . GL_I NVALI D_VALUE is generat ed if bufSize is less t han 0.

GL_I NVALI D_OPERATI ON is generat ed if glGetShaderSource is execut ed bet w een t he execut ion of glBegin and t he corresponding execut ion of glEnd.

Associated Gets glGetShader wit h argum ent GL_SHADER_SOURCE_LENGTH glsShader

See Also glCreateShader, glShaderSource

glGetUniform Name glGetUniformfv, glGetUniformiv Ret urn t he value of a uniform variable

C Specification void glGetUniformfv(GLuint program, GLint location, GLfloat *params) void glGetUniformiv(GLuint program, GLint location, GLint *params)

Parameters program

Specifies t he program obj ect t o be queried.

location

Specifies t he locat ion of t he uniform variable t o be queried.

params

Ret urns t he value of t he specified uniform variable.

Description glGetUniform ret urns in params t he value or values of t he specified uniform variable. The t ype of t he uniform variable specified by location det erm ines t he num ber of values ret urned. I f t he uniform variable is defined in t he shader as a Boolean, int , or float , a single value is ret urned. I f it is defined as a vec2, ivec2, or bvec2, t w o values are ret urned. I f it is defined as a vec3, ivec3, or bvec3, t hr ee values are ret urned, and so on. To query values st ored in uniform variables declar ed as arrays, call glGetUniform for each elem ent of t he array. To quer y values st ored in uniform variables declared as st ruct ures, call glGetUniform for each field in t he st ruct ure. The values for uniform variables declared as a m at r ix are ret urned in colum n m aj or order.

The locat ions assigned t o uniform variables are not known unt il t he program obj ect is linked. Aft er linking has occurred, t he com m and glGetUniformLocation obt ains t he locat ion of a uniform variable. This locat ion value can t hen be passed t o glGetUniform t o query t he current value of t he uniform variable. Aft er a program obj ect has been linked successfully, t he index values for uniform variables rem ain fixed unt il t he next link com m and occurs. The uniform variable values can be queried only aft er a link if t he link was successful.

Notes glGetUniform is available only if t he GL version is 2.0 or great er.

I f an error is generat ed, no change is m ade t o t he cont ent s of params.

Errors GL_I NVALI D_VALUE is generat ed if program is not a value generat ed by OpenGL.

GL_I NVALI D_OPERATI ON is generat ed if program is not a program obj ect . GL_I NVALI D_OPERATI ON is generat ed if program has not been successfully linked. GL_I NVALI D_OPERATI ON is generat ed if location does not correspond t o a valid uniform variable locat ion for t he specified program obj ect . GL_I NVALI D_OPERATI ON is generat ed if glGetUniform is execut ed bet w een t he execut ion of glBegin and t he corresponding execut ion of glEnd.

Associated Gets glGetActiveUniform wit h argum ent s program and t he index of an act ive uniform variable glGetProgram wit h argum ent s program and GL_ACTI VE_UNI FORMS or

GL_ACTI VE_UNI FORM_MAX_LENGTH glGetUniformLocation wit h argum ent s program and t he nam e of a uniform variable glsProgram

See Also glCreateProgram, glLinkProgram, glUniform

glGetUniformLocation Name glGetUniformLocation Ret urns t he locat ion of a uniform variable

C Specification GLint glGetUniformLocation(GLuint program, const GLchar *name)

Parameters program

Specifies t he program obj ect t o be queried.

name

Point s t o a null t erm inat ed st ring cont aining t he nam e of t he uniform variable whose locat ion is t o be queried.

Description glGetUniformLocation ret urns an int eger t hat represent s t he locat ion of a specific uniform variable wit hin a program obj ect . name m ust be a null t erm inat ed st ring t hat cont ains no whit e space. name m ust be an act ive uniform variable nam e in program t hat is not a st ruct ure, an array of st ruct ures, or a subcom ponent of a vect or or a m at rix. This funct ion ret urns - 1 if name does not correspond t o an act ive uniform variable in program or if name st art s wit h t he reserved prefix

" gl_" . Uniform variables t hat are st ruct ur es or arrays of st ruct ures m ay be queried wit h glGetUniformLocation for each field wit hin t he st ruct ure. The array elem ent operat or " [ ] " and t he st ruct ure field operat or " ." m ay be used in name t o select elem ent s w it hin an array or fields

wit hin a st ruct ure. The result of using t hese operat ors is not allowed t o be anot her st ruct ure, an array of st ruct ures, or a subcom ponent of a vect or or a m at rix. Except if t he last part of name indicat es a uniform variable arr ay, t he locat ion of t he first elem ent of an array can be ret rieved wit h t he nam e of t he array or w it h t he nam e appended by " [ 0] " . The act ual locat ions assigned t o uniform variables are not known unt il t he program obj ect is linked successfully. Aft er linking has occurred, t he com m and glGetUniformLocation obt ains t he locat ion of a uniform variable. This locat ion value can t hen be passed t o glUniform t o set t he value of t he uniform variable or t o glGetUniform t o query t he current value of t he uniform variable. Aft er a program obj ect has been linked successfully, t he index values for uniform variables rem ain fixed unt il t he next link com m and occurs. Uniform variable locat ions and values can only be queried aft er a link if t he link was successful.

Notes glGetUniformLocation is available only if t he GL version is 2.0 or great er.

Errors GL_I NVALI D_VALUE is generat ed if program is not a value generat ed by OpenGL.

GL_I NVALI D_OPERATI ON is generat ed if program is not a program obj ect . GL_I NVALI D_OPERATI ON is generat ed if program has not been successfully linked. GL_I NVALI D_OPERATI ON is generat ed if glGetUniformLocation is execut ed bet w een t he execut ion of glBegin and t he corresponding execut ion of glEnd.

Associated Gets glGetActiveUniform wit h argum ent s program and t he index of an act ive uniform variable glGetProgram wit h argum ent s program and GL_ACTI VE_UNI FORMS or

GL_ACTI VE_UNI FORM_MAX_LENGTH glGetUniform wit h argum ent s program and t he nam e of a uniform variable glsProgram

See Also glLinkProgram, glUniform

glGetVertexAttrib Name glGetVertexAttribdv, glGetVertexAttribfv, glGetVertexAttribiv Ret urn a generic vert ex at t ribut e

param et er

C Specification void glGetVertexAttribdv(GLuint index, GLenum pname, GLdouble *params) void glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params) void glGetVertexAttribiv(GLuint index, GLenum pname, GLint *params)

Parameters index

Specifies t he generic vert ex at t ribut e t o be queried.

pname

Specifies t he sym bolic nam e of t he vert ex at t ribut e param et er t o be queried. GL_VERTEX_ATTRI B_ARRAY_ENABLED, GL_VERTEX_ATTRI B_ARRAY_SI ZE, GL_VERTEX_ATTRI B_ARRAY_STRI DE, GL_VERTEX_ATTRI B_ARRAY_TYPE, GL_VERTEX_ATTRI B_ARRAY_NORMALI ZED, GL_CURRENT_VERTEX_ATTRI B are accept ed.

params

Ret urns t he request ed dat a.

Description glGetVertexAttrib ret urns in param s t he value of a gener ic vert ex at t ribut e par am et er. The generic vert ex at t ribut e t o be queried is specified by index, and t he param et er t o be queried is specified by pname.

The accept ed param et er nam es are as follow s: GL_VERTEX_ATTRI B_ARRAY_ENABLED params ret urns a single value t hat is non- zer o ( t rue) if t he vert ex at t ribut e array for index is enabled and 0 ( false) if it is disabled. The init ial value is GL_FALSE.

GL_VERTEX_ATTRI B_ARRAY_SI ZE params ret urns a single value, t he size of t he vert ex at t ribut e array for index. The size

is t he num ber of values for each elem ent of t he vert ex at t ribut e array, and it is 1, 2, 3, or 4. The init ial value is 4. GL_VERTEX_ATTRI B_ARRAY_STRI DE params ret urns a single value, t he array st ride for ( num ber of byt es bet ween successive elem ent s in) t he vert ex at t ribut e array for index. A value of 0 signifies

t hat t he arr ay elem ent s are st ored sequent ially in m em ory. The init ial value is 0. GL_VERTEX_ATTRI B_ARRAY_TYPE params ret urns a single value, a sym bolic const ant indicat ing t he array t ype for t he vert ex at t ribut e array for index. Possible values are GL_BYTE, GL_UNSI GNED_BYTE,

GL_SHORT, GL_UNSI GNED_SHORT, GL_I NT, GL_UNSI GNED_I NT, GL_FLOAT, and GL_DOUBLE. The init ial value is GL_FLOAT. GL_VERTEX_ATTRI B_ARRAY_NORMALI ZED params ret urns a single value t hat is non- zer o ( t rue) if fixed- point dat a t ypes for t he vert ex at t ribut e array indicat ed by index are norm alized w hen t hey are convert ed t o float ing point , and 0 ( false) ot herwise. The init ial value is GL_FALSE.

GL_CURRENT_VERTEX_ATTRI B params ret urns four values t hat represent t he current value for t he generic vert ex at t ribut e specified by index. Generic vert ex at t ribut e 0 is unique in t hat it has no current st at e, so an error is gener at ed if index is 0. The init ial value for all ot her

generic vert ex at t ribut es is ( 0,0,0,1) . All t he param et ers except GL_CURRENT_VERTEX_ATTRI B represent client - side st at e.

Notes glGetVertexAttrib is available only if t he GL version is 2.0 or great er.

I f an error is generat ed, no change is m ade t o t he cont ent s of params.

Errors GL_I NVALI D_VALUE is generat ed if index is great er t han or equal t o GL_MAX_VERTEX_ATTRI BS. GL_I NVALI D_ENUM is generat ed if pname is not an accept ed value. GL_I NVALI D_OPERATI ON is generat ed if index is 0 and pname is GL_CURRENT_VERTEX_ATTRI B.

Associated Gets glGet wit h argum ent GL_MAX_VERTEX_ATTRI BS glGetVertexAttribPointer wit h argum ent s index and GL_VERTEX_ATTRI B_ARRAY_POI NTER

See Also glBindAttribLocation, glDisableVertexAttribArray, glEnableVertexAttribArray, glVertexAttrib, glVertexAttribPointer

glGetVertexAttribPointer Name glGetVertexAttributePointerv Ret urns t he address of t he specified point er

C Specification void glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid **pointer)

Parameters index

Specifies t he generic vert ex at t ribut e t o be queried.

pname

Specifies t he sym bolic nam e of t he generic vert ex at t r ibut e param et er t o be queried. Must be GL_VERTEX_ATTRI B_ARRAY_POI NTER.

params

Ret urns t he request ed dat a.

Description glGetVertexAttribPointer ret urns point er inform at ion. index is t he generic vert ex at t ribut e t o be queried, pname is a sym bolic const ant indicat ing t he point er t o be ret urned, and params is a point er t o a locat ion in w hich t o place t he ret urned dat a. The accept ed param et er nam es are as follows:

GL_VERTEX_ATTRI B_ARRAY_POI NTER params ret urns a single value t hat is a point er t o t he vert ex at t ribut e array for t he generic vert ex at t ribut e specified by index.

Notes glGetVertexAttribPointer is available only if t he GL version is 2.0 or great er.

The point er ret urned is client - side st at e. The init ial value for each point er is NULL.

Errors GL_I NVALI D_VALUE is generat ed if index is great er t han or equal t o GL_MAX_VERTEX_ATTRI BS. GL_I NVALI D_ENUM is generat ed if pname is not an accept ed value.

Associated Gets

glGet wit h argum ent GL_MAX_VERTEX_ATTRI BS glGetVertexAttrib wit h argum ent s index and t he nam e of a generic vert ex at t ribut e param et er

See Also glVertexAttribPointer

glIsProgram Name glIsProgram Det erm ines whet her a nam e cor responds t o a program obj ect

C Specification GLboolean glIsProgram(GLuint program)

Parameters program

Specifies a pot ent ial pr ogram obj ect .

Description glIsProgram ret urns GL_TRUE if program is t he nam e of a program obj ect . I f program is zero or a non- zer o value t hat is not t he nam e of a program obj ect , glIsProgram ret urns GL_FALSE.

Notes glIsProgram is available only if t he GL version is 2.0 or great er.

No err or is generat ed if program is not a valid program obj ect nam e.

Errors GL_I NVALI D_OPERATI ON is generat ed if glIsProgram is execut ed bet w een t he execut ion of glBegin and t he corresponding execut ion of glEnd.

Associated Gets glGet wit h t he argum ent GL_CURRENT_PROGRAM glGetActiveAttrib wit h argum ent s program and t he index of an act ive at t ribut e variable glGetActiveUniform wit h argum ent s program and t he index of an act ive uniform variable glGetAttachedShaders wit h argum ent program glGetAttribLocation wit h argum ent s program and t he nam e of an at t ribut e variable glGetProgram wit h argum ent s program and t he param et er t o be queried glGetProgramInfoLog wit h argum ent program glGetUniform wit h argum ent s program and t he locat ion of a uniform variable glGetUniformLocation wit h argum ent s program and t he nam e of a uniform variable

See Also glAttachShader, glBindAttribLocation, glCreateProgram, glDeleteProgram, glDetachShader, glLinkProgram, glUniform, glUseProgram, glValidateProgram

glIsShader Name glIsShader Det erm ines whet her a nam e corresponds t o a shader obj ect

C Specification GLboolean glIsShader(GLuint shader)

Parameters shader

Specifies a pot ent ial shader obj ect .

Description glIsShader ret urns GL_TRUE if shader is t he nam e of a shader obj ect . I f shader is zero or a non- zer o value t hat is not t he nam e of a shader obj ect , glIsShader ret urns GL_FALSE.

Notes glIsShader is available only if t he GL version is 2.0 or great er.

No err or is generat ed if shader is not a valid shader obj ect nam e.

Errors GL_I NVALI D_OPERATI ON is generat ed if glIsShader is execut ed bet w een t he execut ion of glBegin and t he corresponding execut ion of glEnd.

Associated Gets glGetAttachedShaders wit h a valid pr ogram obj ect glGetShader wit h argum ent s shader and a param et er t o be queried glGetShaderInfoLog wit h argum ent object glGetShaderSource wit h argum ent object

See Also glAttachShader, glCompileShader, glCreateShader, glDeleteShader, glDetachShader, glLinkProgram, glShaderSource

glLinkProgram Name glLinkProgram Links a program obj ect

C Specification void glLinkProgram(GLuint program)

Parameters program

Specifies t he handle of t he pr ogram obj ect t o be linked.

Description glLinkProgram links t he program obj ect specified by program. I f any shader obj ect s of t ype GL_VERTEX_SHADER are at t ached t o program, t hey are used t o cr eat e an execut able t hat w ill run

on t he program m able vert ex processor. I f any shader obj ect s of t ype GL_FRAGMENT_SHADER are at t ached t o program, t hey are used t o cr eat e an execut able t hat w ill run on t he pr ogram m able fragm ent processor. The st at us of t he link operat ion is st ored as part of t he program obj ect 's st at e. This value is set t o GL_TRUE if t he program obj ect was linked wit hout errors and is ready for use, and GL_FALSE ot herwise. I t can be queried by calling glGetProgram wit h argum ent s program and GL_LI NK_STATUS. As a result of a successful link operat ion, all act ive user - defined uniform variables belonging t o program are init ialized t o 0, and each of t he program obj ect 's act ive uniform variables is assigned a locat ion t hat can be queried wit h glGetUniformLocation. Also, any act ive user - defined at t ribut e

variables t hat have not been bound t o a generic vert ex at t ribut e index are bound t o one at t his t im e. Linking of a program obj ect can fail for a num ber of reasons as specified in t he OpenGL Shading Language Specificat ion. The following list s som e of t he condit ions t hat cause a link error. z

z z

z z

z

The num ber of act ive at t r ibut e variables support ed by t he im plem ent at ion has been exceeded. The st orage lim it for uniform variables has been exceeded. The num ber of act ive uniform variables support ed by t he im plem ent at ion has been exceeded. The main funct ion is m issing for t he vert ex shader or t he fragm ent shader. A varying variable act ually used in t he fragm ent shader is not declared in t he sam e way ( or is not declared at all) in t he vert ex shader. A reference t o a funct ion or variable nam e is unresolved.

z

A shared global is declared wit h t w o different t ypes or t w o different init ial values.

z

One or m ore of t he at t ached shader obj ect s has not been successfully com piled.

z

z

Binding a generic at t ribut e m at rix caused som e rows of t he m at rix t o fall out side t he allowed m axim um of GL_MAX_VERTEX_ATTRI BS. Not enough cont iguous vert ex at t ribut e slot s could be found t o bind at t ribut e m at rices.

When a program obj ect has been successfully linked, t he program obj ect can be m ade part of current st at e w it h glUseProgram. Whet her or not t he link operat ion was successful, t he program obj ect 's inform at ion log is over- writ t en. The inform at ion log can be ret rieved wit h glGetProgramInfoLog. glLinkProgram also inst alls t he generat ed execut ables as part of t he current rendering st at e if t he

link operat ion was successful and t he specified program obj ect is alr eady cur rent ly in use as a result of a previous call t o glUseProgram. I f t he program obj ect current ly in use is relinked unsuccessfully, it s link st at us is set t o GL_FALSE, but t he execut ables and associat ed st at e rem ain part of t he current st at e unt il a subsequent call t o glUseProgram rem oves it from use. Aft er it is rem oved from use, it cannot be m ade part of current st at e unt il it has been successfully relinked. I f program cont ains shader obj ect s of t ype GL_VERTEX_SHADER but does not cont ain shader obj ect s of t ype GL_FRAGMENT_SHADER, t he vert ex shader is linked against t he im plicit int erface for fixed funct ionalit y fragm ent processing. Sim ilarly, if program cont ains shader obj ect s of t ype GL_FRAGMENT_SHADER but does not cont ain shader obj ect s of t ype GL_VERTEX_SHADER, t he fragm ent shader is linked against t he im plicit int erface for fixed funct ionalit y vert ex processing. The pr ogram obj ect 's inform at ion log is updat ed and t he pr ogram is generat ed at t he t im e of t he link operat ion. Aft er t he link operat ion, applicat ions are free t o m odify at t ached shader obj ect s, com pile at t ached shader obj ect s, det ach shader obj ect s, delet e shader obj ect s, and at t ach addit ional shader obj ect s. None of t hese operat ions affect t he inform at ion log or t he program t hat is part of t he program obj ect .

Notes glLinkProgram is available only if t he GL version is 2.0 or great er.

I f t he link operat ion is unsuccessful, any inform at ion about a previous link operat ion on program is lost ( i.e., a failed link does not rest ore t he old st at e of program) . Cert ain inform at ion can st ill be ret r ieved from program even aft er an unsuccessful link operat ion. See, for inst ance, glGetActiveAttrib and glGetActiveUniform.

Errors GL_I NVALI D_VALUE is generat ed if program is not a value generat ed by OpenGL. GL_I NVALI D_OPERATI ON is generat ed if program is not a program obj ect . GL_I NVALI D_OPERATI ON is generat ed if glLinkProgram is execut ed bet w een t he execut ion of glBegin and t he corresponding execut ion of glEnd.

Associated Gets glGet wit h t he argum ent GL_CURRENT_PROGRAM

glGetActiveAttrib wit h argum ent program and t he index of an act ive at t ribut e variable glGetActiveUniform wit h argum ent program and t he index of an act ive uniform variable glGetAttachedShaders wit h argum ent program glGetAttribLocation wit h argum ent program and an at t ribut e var iable nam e glGetProgram wit h argum ent s program and GL_LI NK_STATUS glGetProgramInfoLog wit h argum ent program glGetUniform wit h argum ent program and a uniform variable locat ion glGetUniformLocation wit h argum ent program and a uniform variable nam e glIsProgram

See Also glAttachShader, glBindAttribLocation, glCompileShader, glCreateProgram, glDeleteProgram, glDetachShader, glUniform, glUseProgram, glValidateProgram

glShaderSource Name glShaderSource Replaces t he source code in a shader obj ect

C Specification void glShaderSource(GLuint shader, GLsizei count, const GLchar **string, const GLint *length)

Parameters shader

Specifies t he handle of t he shader obj ect whose source code is t o be replaced.

count

Specifies t he num ber of elem ent s in t he string and length arrays.

string

Specifies an array of point ers t o st rings cont aining t he source code t o be loaded int o t he shader.

length

Specifies an array of st ring lengt hs.

Description glShaderSource set s t he source code in shader t o t he source code in t he array of st rings specified by string. Any source code previously st ored in t he shader obj ect is com plet ely replaced. The num ber of st rings in t he array is specified by count. I f length is NULL, each st ring is assum ed t o be null t erm inat ed. I f length is a value ot her t han NULL, it point s t o an ar ray cont aining a st ring lengt h for each of t he corresponding elem ent s of string. Each elem ent in t he length array m ay

cont ain t he lengt h of t he corresponding st ring ( t he null charact er is not count ed as part of t he st ring lengt h) or a value less t han 0 t o indicat e t hat t he st ring is null t erm inat ed. The source code st rings are not scanned or parsed at t his t im e; t hey are sim ply copied int o t he specified shader obj ect .

Notes glShaderSource is available only if t he GL version is 2.0 or great er.

OpenGL copies t he shader source code st rings when glShaderSource is called, so an applicat ion can free it s copy of t he source code st rings im m ediat ely aft er t he funct ion ret urns.

Errors GL_I NVALI D_VALUE is generat ed if shader is not a value generat ed by OpenGL. GL_I NVALI D_OPERATI ON is generat ed if shader is not a shader obj ect . GL_I NVALI D_VALUE is generat ed if count is less t han 0.

GL_I NVALI D_OPERATI ON is generat ed if glShaderSource is execut ed bet w een t he execut ion of glBegin and t he corresponding execut ion of glEnd.

Associated Gets glGetShader wit h argum ent s shader and GL_SHADER_SOURCE_LENGTH glGetShaderSource wit h argum ent shader glIsShader

See Also glCompileShader, glCreateShader, glDeleteShader

glUniform Name glUniform1f, glUniform2f, glUniform3f, glUniform4f, glUniform1i, glUniform2i, glUniform3i, glUniform4i, glUniform1fv, glUniform2fv, glUniform3fv, glUniform4fv, glUniform1iv, glUniform2iv, glUniform3iv, glUniform4iv, glUniformMatrix2fv, glUniformMatrix3fv, glUniformMatrix4fv Specify t he value of a uniform

variable for t he current program obj ect

C Specification void glUniform1f(GLint location, GLfloat v0) void glUniform2f(GLint location, GLfloat v0, GLfloat v1) void glUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) void glUniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) void glUniform1i(GLint GLint void glUniform2i(GLint GLint GLint void glUniform3i(GLint GLint GLint GLint void glUniform4i(GLint GLint GLint GLint GLint

location, v0) location, v0, v1) location, v0, v1, v2) location, v0, v1, v2, v3)

Parameters location

Specifies t he locat ion of t he uniform variable t o be m odified.

v0, v1, v2, v3

Specify t he new values t o be used for t he specified uniform variable.

C Specification void glUniform1fv(GLint location, GLsizei count, const GLfloat *value)

void glUniform2fv(GLint location, GLsizei count, const GLfloat *value) void glUniform3fv(GLint location, GLsizei count, const GLfloat *value) void glUniform4fv(GLint location, GLsizei count, const GLfloat *value) void glUniform1iv(GLint location, GLsizei count, const GLint *value) void glUniform2iv(GLint location, GLsizei count, const GLint *value) void glUniform3iv(GLint location, GLsizei count, const GLint *value) void glUniform4iv(GLint location, GLsizei count, const GLint *value)

Parameters location

Specifies t he locat ion of t he uniform value t o be m odified.

count

Specifies t he num ber of elem ent s t hat are t o be m odified ( t his should be 1 if t he t arget ed uniform variable is not an array, 1 or m ore if it is an array) .

value

Specifies a point er t o an array of count values t hat are used t o updat e t he specified uniform variable.

C Specification void glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) void glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) void glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)

Parameters location

Specifies t he locat ion of t he uniform value t o be m odified.

count

Specifies t he num ber of elem ent s t hat are t o be m odified ( t his should be 1 if t he t arget ed uniform variable is not an array, 1 or m ore if it is an array) .

transpose

Specifies w het her t o t ranspose t he m at r ix as t he values are loaded int o t he uniform variable. value

Specifies a point er t o an array of count values t hat are used t o updat e t he specified uniform variable.

Description glUniform m odifies t he value of a uniform variable or a uniform variable arr ay. The locat ion of t he uniform variable t o be m odified is specified by location, which should be a value ret urned by glGetUniformLocation. glUniform oper at es on t he progr am obj ect t hat was m ade part of current st at e wit h glUseProgram.

The com m ands glUniform{1|2|3|4}{f|i} change t he value of t he uniform variable specified by location, using t he values passed as argum ent s. The num ber specified in t he com m and should m at ch t he num ber of com ponent s in t he dat a t ype of t he specified uniform variable ( e.g., 1 for float , int , bool; 2 for vec2, ivec2, bvec2) . The suffix f m eans t hat float ing- point values are being passed; t he suffix i m eans t hat int eger values are being passed, and t his t ype should also m at ch t he dat a t ype of t he specified uniform variable. The i variant s of t his funct ion provide values for uniform variables defined as int , ivec2, ivec3, ivec4, or arrays of t hese. The f variant s provide values for uniform variables of t ype float , vec2, vec3, vec4, or arrays of t hese. Eit her t he i or t he f variant s can pr ovide values for uniform variables of t ype bool, bvec2, bvec3, bvec4, or arrays of t hese. The uniform variable is set t o false if t he input value is 0 or 0.0f, and it is set t o t rue ot herw ise. All act ive uniform variables defined in a progr am obj ect are init ialized t o 0 when t he program obj ect is linked successfully. They ret ain t he values assigned t o t hem wit h glUniform unt il t he next successful link operat ion occurs on t he progr am obj ect , when t hey are once again init ialized t o 0. The com m ands glUniform{1|2|3|4}{f|i}v m odify a single uniform variable or a uniform variable array. These com m ands pass a count and a point er t o t he values t o be loaded int o a uniform variable or a uniform variable array. Use a count of 1 if m odifying t he value of a single uniform variable, and a count of 1 or great er if m odifying an ent ire array or part of an arr ay. When n elem ent s st art ing at an ar bit rary posit ion m in a uniform variable ar ray are loaded, elem ent s m + n 1 in t he array ar e r eplaced w it h t he new values. I f m + n 1 is larger t han t he size of t he uniform variable array, values for all array elem ent s beyond t he end of t he array ar e ignored. The num ber specified in t he nam e of t he com m and indicat es t he num ber of com ponent s for each elem ent in value, and it should m at ch t he num ber of com ponent s in t he dat a t ype of t he specified uniform variable ( e.g., 1 for float , int , bool; 2 for vec2, ivec2, bvec2) . The dat a t ype specified in t he nam e of t he com m and m ust m at ch t he dat a t ype for t he specified uniform variable as described previously for glUniform{1|2|3|4}{f|i}. For uniform variable arrays, each elem ent of t he array is considered t o be of t he t ype indicat ed in t he nam e of t he com m and ( e.g., glUniform3f or glUniform3fv can be used t o load a uniform variable array of t ype vec3) . The num ber of elem ent s of t he uniform variable array t o be m odified is specified by count. The com m ands glUniformFloatMatrix{2|3|4}fv m odify a m at rix or an array of m at rices. The num ber in t he com m and nam e is int erpret ed as t he dim ensionalit y of t he m at rix. The num ber 2 indicat es a 2 x 2 m at rix ( i.e., 4 values) , t he num ber 3 indicat es a 3 x 3 m at rix ( i.e., 9 values) , and t he num ber 4 indicat es a 4 x 4 m at rix ( i.e., 16 values) . I f transpose is GL_FALSE, each m at rix is assum ed t o be supplied in colum n m aj or order. I f transpose is GL_TRUE, each m at rix is assum ed t o be supplied in row m aj or order. The count argum ent specifies t he num ber of m at r ices t o be passed. Use a count of 1 if m odifying t he value of a single m at rix, and a count great er t han 1 if m odifying an array of m at rices.

Notes glUniform is available only if t he GL version is 2.0 or great er. glUniform1i and glUniform1iv are t he only t wo funct ions t hat m ay load uniform variables defined as

sam pler t ypes. Loading sam plers wit h any ot her funct ion result s in a GL_I NVALI D_OPERATI ON error. I f count is great er t han 1 and t he indicat ed uniform variable is not an array, a GL_I NVALI D_OPERATI ON error is generat ed and t he specified uniform variable rem ains unchanged. Ot her t han t he preceding except ions, if t he t ype and size of t he uniform variable as defined in t he shader do not m at ch t he t ype and size specified in t he nam e of t he com m and used t o load a value for t he uniform variable, a GL_I NVALI D_OPERATI ON error is generat ed and t he specified uniform variable rem ains unchanged. I f location is a value ot her t han 1 and it does not represent a valid uniform variable locat ion in t he current program obj ect , an error is gener at ed, and no changes are m ade t o t he uniform variable st orage of t he curr ent pr ogram obj ect . I f location is equal t o 1, t he dat a passed in is silent ly ignored and t he specified uniform variable is unchanged.

Errors GL_I NVALI D_OPERATI ON is generat ed if t her e is no curr ent pr ogram obj ect . GL_I NVALI D_OPERATI ON is generat ed if t he size of t he uniform variable declared in t he shader does not m at ch t he size indicat ed by t he glUniform com m and. GL_I NVALI D_OPERATI ON is generat ed if one of t he int eger variant s of t his funct ion loads a uniform variable of t ype float , vec2, vec3, vec4, or an array of t hese, or if one of t he float ingpoint variant s of t his funct ion loads a uniform var iable of t ype int , ivec2, ivec3, or ivec4, or an array of t hese. GL_I NVALI D_OPERATI ON is generat ed if location is an invalid uniform locat ion for t he current program obj ect and location is not equal t o 1. GL_I NVALI D_VALUE is generat ed if count is less t han 0. GL_I NVALI D_OPERATI ON is generat ed if count is great er t han 1 and t he indicat ed uniform variable is not an arr ay variable. GL_I NVALI D_OPERATI ON is generat ed if a sam pler is loaded w it h a com m and ot her t han glUniform1i and glUniform1iv. GL_I NVALI D_OPERATI ON is generat ed if glUniform is execut ed bet w een t he execut ion of glBegin and t he corresponding execut ion of glEnd.

Associated Gets glGet wit h t he argum ent GL_CURRENT_PROGRAM glGetActiveUniform wit h t he handle of a program obj ect and t he index of an act ive unifor m

variable glGetUniform wit h t he handle of a program obj ect and t he locat ion of a uniform var iable

glGetUniformLocation wit h t he handle of a program obj ect and t he nam e of a uniform variable

See Also glLinkProgram, glUseProgram

glUseProgram Name glUseProgram I nst alls a pr ogram obj ect as part of current rendering st at e

C Specification void glUseProgram(GLuint program)

Parameters program

Specifies t he handle of t he program obj ect current rendering st at e.

whose exec

Description glUseProgram inst alls t he program obj ect specified by program as part of current rendering st at e. Cr a program obj ect involves successfully at t aching shader obj ect s t o it wit h glAttachShader, successfu wit h glCompileShader, and successfully linking t he pr ogram obj ect wit h glLinkProgram.

A program obj ect cont ains an execut able t hat will run on t he vert ex processor if it cont ains one o GL_VERTEX_SHADER t hat have been successfully com piled and linked. Sim ilarly, a program obj e will run on t he fragm ent processor if it cont ains one or m ore shader obj ect s of t ype GL_FRAGMEN successfully com piled and linked. Successfully inst alling an execut able on a program m able processor disables t he corresponding fix Specifically, if an execut able is inst alled on t he vert ex processor, t he OpenGL fixed funct ionalit y z

The m odelview m at rix is not applied t o vert ex coordinat es.

z

The pr oj ect ion m at rix is not applied t o vert ex coordinat es.

z

The t ext ure m at r ices are not applied t o t ext ure coordinat es.

z

Norm als are not t ransform ed t o eye coordinat es.

z

Norm als are not rescaled or norm alized.

z

Norm alizat ion of GL_AUTO_NORMAL evaluat ed norm als is not perform ed.

z

Text ure coordinat es are not generat ed aut om at ically.

z

Per- vert ex light ing is not perform ed.

z

Color m at erial com put at ions are not perform ed.

z

Color index light ing is not perform ed.

This list also applies t o set t ing t he current rast er posit ion. The execut able t hat is inst alled on t he vert ex processor is expect ed t o im plem ent any or all of t h preceding list . Sim ilar ly, if an execut able is inst alled on t he fragm ent processor, t he OpenGL fixe follows. z

Text ure environm ent and t ext ure funct ions are not applied.

z

Text ure applicat ion is not applied.

z

Color sum is not applied.

z

Fog is not applied.

Again, t he fragm ent shader t hat is inst alled is expect ed t o im plem ent any or all of t he desired fu list . While a program obj ect is in use, applicat ions are free t o m odify at t ached shader obj ect s, com pil addit ional shader obj ect s, and det ach or delet e shader obj ect s. None of t hese operat ions affect t t he current st at e. However, relinking t he pr ogram obj ect t hat is current ly in use inst alls t he prog rendering st at e if t he link operat ion was successful ( see glLinkProgram) . I f t he program obj ect cur unsuccessfully, it s link st at us is set t o GL_FALSE but t he execut ables and associat ed st at e rem ai subsequent call t o glUseProgram rem oves t he program obj ect from use. Aft er it is rem oved from u current st at e unt il it has been successfully relinked. I f program cont ains shader obj ect s of t ype GL_VERTEX_SHADER but does not cont ain shader obj e GL_FRAGMENT_SHADER, an execut able is inst alled on t he vert ex processor but fixed funct ionalit processing. Sim ilarly, if program cont ains shader obj ect s of t ype GL_FRAGMENT_SHADER but does t ype GL_VERTEX_SHADER, an execut able is inst alled on t he fragm ent processor but fixed funct io processing. I f program is 0, t he pr ogram m able processors are disabled and fixed funct ionalit y is us processing.

Notes glUseProgram is available only if t he GL version is 2.0 or great er.

While a program obj ect is in use, t he st at e t hat cont rols t he disabled fixed funct ionalit y m ay also OpenGL calls. Like display list s and t ext ure obj ect s, t he nam e space for program obj ect s m ay be shared across server sides of t he cont ext s share t he sam e address space. I f t he nam e space is shared across c t he dat a associat ed wit h t hose at t ached obj ect s are shared as well. Applicat ions are responsible for synchronizing across API calls when obj ect s are accessed from d

Errors GL_I NVALI D_VALUE is generat ed if program is neit her 0 nor a value generat ed by OpenGL. GL_I NVALI D_OPERATI ON is generat ed if program is not a program obj ect . GL_I NVALI D_OPERATI ON is generat ed if program could not be m ade part of current st at e. GL_I NVALI D_OPERATI ON is generat ed if glUseProgram is execut ed bet w een t he execut ion of glBegi execut ion of glEnd.

Associated Gets glGet wit h t he argum ent GL_CURRENT_PROGRAM glGetActiveAttrib wit h a valid pr ogram obj ect and t he index of an act ive at t ribut e variable glGetActiveUniform wit h a valid pr ogram obj ect and t he index of an act ive uniform variable glGetAttachedShaders wit h a valid pr ogram obj ect glGetAttribLocation wit h a valid pr ogram obj ect and t he nam e of an at t ribut e variable glGetProgram wit h a valid pr ogram obj ect and t he param et er t o be queried glGetProgramInfoLog wit h a valid pr ogram obj ect glGetUniform wit h a valid pr ogram obj ect and t he locat ion of a uniform variable glGetUniformLocation wit h a valid pr ogram obj ect and t he nam e of a uniform variable glIsProgram

See Also gllAttachShader, glBindAttribLocation, glCompileShader, glCreateProgram, glDeleteProgram, glDetachShader, glLin glValidateProgram, glVertexAttrib

glValidateProgram Name glValidateProgram Validat es a program obj ect

C Specification void glValidateProgram(GLuint program)

Parameters program

Specifies t he handle of t he program obj ect t o be validat ed.

Description glValidateProgram checks t o see whet her t he execut ables cont ained in program can execut e given

t he current OpenGL st at e. The inform at ion generat ed by t he validat ion pr ocess is st ored in program's inform at ion log. The validat ion inform at ion m ay consist of an em pt y st ring, or it m ay

be a st ring cont aining inform at ion about how t he current program obj ect int eract s w it h t he rest of current OpenGL st at e. This funct ion provides a w ay for OpenGL im plem ent ors t o convey m ore inform at ion about why t he current program is inefficient , subopt im al, failing t o execut e, and so on. The st at us of t he validat ion operat ion is st or ed as part of t he program obj ect 's st at e. This value is set t o GL_TRUE if t he validat ion succeeded, and GL_FALSE ot herwise. I t can be queried by calling glGetProgram wit h argum ent s program and GL_VALI DATE_STATUS. I f validat ion is successful, program is guarant eed t o execut e given t he current st at e. Ot herw ise, program is guarant eed t o not execut e. This funct ion is t ypically useful only during applicat ion developm ent . The inform at ional st ring st ored in t he inform at ion log is com plet ely im plem ent at ion dependent ; t herefore, different OpenGL im plem ent at ions cannot be expect ed t o produce ident ical inform at ion st rings.

Notes glValidateProgram is available only if t he GL version is 2.0 or great er.

This funct ion m im ics t he validat ion operat ion t hat OpenGL im plem ent at ions m ust perform w hen rendering com m ands are issued while program m able shaders are part of current st at e. The error GL_I NVALI D_OPERATI ON is generat ed by glBegin, glRasterPos, or any com m and t hat perform s an im plicit call t o glBegin if z

z

any t wo act ive sam plers in t he current program obj ect ar e of different t ypes but refer t o t he sam e t ext ur e im age unit ; any act ive sam pler in t he cur rent program obj ect refers t o a t ext ure im age unit in which fixed funct ion fragm ent processing accesses a t ext ure t arget t hat does not m at ch t he sam pler t ype; or

z

t he sum of t he num ber of act ive sam plers in t he program and t he num ber of t ext ure im age unit s enabled for fixed funct ion fr agm ent processing exceeds t he com bined lim it on t he t ot al num ber of t ext ure im age unit s allow ed.

Difficult ies or perform ance degradat ion m ay occur if applicat ions t ry t o cat ch t hese errors when issuing rendering com m ands. Ther efore, applicat ions are advised t o m ake calls t o glValidateProgram t o det ect t hese issues during applicat ion developm ent .

Errors GL_I NVALI D_VALUE is generat ed if program is not a value generat ed by OpenGL. GL_I NVALI D_OPERATI ON is generat ed if program is not a program obj ect . GL_I NVALI D_OPERATI ON is generat ed if glValidateProgram is execut ed bet w een t he execut ion of glBegin and t he corresponding execut ion of glEnd.

Associated Gets glGetProgram wit h argum ent s program and GL_VALI DATE_STATUS glGetProgramInfoLog wit h argum ent program glIsProgram

See Also glLinkProgram, glUseProgram

glVertexAttrib Name glVertexAttrib1f, glVertexAttrib1s, glVertexAttrib1d, glVertexAttrib2f, glVertexAttrib2s, glVertexAttrib2d, glVertexAttrib3f, glVertexAttrib3s, glVertexAttrib3d, glVertexAttrib4f, glVertexAttrib4s, glVertexAttrib4d, glVertexAttrib4Nub, glVertexAttrib1fv, glVertexAttrib1sv, glVertexAttrib1dv, glVertexAttrib2fv, glVertexAttrib2sv, glVertexAttrib2dv, glVertexAttrib3fv, glVertexAttrib3sv, glVertexAttrib3dv, glVertexAttrib4fv, glVertexAttrib4sv, glVertexAttrib4dv, glVertexAttrib4iv, glVertexAttrib4bv, glVertexAttrib4ubv, glVertexAttrib4usv, glVertexAttrib4uiv, glVertexAttrib4Nbv, glVertexAttrib4Nsv, glVertexAttrib4Niv, glVertexAttrib4Nubv, glVertexAttrib4Nusv, glVertexAttrib4Nuiv Specify t he value of a generic vert ex

at t ribut e

C Specification void glVertexAttrib1f(GLuint index, GLfloat v0) void glVertexAttrib1s(GLuint index, GLshort v0) void glVertexAttrib1d(GLuint index, GLdouble v0) void glVertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1) void glVertexAttrib2s(GLuint index, GLshort v0, GLshort v1) void glVertexAttrib2d(GLuint index, GLdouble v0, GLdouble v1) void glVertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2) void glVertexAttrib3s(GLuint index, GLshort v0, GLshort v1, GLshort v2) void glVertexAttrib3d(GLuint index, GLdouble v0, GLdouble v1, GLdouble v2) void glVertexAttrib4f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) void glVertexAttrib4s(GLuint index, GLshort v0, GLshort v1, GLshort v2, GLshort v3) void glVertexAttrib4d(GLuint index, GLdouble v0, GLdouble v1, GLdouble v2,

GLdouble v3) void glVertexAttrib4Nub(GLuint index, GLubyte v0, GLubyte v1, GLubyte v2, GLubyte v3)

Parameters index

Specifies t he index of t he generic vert ex at t ribut e t o be m odified.

v0, v1, v2, v3

Specify t he new values t o be used for t he specified vert ex at t ribut e.

C Specification void glVertexAttrib1fv(GLuint index, const GLfloat *v) void glVertexAttrib1sv(GLuint index, const GLshort *v) void glVertexAttrib1dv(GLuint index, const GLdouble *v) void glVertexAttrib2fv(GLuint index, const GLfloat *v) void glVertexAttrib2sv(GLuint index, const GLshort *v) void glVertexAttrib2dv(GLuint index, const GLdouble *v) void glVertexAttrib3fv(GLuint index, const GLfloat *v) void glVertexAttrib3sv(GLuint index, const GLshort *v) void glVertexAttrib3dv(GLuint index, const GLdouble *v) void void void void void

glVertexAttrib4fv(GLuint glVertexAttrib4sv(GLuint glVertexAttrib4dv(GLuint glVertexAttrib4iv(GLuint glVertexAttrib4bv(GLuint

index, index, index, index, index,

const const const const const

GLfloat *v) GLshort *v) GLdouble *v) GLint *v) GLbyte *v)

void glVertexAttrib4ubv(GLuint index, const GLubyte *v) void glVertexAttrib4usv(GLuint index, const GLushort *v) void glVertexAttrib4uiv(GLuint index, const GLuint *v) void void void void void void

glVertexAttrib4Nbv(GLuint index, const GLbyte *v) glVertexAttrib4Nsv(GLuint index, const GLshort *v) glVertexAttrib4Niv(GLuint index, const GLint *v) glVertexAttrib4Nubv(GLuint index, const GLubyte *v) glVertexAttrib4Nusv(GLuint index, const GLushort *v) glVertexAttrib4Nuiv(GLuint index, const GLuint *v)

Parameters index

Specifies t he index of t he generic vert ex at t ribut e t o be m odified.

v

Specifies a point er t o an array of values t o be used for t he gener ic vert ex at t ribut e.

Description OpenGL defines a num ber of st andard vert ex att r ibut es t hat applicat ions can m odify w it h st andard API ent ry point s ( color, norm al, t ext ure coordinat es, et c.) . The glVertexAttrib fam ily of ent ry point s allows an applicat ion t o pass generic vert ex at t ribut es int o num bered locat ions. Generic at t ribut es are defined as four - com ponent values t hat are organized int o an array. The first ent ry of t his array is num bered 0, and t he size of t he array is specified by t he im plem ent at ion- dependent const ant GL_MAX_VERTEX_ATTRI BS. I ndividual elem ent s of t his array can be m odified wit h a glVertexAttrib call t hat specifies t he index of t he elem ent t o be m odified and a value for t hat elem ent . These com m ands can specify one, t w o, t hr ee, or all four com ponent s of t he generic vert ex at t ribut e specified by index. A 1 in t he com m and nam e m eans t hat only one value is passed and t hat it m odifies t he first com ponent of t he generic vert ex at t ribut e. The second and t hird com ponent s are set t o 0, and t he fourt h com ponent is set t o 1. Sim ilarly, a 2 in t he com m and nam e m eans t hat values are provided for t he first t w o com ponent s, t he t hird com ponent is set t o 0, and t he four t h com ponent is set t o 1. A 3 in t he com m and nam e m eans t hat values are provided for t he first t hree com ponent s and t hat t he fourt h com ponent is set t o 1, and a 4 in t he com m and nam e m eans t hat values are pr ovided for all four com ponent s. The let t ers s, f, i, d, ub, us, and ui specify whet her t he argum ent s are of t ype short , float , int , double, unsigned byt e, unsigned short , or unsigned int . When v is appended t o t he nam e, t he com m ands can t ake a point er t o an array of such values. The let t er N in a com m and nam e m eans t hat t he argum ent s ar e passed as fixed- point values t hat are scaled t o a norm alized range according t o t he com ponent conversion rules defined by t he OpenGL specificat ion. Signed values ar e underst ood t o r epresent fixed- point values in t he range [ - 1,1] , and unsigned values are underst ood t o represent fixed- point values in t he range [ 0,1] . OpenGL Shading Language at t ribut e variables are allowed t o be of t ype m at 2, m at 3, or m at 4. At t ribut es of t hese t ypes can be loaded by t he glVertexAttrib ent ry point s. Mat rices m ust be loaded int o successive generic at t ribut e slot s in colum n m aj or order, wit h one colum n of t he m at r ix in each generic at t ribut e slot . A user- defined at t ribut e variable declared in a vert ex shader can be bound t o a generic at t ribut e index w it h glBindAttribLocation. Such binding allows an applicat ion t o use m ore descript ive variable nam es in a vert ex shader. A subsequent change t o t he specified generic vert ex at t ribut e is im m ediat ely reflect ed as a change t o t he corresponding at t ribut e variable in t he ver t ex shader . The binding bet ween a generic vert ex at t ribut e index and a user - defined at t ribut e var iable in a ver t ex shader is par t of t he st at e of a pr ogram obj ect , but t he current value of t he generic vert ex at t ribut e is not . The value of each generic vert ex at t ribut e is part of current st at e, j ust like st andard vert ex at t ribut es, and it is m aint ained even if a differ ent pr ogram obj ect is used. An applicat ion m ay freely m odify generic vert ex at t r ibut es t hat are not bound t o a nam ed ver t ex shader at t ribut e variable. These values are sim ply m aint ained as part of cur rent st at e and are not accessed by t he vert ex shader. I f a generic vert ex at t ribut e bound t o an at t r ibut e variable in a vert ex shader is not updat ed while t he vert ex shader is execut ing, t he vert ex shader repeat edly uses t he current value for t he generic vert ex at t ribut e. The generic vert ex at t ribut e wit h index 0 is t he sam e as t he vert ex posit ion at t ribut e previously defined by OpenGL. A glVertex2, glVertex3, or glVertex4 com m and is com plet ely equivalent t o t he corresponding glVertexAttrib com m and wit h an index argum ent of 0. A vert ex shader can access generic vert ex at t ribut e 0 by using t he built - in at t ribut e variable gl_Vertex. There are no current values for generic vert ex at t ribut e 0. This is t he only generic vert ex at t ribut e wit h t his propert y; calls t o set ot her st andard vert ex at t ribut es can be fr eely m ixed wit h calls t o set any of t he ot her generic vert ex at t ribut es.

Notes glVertexAttrib is available only if t he GL version is 2.0 or great er.

Generic vert ex at t ribut es can be updat ed at any t im e. I n part icular, glVertexAttrib can be called bet w een a call t o glBegin and t he corresponding call t o glEnd. An applicat ion can bind m or e t han one at t ribut e nam e t o t he sam e generic vert ex at t ribut e index. This is referred t o as aliasing, and it is allowed only if j ust one of t he aliased at t ribut e variables is act ive in t he vert ex shader, or if no pat h t hrough t he vert ex shader consum es m ore t han one of t he at t ribut es aliased t o t he sam e locat ion. OpenGL im plem ent at ions are not required t o do error checking t o det ect aliasing; t hey are allowed t o assum e t hat aliasing does not occur, and t hey are allowed t o em ploy opt im izat ions t hat w ork only in t he absence of aliasing. There is no provision for binding st andard vert ex at t ribut es; t herefore, it is not possible t o alias gener ic at t ribut es wit h st andard at t ribut es.

Errors GL_I NVALI D_VALUE is generat ed if index is great er t han or equal t o GL_MAX_VERTEX_ATTRI BS.

Associated Gets glGet wit h t he argum ent GL_CURRENT_PROGRAM glGetActiveAttrib wit h argum ent program and t he index of an act ive at t ribut e variable glGetAttribLocation wit h argum ent program and an at t ribut e var iable nam e glGetVertexAttrib wit h argum ent s GL_CURRENT_VERTEX_ATTRI B and index

See Also glBindAttribLocation, glVertex, glVertexAttribPointer

glVertexAttribPointer Name glVertexAttribPointer Defines a generic vert ex at t ribut e array

C Specification void glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer)

Parameters index

Specifies t he index of t he generic vert ex at t ribut e t o be m odified.

size

Specifies t he num ber of values for each elem ent of t he generic vert ex at t ribut e array. Must be 1, 2, 3, or 4.

type

Specifies t he dat a t ype of each com ponent in t he array. Sym bolic const ant s GL_BYTE, GL_UNSI GNED_BYTE, GL_SHORT, GL_UNSI GNED_SHORT, GL_I NT, GL_UNSI GNED_I NT, GL_FLOAT, and GL_DOUBLE are accept ed.

normalized

Specifies w het her fixed- point dat a values should be norm alized ( GL_TRUE) or convert ed direct ly as fixed- point values ( GL_FALSE) when t hey are accessed.

stride

Specifies t he byt e offset bet w een consecut ive at t ribut e values. I f stride is 0 ( t he init ial value) , t he at t ribut e values are underst ood t o be t ight ly packed in t he array.

pointer

Specifies a point er t o t he first com ponent of t he first at t ribut e value in t he array.

Description glVertexAttribPointer specifies t he locat ion and dat a form at of an array of generic vert ex at t ribut e values t o use when rendering. size specifies t he num ber of com ponent s per at t ribut e and m ust be 1, 2, 3, or 4. type specifies t he dat a t ype of each com ponent , and stride specifies t he byt e

st ride from one at t r ibut e t o t he next , allowing at t ribut e values t o be int erm ixed wit h ot her at t ribut e values or st ored in a separat e array. A value of 0 for stride m eans t hat t he values are st ored sequent ially in m em ory wit h no gaps bet ween successive elem ent s. I f set t o GL_TRUE, normalized m eans t hat values st ored in an int eger form at are t o be m apped t o t he range [ 1,1] ( for signed values) or [ 0,1] ( for unsigned values) when t hey are accessed and convert ed t o float ing point . Ot herw ise, values are convert ed t o float s direct ly wit hout norm alizat ion. When a generic vert ex at t ribut e array is specified, size, type, normalized, stride, and pointer are saved as client - side st at e.

To enable and disable t he generic vert ex at t ribut e array, call glEnableVertexAttribArray and glDisableVertexAttribArray w it h index. I f enabled, t he generic vert ex at t ribut e array is used w hen glDrawArrays, glDrawElements, glDrawRangeElements, glArrayElement, glMultiDrawElements, or glMultiDrawArrays is called.

Notes glVertexAttribPointer is available only if t he GL version is 2.0 or great er.

Each generic vert ex at t ribut e array is init ially disabled and is not accessed when glDrawArrays, glDrawElements, glDrawRangeElements, glArrayElement, glMultiDrawElements, or glMultiDrawArrays is called. Execut ion of glVertexAttribPointer is not allowed bet ween t he execut ion of glBegin and glEnd, but an error m ay or m ay not be gener at ed. I f no error is generat ed, t he operat ion is undefined. glVertexAttribPointer is t ypically im plem ent ed on t he client side.

Generic vert ex at t ribut e array param et ers are client - side st at e and are t herefore not saved or rest ored by glPushAttrib and glPopAttrib. Use glPushClientAttrib and glPopClientAttrib inst ead.

Errors GL_I NVALI D_VALUE is generat ed if index is great er t han or equal t o GL_MAX_VERTEX_ATTRI BS. GL_I NVALI D_VALUE is generat ed if size is not 1, 2, 3, or 4. GL_I NVALI D_ENUM is generat ed if type is not an accept ed value. GL_I NVALI D_VALUE is generat ed if stride is negat ive.

Associated Gets glGet wit h argum ent GL_MAX_VERTEX_ATTRI BS glGetVertexAttrib wit h argum ent s index and t he nam e of a vert ex at t ribut e param et er glGetVertexAttribPointer wit h argum ent s index and GL_VERTEX_ATTRI B_ARRAY_POI NTER

See Also glArrayElement, glBindAttribLocation, glDisableVertexAttribArray, glDrawArrays, glDrawElements, glDrawRangeElements, glEnableVertexAttribArray, glMultiDrawArrays, glMultiDrawElements, glPopClientAttrib, glPushClientAttrib, glVertexAttrib

OpenGL 1.5 to OpenGL 2.0 GLSL Migration Guide The OpenGL Shading Language was init ially suppor t ed t hrough ARB ext ensions t o OpenGL 1.5. The following t able ( originally com piled by Teri Morrison) docum ent s t he m apping of OpenGL 1.5 ARB ext ension API ent r y point s t o t he OpenGL 2.0 API ent ry point s. glAttachObjectARB

Renam ed t o glAttachShader. I nput argum ent s program and shader were changed from GLhandleARB t o GLuint .

glBindAttribLocationARB

Renam ed t o glBindAttribLocation. I nput argum ent program w as changed from GLhandleARB t o GLuint . I nput argum ent name was changed from const GLcharARB* t o const GLchar* .

glCompileShaderARB

Renam ed t o glCompileShader. I nput argum ent shader w as changed from GLhandleARB t o GLuint .

glCreateProgramObjectARB

Renam ed t o glCreateProgram. Funct ion ret urn value was changed from GLhandleARB t o GLuint .

glCreateShaderObjectARB

Renam ed t o glCreateShader. Funct ion ret urn value was changed from GLhandleARB t o GLuint .

glDeleteObjectARB

Split int o t wo funct ions, glDeleteProgram and glDeleteShader. I nput argum ent object was changed from GLhandleARB t o GLuint . Addit ional error checking was added t o ensure t hat t he input argum ent in t he new funct ion ( program or shader) is t he pr oper obj ect t ype.

glDetachObjectARB

Renam ed t o glDetachShader. I nput argum ent s program and shader were changed from GLhandleARB t o GLuint .

glDisableVertexAttribArrayARB Renam ed t o glDisableVertexAttribArray. glEnableVertexAttribArrayARB Renam ed t o glEnableVertexAttribArray. glGetActiveAttribARB

Renam ed t o glGetActiveAttrib. I nput argum ent program w as changed from GLhandleARB t o GLuint . I nput argum ent name was changed from GLcharARB* t o GLchar* .

glGetActiveUniformARB

Renam ed t o glGetActiveUniform. I nput argum ent program w as changed from GLhandleARB t o GLuint . I nput argum ent name was changed from GLcharARB* t o GLchar* .

glGetAttachedObjectsARB

Renam ed t o glGetAttachedShaders. I nput argum ent program was changed from GLhandleARB t o GLuint . I nput argum ent objects was changed from GLhandleARB* t o GLuint * .

glGetAttribLocationARB

Renam ed t o glGetAttribLocation. I nput argum ent program w as changed from GLhandleARB t o GLuint . I nput argum ent name was changed from const GLcharARB* t o const GLchar* .

glGetHandleARB

Replaced by calling glGet wit h t he sym bolic const ant GL_CURRENT_PROGRAM.

glGetInfoLogARB

Split int o t wo funct ions, glGetProgramInfoLog and glGetShaderInfoLog. I nput argum ent object was changed from GLhandleARB t o GLuint . Out put argum ent infoLog w as changed from const GLcharARB* t o const GLchar* . New error checking was added t o ensure t hat t he input

argum ent in t he new funct ion (program or shader) is t he proper obj ect t ype. glGetObjectParameterARB

Split int o t wo funct ions, glGetProgram and glGetShader. I nput argum ent object was changed from GLhandleARB t o GLuint . Addit ional error checking was added t o ensure t hat t he input argum ent in t he new funct ion (program or shader) is t he proper obj ect t ype. I n OpenGL 2.0 t here is no equivalent for t he float ing- point version of t he ARB funct ion glGetObjectParameterfvARB.

glGetShaderSourceARB

Renam ed t o glGetShaderSource. I nput argum ent shader w as changed from GLhandleARB t o GLuint . Out put argum ent source was changed from const GLcharARB* t o const GLchar* .

glGetUniformARB

Renam ed t o glGetUniform. I nput argum ent program w as changed from GLhandleARB t o GLuint .

glGetUniformLocationARB

Renam ed t o glGetUniformLocation. I nput argum ent program was changed from GLhandleARB t o GLuint . I nput argum ent name was changed from const GLcharARB* t o const GLchar* .

glGetVertexAttribARB

Renam ed t o glGetVertexAttrib.

glGetVertexAttribPointerARB

Renam ed t o glGetVertexAttribPointer.

glLinkProgramARB

Renam ed t o glLinkProgram. I nput argum ent program w as changed from GLhandleARB t o GLuint .

glShaderSourceARB

Renam ed t o glShaderSource. I nput argum ent shader w as changed from GLhandleARB t o GLuint . I nput argum ent strings was changed from const GLcharARB* * t o const GLchar* * .

glUniformARB

Renam ed t o glUniform.

glUseProgramObjectARB

Renam ed t o glUseProgram. I nput argum ent program w as changed from GLhandleARB t o GLuint .

glValidateProgramARB

Renam ed t o glValidateProgram. I nput argum ent program w as changed from GLhandleARB t o GLuint .

glVertexAttribARB

Renam ed t o glVertexAttrib.

glVertexAttribPointerARB

Renam ed t o glVertexAttribPointer.

New functions

The funct ions glIsProgram and glIsShader were added in OpenGL 2.0 and have no equivalent in t he ARB ext ensions t hat support GLSL. The funct ion glDrawBuffers w as prom ot ed t o OpenGL 2.0 from t he ARB_draw _buffers ext ension specificat ion, where it was called glDrawBuffersARB.

Afterword Writ ing a book requires a lot of t im e and effort . Som et im es aut hors refer t o t he finished product as " a labor of love." I have t o say t hat for m e, writ ing t his book has been " a labor of fun." I have been fort unat e t o part icipat e in a m aj or archit ect ural revolut ion in com put er graphics hardw are. I n t he last few years, consum er graphics hardware has undergone a sea changefrom pure fixed funct ionalit y t o alm ost com plet e user program m abilit y. I n m any ways, t his t im e feels like t he lat e 1970s and early 1980s, when significant advances were being m ade in com put er graphics at places like t he Universit y of Ut ah, NYU, Lucasfilm , JPL, UNC, and Cornell. The difference t his t im e is t hat graphics hardware is now cheap enough and fast enough t hat you don't have t o work at a resear ch inst it ut e or at t end an elit e graduat e school t o play wit h it . You can explore t he brave new world on your ow n personal com put er . I t is relat ively rare t o part icipat e in est ablishing even one indust ry st andard, but I have had t he good fort une t o play a role in t he definit ion of t hree im port ant graphics st andards. First w as PEX in t he lat e 1980s. Next was OpenGL in t he early 1990s, and now, t he OpenGL Shading Language in t he first years of t he new m illennium . These effort s have been grat ifying t o m e because t hey pr ovide graphics hardware capabilit ies t o people in an indust ry- st andard way. Applicat ions writ t en t o a st andard are port able, and t herefore t he t echnology t hey are built on is accessible t o a wider audience. I t 's been a labor of fun because it is a lot of fun and t ruly rem arkable t o be one of t he first people t o im plem ent classic rendering algorit hm s by using a high- level language on low- cost but high- perform ance graphics hardware. When our t eam first got t he brick shader running on 3Dlabs Wildcat VP graphics hardware, it was a j aw - dropping " Wow! " m om ent . A sim ilar feeling occurred when I got a shader I was developing t o run successfully for t he first t im e or saw, working for t he first t im e, a shader writ t en by som eone else in t he group. I t seem s t o m e t hat t his feeling m ust be sim ilar t o t hat felt by t he gr aphics pioneers 2025 years ago when t hey got t he first successful result s from t heir new algorit hm s. And it is great fun t o hear from end users who experience t hose sam e sort s of j aw - dropping " Wow! " m om ent s. Because of t he archit ect ural revolut ion in consum er graphics hardware, t oday, people like you and m e can quickly and easily writ e shaders t hat im plem ent t he rendering algorit hm s devised 20 years ago by t he pioneers of com put er graphics. To im plem ent bum p m apping, we looked up Blinn's 1978 paper, and t o im plem ent part icle syst em s, we looked at Reeves's 1983 paper. I chuckled t o m yself when I saw t he hand- drawn diagram s in Alvy Ray Sm it h's 1983 m em o on digit al filt ering. I m ages t hat t ook hours t o generat e t hen t ake m illiseconds t o render t oday. And shader code t hat t ook weeks t o develop can now be writ t en in m inut es w it h a high- level shading language developed specifically for t his t ask. I t is m ind- boggling t o t hink how painst aking it m ust have been for Mandelbrot t o generat e im ages of his fam ous set in t he lat e 1970s, com pared t o how easy it is t o do t oday wit h t he OpenGL Shading Language. And part of t he reason t hat I 've so enj oyed writ ing t his book is t hat I know t here are significant new discoveries t o be m ade in t he area of com put er graphics. I f som eone like m e can sim ply and easily im plem ent rendering algorit hm s t hat previously could run only on soft ware on CPUs, im agine how m uch m ore is possible wit h t he progr am m able graphics hardware t hat is available t oday. The availabilit y of low- cost program m able graphics hardware m akes it possible for m any m ore people t o experim ent w it h new rendering t echniques. Algorit hm s of m uch higher com plexit y can be developed. And I know t hat som e of you out t here w ill invent som e excit ing new rendering t echniques when using t he OpenGL Shading Language. This t echnology is m oving rapidly t o handheld devices such as PDAs and cell phones. A version of t he OpenGL Shading Language for em bedded devices was approved as part of OpenGL ES in t he sum m er of 2005. That m eans t hat m illions of devices will soon be running applicat ions t hat use GLSL t o unlock t he power of t he underlying program m able graphics hardware.

My m ission in writ ing t his book has been t o educat e you and, perhaps m ore im port ant , t o t ry t o open your eyes t o t he rendering possibilit ies t hat exist beyond t he fixed funct ionalit y wit h which we've been shackled for so m any years. I n m y view , t here's no longer any reason t o cont inue t o use t he fixed funct ionalit y of OpenGL. Everyone should be writ ing shaders t o render t hings t he way t hey want inst ead of t he way t he fixed funct ionalit y graphics har dw are has allowed. I encourage you t o t hink out side t he box, explore new ways of get t ing pixels on t he screen, and share your discover ies w it h ot hers. I f you w ant , you can send your discoveries t o m e at [email protected] and I 'll m ake t hem available t o ot hers on m y Web sit e. Keep on pushing t he pixels, and best of luck in all your rendering endeavors! Randi Rost , Fort Collins, CO June 2003, 1st edit ion August 2005, 2nd edit ion

Glossary

1D

TEX TURE

A one- dim ensional ( widt h only) array of values st ored in t ext ure m em ory.

2D

TEX TURE

A t wo- dim ensional ( widt h and height ) array of values st ored in t ext ur e m em ory.

3D

TEX TURE

A t hree- dim ensional ( widt h, height , and dept h) array of values st ored in t ext ure m em or y.

ACCUM ULATI ON BUFFER

An OpenGL offscreen m em ory buffer t hat can accum ulat e t he result s of m ult iple rendering operat ions. This buffer oft en has m ore bit s per pixel t han t he ot her offscreen m em ory buffers in order t o support such accum ulat ion operat ions.

ACTI V E ATTRI BUTES

At t ribut e variables t hat can be accessed when a vert ex shader is execut ed, including built - in at t ribut e variables and user- defined at t ribut e variables. ( I t is allowed t o have at t ribut e variables t hat are defined but never used wit hin a vert ex shader.)

ACTI VE SAM PLERS

Sam plers t hat can be accessed when a program is execut ed.

ACTI V E TEX TU RE UN I T

The t ext ur e unit current ly defined as t he t arget of com m ands t hat m odify t ext ure access st at e such as t he current 1D/ 2D/ 3D/ cube m ap t ext ure, t ext ure unit enable/ disable, t ext ure environm ent st at e, and so on.

ACTI VE UN I FORM S

Uniform variables t hat can be accessed when a shader is execut ed, including built - in uniform variables and user- defined uniform variables. ( I t is allowed t o have uniform variables t hat ar e defined but never used wit hin a shader.)

ALI ASI N G

Ar t ifact s caused by insufficient sam pling or inadequat e repr esent at ion of high- frequency com ponent s in a com put er graphics im age. These art ifact s are also com m only referred t o as " j aggies."

ALPH A

The fourt h com ponent of a color value ( aft er red, green, and blue) . Alpha indicat es t he opacit y of a pixel ( 1.0 m eans t he pixel is fully opaque; 0.0 m eans t he pixel is fully t ransparent ) . Alpha is used in color blending operat ions.

ALPH A TEST

An OpenGL pipeline st age t hat discards fragm ent s depending on t he out com e of a com parison bet w een t he current fragm ent 's alpha value and a const ant r eference alpha value.

AM BI EN T OCCLUSI ON

A t echnique for producing m ore realist ic light ing and shadowing effect s t hat uses a precom put ed occlusion ( or accessibilit y) fact or t o scale t he diffuse illum inat ion at each point on t he surface of an obj ect .

AM PLI TUD E

The dist ance of a funct ion's m axim um or m inim um from t he m ean of t he funct ion.

AN I SOTROPI C

Som et hing wit h propert ies t hat differ when m easured in different direct ions, such as t he propert y of a m at erial ( anisot r opic reflect ion) or a charact erist ic of an algor it hm ( anisot ropic t ext ure filt ering) . Cont rast wit h I SOTROPI C.

AN TI ALI ASI N G

The effort t o reduce or elim inat e art ifact s caused by insufficient sam pling or inadequat e represent at ion of high- frequency com ponent s in a com put er graphics im age.

APPLI CATI ON PROGRAM M I N G I N TERFACE

( API )

A source- level int erface provided for use by applicat ions.

AREA SAM PLI N G

An ant ialiasing t echnique t hat considers t he area of t he prim it ive being sam pled. This m et hod usually produces bet t er result s t han eit her point sam pling or supersam pling, but it can be m ore expensive t o com put e.

ATTEN UATI ON

I n t he light ing com put at ion, t he effect of light int ensit y dim inishing as a funct ion of dist ance from t he light source.

ATTRI BUTE ALI ASI N G

Binding m ore t han one user- defined at t ribut e var iable t o t he sam e gener ic vert ex at t ribut e index. This binding is allowed only if j ust one of t he aliased at t ribut es is act ive in t he execut able pr ogram or if no pat h t hr ough t he shader consum es m ore t han one at t ribut e of a set of at t ribut es aliased t o t he sam e locat ion.

ATTRI BUTE V ARI ABLE

An OpenGL Shading Language variable t hat is qualified wit h t he attribute keyword. At t ribut e var iables cont ain t he values t hat an applicat ion passes t hrough t he OpenGL API by using generic, num bered vert ex at t ribut es. Wit h at t ribut e var iables, a vert ex shader can obt ain unique dat a at every vert ex. These variables are read- only and can be defined only in vert ex shaders. At t ribut e variables are used t o pass frequent ly changing dat a t o a shader.

AUX I LI ARY BUFFER

A region of offscreen m em ory t hat st ores arbit r ary or generic dat a, for exam ple, int erm ediat e result s from a m ult ipass rendering algorit hm . A fram ebuffer m ay have m ore t han one associat ed auxiliary buffer.

BEN T N ORM AL

A surface at t ribut e t hat represent s t he average direct ion of t he available light t hat is received at t hat point on t he surface. This value is com put ed as follows: Cast rays from t he point on t he surface in t he hem isphere indicat ed by t he surface norm al and t hen average all rays t hat are unoccluded by ot her part s of t he m odel.

BI D I RECTI ON AL REFLECTAN CE D I STRI BU TI ON FU N CTI ON

( BRD F )

A m odel for com put ing t he reflect ion from a surface. The elevat ion and azim ut h angles of t he incom ing and out going energy direct ions are used t o com put e t he r elat ive am ount of energy reflect ed in t he out going direct ion. Measurem ent s of real- world m at erials can be used in t his com put at ion t o creat e a m ore realist ic looking surface. BRDFs can m ore accurat ely render m at erials w it h anisot ropic reflect ion pr opert ies.

BRD F

See

BI DI RECTI ONAL REFLECTANCE DI STRI BUTI ON FUNCTI ON .

BU FFERS

Regions of m em ory on t he graphics accelerat or devot ed t o st oring a part icular t ype of dat a. A color buffer st ores color values, a dept h buffer st ores dept h values, et c.

BU M P M AP

A t wo- dim ensional array of norm al pert urbat ion values t hat can be st or ed in t ext ure m em ory.

BU M P M APPI N G

A rendering t echnique t hat sim ulat es t he appearance of bum ps, wrinkles, or ot her surface irregularit ies by pert urbing surface norm als before light ing calculat ions are perform ed.

CALL BY V ALUE - RETURN

A subrout ine calling convent ion whereby input param et ers are copied int o t he funct ion at call t im e and out put param et ers are copied back t o t he caller before t he funct ion exit s.

CH ROM ATI C ABERRATI ON

The t endency of a lens t o bend light of different colors by unequal am ount s because of differences in t he indices of refract ion of t he const it uent wavelengt hs of t he light .

CH ROM ATI C D I SPERSI ON

The effect of dist ribut ing a light source int o it s const it uent wavelengt hs, for exam ple, by passing it t hrough a prism .

CLI P SPACE

See

CLI PPI NG COORDI NATE SYSTEM .

CLI PPI N G

The pr ocess of com paring incom ing gr aphics prim it ives t o one or m ore reference planes and discarding any port ion of prim it ives t hat are deem ed t o be out side t hose reference planes.

CLI PPI N G COORD I N ATE SYSTEM

The coordinat e syst em in which view - volum e clipping occurs. Graphics prim it ives are t ransform ed from t he eye coordinat e syst em int o t he clipping coordinat e syst em by t he proj ect ion m at rix.

COLOR SU M

The OpenGL pipeline st age t hat adds t oget her t he prim ary color and t he secondary color. This st age occurs aft er t ext uring t o allow a specular highlight t hat is t he color of t he light source t o be applied on t op of t he t ext ured surface.

COM PI LER FRON T EN D

The part of t he com piler t hat perform s lexical, synt act ical, and sem ant ic analysis of source code and produces a binary repr esent at ion of t he code t hat is suit able for consum pt ion by subsequent phases of com pilat ion.

CON STRUCTOR

A program m ing language feat ure for init ializing aggregat e dat a t ypes or convert ing bet w een dat a t ypes.

CON TROL TEX TURE

A t ext ure m ap whose prim ary funct ion is t o provide values t hat det erm ine t he behavior of a rendering algorit hm rat her t han pr ovide dat a for t he rendering process.

CON V OLUTI ON

The weight ed average of a funct ion over a specified int erval.

CON V OLUTI ON FI LTER

See

CONVOLUTI ON KERNEL.

CON V OLUTI ON KERN EL

The values t hat are used for weight ing in a convolut ion operat ion.

CUBE M AP

A t ext ure m ap com prising six 2D t ext ures t hat correspond t o faces on a cube. The faces are ident ified by t heir axial dir ect ion ( ± x, ± y, ± z) , and t he pr oper face is aut om at ically select ed when a t ext ure access is perform ed.

CUBE M APPI N G

The pr ocess of accessing t he proper face of a cube m ap t ext ure t o ret rieve t he value t hat will be used in t ext ure applicat ion. Cube m apping is one m et hod for perform ing environm ent m apping.

CULLI N G

The act of discarding graphics prim it ives according t o a part icular crit erion, such as whet her t he prim it ives are back facing wit h respect t o t he current viewing posit ion.

D EFERRED SH AD I N G

A shading algorit hm t hat first ident ifies t he visible surfaces in a scene and t hen applies a shading effect only t o t hose visible surfaces.

D EPEN D EN T TEX TURE READ

A t ext ure access operat ion t hat depends on values obt ained from a pr evious t ext ureaccess operat ion.

D EPTH BUFFER

An OpenGL offscreen m em ory buffer t hat m aint ains dept h values. This buffer st ores t he

dept h of t he t opm ost visible graphics prim it ive at each pixel. I n conj unct ion wit h t he dept h t est operat ion, t his buffer can perform hidden surface elim inat ion.

D EPTH - CUI N G

A graphics rendering t echnique t hat alt ers t he appearance of a graphics prim it ive according t o it s dist ance from t he viewer. Dept h- cuing is oft en used t o fade t he color of dist ant pr im it ives t o t he background color t o m ake t hem appear m ore dist ant .

D EPTH M AP

See

SHADOW MAP.

D EPTH TEST

An OpenGL pipeline st age t hat com pares t he dept h associat ed wit h t he incom ing fragm ent wit h t he dept h value ret r ieved from t he fram ebuffer. I f t he t est fails, t he fragm ent is discarded.

D I FFRACTI ON

The change in t he direct ions and int ensit ies of a group of waves ( e.g., light w aves) as t hey pass by an obst acle or pass t hrough an apert ure.

D I FFRACTI ON GRATI N G

A glass or m et al surface wit h large num bers of sm all, par allel, equally spaced grooves or slit s t hat produces a diffract ion effect .

D I SPLAY LI ST

A sequence of OpenGL com m ands t hat is st ored in OpenGLm anaged m em ory for lat er execut ion.

D I SPLAY LI ST M OD E

A m ode of rendering in which OpenGL com m ands are st ored in a display list for execut ion at a lat er t im e rat her t han being execut ed when t hey are specified.

D I SPLAY M EM ORY

Fram ebuffer m em ory t hat is allocat ed t o m aint aining t he im age displayed on t he com put er m onit or or LCD. Display m em ory is read m any t im es per second ( t he refresh rat e) and updat es t he visible display surface.

D OUBLE BUFFERI N G

A graphics rendering t echnique t hat involves rendering t o a back buffer while displaying a front buffer. When rendering is com plet ed, t he t wo buffers are swapped. I n t his way, t he end user never sees part ially com plet e im ages, and anim at ion can be sm oot her and m ore realist ic.

D RI V ER

A piece of soft ware t hat int eract s wit h t he nat ive operat ing syst em and cont rols a specific piece of hardw are in t he syst em .

EN V I RON M EN T M APPI N G

A rendering t echnique t hat involves saving t he scene surrounding an obj ect as one or m ore specialized t ext ure m aps and t hen, when rendering t he obj ect , accessing t hese t ext ure m aps t o com put e accurat e reflect ions of t hat environm ent .

EQU I RECTAN GULAR TEX TURE M AP

A rect angular 2D t ext ure t hat can be used as an environm ent m ap. The t ext ure spans 360° horizont ally and 180° vert ically. Signif icant dist ort ion occurs t oward t he t op and bot t om of t he t ext ure. Also know n as a LATI TUDE- LONGI TUDE ( or LAT- LONG) TEXTURE MAP.

EX ECUTABLE

The m achine code int ended for execut ion on t he ver t ex processor or t he fragm ent processor.

EYE COORD I N ATE SYSTEM

The coordinat e syst em t hat is defined t o have t he eye ( view ing) posit ion at t he origin. Graphics prim it ives are t ransform ed by t he m odelview m at r ix from t he m odeling ( or obj ect ) coordinat e syst em int o t he eye coordinat e syst em .

EYE SPACE

see

EYE COORDI NATE SYSTEM.

FI LTERI N G

The pr ocess of calculat ing a single value according t o t he values of m ult iple sam ples in t he neighbor hood of t hat value.

FI X ED FU N CTI ON ALI TY

The t erm used t o describe port ions of t he OpenGL pipeline t hat are not progr am m able. These port ions of OpenGL operat e in a fixed fashion, and t he behavior can be alt ered only when a predefined set of st at e var iables is changed t hrough t he OpenGL API .

FLAT SH AD I N G

The t erm used t o describe t he applicat ion of a single color value t o t he ext ent of a prim it ive ( cont rast wit h SMOOTH SHADI NG) .

FOG

A rendering t echnique t hat sim ulat es at m ospheric effect s due t o part iculat es such as t hose cont ained in clouds and sm og. Fog is com put ed by at t enuat ion of t he obj ect color as a funct ion of dist ance from t he view er.

FRACTAL

A geom et rically com plex obj ect , t he com plexit y of which arises t hrough t he repet it ion of a given form over a range of scales. ( Ken Musgrave)

FRAGM EN T

The set of dat a t hat is generat ed by rast erizat ion and t hat r epresent s t he inform at ion necessary t o updat e a single fram ebuffer locat ion. A fragm ent consist s of a w indow coordinat e posit ion and associat ed dat a such as color, dept h, t ext ure coordinat es, and t he like.

FRAGM EN T PROCESSI N G

An OpenGL pipeline st age t hat defines t he operat ions t hat occur t o a fragm ent produced by rast erizat ion before t he back- end processing st ages. For OpenGL fixed funct ionalit y, fragm ent processing operat ions include t ext ure access, t ext ure applicat ion, fog, and color sum . For t he OpenGL program m able fragm ent pr ocessor, any t ype of per- fragm ent processing m ay be perform ed.

FRAGM EN T PROCESSOR

A program m able unit t hat replaces t he t r adit ional fixed funct ionalit y fr agm ent processing st age of OpenGL. Fragm ent shaders are execut ed on t he fragm ent processor.

FRAGM EN T SH AD ER

A program writ t en in t he OpenGL Shading Language for execut ion on t he fragm ent processor. The fragm ent shader's m a in funct ion is execut ed once for each fragm ent gener at ed by rast er izat ion and can be pr ogram m ed t o perform bot h t radit ional operat ions ( t ext ure access, t ext ure applicat ion, fog) and nont radit ional operat ions.

FRAM EBUFFER

The region of graphics m em ory t hat st ores t he result s of OpenGL rendering operat ions. Part of t he fram ebuffer ( t he front buffer) is visible on t he display device, and part of it is not .

FRAM EBUFFER OPERATI ON S

An OpenGL pipeline st age cont aining operat ions t hat cont rol or affect t he whole fram ebuffer ( e.g., buffer m asking operat ions, buffer clear operat ions) .

FREQUEN CY

The m easur e of periodicit y in a funct ion ( i.e., how oft en t he pat t ern of a funct ion repeat s) .

F RESN EL EFFECT The result of t r ansparent m at erials causing light t o be bot h reflect ed and refr act ed, wit h t he am ount of light reflect ed and refract ed depending on t he viewing angle.

FRUSTUM

See

VI EW FRUSTUM.

FRUSTUM CLI PPI N G

An OpenGL pipeline st age t hat clips prim it ives t o t he view frust um .

GEOM ETRI C PRI M I TI V E

A point , line, or polygon.

GLOSS M AP

A t ext ure m ap t hat cont rols t he reflect ive charact erist ics of a surface rat her t han supply im age dat a for t he t ext uring operat ion.

GLYPH BOM BI N G

TEXTURE BOMBI NG

G OOCH

using charact er glyphs from a t ext ure m ap.

SH AD I N G

A non- phot orealist ic rendering t echnique t hat at t em pt s t o duplicat e t he look of a t echnical illust rat ion. This t echnique is also called a low dynam ic range art ist ic t one algorit hm .

G OU RAUD

SH AD I N G

See

SMOOTH SHADI NG.

GRAD I EN T

The m easure of how rapidly a funct ion is changing in a part icular direct ion. Properly, t his is a vect or ( see GRADI ENT VECTOR) . More com m only, t he m agnit ude of t he gr adient vect or for t he funct ion f( x,y) in a part icular direct ion is referred t o as t he gradient of t he funct ion f( x,y) in t hat direct ion.

GRAD I EN T N OI SE

See PERLI N NOI SE.

GRAD I EN T V ECTOR

A vect or t hat defines t he rat e of change of a funct ion in all direct ions. The gradient vect or for t he funct ion f( x,y) cont ains t wo com ponent s: t he part ial derivat ive of f w it h respect t o x and t he part ial derivat ive of f w it h respect t o y.

GRAPH I CS ACCELERATOR

Hardware dedicat ed t o t he process of rendering and displaying graphics.

GRAPH I CS CON TEX T

The OpenGL dat a st ruct ure t hat cont ains t he st at e needed t o cont rol t he operat ion of t he rendering pipeline.

GRAPH I CS PROCESSI N G PI PELI N E

The sequence of operat ions t hat occurs when geom et ry or im age dat a defined by an applicat ion is t r ansform ed int o som et hing t hat is st ored in t he fram ebuffer. This processing is divided int o st ages t hat occur in a specific order. Each st age has defined input s and out put s and can be precisely described.

H EM I SPH ERE LI GH TI N G

The pr ocess of illum inat ing scenes and obj ect s by m odeling global illum inat ion as t wo hem ispheres, one represent ing t he color of t he sky and t he ot her represent ing t he color of t he ground ( or shadows) . Com put ing t he illum inat ion at any surface point is done by int egrat ing t he light from t he visible hem isphere at t hat point .

I M AGE- BASED LI GH TI N G

The pr ocess of illum inat ing scenes and obj ect s wit h im ages of light capt ured from t he real world.

I M AGI N G SUBSET

A collect ion of im aging- relat ed funct ionalit y t hat was added t o OpenGL as an opt ional subset in OpenGL 1.2. The im aging subset support s color m at rix, convolut ion, hist ogram , and various blending operat ions. Graphics hardware vendors are not required t o support t his funct ionalit y as part of t heir OpenGL im plem ent at ion.

I M M ED I ATE M OD E

A m ode of rendering in which graphics com m ands are execut ed when t hey are specified rat her t han st ored in a display list for lat er execut ion.

I N D EX OF REFRACTI ON

The pr opert y of a m at erial t hat defines t he rat io of t he speed of light in a vacuum t o t he speed of light in t hat m at erial.

I SOTROPI C

Som et hing wit h propert ies t hat are t he sam e along a pair of ort hogonal axes from w hich t hey are m easured ( i.e., rot at ionally invariant ) . Cont rast wit h ANI SOTROPI C.

KEY - FRAM E I N TERPOLATI ON

An anim at ion t echnique t hat produces " inbet ween" result s based on int erpolat ion bet ween t w o key fram es. This t echnique can save t im e and effort because t he obj ect s in t he scene do not need t o be painst akingly anim at ed for every fram e, only for t hose fram es t hat provide t he key t o t he overall anim at ion sequence.

L- VALU E

An expression ident ifying an obj ect in m em ory t hat can be writ t en t o. For exam ple, variables t hat ar e w rit able are l- values. Array indexing and st ruct ure m em ber select ion are expr essions t hat can result in l- values.

LACU N ARI TY

The frequency m ult iplier ( or gap) bet ween successive it erat ions of a sum m ed noise ( fract al) funct ion.

LATI TUD E - LON GI TUD E TEX TURE M AP

see

EQUI RECTANGULAR TEXTURE MAP.

LEV EL- OF - D ETAI L

The value t hat select s a m ipm ap level from a m ipm ap t ext ure. I ncrem ent ing t he level- ofdet ail by 1 result s in t he select ion of a m ipm ap level t hat is half t he resolut ion of t he previous one. Thus, increasing t he value used for level- of- det ail result s in t he select ion of m ipm ap levels t hat cont ain sm aller and sm aller t ext ures ( suit able for use on sm aller and sm aller obj ect s on t he screen) .

LEXI CAL AN ALYSI S

The pr ocess of scanning t he input t ext t o produce a sequence of t okens ( or t erm inal sym bols) for t he synt act ical analysis phase t hat follows. Charact ers or t okens t hat are not

part of t he language can be ident ified as errors during t his process. Som et im es t his process is referred t o as scanning.

LI GH T PROBE

A device or a syst em t hat capt ures an om nidirect ional, high dynam ic range im age of light from a real- world scene.

LI GH T PROBE I M AGE

An om nidirect ional, high dynam ic range im age of light capt ured from t he real world.

LOW - PASS FI LTERI N G

A m et hod of filt ering t hat elim inat es high frequencies but leaves low frequencies unm odified. Low- pass filt ers are som et im es called SMOOTHI NG FI LTERS because high frequencies are blurred ( sm oot hed) .

M I PM AP LEV EL

A specific t exel array wit hin a m ipm ap t ext ure.

M I PM AP TEX TU RE

An ordered set of t exel arrays represent ing t he sam e im age. Typically, each array has a resolut ion t hat is half t he previous one in each dim ension.

M OD EL SPACE

See

MODELI NG COORDI NATE SYSTEM.

M OD EL TRAN SFORM ATI ON M ATRI X

The m at rix t hat t ransform s coordinat es from t he m odeling coordinat e syst em int o t he world coordinat e syst em . I n OpenGL, t his m at rix is not available separat ely; it is always part of t he m odelview m at rix.

M OD ELI N G

The pr ocess of defining a num erical represent at ion of an obj ect t hat is t o be rendered, for

inst ance, defining t he Bezier cur ves t hat specify a t eapot , or t he vert ex posit ions, colors, surface norm als, and t ext ure coordinat es t hat define a bowling pin.

M OD ELI N G COORD I N ATE SYSTEM

A coordinat e syst em t hat is defined in a way t hat m akes it convenient t o specify and orient a single obj ect . Also known as t he OBJECT COORDI NATE SYSTEM or OBJECT SPACE.

M OD ELI N G TRAN SFORM ATI ON

The t ransform at ion t hat t akes coordinat es from t he m odeling coordinat e syst em int o t he world coordinat e syst em .

M OD ELV I EW M ATRI X

The m at rix t hat t ransform s coordinat es from t he m odeling coordinat e syst em int o t he eye coordinat e syst em .

M OD ELV I EW - PROJECTI ON M ATRI X

The m at rix t hat t ransform s coordinat es from t he m odeling coordinat e syst em int o t he clipping coordinat e syst em .

M ULTI FRACTAL

A funct ion w hose fract al dim ension varies according t o locat ion.

M ULTI SAM PLE BUFFER

A region of offscreen m em ory t hat can perform supersam pling by m aint aining m ore t han one sam ple per pixel and aut om at ically averaging t he sam ples t o pr oduce t he final, ant ialiased im age.

N EI GH BORH OOD AV ERAGI N G

An im age processing t echnique t hat low- pass filt ers ( sm oot hs) an im age by com put ing t he weight ed average of pixels in close pr oxim it y t o one anot her.

N OI SE

A cont inuous, ir regular funct ion wit h a defined range t hat cr eat es com plex and int erest ing pat t erns.

N ON - PH OTOREALI STI C REN D ERI N G

( N PR )

A class of rendering t echniques whose purpose is t o achieve som et hing ot her t han t he m ost realist ic result possible. Such t echniques m ay st rive t o achieve a paint erly or handdrawn appear ance, t he look of a t echnical illust rat ion, or a cart oonlike appearance. Hat ching and Gooch shading are exam ples of NPR t echniques.

N ORM AL M AP

A t ext ure m ap t hat cont ains norm als rat her t han im age dat a.

N ORM ALI ZED D EVI CE COORD I N ATE SPACE

The coordinat e space t hat cont ains t he view volum e in an axis- aligned cube w it h a m inim um corner at ( 1,1,1) and a m axim um corner at ( 1,1,1) .

N PR

See

NON- PHOTOREALI STI C RENDERI NG.

OBJECT COORD I N ATE SYSTEM

See

MODELI NG COORDI NATE SYSTEM.

OBJECT SPACE

See

MODELI NG COORDI NATE SYSTEM.

OCTAV E

Tw o frequencies t hat are relat ed by a rat io of 2: 1.

OFFSCREEN M EM ORY

Fram ebuffer m em ory t hat st ores t hings, such as dept h buffers and t ext ures, t hat are never direct ly visible on t he display screen ( cont r ast wit h DI SPLAY MEMORY) .

O PEN GL

SH AD ER

A t erm applied t o a shader writ t en in t he OpenGL Shading Language t o different iat e from a shader writ t en in anot her shading language.

O PEN GL S H AD I N G L AN GUAGE The high- level program m ing language defined t o allow applicat ion writ ers t o writ e progr am s t hat execut e on t he progr am m able pr ocessors defined wit hin OpenGL.

O PEN GL S H AD I N G L AN GUAGE API The set of funct ion calls added t o OpenGL t o allow OpenGL shaders t o be creat ed, delet ed, queried, com piled, linked, and used.

PARSI N G

See

SYNTACTI C ANALYSI S.

PARTI CLE SYSTEM

A rendering prim it ive t hat consist s of a large num ber of point s or short lines t hat are suit able for rendering a class of obj ect s wit h ill- defined boundaries ( e.g., fire, sparks, liquid sprays) .

PER - FRAGM EN T OPERATI ON S

An OpenGL pipeline st age t hat occurs aft er fragm ent processing and before fr am ebuffer operat ions. I t includes a variet y of t est s, such as t he st encil, alpha, and dept h t est s, aim ed at det erm ining whet her t he fragm ent should be used t o updat e t he fram ebuffer.

P ERLI N

N OI SE

A noise funct ion t hat is defined t o have a value of 0 for int eger input values and whose variabilit y is int roduced by defining pseudorandom gr adient values at each of t hose point s. Also called GRADI ENT NOI SE.

PH OTOREALI SM

The effort t o use com put er gr aphics t o m odel, render, and anim at e a scene in such a way

t hat it is indist inguishable from a phot ograph or film sequence of t he sam e scene in real life.

PI X EL GROUP

A value t hat will ult im at ely be used t o updat e t he fram ebuffer ( i.e., a color, dept h, or st encil value) .

PI X EL OW N ERSH I P TEST

An OpenGL pipeline st age t hat decides whet her a fragm ent can be used t o updat e t he fram ebuffer or w het her t he t arget ed fram ebuffer locat ion belongs t o anot her window or t o anot her OpenGL graphics cont ext .

PI X EL PACKI N G

An OpenGL pipeline st age t hat writ es pixels ret rieved from OpenGL int o applicat ioncont rolled m em ory.

PI X EL RECTAN GLE

A rect angular array of pixels ( i.e., an im age) .

PI X EL TRAN SFER

An OpenGL pipeline st age t hat processes pixel dat a while it is being t ransferred wit hin OpenGL. At t his st age, operat ions can occur for t he following: scaling and biasing, lookup t able, convolut ion, hist ogram , color m at r ix, and t he like.

PI X EL UN PACKI N G

An OpenGL pipeline st age t hat reads pixels ( i.e., im age dat a) from applicat ion- cont rolled m em ory and sends t hem on for furt her processing by OpenGL.

POI N T SAM PLI N G

The pr ocess of det erm ining t he value at each pixel by sam pling t he funct ion at j ust one point . This is t he t ypical behavior of graphics hardw are and m any graphics algorit hm s, and it can lead t o aliasing art ifact s. Cont rast w it h SUPERSAMPLI NG and AREA SAMPLI NG.

POI N T SPRI TE

A screen- aligned quadrilat eral t hat has t ext ure coordinat es and t hat is drawn by rast erizing a single point prim it ive. Norm ally, point s are draw n as a single pixel or as a round circle. A point sprit e can be used t o draw an im age st ored in a t ext ure m ap at each point posit ion.

POLYN OM I AL TEX TURE M AP

( PTM )

A light - dependent t ext ure m ap t hat can reconst ruct t he color of a surface under varying light ing condit ions.

PRI M I TI V E ASSEM BLY

An OpenGL pipeline st age t hat occurs aft er vert ex processing and t hat assem bles individual vert ex values int o a prim it ive. The pr im ary funct ion of t his st age is t o buffer vert ex values unt il enough accum ulat e t o define t he desired prim it ive. Point s require one vert ex, lines require t wo, t riangles require t hree, and so on.

PRI M I TI V ES

I n OpenGL parlance, t hings t hat can be rendered: point s, lines, polygons, bit m aps, and im ages.

PROCED URAL TEX TURE SH AD ER

A shader t hat produces it s result s prim arily by synt hesizing rat her t han by relying heavily on precom put ed values.

PROCED URAL TEX TURI N G

The pr ocess of com put ing a t ext ure prim arily by synt hesizing r at her t han by relying heavily on precom put ed values.

PROGRAM

The set of execut ables t hat result from successful linking of a program obj ect . This program can be inst alled as part of OpenGL's current st at e t o provide program m able ver t ex and fr agm ent processing.

PROGRAM OBJECT

An OpenGL- m anaged dat a st ruct ure t hat serves as a cont ainer obj ect for one or m ore shader obj ect s. Program obj ect s are used when shaders are linked. Linking a pr ogram obj ect result s in one or m ore execut ables t hat are part of t he program obj ect and t hat can be inst alled as part of current st at e.

PROJECTI ON M ATRI X

The m at rix t hat t ransform s coordinat es from t he eye coordinat e syst em t o t he clipping coordinat e syst em .

PROJECTI ON TRAN SFORM ATI ON

The t ransform at ion t hat t akes coordinat es from t he eye coordinat e syst em int o t he clipping coordinat e syst em .

PTM

See

POLYNOMI AL TEXTURE MAP.

PULSE TRAI N

A periodic funct ion t hat varies abrupt ly bet ween t w o values ( i.e., a square wave) .

R - VALU E

An expression ident ifying a declared or t em porary obj ect in m em ory t hat can be readfor exam ple, a var iable nam e is an r - value, but funct ion nam es are not . Expressions result in r- values.

RASTER POSI TI ON

A piece of OpenGL st at e t hat posit ions bit m ap and im age writ e operat ions.

RASTERI ZATI ON

The pr ocess of convert ing graphics prim it ives such as point s, lines, polygons, bit m aps, and im ages int o fragm ent s.

READ CON TROL

An OpenGL pipeline st age t hat cont ains st at e t o define t he region of fram ebuffer m em ory t hat is read during pixel r ead operat ions.

REN D ERI N G

The pr ocess of convert ing geom et ry or im age dat a defined by an applicat ion int o som et hing t hat is st ored in t he fram ebuffer.

REN D ERI N G PI PELI N E

See

GRAPHI CS PROCESSI NG PI PELI NE.

SAM PLER

An opaque dat a t ype in t he OpenGL Shading Language t hat st ores t he inform at ion needed t o access a part icular t ext ure from wit hin a shader.

SCAN N I N G

See

LEXI CAL ANALYSI S.

SCEN E GRAPH

Eit her a hierar chical dat a st ruct ure cont aining a descr ipt ion of a scene t o be rendered or a rendering engine for t raversing and rendering such dat a st ruct ures.

SCI SSOR TEST

An OpenGL pipeline st age t hat , when enabled, allows drawing operat ions t o occur only wit hin a specific rect angular region t hat has been defined in window coordinat es.

SEM AN TI C AN ALYSI S

The pr ocess of det erm ining whet her t he input t ext conform s t o t he sem ant ic rules defined or im plied by a program m ing language. Sem ant ic errors in t he input t ext can be ident ified during t his phase of com pilat ion.

SH AD ER

Source code writ t en in t he OpenGL Shading Language t hat is int ended for execut ion on

one of OpenGL's program m able processors.

SH AD ER OBJECT

An OpenGL- m anaged dat a st ruct ure t hat st ores t he source code and t he com piled code for a shader writ t en in t he OpenGL Shading Language. Shader obj ect s can be com piled, and com piled shader obj ect s can be linked t o pr oduce execut able code ( see PROGRAM OBJECT) .

SH AD OW M AP

A t ext ure creat ed by rendering a scene from t he point of view of a light source. This t ext ure is t hen used during a final r endering pass t o det erm ine t he part s of t he scene t hat are in shadow. Also know n as a DEPTH MAP.

SH AD OW M APPI N G

An algorit hm t hat com put es shadows by rendering t he scene once for each shadowcausing light source in t he scene and once for t he final rendering of t he scene, including shadows. The perlight rendering passes are rendered from t he light source's point of view and cr eat e shadow m aps. These t ext ur es ar e t hen accessed on t he final pass t o det erm ine t he part s of t he scene t hat are in shadow.

SM OOTH SH AD I N G

The t erm used t o describe t he applicat ion of linearly int erpolat ed color values across t he ext ent of a prim it ive ( cont rast wit h FLAT SHADI NG) . Also called GOURAUD SHADI NG.

SM OOTH I N G FI LTERS

See

LOW- PASS FI LTERI NG.

SPH ERE M APPI N G

A m et hod for perform ing environm ent m apping t hat sim ulat es t he proj ect ion of t he environm ent ont o a sphere surr ounding t he obj ect t o be rendered. The m apped environm ent is t reat ed as a 2D t ext ure m ap and accessed wit h t he polar coordinat es of t he reflect ion vect or.

STEN CI L BUFFER

An offscreen region of fram ebuffer m em ory t hat can be used wit h t he st encil t est t o m ask

regions. A com plex shape can be st ored in t he st encil buffer, and subsequent drawing operat ions can use t he cont ent s of t he st encil buffer t o det erm ine whet her t o updat e each pixel.

STEN CI L TEST

An OpenGL pipeline st age t hat condit ionally elim inat es a pixel according t o t he result s of a com parison bet w een t he value st ored in t he st encil buffer and a reference value. Applicat ions can specify t he act ion t aken when t he st encil t est fails, t he act ion t aken when t he st encil t est passes and t he dept h t est fails, and t he act ion t o be t aken when bot h t he st encil t est and t he dept h t est pass.

SUPERSAM PLI N G

A rendering t echnique t hat involves t aking t w o or m ore point sam ples per pixel and t hen filt ering t hese values t o det erm ine t he value t o be used for t he pixel. Supersam pling does not elim inat e aliasing but can reduce it t o t he point at which it is no longer obj ect ionable.

SURFACE- LOCAL COORD I N ATE SPACE

A coordinat e syst em t hat assum es t hat each point on a surface is at ( 0,0,0) and t hat t he unpert urbed surface norm al at each point is ( 0,0,1) .

SW I ZZLE

To duplicat e or swit ch around t he order of t he com ponent s of a vect or ( e.g, t o creat e a value t hat cont ains alpha, gr een, blue, red from one t hat cont ains red, green, blue, alpha) .

SYN TACTI C AN ALYSI S

The pr ocess of det erm ining whet her t he st ruct ure of an input t ext is valid according t o t he gram m ar t hat defines t he language. Synt ax errors in t he input t ext can be ident ified during t his phase of com pilat ion. Som et im es referred t o as parsing.

TAN GEN T SPACE

A part icular surface- local coordinat e syst em t hat is defined wit h a t angent vect or as one of t he basis vect ors.

T& L

See

TRANSFORMATI ON AND LI GHTI NG.

TEM PORAL ALI ASI N G

Aliasing art ifact s t hat are caused by insufficient sam pling in t he t im e dom ain or inadequat e repr esent at ion of obj ect s t hat are in m ot ion.

TEX EL

A single pixel in a t ext ure m ap.

TEX TURE ACCESS

The pr ocess of reading from a t ext ure m ap in t ext ure m em ory, including t he filt ering t hat occurs, t he level- of- det ail calculat ion for m ipm ap t ext ures, and so on.

TEXTURE APPLI CATI ON

The pr ocess of using t he value read from t ext ure m em ory t o com put e t he color of a fragm ent . OpenGL's fixed funct ionalit y has fixed form ulas for t his pr ocess, but wit h program m abilit y, t his operat ion has becom e m uch m ore general.

TEX TURE BOM BI N G

The pr ocess of applying irregularly spaced decorat ive elem ent s ( st ars, polka dot s, charact er glyphs, et c.) t o an obj ect 's surface. Decorat ive elem ent s can be com put ed procedurally or obt ained from a t ext ure m ap. They can also be random ly scaled and rot at ed t o add furt her int erest .

TEX TURE M APPI N G

The com binat ion of t ext ure access and t ext ure applicat ion. Tradit ionally, t his m apping involves reading im age dat a from a t ext ure m ap st ored in t ext ure m em ory and using it as t he color for t he prim it ive being render ed. Wit h program m abilit y, t his operat ion has becom e m uch m ore general.

TEX TURE M EM ORY

A region of m em or y on t he graphics accelerat or t hat is used for st oring t ext ur es.

TEX TURE OBJECT

The OpenGL- m anaged dat a st ruct ure t hat cont ains inform at ion t hat describes a t ext ure m ap, including t he t exels t hat define t he t ext ure, t he wrapping behavior, t he filt ering m et hod, and so on.

TEX TURE UN I T

An OpenGL abst ract ion for t he graphics hardware t hat perform s t ext ure access and t ext ure applicat ion. Since version 1.2, OpenGL has allowed t he possibilit y of m ore t han one t ext ure unit , t hus allow ing access t o m ore t han one t ext ure at a t im e.

TRAN SFORM ATI ON AN D LI GH TI N G

( T & L)

The pr ocess of convert ing ver t ex posit ions from obj ect coordinat es int o w indow coordinat es, and for convert ing vert ex colors int o colors t hat are displayable on t he screen, t aking int o account t he effect s of sim ulat ed light sources.

TURBULEN CE

A variat ion of Perlin noise t hat sum s noise funct ions of different fr equencies. These frequencies include an absolut e value funct ion t o int roduce discont inuit ies t o t he funct ion in order t o give t he appear ance of t ur bulent flow .

UN I FORM V ARI ABLE

An OpenGL Shading Language variable t hat is qualified wit h t he uniform keyword. The values for t hese variables are provided by t he applicat ion or t hrough OpenGL st at e. They are read- only from wit hin a shader and m ay be accessed from eit her vert ex shaders or fragm ent shaders. They pass dat a t hat changes relat ively infr equent ly.

UN SH ARP M ASKI N G

A m et hod of sharpening an im age by subt ract ing a blurred version of t he im age from it self.

USER CLI PPI N G

An OpenGL operat ion t hat com pares graphics prim it ives t o user- specified clipping planes in eye space and discards everyt hing t hat is deem ed t o be out side t he int ersect ion of t hose clipping planes.

V ALU E N OI SE

A noise funct ion t hat is defined as follows: Assign pseudorandom values in a defined range ( e.g., [ 0,1] or [ 1,1] ) t o each int eger input value and t hen sm oot hly int erpolat e bet w een t hose values.

V ARYI N G V ARI ABLE

An OpenGL Shading Language variable t hat is qualified wit h t he varying keyword. variables are defined at each ver t ex and int erpolat ed across a graphics prim it ive produce a perspect ive- correct value at each fragm ent . They m ust be declared in ver t ex shader and t he fragm ent shader wit h t he sam e t ype. They are t he out put from vert ex shaders and t he input values for fragm ent shaders.

These to bot h t he values

V ERTEX

A point in t hree- dim ensional space.

V ERTEX ATTRI BUTES

Values t hat are associat ed wit h a vert ex. OpenGL defines bot h st andard and generic vert ex at t ribut es. St andard at t ribut es include vert ex posit ion, color, norm al, and t ext ur e coordinat es. Generic vert ex at t ribut es can be defined t o be arbit rary dat a values t hat are passed t o OpenGL for each vert ex.

V ERTEX PROCESSI N G

An OpenGL pipeline st age t hat defines t he operat ions t hat occur t o each vert ex from t he t im e t he vert ex is provided t o OpenGL until t he prim it ive assem bly st age. For OpenGL fixed funct ionalit y, t his processing includes t ransform at ion, light ing, t ext ure coordinat e gener at ion, and ot her operat ions. For t he OpenGL program m able vert ex processor, any t ype of per- vert ex processing m ay be perform ed.

V ERTEX PROCESSOR

A program m able unit t hat replaces t he t r adit ional fixed funct ionalit y vert ex processing st age of OpenGL. Vert ex shaders ar e execut ed on t he vert ex processor.

V ERTEX SH AD ER

A program writ t en in t he OpenGL Shading Language t hat execut es on t he vert ex processor. The vert ex shader's m a in funct ion is execut ed once for each vert ex provided t o OpenGL and can be program m ed t o perform bot h t r adit ional operat ions ( t ransform at ion, light ing) and nont radit ional operat ions.

V I EW FRUSTUM

The view volum e aft er it has been warped by t he perspect ive division calculat ion.

V I EW V OLUM E

The volum e in t he clipping coordinat e syst em whose coordinat es x, y, z, and w all sat isfy t he condit ions t hat w x w, w y w, and w z w. Any port ion of a geom et ric prim it ive t hat ext ends beyond t his volum e will be clipped.

V I EW I N G M ATRI X

The m at rix t hat t ransform s coordinat es from t he world coordinat e syst em int o t he eye coordinat e syst em . I n OpenGL, t his m at rix is not available separat ely; it is always part of t he m odelview m at rix.

V I EW I N G TRAN SFORM ATI ON

The t ransform at ion t hat t akes coordinat es from t he world coordinat e syst em int o t he eye coordinat e syst em .

V I EW PORT TRAN SFORM ATI ON

The t ransform at ion t hat t akes coordinat es from t he norm alized device coordinat e syst em int o t he w indow coordinat e syst em .

W I N D OW COORD I N ATE SYSTEM

The coordinat e syst em used t o ident ify pixels wit hin a window on t he display device. I n t his coordinat e syst em , x values range from 0 t o t he widt h of t he window m inus 1, and y values range from 0 t o t he height of t he w indow m inus 1. OpenGL defines t he pixel wit h window coordinat es ( 0,0) t o be t he pixel at t he lower - left cor ner of t he window .

W ORLD COORD I N ATE SYSTEM

A coordinat e syst em t hat is defined in a way t hat is convenient for t he placem ent and orient at ion of all of t he obj ect s in a scene.

W ORLD SPACE

See

WORLD COORDI NATE SYSTEM.

Further Reading

3Dlabs developer Web sit e: ht t p: / / developer.3dlabs.com Abram , G. D., and T. Whit t ed, Building Block Shaders, Com put er Graphics ( SI GGRAPH '90 Procee August 1990. Akenine- Möller, Tom as, and E. Haines, Real- Tim e Rendering, Second Edit ion, AK Pet ers, Lt d., Na 2002. ht t p: / / w ww .realt im erendering.com Apodaca, Ant hony A., and Larry Grit z, Advanced RenderMan: Creat ing CGI for Mot ion Pict ures, M Publishers, San Francisco, 1999. ht t p: / / w ww .r ender m an.org/ RMR/ Books/ arm an/ m at erials.ht m l Ar vo, Jam es, ed., Graphics Gem s I I , Academ ic Press, San Diego, 1991. ht t p: / / w ww .acm .org/ pub ATI developer Web sit e. ht t p: / / w ww .at i.com / developer Baker, Dan, and C. Boyd, Advanced Shading and Light ing, Microsoft Corp. Melt down 2001 Presen ht t p: / / www.m icrosoft .com / m scorp/ corpevent s/ m elt down2001/ ppt / DXGLight ing.ppt Baldwin, Dave, OpenGL 2.0 Shading Language Whit e Paper, Version 1.0, 3Dlabs, Oct ober, 2001. [ 1] Barzel, Ronen, Light ing Cont rols for Com put er Cinem at ography, Journal of Graphics Tools, 2( Blinn, Jam es, Models of Light Reflect ion for Com put er Synt hesized Pict ures, Com put er Graphics ( Proceedings) , pp. 192198, July 1977. Blinn, Jam es, Sim ulat ion of Wrinkled Surfaces, Com put er Graphics ( SI GGRAPH '78 Proceedings) , 1978. Blinn, Jam es, Light Reflect ion Funct ions for Sim ulat ion of Clouds and Dust y Surfaces, Com put er G '82 Proceedings) , pp. 2129, July 1982. Blinn, Jam es, and M. E. Newell, Text ure and Reflect ion in Com put er Generat ed I m ages, Com m un vol. 19, no. 10, pp. 542547, Oct ober 1976. Bunnell, Michael, Dynam ic Am bient Occlusion and I ndirect Light ing, in GPU Gem s 2: Program m in High- Perform ance Graphics and General- Pur pose Com put at ion, Edit or: Mat t Pharr, Addison- Wesl Massachuset t s, 2005. ht t p: / / download.nvidia.com / developer/ GPU_Gem s_2/ GPU_Gem s2_ch14.p Bunnell, Michael, and Fabio Pellacini, Shadow Map Ant ialiasing, in GPU Gem s: Program m ing Tech Tricks for Real- Tim e Graphics, Edit or: Randim a Fernando, Addison- Wesley, Reading, Massachuse ht t p: / / developer.nvidia.com / obj ect / gpu_gem s_hom e.ht m l Cabral, B., N. Max, and R. Springm eyer, Bidirect ional Reflect ion Funct ions from Surface Bum p Ma Graphics ( SI GGRAPH '87 Proceedings) , pp. 273281, July 1987. Card, Drew , and Jason L. Mit chell, Non- Phot orealist ic Rendering wit h Pixel and Vert ex Shaders, i ed., ShaderX, Wordware, May 2002. ht t p: / / w ww .shaderx.com Cook, Robert L., and Kennet h E. Torrance, A Reflect ance Model for Com put er Gr aphics, Com put e ( SI GGRAPH '81 Proceedings) , pp. 307316, July 1981. Cook, Robert L., and Kennet h E. Torrance, A Reflect ance Model for Com put er Gr aphics, ACM Tran vol. 1, no. 1, pp. 724, January 1982.

Cook, Robert L., Shade Trees, Com put er Graphics ( SI GGRAPH '84 Proceedings) , pp. 223231, Jul Cook, Robert L., St ochast ic Sam pling in Com put er Graphics, ACM Transact ions on Graphics, vol. January 1986. Cornell Universit y Program of Com put er Graphics Measurem ent Dat a. ht t p: / / www.graphics.cornell.edu/ online/ m easurem ent s Crow , Franklin C., The Aliasing Problem in Com put er - Generat ed Shaded I m ages, Com m unicat ion no. 11, pp. 799805, Novem ber 1977. Crow , Franklin C., Shadow Algorit hm s for Com put er Graphics, Com put er Graphics ( SI GGRAPH '7 11, no. 2, pp. 242248, July 1977. Crow , Franklin C., Sum m ed- Area Tables for Text ure Mapping, Com put er Graphics ( SI GGRAPH '84 207212, July 1984. Curt is, Cassidy J., Sean E. Anderson, Kurt W. Fleischer, and David H. Salesin, Com put er - Generat Com put er Graphics ( SI GGRAPH '97 Proceedings) , pp. 421430, August 1997. ht t p: / / grail.cs.washingt on.edu/ proj ect s/ w at ercolor Curt is, Cassidy J., Loose and Sket chy Anim at ion, SI GGRAPH '98 Technical Sket ch, p. 317, 1998. ht t p: / / w ww .ot hert hings.com / uw / loose/ sket ch.ht m l Daw son, Bruce, What Happened t o My Colours! ?! Gam e Developers Conference, pp. 251268, Ma ht t p: / / www.gdconf.com / archives/ 2001/ dawson.doc Debevec, Paul, I m age- Based Light ing, I EEE Com put er Graphics and Applicat ions, vol. 22, no. 2, ht t p: / / w ww .debevec.or g/ CGAI BL2/ ibl- t ut orialcga2002.pdf Debevec, Paul, personal Web sit e. ht t p: / / w ww .debevec.or g Debevec, Paul, and J. Malik, Recovering High Dynam ic Range Radiance Maps from Phot ogr aphs, ( SI GGRAPH '97 Proceedings) , pp. 369378. ht t p: / / www.debevec.org/ Research/ HDR Debevec, Paul, Rendering Synt het ic Obj ect s int o Real Scenes: Bridging Tr adit ional and I m age- Ba Global I llum inat ion and High Dynam ic Range Phot ography, Com put er Graphics ( SI GGRAPH '98 P 189198. ht t p: / / at hens.ict .usc.edu/ Research/ I BL Delphi3D Web sit e. ht t p: / / delphi3d.net DeLoura, Mark, ed., Gam e Program m ing Gem s, Charles River Media, Hingham , Massachuset t s, 2 DeLoura, Mark, ed., Gam e Program m ing Gem s I I , Charles River Media, Hingham , Massachuset t s DeLoura, Mark, ed., Gam e Program m ing Gem s I I I , Charles River Media, Hingham , Massachuset t Derbyshire, Paul, PGD's Quick Guide t o t he Mandelbrot Set , personal Web sit e. ht t p: / / w ww .globalserve.net / ~ derbyshir e/ m anguide.ht m l ( defunct ) Dippé, Mark A. Z., and Erling Henry Wold, Ant ialiasing Through St ochast ic Sam pling, Com put er G '85 Proceedings) , pp. 6978, July 1985. Duff, Tom , Com posit ing 3- D Rendered I m ages, Com put er Graphics ( SI GGRAPH '85 Proceedings) Ebert , David S., John Hart , Bill Mark, F. Kent on Musgrave, Darw yn Peachey, Ken Perlin, and St ev

and Modeling: A Procedural Approach, Thir d Edit ion, Morgan Kaufm ann Publishers, San Francisco ht t p: / / w ww .t ext uringandm odeling.com Fernando, Randim a, and Mark J. Kilgard, The Cg Tut orial: The Definit ive Guide t o Program m able Addison- Wesley, Bost on, Massachuset t s, 2003. Foley, J. D., A. van Dam , S.K. Feiner, J. F. Hughes, and R.L. Philips, I nt roduct ion t o Com put er Gr Wesley, Reading, Massachuset t s, 1994. Foley, J. D., A. van Dam , S.K. Feiner, and J. F. Hughes, Com put er Graphics: Pr inciples and Pr act Edit ion, Addison- Wesley, Reading, Massachuset t s, 1996. Fosner, Ron, Real- Tim e Shader Program m ing, Covering Direct X 9.0, Morgan Kaufm ann Publisher 2003. Freudenberg, Bert , Maic Masuch, and Thom as St rot hot t e, Walk- Through I llust rat ions: Fram e- Coh St yle in a Gam e Engine, Com put er Graphics Forum , vol. 20 ( 2001) , no. 3, Manchest er, U.K. ht t p m agdeburg.de/ ~ bert / publicat ions Freudenberg, Bert , Maic Masuch, and Thom as St rot hot t e, Real- Tim e Halft oning: A Prim it ive For N Shading, Rendering Techniques 2002, Proceedings 13 t h Eurographics Workshop, pp. 227231, 20 ht t p: / / isgwww.cs.uni- m agdeburg.de/ ~ bert / publicat ions Freudenberg, Bert , and Maic Masuch, Non- Phot orealist ic Shading in an Educat ional Gam e Engine Eurogr aphics Cam pfire, Snowbird, Ut ah, June 1June 4, 2002. ht t p: / / isgwww.cs.uni- m agdeburg.d Freudenberg, Bert , A Non- Phot or ealist ic Fragm ent Shader in OpenGL 2.0, SI GGRAPH 2002 Exhib Texas, July 2002. ht t p: / / isgwww.cs.uni- m agdeburg.de/ ~ bert / publicat ions Freudenberg, Bert , St roke- based Real- Tim e Halft oning Rendering, Ph.D. t hesis, Universit y of Mag 2003. Glaeser, Georg, Reflect ions on Spheres and Cylinders of Revolut ion, Journal for Geom et ry and G ( 1999) , No. 2, pp. 121139. ht t p: / / w ww .helderm ann- verlag.de/ j gg/ j gg01_05/ j gg0312.pdf Glanville, St eve, Text ure Bom bing, in GPU Gem s: Program m ing Techniques, Tips, and Tricks for Edit or: Randim a Fernando, Addison- Wesley, Reading, Massachuset t s, 2004. ht t p: / / developer.nvidia.com / obj ect / gpu_gem s_hom e.ht m l Glassner, Andrew S., ed., Graphics Gem s, Academ ic Press, San Diego, 1990. ht t p: / / www.acm .org/ pubs/ t og/ GraphicsGem s Glassner, Andrew S., Principles of Digit al I m age Synt hesis, vol. 1, Mor gan Kaufm ann Publishers, Glassner, Andrew S., Principles of Digit al I m age Synt hesis, vol. 2, Mor gan Kaufm ann Publishers, Gonzalez, Rafael C., and Richard E. Woods, Digit al I m age Processing, Second Edit ion, Prent ice H River, New Jersey, 2002. Gooch, Am y, I nt eract ive Non- Phot orealist ic Technical I llust rat ion, Mast er's t hesis, Universit y of U ht t p: / / www.cs.ut ah.edu/ ~ gooch/ publicat ion.ht m l Gooch, Am y, Bruce Gooch, Pet er Shirley, and Elaine Cohen, A Non- Phot orealist ic Light ing Model Technical I llust rat ion, Com put er Graphics ( SI GGRAPH '98 Proceedings) , pp. 447452, July 1998. ht t p: / / www.cs.ut ah.edu/ ~ gooch/ publicat ion.ht m l Gooch, Bruce, Pet er- Pike J. Sloan, Am y Gooch, Pet er Shirley, and Richard Riesenfeld, I nt eract ive

Proceedings 1999 Sym posium on I nt eract ive 3D Graphics, pp. 3138, April 1999. ht t p: / / www.cs.ut ah.edu/ ~ gooch/ publicat ion.ht m l Gooch, Bruce, and Am y Gooch, Non- Phot orealist ic Rendering, AK Pet ers Lt d., Nat ick, Massachuse ht t p: / / www.cs.ut ah.edu/ ~ gooch/ book.ht m l Goral, Cindy M., K. Torrance, D. Greenber g, and B. Bat t aile, Modeling t he I nt eract ion of Light Be Surfaces, Com put er Graphics ( SI GGRAPH '84 Proceedings) , pp. 213222, July 1984. Gouraud, H., Cont inuous Shading of Curved Surfaces, I EEE Transact ions on Com put ers, vol. C- 2 1971. GPU Gem s: Program m ing Techniques, Tips, and Tricks for Real- Tim e Graphics, Edit or: Randim a Wesley, Reading, Massachuset t s, 2004. ht t p: / / developer.nvidia.com / obj ect / gpu_gem s_hom e.ht m GPU Gem s 2: Program m ing Techniques for High- Perform ance Graphics and General- Pur pose Com Mat t Pharr, Addison- Wesley, Reading, Massachuset t s, 2005. ht t p: / / developer.nvidia.com / obj ect / gpu_gem s_2_hom e.ht m l Green, Robin, Spherical Harm onic Light ing: The Grit t y Det ails, GDC 2003 Present at ion. ht t p: / / www.research.scea.com / gdc2003/ spherical- harm onic- light ing.ht m l Greene, Ned, Environm ent Mapping and Ot her Applicat ions of World Proj ect ions, I EEE Com put er Applicat ions, vol. 6, no. 11, pp. 2129, Novem ber 1986. Grit z, Larry, LGAnt ialiasedChecks.sl, RenderMan Reposit ory Web sit e. ht t p: / / w ww .r ender m an.org/ RMR/ Shaders/ LGShaders/ index.ht m l Gruschel, Jens, Blend Modes, Pegt op Soft ware Web sit e. ht t p: / / w ww .pegt op.net / delphi/ blendm o Haeberli, Paul, Paint by Num bers: Abst ract I m age Represent at ion, Com put er Graphics ( SI GGRAP pp. 207214, August 1990. Haeberli, Paul, Mat rix Operat ions for I m age Processing, Silicon Graphics I nc., 1993. ht t p: / / www.sgi.com / grafica/ m at rix Haeberli, Paul, and Douglas Voorhies, I m age Processing by I nt erpolat ion and Ext rapolat ion, I RI S no. 28, Silicon Graphics, August 1994. ht t p: / www.sgi.com / grafica/ int erp Haeberli, Paul, and Kurt Akeley, The Accum ulat ion Buffer: Hardwar e Support for High- Qualit y Re Graphics ( SI GGRAPH '90 Proceedings) , pp. 289298, August 1990. Haeberli, Paul, and Mark Segal, Text ure Mapping as a Fundam ent al Draw ing Prim it ive, 4t h Eurog Rendering, pp. 259266, 1993. ht t p: / / w ww .sgi.com / grafica/ t exm ap Haines, Eric, Real- Tim e Shadows, GDC 2001 Present at ion. ht t p: / / w ww .gdconf.com / archives/ 200 Hall, Roy, I llum inat ion and Color in Com put er Generat ed I m agery, Springer- Verlag, New York, 19 Hanrahan, Pat , and Wolfgang Krueger, Reflect ion From Layered Surfaces Due t o Subsurface Scat Graphics ( SI GGRAPH '93 Proceedings) , pages 165174, August 1993. ht t p: / / wwwgraphics.st anford.edu/ papers/ subsurface Hanrahan, Pat , and J. Law son, A Language for Shading and Light ing Calculat ions, Com put er Grap Proceedings) , pp. 289298, August 1990. Hart , Evan, Dave Gosselin, and John I sidoro, Vert ex Shading wit h Direct 3D and OpenGL, Gam e D

Conference, San Jose, March 2001. ht t p: / / www.at i.com / developer/ ATI GDC2001Vert ex.PDF Hart , John C., Perlin Noise Pixel Shaders, ACM SI GGRAPH/ Eurographics Workshop on Graphics H August 2001. ht t p: / / graphics.cs.uiuc.edu/ ~ j ch/ papers/ pixelnoise.pdf Heckbert , Paul S., Survey of Text ure Mapping, I EEE Com put er Gr aphics and Applicat ions, vol. 6, Novem ber 1986. ht t p: / / w ww .cs.cm u.edu/ ~ ph Heckbert , Paul S., Fundam ent als of Text ure Mapping and I m age Warping, Report No. 516, Com p Universit y of California, Berkeley, June 1989. ht t p: / / w ww .cs.cm u.edu/ ~ ph Heckbert , Paul S., ed., Graphics Gem s I V, Academ ic Press, San Diego, 1994. ht t p: / / www.acm .org/ pubs/ t og/ GraphicsGem s Heidrich, Wolfgang, and Hans- Pet er Seidel, View - I ndependent Environm ent Maps, ACM SI GGRAP Workshop on Graphics Hardware, pp. 3945, August 1998. Heidrich, Wolfgang, and Hans- Pet er Seidel, Realist ic, Hardware- Accelerat ed Shading and Light ing ( SI GGRAPH '99 Proceedings) , pp. 171178, August 1999. ht t p: / / www.cs.ubc.ca/ ~ heidrich/ Papers Heidrich, Wolfgang, Environm ent Maps and Their Applicat ions, SI GGRAPH 2000, Course 27, cour ht t p: / / www.csee.um bc.edu/ ~ olano/ s2000c27/ envm ap.pdf Hert zm ann, Aaron, Paint erly Rendering wit h Curved Brush St rokes of Mult iple Sizes, Com put er G '98 Proceedings) , pp. 453460, 1998. ht t p: / / m rl.nyu.edu/ publicat ions/ paint erly98 Hert zm ann, Aaron, I nt roduct ion t o 3D Non- Phot orealist ic Rendering: Silhouet t es and Out lines, S Phot orealist ic Rendering course not es, 1999. ht t p: / / w ww .m rl.nyu.edu/ ~ hert zm an/ hert zm ann- int Hew let t - Packard, Polynom ial Text ure Mapping, Web sit e. ht t p: / / www.hpl.hp.com / pt m Hoffm an, Nat haniel, and A. Preet ham , Render ing Out door Light Scat t ering in Real Tim e, Gam e D 2002. ht t p: / / w ww .at i.com / developer/ dx9/ ATI - Light Scat t ering.pdf Hook, Brian, Mult ipass Rendering and t he Magic of Alpha Blending, Gam e Developer, vol. 4, no. 1997. Hughes, John F., and Tom as Möller, Building an Ort honorm al Basis from a Unit Vect or, Journal of 4, no. 4, pp. 3335, 1999. ht t p: / / www.acm .org/ j gt / papers/ HughesMoller99 I nt ernat ional Light ing Vocabulary, Publicat ion CI E No. 17.4, Joint publicat ion I EC ( I nt ernat ional E Com m ission) and CI E ( Com m it t ee I nt ernat ionale de L'Èclairage) , Geneva, 1987. ht t p: / / www.cie.co.at / fram epublicat ions.ht m l I TU- R Recom m endat ion BT.709, Basic Param et er Values for t he HDTV St andard for t he St udio an Program m e Exchange, [ form erly CCI R Rec. 709] , Geneva, I TU, 1990. Kaj iya, Jam es T., Anisot ropic Reflect ion Models, Com put er Graphics ( SI GGRAPH '85 Proceedings) Kaj iya, Jam es T., The Render ing Equat ion, Com put er Graphics ( SI GGRAPH '86 Proceedings) , pp. 1986. Kaplan, Mat t hew, Bruce Gooch, and Elaine Cohen, I nt eract ive Art ist ic Rendering, Proceedings of Sym posium on Non- Phot orealist ic Anim at ion and Rendering ( NPAR) , pp. 6774, June 2000. ht t p: / / www.cs.ut ah.edu/ npr/ ut ah_papers.ht m l Kaut z, Jan, and Michael D. McCool, I nt eract ive Rendering wit h Ar bit rary BRDFs Using Separable A

Eurogr aphics Workshop on Rendering, pp. 281292, June 1999. ht t p: / / w ww .m pi- sb.m pg.de/ ~ j nk Kaut z, Jan, and Michael D. McCool, Approxim at ion of Glossy Reflect ion wit h Prefilt ered Environm I nt erface 2000, pp. 119126, May 2000. ht t p: / / w ww .m pi- sb.m pg.de/ ~ j nkaut z/ publicat ions Kaut z, Jan, P.- P. Vázquez, W. Heidrich, and H.- P. Seidel, A Unified Approach t o Prefilt ered Enviro Eurogr aphics Workshop on Rendering, pp. 185196, June 2000. ht t p: / / w ww .m pi- sb.m pg.de/ ~ j nk Kaut z, Jan, and Hans- Pet er Seidel, Hardware Accelerat ed Displacem ent Mapping for I m age Base I nt erface 2001, pp. 6170, May 2001. Kaut z, Jan, and Hans- Pet er Seidel, Towards I nt eract ive Bum p Mapping wit h Anisot ropic Shift - Var SI GGRAPH/ Eurographics Workshop on Graphics Hardware, pp. 5158, 2000. ht t p: / / w ww .m pisb.m pg.de/ ~ j nkaut z/ proj ect s/ anisobum pm aps Kaut z, Jan, Chris Wynn, Jonat han Blow, Chris Blasband, Anis Ahm ad, and Michael McCool, Achie Realist ic Reflect ance, Part 1, Gam e Developer, vol. 8, no. 1, pp. 3237, January 2001. Kaut z, Jan, Chris Wynn, Jonat han Blow, Chris Blasband, Anis Ahm ad, and Michael McCool, Achie Realist ic Reflect ance, Part 2, Gam e Developer, vol. 8, no. 2, pp. 3844, February 2001. ht t p: / / www.gdm ag.com / code.ht m Kerlow , I saac V., The Ar t of 3- D: Com put er Anim at ion and I m aging, Second Edit ion, John Wiley 2000. Kernighan, Brian, and Dennis Rit chie, The C Program m ing Language, Second Edit ion, Prent ice Ha New Jersey, 1988. Kessenich, John, Dave Baldwin, and Randi Rost , The OpenGL Shading Language, Version 1.10, 3 ht t p: / / w ww .opengl.org/ docum ent at ion/ spec.ht m l Kilgard, Mark J., A Pract ical and Robust Bum p- m apping Technique for Today's GPUs, Gam e Deve NVI DI A Whit e Paper, 2000. ht t p: / / developer.nvidia.com / obj ect / Pract ical_Bum pm apping_Tech.ht Kirk, David, ed., Graphics Gem s I I I , Academ ic Press, San Diego, 1992. ht t p: / / w ww .acm .org/ pub Lander, Jeff, Collision Response: Bouncy, Trouncy, Fun, Gam e Developer, vol. 6, no. 3, pp. 1519 ht t p: / / www.darwin3d.com / gdm 1999.ht m Lander, Jeff, The Era of Post - Phot or ealism , Gam e Developer, vol. 8, no. 6, pp. 1822, June 2001. Lander, Jeff, Graphics Program m ing and t he Tower of Babel, Gam e Developer, vol. 8, no. 3, pp. ht t p: / / www.gdm ag.com / code.ht m Lander, Jeff, Haunt ed Trees for Halloween, Gam e Developer Magazine, vol. 7, no. 11, pp. 1721, ht t p: / / www.gdm ag.com / code.ht m Lander, Jeff, A Heaping Pile of Pir at e Boot y , Gam e Developer, vol. 8, no. 4, pp. 2230, April 2001 Lander, Jeff, I m ages from Deep in t he Program m er's Cave, Gam e Developer, vol. 8, no. 5, pp. 2 ht t p: / / www.gdm ag.com / code.ht m Lander, Jeff, The Ocean Spray in Your Face, Gam e Developer, vol. 5, no. 7, pp. 1319, July 1998. ht t p: / / www.darwin3d.com / gdm 1998.ht m Lander, Jeff, Physics on t he Back of a Cockt ail Napkin, Gam e Developer, vol. 6, no. 9, pp. 1721, ht t p: / / www.darwin3d.com / gdm 1999.ht m

Lander, Jeff, Ret urn t o Cart oon Cent ral, Gam e Developer Magazine, vol. 7, no. 8, pp. 914, Augus ht t p: / / www.gdm ag.com / code.ht m Lander, Jeff, Shades of Disney: Opaquing a 3D World, Gam e Developer Magazine, vol. 7, no. 3, ht t p: / / www.darwin3d.com / gdm 2000.ht m Lander, Jeff, Skin Them Bones: Gam e Program m ing for t he Web Generat ion, Gam e Developer , v May 1998. ht t p: / / www.darwin3d.com / gdm 1998.ht m Lander, Jeff, Slashing Through Real- Tim e Charact er Anim at ion, Gam e Developer, vol. 5, no. 4, p ht t p: / / www.darwin3d.com / gdm 1998.ht m Lander, Jeff, That 's a Wr ap: Text ure Mapping Met hods, Gam e Developer Magazine, vol. 7, no. 10 2000. ht t p: / / www.gdm ag.com / code.ht m Lander, Jeff, Under t he Shade of t he Rendering Tree, Gam e Developer Magazine, vol. 7, no. 2, p 2000. ht t p: / / www.darwin3d.com / gdm 2000.ht m Landis, Hayden, Product ion- Ready Global I llum inat ion, SI GGRAPH 2002 Course Not es, course 16 Product ion. ht t p: / / www.debevec.org/ HDRI 2004/ landis- S2002- course16- prodr eadyGI .pdf Lasset er, John, Principles of Tradit ional Anim at ion Applied t o 3D Com put er Anim at ion, Com put er '87 Proceedings) pp. 3544, July 1987. Lasset er, John, Tricks t o Anim at ing Charact ers wit h a Com put er, SI GGRAPH '94, Course 1, cours ht t p: / / w ww .siggraph.org/ educat ion/ m at erials/ HyperGraph/ anim at ion/ charact er_anim at ion/ princ Licht enbelt , Bart hold, I nt egrat ing t he OpenGL Shading Language, 3Dlabs int ernal whit e paper, Ju Lindbloom , Bruce J., Accurat e Color Reproduct ion for Com put er Graphics Applicat ions, Com put er '89 Proceedings) , pp. 117126, July 1989. Lindbloom , Bruce J., personal Web sit e, 2003. ht t p: / / www.brucelindbloom .com Lit winowicz, Pet er, Processing I m ages and Video for an I m pressionist Effect , Com put er Graphics Proceedings) , pp. 407414, August 1997. Lorensen, William E., and Harvey E. Cline, Marching Cubes: A High Resolut ion 3D Surface Const r Com put er Graphics ( SI GGRAPH '87 Proceedings) , pp. 163169, July 1987. Lowell, Ross, Mat t ers of Light & Dept h, Lowel- Light Manufact uring, 1992. Malzbender, Tom , Dan Gelb, and Hans Wolt ers, Polynom ial Text ure Maps, Com put er Graphics ( S Proceedings) , pp. 519528, August 2001. ht t p: / / www.hpl.hp.com / research/ pt m / papers/ pt m .pdf Mandelbrot , Benoit B., The Fract al Geom et ry of Nat ure, Updat ed and Augm ent ed, W. H. Freem an York, 1983. Mark, William R., Real- Tim e Shading: St anford Real- Tim e Procedural Shading Syst em , SI GGRAPH course not es, 2001. ht t p: / / graphics.st anford.edu/ proj ect s/ shading/ pubs/ sigcourse2001.pdf Mark, William R., R. St even Glanville, Kurt Akeley, and Mark Kilgard, Cg: A Syst em for Program m Hardwar e in a C- like Language, Com put er Graphics ( SI GGRAPH 2003 Proceedings) , pp. 896907, ht t p: / / www.cs.ut exas.edu/ users/ billm ark/ papers/ Cg Markosian, Lee, Michael A. Kowalski, Daniel Goldst ein, Sam uel J. Trychin, John F. Hughes, and L Real- t im e Nonphot orealist ic Rendering, Com put er Graphics ( SI GGRAPH '97 Proceedings) , pp. 41

ht t p: / / w ww .eecs.um ich.edu/ ~ sapo/ pubs McCool, Michael D., SMASH: A Next - Generat ion API for Program m able Graphics Accelerat ors, Te 2000- 14, Universit y of Wat erloo, August 2000. ht t p: / / w ww .cgl.uwat erloo.ca/ Proj ect s/ rendering/ McCool, Michael D., Jason Ang, and Anis Ahm ad, Hom om orphic Fact orizat ion of BRDFs for High- p Render ing, Com put er Graphics ( SI GGRAPH 2001 Proceedings) , pp. 171178, August 2001. ht t p: / / www.cgl.uwat erloo.ca/ Proj ect s/ rendering/ Papers McReynolds, Tom , David Blyt he, Brad Gr ant ham , and Scot t Nelson, Advanced Graphics Program m Using OpenGL, SI GGRAPH '99 course not es, 1999. ht t p: / / w ww .opengl.org/ resources/ t ut orials/ sig99/ advanced99/ not es/ not es.ht m l McReynolds, Tom , and David Blyt he, Advanced Graphics Program m ing Techniques Using OpenGL Publishers, San Francisco, 2005. Meier , Barbara J, Paint erly Rendering for Anim at ion, Com put er Graphics ( SI GGRAPH '96 Proceed August 1996. ht t p: / / www.cs.virginia.edu/ ~ dbrogan/ CS551.851.anim at ion.sp.2000/ Papers/ p477 Microsoft , Advanced Shading and Light ing, Melt down 2001, July 2001. ht t p: / / www.m icrosoft .com / m scorp/ corpevent s/ m elt down2001/ present at ions.asp Microsoft , Advanced Shading and Light ing, Direct X 9.0 SDK, 2003. ht t p: / / m sdn.m icrosoft .com / d Mit chell, Jason L., Advanced Vert ex and Pixel Shader Techniques, European Gam e Developers Co Sept em ber 2001. ht t p: / / www.pixelm aven.com / j ason Mit chell, Jason L., I m age Processing wit h Pixel Shaders in Direct 3D, in Engel, Wolfgang, ed., Sha 2002. ht t p: / / www.pixelm aven.com / j ason Muchnick, St even, Advanced Com piler Design and I m plem ent at ion, Morgan Kaufm ann Publishers 1997. Myler, Harley R., and Art hur R. Weeks, The Pocket Handbook of I m age Processing Algorit hm s in Upper Saddle River, NJ, 1993. NASA, Eart h Observat ory, Web sit e. ht t p: / / eart hobservat ory.nasa.gov/ Newsroom / BlueMarble Nishit a, Tom oyuki, Takao Sirai, Kat sum i Tadam ura, and Eihachir o Nakam ae, Display of t he Eart h At m ospheric Scat t ering, Com put er Graphics ( SI GGRAPH '93 Proceedings) , pp. 175182, August 1 lab.is.s.u- t okyo.ac.j p/ ~ nis/ abs_sig.ht m l# sig93 NVI DI A developer Web sit e. ht t p: / / developer.nvidia.com NVI DI A Corporat ion, Cg Toolkit , Release 1.4, soft w are and docum ent at ion. ht t p: / / developer.nvidia.com / obj ect / cg_t oolkit .ht m l Olano, Marc, and Anselm o Last ra, A Shading Language on Gr aphics Har dw are: The PixelFlow Sha Com put er Graphics ( SI GGRAPH '98 Proceedings) , pp. 159168, July 1998. ht t p: / / w ww .csee.um bc Olano, Marc, John Hart , Wolfgang Heidrich, and Michael McCool, Real- Tim e Shading, AK Pet ers, L Massachuset t s, 2002. OpenGL Archit ect ure Review Board, Dave Shreiner, J. Neider, T. Davis, and M. Woo, OpenGL Pro Fift h Edit ion: The Official Guide t o Learning OpenGL, Version 2, Addison- Wesley, Reading, Massa OpenGL Archit ect ure Review Board, ARB_fragm ent _program Ext ension Specificat ion, OpenGL Ex

ht t p: / / oss.sgi.com / proj ect s/ oglsam ple/ regist ry OpenGL Archit ect ure Review Board, ARB_fragm ent _shader Ext ension Specificat ion, OpenGL Ext e ht t p: / / oss.sgi.com / proj ect s/ ogl- sam ple/ regist ry OpenGL Archit ect ure Review Board, ARB_shader_obj ect s Ext ension Specificat ion, OpenGL Ext ens ht t p: / / oss.sgi.com / proj ect s/ ogl- sam ple/ regist ry OpenGL Archit ect ure Review Board, ARB_vert ex_program Ext ension Specificat ion, OpenGL Ext en ht t p: / / oss.sgi.com / proj ect s/ ogl- sam ple/ regist ry OpenGL Archit ect ure Review Board, ARB_vert ex_shader Ext ension Specificat ion, OpenGL Ext ens ht t p: / / oss.sgi.com / proj ect s/ ogl- sam ple/ regist ry OpenGL Archit ect ure Review Board, OpenGL Reference Manual, Fourt h Edit ion: The Official Refer Version 1.4, Edit or: Dave Shreiner, Addison- Wesley, Reading, Massachuset t s, 2004. OpenGL, official Web sit e. ht t p: / / opengl.org OpenGL Perform er Web sit e. ht t p: / / w ww .sgi.com / product s/ soft w are/ perform er/ OpenSceneGraph Web sit e. ht t p: / / w ww .openscenegraph.org/ OpenSG Web sit e. ht t p: / / www.opensg.org Owen, G. Scot t , Com put er Anim at ion, Web sit e. ht t p: / / w ww .siggraph.org/ educat ion/ m at erials/ HyperGraph/ anim at ion/ anim 0.ht m Pandrom eda Web sit e. ht t p: / / www.pandrom eda.com Parent , Rick, Com put er Anim at ion: Algorit hm s and Techniques, Morgan Kaufm ann Publishers, Sa Peachey, Darwyn, Solid Text ur ing of Com plex Surfaces, Com put er Graphics ( SI GGRAPH '85 Proc July 1985. Peeper, Craig, and Jason Mit chell, I nt roduct ion t o t he Direct X 9 High- Level Shader Language, in Program m ing Tips and Tricks wit h Direct X 9.0, Edit or: Wolfgang Engel, Wordw are Publishing, 20 ht t p: / / www.at i.com / developer/ ShaderX2_I nt roduct ionToHLSL.pdf Peercy, Mark S., Marc Olano, John Airey, and P. Jeffrey Ungar, I nt eract ive Mult i- Pass Program m a Com put er Graphics ( SI GGRAPH 2000 Proceedings) , pp. 425432, July 2000. ht t p: / / w ww .csee.um Peit gen, Heinz- Ot t o, and P. H. Richt er, The Beaut y of Fract als, I m ages of Com plex Dynam ical Sy Verlag, Berlin Heidelberg, 1986. Peit gen, Heinz- Ot t o, D. Saupe, M. F. Barnsley, R. L. Devaney, B. B. Mandelbrot , and R. F. Voss, I m ages, Springer Verlag, New York, 1988. Perlin, Ken, An I m age Synt hesizer , Com put er Graphics ( SI GGRAPH '85 Proceedings) , pp. 287296 Perlin, Ken, I m plem ent ing I m proved Perlin Noise in GPU Gem s: Program m ing Techniques, Tips, a Tim e Graphics, Edit or: Randim a Fernando, Addison- Wesley, Reading, Massachuset t s, 2004. ht t p: / / developer.nvidia.com / obj ect / gpu_gem s_hom e.ht m l Perlin, Ken, I m proving Noise, Com put er Graphics ( SI GGRAPH 2002 Proceedings) , pp. 681682, Ju ht t p: / / m rl.nyu.edu/ perlin/ paper445.pdf

Perlin, Ken, personal Web sit e. ht t p: / / www.noisem achine.com Perlin, Ken, personal Web sit e. ht t p: / / m rl.nyu.edu/ ~ perlin Pharr, Mat t , and Sim on Green, Am bient Occlusion, in GPU Gem s: Program m ing Techniques, Tips Tim e Graphics, Edit or: Randim a Fernando, Addison- Wesley, Reading, Massachuset t s, 2004. ht t p: / / developer.nvidia.com / obj ect / gpu_gem s_hom e.ht m l Pharr, Mat t , and Greg Hum phreys, Physically Based Rendering: From Theory t o I m plem ent at ion, San Fr ancisco, 2004. ht t p: / / pbrt .org/ Phong, Bui Tuong, I llum inat ion for Com put er Generat ed Pict ures, Com m unicat ions of t he ACM, v 311317, June 1975. Pixar, The Render Man I nt erface Specificat ion, Version 3.2, Pixar, July 2000. ht t ps: / / renderm an.pixar.com / product s/ rispec/ index.ht m Port er, Thom as, and Tom Duff, Com posit ing Digit al I m ages, Com put er Graphics ( SI GGRAPH '84 253259, July 1984. Poulin, P., and A. Fournier, A Model for Anisot ropic Reflect ion, Com put er Graphics ( SI GGRAPH '9 273282, August 1990. Poynt on, Charles A., Frequent ly Asked Quest ions about Color, 1997. ht t p: / / w ww .poynt on.com / P Poynt on, Charles A., Frequent ly Asked Quest ions about Gam m a, 1997. ht t p: / / w ww .poynt on.com Poynt on, Charles A., A Technical I nt roduct ion t o Digit al Video, John Wiley & Sons, New York, 199 Praun, Em il, Adam Finkelst ein, and Hugues Hoppe, Lapped Text ures, Com put er Graphics ( SI GGR Proceedings) , pp. 465470, July 2000. ht t p: / / www.cs.princet on.edu/ gfx/ proj / lapped_t ex Praun, Em il, Hugues Hoppe, Mat t hew Webb, and Adam Finkelst ein, Real- t im e Hat ching, Com put e ( SI GGRAPH 2000 Proceedings) , pp. 581586, August 2001. ht t p: / / www.cs.princet on.edu/ gfx/ proj Proakis, John G., and Dim it r is G. Manolakis, Digit al Signal Processing: Principles, Algorit hm s, and Edit ion, Prent ice Hall, Upper Saddle River, New Jersey, 1995. Proudfoot , Kekoa, William R. Mark, Sv et oslav Tzvet kov, and Pat Hanrahan, A Real- Tim e Procedur for Pr ogram m able Graphics Hardware, Com put er Graphics ( SI GGRAPH 2001 Proceedings) , pp. 1 ht t p: / / graphics.st anford.edu/ proj ect s/ shading/ pubs/ sig2001 Purcell, Tim ot hy J., I an Buck, William R. Mark, and Pat Hanrahan, Ray Tracing on Program m able Com put er Graphics ( SI GGRAPH 2002 Proceedings) , July 2002. ht t p: / / www - graphics.st anford.edu Ram am oort hi, Ravi, and P. Hanrahan, An Efficient Represent at ion for I rradiance Environm ent Ma Graphics ( SI GGRAPH 2001 Proceedings) , pp. 497500, August 2001. ht t p: / / www1.cs.colum bia.edu/ ~ ravir/ papers/ envm ap/ index.ht m l Raskar, Ram esh, and Michael Cohen, I m age Precision Silhouet t e Edges, Proceedings 1999 Sym p 3D Graphics, pp. 135140, April 1999. ht t p: / / www.cs.unc.edu/ ~ raskar/ NPR Raskar, Ram esh, Hardwar e Support for Non- phot orealist ic Rendering, ACM SI GGRAPH/ Eurograph Graphics Hardware, pp. 4146, 2001. ht t p: / / www.cs.unc.edu/ ~ raskar/ HWWS Reeves, William T., Part icle Syst em sA Technique for Modeling a Class of Fuzzy Obj ect s, ACM Tran vol. 2, no. 2, pp. 91108, April 1983.

Reeves, William T., and Ricki Blau, Approxim at e and Probabilist ic Algorit hm s for Shading and Ren Part icle Syst em s, Com put er Graphics ( SI GGRAPH '85 Proceedings) , pp. 313322, July 1985. Reeves, William T., David H. Salesin, and Robert L. Cook, Render ing Ant ialiased Shadows wit h D Graphics ( SI GGRAPH '87 Proceedings) , pp. 283291, July 1987. Reynolds, Craig, St ylized Depict ion in Com put er Graphics, Web sit e. ht t p: / / w ww .red3d.com / cwr / Rost , Randi J., The OpenGL Shading Language, SI GGRAPH 2002, Course 17, course not es. ht t p: / Rost , Randi J., Using OpenGL for I m aging, SPI E Medical I m aging '96 I m age Display Conference, ht t p: / / 3dshaders.com / pubs Salisbury, Michael, Sean E. Anderson, Ronen Barzel, and David H. Salesin, I nt eract ive Pen- and- I Com put er Graphics ( SI GGRAPH '94 Proceedings) , pp. 101108, July 1994. ht t p: / / grail.cs.w ashing Salisbury, Michael, I m age- Based Pen- and- I nk I llust rat ion, Ph.D. t hesis, Universit y of Washingt on ht t p: / / grail.cs.w ashingt on.edu/ t heses Sait o, Takafum i, and Tokiichiro Takahashi, Com prehensible Rendering of 3- D Shapes, Com put er '90 Proceedings) , pp. 197206, August 1990. Schlick, Christ ophe, An I nexpensive BRDF Model for Physically Based Rendering, Eurographics '9 Com put er Graphics Forum , vol. 13., no. 3, pp. 149162, Sept em ber 1994. Schneider, Philip, and David Eberly, Geom et r ic Tools for Com put er Graphics, Morgan Kaufm ann P Francisco, 2002. Segal, Mark, C. Korobkin, R. van Widenfelt , J. Foran, and P. Haeberli, Fast Shadow s and Light ing Mapping, Com put er Graphics ( SI GGRAPH '92 Proceedings) , pp. 249252, July 1992. Segal, Mark, and Kurt Akeley, The Design of t he OpenGL Graphics I nt erface, Silicon Graphics I nc ht t p: / / wwws.sun.com / soft ware/ graphics/ opengl/ OpenGLdesign.pdf Segal, Mark, and Kurt Akeley, The OpenGL Graphics Syst em : A Specificat ion ( Version 2.0) , Edit o Frazier, ( v1.21.5) : Jon Leech, ( v2.0) : Jon Leech and Pat Brown, Sept em ber 2004. ht t p: / / w ww .opengl.org/ docum ent at ion/ spec.ht m l SGI OpenGL Web sit e. ht t p: / / www.sgi.com / soft ware/ opengl SGI OpenGL Shader Web sit e. ht t p: / / www.sgi.com / soft ware/ shader( defunct ) ShaderX2 : Shader Program m ing Tips and Tricks wit h Direct X 9.0, Edit or: Wolfgang Engel, Word 2003. ht t p: / / w ww .shaderx2.com Shishkovt sov, Oles, Deferred Shading in S.T.A.L.K.E.R., in GPU Gem s 2: Program m ing Technique Perform ance Graphics and General- Pur pose Com put at ion, Edit or: Mat t Pharr, Addison- Wesley, R Massachuset t s, 2005. ht t p: / / developer.nvidia.com / obj ect / gpu_gem s_2_hom e.ht m l SI GGRAPH Proceedings, Web sit e of online m at erials. ht t p: / / port al.acm .org. Sillion, François, and Claude Puech, Radiosit y and Global I llum inat ion, Morgan Kaufm ann Publish 1994. Sloup, Jaroslav, Physically- based Sim ulat ion: A Survey of t he Modelling and Rendering of t he Ear Proceedings of t he 18t h Spring Conference on Com put er Graphics, pp. 141150, April 2002. ht t p: / / sgi.felk.cvut .cz/ ~ sloup/ ht m l/ research/ proj ect

Sm it h, Alvy Ray, Color Gam ut Transform Pair s, Com put er Graphics ( SI GGRAPH '78 Proceedings) 1978. ht t p: / / w ww .alvyray.com Sm it h, Alvy Ray, Digit al Filt ering Tut orial for Com put er Gr aphics, Lucasfilm Technical Mem o 27, r ht t p: / / www.alvyray.com / m em os/ default .ht m Sm it h, Alvy Ray, Digit al Filt ering Tut orial, Part I I , Lucasfilm Technical Mem o 27, revised March 1 ht t p: / / www.alvyray.com / m em os/ default .ht m Sm it h, Alvy Ray, A Pixel I s Not a Lit t le Square, A Pixel I s Not a Lit t le Square, A Pixel I s Not a Lit t Voxel is Not a Lit t le Cube) , Technical Mem o 6, Microsoft Research, July 1995. ht t p: / / www.alvyray.com / m em os/ default .ht m SMPTE RP 1771993, Derivat ion of Basic Television Color Equat ions. St am , Jos, Diffract ion Shaders, Com put er Graphics ( SI GGRAPH '99 Proceedings) , pp. 101110, Au ht t p: / / www.dgp.t oront o.edu/ people/ st am / realit y/ Research/ pdf/ diff.pdf St am , Jos, Sim ulat ing Diffract ion, in GPU Gem s: Program m ing Techniques, Tips, and Tricks for R Edit or: Randim a Fernando, Addison- Wesley, Reading, Massachuset t s, 2004. ht t p: / / developer.nvidia.com / obj ect / gpu_gem s_hom e.ht m l St okes, Michael, Mat t hew Anderson, Srinivasan Chandrasekar, and Ricardo Mot t a, A St andard De t he I nt ernet sRGB, Version 1.10, Novem ber 1996. ht t p: / / www.color.org/ sRGB.ht m l St one, Maur een, A Survey of Color for Com put er Gr aphics, Course 4 at SI GGRAPH 2001, August ht t p: / / www.st onesc.com St rot hot t e, Thom as, and S. Schlect weg, Non- Phot orealist ic Com put er Graphics, Modeling, Rende Morgan Kaufm ann Publishers, San Francisco, 2002. St roust r up, Bj arne, The C+ + Program m ing Language ( Special 3rd Edit ion) , Addison- Wesley, Rea 2000. Taylor, Philip, Per - Pixel Light ing, Microsoft Corp., Novem ber 2001. Thom as, Frank, and Ollie Johnst on, Disney Anim at ionThe I llusion of Life, Abbeville Press, New Yo Thom as, Frank, and Ollie Johnst on, The I llusion of LifeDisney Anim at ion, Revised Edit ion, Hyperi Torr ance, K., and E. Sparrow, Theory for Off- Specular Reflect ion from Roughened Surfaces, J. Op Am erica, vol. 57, Sept em ber 1967. Tuft e, Edward, Visual Explanat ions, Graphics Press, Cheshire, Connect icut , 1997. Upst ill, St eve, The Render Man Com panion: A Program m er's Guide t o Realist ic Com put er Graphic Reading, Massachuset t s, 1990. Verbeck, Channing P., and D. Greenberg, A Com prehensive Light Source Descript ion for Com put Com put er Graphics and Applicat ions, vol. 4, no. 7, July 1984, pp. 6675. War d, Gregory, Measuring and Modeling Anisot ropic Reflect ion, Com put er Graphics ( SI GGRAPH ' 265272, July 1992. ht t p: / / radsit e.lbl.gov/ radiance/ papers/ sg92/ paper.ht m l Wat t , Alan H., and Mark Wat t , Advanced Anim at ion and Rendering Techniques: Theory and Pract Reading, Massachuset t s, 1992.

Whit t ed, Turner, An I m proved I llum inat ion Model for Shaded Display, Com m unicat ions of t he AC 343349, 1980. William s, Lance, Pyram idal Param et rics, Com put er Graphics ( SI GGRAPH '83 Proceedings) , pp. 11 Winkenbach, Georges, and David Salesin, Com put er- Generat ed Pen- and- I nk I llust rat ion, Com pu ( SI GGRAPH '94 Proceedings) , pp. 91100, July 1994. ht t p: / / grail.cs.w ashingt on.edu/ pub Winkenbach, Georges, Com put er- Generat ed Pen- and- I nk I llust rat ion, Ph.D. Dissert at ion, Univers 1996. ht t p: / / grail.cs.w ashingt on.edu/ t heses Wolber g, George, Digit al I m age Warping, Wiley- I EEE Press, 2002. Woo, Andrew, P. Poulin, and A. Fournier, A Survey of Shadow Algorit hm s, I EEE Com put er Gr aph vol. 10, no. 6, pp.1332, Novem ber 1990. Worley, St even, A Cellular Text ure Basis Funct ion, Com put er Graphics ( SI GGRAPH '96 Proceedin August 1996. Wright , Richard, and Benj am in Lipchak, OpenGL SuperBible, Third Edit ion, Sam s Publishing, 200 ht t p: / / www.st arst onesoft ware.com / OpenGL/ opengl_superbbile.ht m Wright , Richard, Underst anding and Using OpenGL Text ure Obj ect s, Gam asut r a, July 23, 1999. ht t p: / / www.gam asut ra.com / feat ures/ 19990723/ opengl_t ext ure_obj ect s_01.ht m Zhukov, Sergei, A. I ones, G. Kronin, An Am bient Light I llum inat ion Model, Proceedings of Eurogr Workshop '98. Zwillinger, Dan, CRC St andard Mat hem at ical Tables and Form ulas, 30t h Edit ion, CRC Press, 1995 ht t p: / / geom .m at h.uiuc.edu/ docs/ reference/ CRC- form ulas/