About Monkey 2 › Forums › Monkey 2 Projects › Poor mans Antialias
This topic contains 3 replies, has 4 voices, and was last updated by
Mark Sibly
2 years, 3 months ago.
-
AuthorPosts
-
January 10, 2017 at 10:25 am #6365
I have the need for antialiasing my vectordrawings, and after several attemts, I’ve come up with this simple aproach that seems to work well. The idea is to render an oversized copy, and then draw it in tiles, downscaled to fit the target.
Extra memory needed is only temporarily an extra target image size.
Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133' Poor mans antialias.' Antialias a vector drawing ( or anyting really if modified) by oversamling, and tiledrawing to a canvas.' Tested on MacOS, iOS and Android' by Peter Scheutz aka Diffrenzy' 2017.01.10'#Import "<std>"#Import "<mojo>"Using std..Using mojo..Class AAPolygonTest Extends WindowField img:ImageField points:Float[]Method New()local pointlist:= New List<Float>Local radius:Float = 200local offx:Float = 200Local offy:Float = 200For Local angle:Float = 0 to Pi*2 Step Pi/4.0Local x:float = Cos(angle)*radius+offxLocal y:float = Sin(angle)*radius+offypointlist.AddLast(x)pointlist.AddLast(y)Nextpoints= pointlist.ToArray()img = Polygon2AAImage(points,Color.Red,420,420)EndMethod OnRender( canvas:Canvas ) OverrideApp.RequestRender()canvas.Clear( Color.White)canvas.Alpha=1Local time:Float = Millisecs() *0.0005Local x:Float = Cos(time)*100Local y:Float = Sin(time)*100' draw normal polygoncanvas.Color = Color.Bluecanvas.DrawPoly(points)' draw oversampled imagecanvas.Color = Color.Whitecanvas.DrawImage(img,x,y)EndEndFunction Main()New AppInstanceNew AAPolygonTestApp.Run()End' oversample polygon by drawing it ovesized, and scaling it downFunction Polygon2AAImage:Image(points:Float[],fill:Color,w:Int,h:Int)Local anti:Int = 4' scale pointsLocal drawpoints:= New Float[points.Length]For Local i:Int =0 Until points.Lengthdrawpoints[i] = points[i] * antinext' the image to returnLocal finalimage:Image = New Image(w,h)Local finalcanvas:= New Canvas(finalimage)' the image we render the anti*anti parts toLocal tempimage:Image = New Image(w,h)Local tempcanvas:= New Canvas(tempimage)' remember to set mipmap flag for downscalingtempcanvas.TextureFilter = TextureFilter.Mipmapfinalcanvas.Clear( New Color(0,0,0,0 ))Local sc:Float = 1.0/anti' downscale the "brush" imagetempimage.Scale = New Vec2f(sc,sc)tempcanvas.Color = fill' tile render with offset' remember to Flush(), or you will only see the last tile.For Local y:Int = 0 Until antiFor Local x:Int = 0 Until antitempcanvas.Clear( New Color(0,0,0,0 ))tempcanvas.PushMatrix()tempcanvas.Translate(-x*w,-y*h)tempcanvas.DrawPoly(drawpoints)tempcanvas.Flush()tempcanvas.PopMatrix()finalcanvas.DrawImage(tempimage,x*w/anti,y*h/anti)finalcanvas.Flush()nextnextReturn finalimageEnd FunctionAttachments:
January 10, 2017 at 4:18 pm #6369Great, that works well.
January 10, 2017 at 7:40 pm #6375This looks very good for a graphics filter.
January 12, 2017 at 10:09 pm #6472This is apparently done with shaders a lot these days – possibly not quite as good, but not 4x slower either:
https://blog.codinghorror.com/fast-approximate-anti-aliasing-fxaa/
-
AuthorPosts
You must be logged in to reply to this topic.
