smkplus / ShaderMan

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

Would It be Possible to convert this shader? #18

Open FalseHope00 opened 4 years ago

FalseHope00 commented 4 years ago

How Hard Would It Be To COnvert This Shader https://www.shadertoy.com/view/Xtf3Rn i get stuck at lines such as this: p.xz*=fixed2x2(-0.416,-0.91,0.91,-0.416); Also when using the IO version i get this error when ported to unity float3 lightdir=normalize(vec3(0.5,-0.3,-1.)); unity does not like this line Unity Version 2017.4.28.f1

smkplus commented 4 years ago

Hi dear friend currently I'm busy I will answer as soon as possible

smkplus commented 4 years ago

p.xz*=fixed2x2(-0.416,-0.91,0.91,-0.416);

p.xz = mul(p.xz,fixed2x2(-0.416,-0.91,0.91,-0.416);

Hi I just converted syntax I haven't enough time to fix this you should use a raymarching shader


Shader "Hidden/JustConvertSyntax"
{
    Properties
    {
        _MainTex ("Texture", 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 _MainTex;

            #define ENABLE_HARD_SHADOWS // turn off to enable faster AO soft shadows 
//#define ENABLE_VIBRATION
#define ENABLE_POSTPROCESS // Works better on window view rather than full screen

#define RAY_STEPS 70
#define SHADOW_STEPS 50
#define LIGHT_COLOR float3(.85,.9,1.)
#define AMBIENT_COLOR float3(.8,.83,1.)
#define FLOOR_COLOR float3(1.,.7,.9)
#define ENERGY_COLOR float3(1.,.7,.4)
#define BRIGHTNESS .9
#define GAMMA 1.3
#define SATURATION .85

#define detail .00005
#define t _Time.y*.25

float3 lightdir=normalize(float3(0.5,-0.3,-1.));
float3 ambdir=normalize(float3(0.,0.,1.));
const float3 origin=float3(0.,3.11,0.);
float3 energy=float3(0.01,0.01,0.01);
#ifdef ENABLE_VIBRATION
float vibration=sin(_Time.y*60.)*.0013;
#else
float vibration=0.;
#endif
float det=0.0;
float3 pth1;

float2x2 rot(float a) {
    return float2x2(cos(a),sin(a),-sin(a),cos(a));  
}

float3 path(float ti) {
return float3(sin(ti),.3-sin(ti*.632)*.3,cos(ti*.5))*.5;
}

float Sphere(float3 p, float3 rd, float r){//A RAY TRACED SPHERE
    float b = dot( -p, rd );
    float inner = b * b - dot( p, p ) + r * r;
    if( inner < 0.0 ) return -1.0;
    return b - sqrt( inner );
}

float2 de(float3 pos) {
    float hid=0.;
    float3 tpos=pos;
    tpos.xz=abs(.5-fmod(tpos.xz,1.));
    float4 p=float4(tpos,1.);
    float y=max(0.,.35-abs(pos.y-3.35))/.35;
    for (int i=0; i<7; i++) {//LOWERED THE ITERS
        p.xyz = abs(p.xyz)-float3(-0.02,1.98,-0.02);
        p=p*(2.0+vibration*y)/clamp(dot(p.xyz,p.xyz),.4,1.)-float4(0.5,1.,0.4,0.);
        p.xz = mul(p.xz,float2x2(-0.416,-0.91,0.91,-0.416));
    }
    float fl=pos.y-3.013;
    float fr=(length(max(abs(p.xyz)-float3(0.1,5.0,0.1),float3(0,0,0)))-0.05)/p.w;//RETURN A RRECT
    //float fr=length(p.xyz)/p.w;
    float d=min(fl,fr);
    d=min(d,-pos.y+3.95);
    if (abs(d-fl)<.001) hid=1.;
    return float2(d,hid);
}

float3 normal(float3 p) {
    float3 e = float3(0.0,det,0.0);

    return normalize(float3(
            de(p+e.yxx).x-de(p-e.yxx).x,
            de(p+e.xyx).x-de(p-e.xyx).x,
            de(p+e.xxy).x-de(p-e.xxy).x
            )
        );  
}

float shadow(float3 pos, float3 sdir) {//THIS ONLY RUNS WHEN WITH HARD SHADOWS
    float sh=1.0;
    float totdist =2.0*det;
    float dist=10.;
    float t1=Sphere((pos-.005*sdir)-pth1,-sdir,0.015);
    if (t1>0. && t1<.5) {
        float3 sphglowNorm=normalize(pos-t1*sdir-pth1);
        sh=1.-pow(max(.0,dot(sphglowNorm,sdir))*1.2,3.);
    } 
        for (int steps=0; steps<SHADOW_STEPS; steps++) {
            if (totdist<.6 && dist>detail) {
                float3 p = pos - totdist * sdir;
                dist = de(p).x;
                sh = min( sh, max(50.*dist/totdist,0.0) );
                totdist += max(.01,dist);
            }
        }

    return clamp(sh,0.1,1.0);
}

float calcAO( const float3 pos, const float3 nor ) {
    float aodet=detail*40.;
    float totao = 0.0;
    float sca = 14.0;
    for( int aoi=0; aoi<5; aoi++ ) {
        float hr = aodet*float(aoi*aoi);
        float3 aopos =  nor * hr + pos;
        float dd = de( aopos ).x;
        totao += -(dd-hr)*sca;
        sca *= 0.7;
    }
    return clamp( 1.0 - 5.0*totao, 0., 1.0 );
}

float _texture(float3 p) {
    p=abs(.5-frac(p*10.));
    float3 c=float3(3.,3.,3.);
    float es, l=es=0.;
    for (int i = 0; i < 10; i++) { 
            p = abs(p + c) - abs(p - c) - p; 
            p/= clamp(dot(p, p), .0, 1.);
            p = p* -1.5 + c;
            if ( fmod(float(i), 2.) < 1. ) { 
                float pl = l;
                l = length(p);
                es+= exp(-1. / abs(l - pl));
            }
    }
    return es;
}

float3 light(in float3 p, in float3 dir, in float3 n, in float hid) {//PASSING IN THE NORMAL
    #ifdef ENABLE_HARD_SHADOWS
        float sh=shadow(p, lightdir);
    #else
        float sh=calcAO(p,-2.5*lightdir);//USING AO TO MAKE VERY SOFT SHADOWS
    #endif
    float ao=calcAO(p,n);
    float diff=max(0.,dot(lightdir,-n))*sh;
    float y=3.35-p.y;
    float3 amb=max(.5,dot(dir,-n))*.5*AMBIENT_COLOR;
    if (hid<.5) {
        amb+=max(0.2,dot(float3(0.,1.,0.),-n))*FLOOR_COLOR*pow(max(0.,.2-abs(3.-p.y))/.2,1.5)*2.;
        amb+=energy*pow(max(0.,.4-abs(y))/.4,2.)*max(0.2,dot(float3(0.,-sign(y),0.),-n))*2.;
    }
    float3 r = reflect(lightdir,n);
    float spec=pow(max(0.,dot(dir,-r))*sh,10.);
    float3 col;
    float energysource=pow(max(0.,.04-abs(y))/.04,4.)*2.;
    if (hid>1.5) {col=float3(1.,1.,1.); spec=spec*spec;}
    else{
        float k=_texture(p)*.23+.2; 
        k=min(k,1.5-energysource);
        col=lerp(float3(k,k*k,k*k*k),float3(k,k,k),.3);
        if (abs(hid-1.)<.001) col*=FLOOR_COLOR*1.3;
    }
    col=col*(amb+diff*LIGHT_COLOR)+spec*LIGHT_COLOR;    
    if (hid<.5) { 
        col=max(col,energy*2.*energysource);
    }
    col*=min(1.,ao+length(energy)*.5*max(0.,.1-abs(y))/.1);
    return col;
}

float3 raymarch(in float3 from, in float3 dir) 

{
    float ey=fmod(t*.5,1.);
    float glow,eglow,ref,sphdist,totdist=glow=eglow=ref=sphdist=0.;
    float2 d=float2(1.,0.);
    float3 p, col=float3(0.,0.,0.);
    float3 origdir=dir,origfrom=from,sphNorm;

    //FAKING THE SQUISHY BALL BY MOVING A RAY TRACED BALL
    float3 wob=cos(dir*500.0*length(from-pth1)+(from-pth1)*250.+_Time.y*10.)*0.0005;
    float t1=Sphere(from-pth1+wob,dir,0.015);
    float tg=Sphere(from-pth1+wob,dir,0.02);
    if(t1>0.){
        ref=1.0;from+=t1*dir;sphdist=t1;
        sphNorm=normalize(from-pth1+wob);
        dir=reflect(dir,sphNorm);
    } 
    else if (tg>0.) { 
        float3 sphglowNorm=normalize(from+tg*dir-pth1+wob);
        glow+=pow(max(0.,dot(sphglowNorm,-dir)),5.);
    };

    for (int i=0; i<RAY_STEPS; i++) {
        if (d.x>det && totdist<3.0) {
            p=from+totdist*dir;
            d=de(p);
            det=detail*(1.+totdist*60.)*(1.+ref*5.);
            totdist+=d.x; 
            energy=ENERGY_COLOR*(1.5+sin(_Time.y*20.+p.z*10.))*.25;
            if(d.x<0.015)glow+=max(0.,.015-d.x)*exp(-totdist);
            if (d.y<.5 && d.x<0.03){//ONLY DOING THE GLOW WHEN IT IS CLOSE ENOUGH
                float glw=min(abs(3.35-p.y-ey),abs(3.35-p.y+ey));//2 glows at once
                eglow+=max(0.,.03-d.x)/.03*
                (pow(max(0.,.05-glw)/.05,5.)
                +pow(max(0.,.15-abs(3.35-p.y))/.15,8.))*1.5;
            }
        }
    }
    float l=pow(max(0.,dot(normalize(-dir.xz),normalize(lightdir.xz))),2.);
    l*=max(0.2,dot(-dir,lightdir));
    float3 backg=.5*(1.2-l)+LIGHT_COLOR*l*.7;
    backg*=AMBIENT_COLOR;
    if (d.x<=det) {
        float3 norm=normal(p-abs(d.x-det)*dir);//DO THE NORMAL CALC OUTSIDE OF LIGHTING (since we already have the sphere normal)
        col=light(p-abs(d.x-det)*dir, dir, norm, d.y)*exp(-.2*totdist*totdist); 
        col = lerp(col, backg, 1.0-exp(-1.*pow(totdist,1.5)));
    } else { 
        col=backg;
    }
    float3 lglow=LIGHT_COLOR*pow(l,30.)*.5;
    col+=glow*(backg+lglow)*1.3;
    col+=pow(eglow,2.)*energy*.015;
    col+=lglow*min(1.,totdist*totdist*.3);
    if (ref>0.5) {
        float3 sphlight=light(origfrom+sphdist*origdir,origdir,sphNorm,2.);
        col=lerp(col*.3+sphlight*.7,backg,1.0-exp(-1.*pow(sphdist,1.5)));
    }
    return col; 
}

float3 move(inout float2x2 rotview1,inout float2x2 rotview2) {
    float3 go=path(t);
    float3 adv=path(t+.7);
    float3 adfloat=normalize(adv-go);
    float an=atan2(adfloat.x,adfloat.z);
    rotview1=float2x2(cos(an),sin(an),-sin(an),cos(an));
          an=adfloat.y*1.7;
    rotview2=float2x2(cos(an),sin(an),-sin(an),cos(an));
    return go;
}

            fixed4 frag (v2f i) : SV_Target
            {
pth1 = path(t+.3)+origin+float3(0.,.01,0.);
    float2 uv = i.uv.xy*2-1;
    float2 uv2=uv;
#ifdef ENABLE_POSTPROCESS
    uv*=1.+pow(length(uv2*uv2*uv2*uv2),4.)*.07;
#endif
    // uv.y*=iResolution.y/iResolution.x;
    // float2 mouse=(iMouse.xy/iResolution.xy-.5)*3.;
    float2 mouse = float2(0,0);
    // if (iMouse.z<1.) mouse=float2(0.,0.);
    float2x2 rotview1, rotview2;
    float3 from=origin+move(rotview1,rotview2);
    float3 dir=normalize(float3(uv*.8,1.));
    dir.yz = mul(dir.yz,rot(mouse.y));
    dir.xz = mul(dir.xz,rot(mouse.x));
    dir.yz = mul(dir.yz,rotview2);
    dir.xz =mul(dir.xz,rotview1);
    float3 color=raymarch(from,dir); 
    color=clamp(color,float3(.0,.0,.0),float3(1.,1.,1.));
    color=pow(color,float3(GAMMA,GAMMA,GAMMA))*BRIGHTNESS;
    color=lerp(float3(length(color),length(color),length(color)),color,SATURATION);
#ifdef ENABLE_POSTPROCESS
    float3 rain=pow(tex2D(_MainTex,uv2+_Time.y*7.25468).rgb,float3(1.5,1.5,1.5));
    color=lerp(rain,color,clamp(_Time.y*.5-.5,0.,1.));
    color*=1.-pow(length(uv2*uv2*uv2*uv2)*1.1,6.);
    // uv2.y *= iResolution.y / 360.0;
    color.r*=(.5+abs(.5-fmod(uv2.y     ,.021)/.021)*.5)*1.5;
    color.g*=(.5+abs(.5-fmod(uv2.y+.007,.021)/.021)*.5)*1.5;
    color.b*=(.5+abs(.5-fmod(uv2.y+.014,.021)/.021)*.5)*1.5;
    color*=.9+rain*.35;
#endif
    return float4(color,1);
            }
            ENDCG
        }
    }
}

raymarching example:


// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Apollonian"
{
        Properties{
            //_iMouse("Mouse",Vector) = (0,0,0,0)

        }
    Subshader
    {
        Pass
        {
            CGPROGRAM
            #pragma vertex vertex_shader
            #pragma fragment pixel_shader
            #pragma target 3.0

            struct custom_type
            {
                float4 screen_vertex : SV_POSITION;
                float3 world_vertex : TEXCOORD1;
                float2 uv : TEXCOORD2;
            };
        float2 fragCoordinate;              
float3 equirectangularRay(){
    float2 texCoord = fragCoordinate.xy; 
    float2 thetaphi = ((texCoord * 2.0) - float2(1,1)) * float2(3.1415926535897932384626433832795, 1.5707963267948966192313216916398); 
    float3 rayDirection = float3(cos(thetaphi.y) * cos(thetaphi.x), sin(thetaphi.y), cos(thetaphi.y) * sin(thetaphi.x));

    return rayDirection;
}

            #define AA 1
            float4 orb;         
            float map (float3 p,float s)
            {
                    float scale = 1.0;
    orb = float4(1000.0,1000.0,1000.0,1000.0); 

    for( int i=0; i<8;i++ )
    {
        p = -1.0 + 2.0*frac(0.5*p+0.5);

        float r2 = dot(p,p);

        orb = min( orb, float4(abs(p),r2) );

        float k = s/r2;
        p     *= k;
        scale *= k;
    }

    return 0.25*abs(p.y)/scale;         }

            float ambient_occlusion( float3 pos, float3 nor )
            {
                float occ = 0.0;
                float sca = 1.0;
                for( int i=0; i<5; i++ )
                {
                    float hr = 0.01 + 0.12*float(i)/4.0;
                    float3 aopos =  nor * hr + pos;
                    float dd = map( aopos, 0);
                    occ += -(dd-hr)*sca;
                    sca *= 0.95;
                }
                return clamp( 1.0 - 3.0*occ, 0.0, 1.0 );    
            }

            float3 calcNormal( in float3 pos, in float t, in float s )
            {
                float precis = 0.001 * t;

                float2 e = float2(1.0,-1.0)*precis;
                return normalize( e.xyy*map( pos + e.xyy, s ) + 
                                e.yyx*map( pos + e.yyx, s ) + 
                                e.yxy*map( pos + e.yxy, s ) + 
                                e.xxx*map( pos + e.xxx, s ) );
            }

            float3 lighting (float3 p)
            {
                float3 AmbientLight = float3 (0.1,0.1,0.1);
                float3 LightDirection = normalize(float3 (4.0,10.0,-10.0));
                float3 LightColor = float3 (1.0,1.0,1.0);
                float3 NormalDirection = calcNormal(p,0,0);//xxx
                return (max(dot(LightDirection, NormalDirection),0.0) * LightColor + AmbientLight)*ambient_occlusion(p,NormalDirection);
            }

                float trace( in float3 ro, in float3 rd, float s )
                {
                    float maxd = 30.0;
                    float t = 0.01;
                    for( int i=0; i<200; i++ )
                    {
                        float precis = 0.001 * t;

                        float h = map( ro+rd*t, s );
                        if( h<precis||t>maxd ) break;
                        t += h;
                    }

                    if( t>maxd ) t=-1.0;
                    return t;
                }

            float4 _iMouse;

            float3 render( in float3 ro, in float3 rd, in float anim )
            {
                               // trace 
    float3 col = float3(0.0,0.0,0.0);
    float t = trace( ro, rd, anim );
    if( t>0.0 )
    {
        float4 tra = orb;
        float3 pos = ro + t*rd;
        float3 nor = calcNormal( pos, t, anim );

        // lighting
        float3  light1 = float3(  0.577, 0.577, -0.577 );
        float3  light2 = float3( -0.707, 0.000,  0.707 );
        float key = clamp( dot( light1, nor ), 0.0, 1.0 );
        float bac = clamp( 0.2 + 0.8*dot( light2, nor ), 0.0, 1.0 );
        float amb = (0.7+0.3*nor.y);
        float ao = pow( clamp(tra.w*2.0,0.0,1.0), 1.2 );

        float3 brdf  = 1.0*float3(0.40,0.40,0.40)*amb*ao;
        brdf += 1.0*float3(1.00,1.00,1.00)*key*ao;
        brdf += 1.0*float3(0.40,0.40,0.40)*bac*ao;

        // material     
        float3 rgb = float3(1.0,1.0,1.0);
        rgb = lerp( rgb, float3(1.0,0.80,0.2), clamp(6.0*tra.y,0.0,1.0) );
        rgb = lerp( rgb, float3(1.0,0.55,0.0), pow(clamp(1.0-2.0*tra.z,0.0,1.0),8.0) );

        // color
        col = rgb*brdf*exp(-0.2*t); 
            }
                    return sqrt(col);   
            }

            custom_type vertex_shader (float4 vertex : POSITION,float2 uv:TEXCOORD1)
            {
                custom_type vs;
                vs.screen_vertex = UnityObjectToClipPos (vertex);
                vs.world_vertex = mul (unity_ObjectToWorld, vertex);
                vs.uv = uv;
                return vs;
            }

            float4 pixel_shader (custom_type ps ) : SV_TARGET
            {
                float iTime = _Time.y;
                fragCoordinate = ps.uv;
                // float3 worldPosition = ps.world_vertex;
                // float3 viewDirection = normalize(ps.world_vertex - _WorldSpaceCameraPos.xyz);
                //float3 ro = ps.world_vertex;
                    float time = iTime*0.25 + 0.01*_iMouse.x;
    float anim = 1.1 + 0.5*smoothstep( -0.3, 0.3, cos(0.1*iTime) );

        float3 tot = float3(0.0,0.0,0.0);
        float2 q = ps.uv.xy;
        float2 p = 2.0*q-1;
        // camera
        float3 ro = float3( 2.8*cos(0.1+.33*time), 0.4 + 0.30*cos(0.37*time), 2.8*cos(0.5+0.35*time) );
        float3 ta = float3( 1.9*cos(1.2+.41*time), 0.4 + 0.10*cos(0.27*time), 1.9*cos(2.0+0.38*time) );
        float roll = 0.2*cos(0.1*time);
        float3 cw = normalize(ta-ro);
        float3 cp = float3(sin(roll), cos(roll),0.0);
        float3 cu = normalize(cross(cw,cp));
        float3 cv = normalize(cross(cu,cw));
        float3 rd = normalize( p.x*cu + p.y*cv + 2.0*cw );

        tot += render( ro, equirectangularRay(), anim );

    return float4( tot, 1.0 );  
            }

            ENDCG

        }
    }
}
FalseHope00 commented 4 years ago

how do I fix this line? color=lerp(fixed3(length(color)),color,SATURATION); Error i get in unity is Incorrect number of arguments to numeric-type constructor at line 325

smkplus commented 4 years ago

it's because glsl compiler float3(x) know as float3(x,x,x) but in hlsl (unity) compiler couldn't understand what is float3(x)!?

color=lerp(fixed3(length(color),length(color),length(color)),color,SATURATION);

or

color=lerp(fixed3(1,1,1)*length(color),color,SATURATION);