Unity 圆角矩形Shader实现(支持长方形)(只写两行)

这篇具有很好参考价值的文章主要介绍了Unity 圆角矩形Shader实现(支持长方形)(只写两行)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、 效果与引言

Unity 圆角矩形Shader实现(支持长方形)(只写两行)
相信很多小伙伴都会遇到做圆角矩形的需求,网上的shader还不明白是怎么实现的,甚至还有一部分是错误的,本文讲从原理到代码讲解圆角矩形shader的实现

二、 原理分析

想要实现一个圆角矩形,常见的是抽象成一个数学模型,如下图紫色区域,就是我们应该保留的区域,为了更准确的描述这个图形,我们在四个角创建四个相等的圆形。
Unity 圆角矩形Shader实现(支持长方形)(只写两行)
因为控制每个像素的颜色主要是由片元着色器负责的,所以我们也通过Fragment Shader去实现这个效果,可以看到在这个函数里我们只能拿到 uv和vertex,所以我们根据uv坐标判定是否在上图的紫色区域,如果在则返回原本的颜色,如果不在返回完全透明的颜色。
(对每个像素都会执行一次frag函数获取真正渲染的颜色)

struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };
            
 fixed4 frag (v2f i) : SV_Target
 {
 	//....省略
 }

因为我们通过uv来判断是否是紫色区域,所以我们需要先了解uv坐标系
首先我们要了解UV坐标系,这并不是什么高深的数学概念,而是一个简单的道理。
首先,我们把水平方向定义为X轴,竖直方向为Y轴把图片左下角定义为(0,0),右上角定义为(1,1),其他的坐标以此类推

Unity 圆角矩形Shader实现(支持长方形)(只写两行)

读者可能会产生疑惑,为什么xy两个轴长度不同,但是坐标却不相同?
笔者暂时只能这样描述:我们就如此定义一个坐标系,x轴和y轴单位长度不同

我们需要用户去调整四个圆形的半径 设为Radius,因为uv坐标系的xy单位长度不同,我们设Ratio = Height/Width,Ratio即为y轴单位长度与x轴单位长度之比。

float Radius 圆形半径
float Ratio Y单位长度/X单位长度

接下来我们在图上画四个圆形并作辅助线

Unity 圆角矩形Shader实现(支持长方形)(只写两行)
通过观察,我们可以发现以下特征

1.只有在红色区域才有可能被舍弃
2.三个圆形R2,R3,R4对应红色区域的任意一个位置,都能在R1内找到等价位置
3. UV坐标转正常坐标的公式为 f (x ,y)= (uv.x , uv.y * Ratio)

在UV坐标内,我们无法通过x2 + y2 来计算长度,因为uv坐标的xy单位不同,所以我们通过上述的坐标转换公式来转化为相同的坐标系

我们需要按以下步骤进行处理

1.将白色区域坐标在左下角找到等价uv坐标,position = abs(step(0.5,uv) - uv)
Unity 圆角矩形Shader实现(支持长方形)(只写两行)
2.判断等价uv是否在左下角可能舍弃区域,uv.x<Raduis && uv.y < Radius * Ratio
如果不在,则返回原色,如果在则进入下一步

Unity 圆角矩形Shader实现(支持长方形)(只写两行)
3. 求圆心距 distance = [f(uv.x,uv.y) - f(Radius,Radius)]的长度
如果大于半径则返回fixed(0,0,0,0),否则返回原色

Unity 圆角矩形Shader实现(支持长方形)(只写两行)

三、着色器代码

在shader内尽量不要使用if语句
Unity 圆角矩形Shader实现(支持长方形)(只写两行)
以上来着自Hking_Auditore 大大的Shader入门书,通常我们用step和lerp等来代替if
step函数的逻辑可以等价为

step (a, x)
{
  if (a>x)  return 0;
  else return 1;
}

接下来的代码虽然看着多,实际上我们只写了两行
这就是这两行

 float2 p = abs(step(0.5,i.uv) - i.uv);
 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));

这是完整的着色器代码文章来源地址https://www.toymoban.com/news/detail-441621.html

Shader "Unlit/MyShader"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Radius ("Radius",float) = 0
        _Ratio("Height/Width",float )= 1
    }
    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue" = "Transparent"}
        LOD 100
        Blend SrcAlpha OneMinusSrcAlpha
        Pass
        {
            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实现(支持长方形)(只写两行)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【前端知识】Three 学习日志(十)—— 常见几何体(长方体、球体、圆柱、矩形平面、圆形平面)

    Three 学习日志(十)—— 常见几何体(长方体、球体、圆柱、矩形平面、圆形平面) 一、构建常用几何体 二、 遍历加入场景中 三、效果展示 四、完整代码

    2024年02月07日
    浏览(38)
  • NSBezierPath绘制圆角矩形的圆角不够圆滑?

    在Macos应用开发过程中,使用OC语言编码,效果是:圆角的线宽 比 边框的 大或者浓。 经过大量查询,发现:如果圆角矩形宽高和View的宽高一样大,就导致圆角矩形的边框线有一半在View外面而被裁剪。 调整后的代码如下: 参考链接: https://outofmemory.cn/web/1018338.html     htt

    2024年02月10日
    浏览(35)
  • css不规则圆角矩形

    这个收集的css 效果是真的多 https://github.com/chokcoco/iCSS强烈推荐

    2024年02月20日
    浏览(41)
  • android:绘制圆角矩形,椭圆形

    一、前言:在我们工作中会有绘制不同圆角的按钮图形,具体该怎么做之前也只是了解个大概,今天看了一节课,听完老师讲的我自己又写了一遍,记录一下。 二、代码展示: 首先先创建一个DrawableShapeActivity 相对应的xml 以及两个形状xml:shape_oval_rose.xml shape_ract_gold.xml

    2024年02月06日
    浏览(42)
  • Qt QWidget 抗锯齿圆角窗口的一个实现方案(支持子控件)

    由于 QWidget::setMask 接口设置圆角不支持抗锯齿,所以通常会使用透明窗口加圆角背景,但圆角背景不能满足对子控件的裁剪,子控件与圆角区域重叠的部分还是能显示出来。当然对于大多数窗口,留出足够的边距也是可以接受。 对一些特殊场景,比如QComboBox的列表框,UI设计

    2023年04月24日
    浏览(62)
  • 在Unity中编写Shader的编译器环境配置(支持CG和HLSL)

    Unity默认使用的编译器VisualStudio带有扩展插件ShaderLabVS,但功能很差,所以还是选用VisualStudioCode作为编写Shader的编译器,一方面其能自动识别Shaderlab语法,并且还有丰富的Shader扩展插件来辅助编写。 实际上编写时我们只希望.shader文件有VSCODE打开,其他脚本正常还是用VS,可以

    2024年02月15日
    浏览(36)
  • 【零基础学web前端】CSS学习,字体属性,文本属性,背景属性,圆角矩形属性

    前言: 大家好,我是 良辰丫 ,在上一篇文章中我们了解了CSS引入方式,CSS基础选择器,CSS复合选择器,今天我们继续学习CSS的相关知识点.💞💞 🧑个人主页:良辰针不戳 📖所属专栏:零基础学web前端 🍎励志语句:生活也许会让我们遍体鳞伤,但最终这些伤口会成为我们一辈子的

    2024年02月05日
    浏览(79)
  • 数字图像处理(实践篇)二十九 OpenCV-Python在图像中检测矩形、正方形和三角形的实践

    目录 1 方案 2 实践 1 方案 ①检测矩形和正方形 ⒈检测图像中的所有轮廓。 ⒉循环检查所有检测到的轮廓。 ⒊为每个轮廓找到近似的轮廓。如果近似轮廓中的顶点数为4,则计算 宽高比 用来区分 矩形 和 正方形 。如果宽高比在0.9到1.1之间,则认为为正方形,否则的话,则为

    2024年01月25日
    浏览(61)
  • 【unity】URP的shader开发中支持多光源,_ADDITIONAL_LIGHTS_VERTEX 和 _ADDITIONAL_LIGHTS 区别

    项目里有一个其他同事实现的shader,美术那边希望能支持多个光源, 我一看代码里面, frag 函数里已经实现了   代码也加了:             #pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS 材质里加了这个keyword还是没起作用,   若宏控制注了有效。  一开始没搞明白

    2024年02月11日
    浏览(48)
  • 【Vuforia+Unity】AR02-长方体物体识别

      选择多维长方体图,这个长方体是生活中的真实物体的拍摄图,提前把6个面拍摄好并裁剪干净。 官网创建模型 https://developer.vuforia.com/targetmanager/project/targets?projectId=0ddbb5c17e7f4bf090834650bbea4995av=false  设置长宽高,这个长宽高需要与真实物体的长宽保持一样的比例 提前处理好

    2024年02月21日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包