// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader"ShaderMan/MyShader"{
Properties
{
_iResolution("iResolution", Vector) = (1,1,0,0)
_iMouse("iMouse", Vector) = (0,0,0,0)
}
SubShader{
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
uniform fixed3 _iResolution; // viewport resolution in pixels
uniform fixed4 fragColor;
uniform fixed iChannelTime[4];// channel playback time (in seconds)
uniform fixed3 iChannelResolution[4];// channel resolution (in pixels)
uniform fixed4 _iMouse;// mouse pixel coords. xy: current (if MLB down), zw: click
uniform fixed4 iDate;// (year, month, day, time in seconds)
uniform fixed iSampleRate;// sound sample rate (i.e., 44100)
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
float4 screenCoord : TEXCOORD1;
};
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
o.screenCoord.xy = ComputeScreenPos(o.vertex);
return o;
}
fixed smoothMerge(fixed d1, fixed d2, fixed k)
{
fixed h = clamp(0.5 + 0.5*(d2 - d1)/k, 0.0, 1.0);
return lerp(d2, d1, h) - k * h * (1.0-h);
}
fixed merge(fixed d1, fixed d2)
{
return min(d1, d2);
}
fixed mergeExclude(fixed d1, fixed d2)
{
return min(max(-d1, d2), max(-d2, d1));
}
fixed substract(fixed d1, fixed d2)
{
return max(-d1, d2);
}
fixed intersect(fixed d1, fixed d2)
{
return max(d1, d2);
}
fixed2 rotateCCW(fixed2 p, fixed a)
{
fixed2x2 m = fixed2x2(cos(a), sin(a), -sin(a), cos(a));
return mul(p,m);
}
fixed2 rotateCW(fixed2 p, fixed a)
{
fixed2x2 m = fixed2x2(cos(a), -sin(a), sin(a), cos(a));
return mul(p,m);
}
fixed2 translate(fixed2 p, fixed2 t)
{
return p - t;
}
fixed pie(fixed2 p, fixed angle)
{
angle = radians(angle) / 2.0;
fixed2 n = fixed2(cos(angle), sin(angle));
return abs(p).x * n.x + p.y*n.y;
}
fixed circleDist(fixed2 p, fixed radius)
{
return length(p) - radius;
}
fixed triangleDist(fixed2 p, fixed radius)
{
return max( abs(p).x * 0.866025 +
p.y * 0.5, -p.y)
-radius * 0.5;
}
fixed triangleDist(fixed2 p, fixed width, fixed height)
{
fixed2 n = normalize(fixed2(height, width / 2.0));
return max( abs(p).x*n.x + p.y*n.y - (height*n.y), -p.y);
}
fixed semiCircleDist(fixed2 p, fixed radius, fixed angle, fixed width)
{
width /= 2.0;
radius -= width;
return substract(pie(p, angle),
abs(circleDist(p, radius)) - width);
}
fixed boxDist(fixed2 p, fixed2 size, fixed radius)
{
size -= fixed2(radius,radius);
fixed2 d = abs(p) - size;
return min(max(d.x, d.y), 0.0) + length(max(d, 0.0)) - radius;
}
fixed lineDist(fixed2 p, fixed2 start, fixed2 end, fixed width)
{
fixed2 dir = start - end;
fixed lngth = length(dir);
dir /= lngth;
fixed2 proj = max(0.0, min(lngth, dot((start - p), dir))) * dir;
return length( (start - p) - proj ) - (width / 2.0);
}
fixed fillMask(fixed dist)
{
return clamp(-dist, 0.0, 1.0);
}
fixed innerBorderMask(fixed dist, fixed width)
{
//dist += 1.0;
fixed alpha1 = clamp(dist + width, 0.0, 1.0);
fixed alpha2 = clamp(dist, 0.0, 1.0);
return alpha1 - alpha2;
}
fixed outerBorderMask(fixed dist, fixed width)
{
//dist += 1.0;
fixed alpha1 = clamp(dist, 0.0, 1.0);
fixed alpha2 = clamp(dist - width, 0.0, 1.0);
return alpha1 - alpha2;
}
fixed sceneDist(fixed2 p)
{
fixed c = circleDist( translate(p, fixed2(100, 250)), 40.0);
fixed b1 = boxDist( translate(p, fixed2(200, 250)), fixed2(40, 40), 0.0);
fixed b2 = boxDist( translate(p, fixed2(300, 250)), fixed2(40, 40), 10.0);
fixed l = lineDist( p, fixed2(370, 220), fixed2(430, 280), 10.0);
fixed t1 = triangleDist( translate(p, fixed2(500, 210)), 80.0, 80.0);
fixed t2 = triangleDist( rotateCW(translate(p, fixed2(600, 250)), _Time.y), 40.0);
fixed m = merge(c, b1);
m = merge(m, b2);
m = merge(m, l);
m = merge(m, t1);
m = merge(m, t2);
fixed b3 = boxDist( translate(p, fixed2(100, sin(_Time.y * 3.0 + 1.0) * 40.0 + 100.0)),
fixed2(40, 15), 0.0);
fixed c2 = circleDist( translate(p, fixed2(100, 100)), 30.0);
fixed s = substract(b3, c2);
fixed b4 = boxDist( translate(p, fixed2(200, sin(_Time.y * 3.0 + 2.0) * 40.0 + 100.0)),
fixed2(40, 15), 0.0);
fixed c3 = circleDist( translate(p, fixed2(200, 100)), 30.0);
fixed i = intersect(b4, c3);
fixed b5 = boxDist( translate(p, fixed2(300, sin(_Time.y * 3.0 + 3.0) * 40.0 + 100.0)),
fixed2(40, 15), 0.0);
fixed c4 = circleDist( translate(p, fixed2(300, 100)), 30.0);
fixed a = merge(b5, c4);
fixed b6 = boxDist( translate(p, fixed2(400, 100)), fixed2(40, 15), 0.0);
fixed c5 = circleDist( translate(p, fixed2(400, 100)), 30.0);
fixed sm = smoothMerge(b6, c5, 10.0);
fixed sc = semiCircleDist(translate(p, fixed2(500,100)), 40.0, 90.0, 10.0);
fixed b7 = boxDist( translate(p, fixed2(600, sin(_Time.y * 3.0 + 3.0) * 40.0 + 100.0)),
fixed2(40, 15), 0.0);
fixed c6 = circleDist( translate(p, fixed2(600, 100)), 30.0);
fixed e = mergeExclude(b7, c6);
m = merge(m, s);
m = merge(m, i);
m = merge(m, a);
m = merge(m, sm);
m = merge(m, sc);
m = merge(m, e);
return m;
}
fixed sceneSmooth(fixed2 p, fixed r)
{
fixed accum = sceneDist(p);
accum += sceneDist(p + fixed2(0.0, r));
accum += sceneDist(p + fixed2(0.0, -r));
accum += sceneDist(p + fixed2(r, 0.0));
accum += sceneDist(p + fixed2(-r, 0.0));
return accum / 5.0;
}
fixed shadow(fixed2 p, fixed2 pos, fixed radius)
{
fixed2 dir = normalize(pos - p);
fixed dl = length(p - pos);
// fracion of light visible, starts at one radius (second fixed added in the end);
fixed lf = radius * dl;
// distance traveled
fixed dt = 0.01;
for (int i = 0; i < 64; ++i)
{
// distance to scene at current position
fixed sd = sceneDist(p + dir * dt);
// early out when this ray is guaranteed to be full shadow
if (sd < -radius)
return 0.0;
// width of cone-overlap at light
// 0 in center, so 50% overlap: add one radius outside of loop to get total coverage
// should be '(sd / dt) * dl', but '*dl' outside of loop
lf = min(lf, sd / dt);
// move ahead
dt += max(1.0, abs(sd));
if (dt > dl) break;
}
// multiply by dl to get the real projected overlap (moved out of loop)
// add one radius, before between -radius and + radius
// normalize to 1 ( / 2*radius)
lf = clamp((lf*dl + radius) / (2.0 * radius), 0.0, 1.0);
lf = smoothstep(0.0, 1.0, lf);
return lf;
}
fixed4 drawLight(fixed2 p, fixed2 pos, fixed4 color, fixed dist, fixed range, fixed radius)
{
// distance to light
fixed ld = length(p - pos);
// out of range
if (ld > range) return fixed4(0.0,0.0,0.0,0.0);
// shadow and falloff
fixed shad = shadow(p, pos, radius);
fixed fall = (range - ld)/range;
fall *= fall;
fixed source = fillMask(circleDist(p - pos, radius));
return (shad * fall + source) * color;
}
fixed luminance(fixed4 col)
{
return 0.2126 * col.r + 0.7152 * col.g + 0.0722 * col.b;
}
void setLuminance(inout fixed4 col, fixed lum)
{
lum /= luminance(col);
col *= lum;
}
fixed AO(fixed2 p, fixed dist, fixed radius, fixed intensity)
{
fixed a = clamp(dist / radius, 0.0, 1.0) - 1.0;
return 1.0 - (pow(abs(a), 5.0) + 1.0) * intensity + (1.0 - intensity);
return smoothstep(0.0, 1.0, dist / radius);
}
fixed4 frag(v2f i) : SV_Target{
{
fixed2 p = i.uv.xy * _iResolution.xy + fixed2(0.5,0.5);
//fixed2 p = i.uv.xy * 512.0 + fixed2(0.5,0.5);
fixed2 c = _iResolution.xy / 2.0;
//fixed dist = sceneSmooth(p, 5.0);
fixed dist = sceneDist(p);
fixed2 light1Pos = _iMouse.xy;
//fixed2 light1Pos = fixed4(0,0,0,0);
fixed4 light1Col = fixed4(0.75, 1.0, 0.5, 1.0);
setLuminance(light1Col, 0.4);
fixed2 light2Pos = fixed2(_iResolution.x * (sin(_Time.y + 3.1415) + 1.2) / 2.4, 175.0);
fixed4 light2Col = fixed4(1.0, 0.75, 0.5, 1.0);
setLuminance(light2Col, 0.5);
fixed2 light3Pos = fixed2(_iResolution.x * (sin(_Time.y) + 1.2) / 2.4, 340.0);
fixed4 light3Col = fixed4(0.5, 0.75, 1.0, 1.0);
setLuminance(light3Col, 0.6);
// gradient
fixed4 col = fixed4(0.5, 0.5, 0.5, 1.0) * (1.0 - length(c - p)/_iResolution.x);
// grid
col *= clamp(min(fmod(p.y, 10.0), fmod(p.x, 10.0)), 0.9, 1.0);
// ambient occlusion
col *= AO(p, sceneSmooth(p, 10.0), 40.0, 0.4);
//col *= 1.0-AO(p, sceneDist(p), 40.0, 1.0);
// light
col += drawLight(p, light1Pos, light1Col, dist, 150.0, 6.0);
col += drawLight(p, light2Pos, light2Col, dist, 200.0, 8.0);
col += drawLight(p, light3Pos, light3Col, dist, 300.0, 12.0);
// shape fill
col = lerp(col, fixed4(0.5, 0.5, 0.5, 1.0), fillMask(dist));
// shape outline
col = lerp(col, fixed4(0.4, 0.4, 0.4, 1.0), innerBorderMask(dist, 1.5));
return clamp(col, 0.0, 1.0);
}
}ENDCG
}
}
}
``