美文网首页Unity Shader分享
ImageEffects_Twirl(转)

ImageEffects_Twirl(转)

作者: 树上的cat_ee3c | 来源:发表于2017-09-28 23:14 被阅读11次

    Twirl是一个全屏画面扭曲的效果,新仙剑的战斗切换有用到这个效果。

    主要有三个设置:

    center扭曲的中心点

    radius扭曲的范围

    angle扭曲的角度

    用到了如下函数

    Matrix4x4.TRS(Vector3 pos, Quaternion rotate,Vector3 scale)

    创建一个包括位移,旋转,缩放的矩阵

    Matrix4x4rotationMatrix =Matrix4x4.TRS(Vector3.zero,Quaternion.Euler(0,0, angle),Vector3.one);

    然后通过material的以下函数向shader里传参数

    material.SetMatrix("name",value)对应Shader里的 float4x4

    material.SetVector("name",value)对应Shader里的 float4

    float2 MultiplyUV (float4x4 mat, float2 inUV) {

    float4 temp = float4 (inUV.x, inUV.y, 0, 0);

    temp = mul (mat, temp);

    return temp.xy;

    }

    步骤:

    脚本

    (1) 通过Angle得到旋转矩阵

    Matrix4x4rotationMatrix =Matrix4x4.TRS(Vector3.zero,Quaternion.Euler(0,0, angle),Vector3.one);

    (2) 将矩阵和 旋转中点 及 半径传入shader.

    Shader

    (1) 将坐标系从左下角的坐标系 转到 以旋转中点为 原点的坐标系

    vert里 o.uv = v.texcoord- _CenterRadius.xy;

    (2) 将旋转坐标系 里的uv乘以 旋转矩阵。

    (3) 将uv除以 半径, 再取长度。长度超过1则为 旋转区域外,小于则在区域内

    (4) 如果在区域外,则为默认offset, 在内则是旋转后的offset

    脚本

    usingUnityEngine;

    usingSystem.Collections;

    public classTwirlEffectMe :MonoBehaviour{

    public Shadershader;

    private Materialmat;

    public Vector2radius =new Vector2(0.3F,0.3F);

    publicfloatangle =50;

    public Vector2center =new Vector2(0.5F,0.5F);

    voidStart()

    {

    mat =newMaterial(shader);

    }

    voidOnRenderImage (RenderTexturesource,RenderTexturedestination) {

    RenderDistortion (mat, source, destination, angle, center, radius);

    }

    publicstaticvoidRenderDistortion(Materialmaterial,RenderTexturesource,RenderTexturedestination,floatangle,Vector2center,Vector2radius)

    {

    Matrix4x4rotationMatrix =Matrix4x4.TRS(Vector3.zero,Quaternion.Euler(0,0, angle),Vector3.one);

    material.SetMatrix("_RotationMatrix", rotationMatrix);

    material.SetVector("_CenterRadius",newVector4(center.x, center.y, radius.x, radius.y));

    Graphics.Blit(source, destination, material);

    }

    }

    Shader脚本

    Shader"Custom/TwirlEffectMe"{

    Properties{

    _MainTex ("Base (RGB)",2D) ="white"{}

    }

    SubShader{

    Pass{

    ZTestAlwaysCullOffZWriteOff

    Fog{Modeoff}

    CGPROGRAM

    #pragmavertex vert

    #pragmafragment frag

    #include"UnityCG.cginc"

    uniformsampler2D_MainTex;

    uniformfloat4_MainTex_TexelSize;

    uniformfloat4_CenterRadius;

    uniformfloat4x4_RotationMatrix;

    structv2f {

    float4pos : POSITION;

    float2uv :TEXCOORD0;

    } ;

    v2f vert( appdata_img v )

    {

    v2f o;

    o.pos =mul(UNITY_MATRIX_MVP, v.vertex);

    o.uv = v.texcoord- _CenterRadius.xy;

    returno;

    }

    float4frag (v2f i) :COLOR

    {

    float2offset= i.uv;

    float2distortedOffset = MultiplyUV (_RotationMatrix,offset.xy);

    float2tmp =offset/ _CenterRadius.zw;

    float2finalUV;

    floatlen =length(tmp);

    // out of twirl

    if( len >1)

    {

    finalUV =offset;

    }

    else

    {

    finalUV =distortedOffset;

    }

    // back to normal uv coordinate

    finalUV += _CenterRadius.xy;

    returntex2D(_MainTex, finalUV);

    }

    ENDCG

    }

    }

    Fallbackoff

    }

    但是运行后,发现仅仅是简单旋转。需要再加上模糊。

    分析一下,发现是由内向外从distortedOffset 渐渐向 正常offset过度的过程

    于是将43行的finalUV =distortedOffset;改为

    finalUV =lerp(distortedOffset,offset, len );

    整体代码如下:

    Shader"Custom/TwirlEffectMe"{

    Properties{

    _MainTex ("Base (RGB)",2D) ="white"{}

    }

    SubShader{

    Pass{

    ZTestAlwaysCullOffZWriteOff

    Fog{Modeoff}

    CGPROGRAM

    #pragmavertex vert

    #pragmafragment frag

    #include"UnityCG.cginc"

    uniform sampler2D_MainTex;

    uniformfloat4_MainTex_TexelSize;

    uniformfloat4_CenterRadius;

    uniformfloat4x4_RotationMatrix;

    structv2f {

    float4pos : POSITION;

    float2uv :TEXCOORD0;

    } ;

    v2f vert( appdata_img v )

    {

    v2f o;

    o.pos =mul(UNITY_MATRIX_MVP, v.vertex);

    o.uv = v.texcoord- _CenterRadius.xy;

    returno;

    }

    float4frag (v2f i) :COLOR

    {

    float2offset= i.uv;

    float2distortedOffset = MultiplyUV (_RotationMatrix,offset.xy);

    float2tmp =offset/ _CenterRadius.zw;

    float2finalUV;

    floatlen =length(tmp);

    // out of twirl

    if( len >1)

    {

    finalUV =offset;

    }

    else

    {

    finalUV =lerp(distortedOffset,offset, len );

    }

    // back to normal uv coordinate

    finalUV += _CenterRadius.xy;

    returntex2D(_MainTex, finalUV);

    }

    ENDCG

    }

    }

    Fallbackoff

    }

    点击运行,效果对了。

    相关文章

      网友评论

        本文标题: ImageEffects_Twirl(转)

        本文链接:https://www.haomeiwen.com/subject/kkhbextx.html