Is it possible to draw line thickness in a fragment shader?
文章推薦指數: 80 %
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
延伸文章資訊
- 1Smooth line drawing, glsl, shader, openframeworks, sketch
Smooth line drawing, glsl, shader, openframeworks, sketch - ofApp.cpp. ... I draw the lines as on...
- 2Draw Line - Shadertoy
Build shaders, share them, and learn from the best community.
- 3Drawing Lines with WebGL - Scott Logic Blog
How would we do this in the vertex shader? We can take advantage of GL_TRIANGLE_STRIP . A triangl...
- 4Compute Shader for Drawing Lines - gists · GitHub
https://forum.unity.com/threads/compute-shader-for-line-drawing.599989/. #pragma kernel CSMain. R...
- 5Drawing lines with shader - OpenGL - Khronos Forums
Hello, I'm trying to draw cube with lines which connects every single vertex on 3D space. and I w...