Unity-Shader - 2DSprite描边效果

实现一个简单的2D精灵图描边效果,效果如下
在这里插入图片描述
实现思路:
可以通过判断该像素周围是否有透明度为 0的值,如果有,则说明该像素位于边缘。
所以我们需要打开alpha blend,即: Blend SrcAlpha OneMinusSrcAlpha,并且加入渲染队列,

Tags{"Queue" = "Transparent"
}
Blend SrcAlpha OneMinusSrcAlpha

根据图片的Alpha值边缘判定,向内扩一段距离做边缘,颜色设置为描边颜色;
片元着色阶段,向上下左右四个方向做检测,有一个点的透明度为0,判定为边缘;

fixed4 frag(v2f i) : SV_Target{fixed4 col = tex2D(_MainTex, i.uv);// 采样周围4个点float2 up_uv = i.uv + float2(0, 1) * _LineWidth * 1 / 10 * _MainTex_ST.xy;float2 down_uv = i.uv + float2(0,-1) * _LineWidth * 1 / 10 * _MainTex_ST.xy;float2 left_uv = i.uv + float2(-1,0) * _LineWidth * 1 / 10 * _MainTex_ST.xy;float2 right_uv = i.uv + float2(1,0) * _LineWidth * 1 / 10 * _MainTex_ST.xy;// 如果有一个点透明度为0 说明是边缘float w = tex2D(_MainTex,up_uv).a * tex2D(_MainTex,down_uv).a * tex2D(_MainTex,left_uv).a * tex2D(_MainTex,right_uv).a;if (w == 0) {col.rgb = lerp(_LineColor * _Intensity, col.rgb, w);}return col;}

如果图片内容恰好铺满整张图,没有alpha值,方法不适用

outline

可以和原图做插值,根据边缘判断来混合线的颜色和原图颜色
完整shader如下

Shader "shader2D/outline"
{Properties{_MainTex ("Texture", 2D) = "white" {}  // 主纹理属性,用于存储2D纹理_lineWidth("lineWidth",Range(0,10)) = 1  // 线宽属性,范围在0到10之间,默认值为1_lineColor("lineColor",Color)=(1,1,1,1)  // 线的颜色属性,RGBA格式,默认为白色}SubShader{// 渲染队列采用透明Tags{"Queue" = "Transparent"}Blend SrcAlpha OneMinusSrcAlpha  // 设置混合模式为源颜色乘以源透明度减去源透明度Pass{CGPROGRAM#pragma vertex vert  #pragma fragment frag  #include "UnityCG.cginc"  // 顶点着色器输入结构体 struct VertexInput{float4 vertex : POSITION;  // 顶点坐标float2 uv : TEXCOORD0;  // 纹理坐标};// 顶点着色器输出结构体 struct VertexOutput{float2 uv : TEXCOORD0;  // 纹理坐标float4 vertex : SV_POSITION;  // 顶点坐标};VertexOutput vert (VertexInput v){VertexOutput o;o.vertex = UnityObjectToClipPos(v.vertex);  // 将顶点坐标转换到裁剪空间o.uv = v.uv;  // 传递纹理坐标return o;}sampler2D _MainTex;  // 主纹理float4 _MainTex_TexelSize;  // 主纹理的像素大小float _lineWidth;  // 线宽float4 _lineColor;  // 线的颜色fixed4 frag (VertexOutput i) : SV_Target{fixed4 col = tex2D(_MainTex, i.uv);  // 获取纹理颜色// 采样周围4个点float2 up_uv = i.uv + float2(0,1) * _lineWidth * _MainTex_TexelSize.xy;float2 down_uv = i.uv + float2(0,-1) * _lineWidth * _MainTex_TexelSize.xy;float2 left_uv = i.uv + float2(-1,0) * _lineWidth * _MainTex_TexelSize.xy;float2 right_uv = i.uv + float2(1,0) * _lineWidth * _MainTex_TexelSize.xy;// 如果有一个点透明度为0,说明是边缘float w = tex2D(_MainTex,up_uv).a * tex2D(_MainTex,down_uv).a * tex2D(_MainTex,left_uv).a * tex2D(_MainTex,right_uv).a;// 和原图做插值,根据边缘判断来混合线的颜色和原图颜色col.rgb = lerp(_lineColor,col.rgb,w);return col;}ENDCG}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/200591.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

leetcode:1422. 分割字符串的最大得分(python3解法)

难度:简单 给你一个由若干 0 和 1 组成的字符串 s ,请你计算并返回将该字符串分割成两个 非空 子字符串(即 左 子字符串和 右 子字符串)所能获得的最大得分。 「分割字符串的得分」为 左 子字符串中 0 的数量加上 右 子字符串中 1…

Android 12.0 Folder文件夹全屏后文件夹图标列表居中时拖拽app到桌面的优化

1.概述 在12.0的系统rom产品开发中,在Launcher3中在目前的产品需求开发中,对于Launcher3中的文件夹Folder的布局UI 进行了定制化的需求要求把Folder修改为全屏,然后在中间显示文件夹图标的列表,这时候如果Folder是全屏的话,如果拖拽文件夹列表中的app图标,只有拖拽 到屏…

UEC++ 探索虚幻5笔记(捡金币案例) day12

吃金币案例 创建金币逻辑 之前的MyActor_One.cpp,直接添加几个资源拿着就用 //静态网格UPROPERTY(VisibleAnywhere, BlueprintReadOnly)class UStaticMeshComponent* StaticMesh;//球形碰撞体UPROPERTY(VisibleAnywhere, BlueprintReadWrite)class USphereCompone…

JSON 语法详解:轻松掌握数据结构(上)

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云…

【代码随想录】算法训练计划39

dp 1、62. 不同路径 题目: 求路径方案多少个 思路: 这道题就有点dp了哈 func uniquePaths(m int, n int) int {//dp,写过,代表的是多少种// 初始化dp : make([][]int, m)for i : range dp {dp[i] make([]int, n)dp[i][0] 1 // 代表到…

用友NC Cloud FileParserServlet反序列化RCE漏洞复现

0x01 产品简介 用友 NC Cloud 是一种商业级的企业资源规划云平台,为企业提供全面的管理解决方案,包括财务管理、采购管理、销售管理、人力资源管理等功能,实现企业的数字化转型和业务流程优化。 0x02 漏洞概述 用友 NC Cloud FileParserServlet接口存在反序列化代码执行漏…

response应用

文章目录 [TOC](文章目录) response说明一、response文件下载二、待补充。。。 response说明 response是指HttpServletResponse,该响应有很多的应用,比如像浏览器输出消息,下载文件,实现验证码等。 一、response文件下载 1.创建一个javaw…

springboot整合swagger

1)简介: 作为后端开放人员,最烦的事就是自己写接口文档和别人没有写接口文档,不管是前端还是后端开发,多多少少都会被接口文档所折磨,前端会抱怨后端没有及时更新接口文档,而后端又会觉得编写接…

备份和恢复Linux服务器上的HTTP配置

备份和恢复Linux服务器上的HTTP配置是一项重要的任务,它可以确保您的服务器在出现故障或配置错误时能够迅速恢复正常运行。下面我们将介绍如何备份和恢复Linux服务器上的HTTP配置。 备份HTTP配置 登录到Linux服务器上,并使用root权限。 备份HTTP配置文…

分部积分法

1.形式:u对v求积分uv-v对u求积分,一前一后,一般把三角函数,反三角函数,In,e的x次方提到d里面 2. 3. 4. 5. 6. 7. 当结果中出现要求的不要慌,不是1直接求,是1重新计算

一体化污水处理设备材质怎么选

在环保意识日益增强的今天,污水处理设备成为城市建设过程中的重要环节。而选择合适的一体化污水处理设备材质,则成为了一项重要的决策。本文将从专业的角度出发,为您解析一体化污水处理设备材质的选取。 首先,一体化污水处理设备材…

postman常用脚本

在参数中动态添加开始时间和结束时间的时间戳 1.先在collection中添加参数,这里的作用域是collection,也可以是其他的任何scope 2.在Pre-request Script 中设定开始时间和结束时间参数,比如昨天和今天的时间戳,下面是js代码 con…

Android Studio Hedgehog | 2023.1.1(刺猬)

Android Gradle 插件和 Android Studio 兼容性 Android Studio 构建系统基于 Gradle,并且 Android Gradle 插件 (AGP) 添加了一些特定于构建 Android 应用程序的功能。下表列出了每个版本的 Android Studio 所需的 AGP 版本。 Android Studio versionRequired AG…

python学习:opencv+用鼠标画矩形和圆形

目录 步骤 定义数据 新建一个窗口黑色画布 显示黑色画布 添加鼠标回调函数 循环 一直显示图片 一直判断有没有按下字母 m 关闭所有窗口 鼠标回调函数 步骤 当鼠标按下记录坐标并记录鼠标标记位为true,移动的时候就会不断的画矩形或者圆,松下的时候就再…

STM32F1中断NVIC

目录 1. 中断系统 2. 中断向量表 3. NVIC基本结构 4. NVIC优先级分组 5. NVIC程序编写 5.1 中断分组 5.2 中断结构体变量 5.3 中断通道选择 5.4 抢占优先级和响应优先级配置 6. 中断程序执行 1. 中断系统 中断:在主程序运行过程中&#xff0…

如何设计自动化测试脚本

企业中如何设计自动化测试脚本呢?今天我们就来为大家分享一些干货。 一、线性设计 线性脚本设计方式是以脚本的方式体现测试用例,是一种非结构化的编码方式,多数采用录制回放的方式,测试工程师通过录制回访的访问对被测系统进行…

基于JSDoc实现TypeScript类型安全的实践报告

在FEDay 2023中我讲了《从JS到TS无缝迁移的实践报告》【视频在这里在这里】,是将一个传统的JS项目(mochajs/mocha)迁移到TypeScript环境的全程。其中提到了一件事情,就是“可以通过JSDoc/TSDoc来生成.d.ts”,从而实现T…

mvc模式test2

关于上篇book.java中使用类型不一样导致的报错 是在bookdao.java中解决 bookservlet.java package servlet; import java.io.IOException; import beans.Book; import dao.BookDao; import java.util.ArrayList; import javax.servlet.ServletException; import javax.servl…

RabbitMQ的消息发送和接收机制

所有 MQ 产品从模型抽象上来说都是一样的过程: 消费者(consumer)订阅某个队列。生产者(producer)创建消息,然后发布到队列(queue)中,最后将消息发送到监听的消费者。 上…

C语言 - 字符函数和字符串函数

系列文章目录 文章目录 系列文章目录前言1. 字符分类函数islower 是能够判断参数部分的 c 是否是⼩写字⺟的。 通过返回值来说明是否是⼩写字⺟,如果是⼩写字⺟就返回⾮0的整数,如果不是⼩写字⺟,则返回0。 2. 字符转换函数3. strlen的使⽤和…