生成万花筒效果并截图

通过shader实现万花筒效果,shader放在文末

由右图到左图,需要去掉背景,只留车的图,并且要从正上方视角看下去的图片才可以产生左侧的效果。

shader参数:

画布比例:显示图片image的比例

图片比例:texture2d图片的比例

行数:是指再画布上显示多少行的万花筒图片

列数:是指再画布上显示多少列的万花筒图片

Tim:通过调节可调节万花筒效果

样式:整数,可调节万花筒样式,一般零即可。

 

通过相机获取图片:

通过一个Quad添加此shader 的Albedo绑定一个RenderTexture,并把此RenderTexture付给车的相机,这样就可以获取持续的万花筒效果,再增加一个正交相机来单独渲染Quad,即可通过相机截图来获取图片

 

Shader "Custom/GaussBlur" {
    Properties{
    _MainTex("Albedo (RGB)", 2D) = "white" {}
    _Plansize("画布比例", float) = 1
    _Texturesize("图片比例", float) = 1
        _SizeZT("缩放zT", Range(0, 20)) = 0
        _Whith("行数", float) = 1
        _Hight("列数", float) = 1
        _Tim("Tim", float) = 1
        _A("透明度", Range(0, 1)) = 1
        _style("样式", int) = 0//0单旋 1散开 2回旋 3慢旋 4散聚
    }
        SubShader{
            Tags{ "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" }
            LOD 100
            ZWrite Off
            Blend SrcAlpha OneMinusSrcAlpha
            Pass{
            CGPROGRAM

    #pragma exclude_renderers gles
    #pragma vertex vert
    #pragma fragment frag
    #include "UnityCG.cginc"

    sampler2D _MainTex;
    int _RepeatNUM;
    float _Centrifuge;
    float _Plansize;
    float _Texturesize;

    float _ElaT;

    float _Dx;
    float _Dy;

    float _Size;
    float _Size2;
    float _SizeZT;
    float K;

    float _Whith;
    float _Hight;
    
    float _JZ, _JZ2, _Tim;
    float _A;
    int _style;
    struct appdata
    {
        float4 vertex : POSITION;
        float2 uv : TEXCOORD0;
    };
    struct v2f {
        float4 pos : SV_POSITION;
        float2 uv : TEXCOORD0;
    };


    v2f vert(appdata_img v)
    {
        v2f o;
        o.pos = UnityObjectToClipPos(v.vertex);
        o.uv = v.texcoord.xy;
        return o;
    }

    float4 Repeatpicture(float2 uv)
    {
        float4 color1 = tex2D(_MainTex, uv);
        if (uv.x<0 || uv.x>1 || uv.y<0 || uv.y>1) {
            color1.a = 0;
        }
        uv = uv + 0.2;
        float4 color2 = tex2D(_MainTex, uv);
        if (uv.x<0 || uv.x>1 || uv.y<0 || uv.y>1) {
            color2.a = 0;
        }
        float4 colorTmp = color1*(1 - color2.a)*color1.a + color2*color2.a;
        return colorTmp;
    }
    float BezierADm(float tim1, float tim2, float na, float nb, float ka, float kb, float Time)//时间从tim1到tim2,数值从na到nb。曲线斜率ka,kb。总时间Time
    {
        float num;
        float L = (tim2 - tim1) / 2.0f;
        if (Time < tim1)
        {
            num = na;
        }
        else
        {
            if (Time <= tim2)
            {
                float t = (Time - tim1) / (tim2 - tim1);
                float3 p0 = float3(tim1, na, 0);
                float3 p1 = float3(L, tan(ka) * L, 0);
                float3 p2 = float3(-L, tan(kb) * L, 0);
                float3 p3 = float3(tim2, nb, 0);
                float3 b0 = float3(0, 0, 0);
                float3 b1 = float3(0, 0, 0);
                float3 b2 = float3(0, 0, 0);
                float3 b3 = float3(0, 0, 0);
                float Ax, Ay, Az, Bx, By, Bz, Cx, Cy, Cz;

                Cx = 3.0 * ((p0.x + p1.x) - p0.x);
                Bx = 3.0 * ((p3.x + p2.x) - (p0.x + p1.x)) - Cx;
                Ax = p3.x - p0.x - Cx - Bx;
                Cy = 3.0 * ((p0.y + p1.y) - p0.y);
                By = 3.0 * ((p3.y + p2.y) - (p0.y + p1.y)) - Cy;
                Ay = p3.y - p0.y - Cy - By;
                Cz = 3.0 * ((p0.z + p1.z) - p0.z);
                Bz = 3.0 * ((p3.z + p2.z) - (p0.z + p1.z)) - Cz;
                Az = p3.z - p0.z - Cz - Bz;
                b0 = p0;
                b1 = p1;
                b2 = p2;
                b3 = p3;
                float t2 = t * t;
                float t3 = t * t * t;
                float x = Ax * t3 + Bx * t2 + Cx * t + p0.x;
                float y = Ay * t3 + By * t2 + Cy * t + p0.y;
                float z = Az * t3 + Bz * t2 + Cz * t + p0.z;
                num = y;

            }
            else
            {
                num = nb;
            }
        }
        return num;
    }
    void funtion() {
        
        if (_style==0) {
            if (_Tim<22) {
                if (_Tim<12) {
                    if (_Tim<2) {
                        _ElaT = 1.056;
                        _Size2 = lerp(0, 0.2, _Tim / 12.0);
                        _Centrifuge = 0.131;
                        _JZ = 0.893;
                        _JZ2 = 0;
                    }
                    else {
                        _ElaT = lerp(1.056, 0.056, (_Tim - 2) / 20.0);
                        _Size2 = lerp(0, 0.2, _Tim / 12.0);
                        _Centrifuge = lerp(0.131, 0.06, (_Tim - 2) / 10.0);
                        _JZ = lerp(0.893, 1, (_Tim - 2) / 10.0);
                        _JZ2 = lerp(0, -0.0019, (_Tim - 2) / 10.0);
                    }
                }
                else {
                    _ElaT = lerp(1.056, 0.056, (_Tim - 2) / 20.0);
                    _Size2 = lerp(0.2, 0, (_Tim - 12) / 12.0);
                    _Centrifuge = lerp(0.06, 0.131, (_Tim - 12) / 10.0);
                    _JZ = lerp(1, 0.893, (_Tim - 12) / 10.0);
                    _JZ2 = lerp(-0.0019, 0, (_Tim - 12) / 10.0);
                }
            }
            else {
                _ElaT = 0.056;
                _Size2 = lerp(0.2, 0, (_Tim - 12) / 12.0);
                _Centrifuge = 0.131;
                _JZ = 0.893;
                _JZ2 = 0;
            }
        }
        else if (_style == 1) {
            if (_Tim<10) {
                _ElaT = 0.3325;
                _Size2 = lerp(0, 0.1, _Tim / 10.0);
                _Centrifuge = 0.17;
                _JZ = 0.82;
            }
            else {
                _ElaT = lerp(0.3325, 0.4, (_Tim - 10.0) / 14.0);
                _Size2 = lerp(0.1, 0.2535, (_Tim - 10.0) / 14.0);
                _Centrifuge = BezierADm(10, 24, 0.17, 2.6, 0, -0.4, _Tim);
                _JZ = 1 - ((_Tim - 10.0 - 100) / -93.46) + 0.89;

            }
        }
        else if (_style == 2) {
            if (_Tim<22) {
                if (_Tim<12) {
                    if (_Tim<2) {
                        _ElaT = 1.056;
                        //_Size2 = lerp(0, 0.2, _Tim / 12.0);
                        _Size2 = BezierADm(0, 12, 0, 0.2, 0.02, 0, _Tim);
                        _Centrifuge = 0.131;
                        _JZ = 0.893;
                        _JZ2 = 0;
                    }
                    else {
                        //_ElaT = lerp(1.056, 0.056, (_Tim - 2) / 20.0);
                        _ElaT = BezierADm(2, 12, 1.056, 0.5, 0, 0, _Tim);
                        //_Size2 = lerp(0, 0.2, _Tim / 12.0);
                        _Size2 = BezierADm(0, 12, 0, 0.2, 0.02, 0, _Tim);
                        _Centrifuge = lerp(0.131, 0.06, (_Tim - 2) / 10.0);
                        _JZ = lerp(0.893, 1, (_Tim - 2) / 10.0);
                        _JZ2 = lerp(0, -0.0019, (_Tim - 2) / 10.0);
                    }
                }
                else {
                    //_ElaT = lerp(1.056, 0.056, (_Tim - 2) / 20.0);
                    _ElaT = BezierADm(12, 22, 0.5, 1.056, 0, 0, _Tim);
                    //_Size2 = lerp(0.2, 0, (_Tim - 12) / 12.0);
                    _Size2 = BezierADm(12, 24, 0.2, 0, 0, 0.02, _Tim);
                    _Centrifuge = lerp(0.06, 0.131, (_Tim - 12) / 10.0);
                    _JZ = lerp(1, 0.893, (_Tim - 12) / 10.0);
                    _JZ2 = lerp(-0.0019, 0, (_Tim - 12) / 10.0);
                }
            }
            else {
                _ElaT = 0.056;
                //_Size2 = lerp(0.2, 0, (_Tim - 12) / 12.0);
                _Size2 = BezierADm(12, 24, 0.2, 0, 0, 0.02, _Tim);
                _Centrifuge = 0.131;
                _JZ = 0.893;
                _JZ2 = 0;
            }
        }
        else if (_style == 3) {
            if (_Tim<22) {
                if (_Tim<12) {
                    if (_Tim<2) {
                        _ElaT = BezierADm(0, 24, 1.056, 0.8, 0, 0, _Tim);
                        _Size2 = BezierADm(0, 12, 0, 0.2, 0.02, 0, _Tim);
                        _Centrifuge = 0.131;
                        _JZ = 0.893;
                        _JZ2 = 0;
                    }
                    else {
                        _ElaT = BezierADm(0, 24, 1.056, 0.8, 0, 0, _Tim);
                        _Size2 = BezierADm(0, 12, 0, 0.2, 0.02, 0, _Tim);
                        _Centrifuge = lerp(0.131, 0.06, (_Tim - 2) / 10.0);
                        _JZ = lerp(0.893, 1, (_Tim - 2) / 10.0);
                        _JZ2 = lerp(0, -0.0019, (_Tim - 2) / 10.0);
                    }
                }
                else {
                    _ElaT = BezierADm(0, 24, 1.056, 0.8, 0, 0, _Tim);
                    _Size2 = BezierADm(12, 24, 0.2, 0, 0, 0.02, _Tim);
                    _Centrifuge = lerp(0.06, 0.131, (_Tim - 12) / 10.0);
                    _JZ = lerp(1, 0.893, (_Tim - 12) / 10.0);
                    _JZ2 = lerp(-0.0019, 0, (_Tim - 12) / 10.0);
                }
            }
            else {
                _ElaT = BezierADm(0, 24, 1.056, 0.8, 0, 0, _Tim);
                _Size2 = BezierADm(12, 24, 0.2, 0, 0, 0.02, _Tim);
                _Centrifuge = 0.131;
                _JZ = 0.893;
                _JZ2 = 0;
            }
        }
        else if (_style == 4) {
            float _Tt = 24 - _Tim;
            if (_Tt<10) {
                _ElaT = 0.3325;
                _Size2 = lerp(0, 0.1, _Tt / 10.0);
                _Centrifuge = 0.17;
                _JZ = 0.82;
            }
            else {
                _ElaT = lerp(0.3325, 0.4, (_Tt - 10.0) / 14.0);
                _Size2 = lerp(0.1, 0.2535, (_Tt - 10.0) / 14.0);
                _Centrifuge = BezierADm(10, 24, 0.17, 2.6, 0, -0.4, _Tt);
                _JZ = 1 - ((_Tt - 10.0 - 100) / -93.46) + 0.89;

            }
        }
        else{
            if (_Tim<22) {
                if (_Tim<12) {
                    if (_Tim<2) {
                        _ElaT = 1.056;
                        _Size2 = lerp(0, 0.2, _Tim / 12.0);
                        _Centrifuge = 0.131;
                        _JZ = 0.893;
                        _JZ2 = 0;
                    }
                    else {
                        _ElaT = lerp(1.056, 0.056, (_Tim - 2) / 20.0);
                        _Size2 = lerp(0, 0.2, _Tim / 12.0);
                        _Centrifuge = lerp(0.131, 0.06, (_Tim - 2) / 10.0);
                        _JZ = lerp(0.893, 1, (_Tim - 2) / 10.0);
                        _JZ2 = lerp(0, -0.0019, (_Tim - 2) / 10.0);
                    }
                }
                else {
                    _ElaT = lerp(1.056, 0.056, (_Tim - 2) / 20.0);
                    _Size2 = lerp(0.2, 0, (_Tim - 12) / 12.0);
                    _Centrifuge = lerp(0.06, 0.131, (_Tim - 12) / 10.0);
                    _JZ = lerp(1, 0.893, (_Tim - 12) / 10.0);
                    _JZ2 = lerp(-0.0019, 0, (_Tim - 12) / 10.0);
                }
            }
            else {
                _ElaT = 0.056;
                _Size2 = lerp(0.2, 0, (_Tim - 12) / 12.0);
                _Centrifuge = 0.131;
                _JZ = 0.893;
                _JZ2 = 0;
            }
        }

    }

    //自转
    float2 RotUV(float2 uv,float _El)
    {
        float _Px = 0.5;
        float _Py = 0.5;
        float _Ela = (_El+0.09)*6.28318;
        float2 uv1 = float2 ((uv.x - _Px)*cos(_Ela) - (uv.y - _Py)*sin(_Ela) + _Px, (uv.x - _Px)*sin(_Ela) + (uv.y - _Py)*cos(_Ela) + _Py);
        return uv1;
    }
    //分辨率自适应计算
    float2 resolutionUV(float2 uv,float P,float T)
    {
        float k = P/T;
        float2 uv1;
        
        if (k>1) {
            uv1 = float2((uv.x - 0.5) * k + 0.5, uv.y);
        }
        else {
            uv1 = float2(uv.x, (uv.y - 0.5) / k + 0.5);
        }
        return uv1;
    }
    //平移
    float2 translationUV(float2 uv,float x,float y)
    {
        float2 uv1 = float2(uv.x - x, uv.y - y);
        return uv1;
    }
    
    //缩放
    float2 scalingUV(float2 uv,float s) {
        float2 uv1 = float2((uv.x - 0.5)/s + 0.5, (uv.y - 0.5)/s + 0.5);
        return uv1;
    }

    //重叠
    float4 Repeatpicture2(float2 uvv)
    {
        float4 colorTmp = (0, 0, 0, 0);
        for (int i = 0; i < _RepeatNUM; i++) {
            float ll= _JZ*6.28+2.15;
            float Lx;
            float Ly;

            Lx = (sin((i / (float)_RepeatNUM)*6.28 + ll)*(10 * _Centrifuge) / 100.0)/*+abs ((sin((i / (float)_RepeatNUM)*6.28 + ll)*(10 * 0.2) / 100.0))*01.55*/;
            Ly = (cos((i / (float)_RepeatNUM)*6.28 + ll)*(10 * _Centrifuge) / 100.0)/*+ abs((cos((i / (float)_RepeatNUM)*6.28 + ll)*(10 * 0.2) / 100.0))*01.55*/;
            float sas;
            if(i>5){
                sas = 0;
            }else{
                sas = _JZ2;
            }
            sas = _JZ2;
            float2 uv = translationUV(resolutionUV(RotUV(scalingUV(translationUV(uvv.xy, Lx, Ly), _Size), (_ElaT- sas*(_RepeatNUM-i))+i/ (float)_RepeatNUM),1, _Texturesize),_Dx, _Dy);
            float4 color = tex2D(_MainTex, uv);
            if (uv.x<0 || uv.x>1 || uv.y<0 || uv.y>1) {
                color.a = 0;
            }
            colorTmp = colorTmp*(1 - color.a)*colorTmp.a + color*color.a;
        }
        return colorTmp;
    }
    //重叠fb
    float4 Repeatpicture3(float2 uvv)
    {
        float4 colorTmp = (0, 0, 0, 0);
        for (int i = 1; i < _RepeatNUM; i++) {
            float ll = 3.28;
            float Lx = (sin((i / (float)_RepeatNUM)*6.28 + ll)*(i*_Centrifuge) / 100.0);
            float Ly = (cos((i / (float)_RepeatNUM)*6.28 + ll)*(i*1.3*_Centrifuge) / 100.0);
            float2 uv = translationUV(resolutionUV(RotUV(scalingUV(translationUV(uvv.xy, Lx, Ly), _Size),_ElaT + i /(float)_RepeatNUM), 1, _Texturesize), _Dx, _Dy);
            float4 color = tex2D(_MainTex, uv);
            if (uv.x<0 || uv.x>1 || uv.y<0 || uv.y>1) {
                color.a = 0;
            }
            colorTmp = colorTmp*(1 - color.a)*colorTmp.a + color*color.a;
        }
        return colorTmp;
    }
    //四面镜像
    float2 Fourimages(float2 uv) {
        float2 uv1 = abs(uv.xy - 0.5) * 2;
        return uv1;
    }
    //行列变换
    float2 arrayUV(float2 uv,float w,float h) {

        float2 uv1 = abs(float2(uv.x % (1 / w), uv.y % (1 / h)));
        float2 uv2 = float2(uv1.x + (w - 1) / (2 * w), uv1.y + (h - 1) / (2 * h));
        return uv2;
    }
    
    
    half4 frag(v2f i) : SV_Target
    {
        _Tim = clamp(_Tim,0,24);
    
    _RepeatNUM = 11;//重复数
    _Dy = 0;//Local位移y
    
    funtion();
    _Size = _Size2;
    
    
    float2 uv = scalingUV(resolutionUV(scalingUV(translationUV(Fourimages(arrayUV(i.uv.xy, _Whith, _Hight)), -0.5, -0.5), 2),_Plansize,1), _SizeZT);
    //float2 uv = i.uv.xy;
    


    float4 color = Repeatpicture2(uv);
    //float4 color = tex2D(_MainTex, uv);

    if (uv.x<0||uv.x>1||uv.y<0||uv.y>1) {
        color.a = 0;
    }
    return fixed4(color.r, color.g, color.b, color.a*_A);
        
    }
        ENDCG
    }
    }
        FallBack "Diffuse"
}

 

posted @ 2018-12-14 11:17  81192  阅读(930)  评论(0编辑  收藏  举报