Unity 圆角矩形Shader实现(支持长方形)(只写两行)
一、 效果與引言
相信很多小伙伴都會遇到做圓角矩形的需求,網(wǎng)上的shader還不明白是怎么實現(xiàn)的,甚至還有一部分是錯誤的,本文講從原理到代碼講解圓角矩形shader的實現(xiàn)
二、 原理分析
想要實現(xiàn)一個圓角矩形,常見的是抽象成一個數(shù)學模型,如下圖紫色區(qū)域,就是我們應該保留的區(qū)域,為了更準確的描述這個圖形,我們在四個角創(chuàng)建四個相等的圓形。
因為控制每個像素的顏色主要是由片元著色器負責的,所以我們也通過Fragment Shader去實現(xiàn)這個效果,可以看到在這個函數(shù)里我們只能拿到 uv和vertex,所以我們根據(jù)uv坐標判定是否在上圖的紫色區(qū)域,如果在則返回原本的顏色,如果不在返回完全透明的顏色。
(對每個像素都會執(zhí)行一次frag函數(shù)獲取真正渲染的顏色)
因為我們通過uv來判斷是否是紫色區(qū)域,所以我們需要先了解uv坐標系
首先我們要了解UV坐標系,這并不是什么高深的數(shù)學概念,而是一個簡單的道理。
首先,我們把水平方向定義為X軸,豎直方向為Y軸,把圖片左下角定義為(0,0),右上角定義為(1,1),其他的坐標以此類推
讀者可能會產(chǎn)生疑惑,為什么xy兩個軸長度不同,但是坐標卻不相同?
筆者暫時只能這樣描述:我們就如此定義一個坐標系,x軸和y軸單位長度不同
我們需要用戶去調整四個圓形的半徑 設為Radius,因為uv坐標系的xy單位長度不同,我們設Ratio = Height/Width,Ratio即為y軸單位長度與x軸單位長度之比。
float Radius 圓形半徑
float Ratio Y單位長度/X單位長度
接下來我們在圖上畫四個圓形并作輔助線
通過觀察,我們可以發(fā)現(xiàn)以下特征
1.只有在紅色區(qū)域才有可能被舍棄
2.三個圓形R2,R3,R4對應紅色區(qū)域的任意一個位置,都能在R1內找到等價位置
3. UV坐標轉正常坐標的公式為 f (x ,y)= (uv.x , uv.y * Ratio)
在UV坐標內,我們無法通過x2 + y2 來計算長度,因為uv坐標的xy單位不同,所以我們通過上述的坐標轉換公式來轉化為相同的坐標系
我們需要按以下步驟進行處理
1.將白色區(qū)域坐標在左下角找到等價uv坐標,position = abs(step(0.5,uv) - uv)
2.判斷等價uv是否在左下角可能舍棄區(qū)域,uv.x<Raduis && uv.y < Radius * Ratio
如果不在,則返回原色,如果在則進入下一步
3. 求圓心距 distance = [f(uv.x,uv.y) - f(Radius,Radius)]的長度
如果大于半徑則返回fixed(0,0,0,0),否則返回原色
三、著色器代碼
在shader內盡量不要使用if語句
以上來著自Hking_Auditore 大大的Shader入門書,通常我們用step和lerp等來代替if
step函數(shù)的邏輯可以等價為
接下來的代碼雖然看著多,實際上我們只寫了兩行
這就是這兩行
這是完整的著色器代碼
Shader "Unlit/MyShader" {Properties{_MainTex ("Texture", 2D) = "white" {}_Radius ("Radius",float) = 0_Ratio("Height/Width",float )= 1}SubShader{Tags { "RenderType"="Transparent" "Queue" = "Transparent"}LOD 100Blend SrcAlpha OneMinusSrcAlphaPass{CGPROGRAM#pragma vertex vert#pragma fragment frag// make fog work#pragma multi_compile_fog#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;};struct v2f{float2 uv : TEXCOORD0;UNITY_FOG_COORDS(1)float4 vertex : SV_POSITION;};sampler2D _MainTex;float4 _MainTex_ST;float _Radius;float _Ratio;v2f vert (appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = TRANSFORM_TEX(v.uv, _MainTex);UNITY_TRANSFER_FOG(o,o.vertex);return o;}fixed4 frag (v2f i) : SV_Target{ //坐標等價到左下角float2 p = abs(step(0.5,i.uv) - i.uv);//三個條件同時成立則乘0,否則乘1//1.在左下角 ,2.長度超過半徑fixed4 col = tex2D(_MainTex, i.uv) * (step(_Radius,p.x) ||step( _Radius ,p.y*_Ratio) || step(length(float2(p.x-_Radius,p.y*_Ratio-_Radius)),_Radius));UNITY_APPLY_FOG(i.fogCoord, col);return col;}ENDCG}} }總結
以上是生活随笔為你收集整理的Unity 圆角矩形Shader实现(支持长方形)(只写两行)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 怎样关闭tp-link无线路由器防火墙
- 下一篇: solaries使用date获取前一天日