Is it possible to draw line thickness in a fragment shader?

文章推薦指數: 80 %
投票人數:10人

No, it is not possible in the fragment shader using only GL_LINES . This is because GL restricts you ... Home Public Questions Tags Users Companies Collectives ExploreCollectives Teams StackOverflowforTeams –Startcollaboratingandsharingorganizationalknowledge. CreateafreeTeam WhyTeams? Teams CreatefreeTeam Collectives™onStackOverflow Findcentralized,trustedcontentandcollaboratearoundthetechnologiesyouusemost. LearnmoreaboutCollectives Teams Q&Aforwork Connectandshareknowledgewithinasinglelocationthatisstructuredandeasytosearch. LearnmoreaboutTeams Isitpossibletodrawlinethicknessinafragmentshader? AskQuestion Asked 9years,6monthsago Modified 1year,7monthsago Viewed 48ktimes 26 14 IsitpossibleformetoaddlinethicknessinthefragmentshaderconsideringthatIdrawthelinewithGL_LINES?MostoftheexamplesIsawseemtoaccessonlythetexelswithintheprimitiveinthefragmentshaderandalinethicknessshaderwouldneedtowritetotexelsoutsidethelineprimitivetoobtainthethickness.Ifitispossiblehowever,averysmall,basic,example,wouldbegreat. opengl-esopengl-es-2.0 Share Follow editedMar7,2013at18:59 genpfault 49.8k1010goldbadges8181silverbadges130130bronzebadges askedMar7,2013at16:28 MedaMeda 2,66644goldbadges1919silverbadges3131bronzebadges 1 Despitetheacceptedanswer,themorepracticalansweris"youdon'twanttodothat"(inafragmentshader)-itsnotatechniquethatwillscalewelltomanylines.Seeitjak'sanswer. – ToolmakerSteve Jul4,2019at18:32 Addacomment  |  5Answers 5 Sortedby: Resettodefault Highestscore(default) Trending(recentvotescountmore) Datemodified(newestfirst) Datecreated(oldestfirst) 30 Quitealotispossiblewithfragmentshaders.Justlookwhatsomeguysaredoing.I'mfarawayfromthatlevelmyselfbutthiscodecangiveyouanidea: #defineresolutionvec2(500.0,500.0) #defineThickness0.003 floatdrawLine(vec2p1,vec2p2){ vec2uv=gl_FragCoord.xy/resolution.xy; floata=abs(distance(p1,uv)); floatb=abs(distance(p2,uv)); floatc=abs(distance(p1,p2)); if(a>=c||b>=c)return0.0; floatp=(a+b+c)*0.5; //medianto(p1,p2)vector floath=2/c*sqrt(p*(p-a)*(p-b)*(p-c)); returnmix(1.0,0.0,smoothstep(0.5*Thickness,1.5*Thickness,h)); } voidmain() { gl_FragColor=vec4( max( max( drawLine(vec2(0.1,0.1),vec2(0.1,0.9)), drawLine(vec2(0.1,0.9),vec2(0.7,0.5))), drawLine(vec2(0.1,0.1),vec2(0.7,0.5)))); } Anotheralternativeistocheckwithtexture2Dforthecolorofnearbypixel-thatwayyoucanmakeyouimagegloworthicken(e.g.ifanyoftheadjustmentpixelsarewhite-makecurrentpixelwhite,ifnexttonearbypixeliswhite-makecurrentpixelgrey). Share Follow answeredOct6,2013at18:08 defhltdefhlt 1,76722goldbadges1717silverbadges2424bronzebadges 6 Man,thatwebsiteisgrand! – Meda Oct12,2013at21:34 15 Whilethis"works",itshouldbenotedthatthisisprobablythemostinefficientwayinthworldtodrawthreelines.99%ofthefragmentsthatareprocessedarethrownawayduringblending. – Damon Oct21,2013at18:56 1 +Damonsureitwasnotintendedasbestpracticesandmyexampleissomewhatsilly;butjusttodemonstratetheprincipleandpossibilitiesofshaders-thesimilarwayyoucoulddovariousgloworparticleeffectsorrenderthewholeterrainsfromheightmapsorcomplexgeometricalfractalsfromdistancefieldsnotusingasinglevertex.Surprisinglyshaderscanbeprettyfast. – defhlt Oct21,2013at20:49 1 +Damon,btw,moreinefficientwaythanthiswouldbecalculatingpixelswithCPU,whichiswidelyusednevertheless. – defhlt Oct21,2013at20:59 1 +1towhatDamonsaid.Usingageometryshaderislikelytobemorethan1000xquickerthanthismethod,andallowyoutousenormalfragmentshaderstoapplyadesigntothelinewhenyouwant.Iwouldagreethatthisanswerisgreattosolvethequestiontotheletter,butperhapsnotinspirit. – ElliotWoods Mar10,2016at10:18  |  Show1morecomment 4 Here'smyapproach.Letp1andp2bethetwopointsdefiningtheline,andletpointbethepointwhosedistancetothelineyouwishtomeasure.Pointismostlikelygl_FragCoord.xy/resolution; Here'sthefunction. floatdistanceToLine(vec2p1,vec2p2,vec2point){ floata=p1.y-p2.y; floatb=p2.x-p1.x; returnabs(a*point.x+b*point.y+p1.x*p2.y-p2.x*p1.y)/sqrt(a*a+b*b); } Thenusethatinyourmixandsmoothstepfunctions. Alsocheckoutthisanswer: https://stackoverflow.com/a/9246451/911207 Share Follow editedMay23,2017at12:25 CommunityBot 111silverbadge answeredNov13,2014at5:49 DavidBraunDavidBraun 71211goldbadge88silverbadges1616bronzebadges Addacomment  |  4 No,itisnotpossibleinthefragmentshaderusingonlyGL_LINES.ThisisbecauseGLrestrictsyoutodrawonlyonthegeometryyousubmittotherasterizer,soyouneedtousegeometrythatencompassesthejaggedoriginallineplusanysmoothingvertices.E.g.,youcanuseageometryshadertoexpandyourlinetoaquadaroundtheidealline(or,actuallytwotriangles)whichcanposeasathickline. Ingeneral,ifyougeneratebiggergeometry(includingafullscreenquad),youcanusethefragmentshadertodrawsmoothlines. Here'sanicediscussiononthatsubject(withcodesamples). Share Follow editedFeb14,2020at19:27 answeredMar7,2013at16:36 ltjaxltjax 15.6k22goldbadges3636silverbadges6262bronzebadges 6 sointhefragmentshaderyoucanonlyaccess/modifythefragmentswithinthedrawingprimitives?Thatwouldmakesense.Asforyourproposedsolution,thanksbutinopenglesIcan'tusegeometryshaders:( – Meda Mar7,2013at16:55 Notaccess-youcanreadfromanysource,butyoucanonlywritetoonelocationandthat'sgiventoyoubytherasterizer.YoucanusethesamemethodontheCPUifyoudon'thavegeometryshaders. – ltjax Mar7,2013at17:05 5 neversaynounlessyoucanproveit – GottZ Apr21,2016at8:54 1 @GottZ:Well,Iwasansweringundertheconditionsinthequestion,namelydrawingthelineswithGL_LINES.Sure,ifyourenderfullscreenquad,youcandrawanythinginthefragmentshader.Butthatwasnotwhatwasaskedfor. – ltjax Aug18,2017at14:13 soundssillybutyesiwasreferingtoafullscreenfragmentshaderwhereyouknowresolution(insidetheshader).whydoisaythat?i.imgur.com/dw6y7Ko.pngcauseididit.(yesthisisjusttwopolygonsyouseethere).thiswasmainlyaproofofconceptinrawglslplussomec++winapimagicthough.ineededpixelsizeinformationtogetperfectantialiasingwithoutpostprocessing – GottZ Aug18,2017at15:48  |  Show1morecomment 0 Asimplehackistojustaddajitterinthevertexshader: gl_Position+=vec4(delta,delta,delta,0.0); wheredeltaisthepixelsizei.e.1.0/viewsize Dotheline-drawpasstwiceusingzero,andthenthedeltaasjitter(passedinasauniform). Share Follow answeredJul26,2019at3:33 KBVISKBVIS 1 Addacomment  |  0 TodrawalineinFragmentShader,weshouldcheckthatthecurrentpixel(UV)isonthelineposition.(isnotefficientusingonlytheFragmentshadercode!thisisjustforthetestwithglslsandbox) AnacceptableUVpointshouldhavethesetwoconditions: 1-Themaximumpermissibledistancebetween(uv,pt1)shouldbesmallerthanthedistancebetween(pt1,pt2). Withthisconditionwecreateaassumedcirclewiththecenterofpt2andradious=distance(pt2,pt1)andalsopreventthedrawingoflinethatislongerthanthedistance(pt2,pt1). 2-ForeachUVweassumeahypotheticalcirclewithaconnectionpointonptcpositionoftheline(pt2,pt1). IfthedistancebetweenUVandPTCislessthanthelinetickness,weselectthisUVasthelinepoint. inourcode: r=distance(uv,pt1)/distance(pt1,pt2)giveusavaluebetween0and1. weinterpolateapoint(ptc)betweenpt1andpt2withvalueofr code: #ifdefGL_ES precisionmediumpfloat; #endif uniformfloattime; uniformvec2mouse; uniformvec2resolution; floatline(vec2uv,vec2pt1,vec2pt2,vec2resolution) { floatclrFactor=0.0; floattickness=3.0/max(resolution.x,resolution.y);//onlyusedfortickness floatr=distance(uv,pt1)/distance(pt1,pt2); if(r<=1.0)//ifdesiredHypotheticalcircleinrangeofvector(pt2,pt1) { vec2ptc=mix(pt1,pt2,r);//ptc=connectionpointofHypotheticalcircleandlinecalculatedwithinterpolation floatdist=distance(ptc,uv);//distancebetwenncurrentpixel(uv)andptc if(dist



請為這篇文章評分?