【UnityShader】图片圆角

2024-04-22 01:28
文章标签 图片 圆角 unityshader

本文主要是介绍【UnityShader】图片圆角,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.需求

        我们在开发的时候,有时候一些按钮或者菜单栏的边角是直角的需要改成圆角,但是让美术重新绘制耽误时间不说也确实没必要,这个时候我们不妨使用一个简单的shader去解决这个问题,下面我们就讲讲这个shader要如何实现。

需求1:可以将图片四角任意一角从直角变为圆角,可控制圆角大小

需求2:在需求一的基础上可以选择是否给图片加上边框,颜色可变

附加小需求:可更改图片透明度

2.实现

2.1. 准备

        在实现之前,除此了解shader的同学可以去了解一下unity内置的一些shader变量和函数,熟悉了这些变量和函数的含义,对我们实现一个shader有很大的帮助。

【UnityShader预备知识】内置变量和函数

2.1.1.Tags

我们先了解一些需要使用的Tags:

 Tags{"Queue" = "Transparent""IgnoreProjector" = "True""RenderType" = "Transparent""PreviewType" = "Plane""CanUseSpriteAtlas" = "True"}

这些是Unity Shader标签,用于指定渲染顺序、忽略投影、渲染类型以及预览方式。其中,“Transparent”表示该Shader将被渲染在所有不透明物体之后,因此适合用作UI元素或半透明物体的材质。如果你想让这个Shader按照标准的渲染顺序进行渲染,可以去掉“Transparent”标签并将“Queue”改为“Geometry”。

另外,“CanUseSpriteAtlas”允许该Shader使用精灵图集,这对于使用多个精灵制作复杂的图形很有用。如果你想让Shader支持精灵图集,请确保你的项目中已经启用了相应的功能。

2.1.2.Stencil

接下来我们再看一下模板缓冲区Stencil Buffer如何设置:

Stencil{Ref[_Stencil]Comp[_StencilComp]Pass[_StencilOp]ReadMask[_StencilReadMask]WriteMask[_StencilWriteMask]}
  • Stencil Buffer(模板缓冲区)是一个与颜色缓冲区和深度缓冲区类似的额外缓冲区,可用于记录每个像素是否被绘制过。当启用模板测试时,只有满足特定条件的像素才会被绘制。
  • Ref[_Stencil]指定了模板缓冲区的参考值,即只有当模板值等于该值时才绘制。
  • Comp[_StencilComp]指定了模板比较函数,例如等于、不等于、小于等等。
  • Pass[_StencilOp]指定了当模板测试失败时的操作,例如替换为Ref[_Stencil]或其他值。
  • ReadMask[_StencilReadMask]和WriteMask[_StencilWriteMask]分别指定了读取和写入模板缓冲区的掩码。

2.1.3.基础设置

shader中需要对光照、深度等进行一些设置,比如:

        Cull Off  //关闭了背面剔除,使得物体的正面和背面都可以被渲染。Lighting Off  //关闭了光照计算,这意味着不会对物体表面产生光照影响。ZWrite Off  //关闭了深度写入,使得物体不会影响场景的深度信息。ZTest[unity_GUIZTestMode]  //指定了深度测试模式,对于GUI元素通常使用Less或Greater模式。Blend SrcAlpha OneMinusSrcAlpha  //启用了混合模式,用于控制透明度。ColorMask[_ColorMask]  //控制哪些颜色通道会被写入,通常用于控制透明度。

这些设置关闭了背面剔除、光照计算、深度写入,并开启了混合模式,同时还设置了颜色掩码。这通常是用于渲染UI元素的标准设置。其中,Cull Off表示不剔除任何面,Lighting Off表示不进行光照计算,ZWrite Off表示不写入深度缓冲区,ZTest[unity_GUIZTestMode]表示使用Unity GUI的特殊深度测试模式,Blend SrcAlpha OneMinusSrcAlpha表示开启混合模式,使得透明度能够正确显示,ColorMask[_ColorMask]则控制哪些颜色通道会被写入。如果你希望对这些设置进行自定义,可以在Shader中添加相应的标签。

2.2.功能实现思路

2.2.1.直角变圆角

如果要将一个直角变成圆角,那么首先我们得要确定这个圆角的中心点O和半径r,然后将图片超出半径范围的像素进行剔除舍弃即使其alpha=0。以左下角为例:

//左下角
if (x < r && y < r)//x和y分别是当前像素的UV坐标{anc_size = (x - r) * (x - r) + (y - r) * (y - r);if (anc_size > r * r){color.a = 0;}}

首先,我们检查当前像素是否在圆角范围内,如果是,则计算其离中心点的距离(anc_size)。

如果anc_size大于半径的平方(r*r),则说明该像素超出了圆角范围,应被舍弃。其他几个角依次类推,大家可以自己手动画一张图这样更明了一些。需要注意的是UV坐标系,左下角为(0,0),右上角为(1,1)。相信图应该都能画出来,这边我也会在下面贴出来草图以供参考。

其他三角:

//左上角if (x < r && y > (height - r)){anc_size = (x - r) * (x - r) + (y - (height - r)) * (y - (height - r));if (anc_size > r * r){color.a = 0;}else if (edge_width > 0 && anc_size > (r - edge_width) * (r - edge_width)){color = edge_color;}}r = _EdgeCore.z;//右下角if (x > (width - r) && y < r){anc_size = (x - (width - r)) * (x - (width - r)) + (y - r) * (y - r);if (anc_size > r * r){color.a = 0;}else if (edge_width > 0 && anc_size > (r - edge_width) * (r - edge_width)){color = edge_color;}}r = _EdgeCore.y;//右上角if (x > (width - r) && y > (height - r)){anc_size = (x - (width - r)) * (x - (width - r)) + (y - (height - r)) * (y - (height - r));if (anc_size > r * r){color.a = 0;}else if (edge_width > 0 && anc_size > (r - edge_width) * (r - edge_width)){color = edge_color;}}

2.2.2.添加边框

添加边框是什么意思,简单点说就是把图片边上一部分的颜色进行转换,有了上面进行圆角的转换,我们只要根据边框的宽度算出对应的区域范围,将此区域范围内的颜色进行更改即可,依旧以左下角为例:

 if (x < r && y < r)
{arc_size = (x - r) * (x - r) + (y - r) * (y - r);if (arc_size > r * r){color.a = 0;}else if (b_width > 0 && arc_size > (r - b_width) * (r - b_width)){color = b_color;}
}

在上面我们已经计算出了arc_size,如果它介于半径和半径减去边框宽度之间(即边框区域),则应用边框颜色。这里的r代表圆角半径,x和y分别是当前像素的UV坐标。你可以根据需要修改r和b_width这两个变量来改变圆角大小和边框宽度。同时,你也需要在Shader的Properties块中声明对应的属性。

做到这里,你可能会发现你的效果是这样的:

哎,没错,这个效果说不定也有人有需要也是一个有意思的形状,当然,这还不是完整的边框,刚刚我们只考虑了边角,没有考虑其他地方,所以我们还要对其他地方的边框进行处理:

if (b_width > 0)
{//下边
if (x > _RCorner.w && x < (width - _RCorner.z) && y < b_width){color = border_color;}//上边
if (x > _RCorner.x && x < (width - _RCorner.y) && (height - y) < b_width){color = border_color;}
//左边
if (y > _RCorner.w && y < (height - _RCorner.x) && x < b_width){color = border_color;}
//右边if (y > _RCorner.z && y < (height - _RCorner.y) && x > (width - b_width)){color = border_color;}}

2.2.3.修改图片透明度

修改透明度的方式很简单,就是对颜色的alpha进行修改:

if (_MainTex_TexelSize.z > 0){color = (tex2D(_MainTex, IN.texcoord)) * IN.color;}
color.a= _Alpha;

需要注意的是alpha通道要在最后进行设置,以免后面再对颜色进行修改影响其值。

比如你只想改改边框的透明度,你就可以把这段修改放在修改边框那边。

2.3.最终效果

3.下载链接

https://download.csdn.net/download/qq_35064654/89194087

这篇关于【UnityShader】图片圆角的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/924511

相关文章

Java如何根据文件名前缀自动分组图片文件

《Java如何根据文件名前缀自动分组图片文件》一大堆文件(比如图片)堆在一个目录下,它们的命名规则遵循一定的格式,混在一起很难管理,所以本文小编就和大家介绍一下如何使用Java根据文件名前缀自动分组图... 目录需求背景分析思路实现代码输出结果知识扩展需求一大堆文件(比如图片)堆在一个目录下,它们的命名规

将图片导入Python的turtle库的详细过程

《将图片导入Python的turtle库的详细过程》在Python编程的世界里,turtle库以其简单易用、图形化交互的特点,深受初学者喜爱,随着项目的复杂度增加,仅仅依靠线条和颜色来绘制图形可能已经... 目录开篇引言正文剖析1. 理解基础:Turtle库的工作原理2. 图片格式与支持3. 实现步骤详解第

在React聊天应用中实现图片上传功能

《在React聊天应用中实现图片上传功能》在现代聊天应用中,除了文字和表情,图片分享也是一个重要的功能,本文将详细介绍如何在基于React的聊天应用中实现图片上传和预览功能,感兴趣的小伙伴跟着小编一起... 目录技术栈实现步骤1. 消息组件改造2. 图片预览组件3. 聊天输入组件改造功能特点使用说明注意事项

Android使用ImageView.ScaleType实现图片的缩放与裁剪功能

《Android使用ImageView.ScaleType实现图片的缩放与裁剪功能》ImageView是最常用的控件之一,它用于展示各种类型的图片,为了能够根据需求调整图片的显示效果,Android提... 目录什么是 ImageView.ScaleType?FIT_XYFIT_STARTFIT_CENTE

关于MongoDB图片URL存储异常问题以及解决

《关于MongoDB图片URL存储异常问题以及解决》:本文主要介绍关于MongoDB图片URL存储异常问题以及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录MongoDB图片URL存储异常问题项目场景问题描述原因分析解决方案预防措施js总结MongoDB图

python实现svg图片转换为png和gif

《python实现svg图片转换为png和gif》这篇文章主要为大家详细介绍了python如何实现将svg图片格式转换为png和gif,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录python实现svg图片转换为png和gifpython实现图片格式之间的相互转换延展:基于Py

使用Python从PPT文档中提取图片和图片信息(如坐标、宽度和高度等)

《使用Python从PPT文档中提取图片和图片信息(如坐标、宽度和高度等)》PPT是一种高效的信息展示工具,广泛应用于教育、商务和设计等多个领域,PPT文档中常常包含丰富的图片内容,这些图片不仅提升了... 目录一、引言二、环境与工具三、python 提取PPT背景图片3.1 提取幻灯片背景图片3.2 提取

Python实现图片分割的多种方法总结

《Python实现图片分割的多种方法总结》图片分割是图像处理中的一个重要任务,它的目标是将图像划分为多个区域或者对象,本文为大家整理了一些常用的分割方法,大家可以根据需求自行选择... 目录1. 基于传统图像处理的分割方法(1) 使用固定阈值分割图片(2) 自适应阈值分割(3) 使用图像边缘检测分割(4)

C#实现将Excel表格转换为图片(JPG/ PNG)

《C#实现将Excel表格转换为图片(JPG/PNG)》Excel表格可能会因为不同设备或字体缺失等问题,导致格式错乱或数据显示异常,转换为图片后,能确保数据的排版等保持一致,下面我们看看如何使用C... 目录通过C# 转换Excel工作表到图片通过C# 转换指定单元格区域到图片知识扩展C# 将 Excel

JS+HTML实现在线图片水印添加工具

《JS+HTML实现在线图片水印添加工具》在社交媒体和内容创作日益频繁的今天,如何保护原创内容、展示品牌身份成了一个不得不面对的问题,本文将实现一个完全基于HTML+CSS构建的现代化图片水印在线工具... 目录概述功能亮点使用方法技术解析延伸思考运行效果项目源码下载总结概述在社交媒体和内容创作日益频繁的