smkplus / ShaderMan

Convert ShaderToy to Unity HLSL/CG
https://smkplus.github.io/ShaderMan.io
MIT License
1.4k stars 197 forks source link

I want run this shader in Unity2019.3, but unfortunately it doesnot work. #23

Open nakamura343 opened 4 years ago

nakamura343 commented 4 years ago

https://www.shadertoy.com/view/wlXBWM

Please m( )m

smkplus commented 4 years ago

Hi, I tried to convert it but It's blue!

image

Shader "Hidden/Test"
{
    Properties
    {
        iChannel0 ("iChannel0", 2D) = "white" {}
        iChannel1 ("iChannel1", 2D) = "white" {}
    }
    SubShader
    {
        // No culling or depth
        Cull Off ZWrite Off ZTest Always

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

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

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                return o;
            }

            sampler2D iChannel0;
            sampler2D iChannel1;

             float pi = 3.14159265358979323;

float dot2( in fixed3 v ) { return dot(v,v); }

fixed3 mod(fixed3 x, fixed3 y)
{
return x - y * floor(x/y);
}

// Originally from https://www.shadertoy.com/view/llcfRf
// Modified to remove the caps and return the whole intersection interval.
fixed2 iCappedCone2( in fixed3  ro, in fixed3  rd, 
                  in fixed3  pa, in fixed3  pb, 
                  in float ra, in float rb )
{
    fixed3  ba = pb - pa;
    fixed3  oa = ro - pa;
    fixed3  ob = ro - pb;

    float m0 = dot(ba,ba);
    float m1 = dot(oa,ba);
    float m3 = dot(rd,ba);

    // body
    float m4 = dot(rd,oa);
    float m5 = dot(oa,oa);
    float rr = ra - rb;
    float hy = m0 + rr*rr;

    float k2 = m0*m0    - m3*m3*hy;
    float k1 = m0*m0*m4 - m1*m3*hy + m0*ra*(rr*m3*1.0        );
    float k0 = m0*m0*m5 - m1*m1*hy + m0*ra*(rr*m1*2.0 - m0*ra);

    float h = k1*k1 - k2*k0;
    if( h<0.0 ) return fixed2(-1.0,-1.0);

    return ((fixed2(-1, +1) * sqrt(h)) - k1) / k2;
}

// Originally from https://www.shadertoy.com/view/4lcSRn
// Modified to remove the caps and return the whole intersection interval.
fixed2 iCylinder2( in fixed3 ro, in fixed3 rd, 
                in fixed3 pa, in fixed3 pb, in float ra ) // point a, point b, radius
{
    // center the cylinder, normalize axis
    fixed3 cc = 0.5*(pa+pb);
    float ch = length(pb-pa);
    fixed3 ca = (pb-pa)/ch;
    ch *= 0.5;

    fixed3  oc = ro - cc;

    float card = dot(ca,rd);
    float caoc = dot(ca,oc);

    float a = 1.0 - card*card;
    float b = dot( oc, rd) - caoc*card;
    float c = dot( oc, oc) - caoc*caoc - ra*ra;
    float h = b*b - a*c;
    if( h<0.0 ) return fixed2(-1.0,-1.0);

    return ((fixed2(-1, +1) * sqrt(h)) - b) / a;
}

float dofLine(fixed3 c0, fixed3 c1, float ra, fixed3 p0, fixed3 p1)
{
    float dlen = length(p1 - p0);
    fixed3 dir = (p1 - p0) / dlen;

    // Test for intersection of the line segment with the cone of defocused rays.

    fixed2 res = iCappedCone2(p0, dir, c0, c1, ra, 0.);

    if(res.y < 0. || res.x > dlen)
    {
        // To avoid rendering subpixel-sized lines which would end up being heavily under-sampled,
        // the center of the defocus cone is modelled as a thick cylinder.

        fixed2 res2 = iCylinder2(p0, dir, c0, c1, 2e-3);

        if(res2.y > res2.x && res2.y > 0. && res2.x < dlen)
        {
            res.x = min(res.x, res2.x);
            res.y = max(res.y, res2.y);
        }

        if(res.y < 0. || res.x > dlen)
            return 0.;
    }

    fixed3 q0 = p0 + dir * res.x;
    fixed3 q1 = p0 + dir * res.y;

    // Contribution is modelled somewhat on the usual monte carlo raytracing.
    // This amounts to integrating coverage of a varying disc by a small point.
    // Function to integrate is: 1 / (pi * ((a * x + b) ^ 2))
    // Integral is: -1 / (pi * a * a * x + pi * a * b)

    fixed3 cd = c1 - c0;
    float cl2 = ra / dot(cd, cd);

    float z0 = dot(q0 - c1, cd);
    float z1 = dot(q1 - c1, cd);

    float a = cl2 * (z1 - z0);
    float b = cl2 * z0;

    float i0 = pi * a * b;
    float i1 = pi * a * (a + b);

    i0 = 1e-4 / max(1e-10, abs(i0)) * sign(i0);
    i1 = 1e-4 / max(1e-10, abs(i1)) * sign(i1);

    return min(1., abs(i1 - i0));
}

float heightmap(fixed2 uv)
{
    return (tex2D(iChannel0, uv.yx / 256.).r - .1) * 2.;
}

fixed3x3 rotX(float a)
{
    return fixed3x3(1., 0., 0., 0., cos(a), sin(a), 0., -sin(a), cos(a));
}

fixed3x3 rotY(float a)
{
    return fixed3x3(cos(a), 0., sin(a), 0., 1., 0., -sin(a), 0., cos(a));
}

fixed3x3 rotZ(float a)
{
    return fixed3x3(cos(a), sin(a), 0., -sin(a), cos(a), 0., 0., 0., 1.);
}

            fixed4 frag (v2f i) : SV_Target
            {
    //fixed2 uv = fragCoord / iResolution.xy * 2. - 1.;
    fixed2 uv = i.uv*2.0-1.0;
//    uv.x *= iResolution.x / iResolution.y;

    fixed3 ro = fixed3(-0.2, 1., 0.);
    fixed3 focus = ro + fixed3(uv.xy, -3.5);

    float ra = .08;
    float t = _Time.y / 2.;

    fixed3x3 m = rotX(.23);

    fixed3 col = fixed3(0,0,0);

    // Landscape.

    fixed4 fragColor;

    for(int y = -14; y < -1; ++y)
    {
        fixed3 ps[4];
        for(int x = -6; x < 6; ++x)
        {            
            ps[1] = ps[0];
            ps[3] = ps[2];
            ps[0] = fixed3(float(x + 0), 0, float(y + 0)) / 2.;
            ps[2] = fixed3(float(x + 0), 0, float(y + 1)) / 2.;

            ps[0].y = heightmap(ps[0].xz + fixed2(0., -floor(t))) + cos(_Time.y / 3.) * .1;
            ps[0].z += frac(t);
            ps[0] = mul(m , ps[0]);

            ps[2].y = heightmap(ps[2].xz + fixed2(0., -floor(t))) + cos(_Time.y / 3.) * .1;
            ps[2].z += frac(t);
            ps[2] = mul(m , ps[2]);

            if(x > -6)
            {
                if(abs(x) > -y / 2)
                    continue;

                float f = 1. - smoothstep(2.8, 3.2,
                          abs(max(abs(ps[0].z + 3.), max(abs(ps[1].z + 3.),
                          max(abs(ps[2].z + 3.), abs(ps[3].z + 3.))))));

                if(f > 0.01)
                {
                    col += dofLine(ro, focus, ra, ps[0], ps[1]) * f * .5;
                    col += dofLine(ro, focus, ra, ps[1], ps[3]) * f * .5;
                }
            }
        }
    }

    // Dust particles.

    for(int i = 0; i < 32; ++i)
    {
        fixed3 dotp = cos(fixed3(19, 129, 99) * (float(i))) * fixed3(2., 0.4, 5.) + fixed3(0, 0.4, 0.);
        dotp.z += t;
        dotp.z = mod(dotp.z, 5.) - 6.;
        dotp = mul(m , dotp);
        float f = 1. - smoothstep(1.5, 2., abs(dotp.z + 3.));
        if(f > 0.01)
            col += dofLine(ro, focus, ra, dotp, dotp + 1e-4) * f * fixed3(1,.8,.2);
    }

    col = pow(col + (1. - smoothstep(0., 3.8, length(uv))) * .1, fixed3(1.8, 1.4, 1));
    fragColor.rgb = col * 2.;

    // Gamma correction

    // fragColor.rgb = pow(min(fragColor.rgb, 1.), fixed3(1.,1.,1.)*1. / 2.2) +
    //      texelFetch(iChannel1, ifixed2(fragCoord) & 1023, 0).r / 100.;
    fragColor.rgb = pow(min(fragColor.rgb, 1.), fixed3(1.,1.,1.)*1. / 2.2);
    fragColor.a = 1.;
        return fragColor;

            }
            ENDCG
        }
    }
}