基于Unity怎么实现2D边缘检测
发表于:2025-11-07 作者:千家信息网编辑
千家信息网最后更新 2025年11月07日,今天小编给大家分享一下基于Unity怎么实现2D边缘检测的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们
千家信息网最后更新 2025年11月07日基于Unity怎么实现2D边缘检测
今天小编给大家分享一下基于Unity怎么实现2D边缘检测的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。
一、ShaderLab
1.Alpha值边缘检测
根据图片的Alpha值边缘判定,向内扩一段距离做边缘,颜色设置未描边颜色;
片元着色阶段,向上下左右四个方向做检测,有一个点的透明度为0,判定为边缘;
Shader "2DOutline"{ Properties { _MainTex("Texture", 2D) = "white" {} _LineWidth("Width",Range(0,0.4)) = 1.0 _LineColor("LineColor",color) = (1,1,1,1) _Intensity("Intensity",Range(1,10)) = 1.0 } SubShader { Tags { "RenderType" = "Opaque" "Queue" = "Transparent"} Blend SrcAlpha OneMinusSrcAlpha Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; sampler2D _MainTex; float4 _MainTex_ST; fixed _LineWidth; float4 _LineColor; fixed _Intensity; v2f vert(appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); return o; } 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; } ENDCG } }}如果图片内容恰好铺满整张图,没有alpha值,方法不适用;下图底部边缘消失了;
2.卷积边缘检测
在屏幕后处理阶段,使用卷积做边缘检测;
卷积:根据像素周围八个方向的像素的计算出新的像素值;
边缘检测卷积算子,都包含水平和竖直两个方向的卷积核;
梯度公式:G = sqrt(Gx*Gx + Gy*Gy);
考虑性能问题,使用:G = |Gx|+|Gy|;
顶点着色器计算卷积纹理采样坐标,减少计算量(片元数量更多);
片元着色阶段Sobel卷积计算,插值获得片元像素颜色;
Sobel计算结果和梯度Gradient比较,大于梯度和EdgeColor做插值;
屏幕后效调用OnRenderImage接口;
Shader "EdgeDetection" { Properties{ _MainTex("Base (RGB)", 2D) = "white" {} _EdgeColor("Edge Color", Color) = (0, 0, 0, 1) //卷积梯度 _Gradient("Gradient",float) =0.0 } SubShader{ Pass { ZTest Always Cull Off ZWrite Off CGPROGRAM #include "UnityCG.cginc" #pragma vertex vert #pragma fragment frag sampler2D _MainTex; uniform half4 _MainTex_TexelSize; //fixed _EdgeOnly; fixed4 _EdgeColor; //fixed4 _BackgroundColor; fixed _Gradient; struct v2f { float4 pos : SV_POSITION; half2 uv[9] : TEXCOORD0; }; v2f vert(appdata_img v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); half2 uv = v.texcoord; o.uv[0] = uv + _MainTex_TexelSize.xy * half2(-1, -1); o.uv[1] = uv + _MainTex_TexelSize.xy * half2(0, -1); o.uv[2] = uv + _MainTex_TexelSize.xy * half2(1, -1); o.uv[3] = uv + _MainTex_TexelSize.xy * half2(-1, 0); o.uv[4] = uv + _MainTex_TexelSize.xy * half2(0, 0); o.uv[5] = uv + _MainTex_TexelSize.xy * half2(1, 0); o.uv[6] = uv + _MainTex_TexelSize.xy * half2(-1, 1); o.uv[7] = uv + _MainTex_TexelSize.xy * half2(0, 1); o.uv[8] = uv + _MainTex_TexelSize.xy * half2(1, 1); return o; } fixed luminance(fixed4 color) { return 0.2125 * color.r + 0.7154 * color.g + 0.0721 * color.b; } half Sobel(v2f i) { const half Gx[9] = { -1, 0, 1, -2, 0, 2, -1, 0, 1}; const half Gy[9] = { -1, -2, -1, 0, 0, 0, 1, 2, 1}; half texColor; half edgeX = 0; half edgeY = 0; for (int it = 0; it < 9; it++) { texColor = luminance(tex2D(_MainTex, i.uv[it])); edgeX += texColor * Gx[it]; edgeY += texColor * Gy[it]; } half edge = 1 - abs(edgeX) - abs(edgeY); return edge; } fixed4 frag(v2f i) : SV_Target { half edge = Sobel(i); fixed4 col = tex2D(_MainTex, i.uv[4]); if(edge> _Gradient) col = lerp(_EdgeColor, tex2D(_MainTex, i.uv[4]), edge); return col; } ENDCG } } FallBack Off}二、ShaderGraph
抓取图片缓冲,上下左右四个方位平移,乘以描边颜色;
四张图合并,减去原图范围的像素,只剩边缘;
最后将原图和边缘合并(可插值使边缘柔和);
升级项目到URP,修改projectsetting-graphic-pielinesettings;
导入ShaderGraph包,开始拖拖拽拽,真的香,效果好,速度快,思路清晰;
以上就是"基于Unity怎么实现2D边缘检测"这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注行业资讯频道。
边缘
卷积
检测
像素
梯度
知识
篇文章
颜色
内容
图片
方向
阶段
插值
原图
屏幕
更多
透明度
不同
很大
平和
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
http 2 服务器
结构化软件开发基本要点
中国人民网络安全法实行时间
软件开发前端学什么
多桌面的软件开发
大兴区数据网络技术软件
初级服务器试题
虚拟机对服务器的要求
网络技术合作伙伴
长飞智慧网络技术有限公司涂金格
订餐系统数据库代码
手机如何远程云服务器
小学校园网络安全主题班会记录
机关网络安全演练方案
政府绩效管理软件开发
以网络安全写广告词
到电子厂做软件开发
成功网络安全等级保护制度
宣传 护苗网络安全课
软件开发工程费用怎么计算
精益仿真软件开发
网络安全八条禁令
政企云服务器
网络安全法手抄报
关于网络安全手抄报内容
网络技术合作伙伴
北京金源万博软件开发
gee数据库sql转dbc
电脑服务器密码到期了怎么办
新乡天气预报软件开发