首页
学习
活动
专区
圈层
工具
发布

第二个shader练习项目:用Shader画一个圆

一。圆的方程

首先我们都知道圆的方程,如下:

x^2 + y^2 = r^2 (其中x是x轴坐标,y是y轴坐标,r是圆的半径)。

我们将上面的公式变形一下:

x^2 + y^2 - r^2 = 0

我们可以使用函数可视化工具来展示这个方程的意义,这里我用的是GeoGebra,可以在自行在官网下载体验。如下图所示,表示一个圆心在(0,0)处,半径为2的圆,a是圆的半径,调整a的值,圆的大小也会跟着变化。

二。用Shader实现圆

接下来,我们用Shader来实现这个圆。上面的公式有另一个意思是:任意一坐标点(x,y)与圆心(0,0)的距离d,如果d = 0 表示这个点(x, y)在圆上,d < 0表示这个点(x, y)在圆内,d > 0 表示这个点(x, y)在圆外。因此依据这个我们希望在圆上的像素或者在圆内的像素用红色表示,在圆外的像素就是背景色。开始动手吧,上一篇文章我们已经展示了怎么创建unity项目,怎么创建材质(Material),怎么创建最简单的着色器(Shader),怎么将创建一个2D的Panle,怎么把材质加在Panle上,如果有不清楚,可以自行看下文章"第一个shader练习项目"。

我们继续在上一篇文章中最简单的shader代码中修改,shader代码如下:

Shader "Unlit/TestShader" { Properties { } SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } fixed4 frag (v2f i) : SV_Target { fixed4 col = fixed4(1.0,1.0,1.0,1.0); return col; } ENDCG } } }

现在我们定一个Circle函数,参数是传入的uv坐标,半径r,返回值为根据(x,y)坐标与圆心(0,0)的距离,来返回不同的颜色,在圆上或者圆内(即d<=0)的像素点为蓝色,否则为背景色-白色。

float3 Circle(float2 uv, float r) { float x = uv.x; float y = uv.y; float d = length(float2(x, y)) - r; if(d > 0) { return float3(1.0, 1.0, 1.0); } else { return float3(0.0, 0.0, 1.0); } }

接下来我们将修改片元着色器代码,调用Circle函数来生成一个圆,如下:

fixed4 frag (v2f i) : SV_Target { float3 col = Circle(i.uv, 0.2); return fixed4(col, 1.0); }

在utniy中的效果如下,发现只有一个1/4的圆。

为什么是只有1/4圆呢?是因为UV坐标系当前设置的原点(0, 0)是在左下角, 我们通过给每个uv坐标减去0.5来将圆心移动到画布中心,代码如下:

fixed4 frag (v2f i) : SV_Target { float2 uv = i.uv; uv -= float2(0.5, 0.5); float3 col = Circle(uv, 0.2); return fixed4(col, 1.0); }

修改代码之后在unity中的效果如下:

可以发现这个圆似乎不够圆,有点像椭圆了。这是因为画布的纵横比导致的,我们修改如下,通过将uv坐标的x分量乘以画布的纵横比来解决,代码如下:

fixed4 frag (v2f i) : SV_Target { float2 uv = i.uv; uv -= float2(0.5, 0.5); float aspect = _ScreenParams.x / _ScreenParams.y; uv.x *= aspect; float3 col = Circle(uv, 0.2); return fixed4(col, 1.0); }

修改之后在untiy中的效果如下:

完整的项目地址放在github上,可以自行下载(https://github.com/evazhuang/Shader.git)。

到这里,我们用Shader生成一个圆的练习就结束了,感谢观看,预告下一次将练习如何用Shader让这个圆动起来,以及让这个圆的颜色更加丰富,敬请期待!

  • 发表于:
  • 原文链接https://page.om.qq.com/page/ONRUEm6e7nY1xFrimyflimcA0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。
领券