Shader特效——“Distance 2D”的实现【ShaderToy】
发表于2018-02-07
本篇文章和大家介绍的是ShaderToy实现的Distance 2D效果。
RoundedBox
效果图:

ShaderToy代码及算法注释:
// Created by inigo quilez - iq/2015
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
// signed distance to a 2D rounded box
float sdRoundBox( in vec2 p, in vec2 b, in float r )
{
vec2 q = abs(p) - b;
//float d = q.x; // '|'
//float d = q.y; // '-'
// 矩形
vec2 m = vec2( min(q.x,q.y), max(q.x,q.y) );// 1.黄色区域取交集(白色区域取并集), 2.黄色区域取并集(白色区域取交集)
//float d = m.x;
//float d = m.y;
// 绘制圆角/矩形
float d = (m.x > 0.0) ? length(q) : m.y;
//float d = (m.x > 0.) ? length(q):0.;
//float d = (m.x > 0.) ? 0.:m.y;
return d - r;
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 p = (2.0*fragCoord.xy-iResolution.xy)/iResolution.y; // -vec2(iResolution.x/iResolution.y, 1.), vec2(iResolution.x/iResolution.y, 1.)
vec2 ra = 0.4 + 0.3*sin( iGlobalTime + vec2(0.0,1.57) ); // [0.1, 0.7], vec2(0.0, 1.57) 控制矩形的纵横比
float d = sdRoundBox( p, ra, 0.2 );
vec3 col = vec3(1.0) - sign(d)*vec3(0.1,0.4,0.7);// 根据d的符号,设置不同的颜色(矩形内部为白色,矩形外部为黄色)
col *= 1. - exp(-2.0*abs(d)); // 增强颜色对比度
col *= 0.8 + 0.2*cos(120.0*d); // 波纹效果
col = mix( col, vec3(1.0), 1.0-smoothstep(0.0,0.02,abs(d)) ); // 白色边界,大约0.02宽
fragColor = vec4(col,1.0);
}
Triangle
效果图:

GLSL代码及算法注释:
// Created by inigo quilez - iq/2014
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
// signed distance to a 2D triangle
float sdTriangle( in vec2 p0, in vec2 p1, in vec2 p2, in vec2 p )
{
// 三角形三条边的向量(顺时针)
vec2 e0 = p1 - p0;
vec2 e1 = p2 - p1;
vec2 e2 = p0 - p2;
// 三角形三个顶点到p点的向量
vec2 v0 = p - p0;
vec2 v1 = p - p1;
vec2 v2 = p - p2;
// p点到三条边的距离向量
vec2 pq0 = v0 - e0*clamp( dot(v0,e0)/dot(e0,e0), 0.0, 1.0 );
vec2 pq1 = v1 - e1*clamp( dot(v1,e1)/dot(e1,e1), 0.0, 1.0 );
vec2 pq2 = v2 - e2*clamp( dot(v2,e2)/dot(e2,e2), 0.0, 1.0 );
// p点到最近的边的距离,通过叉乘判断p点在三角形内(+)还是三角形外(-)
vec2 d = min( min( vec2( dot( pq0, pq0 ), v0.x*e0.y-v0.y*e0.x ),
vec2( dot( pq1, pq1 ), v1.x*e1.y-v1.y*e1.x )),
vec2( dot( pq2, pq2 ), v2.x*e2.y-v2.y*e2.x ));
// 返回最近的距离
return -sqrt(d.x)*sign(d.y);
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 p = (2.0*fragCoord.xy-iResolution.xy)/iResolution.y;
// 顺时针方向
vec2 v1 = cos( iGlobalTime + vec2(0.0,1.57) + 0.0 );
vec2 v2 = cos( iGlobalTime + vec2(0.0,1.57) + 2.0 );
vec2 v3 = cos( iGlobalTime + vec2(0.0,1.57) + 4.0 );
float d = sdTriangle( v1, v2, v3, p );
// 内部为白色,外部为黄色
vec3 col = vec3(1.0) - sign(d)*vec3(0.1,0.4,0.7);
// 增大颜色对比度
col *= 1.0 - exp(-2.0*abs(d));
// 波纹形状
col *= 0.8 + 0.2*cos(120.0*d);
// 白色边界
col = mix( col, vec3(1.0), 1.0-smoothstep(0.0,0.02,abs(d)) );
fragColor = vec4(col,1.0);
}
Circle
效果图:

GLSL代码及注释:
float sdCircle( vec2 p, in float r )
{
return length(p) - r;
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = -1.0 + 2.0 * fragCoord.xy/iResolution.xy;
uv.x *= iResolution.x/iResolution.y;
float d = sdCircle( uv, 0.5 );
vec3 col = vec3(1.0) - sign(d)*vec3(0.1,0.4,0.7);
col *= 1.0 - exp(-2.0*abs(d));
col *= 0.8 + 0.2*cos(120.0*d);
col = mix( col, vec3(1.0), 1.0-smoothstep(0.0,0.02,abs(d)) );
fragColor = vec4( col, 1.0 );
}
