实现一个涂抹擦除效果

涂抹效果还是满常见的效果。

要做涂抹,首先要存一张中间贴图作为mask。

然后需要两个shader,一个做mask一个做混合。

MaskShader:

Shader "Unlit/MaskShader"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _MaskDecalTex("Mask Decal Texture", 2D) = "white" {}
        _MaskOffset("Mask Offset", vector) = (0,0,0,0)
    }

    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        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;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            float4 _MaskOffset;

            sampler2D _MaskDecalTex;

            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 r = tex2D(_MainTex, i.uv);

#if UNITY_UV_STARTS_AT_TOP
                float grabSign = -_ProjectionParams.x;
#else
                float grabSign = _ProjectionParams.x;
#endif

                half2 uv = float2(1, grabSign) * (i.uv - half2(0.5, 0.5)) / _MaskOffset.ww + half2(0.5, 0.5);

                fixed4 mask = tex2D(_MaskDecalTex, uv + _MaskOffset.xy);
                return r + mask;
            }
            ENDCG
        }
    }
}

BlendShader:

Shader "Unlit/BlendShader"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _SecondTex("Second Texture", 2D) = "white" {}
        _MaskTex("Mask Texture", 2D) = "white" {}
    }

    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        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;
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            sampler2D _SecondTex;
            sampler2D _MaskTex;

            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 col1 = tex2D(_MainTex, i.uv);
                fixed4 col2 = tex2D(_SecondTex, i.uv);

#if UNITY_UV_STARTS_AT_TOP
                float grabSign = -_ProjectionParams.x;
#else
                float grabSign = _ProjectionParams.x;
#endif

                half2 uv = float2(1, grabSign) * (i.uv - half2(0.5, 0.5)) + half2(0.5, 0.5);

                fixed4 mask = tex2D(_MaskTex, uv);
                return lerp(col1, col2, mask.a);
            }
            ENDCG
        }
    }
}

脚本(核心部分):

var viewPortPoint = Camera.main.WorldToViewportPoint(maskMappingPoint.position);

viewPortPoint -= new Vector4(0.5f, 0.5f);
viewPortPoint.w = maskMappingPoint.localScale.x;

if (mPersistMaskTex == null)
{
    mPersistMaskTex = new Texture2D(src.width, src.height, TextureFormat.RGBA32, false, true);
    for (int x = 0; x < mPersistMaskTex.width; x++)
        for (int y = 0; y < mPersistMaskTex.height; y++)
            mPersistMaskTex.SetPixel(x, y, new Color(0, 0, 0, 0));

    mPersistMaskTex.Apply();
}

maskMat.SetTexture("_MainTex", mPersistMaskTex);
maskMat.SetVector("_MaskOffset", viewPortPoint);
Graphics.Blit(mPersistMaskTex, maskRT, maskMat);

blendMat.SetTexture("_MainTex", src);
blendMat.SetTexture("_SecondTex", tempRT);
blendMat.SetTexture("_MaskTex", maskRT);
Graphics.Blit(src, des, blendMat);

var cacheActive = RenderTexture.active;

RenderTexture.active = maskRT;

mPersistMaskTex.ReadPixels(new Rect(0, 0, mPersistMaskTex.width, mPersistMaskTex.height), 0, 0);
mPersistMaskTex.Apply();

RenderTexture.active = cacheActive;
时间: 2024-10-10 08:54:23

实现一个涂抹擦除效果的相关文章

HTML5 实现橡皮擦的擦除效果

声明:本文为原创文章,如需转载,请注明来源WAxes,谢谢! 最近项目刚好用到这种效果,也就是有点像刮刮卡一样,在移动设备上,把某张图片刮掉显示出另一张图片.效果图如下:  DEMO请戳右:DEMO 这种在网上还是挺常见的,本来就想直接网上找个demo套用下他的方法就行了,套用了才发现,在android上卡出翔了,因为客户要求,在android不要求特别流畅,至少要能玩,但是网上找的那个demo实在太卡,根本就是没法玩的情况.于是就想自己写一个算了,本文也就权当记录一下研究过程. 这种刮图的效果

098在屏幕中实现一个检索框效果

效果如下: ViewController.h 1 #import <UIKit/UIKit.h> 2 3 @interface ViewController : UITableViewController<UISearchBarDelegate> 4 @property (strong, nonatomic) UISearchBar *searchBar; 5 @property (strong, nonatomic) NSMutableArray *mArrDataSourceO

简单的一个轮播效果

刚刚学了Jquery,写了一个简单的图片滑动,但不是完成品. <!DOCTYPE html> <meta content="text/html" charset="utf-8"/><html><head> <title></title> <link href="css/lunbo.css" rel="stylesheet"/> <scri

QVariant(相当于是Java里面的Object,起到一个数据类型“擦除”的作用,可以使用Q_DECLARE_METATYPE进行注册)

=QVariant= [%这个类型相当于是Java里面的Object,它把绝大多数Qt提供的数据类型都封装起来,起到一个数据类型“擦除”的作用.比如我们的 table单元格可以是string,也可以是int,也可以是一个颜色值,那么这么多类型怎么返回呢?于是,Qt提供了这个QVariant类型,你可 以把这很多类型都存放进去,到需要使用的时候使用一系列的to函数取出来即可.比如你把int包装成一个QVariant,使用的时候要用 QVariant::toInt()重新取出来.这里需要注意的是,Q

非常不错的一个JS分页效果代码

这里分享一个不错的js分页代码. 代码中cpage是页面计数,应为全局变量,可以随处调用它: totalpage是总页数. 与asp分页代码很类似,也是先取得记录总数,然后实现分页,基本的分页思路与原理还是相通的,感兴趣的朋友做个参考吧. 例子,js分页效果代码. <!doctype html public "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-t

HTML5 Canvas实现图片擦除效果

HTML5 Canvas实现图片擦除效果,该效果主要应用了canvas的globalCompositeOperation 属性值实现. index.html <!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="utf-8"> <meta content="width=device-width,initial-scale=1.0,maximu

收藏一个带动画效果的ScrollViewer以及ScrollBar的模板

原文:收藏一个带动画效果的ScrollViewer以及ScrollBar的模板 这里介绍一个带动画效果的ScrollViewer和ScrollBar,总共分为两个资源字典,直接拿来引用即可: 1 ScrollBarStyle.xaml <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft

网上英语外教一对一×××?我来推荐一个性价比高效果又好的!

现在学英语的越来越多,对于上班族和学生党来说要考虑时间和地域的限制,网上英语外教一对一是最适合的英语学习方式,但是很多刚接触网上英语外教一对一的网友们可能还有些犹豫和顾虑,毕竟网上一对一的机构那么多,不可能每家效果都好,性价比高吧,这么多家英语外教一对一的机构,哪家比较好呢?作为过来人,我来给大家推荐一个性价比高效果又好的吧! 网上英语外教一对一的机构有很多,我了解并去体验过的有3-4家的样子,每家机构课程.师资还有收费都不一样,如果想找性价比高效果又好的我推荐这个[https://www.ac

用bootstrap的tab插件做一个图层切换效果(感觉会误导淫们,大家当乐子看吧)

小伙伴们啊,我JS真的是个渣渣,所以总想要偷懒,于是为了实现效果就把tab插件给改了(各位大神轻拍啊,我是小白,很纯洁滴,小心脏也很脆弱)…… 最近做的项目为了考虑以后的移动设备兼容性,所以用了Bootstrap.首页有一个需要鼠标点击不一样的按钮固定位置图层内容变化的效果(我描述清楚了吗Orz……),如下图: 分别点击1,2,3,4按钮时现实对应的内容变化. 我就呵呵了,这个跟tab插件很类似啊~~不就是点按钮换图层吗.如果在别处找独立插件,我这记性的,项目js文件里早晚被我弄得乱七八糟我都不