Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
  • Help Room /
avatar image
2
Question by adamtea · Aug 22, 2013 at 11:59 PM · 2dcircledrawingprimitives

How do you draw 2D circles and primitives

I want to know how to draw clean, anti-aliased, scalable circles / ovals / lines and other primitives in Unity!

I know you can create a quad for a square, and you can create a mesh for polygons (like a star, or a pentagon, for example).

But a circle is unique - using a cylinder with 0 height for a circle doesn't work as scaling it shows the polygons.

If anybody knows the game Hundreds on iOS - basically, how is that sort of thing attainable?

Cheers all!

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

5 Replies

· Add your reply
  • Sort: 
avatar image
5

Answer by Liquidwad · Nov 22, 2015 at 06:06 PM

Building off Walter's answer, and adding some more parameters and simple-anti aliasing:

 Shader "Custom/Circle" {
      Properties {
          _Color ("Color", Color) = (1,0,0,0)
          _Thickness("Thickness", Range(0.0,0.5)) = 0.05
          _Radius("Radius", Range(0.0, 0.5)) = 0.4
          _Dropoff("Dropoff", Range(0.01, 4)) = 0.1
      }
      SubShader {
          Pass {
              Blend SrcAlpha OneMinusSrcAlpha // Alpha blending
              CGPROGRAM
             
              #pragma vertex vert
              #pragma fragment frag
              #include "UnityCG.cginc"
             
             
              fixed4 _Color; // low precision type is usually enough for colors
             float _Thickness;
             float _Radius;
             float _Dropoff;
             
              struct fragmentInput {
                  float4 pos : SV_POSITION;
                  float2 uv : TEXTCOORD0;
              };
  
              fragmentInput vert (appdata_base v)
              {
                  fragmentInput o;
  
                  o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
                  o.uv = v.texcoord.xy - fixed2(0.5,0.5);
  
                  return o;
              }
  
              // r = radius
              // d = distance
              // t = thickness
              // p = % thickness used for dropoff
              float antialias(float r, float d, float t, float p) {
                  if( d < (r - 0.5*t))
                     return - pow( d - r + 0.5*t,2)/ pow(p*t, 2) + 1.0;
                 else if ( d > (r + 0.5*t))
                     return - pow( d - r - 0.5*t,2)/ pow(p*t, 2) + 1.0; 
                 else
                     return 1.0;
              }
              
              fixed4 frag(fragmentInput i) : SV_Target {
                 float distance = sqrt(pow(i.uv.x, 2) + pow(i.uv.y,2));
                     
                 return fixed4(_Color.r, _Color.g, _Color.b, _Color.a*antialias(_Radius, distance, _Thickness, _Dropoff));
              }
              
              
              ENDCG
          }
      }
  }


Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Cherno · Nov 22, 2015 at 07:20 PM 0
Share

This might be a useful addition to the user wiki :)

avatar image LucasKlein16 · Mar 31, 2017 at 05:18 PM 1
Share

add this before pass{} in subshader{} to add transparency

 Tags{ "Queue" = "Transparent" "RenderType" = "Transparent" }
        Blend SrcAlpha One$$anonymous$$inusSrcAlpha

and delete Blend SrcAlpha One$$anonymous$$inusSrcAlpha

from the pass{}

avatar image Heremeus LucasKlein16 · Jul 07, 2018 at 09:59 PM 0
Share

If you add the tags as suggested by Lucas$$anonymous$$lein16, you should also add ZWrite Off:

 Tags{ "Queue" = "Transparent" "RenderType" = "Transparent" }
 Blend SrcAlpha One$$anonymous$$inusSrcAlpha
 ZWrite Off

Otherwise the object being rendered occludes other objects behind it.

avatar image
3

Answer by W.Walter · Jun 23, 2015 at 04:37 AM

I know this post is years old, but for future visitors;
There is an alternative to creating a 'perfect' circle that will be perfect at any size, using a custom vertex/fragment shader. Here is my current implementation:

 Shader "Custom/SolidColor" {
     Properties {
         _Color ("Color", Color) = (1,0,0,0)
     }
     SubShader {
         Pass {
             CGPROGRAM
 
             #pragma vertex vert
             #pragma fragment frag
             #include "UnityCG.cginc"
 
             fixed4 _Color; // low precision type is usually enough for colors
 
             struct fragmentInput {
                 float4 pos : SV_POSITION;
                 float2 uv : TEXTCOORD0;
             };
 
             fragmentInput vert (appdata_base v)
             {
                 fragmentInput o;
 
                 o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
                 o.uv = v.texcoord.xy - fixed2(0.5,0.5);
 
                 return o;
             }
 
             fixed4 frag(fragmentInput i) : SV_Target {
                 float distance = sqrt(pow(i.uv.x, 2) + pow(i.uv.y,2));
                 //float distancez = sqrt(distance * distance + i.l.z * i.l.z);
 
 
                 if(distance > 0.5f){
                     return fixed4(1,0,0,1);
                 }
                 else{
                     return fixed4(0,1,0,1);
                 }
             }
             ENDCG
         }
     }
 }


Simply add a material using this shader to the unity 'quad' and it will be rendered as a perfect circle. This code is uncomplete, but it shows the concept :)

EDIT: No anti aliasing sorry, but it can be added.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image kyledavis_io · Jul 22, 2015 at 04:57 PM 0
Share

This seems overly complex just to draw a 2d primitive circle. Why is there not just a method that takes an x,y and diameter??

avatar image W.Walter · Jul 23, 2015 at 11:58 PM 0
Share

Welcome to computer graphics... You want a 'perfect' circle, which involves calculating each pixel separately. (which is what this shader does. For each screen pixel it calculates the distance to the origin of the uv coordinates, and if it is outside the diameter then the pixel is discarded). The only alternatives is creating a mesh programatically with as many vertices as you want for the desired resolution, or using a texture/alpha mask. This shader is probably the most efficiant of the three, and doesn't even take up graphics mem with a texture.

avatar image Zoom377 · Oct 12, 2015 at 01:52 PM 0
Share

Brilliant, thanks. This is very useful for my space exploration project where the edges of planets need to be smooth at a very small scale compared to their full size.

avatar image
2

Answer by Eric5h5 · Aug 23, 2013 at 02:12 AM

You can create meshes using the Mesh class. For a circle, use many polygons so the straight lines aren't distinguishable.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by sparkzbarca · Aug 23, 2013 at 12:04 AM

What your going to want to do for ALL OF THOSE

is use a plane

now to get the shape what your going to want to do is create a circle in photoshop that fits in a square and make the square itself White and the circle However you want just dont use white (this color can be changed used photoshop to any at all if you need to use white its just standard)

now your going to go create whats called an alpha channel.

That is basically where your going to pick 2 colors like say black and white and if its black in that area it'll be fully visible and if its white it'll be fully transparent and grey will be opaque.

You can then basically have it so while you have a plane you can only see the circle portion.

Look up on youtube and google alpha masks and alpha mask transparency and key words like that maybe combined with Gimp and photoshop (2 major tools for creating alpha masked textures)

this will give you tuts on how to do this.

Mark as answered and have a nice day!

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image adamtea · Aug 23, 2013 at 12:13 AM 1
Share

If I scale the plane up though won't the circle get pixellated?

avatar image sparkzbarca · Aug 23, 2013 at 01:27 AM 0
Share

only in relation to the texture size.

If you use a sufficiently sized resolution texture you would find it quite hard before it would become pixelated

avatar image
0

Answer by arthursb · Mar 16, 2017 at 08:29 PM

Building off @Liquidwad's answer, a simple shader that renders the circle on top of your sprite:

 Shader "Custom/CircleOnTop" {
     Properties {
         [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
 
         _Thickness("Thickness", Range(0.0,0.5)) = 0.05
         _Radius("Radius", Range(0.0, 0.5)) = 0.4
         _Dropoff("Dropoff", Range(0.01, 4)) = 0.1
 
         [HideInInspector] _StencilComp ("Stencil Comparison", Float) = 8
         [HideInInspector] _Stencil ("Stencil ID", Float) = 0
         [HideInInspector] _StencilOp ("Stencil Operation", Float) = 0
         [HideInInspector] _StencilWriteMask ("Stencil Write Mask", Float) = 255
         [HideInInspector] _StencilReadMask ("Stencil Read Mask", Float) = 255
         [HideInInspector] _ColorMask ("Color Mask", Float) = 15
         [HideInInspector] [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
     }
 
     SubShader {
         Tags
         { 
             "Queue"="Transparent" 
             "IgnoreProjector"="True" 
             "RenderType"="Transparent" 
             "PreviewType"="Plane"
             "CanUseSpriteAtlas"="True"
         }
         
         Stencil
         {
             Ref [_Stencil]
             Comp [_StencilComp]
             Pass [_StencilOp] 
             ReadMask [_StencilReadMask]
             WriteMask [_StencilWriteMask]
         }
 
         Cull Off
         Lighting Off
         ZWrite Off
         ZTest [unity_GUIZTestMode]
         Blend SrcAlpha OneMinusSrcAlpha
         ColorMask [_ColorMask]
 
         Pass
         {
         CGPROGRAM
             #pragma vertex vert
             #pragma fragment frag
             #pragma target 2.0
 
             #include "UnityCG.cginc"
             #include "UnityUI.cginc"
 
             #pragma multi_compile __ UNITY_UI_ALPHACLIP
             
             struct appdata_t
             {
                 float4 vertex   : POSITION;
                 float4 color    : COLOR;
                 float2 texcoord : TEXCOORD0;
                 UNITY_VERTEX_INPUT_INSTANCE_ID
             };
 
             struct v2f
             {
                 float4 vertex   : SV_POSITION;
                 fixed4 color    : COLOR;
                 float2 texcoord  : TEXCOORD0;
                 float4 worldPosition : TEXCOORD1;
                 UNITY_VERTEX_OUTPUT_STEREO
             };
 
             sampler2D _MainTex;
             float _Thickness;
             float _Radius;
             float _Dropoff;
 
             fixed4 _TextureSampleAdd;
             float4 _ClipRect;
 
             v2f vert(appdata_t IN)
             {
                 v2f OUT;
                 UNITY_SETUP_INSTANCE_ID(IN);
                 UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
 
                 OUT.worldPosition = IN.vertex;
                 OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);
                 OUT.texcoord = IN.texcoord;
                 OUT.color = IN.color;
 
                 return OUT;
             }
 
             float antialias(float radius, float dist, float thick, float drop) {
                 if( dist < (radius - 0.5*thick))
                     return 1 - pow( dist - radius + 0.5*thick,2)/ pow(drop*thick, 2);
                 else if ( dist > (radius + 0.5*thick))
                     return 1 - pow( dist - radius - 0.5*thick,2)/ pow(drop*thick, 2); 
                 else
                     return 1;
             }
 
             fixed4 frag(v2f IN) : SV_Target
             {
                 half4 color;
 
                 float distance = sqrt(pow(IN.texcoord.x - 0.5, 2) + pow(IN.texcoord.y - 0.5,2));
                 float alias = antialias(_Radius, distance, _Thickness, _Dropoff);
 
                 if(alias != 1){
                     color = tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd;
                     color.a *= IN.color.a;
 
                     #ifdef UNITY_UI_ALPHACLIP
                     clip (color.a - 0.001);
                     #endif
                 }
                 else{
                     color = IN.color;
                     color.a = IN.color.a * alias;
                 }
 
                 return color;
             }
 
         ENDCG
         }
     }
 }

The result is this: http://imgur.com/zPG3pDT

The alpha applies to the sprite as well, so if you set the Image.Color to Color.clear, both the sprite and the circle will disappear.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

25 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Creating a dynamic circle outline around a circle object to indicate radius 1 Answer

Creating Perfect Circle That Can Get Narrower - 2D 0 Answers

2D Matching Game Question 1 Answer

following round transparent around player (2D) 0 Answers

User drawing game in unity (2d) 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges