Shader特效——“Distance 2D”的实现【ShaderToy】

发表于2018-02-07
评论0 1.5k浏览
本篇文章和大家介绍的是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 );  
}  

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

标签: