GLSL 4.0: Using Subroutines to Select Shader Functionality
文章推薦指數: 80 %
The value of this variable can be set from the OpenGL side, ... avoiding a conditional statement or a shader swap can be very valuable. Home»GLSL4.0:UsingSubroutinestoSelectShaderFunctionality GLSL4.0:UsingSubroutinestoSelectShaderFunctionality BacktoPosts GLSL4.0:UsingSubroutinestoSelectShaderFunctionality AhrenStevens-Taylor2022-05-27T09:58:52+00:00 OpenGL4.0ShadingLanguageCookbook Over60highlyfocused,practicalrecipestomaximizeyourOpenGLShadinglanguageuse InmanywaysitissimilartofunctionpointersinC.Auniformvariableservesasthepointerandisusedtoinvokethefunction.ThevalueofthisvariablecanbesetfromtheOpenGLside,therebybindingittooneofafewpossibledefinitions.Thesubroutine’sfunctiondefinitionsneednothavethesamename,butmusthavethesamenumberandtypeofparametersandthesamereturntype. Asingleshadercouldbewrittentoprovideseveralshadingalgorithmsintendedforuseondifferentobjectswithinthescene.Whenrenderingthescene,ratherthanswappingshaderprograms(orusingaconditionalstatement),wecansimplychangethesubroutine’suniformvariabletochoosetheappropriateshadingalgorithmaseachobjectisrendered. Sinceperformanceiscrucialinshaderprograms,avoidingaconditionalstatementorashaderswapcanbeveryvaluable.Withsubroutines,wecanimplementthefunctionalityofaconditionalstatementorshaderswapwithoutthecomputationaloverhead. Inthefollowingimage,weseeanexampleofarenderingthatwascreatedusingsubroutines.TheteapotontheleftisrenderedwiththefullADSshadingmodel,andtheteapotontherightisrenderedwithdiffuseshadingonly.Asubroutineisusedtoswitchbetweenshaderfunctionality. Gettingready Aswithpreviousrecipes,providethevertexpositionatattributelocation0andthevertexnormalatattributelocation1.UniformvariablesforalloftheADScoefficientsshouldbesetfromtheOpenGLside,aswellasthelightpositionandthestandardmatrices. We’llassumethat,intheOpenGLapplication,thevariableprogramHandlecontainsthehandletotheshaderprogramobject. Howtodoit… Tocreateashaderprogramthatusesasubroutinetoswitchbetweenpure-diffuseandADSshading,usethefollowingcode: Usethefollowingcodeforthevertexshader: #version400 subroutinevec3shadeModelType(vec4position,vec3normal); subroutineuniformshadeModelTypeshadeModel; layout(location=0)invec3VertexPosition; layout(location=1)invec3VertexNormal; outvec3LightIntensity; structLightInfo{ vec4Position;//Lightpositionineyecoords. vec3La;//Ambientlightintensity vec3Ld;//Diffuselightintensity vec3Ls;//Specularlightintensity }; uniformLightInfoLight; structMaterialInfo{ vec3Ka;//Ambientreflectivity vec3Kd;//Diffusereflectivity vec3Ks;//Specularreflectivity floatShininess;//Specularshininessfactor }; uniformMaterialInfoMaterial; uniformmat4ModelViewMatrix; uniformmat3NormalMatrix; uniformmat4ProjectionMatrix; uniformmat4MVP; voidgetEyeSpace(outvec3norm,outvec4position) { norm=normalize(NormalMatrix*VertexNormal); position=ModelViewMatrix*vec4(VertexPosition,1.0); } subroutine(shadeModelType) vec3phongModel(vec4position,vec3norm) { //TheADSshadingcalculationsgohere(see:“Using //functionsinshaders,”and“Implementing //per-vertexambient,diffuseandspecular(ADS)shading”) … } subroutine(shadeModelType) vec3diffuseOnly(vec4position,vec3norm) { vec3s=normalize(vec3(Light.Position–position)); return Light.Ld*Material.Kd*max(dot(s,norm),0.0); } voidmain() { vec3eyeNorm; vec4eyePosition; //Getthepositionandnormalineyespace getEyeSpace(eyeNorm,eyePosition); //Evaluatetheshadingequation.Thiswillcalloneof //thefunctions:diffuseOnlyorphongModel. LightIntensity=shadeModel(eyePosition,eyeNorm); gl_Position=MVP*vec4(VertexPosition,1.0); } Usethefollowingcodeforthefragmentshader: #version400 invec3LightIntensity; layout(location=0)outvec4FragColor; voidmain(){ FragColor=vec4(LightIntensity,1.0); } IntheOpenGLapplication,compileandlinktheaboveshadersintoashaderprogram,andinstalltheprogramintotheOpenGLpipeline. WithintherenderfunctionoftheOpenGLapplication,usethefollowingcode: GLuintadsIndex= glGetSubroutineIndex(programHandle, GL_VERTEX_SHADER,”phongModel”); GLuintdiffuseIndex= glGetSubroutineIndex(programHandle, GL_VERTEX_SHADER,“diffuseOnly”); glUniformSubroutinesuiv(GL_VERTEX_SHADER,1,&adsIndex); …//Rendertheleftteapot glUniformSubroutinesuiv(GL_VERTEX_SHADER,1,&diffuseIndex); …//Rendertherightteapot Howitworks… Inthisexample,thesubroutineisdefinedwithinthevertexshader.Thefirststepinvolvesdeclaringthesubroutinetype. subroutinevec3shadeModelType(vec4position, vec3normal); ThisdefinesanewsubroutinetypewiththenameshadeModelType.Thesyntaxisverysimilartoafunctionprototype,inthatitdefinesaname,aparameterlist,andareturntype.Aswithfunctionprototypes,theparameternamesareoptional. Aftercreatingthenewsubroutinetype,wedeclareauniformvariableofthattypenamedshadeModel. subroutineuniformshadeModelTypeshadeModel; ThisvariableservesasourfunctionpointerandwillbeassignedtooneofthetwopossiblefunctionsintheOpenGLapplication. Wedeclaretwofunctionstobepartofthesubroutinebyprefixingtheirdefinitionwiththesubroutinequalifier: subroutine(shadeModelType) Thisindicatesthatthefunctionmatchesthesubroutinetype,andthereforeitsheadermustmatchtheoneinthesubroutinetypedefinition.WeusethisprefixforthedefinitionofthefunctionsphongModelanddiffuseOnly.ThediffuseOnlyfunctioncomputesthediffuseshadingequation,andthephongModelfunctioncomputesthecompleteADSshadingequation. WecalloneofthetwosubroutinefunctionsbyutilizingthesubroutineuniformshadeModelwithinthemainfunction. LightIntensity=shadeModel(eyePosition,eyeNorm); Again,thiscallwillbeboundtooneofthetwofunctionsdependingonthevalueofthesubroutineuniformshadeModel,whichwewillsetwithintheOpenGLapplication. WithintherenderfunctionoftheOpenGLapplication,weassignavaluetothesubroutineuniformwiththefollowingsteps.First,wequeryfortheindexofeachsubroutinefunctionusingglGetSubroutineIndex.Thefirstargumentistheprogramhandle.Thesecondistheshaderstage.Inthiscase,thesubroutineisdefinedwithinthevertexshader,soweuseGL_VERTEX_SHADERhere.Thethirdargumentisthenameofthesubroutine.WequeryforeachfunctionindividuallyandstoretheindexesinthevariablesadsIndexanddiffuseIndex. Toselecttheappropriatesubroutinefunction,weneedtosetthevalueofthesubroutineuniformshadeModel.Todoso,wecallglUniformSubroutinesuiv.Thisfunctionisdesignedforsettingmultiplesubroutineuniformsatonce.Inourcase,ofcourse,wearesettingonlyasingleuniform.Thefirstargumentistheshaderstage(GL_VERTEX_SHADER),thesecondisthenumberofuniformsbeingset,andthethirdisapointertoanarrayofsubroutinefunctionindexes.Sincewearesettingasingleuniform,wesimplyprovidetheaddressoftheGLuintvariablecontainingtheindex,ratherthanatruearrayofvalues.Ofcourse,wewoulduseanarrayifmultipleuniformswerebeingset.Ingeneral,thearrayofvaluesprovidedasthethirdargumentisassignedtosubroutineuniformvariablesinthefollowingway.Theithelementofthearrayisassignedtothesubroutineuniformvariablewithindexi.Sincewehaveprovidedonlyasinglevalue,wearesettingthesubroutineuniformatindexzero. Youmaybewondering,“Howdoweknowthatoursubroutineuniformislocatedatindexzero?Wedidn’tqueryfortheindexbeforecallingglUniformSubroutinesuiv!”ThereasonthatthiscodeworksisthatwearerelyingonthefactthatOpenGLwillalwaysnumbertheindexesofthesubroutinesconsecutivelystartingatzero.Ifwehadmultiplesubroutineuniforms,wecould(andshould)queryfortheirindexesusingglGetSubroutineUniformLocation,andthenorderourarrayappropriately. Finally,weselectthephongModelfunctionbysettingtheuniformtoadsIndexandthenrendertheleftteapot.WethenselectthediffuseOnlyfunctionbysettingtheuniformtodiffuseIndexandrendertherightteapot. There’smore… Asubroutinefunctiondefinedinashadercanmatchmultiplesubroutinetypes.Inthatcase,thesubroutinequalifiercancontainacomma-separatedlistofsubroutinetypes.Forexample,ifasubroutinematchedthetypestype1andtype2,wecouldusethefollowingqualifier: subroutine(type1,type2) Thiswouldallowustousesubroutineuniformsofdifferingtypestorefertothesamesubroutinefunction. Summary Withsubroutineswecanimplementthefunctionalityofaconditionalstatementorshaderswapwithoutthecomputationaloverhead. Furtherresourcesonthissubject: TipsandTricksforGettingStartedwithOpenGLandGLSL4.0[Article] OpenGL4.0:UsingUniformBlocksandUniformBufferObjects[Article] OpenGL4.0:BuildingaC++ShaderProgramClass[Article] TheBasicsofGLSL4.0Shaders[Article] GLSL4.0:DiscardingFragmentstoCreateaPerforatedLook[Article] AhrenStevens-Taylor GameDevelopmentNews,Tutorials 0Comments Like:0 Sharethispost Facebook Twitter LinkedIn Email Reddit LeaveaReplyCancelreplyYouremailaddresswillnotbepublished.Requiredfieldsaremarked*Comment*Name* Email* Website Savemyname,email,andwebsiteinthisbrowserforthenexttimeIcomment. BacktoPosts RelatedPosts 15JunJune15,2022 HowtobuildaGaussianMixtureModel [boxtype="note"align=""class=""width=""]ThisarticleisanexcerptfromabookauthoredbyOsvaldoMartintitledBayesianAnalysiswith...readmore 14JunJune14,2022 HowtoformatandpublishcodeusingRMarkdown [boxtype="note"align=""class=""width=""]ThisarticleisanexcerptfromabookwrittenbyAhmedSheriftitledPracticalBusinessIntelligence....readmore 14JunJune14,2022 ImplementNamedEntityRecognition(NER)usingOpenNLPandJava [boxtype="note"align=""class=""width=""]ThisarticleisanexcerptfromabookwrittenbyRichardM.ReeseandJenniferL....readmore 14JunJune14,2022 HowtocreateaBoxandWhiskerPlotinTableau [boxtype="note"align=""class=""width=""]ThisarticleisanexcerptfromabookwrittenbyShwetaSankhe-Savale,titledTableauCookbook–...readmore 14JunJune14,2022 WorkingwithKibanainElasticsearch5.x [boxtype="note"align=""class=""width=""]BelowgivenpostisabookexcerptfromMasteringElasticsearch5.xwrittenby BharviDixit.This...readmore 14JunJune14,2022 SavingbackupsoncloudserviceswithElasticSearchplugins [boxtype="note"align=""class=""width=""]OurarticleisabookexcerpttakenfromMasteringElasticsearch5.x.writtenbyBharviDixit.This...readmore 14JunJune14,2022 HowtoexecuteasearchqueryinElasticSearch [boxtype="note"align=""class=""width=""]ThispostisanexcerptfromabookauthoredbyAlbertoParo,titledElasticsearch5.xCookbook....readmore 14JunJune14,2022 Whatarediscriminativeandgenerativemodelsandwhentousewhich? [boxtype="note"align=""class=""width=""]OurarticleisabookexcerptfromBayesianAnalysiswithPythonwrittenOsvaldoMartin.Thisbook...readmore 14JunJune14,2022 RunningParallelDataOperationsusingJavaStreams [boxtype="note"align=""class=""width=""]Ourarticleisanexcerptfromabookco-authoredbyRichardM.ReeseandJenniferL....readmore 14JunJune14,2022 HowtoImplementaNeuralNetworkwithSingle-LayerPerceptron [boxtype="note"align=""class=""width=""]ThisarticleisanexcerptfromabookbyRodolfoBonnintitledMachineLearningforDevelopers....readmore Search CategoriesCategories SelectCategory Cloud&NetworkingNews (737) CloudComputingNews (97) DevOpsNews (28) NetworkingNews (110) ServersNews (93) VirtualizationNews (112) DataNews (1,148) ArtificialIntelligenceNews (277) BigDataNews (153) BusinessIntelligenceNews (86) DataAnalysisNews (94) DatabasesNews (20) Featured (32) GameDevelopmentNews (361) 2DGameDevelopmentNews (62) 3DGameDevelopmentNews (108) GameAINews (8) GameDesignNews (26) GameOptimizationNews (4) Insights (506) Interviews (31) IoT&HardwareNews (149) 3DPrintingNews (13) EmbeddedSystemsNews (13) HomeAutomationNews (8) RoboticsNews (35) SingleBoardComputersNews (70) MobileNews (246) AndroidProgrammingNews (60) AugmentedReality/VirtualRealityNews (7) Cross-PlatformMobileDevelopmentNews (95) iOSProgrammingNews (71) MobileGameDevelopmentNews (3) News (169) ProgrammingNews (994) ApplicationDevelopmentNews (328) DesignPatternsNews (30) HighPerformanceNews (39) LanguagesNews (94) MicroservicesNews (13) SecurityNews (131) CybersecurityNews (56) ForensicsNews (18) MalwareAnalysisNews (2) PenetrationTestingNews (55) Tutorials (5,838) Uncategorized (6) WebDevelopmentNews (1,764) CMS&E-CommerceNews (830) Front-EndWebDevelopmentNews (365) Full-StackWebDevelopmentNews (35) Server-SideWebDevelopmentNews (391) WebDesignNews (129) LatestPosts HowtobuildaGaussianMixtureModel 29thDec.’17–Headlines HowtoformatandpublishcodeusingRMarkdown ImplementNamedEntityRecognition(NER)usingOpenNLPandJava HowtocreateaBoxandWhiskerPlotinTableau PleaseNote:Accountswillnotsyncforexistingusersofpacktpub.combutyoucancreatenewaccountsduringthecheckoutprocessonthisnewStore. Weusecookiesonourwebsitetogiveyouthemostrelevantexperiencebyrememberingyourpreferencesandrepeatvisits.Byclicking“Accept”,youconsenttotheuseofALLthecookies.HoweveryoumayvisitCookieSettingstoprovideacontrolledconsent.CookiesettingsACCEPTManageconsent Close PrivacyOverview Thiswebsiteusescookiestoimproveyourexperiencewhileyounavigatethroughthewebsite.Outofthesecookies,thecookiesthatarecategorizedasnecessaryarestoredonyourbrowserastheyareessentialfortheworkingofbasicfunctionalitiesofthewebsite.Wealsousethird-partycookiesthathelpusanalyzeandunderstandhowyouusethiswebsite.Thesecookieswillbestoredinyourbrowseronlywithyourconsent.Youalsohavetheoptiontoopt-outofthesecookies.Butoptingoutofsomeofthesecookiesmayhaveaneffectonyourbrowsingexperience. Necessary Necessary AlwaysEnabled Necessarycookiesareabsolutelyessentialforthewebsitetofunctionproperly.Thesecookiesensurebasicfunctionalitiesandsecurityfeaturesofthewebsite,anonymously. CookieDurationDescriptioncookielawinfo-checkbox-analytics11monthsThiscookieissetbyGDPRCookieConsentplugin.Thecookieisusedtostoretheuserconsentforthecookiesinthecategory"Analytics".cookielawinfo-checkbox-functional11monthsThecookieissetbyGDPRcookieconsenttorecordtheuserconsentforthecookiesinthecategory"Functional".cookielawinfo-checkbox-necessary11monthsThiscookieissetbyGDPRCookieConsentplugin.Thecookiesisusedtostoretheuserconsentforthecookiesinthecategory"Necessary".cookielawinfo-checkbox-others11monthsThiscookieissetbyGDPRCookieConsentplugin.Thecookieisusedtostoretheuserconsentforthecookiesinthecategory"Other.cookielawinfo-checkbox-performance11monthsThiscookieissetbyGDPRCookieConsentplugin.Thecookieisusedtostoretheuserconsentforthecookiesinthecategory"Performance".viewed_cookie_policy11monthsThecookieissetbytheGDPRCookieConsentpluginandisusedtostorewhetherornotuserhasconsentedtotheuseofcookies.Itdoesnotstoreanypersonaldata. Functional functional Functionalcookieshelptoperformcertainfunctionalitieslikesharingthecontentofthewebsiteonsocialmediaplatforms,collectfeedbacks,andotherthird-partyfeatures. Performance performance Performancecookiesareusedtounderstandandanalyzethekeyperformanceindexesofthewebsitewhichhelpsindeliveringabetteruserexperienceforthevisitors. Analytics analytics Analyticalcookiesareusedtounderstandhowvisitorsinteractwiththewebsite.Thesecookieshelpprovideinformationonmetricsthenumberofvisitors,bouncerate,trafficsource,etc. Advertisement advertisement Advertisementcookiesareusedtoprovidevisitorswithrelevantadsandmarketingcampaigns.Thesecookiestrackvisitorsacrosswebsitesandcollectinformationtoprovidecustomizedads. Others others Otheruncategorizedcookiesarethosethatarebeinganalyzedandhavenotbeenclassifiedintoacategoryasyet. Save&Accept
延伸文章資訊
- 1GLSL 4.0: Using Subroutines to Select Shader Functionality
The value of this variable can be set from the OpenGL side, ... avoiding a conditional statement ...
- 2OpenGL Shading Language ( GLSL ) I
Return: A non-zero value for future reference. void glShaderSource ( GLuint shader, GLsizei count...
- 3Advanced GLSL - LearnOpenGL
The gl_Position and gl_PointSize are output variables since their value is read as output from th...
- 4swap.glsl - gists · GitHub
Instantly share code, notes, and snippets. @gre · gre/swap.glsl. Forked from gre ...
- 5The Book of Shaders: color
Another great feature of vector types in GLSL is that the properties can be combined in any order...