先上个效果图

制作思路

如上图我们要渲染的就是上图带颜色的部分

步骤:

先获取黄色和蓝绿部分

例如以下图

算法

|U|<(0.5-r)或|V|<(0.5-r)

注意的是模型贴图最大值是1.

然后获取红色的四份之中的一个圆部分

实现过程

首先在unity里创建一个shader。

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

创建完毕后

然后双击newshader(名字是能够随便起)

将里面的内容所有删掉

代码例如以下:

Shader "Custom/NewShader" {

    Properties {

        _MainTex ("Base (RGB)", 2D) = "white" {}

    }

    SubShader

    {

        pass

        {

        

        CGPROGRAM

        #pragma vertex vert

        #pragma fragment frag

        #include "unitycg.cginc"

        sampler2D _MainTex;

        struct v2f

        {

        float4 pos : SV_POSITION ;

        float2 ModeUV: TEXCOORD0;

        };

        v2f vert(appdata_base v)

        {

        v2f o;

        o.pos=mul(UNITY_MATRIX_MVP,v.vertex);  //将模型顶点坐标转换到视图坐标矩阵中

        o.ModeUV=v.texcoord;   //获取模型的UV坐标

        return o;

        }

        fixed4 frag(v2f i):COLOR

        {

        fixed4 col;

        

        col=tex2D(_MainTex,i.ModeUV);      //依据模型UV坐标获取贴图相相应的颜色

        

        return col;        

        }

        ENDCG

        

        }

    }

}

上述主要代码以凝视。

如今实现了一个简单的顶点像素shader。

然后建一个material材质球。将你写的shader拖到material上面去,然后给material赋值一张图片。

然后创建一个3D的Plane物体,将material拖到物体上面去。

效果例如以下图:

好了如今我们来切圆角矩形。

要说明的是我们为了计算方便坐标系原点在uv的中心,可是unity模型的uv的原点在左下角例如以下图,切vu取值范围(0,1)。就是说贴图的像素坐标也是(0,1)表示全部的像素坐标点

unity的uv坐标系

所以为了统一,我们将unity的uv坐标系处理成中心坐标系,用一个变量存储处理后的坐标系

方法是

unity的uv-float(0.5,0.5)

首先我们实现下图区域的显示

改动上面的代码,我们须要加入一个圆角半径的属性。然后我们要获取上面所说的黄色和蓝绿色部分,加入代码以下红色字体。

代码改动后例如以下:

Shader "Custom/NewShader" {

Properties {

_MainTex ("Base (RGB)", 2D) = "white" {}

_RADIUSBUCE("_RADIUSBUCE",Range(0,0.5))=0.2

}

SubShader

{

pass

{



CGPROGRAM



#pragma exclude_renderers gles

#pragma vertex vert

#pragma fragment frag

#include "unitycg.cginc"

float _RADIUSBUCE;

sampler2D _MainTex;





struct v2f

{

float4 pos : SV_POSITION ;

float2 ModeUV: TEXCOORD0;

float2 RadiusBuceVU : TEXCOORD1;

};

v2f vert(appdata_base v)

{

v2f o;

o.pos=mul(UNITY_MATRIX_MVP,v.vertex); //v.vertex;

o.ModeUV=v.texcoord;

o.RadiusBuceVU=v.texcoord-float2(0.5,0.5);       //将模型UV坐标原点置为中心原点,为了方便计算





return o;

}









fixed4 frag(v2f i):COLOR

{

fixed4 col;

col=(0,1,1,0);





if(abs(i.RadiusBuceVU.x)<0.5-_RADIUSBUCE||abs(i.RadiusBuceVU.y)<0.5-_RADIUSBUCE)    //即上面说的|x|<(0.5-r)或|y|<(0.5-r)

{



col=tex2D(_MainTex,i.ModeUV);





}



return col;


}

ENDCG



}

}

}

效果例如以下图:

好了如今我们開始获取红色四份之中的一个圆区域

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

继续改动代码(蓝色字体)

Shader "Custom/NewShader" {

Properties {

_MainTex ("Base (RGB)", 2D) = "white" {}

_RADIUSBUCE("_RADIUSBUCE",Range(0,0.5))=0.2

}

SubShader

{

pass

{



CGPROGRAM



#pragma exclude_renderers gles

#pragma vertex vert

#pragma fragment frag

#include "unitycg.cginc"

float _RADIUSBUCE;

sampler2D _MainTex;





struct v2f

{

float4 pos : SV_POSITION ;

float2 ModeUV: TEXCOORD0;

float2 RadiusBuceVU : TEXCOORD1;

};

v2f vert(appdata_base v)

{

v2f o;

o.pos=mul(UNITY_MATRIX_MVP,v.vertex); //v.vertex;

o.ModeUV=v.texcoord;

o.RadiusBuceVU=v.texcoord-float2(0.5,0.5);       //将模型UV坐标原点置为中心原点,为了方便计算





return o;

}









fixed4 frag(v2f i):COLOR

{

fixed4 col;

col=(0,1,1,0);





if(abs(i.RadiusBuceVU.x)<0.5-_RADIUSBUCE||abs(i.RadiusBuceVU.y)<0.5-_RADIUSBUCE)    //即上面说的|x|<(0.5-r)或|y|<(0.5-r)

{



col=tex2D(_MainTex,i.ModeUV);





}

else

{

if(length( abs( i.RadiusBuceVU)-float2(0.5-_RADIUSBUCE,0.5-_RADIUSBUCE)) <_RADIUSBUCE)

{

col=tex2D(_MainTex,i.ModeUV);



}

else

{

discard;

}

}

return col;


}

ENDCG



}

}

}

这是在曾经的代码的基础上加入了else分支推断。

逻辑顺序是这种 if推断的是下图区域的,else就是非下图区域的其它区域

if推断的区域

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

else区域(蓝色框的区域)

然后我们在else下再推断像素点是否在四份之中的一个圆呢即可了

if(length( abs( i.RadiusBuceVU)-float2(0.5-_RADIUSBUCE,0.5-_RADIUSBUCE)) <_RADIUSBUCE)

上面这句推断有点乱

首先我们先获取UV坐标u和v都是正半轴的四份之中的一个圆:以下蓝色框区域。

首先我们获取下图p点坐标

即:p=float2(0.5-_RADIUSBUCE,0.5-_RADIUSBUCE) //_RADIUSBUCE是上图的r

然后将每次获取的模型uv坐标减去p坐标,相当于将坐标系平移p后获取的新的uv坐标。如上图绿色坐标系。

例如以下代码

i.RadiusBuceVU-float2(0.5-_RADIUSBUCE,0.5-_RADIUSBUCE)

然后我们就能够通过绿色坐标系进行计算是否在圆内了。

仅仅要在新的坐标系中vu到原点的长度小于半径r就能够渲染颜色,否则就不渲染(cg函数为:discard--------跳出渲染管线不渲染)

if(length(i.RadiusBuceVU-float2(0.5-_RADIUSBUCE,0.5-_RADIUSBUCE))<_RADIUSBUCE)

{

col=tex2D(_MainTex,i.ModeUV);



}

else

{

discard;

}

能够将上面的代码替换(绿色字体)測试一下

Shader "Custom/NewShader" {

Properties {

_MainTex ("Base (RGB)", 2D) = "white" {}

_RADIUSBUCE("_RADIUSBUCE",Range(0,0.5))=0.2

}

SubShader

{

pass

{



CGPROGRAM



#pragma exclude_renderers gles

#pragma vertex vert

#pragma fragment frag

#include "unitycg.cginc"

float _RADIUSBUCE;

sampler2D _MainTex;





struct v2f

{

float4 pos : SV_POSITION ;

float2 ModeUV: TEXCOORD0;

float2 RadiusBuceVU : TEXCOORD1;

};

v2f vert(appdata_base v)

{

v2f o;

o.pos=mul(UNITY_MATRIX_MVP,v.vertex); //v.vertex;

o.ModeUV=v.texcoord;

o.RadiusBuceVU=v.texcoord-float2(0.5,0.5);       //将模型UV坐标原点置为中心原点,为了方便计算





return o;

}









fixed4 frag(v2f i):COLOR

{

fixed4 col;

col=(0,1,1,0);





if(abs(i.RadiusBuceVU.x)<0.5-_RADIUSBUCE||abs(i.RadiusBuceVU.y)<0.5-_RADIUSBUCE)    //即上面说的|x|<(0.5-r)或|y|<(0.5-r)

{



col=tex2D(_MainTex,i.ModeUV);





}

else

{

if(length( i.RadiusBuceVU-float2(0.5-_RADIUSBUCE,0.5-_RADIUSBUCE)) <_RADIUSBUCE)

{

col=tex2D(_MainTex,i.ModeUV);



}

else

{

discard;

}

}

return col;


}

ENDCG



}

}

}

效果例如以下图

发现如今已经完毕了一个角的计算。其它角仅仅要在获得的新uv坐标加个绝对值。将全部坐标转换到正坐标系下就能够了

终于代码例如以下

Shader "Custom/NewShader" {

Properties {

_MainTex ("Base (RGB)", 2D) = "white" {}

_RADIUSBUCE("_RADIUSBUCE",Range(0,0.5))=0.2

}

SubShader

{

pass

{



CGPROGRAM



#pragma exclude_renderers gles

#pragma vertex vert

#pragma fragment frag

#include "unitycg.cginc"

float _RADIUSBUCE;

sampler2D _MainTex;





struct v2f

{

float4 pos : SV_POSITION ;

float2 ModeUV: TEXCOORD0;

float2 RadiusBuceVU : TEXCOORD1;

};

v2f vert(appdata_base v)

{

v2f o;

o.pos=mul(UNITY_MATRIX_MVP,v.vertex); //v.vertex;

o.ModeUV=v.texcoord;

o.RadiusBuceVU=v.texcoord-float2(0.5,0.5);       //将模型UV坐标原点置为中心原点,为了方便计算





return o;

}









fixed4 frag(v2f i):COLOR

{

fixed4 col;

col=(0,1,1,0);





if(abs(i.RadiusBuceVU.x)<0.5-_RADIUSBUCE||abs(i.RadiusBuceVU.y)<0.5-_RADIUSBUCE)    //即上面说的|x|<(0.5-r)或|y|<(0.5-r)

{



col=tex2D(_MainTex,i.ModeUV);





}

else

{

if(length( abs( i.RadiusBuceVU)-float2(0.5-_RADIUSBUCE,0.5-_RADIUSBUCE)) <_RADIUSBUCE)

{

col=tex2D(_MainTex,i.ModeUV);



}

else

{

discard;

}

}

return col;


}

ENDCG



}

}

}

终于效果

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

项目下载链接

http://download.csdn.net/detail/fengya1/9449577

unity 切圆角矩形 --shader编程的更多相关文章

  1. 解读Unity中的CG编写Shader系列四(unity中的圆角矩形shader)

    转自 http://www.itnose.net/detail/6097625.html 上篇文章中我们掌握了表面剔除和剪裁模式 这篇文章将利用这些知识实现一个简单的,但是又很常用的例子:把一张图片做 ...

  2. 解读Unity中的CG编写Shader系列4——unity中的圆角矩形shader

    上篇文章中我们掌握了表面剔除和剪裁模式 这篇文章将利用这些知识实现一个简单的,可是又非经常常使用的样例:把一张图片做成圆角矩形 例3:圆角矩形Shader 好吧我承认在做这个样例的时候走了不少弯路,因 ...

  3. [转]解读Unity中的CG编写Shader系列4——unity中的圆角矩形shader

    上篇文章中我们掌握了表面剔除和剪裁模式这篇文章将利用这些知识实现一个简单的,但是又很常用的例子:把一张图片做成圆角矩形 例3:圆角矩形Shader好吧我承认在做这个例子的时候走了不少弯路,由于本人对矩 ...

  4. 圆角矩形shader

    在游戏中,有时需要对一张矩形图片进行切割,绘制成圆角矩形. circelrect.vert attribute vec4 a_position; attribute vec4 a_normal; at ...

  5. 【浅墨Unity3D Shader编程】之二 雪山飞狐篇:Unity的基本Shader框架写法&amp;颜色、光照与材质

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/40955607 作者:毛星云(浅墨)  ...

  6. 【Unity】用Shader编程实现3D红心

    有些形状,即使没有3D美术设计师提供模型,也能够用代码生成. 对于想保持原创性不想借用他人模型的独立开发人员来说,这无非是一个非常重要的途径. 今天献给大家的是用Shader编程实现的一颗红心,寄托下 ...

  7. 小强学渲染之Unity Shader编程HelloWorld

    第一个简单的顶点vert/片元frag着色器   1)打开Unity 5.6编辑器,新建一个场景后ctrl+s保存命名为Scene_5.默认创建的场景是包含了一摄像机,一平行光,且场景背景是一天空盒而 ...

  8. SimpleRoundedImage-不使用mask实现圆角矩形图片

    1.一张图片是如何显示在屏幕上的 一张图片渲染到unity界面中的大致流程. 2.我们要做什么 我们要做的就是在CPU中将图片的矩形顶点数据修改成圆角矩形的顶点信息,之后Unity会将修改后的顶点数据 ...

  9. [BOT] 一种android中实现“圆角矩形”的方法

    内容简介 文章介绍ImageView(方法也可以应用到其它View)圆角矩形(包括圆形)的一种实现方式,四个角可以分别指定为圆角.思路是利用"Xfermode + Path"来进行 ...

随机推荐

  1. [CQOI2014][bzoj3504] 危桥 [最大流]

    题面 传送门 思路 这道题中惟一的特别之处,就在于"危桥"这一个只能走两次的东西 我的第一想法是做一个dp,但是这道题只需要能不能走,也没有必要 网络流?貌似是个很好的选择 我们把 ...

  2. input上传多张图片

    input的file上传多张图片的时候,用ajaxupload这个插件的时候,每次执行完,需要重新生成元素再绑定事件

  3. [Linux]方便openmp等程序的类似编译

    因为总是打参数例如-fopenmp或者-lGL等等有些麻烦,所以特地写一个可以使用的bash文件用来执行简单的操作 首先在.profile中添加 if [ -d "$HOME/bin&quo ...

  4. Java EE 学习(6):IDEA + maven + spring 搭建 web(2)- 配置 Spring

    参考:https://my.oschina.net/gaussik/blog/513353 注:此文承接上一文:Java EE 学习(5):IDEA + maven + spring 搭建 web(1 ...

  5. 品酒大会(uoj 131)

    一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品酒家”和“首席猎手”两个奖项,吸引了众多品酒师参加. 在大会的晚餐上,调酒师 Rainbow 调制了 ...

  6. 一张图让你学会Python【转】

    转自:http://blog.csdn.net/qq_30845505/article/details/51588423 有编程基础的人一看就可以了解 Python 的用法了.真正的 30 分钟上手. ...

  7. (5)php数组

    定义数组 $arr=array('篮球','自行车','海贼王'); 打印指定数组 echo $arr[0]; 打印全部数组 print_r($arr); 改变数组的值 $arr[0]='足球'; 赋 ...

  8. HDU 1223 还是畅通过程【最小生成树模板】

    还是畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  9. springboot 2.0.8 跳转jsp页面

    springboot项目创建教程 https://blog.csdn.net/q18771811872/article/details/88126835 springboot 2.0跳转 html教程 ...

  10. c# datetime是一年中的第几周

    public static int WeekOfYear(DateTime dt, CultureInfo ci) { return ci.Calendar.GetWeekOfYear(dt, ci. ...