ShadersRoom - Mix2Textures

先上一个效果图,如下:


MixTextures.gif

大致的实现思路是:
1.根据当前模型坐标的x取值和图片的分割位置比较,x坐标值小于这分割位置时显示第一张图片,大于则显示另外一张;
2.然后在分割点的两边做一个图片渐变的融合即可。

先实现第一步:
1.需要的属性三个:两张贴图和一个分割点的值:

    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _SecondTex ("SecondTex", 2D) = "white" {}
        _TextureMix("TextureMix",range(0,1)) = 0.5
    }

模型到顶点的结构体有两个,模型的顶点坐标和UV

struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

顶点到片元函数的结构体需要得到模型空间下的坐标(只需要X,Y两个值)和两个需要采样的UV:

struct v2f
            {
                float2 uv1 : TEXCOORD0;
                float2 uv2 : TEXCOORD1;
                float4 vertex : SV_POSITION;
                float2 localPos : TEXCOORD2;
            };

在顶点函数中需要注意的是,需要将模型空间下的顶点坐标的范围做一下转化,如下面的代码注释:

 v2f vert (appdata v)
            {
                v2f o;
                o.localPos = v.vertex.xy + float2(0.5,0.5);  //v.vertex 范围在(-0.5,0.5)之间,加上0.5取值到0-1
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv1 = TRANSFORM_TEX(v.uv, _MainTex);
                o.uv2= TRANSFORM_TEX(v.uv, _SecondTex);
                return o;
            }

最后在片元函数中输出:

 fixed4 frag (v2f i) : SV_Target
            {
                if(i.localPos.x < _TextureMix)
                {
                    return tex2D(_MainTex, i.uv1);
                }
                else
                {
                    return tex2D(_SecondTex,i.uv2);
                }

完成后可以看到,拖动分割的位置,两张图片会根据这个位置分别显示在面片上:


1.gif

2.继续第二步,需要在分割点上进行两张图片的融合,有一个渐变的过程看起来不那么僵硬:
在最后的片元函数中,先计算出需要 分割点模型位置x 的距离:

                fixed distanceFrontMixPoint = _TextureMix - i.localPos.x;

有了距离后,需要一个渐变的距离y,当距离这个分割点在y的范围内时,两张图片做一个融合显示,我用的是0.2,这个值可以根据自己的喜好调整:

                if(abs(distanceFrontMixPoint) < 0.2)   //取绝对值,因为左右两边都需要显示
                {
                    fixed mixFactor = 1 - (distanceFrontMixPoint + 0.2)/0.4;  //取得混合因子,这个记住就好了,如果修改了显示范围的话,分母需要修改长度的两倍
                    return lerp(tex2D(_MainTex, i.uv1),tex2D(_SecondTex,i.uv2),mixFactor);
                }

完成后可以看到,在滑动分割点时,图片出现了融合,但是有一个问题是在最左边和最右边(也就是0和1的位置)时,显示也出现了融合:


2.gif

什么原因呢,因为当在x在0的位置时,也满足进行混合的条件:

 if(abs(distanceFrontMixPoint) < 0.2) 

同样在1的位置也是一样,所以想要在0和1的位置显示完成的图片,修改一下分割点的范围即可(两边分别增加一个融合的范围,这里例子中是0.2):

_TextureMix("TextureMix",range(-0.2,1.2)) = 0.5

完成后就和开头实现的效果一样啦~~

git仓库:https://github.com/Looooooong/ShadersRoom

最后附上整体的源码:

Shader "ShadersRoom/MixTwoTextures"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _SecondTex ("SecondTex", 2D) = "white" {}
        _TextureMix("TextureMix",range(-0.2,1.2)) = 0.5
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            
            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv1 : TEXCOORD0;
                float2 uv2 : TEXCOORD1;
                float4 vertex : SV_POSITION;
                float2 localPos : TEXCOORD2;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            sampler2D _SecondTex;
            float4 _SecondTex_ST;
            half _TextureMix;
            
            v2f vert (appdata v)
            {
                v2f o;
                o.localPos = v.vertex.xy + float2(0.5,0.5);  //v.vertex 范围在(-0.5,0.5)之间,加上0.5取值到0-1
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv1 = TRANSFORM_TEX(v.uv, _MainTex);
                o.uv2= TRANSFORM_TEX(v.uv, _SecondTex);
                return o;
            }
            
            fixed4 frag (v2f i) : SV_Target
            {
                fixed distanceFrontMixPoint = _TextureMix - i.localPos.x;

                if(abs(distanceFrontMixPoint) < 0.2)
                {
                    fixed mixFactor = 1 - (distanceFrontMixPoint + 0.2)/0.4;
                    return lerp(tex2D(_MainTex, i.uv1),tex2D(_SecondTex,i.uv2),mixFactor);
                }
                
                if(i.localPos.x < _TextureMix)
                {
                    return tex2D(_MainTex, i.uv1);
                }
                else
                {
                    return tex2D(_SecondTex,i.uv2);
                }

            }
            ENDCG
        }
    }
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容

  • 转载自VR设计云课堂[https://www.jianshu.com/u/c7ffdc4b379e]Unity S...
    水月凡阅读 1,006评论 0 0
  • 本文首发于个人博客:Lam's Blog - 【OpenGL ES】入门及绘制一个三角形,文章由MarkDown语...
    格子林ll阅读 7,248评论 2 18
  • 《雪的声音》 南明海辰 那天的冬阳 淡的能拧出水来 我数着头顶 路过的枝桠 听见了刚停落的雪 窃窃私语 嘎吱响的是...
    南明海辰阅读 161评论 0 0
  • 文/紫苏wmt -01- 这俩天,表姐老和我在微信里抱怨说她过的不开心,并且把她和舍友的聊天记录给我看了一下。 “...
    紫苏语阅读 267评论 3 2
  • 今天回家的时候在路上,我一抬头看见了天空中有一个亮光。我就问妈妈,我也不知道是飞机还是星星,我就说了一个是...
    玉珺阅读 153评论 0 0