WebGL Animated Grapheme - Demon Lord

Sougwen Chung dropped by our co-working space on Gran Canaria and one of her projects that I found fascinating were the animated grapheme called “Kinexuviae”.

Looking at them, I first thought “let’s pre-render my own set with 3ds max as animated gifs”, but then I wanted the letters to influence each other and their environment, so instead I went with WebGL and some noise textures.

>>> Click here try it out <<<

Basically, this is the three.js THREE.EffectComposer with the following effect chain:

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
Draw the text
blur
blur
blur
blur
save this as rtBlurFew

blur
blur
levels
multiply with barbed wire texture
levels
colorize
save this as rtLayer10

multiply with noise texture
blur
blur
levels

fill rtBlood with current (text * blur * noise * blur * levels)
blur
blur
apply levels and store result into rtContinuousBloodInput

move from rtBlood to rtBlood2
blur
blur
move from rtBlood2 back to main buffer
blur
blur
multiply with noise
levels
store as rtLayer9

blur
blur
blur
blur
blur
blur
levels
blur
blur
multiply with noise
levels
colorize
store as rtLayer11

load from rtBlurFew
blur
blur
levels
multiply with noise
levels
colorize
store as rtLayer12

re-draw text on black background
multiply with noise
blur
blur
levels
store as rtLayer14

load from rtContinuousBloodInput
move and add rtContinuousBlood
blur
blur
store back into rtContinuousBlood for next frame
colorize
levels
add rtLayer12
add rtLayer11
subtract rtLayer9
subtract rtLayer10
subtract rtLayer14
subtract rtLayer14 with offset for ghosting effect

copy to screen

For the dripping blood effect, I ping-pong between two render targets with an offset to make things move over time. From rtContinuousBlood, last frame’s data is copied into the main buffer. I add rtContinuousBloodInput, move things a bit, blur it a bit, and store it back into rtContinuousBlood for next frame.

rtContinuousBloodInput is basically text * blur * noise * blur * levels, so nothing fancy.

For the curious, see the source code of index.html. And shaders are: HajoColorizeShader.js. HajoLevelsShader.js. HajoMultiplyShader.js. HajoOffsetAddShader.js.