-
Notifications
You must be signed in to change notification settings - Fork 1
/
Seigaiha Mandala
160 lines (126 loc) · 4.79 KB
/
Seigaiha Mandala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
//https://www.shadertoy.com/view/WdtGWf,日本青海波图案
#define S(a,b,c) smoothstep(a,b,c)
// 将预乘(pre-multiplied)的源颜色和目标颜色混合起来(没有alpha值)
vec3 premulMix(vec4 src, vec3 dst)
{
return dst.rgb * (1.0 - src.a) + src.rgb;
}
// 将预乘(pre-multiplied)的源颜色和目标颜色混合起来(有alpha值)
vec4 premulMix(vec4 src, vec4 dst)
{
vec4 res;
res.rgb = premulMix(src, dst.rgb);
res.a = 1.0 - (1.0 - src.a) * (1.0 - dst.a);
return res;
}
// 计算鳞片花纹和其遮罩(mask)
vec4 roundPattern(vec2 uv)
{
float dist = length(uv);
// 根据分辨率决定抗锯齿效果,得到更好的缩略图
float aa = 8. / iResolution.x;
// 阈值化三角波函数得到同心圆
float triangle = abs(fract(dist * 11.0 + 0.3) - 0.5);
float circles = S(0.25 - aa * 10.0, 0.25 + aa * 10.0, triangle);
// 对圆环应用光照梯度
float grad = dist * 2.0;
vec3 col = mix(vec3(0.0, 0.5, 0.6), vec3(0.0, 0.2, 0.5), grad * grad);
col = mix(col, vec3(1.0), circles);
// 边缘和中心是红的
vec3 borderColor = vec3(0.7, 0.2, 0.2);
col = mix(col, borderColor, S(0.44 - aa, 0.44 + aa, dist));
col = mix(col, borderColor, S(0.05 + aa, 0.05 - aa, dist));
// 用软阴影(soft shadow)计算遮罩
float mask = S(0.5, 0.49, dist);
float blur = 0.3;
float shadow = S(0.5 + blur, 0.5 - blur, dist);
return vec4(col * mask, clamp(mask + shadow * 0.55, 0.0, 1.0));
}
//以给定缩放,在给定半径的圆环上计算鳞片
vec4 ring(vec2 uv, float angle, float angleOffset, float centerDist, float numcircles, float circlesRad)
{
//每个鳞片的极坐标空间按象限划分
float quadId = floor(angle * numcircles + angleOffset);
// 计算到象限原点的角度(6.283=2*PI)
float quadAngle = (quadId + 0.5 - angleOffset) * (6.283 / numcircles);
// 计算圆上(局部)象限原点
vec2 quadCenter = vec2(cos(quadAngle), sin(quadAngle)) * centerDist;
// 象限中返回鳞片颜色
vec2 circleUv = (uv + quadCenter) / circlesRad;
return roundPattern(circleUv);
}
// 计算具有两层重叠图案的环
vec4 dblRing(vec2 uv, float angle, float centerDist, float numcircles, float circlesRad, float t)
{
// 奇数和偶数的鳞片上下浮动
float s = sin(t * 3.0 + centerDist * 10.0) * 0.05;
float d1 = 1.05 + s;
float d2 = 1.05 - s;
// 整个旋转遵循正弦扰动
float rot = t * centerDist * 0.4 + sin(t + centerDist * 5.0) * 0.2;
// 计算任何一个圆环
vec4 ring1 = ring(uv, angle, 0.0 + rot, centerDist * d1, numcircles, circlesRad);
vec4 ring2 = ring(uv, angle, 0.5 + rot, centerDist * d2, numcircles, circlesRad);
// 混合结果
vec4 col = premulMix(ring1, ring2);
//添加一点距离阴影,增强深度感
col.rgb *= 1.0 - (centerDist * centerDist) * 0.4;
return col;
}
// 给定半径计算双环,用几个缩放值填满圆
vec4 autoRing(vec2 uv, float angle, float centerDist, float t)
{
float nbCircles = 1.0 + floor(centerDist * 23.0);
return dblRing(uv, angle, centerDist, nbCircles, 0.23, t);
}
// 在某一时刻计算像素颜色
vec3 fullImage(vec2 uv, float angle, float centerDist, float t)
{
vec3 col;
// 屏幕以同心圆剪裁
float space = 0.1;
// 指定像素在哪个圆环里面
float ringRad = floor(centerDist / space) * space;
// 计算“前中后”圆环的缩放
vec4 ringCol1 = autoRing(uv, angle, ringRad - space, t);
vec4 ringCol2 = autoRing(uv, angle, ringRad, t);
vec4 ringCol3 = autoRing(uv, angle, ringRad + space, t);
// 除了中心之外,把所有东西混合到一起
if (ringRad > 0.0)
{
col.rgb = ringCol3.rgb;
col.rgb = premulMix(ringCol2, col.rgb);
col.rgb = premulMix(ringCol1, col.rgb);
}
else
{
col.rgb = ringCol2.rgb;
}
return col;
}
// 一个噪波函数,用在这里,看上去更高斯视觉一些
float noise21(vec2 uv)
{
vec2 n = fract(uv* vec2(19.48, 139.9));
n += sin(dot(uv, uv + 30.7)) * 47.0;
return fract(n.x * n.y);
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
// 归一化像素坐标
vec2 uv = (fragCoord - .5 * iResolution.xy) / iResolution.y;
uv *= 0.9;
// 计算极坐标
float angle = atan(uv.y, uv.x) / 6.283 + 0.5;
float centerDist = length(uv);
vec3 col = vec3(0.0);
//在稍微不同的时间,取4个采样的均值进行运动模糊
float noise = noise21(uv + iTime);
for (float i = 0.0; i < 4.0; i++)
{
col += fullImage(uv, angle, centerDist, iTime - ((i + noise) * 0.03));
}
col /= 4.0;
//输出到屏幕
fragColor = vec4(col,1.0);
}