Imaginantia

思ったことを書きます

ゆらゆらごーすとのつくりかた

f:id:phi16_ind:20210527123249p:plain

はじめに

まずロゴを頂きます。めちゃくちゃびっくりします。あまりにも良かったので叫びます。

折角なので動かしたいという話を聞きます。ついでにぶいちゃで動くと最強です。

というわけで Domain Warping をすることにします。

もっと言うと、特定の Vector Field に従って Domain Warp した結果がロゴになるようにすることに、します。

よういする

Kerasを取り出します。

まずベクトル場レイヤーをつくります。こんな感じ

2次元のグリッドの各格子点にベクトルを与えてbicubic補完した値を返すレイヤーです。

そしてこれを紆余曲折しながら4枚繋げます。

def create_model():

    input = Input((2,))
    flow1 = flowlayer.FlowLayer(8, 32, -ratio, ratio, -1, 1)
    flow2 = flowlayer.FlowLayer(8, 32, -ratio, ratio, -1, 1)
    flow3 = flowlayer.FlowLayer(16, 64, -ratio, ratio, -1, 1)
    
    def w4(x):
        return Lambda(lambda x: x * 0.25)(x)
    def w3(x):
        return Lambda(lambda x: x * 0.5)(x)
    def w2(x):
        return Lambda(lambda x: x * 0.5)(x)
    def w1(x):
        return Lambda(lambda x: x * 1.0)(x)

    d2 = Dense(2)

    def fu(a):
        x = a
        x = Add()([x, w4(flow3(x))])
        x = Add()([x, w3(flow2(x))])
        x = Add()([x, w2(flow3(x))])
        x = Add()([x, w1(flow2(x))])
        return x

    def ac(a):
        x = a
        x = flow1(x)
        x = d2(x)
        x = Activation("sigmoid")(x)
        return x

    x = input
    x = fu(x)
    x = ac(x)

    ...

あとは回すだけですが、適当なlossにするとぐちゃぐちゃになって終わるので、今回は binary cross-entropy に加えて「合成されたベクトル場の (Δ=0.001で差分を取った) ラプラシアンの総和」もlossにいれます。これで尖りが減った気がします。

実行すると全然きれいになる気配がないので対策を考えます。

そだてる

最初から複雑な形状にするのはしんどそうなので手で成長方向を指定してあげることにします。

f:id:phi16_ind:20210527125035p:plain

そしてこれらの間を適当に補間 (sdfにしてlerp) させつつ順番に学習器にあたえます。

f:id:phi16_ind:20210527125221p:plain

育ちました (GT, Result, 合成ベクトル場, flow1, flow2, flow3 です)。

ベクトル場の解像度が高いとロゴそのものになっちゃうので適度に能力を潰さないといけないのがむずかしいですね。能力を下げすぎると壊れるし。

現在もまぁ完璧ではないです。

うつしかえる

完成した重みを画像としてexportします。

f:id:phi16_ind:20210527125525p:plain

後はデコーダを書きます。ちなみに4-sample bicubic interpolationはこの過程で出来たやつです。

ついでにまだかわいい目と口?が無いのでシェーダおえかきでぐっと書きます。

f:id:phi16_ind:20210527130030p:plain

できました。

かわいがる

幾つかの演算の結果としてこの状態になっているわけで、その過程を弄るとそれ相応に歪みます。

f:id:phi16_ind:20210527181009p:plain

また、最終的な単色の値だけではなく、中間のベクトル場をそのままdistortionに使えばガラスっぽい感じにもなります。

f:id:phi16_ind:20210527181445p:plain

さて、色々試すにはシェーダコードを弄る必要があるわけですが、折角なのでぶいちゃ上で操作したいところです。

というわけでノードエディタをつくります。

f:id:phi16_ind:20210527181319p:plain

できました。そう。これです。これ

これのつくりかた

  • まずノードを「前から順にソート」します。(バブルソートの1工程だけを1Fでやって時間方向に負荷分散)
  • 前から走査していくとグラフの接続状況が確定します。
  • そこから処理内容のアセンブリコードみたいなものが生えます。
  • その情報をVectorArrayに詰め込んでシェーダに渡して、VMっぽい処理を走らせます。
  • できました。

が、つかいません。使いませんでした。

もっかいうつしかえる

とりあえず放置していたところWebページのティザーとして使えないかという話がきます。

というわけでWebGLに移植します。しました。

あとはいい感じにシェーダを書くといい感じになります。よかったね。

要望としては「ロゴをまだ明らかにしない段階で、ロゴの『輪郭』を出す」というものがあったので (ティザーだからね)、今回のこれはぴったりなのでした。元データ入ってないからね。

ちなみに背景は全部これまでとこれからのGC (とテクノビネガー) の写真です。その domain warp です。あれは。

f:id:phi16_ind:20210527183026p:plain

なつかしいですね。

ティザーとしての役割は全うできたのではないかなと思います。

おわりに

というわけでそんなことをやっていました。

今のところ使いみちがあるわけではないんですが、そのうちどこかで使えたら良いですね。

あともっとおもしろい方法はあると思う。当然この過程にはめちゃくちゃ試行錯誤があってこうなったわけですが、造り手が違えば結果も違うもので。

今回は私がこうしたかったからこうなったので、あの子のもっとかわいい動きがあればとても見てみたい気持ちです。

 

全てにおいて、あの素晴らしいロゴを制作なさったなべさんに感謝をもうしあげます。

おまけ

試行錯誤過程の写真です。

f:id:phi16_ind:20210527185842p:plain

これはこれでいいですね。