Unity Shader with SCript to WebGL?

89 Views Asked by At

Does anyone know how to recode a Shaderlab Shader from Unity with an Script to WebGL Website? The original code is from Shadertoy. It was then recoded so it works with Unity. (Original Source

I don't know much about shaders so, yeah maybe there is an tutorial out there or you can help me directly with that.

Script: `

// Add script to quad and assign material with shader. Play.
// Use left mouse to paint

using UnityEngine;

public class ChimerasBreath : MonoBehaviour 
{
    public int Resolution = 1024;
    public Material material;
    RenderTexture RTA1, RTA2, RTB1, RTB2, RTC1, RTC2, RTD1, RTD2;
    bool swap = true;
    
    void Blit(RenderTexture source, RenderTexture destination, Material mat, string name, int pass)
    {
        RenderTexture.active = destination;
        mat.SetTexture(name, source);
        GL.PushMatrix();
        GL.LoadOrtho();
        GL.invertCulling = true;
        mat.SetPass(pass);
        GL.Begin(GL.QUADS);
        GL.MultiTexCoord2(0, 0.0f, 0.0f);
        GL.Vertex3(0.0f, 0.0f, 0.0f);
        GL.MultiTexCoord2(0, 1.0f, 0.0f);
        GL.Vertex3(1.0f, 0.0f, 0.0f); 
        GL.MultiTexCoord2(0, 1.0f, 1.0f);
        GL.Vertex3(1.0f, 1.0f, 0.0f); 
        GL.MultiTexCoord2(0, 0.0f, 1.0f);
        GL.Vertex3(0.0f, 1.0f, 0.0f);
        GL.End();
        GL.invertCulling = false;
        GL.PopMatrix();
    }
            
    void Start () 
    {
        RTA1 = new RenderTexture(Resolution, Resolution, 0, RenderTextureFormat.ARGBFloat);  //buffer must be floating point RT
        RTA2 = new RenderTexture(Resolution, Resolution, 0, RenderTextureFormat.ARGBFloat);  //buffer must be floating point RT
        RTB1 = new RenderTexture(Resolution, Resolution, 0, RenderTextureFormat.ARGBFloat);  //buffer must be floating point RT
        RTB2 = new RenderTexture(Resolution, Resolution, 0, RenderTextureFormat.ARGBFloat);  //buffer must be floating point RT 
        RTC1 = new RenderTexture(Resolution, Resolution, 0, RenderTextureFormat.ARGBFloat);  //buffer must be floating point RT
        RTC2 = new RenderTexture(Resolution, Resolution, 0, RenderTextureFormat.ARGBFloat);  //buffer must be floating point RT
        RTD1 = new RenderTexture(Resolution, Resolution, 0, RenderTextureFormat.ARGBFloat);  //buffer must be floating point RT
        RTD2 = new RenderTexture(Resolution, Resolution, 0, RenderTextureFormat.ARGBFloat);  //buffer must be floating point RT     
        GetComponent<Renderer>().material = material;
    }
    
    void Update () 
    {
        RaycastHit hit;
        if (Input.GetMouseButton(0))
        {
            if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition) , out hit))
                material.SetVector("iMouse", new Vector4(
                    hit.textureCoord.x * Resolution, hit.textureCoord.y * Resolution,
                    1.0f,
                    1.0f));
        }
        else
        {
            material.SetVector("iMouse", new Vector4(-1000.0f, -1000.0f, -1.0f, -1.0f));
        }
        
        material.SetInt("iFrame",Time.frameCount);
        material.SetVector("iResolution", new Vector4(Resolution,Resolution,0.0f,0.0f));
        
        if (swap)
        {           
            material.SetTexture("_BufferA", RTA1);
            Blit(RTA1, RTA2, material, "_BufferA", 0);
            material.SetTexture("_BufferA", RTA2);
            
            material.SetTexture("_BufferB", RTB1);
            Blit(RTB1, RTB2, material, "_BufferB", 1);
            material.SetTexture("_BufferB", RTB2);
            
            material.SetTexture("_BufferC", RTC1);
            Blit(RTC1, RTC2, material, "_BufferC", 2);
            material.SetTexture("_BufferC", RTC2);
            
            material.SetTexture("_BufferD", RTD1);
            Blit(RTD1, RTD2, material, "_BufferD", 3);
            material.SetTexture("_BufferD", RTD2);          
        
        }
        else
        {
            
            material.SetTexture("_BufferA", RTA2);
            Blit(RTA2, RTA1, material, "_BufferA", 0);
            material.SetTexture("_BufferA", RTA1);
            
            material.SetTexture("_BufferB", RTB2);
            Blit(RTB2, RTB1, material, "_BufferB", 1);
            material.SetTexture("_BufferB", RTB1);
            
            material.SetTexture("_BufferC", RTC2);
            Blit(RTC2, RTC1, material, "_BufferC", 2);
            material.SetTexture("_BufferC", RTC1);
            
            material.SetTexture("_BufferD", RTD2);
            Blit(RTD2, RTD1, material, "_BufferD", 3);
            material.SetTexture("_BufferD", RTD1);          
        
        }
        swap = !swap;
    }
    
    void OnDestroy ()
    {
        RTA1.Release();
        RTA2.Release();
        RTB1.Release();
        RTB2.Release();
        RTC1.Release();
        RTC2.Release(); 
        RTD1.Release();
        RTD2.Release();         
    }
}

`

Shader: `

// Original reference: https://www.shadertoy.com/view/4tGfDW
// Translated from GLSL to HLSL by Przemyslaw Zaworski

Shader "ShaderToy/Chimeras Breath"
{
    SubShader
    {

//-------------------------------------------------------------------------------------------
    
        CGINCLUDE
        #pragma vertex VSMain
        #pragma fragment PSMain
        
        Texture2D _BufferA; 
        Texture2D _BufferB;
        Texture2D _BufferC; 
        Texture2D _BufferD; 
        SamplerState _LinearClamp;
        SamplerState _LinearRepeat;     
        int iFrame;
        float4 iMouse;
        float4 iResolution;

        #define dt 0.15
        #define USE_VORTICITY_CONFINEMENT
        #define VORTICITY_AMOUNT 0.11

        float mag2(float2 p)
        {
            return dot(p,p);
        }

        float2 point1(float t) 
        {
            t *= 0.62;
            return float2(0.12,0.5 + sin(t)*0.3);
        }
        float2 point2(float t) 
        {
            t *= 0.62;
            return float2(0.88,0.5 + cos(t + 1.5708)*0.3);
        }

        float4 solveFluid(Texture2D smp, float2 uv, float2 w, float time, float3 mouse, float3 lastMouse)
        {
            const float K = 0.2;
            const float v = 0.55;    
            float4 data = smp.SampleLevel (_LinearRepeat, uv, 0.0);
            float4 tr = smp.SampleLevel (_LinearRepeat, uv + float2(w.x , 0), 0.0);
            float4 tl = smp.SampleLevel (_LinearRepeat, uv - float2(w.x , 0), 0.0);
            float4 tu = smp.SampleLevel (_LinearRepeat, uv + float2(0 , w.y), 0.0);
            float4 td = smp.SampleLevel (_LinearRepeat, uv - float2(0 , w.y), 0.0);  
            float3 dx = (tr.xyz - tl.xyz)*0.5;
            float3 dy = (tu.xyz - td.xyz)*0.5;
            float2 densDif = float2(dx.z ,dy.z);  
            data.z -= dt*dot(float3(densDif, dx.x + dy.y) ,data.xyz); //density
            float2 laplacian = tu.xy + td.xy + tr.xy + tl.xy - 4.0*data.xy;
            float2 viscForce = float2(v,v)*laplacian;
            data.xyw = smp.SampleLevel (_LinearRepeat,uv - dt*data.xy*w, 0.0).xyw; //advection 
            float2 newForce = float2(0,0);
            newForce.xy += 0.75*float2(.0003, 0.00015)/(mag2(uv-point1(time))+0.0001);
            newForce.xy -= 0.75*float2(.0003, 0.00015)/(mag2(uv-point2(time))+0.0001);  
            if (mouse.z > 1. && lastMouse.z > 1.)
            {
                float2 vv = clamp(float2(mouse.xy*w - lastMouse.xy*w)*400., -6., 6.);
                newForce.xy += .001/(mag2(uv - mouse.xy*w)+0.001)*vv;
            }   
            data.xy += dt*(viscForce.xy - K/dt*densDif + newForce); //update velocity
            data.xy = max(float2(0,0), abs(data.xy)-1e-4)*sign(data.xy); //linear velocity decay   
            #ifdef USE_VORTICITY_CONFINEMENT
                data.w = (tr.y - tl.y - tu.x + td.x);
                float2 vort = float2(abs(tu.w) - abs(td.w), abs(tl.w) - abs(tr.w));
                vort *= VORTICITY_AMOUNT/length(vort + 1e-9)*data.w;
                data.xy += vort;
            #endif
            data.y *= smoothstep(.5,.48,abs(uv.y-0.5)); 
            data = clamp(data, float4(float2(-10, -10), 0.5 , -10.), float4(float2(10,10), 3.0 , 10.)); 
            return data;
        }
        
        void VSMain (inout float4 vertex:POSITION, inout float2 uv0:TEXCOORD0)
        {
            vertex = UnityObjectToClipPos(vertex);
        }
        
        ENDCG

//-------------------------------------------------------------------------------------------

        Pass
        { 
            CGPROGRAM

            float length2(float2 p)
            {
                return dot(p,p);
            }

            float2x2 mm2(in float a)
            {
                float c = cos(a), s = sin(a);
                return float2x2(c,s,-s,c);
            }
        
            void PSMain (float4 vertex:POSITION, float2 uv0:TEXCOORD0, out float4 fragColor:SV_TARGET)
            {
                float2 fragCoord = uv0 * iResolution.xy;
                float2 uv = fragCoord.xy/iResolution.xy;
                float2 w = 1.0/iResolution.xy;   
                float4 lastMouse = _BufferC.Load( int3(0,1,0));
                float4 data = solveFluid(_BufferC, uv, w, _Time.g, iMouse.xyz, lastMouse.xyz);   
                if (iFrame < 20)
                {
                    data = float4(0.5,0,0,0);
                }  
                if (fragCoord.y < 2.)
                    data = iMouse;   
                fragColor = data; 
            }
            
            ENDCG
        }
        
//-------------------------------------------------------------------------------------------
        
        Pass
        { 
            CGPROGRAM

            float length2(float2 p)
            {
                return dot(p,p);
            }

            float2x2 mm2(in float a)
            {
                float c = cos(a), s = sin(a);
                return float2x2(c,s,-s,c);
            }
            
            void PSMain (float4 vertex:POSITION, float2 uv0:TEXCOORD0, out float4 fragColor:SV_TARGET)
            {   
                float2 fragCoord = uv0 * iResolution.xy;            
                float2 uv = fragCoord.xy/iResolution.xy;
                float2 w = 1.0/iResolution.xy;    
                float4 lastMouse = _BufferA.Load( int3(0,1,0));
                float4 data = solveFluid(_BufferA, uv, w, _Time.g, iMouse.xyz, lastMouse.xyz);  
                if (iFrame < 20)
                {
                    data = float4(0.5,0,0,0);
                }  
                if (fragCoord.y < 2.)
                    data = iMouse;  
                fragColor = data;
            }
            
            ENDCG
        }

//-------------------------------------------------------------------------------------------
    
        Pass
        { 
            CGPROGRAM
                    
            float length2(float2 p)
            {
                return dot(p,p);
            }

            float2x2 mm2(in float a)
            {
                float c = cos(a), s = sin(a);
                return float2x2(c,s,-s,c);
            }

            void PSMain (float4 vertex:POSITION, float2 uv0:TEXCOORD0, out float4 fragColor:SV_TARGET)
            {
                float2 fragCoord = uv0 * iResolution.xy;    
                float2 uv = fragCoord.xy/iResolution.xy;
                float2 w = 1.0/iResolution.xy;   
                float4 lastMouse = _BufferB.Load( int3(0,1, 0));
                float4 data = solveFluid(_BufferB, uv, w, _Time.g, iMouse.xyz, lastMouse.xyz);  
                if (iFrame < 20)
                {
                    data = float4(0.5,0,0,0);
                }   
                if (fragCoord.y < 2.)
                    data = iMouse;  
                fragColor = data;
            }
            
            ENDCG
        }

//-------------------------------------------------------------------------------------------

        Pass
        { 
            CGPROGRAM

            float2x2 mm2(in float a)
            {
                float c = cos(a), s = sin(a);
                return float2x2(c,s,-s,c);
            }

            float3 getPalette(float x, float3 c1, float3 c2, float3 p1, float3 p2)
            {
                float x2 = frac(x/2.0);
                x = frac(x);   
                float3x3 m = float3x3(c1, p1, c2);
                float3x3 m2 = float3x3(c2, p2, c1);
                float omx = 1.0-x;
                float3 pws = float3(omx*omx, 2.0*omx*x, x*x);
                return clamp(lerp(mul(pws,m), mul(pws,m2), step(x2,0.5)),0.,1.);
            }

            float4 pal(float x)
            {
                float3 pal = getPalette(-x, float3(0.2, 0.5, .7), float3(.9, 0.4, 0.1), float3(1., 1.2, .5), float3(1., -0.4, -.0));
                return float4(pal, 1.);
            }

            float4 pal2(float x)
            {
                float3 pal = getPalette(-x, float3(0.4, 0.3, .5), float3(.9, 0.75, 0.4), float3(.1, .8, 1.3), float3(1.25, -0.1, .1));
                return float4(pal, 1.);
            }
            
            void PSMain (float4 vertex:POSITION, float2 uv0:TEXCOORD0, out float4 fragColor:SV_TARGET)
            {
                float2 fragCoord = uv0 * iResolution.xy;
                float2 uv = fragCoord.xy / iResolution.xy;
                float2 mo = iMouse.xy / iResolution.xy;
                float2 w = 1.0/iResolution.xy;    
                float2 velo = _BufferA.SampleLevel (_LinearClamp, uv, 0.).xy;
                float4 col = _BufferD.SampleLevel (_LinearRepeat, uv - dt*velo*w*3., 0.); //advection
                if (fragCoord.y < 1. && fragCoord.x < 1.)
                    col = 0..xxxx;
                float4 lastMouse = _BufferD.Load( int3(0,1,0)).xyzw;   
                if (iMouse.z > 1. && lastMouse.z > 1.)
                {
                    float str = smoothstep(-.5,1.,length(mo - lastMouse.xy/iResolution.xy));   
                    col += str*0.0009/(pow(length(uv - mo),1.7)+0.002)*pal2(-_Time.g*0.7);
                }  
                col += .0025/(0.0005+pow(length(uv - point1(_Time.g)),1.75))*dt*0.12*pal(_Time.g*0.05 - .0);
                col += .0025/(0.0005+pow(length(uv - point2(_Time.g)),1.75))*dt*0.12*pal2(_Time.g*0.05 + 0.675);  
                if (iFrame < 20)
                {
                    col = 0..xxxx;
                }   
                col = clamp(col, 0.,5.);
                col = max(col - (0.0001 + col*0.004)*.5, 0.);   
                if (fragCoord.y < 1. && fragCoord.x < 1.)
                    col = iMouse;
                fragColor = col;   
            }
            
            ENDCG
        }
        
//-------------------------------------------------------------------------------------------

        Pass
        { 
            CGPROGRAM
            
            void PSMain (float4 vertex:POSITION, float2 uv0:TEXCOORD0, out float4 fragColor:SV_TARGET)
            {
                float2 fragCoord = uv0 * iResolution.xy;
                float4 col = _BufferD.SampleLevel (_LinearRepeat, fragCoord/iResolution.xy, 0.); 
                if (uv0.y<=0.005 || uv0.y>=0.995)
                    col = 0..xxxx;
                fragColor = col;
            }
            
            ENDCG
        }

//-------------------------------------------------------------------------------------------
        
    }
}

`

Thank's if you can help me with that.

0

There are 0 best solutions below