はじめに
こんにちは, 学部3年の木村です.
この記事では, 私がよく使わせて頂いているこのアバターの着物の模様を自分でもかきたくなったのでシェーダーで袖に絵を描けるようにしたことを書きます.
試したこと
袖の領域をマスクする
まずは袖のマスク用のテクスチャを用意しました.
こんな感じで袖の領域を切り抜けます.
シェーダーはArktoon-Shadersを少し改変して使いました.
arcludeFrag.cginc
のフラグメントシェーダーでDiffuse
が宣言している箇所を以下のように変更し, float3 customColor(float2 uv, float3 color)
関数内で絵を描きます.
float3 Diffuse = (customColor(i.uv0, _MainTex_var.rgb)*REF_COLOR.rgb);
上の画像のようにマスクした領域をピンクに塗る場合はこのようになります.
float3 customColor(float2 uv, float3 color) { float mask = UNITY_SAMPLE_TEX2D(REF_SHADERMASK, TRANSFORM_TEX(uv, REF_SHADERMASK)).r; return lerp(color, float3(1, 0, 1), mask); }
ここで試しに袖に絵を描いてみましたが, 境界線が目立ってしまってよくなかったです.
UV座標を見て頑張る
次に試したのは絵を描きたい領域をUV座標で直接切り分ける方法です.
float2 st = uv*2. - 1.; float3 col = color; if(color.r >= .1 && color.g >= .1 && color.b >= .1) return float3(st, 0); // 襟の部分 if(st.x >= 0.) return float3(st, 0); // 胴の部分 if(st.y <= 0.) { // 左袖 st = mul(st + 1., R(-.74)); float i = smoothstep(.5, 1., st.x); st.x -= _Time.x*.5; st.y += _Time.x; col = lerp(col, float3(st.x-.83, st.y+.2, 0), i); } else { // 右袖 st = mul(st, R(-.85)); float i = smoothstep(.5, 1.,st.y); st.x += _Time.x; st.y -= _Time.x*.5; col = lerp(col, float3(st.x + .25, st.y-.8, 0), i); } return col;
無理矢理感しかないですが, とりあえず部位ごとに色を塗れるようになりました.
あとは袖にだけ絵を描きます.
最終的にこうなりました
着物の柄できた! pic.twitter.com/7Js4e8ggbU
— bigdra (@bigdra50) May 6, 2020
花びらの距離関数
float sdFlower(float2 p, float size) { p+= .5; p*=.7; float a = atan2(p.y, p.x); // -PI~PI a+= sin(_Time.y); float d = min(abs(cos(a * 5.) + .4), abs(sin(a * 5.)) + 1.1) * .32*size; return step(length(p), d); }
今後
この記事を書いてる途中でマスクを使っても境界線は誤魔化せそうだなと思いました.
また, 花びらの動き方など単調なのでもっと自然の花びらのような動きをさせたいです.