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 ); }