Any way to smooth circle edges?

Hi all,

There’s been a few projects that I’ve wanted to include rounded avatars but have been turned off by the sharpness of the outlines I try to put behind them:

The outlines I am currently using are made from surface.DrawCircle. Is anyone aware of any methods to soften those edges a little? I’m not a huge fan of how jagged they are.

Thanks!

I think the only ‘good’ way would be with stencils, can a big server men halp?

I would suggest using a material instead.

Yeah, material is probably right. Stencils will make the same aliasing problem.

Not near my PC but one way it could be done is;

  1. Make an anti-aliased circle texture in advance
  2. Use a 2-texture material and use the circle texture as a mask
  3. Set the texture you want to draw as the other texture in the material, and draw the material

Hope that works!

ehh, try this.



local PANEL = {}
local cos, sin, rad = math.cos, math.sin, math.rad
AccessorFunc(PANEL, "m_masksize", "MaskSize", FORCE_NUMBER)

function PANEL:Init()
    self.Avatar = vgui.Create("AvatarImage", self)
    self.Avatar:SetPaintedManually(true)
    self:SetMaskSize(24)
end

function PANEL:PerformLayout()
    self.Avatar:SetSize(self:GetWide(), self:GetTall())
end

function PANEL:SetPlayer(id)
    self.Avatar:SetPlayer(id, self:GetWide())
end

function PANEL:SetSteamID(steamid, size)
    self.Avatar:SetSteamID(steamid, size)
end

function PANEL:Paint(w, h)
    render.ClearStencil() -- some people are so messy
    render.SetStencilEnable(true)
    render.SetStencilWriteMask(1)
    render.SetStencilTestMask(1)
    render.SetStencilFailOperation(STENCILOPERATION_REPLACE)
    render.SetStencilPassOperation(STENCILOPERATION_ZERO)
    render.SetStencilZFailOperation(STENCILOPERATION_ZERO)
    render.SetStencilCompareFunction(STENCILCOMPARISONFUNCTION_NEVER)
    render.SetStencilReferenceValue(1)
    local _m = self.m_masksize
    local circle, t = {}, 0

    for i = 1, 360 do
        t = rad(i * 720) / 720

        circle* = {
            x = w / 2 + cos(t) * _m,
            y = h / 2 + sin(t) * _m
        }
    end

    draw.NoTexture()
    surface.SetDrawColor(color_white)
    surface.DrawPoly(circle)
    render.SetStencilFailOperation(STENCILOPERATION_ZERO)
    render.SetStencilPassOperation(STENCILOPERATION_REPLACE)
    render.SetStencilZFailOperation(STENCILOPERATION_ZERO)
    render.SetStencilCompareFunction(STENCILCOMPARISONFUNCTION_EQUAL)
    render.SetStencilReferenceValue(1)
    self.Avatar:SetPaintedManually(false)
    self.Avatar:PaintManual()
    self.Avatar:SetPaintedManually(true)
    render.SetStencilEnable(false)
    render.ClearStencil()
end

vgui.Register("AvatarCircleMask", PANEL)


Usage:




                local Avatar = vgui.Create("AvatarCircleMask", PARENT )
                Avatar:SetSize(128, 128)
                Avatar:SetPos(0, 0)
                Avatar:SetMaskSize(128 / 2) --should be half of size


Tried drawing a poly circle behind the image before I tried using surface.DrawCircle :frowning:

Thanks for this kpj, but had the same result as the stencil that I’m using:

I’ll be trying this next. I appreciate all the help guys!

EDIT:
Thanks for all the help everyone, I managed to create a anti aliased circle material and just put it behind the stenciled avatar, and now it looks much smoother. Thank you Nak and NeatNit in particular :slight_smile:

(this is now solved)