庄懂的TA笔记(十五)<特效:流动 + 扰动>

庄懂的TA笔记(十五)<特效:流动 + 扰动>

效果展示:

正文:

大纲:

一、增广:

1、排序问题:

造成这个问题的原因是,他在取背景前,小人的胳膊不算是透明的,所以在编译过程中他就是被忽略的透明。

透贴问题 Detach Attach Zwrite Off 解决。(如何使用呢?这里暂时没讲)

判断 前方物体,是否遮挡了后方物体。并判断前方物体是否透明,Z深度像素点,是否更靠前,更近。

2、Alpha 通道预乘问题:

两种图片类型:

左图为,没预乘图。

右图为,预乘贴图。

什么是预乘呢?

就是吧颜色,RGB图片 和 透贴 乘一下,然后放在放到RGB里面。

需要注意什么呢?

在写,AB时(预乘时), 可以用 One OneMinusSrcAlpha的混合方式。

在写,AD时(不预乘时),可以用 SrcAlpha OneMinusSrcAlpha或 在shader里做乘法的混合方式。

3、AB AD 代码改进:

这里,实际上和上一篇的 笔记 记录的一致,AB,和AD 的区别 就在于:

Blend One OneBlend One OneMinusSrcAlpha .

二、UV流动效果实现:

1、演示· Ghost Flow

控制参数 设计:(定义材质面板)

1、添加噪波纹理 _NoiseTex

2、控制噪波强度 _NoiseInt

3、控制Flow速度 _FlowSpeed

知识点:

整体表现是 有亮,有暗(既对背景做提亮,也会对背景压暗),如果为这种直观感受,一般这种就算是AB。

如果是对所有背景做一个提亮,那一半就是AD。

2、代码 · GhostFlow

3、代码 · GhostFlow;

frac(取余,就是取小数点的意思,否则只取整数观感上是没有变化的).原因是部分低配机的情况下,不取余会花掉,在深入下,花掉的原因是 Time是从开了unity后,就一直无限增长的容易溢出,取余后,就不会了。

例图:

顶点shader:

让UV1(噪波UV)流动:

1、TRANSFORM_TEX支持贴图缩放

2、对V轴 加上 随时间变化的 偏移量,实现流动。_Time.(X,Y,Z)分3级,从慢到快,递增2倍速。

像素shader:

1、采样噪波图,只取单通道,R。

2、获得FinalRGB.

3、计算 opacity 透贴。

Remap噪波图(从0~1映射到0~2),以 1 为 中间值。lerp(1,var_NoiseTex * 2 , _NoiseInt*2);

截去噪波负值

计算opacity = 透贴 * 总不透明度 * 噪声图;

返回输出:float4 (FinalRGB,opacity);

代码示例:

Shader "Unlit/Sc014Flow01"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _NoiseTex ("_NoiseTex", 2D) = "gray" {}
        _NoiseInt ("噪波强度",Range(0,5))=1
        _FlowSpeed("流动速度",Range(-10,10))=5
        _Cutout("透贴",Range(0,1))=0.5
    }
    SubShader
    {
        Tags { 
                "Queue"="Transparent"
                "RenderType"="Transparent" 
                "ForceNoShadowCasting"="True"       // 关闭阴影投射
                "IgnoreProjector"="True"            // 不响应投射器
                
              }
        LOD 100
         Pass {
            Name "FORWARD"
            Tags {
                "LightMode"="ForwardBase"
            }

            Blend One OneMinusSrcAlpha

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_instancing
            #include "UnityCG.cginc"
            #pragma multi_compile_fwdbase_fullshadows
            #pragma target 3.0
            UNITY_INSTANCING_BUFFER_START( Props )
               // UNITY_DEFINE_INSTANCED_PROP( float4, _Color)
            UNITY_INSTANCING_BUFFER_END( Props )
            
            uniform sampler2D _MainTex;//uniform float4 _MainTex_ST;
            uniform sampler2D _NoiseTex;uniform float4 _NoiseTex_ST;
            uniform float _Cutout;
            uniform float _NoiseInt;
            uniform float _FlowSpeed;

            //输入结构
            struct VertexInput
            {
                float4 vertex : POSITION;
                float2 uv0 : TEXCOORD0;
                
            };
            //顶点输出结构
            struct VertexOutput 
            {
                float4 pos : SV_POSITION;
                float2 uv0 : TEXCOORD0;         //采样主贴图
                float2 uv1 : TEXCOORD1;         //采样噪波图
            };
            //输出结构>>>顶点shader>>>输出结构
            VertexOutput vert (VertexInput v) 
            {
                VertexOutput o = (VertexOutput)0;
                o.pos = UnityObjectToClipPos(v.vertex);
                o.uv0 = v.uv0;
                o.uv1 = TRANSFORM_TEX(v.uv0,_NoiseTex);
                o.uv1.y = o.uv1.y + frac(_Time.x) * _FlowSpeed;
                return o ;
            }
            //色彩输出结构
            float4 frag(VertexOutput i) : COLOR 
            {
                float4 var_mainTex = tex2D(_MainTex,i.uv0);
                float var_noiseTex = tex2D(_NoiseTex,i.uv1).r;
                float noise = lerp(1,var_noiseTex * 2,_NoiseInt);         // var_noiseTex * 2 == 将 noise 的值域 扩大到 0 - 2 .   并用lerp,加以控制。
                noise = max(0,noise); // 赋值截断,取消负值,就没有花花绿绿的东西了。
                float3 finalRGB = var_mainTex;
                float opacity = var_mainTex.a * _Cutout * noise;
                
                return float4(finalRGB*opacity,opacity);//这里注意,最后FinalRGB乘了一个 透贴,是因为开始没有预乘,这里做了预乘。(预乘:指 吧透贴和色彩都放在RGB中)
                //return noise;//输出噪波图
                //return opacity;//输出透明噪波图
            }
            ENDCG
        }
    }
}

三、UV扰动效果实现:

1、演示 · Ghost Warp :

1、扰动,在Flow代码段基础上增加了一个 扭曲图,噪波图是单通道的,而 扭曲图是三通道的

2、扭曲的是什么,是UV,UV有几个分量,有两个分量,对不同的分量,要有不同的方向。所以,扭曲图是有两个通道控制扭曲方向的.(这里为了减少贴图采样的计算量,将噪波图合并入 扭曲图

RG =扭曲图

B = 噪波图

3、追加 扭曲强度

2、准备Warp Tex : 如何做扭曲图

3、代码 · GhostWarp:

在这里,遇到了一个问题,就是在Gamma 和 Liner 两个色彩空间下,扰动效果不一样,如图。

解决方法有2

方法1:切换为Gamma色彩空间。

方法2:保持Liner 色彩空间,选中 用到的图片,取消勾选sRGB 。

这里问了群友为什么,为什么,gamma 和 liner 不同色彩空间下,会有不同UV偏移?

群友一位大佬提供了一个解释链接:

Gamma校正 - LearnOpenGL CN

大概意思为 引擎中,与 显示器 中,因硬件算法原因,会有Pow2.2的色彩亮度差别,这个pow2.2是弥补掉那个线性差,从而达到合理的观察效果。(没读完,理解可能相差甚远)

参考例图:

4、代码GhostWarp:

四、任务委托:

1、作业:

猜你喜欢

转载自blog.csdn.net/Allen7474/article/details/130595045