Unity Shader 像素图描边

思路:在片元着色器中,处理像素p,针对p的上下左右四个像素采样(使用一个变量width来控制描边宽度,也就是处理上下左右多远的像素),若p本身是透明像素,则
- 若上下左右存在非透明像素,则当前像素p返回描边颜色
- 若上下左右都是透明像素,则返回透明即可
若 p 本身非透明像素,则返回本身颜色即可
Shader "Custom_Shader/ImageOuterOutline"
{
Properties
{
_MainTex ("Sprite Texture", 2D) = "white" {}
_OutlineWidth ("Outline Width", float) = 1
_OutlineColor ("Outline Color", Color) = (1.0, 1.0, 1.0, 1.0)
_AlphaValue ("Alpha Value", Range(0, 1)) = 0.1
[ToggleUI] _IsWhite ("IsWhite", Float) = 0
}
SubShader
{
Blend SrcAlpha OneMinusSrcAlpha
Tags
{
"Queue" = "Transparent"
}
Pass
{
ZTest Off
Blend SrcAlpha OneMinusSrcAlpha
Cull Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
float4 _MainTex_ST;
half4 _MainTex_TexelSize;
float _OutlineWidth;
float4 _OutlineColor;
float _AlphaValue;
float _IsWhite;
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float4 normal : NORMAL;
};
struct v2f
{
float4 vertex : SV_POSITION;
half2 uv : TEXCOORD0;
half2 left : TEXCOORD1;
half2 right : TEXCOORD2;
half2 up : TEXCOORD3;
half2 down : TEXCOORD5;
};
v2f vert(appdata i)
{
v2f o;
o.vertex = UnityObjectToClipPos(i.vertex);
o.uv = TRANSFORM_TEX(i.uv, _MainTex);
o.left = o.uv + half2(-1, 0) * _MainTex_TexelSize.xy * _OutlineWidth;
o.right = o.uv + half2(1, 0) * _MainTex_TexelSize.xy * _OutlineWidth;
o.up = o.uv + half2(0, 1) * _MainTex_TexelSize.xy * _OutlineWidth;
o.down = o.uv + half2(0, -1) * _MainTex_TexelSize.xy * _OutlineWidth;
return o;
}
fixed4 frag(v2f i) : SV_Target
{
const float transparent = tex2D(_MainTex, i.left).a + tex2D(_MainTex, i.right).a + tex2D(_MainTex, i.up)
.a + tex2D(_MainTex, i.down).a;
fixed4 color = tex2D(_MainTex, i.uv);
fixed4 result;
if (color.a < 0.1)
{
if (_IsWhite > 0.1)
{
//闪白
result = step(_AlphaValue, transparent) * (1,1,1,1);
}
else
{
result = step(_AlphaValue, transparent) * _OutlineColor;
}
}
else
{
if (_IsWhite > 0.1)
{
//闪白
result = (1.0, 1.0, 1.0, 1.0);
}
else
{
result = color;
}
}
return result;
}
ENDCG
}
}
}
参考:https://www.jianshu.com/p/c68a730e9a8b
Unity Shader 像素图描边的更多相关文章
- 关于Unity中的模型描边与Shader切换(专题二)
模型描边 1: LOL里面的模型描边效果,点击防御塔会有描边的效果,被攻击的时候模型也要描边凸显一下2: 网上可以找到模型描边的Shader,可以直接下载使用,一组第三方的Shader, 帮我们解决了 ...
- Unity Shader 卡通渲染 基于退化四边形的实时描边
从csdn转移过来,顺便把写过的文章改写一下转过来. 一.边缘检测算法 3D模型描边有两种方式,一种是基于图像,即在所有3D模型渲染完成一张图片后,对这张图片进行边缘检测,最后得出描边效果.一种是基于 ...
- Unity Shader 知识点总结(一)
在学习了一段时间的Unity Shader后,打算写一些知识总结,便于今后的查找.如有错误,希望大家指出更改. 本文参照的unity入门精要一书,做一个知识归纳,如有兴趣可以看看其开源的部分,是一本比 ...
- 【Unity Shader】Unity Chan的卡通材质
写在前面 时隔两个月我终于来更新博客了,之前一直在学东西,做一些项目,感觉没什么可以分享的就一直没写.本来之前打算写云彩渲染或是Compute Shader的,觉得时间比较长所以打算先写个简单的. 今 ...
- 【转】《Unity Shader入门精要》冯乐乐著 书中彩图
为方便个人手机学习时候查阅,从网上转来这些彩图. 如属过当行为,联系本人删除. 勘错表 http://candycat1992.github.io/unity_shaders_book/unity_s ...
- Unity Shader入门精要学习笔记 - 第14章非真实感渲染
转载自 冯乐乐的 <Unity Shader 入门精要> 尽管游戏渲染一般都是以照相写实主义作为主要目标,但也有许多游戏使用了非真实感渲染(NPR)的方法来渲染游戏画面.非真实感渲染的一个 ...
- Unity Shader入门精要学习笔记 - 第12章 屏幕后处理效果
建立一个基本的屏幕后处理脚本系统 屏幕后处理,顾名思义,通常指的是在渲染完整个场景得到屏幕图像后,再对这个图像进行一系列操作,实现各种屏幕特效.使用这种技术,可以为游戏画面添加更多艺术效果,例如景深. ...
- Unity Shader入门精要学习笔记 - 第13章 使用深度和法线纹理
线纹理的代码非常简单,但是我们有必要在这之前首先了解它们背后的实现原理. 深度纹理实际上就是一张渲染纹理,只不过它里面存储的像素值不是颜色值而是一个高精度的深度值.由于被存储在一张纹理中,深度纹理里的 ...
- Unity Shader之模板测试
Unity Shader之模板测试 一沙一世界,一花一天堂 一.Stencil testing 渲染管线 当片段着色器处理完一个片段之后,模板测试(Stencil Test)会开始执行,和深度 ...
- Unity Shader入门
Unity Shader入门 http://www.cnblogs.com/lixiang-share/p/5025662.html http://www.manew.com/blog-30559-1 ...
随机推荐
- 信息资源管理综合题之“什么是公钥基础设施(PKI) 和 PKI的任务核心 和 补全PKI认证服务系统流程图”
一.关于公钥基础设施(PKI),请回如下问题 1.PKI的核心任务是什么? 2.PKI的任务核心是什么? 3.基于PKI的认证服务系统至少由哪几部分组成?请将答案内容(1)~(5)填写在题中图下对应的 ...
- Vue 3中的ref和template refs详解(含Vue2迁移到Vue3方法)
Vue 3中的ref和template refs详解 在Vue 3中,ref和模板引用(template refs)是两个相关但不同的概念,它们在组合式API(Composition API)中扮演着 ...
- vue3 基础-组件间传值及校验
本篇讲基于对页面组件化拆分后, 组件之间如何进行数据传递, 通常是父组件如何给子组件进行传值, 子组件接收并进行数据校验后再使用. 父子组件传值 <!DOCTYPE html> <h ...
- 代码视角-神经网络-Python 实现(上)
说明: 就是巩固一下认识而已, 也是找了篇网上大佬的文章, 看了下写得还行, 抄一抄, 权当编程练习了, 目的成为了, 从代码的角度去认识这些, 莫名其妙的, 让人生畏的, 但其实简单的, 生物学名词 ...
- H5完美适配刘海屏和状态栏高度的全机型解决方案攻略
@charset "UTF-8"; .markdown-body { line-height: 1.75; font-weight: 400; font-size: 15px; o ...
- CUDA 线程ID 计算方式
thread ID 的计算方式,简单来说很像小学学的除法公式,本文转载自同学一篇博客:并进行简单修改: 被除数 = 除数 * 商 + 余数 用公式表示:$$线程Id = blockId * block ...
- 网络编程:阻塞I/O和线程模型
线程 进程模型在处理用户请求的过程中,进程切换上下文的代价比较高,而,一种轻量级的模型可以处理多用户连接请求,那就是线程模型. 线程(thread)是运行在进程中的一个"逻辑流", ...
- AtCoder Beginner Contest 369 补题记录
A - 369 题意: 给定A和B,求有多少个x可以和A,B构成等差数列 思路: 分三种情况讨论 A == B 则x不得不与A和B想等 x位于A和B中间 只有B - A 为偶数才有这种情况存在 x位于 ...
- 异步之舞:FastAPI与MongoDB的极致性能优化之旅
title: 异步之舞:FastAPI与MongoDB的极致性能优化之旅 date: 2025/05/23 21:55:11 updated: 2025/05/23 21:55:11 author: ...
- React-Native开发鸿蒙NEXT-本地与沙盒加载bundle
React-Native开发鸿蒙NEXT-本地与沙盒加载bundle 来晚了来晚了,不是想偷懒,实在是一个图片问题没搞定导致效果出不来,今天刚靠工具查出了原因. RN的加载无非本地加载与沙盒加载两种方 ...