unity 切圆角矩形 --shader编程
先上个效果图
制作思路
如上图我们要渲染的就是上图带颜色的部分
步骤:
先获取黄色和蓝绿部分
例如以下图
算法
|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="">
项目下载链接
unity 切圆角矩形 --shader编程的更多相关文章
- 解读Unity中的CG编写Shader系列四(unity中的圆角矩形shader)
转自 http://www.itnose.net/detail/6097625.html 上篇文章中我们掌握了表面剔除和剪裁模式 这篇文章将利用这些知识实现一个简单的,但是又很常用的例子:把一张图片做 ...
- 解读Unity中的CG编写Shader系列4——unity中的圆角矩形shader
上篇文章中我们掌握了表面剔除和剪裁模式 这篇文章将利用这些知识实现一个简单的,可是又非经常常使用的样例:把一张图片做成圆角矩形 例3:圆角矩形Shader 好吧我承认在做这个样例的时候走了不少弯路,因 ...
- [转]解读Unity中的CG编写Shader系列4——unity中的圆角矩形shader
上篇文章中我们掌握了表面剔除和剪裁模式这篇文章将利用这些知识实现一个简单的,但是又很常用的例子:把一张图片做成圆角矩形 例3:圆角矩形Shader好吧我承认在做这个例子的时候走了不少弯路,由于本人对矩 ...
- 圆角矩形shader
在游戏中,有时需要对一张矩形图片进行切割,绘制成圆角矩形. circelrect.vert attribute vec4 a_position; attribute vec4 a_normal; at ...
- 【浅墨Unity3D Shader编程】之二 雪山飞狐篇:Unity的基本Shader框架写法&颜色、光照与材质
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/40955607 作者:毛星云(浅墨) ...
- 【Unity】用Shader编程实现3D红心
有些形状,即使没有3D美术设计师提供模型,也能够用代码生成. 对于想保持原创性不想借用他人模型的独立开发人员来说,这无非是一个非常重要的途径. 今天献给大家的是用Shader编程实现的一颗红心,寄托下 ...
- 小强学渲染之Unity Shader编程HelloWorld
第一个简单的顶点vert/片元frag着色器 1)打开Unity 5.6编辑器,新建一个场景后ctrl+s保存命名为Scene_5.默认创建的场景是包含了一摄像机,一平行光,且场景背景是一天空盒而 ...
- SimpleRoundedImage-不使用mask实现圆角矩形图片
1.一张图片是如何显示在屏幕上的 一张图片渲染到unity界面中的大致流程. 2.我们要做什么 我们要做的就是在CPU中将图片的矩形顶点数据修改成圆角矩形的顶点信息,之后Unity会将修改后的顶点数据 ...
- [BOT] 一种android中实现“圆角矩形”的方法
内容简介 文章介绍ImageView(方法也可以应用到其它View)圆角矩形(包括圆形)的一种实现方式,四个角可以分别指定为圆角.思路是利用"Xfermode + Path"来进行 ...
随机推荐
- 用jquery实现平滑的页面滚动效果
通过几句jquery代码实现页面平滑滚动到某一锚点的效果.实现代码来源于https://css-tricks.com/snippets/jquery/smooth-scrolling 实现的jquer ...
- [国家集训队][bzoj2038] 小Z的袜子 [莫队]
题面: 传送门 思路: 又是一道标准的莫队处理题目,但是这道题需要一点小改动:求个数变成了求概率 我们思考:每次某种颜色从i个增加到i+1个,符合要求的情况多了多少? 原来的总情况数是i*(i-1)/ ...
- [SDOI2009][bzoj1878] HH的项链 [莫队模板题]
题面: 传送门 思路: 就是一道莫队的模板题目...... 开一个1000000的数组记录每个数出现的次数,然后每次从1到0或者从0到1更新答案 莫队讲解看这里:莫队 Code: #include&l ...
- BZOJ5306 [HAOI2018]染色 【组合数 + 容斥 + NTT】
题目 为了报答小 C 的苹果, 小 G 打算送给热爱美术的小 C 一块画布, 这块画布可 以抽象为一个长度为 \(N\) 的序列, 每个位置都可以被染成 \(M\) 种颜色中的某一种. 然而小 C 只 ...
- THUWC 2018(游记)
这次是在雅礼洋湖中学举行的,一所2017年才创办的学校,新的学校, 貌似有些危险,积雪过多屋顶上的冰块砸下来,很容易砸到人, 听说最近就有一个人被砸死了. Day1 昨天睡的比较迟,12点吧,今天早上 ...
- windows系统部署springboot项目及绑定域名
http://note.youdao.com/noteshare?id=c3ccea255affd2c5d79231d67fa29103&sub=187AEEEA5CF34531A2C2315 ...
- Python 安装MySQLdb模块遇到报错及解决方案:_mysql.c(42) : fatal error C1083: Cannot open include file: 'config-win.h': No such file or directory
一.问题 系统:win7 64位 在下载MySQL-python-1.2.5.zip,使用python setup.py install 安装时,出现以下报错: _mysql.c(42) : fata ...
- vue 中父子组件传值:props和$emit
更新----------- 1 父组件向子组件传值:通过props数组: 在vue-cli Login.vue父组件中有AcceptAndRefuse.vue子组件,首先import进子组件hello ...
- 解决当打开Unity时 提示项目已经打开,而自己之前并没有打开过(可能之前异常关闭)的问题
当打开Unity时 提示项目已经打开,而自己之前并没有打开过(可能之前异常关闭) 发生这种情况时 打开项目目录中的 Temp文件夹,可以找到 一个 UnityLockfile 文件 将这个文件删除就可 ...
- cocoaPod的Podfile文件的创建和内容格式
Podfile创建: 1.终端中,cd到项目总目录(cd +路径名) cd/........./......../...../项目名 2.终端中继续建立Podfile(配置文件) touch Podf ...