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.