ShaderToy中图形效果转译到UnityShaderlab案例分享
系列案例目录
1.数学计算八卦阵_Yin Yang
2.图形循环变换_Pattern
3.2D层层叠叠半透明泡泡_Bubbles
4.科技感电流场_PlasmaGlobe
5.实现卡通心跳_Heart2D
6.卡通层级云_Clouds
一、ShaderToy是什么?
ShaderToy是一个在线平台,允许用户创建、共享和浏览基于着色器(shaders)的实时图形效果。着色器是一种在图形编程中用于描述图形效果的程序,通常在图形处理器(GPU)上运行。ShaderToy专注于片元着色器(pixel shaders),这是一种用于处理屏幕上每个像素的着色器。
在ShaderToy上,用户可以使用OpenGL Shading Language(GLSL)编写着色器代码,以实时渲染各种视觉效果,包括抽象艺术、光影效果、模拟流体等等。用户可以通过简单的链接和分享来展示他们的作品,从而创建一个充满创意和艺术性的社区。
这个平台通常吸引着对图形编程、计算机图形学、计算机艺术等领域感兴趣的人们,他们可以通过ShaderToy分享他们的创意和学习经验。
二、ShaderToy链接
1.数学计算八卦阵_Yin Yang
ShaderToy内的源码与效果图如下:
ShaderToy中的代码如下:
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 p = 1.1 * (2.0*fragCoord-iResolution.xy)/min(iResolution.y,iResolution.x);
float a = dot(p,p);
float b = abs(p.y)-a;
float c = (b>0.0) ? p.y : p.x;
float d = (a-1.0)*(b-0.23)*c;
float r = (a>1.0) ? 0.6 :
(d>0.0) ? 1.0 :
0.0;
fragColor = vec4( r, r, r, 1.0 );
}
下面是在Unity内的效果展示:
在代码中加入了一个旋转矩阵,让阴阳转动起来。
在片段着色器中输入下面的代码:
fixed4 frag(v2f i) : SV_Target
{
float2 uv = i.uv -0.5;
fixed2 p = 1.1 * (2.0*uv);
return fixed4(p.xxx, 1.0 );
}
输出效果如下:
实现画面对半的黑白效果
在片段着色器中输入下面的代码:
fixed4 frag(v2f i) : SV_Target
{
float2 uv = i.uv -0.5;
fixed2 p = 1.1 * (2.0*uv);
fixed h = dot(p,p);
return fixed4(h.xxxx);
}
fixed h = dot(p,p)解析
有点类似求 length 的最终效果,也就是说
fixed h = dot(p,p);
fixed h = length(uv);//这两个最终表现的效果是一样的。
输出效果如下:
在片段着色器中输入下面的代码:
fixed4 frag(v2f i) : SV_Target
{
float2 uv = i.uv -0.5;
fixed2 p = 1.1 * (2.0*uv);
fixed h = length(uv);
fixed d = abs(p.y)-h;
return fixed4(d.xxxx);
}
输出效果如下:
在片段着色器中输入下面的代码:
fixed4 frag(v2f i) : SV_Target
{
float2 uv = i.uv -0.5;
fixed2 p = 1.1 * (2.0*uv);
fixed h = dot(p,p);
fixed d = abs(p.y)-h;
fixed a = d-0.23;
fixed b = h-1.00;
return fixed4( a*b, a*b, a*b, 1.0 );
}
输出效果如下:
完整ShaderLab代码如下:
Shader"ShaderMan/Yin Yang"
{
Properties
{
}
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;
};
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;
}
fixed4 frag(v2f i) : SV_Target
{
float2 uv = i.uv -0.5;
float rad = _Time.y * 4;
float2x2 RotationMatrix = float2x2
(
cos(rad), -sin(rad),
sin(rad),cos(rad)
);
uv = mul(RotationMatrix,uv);
fixed2 p = 1.1 * (2.0*uv);
fixed h = dot(p,p);
fixed d = abs(p.y)-h;
fixed a = d-0.23;
fixed b = h-1.00;
fixed c = sign(a*b*(p.y+p.x + (p.y-p.x)*sign(d)));
c = lerp( c, 0.0, smoothstep(0.98,1.00,h) );
c = lerp( c, 0.6, smoothstep(1.00,1.02,h) );
return fixed4( c, c, c, 1.0 );
}
ENDCG
}
}
}
小总结:旋转计算
下面是以旋转度数为准的计算
void Unity_Rotate_Degrees_float(float2 UV, float2 Center, float Rotation, out float2 Out)
{
//rotation matrix
Rotation = Rotation * (3.1415926f/180.0f);
UV -= Center;
float s = sin(Rotation);
float c = cos(Rotation);
//center rotation matrix
float2x2 rMatrix = float2x2(c, -s, s, c);
rMatrix *= 0.5;
rMatrix += 0.5;
rMatrix = rMatrix*2 - 1;
//multiply the UVs by the rotation matrix
UV.xy = mul(UV.xy, rMatrix);
UV += Center;
Out = UV;
}
2.图形循环变换_Pattern
ShaderToy内的源码与效果图如下:
完整ShaderLab代码如下:
Shader"ShaderToy/Pattern"
{
Properties
{
_MainTex("_MainTex", 2D) = "white"{}
}
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;
};
sampler2D _MainTex;
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 noise( in fixed2 x )
{
fixed2 p = floor(x);
fixed2 f = frac(x);
fixed2 uv = p.xy + f.xy*f.xy*(3.0-2.0*f.xy);
return tex2Dlod( _MainTex,float4( (uv+118.4)/256.0, 0.0 ,0)).x;
}
fixed map( in fixed2 x, fixed t )
{
return noise( 2.5*x - 1.5*t*fixed2(1.0,0.0) );
}
fixed shapes( in fixed2 uv, in fixed r, in fixed e )
{
fixed p = pow( 32.0, r - 0.5 );
fixed l = pow( pow(abs(uv.x),p) + pow(abs(uv.y),p), 1.0/p );
fixed d = l - pow(r,0.6) - e*0.2 + 0.05;
fixed fw = fwidth( d )*0.5;
fw *= 1.0 + 10.0*e;
return (r)*smoothstep( fw, -fw, d ) * (1.0-0.2*e)*(0.4 + 0.6*smoothstep( -fw, fw, abs(l-r*0.8+0.05)-0.1 ));
}
fixed4 frag(v2f i) : SV_Target
{
fixed2 qq = i.uv.xy/1;
fixed2 uv = (i.uv - 0.5) * 0.5 * (sin(_Time.y * 2)+2);
fixed time = 11.0 + (_Time.y + 0.8*sin(_Time.y)) / 1.8;
uv += 0.01*noise( 2.0*uv + 0.2*time );
fixed3 col = 0.1*fixed3(0.10,1.0,0.10) * 0.15 * abs(qq.y-0.5);
fixed2 pq, st; fixed f; fixed3 coo;
pq = floor( uv*9.0 ) / 9.0;
st = frac( uv*9.0 )*2.0 - 1.0;
coo = (fixed3(0.5,0.7,0.7) + 0.3*sin(10.0*pq.x)*sin(13.0*pq.y))*0.6;
col += 1.0*coo*shapes( st, map(pq, time), 0.0 );
col += 0.6*coo*shapes( st, map(pq, time), 1.0 );
pq = floor( uv*9.0+0.5 ) / 9.0;
st = frac( uv*9.0+0.5 )*2.0 - 1.0;
coo = (fixed3(1.0,0.5,0.3) + 0.3*sin(10.0*pq.y)*cos(11.0*pq.x))*1.0;
col += 1.0*coo*shapes( st, 1.0-map(pq, time), 0.0 );
col += 0.4*coo*shapes( st, 1.0-map(pq, time), 1.0 );
col *= pow( 16.0*qq.x*qq.y*(1.0-qq.x)*(1.0-qq.y), 0.05 );
return fixed4( col, 1.0 );
}
ENDCG
}
}
}
3.2D层层叠叠半透明泡泡_Bubbles
ShaderToy内的源码与效果图如下:
完整ShaderLab代码如下:
Shader"ShaderToy/Bubbles"
{
Properties
{
}
SubShader
{
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;
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;
}
fixed4 frag(v2f i) : SV_Target
{
fixed2 uv = i.uv;
uv.x *= 1 / 1;
fixed3 color = fixed3(0.8 + 0.2*uv.y,0.8 + 0.2*uv.y,0.8 + 0.2*uv.y);
[unroll(100)]
for( int i=0; i<40; i++ )
{
fixed pha = sin(fixed(i)*546.13+1.0)*0.5 + 0.5;
fixed siz = pow( sin(fixed(i)*651.74+5.0)*0.5 + 0.5, 4.0 );
fixed pox = sin(fixed(i)*321.55+4.1) * 1 / 1;
fixed rad = 0.1 + 0.5*siz;
fixed2 pos = fixed2( pox, -1.0-rad + (2.0+2.0*rad)*fmod(pha+0.1*_Time.y*(0.2+0.8*siz),1.0));
fixed dis = length( uv - pos );
fixed3 col = lerp( fixed3(0.94,0.3,0.0), fixed3(0.1,0.4,0.8), 0.5+0.5*sin(fixed(i)*1.2+1.9));
fixed f = length(uv-pos)/rad;
f = sqrt(clamp(1.0-f*f,0.0,1.0));
color -= col.zyx *(1.0-smoothstep( rad*0.95, rad, dis )) * f;
}
color *= sqrt(1.5-0.5*length(uv));
return fixed4(color,1.0);
}
ENDCG
}
}
}
4.科技感电流场_PlasmaGlobe
ShaderToy内的源码与效果图如下:
Mac电脑系统下的显示:
Windows系统下的显示:
完整ShaderLab代码如下:
Shader"ShaderToy/PlasmaGlobe"
{
Properties
{
_MainTex("MainTex", 2D) = "white"{}
_iMouse("iMouse", Vector) = (0,0,0,0)
}
SubShader{
Pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
sampler2D _MainTex;
float4 _iMouse;
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;
}
#define NUM_RAYS 13.
#define VOLUMETRIC_STEPS 19
#define MAX_ITER 35
#define FAR 6.
#define time _Time.y*1.1
fixed2x2 mm2(in fixed a)
{
fixed c = cos(a), s = sin(a);
return fixed2x2(c,-s,s,c);
}
fixed noise( in fixed x )
{
return tex2Dlod(_MainTex,float4( fixed2(x*.01,1.),0.0,0)).x;
}
fixed hash( fixed n )
{
return frac(sin(n)*43758.5453);
}
fixed noise(in fixed3 p)
{
fixed3 ip = floor(p);
fixed3 f = frac(p);
f = f*f*(3.0-2.0*f);
fixed2 uv = (ip.xy+fixed2(37.0,17.0)*ip.z) + f.xy;
fixed2 rg = tex2Dlod( _MainTex,float4( (uv+ 0.5)/256.0, 0.0 ,0)).yx;
return lerp(rg.x, rg.y, f.z);
}
fixed3x3 m3 = fixed3x3( 0.00, 0.80, 0.60,
-0.80, 0.36, -0.48,
-0.60, -0.48, 0.64 );
fixed flow(in fixed3 p, in fixed t)
{
fixed z=2.;
fixed rz = 0.;
fixed3 bp = p;
for (fixed i= 1.;i < 5.;i++ )
{
p += time*.1;
rz+= (sin(noise(p+t*0.8)*6.)*0.5+0.5) /z;
p = lerp(bp,p,0.6);
z = mul( z ,2.);
p = mul( p ,2.01);
p = mul( p,m3);
}
return rz;
}
fixed sins(in fixed x)
{
fixed rz = 0.;
fixed z = 2.;
for (fixed i= 0.;i < 3.;i++ )
{
rz += abs(frac(x*1.4)-0.5)/z;
x = mul( x ,1.3);
z = mul( z ,1.15);
x -= time*.65*z;
}
return rz;
}
fixed segm( fixed3 p, fixed3 a, fixed3 b)
{
fixed3 pa = p - a;
fixed3 ba = b - a;
fixed h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1. );
return length( pa - ba*h )*.5;
}
fixed3 path(in fixed i, in fixed d)
{
fixed3 en = fixed3(0.,0.,1.);
fixed sns2 = sins(d+i*0.5)*0.22;
fixed sns = sins(d+i*.6)*0.21;
en.xz = mul( en.xz ,mm2((hash(i*10.569)-.5)*6.2+sns2));
en.xy = mul( en.xy ,mm2((hash(i*4.732)-.5)*6.2+sns));
return en;
}
fixed2 map(fixed3 p, fixed i)
{
fixed lp = length(p);
fixed3 bg = fixed3(0.,0.,0.);
fixed3 en = path(i,lp);
fixed ins = smoothstep(0.11,.46,lp);
fixed outs = .15+smoothstep(.0,.15,abs(lp-1.));
p = mul( p ,ins*outs);
fixed id = ins*outs;
fixed rz = segm(p, bg, en)-0.011;
return fixed2(rz,id);
}
fixed march(in fixed3 ro, in fixed3 rd, in fixed startf, in fixed maxd, in fixed j)
{
fixed precis = 0.001;
fixed h=0.5;
fixed d = startf;
[unroll(100)]
for( int i=0; i<MAX_ITER; i++ )
{
if( abs(h)<precis||d>maxd ) break;
d += h*1.2;
fixed res = map(ro+rd*d, j).x;
h = res;
}
return d;
}
fixed3 vmarch(in fixed3 ro, in fixed3 rd, in fixed j, in fixed3 orig)
{
fixed3 p = ro;
fixed2 r = fixed2(0.,0.);
fixed3 sum = fixed3(0,0,0);
fixed w = 0.;
[unroll(100)]
for( int i=0; i<VOLUMETRIC_STEPS; i++ )
{
r = map(p,j);
p += rd*.03;
fixed lp = length(p);
fixed3 col = sin(fixed3(1.05,2.5,1.52)*3.94+r.y)*.85+0.4;
col.rgb = mul( col.rgb ,smoothstep(.0,.015,-r.x));
col = mul( col ,smoothstep(0.04,.2,abs(lp-1.1)));
col = mul( col ,smoothstep(0.1,.34,lp));
sum += abs(col)*5. * (1.2-noise(lp*2.+j*13.+time*5.)*1.1) / (log(distance(p,orig)-2.)+.75);
}
return sum;
}
fixed2 iSphere2(in fixed3 ro, in fixed3 rd)
{
fixed3 oc = ro;
fixed b = dot(oc, rd);
fixed c = dot(oc,oc) - 1.;
fixed h = b*b - c;
if(h <0.0) return fixed2(-1.,-1.);
else return fixed2((-b - sqrt(h)), (-b + sqrt(h)));
}
fixed4 frag(v2f i) : SV_Target{
{
fixed2 p = i.uv.xy/1-0.5;
p.x = mul( p.x,1/1);
fixed2 um = _iMouse.xy / 1-.5;
fixed3 ro = fixed3(0.,0.,5.);
fixed3 rd = normalize(fixed3(p*.7,-1.5));
fixed2x2 mx = mm2(time*.4+um.x*6.);
fixed2x2 my = mm2(time*0.3+um.y*6.);
ro.xz = mul( ro.xz ,mx);rd.xz = mul(rd.xz ,mx);
ro.xy = mul( ro.xy ,my);rd.xy = mul(rd.xy ,my);
fixed3 bro = ro;
fixed3 brd = rd;
fixed3 col = fixed3(0.0125,0.0,0.025);
#if 1
for (fixed j = 1.;j<NUM_RAYS+1.;j++)
{
ro = bro;
rd = brd;
fixed2x2 mm = mm2((time*0.1+((j+1.)*5.1))*j*0.25);
ro.xy = mul( ro.xy ,mm);rd.xy = mul(rd.xy ,mm);
ro.xz = mul( ro.xz ,mm);rd.xz = mul(rd.xz ,mm);
fixed rz = march(ro,rd,2.5,FAR,j);
if ( rz >= FAR)continue;
fixed3 pos = ro+rz*rd;
col = max(col,vmarch(pos,rd,j, bro));
}
#endif
ro = bro;
rd = brd;
fixed2 sph = iSphere2(ro,rd);
if (sph.x > 0.)
{
fixed3 pos = ro+rd*sph.x;
fixed3 pos2 = ro+rd*sph.y;
fixed3 rf = reflect( rd, pos );
fixed3 rf2 = reflect( rd, pos2 );
fixed nz = (-log(abs(flow(rf*1.2,time)-.01)));
fixed nz2 = (-log(abs(flow(rf2*1.2,-time)-.01)));
col += (0.1 * nz * nz * fixed3(0.12,0.12,0.5) + 0.05 * nz2 * nz2 * fixed3(0.55,0.2,.55))*0.8;
}
return fixed4(col*1.3, 1.0);
}
}ENDCG
}
}
}
5.实现卡通心跳_Heart2D
ShaderToy内的源码与效果图如下:
完整ShaderLab代码如下:
Shader"ShaderToy/Heart2D"
{
Properties
{
}
SubShader
{
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;
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;
}
fixed4 frag(v2f i) : SV_Target
{
fixed2 p = (2.0*i.uv-1)/min(1,1);
fixed3 bcol = fixed3(1.0,0.8,0.7-0.07*p.y)*(1.0-0.25*length(p));
fixed tt = fmod(_Time.y,1.5)/1.5;
fixed ss = pow(tt,.2)*0.5 + 0.5;
ss = 1.0 + ss*0.5*sin(tt*6.2831*3.0 + p.y*0.5)*exp(-tt*4.0);
p *= fixed2(0.5,1.5) + ss*fixed2(0.5,-0.5);
#if 1
p *= 0.8;
p.y = -0.1 - p.y*1.2 + abs(p.x)*(1.0-abs(p.x));
fixed r = length(p);
fixed d = 0.5;
#else
p.y -= 0.25;
fixed a = atan2(p.y,p.x)/3.141593;
fixed r = length(p);
fixed h = abs(a);
fixed d = (13.0*h - 22.0*h*h + 10.0*h*h*h)/(6.0-5.0*h);
#endif
fixed s = 0.75 + 0.75*p.x;
s *= 1.0-0.4*r;
s = 0.3 + 0.7*s;
s *= 0.5+0.5*pow( 1.0-clamp(r/d, 0.0, 1.0 ), 0.1 );
fixed3 hcol = fixed3(1.0,0.5*r,0.3)*s;
fixed3 col = lerp( bcol, hcol, smoothstep( -0.01, 0.01, d-r) );
return fixed4(col,1.0);
}
ENDCG
}
}
}
6.卡通层级云_Clouds
ShaderToy内的源码与效果图如下:
完整ShaderLab代码如下:
Shader"ShaderMan/Clouds"
{
Properties
{
_color ("color",color) = (1,1,1,1)
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
fixed4 _color ;
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
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;
}
#define TAU 6.28318530718
const fixed3 BackColor = fixed3(0.0, 0.4, 0.58);
const fixed3 CloudColor = fixed3(0.18,0.70,0.87);
fixed Func(fixed pX)
{
return 0.6*(0.5*sin(0.1*pX) + 0.5*sin(0.553*pX) + 0.7*sin(1.2*pX));
}
fixed FuncR(fixed pX)
{
return 0.5 + 0.25*(1.0 + sin(fmod(40.0*pX, TAU)));
}
fixed Layer(fixed2 pQ, fixed pT)
{
fixed2 Qt = 3.5*pQ;
pT *= 0.5;
Qt.x += pT;
fixed Xi = floor(Qt.x);
fixed Xf = Qt.x - Xi -0.5;
fixed2 C;
fixed Yi;
fixed D = 1.0 - step(Qt.y, Func(Qt.x));
// Disk:
Yi = Func(Xi + 0.5);
C = fixed2(Xf, Qt.y - Yi );
D = min(D, length(C) - FuncR(Xi+ pT/80.0));
// Previous disk:
Yi = Func(Xi+1.0 + 0.5);
C = fixed2(Xf-1.0, Qt.y - Yi );
D = min(D, length(C) - FuncR(Xi+1.0+ pT/80.0));
// Next Disk:
Yi = Func(Xi-1.0 + 0.5);
C = fixed2(Xf+1.0, Qt.y - Yi );
D = min(D, length(C) - FuncR(Xi-1.0+ pT/80.0));
return min(1.0, D);
}
fixed4 frag(v2f i) : SV_Target
{
// Setup:
fixed2 UV = 2.0*(i.uv.xy - 1/2.0) / min(1, 1);
// Render:
fixed3 Color= BackColor;
[unroll(100)]
for(fixed J=0.0; J<=1.0; J+=0.2)
{
// Cloud Layer:
fixed Lt = _Time.y*(0.5 + 2.0*J)*(1.0 + 0.1*sin(226.0*J)) + 17.0*J;
fixed2 Lp = fixed2(0.0, 0.3+1.5*( J - 0.5));
fixed L = Layer(UV + Lp, Lt);
// Blur and color:
fixed Blur = 4.0*(0.5*abs(2.0 - 5.0*J))/(11.0 - 5.0*J);
fixed V = lerp( 0.0, 1.0, 1.0 - smoothstep( 0.0, 0.01 +0.2*Blur, L ) );
fixed3 Lc= lerp( CloudColor, fixed3(1.0,1.0,1.0), J);
Color =lerp(Color, Lc, V);
}
return (fixed4(Color, 1.0) + fixed4(0,0.5,0.5,0)) * _color;
}
ENDCG
}
}
}