ざらざらした模様(テクスチャ)を作る
この模様の種は 1 です。
同じ種を入れれば、いつでもこの模様に戻ってこられます。
- 粒の大きさ
- 2px(64px の中に 32 個)
- 継ぎ目の段差
- 4.25 / 粒の境目 4.24(比 1.00)
- data URI の長さ
- —
1つ動かすだけで、模様は似ても似つかないものになります。となりの種が「となりの模様」にならないのは、種をかき混ぜてから使っているからです。
敷きつめたところ
CSS の背景は、この 64×64px をタイルのように敷きつめて広い面を 埋めます。上の目盛りの真下が、タイルとタイルの境目です。そこに線が見えないことを確かめてください。
持ち帰る
画面がついたところで、貼れる形にします。
入れた種も、できた模様も、お使いのブラウザの中だけで処理します。計算も画像づくりも、ぜんぶこのブラウザの中で終わっています。
よくある質問
同じ種を入れれば、いつでも同じ模様になりますか?
なります。粒の場所と種を混ぜて計算した数を、そのまま濃さにしています。計算に使うのは掛け算とビットのずらしと排他的論理和だけで、小数も三角関数も出てきません。だからどの機械のどのブラウザで開いても、同じ種からは1粒の狂いもなく同じ模様が出ます。単体テストが、16,384個の値が1つ残らず一致することを見張っています。
種に言葉を入れると、何が起きているのですか?
言葉をUTF-8のバイトに直し、1バイトずつ「排他的論理和をとって素数を掛ける」を繰り返して、32ビットの数に畳んでいます。FNV-1aという古くからある畳み方です。畳んだ数は画面に出しているので、その数のほうを書き留めておけば、あとから確実に同じ模様へ戻れます。ただし畳むと情報は減るので、まったく別の言葉が同じ数になることは理屈のうえではありえます。
繰り返して敷いたとき、継ぎ目の線は見えませんか?
見えません。ざらざらは隣の粒とまったく関係なく決まるので、タイルの端も内側も同じ性質になり、継ぎ目は粒と粒の境目に紛れます。この道具は継ぎ目の段差と、タイルの中の粒の境目の段差を測って比べていて、その比が1に近いことを画面に出しています。気をつけるのは2つだけで、粒の大きさをタイルの幅で割り切れる数にすることと、CSSで画像を引き伸ばさないことです。
うすいざらつきを、透明度(opacity)で作ってはいけませんか?
作れますが、2つ困ることがあります。ひとつは、下に敷いた色が変わると見え方まで変わってしまい、書き出した画像だけでは仕上がりが決まらないこと。もうひとつは、その上に文字を置いたときに、文字と背景の明るさの差が想定より縮んでしまうことです。この道具は透明度を使わず、粒の色の値そのものを地の色に近づけています。だから書き出したPNGは全部不透明で、地の色ごと持っています。
data URIが長すぎます。短くできますか?
粒を大きくすると短くなります。PNGの圧縮は「さっきと同じ並びが出てきた」ところを見つけて縮める仕組みなので、同じ値が何個も続く大きな粒はよく縮みます。反対に1pxの細かい粒はあまり縮みません。隣と関係なくばらけている並びには、「さっきと同じ」がめったに現れないからです。それでも長いときは、PNGとして保存してファイルを置き、CSSからはurl()でそのファイルを指してください。
粒の大きさに6pxを選ぶと、何がちがうのですか?
64を6で割ると10個と余り4になるので、タイルの右端と下端の粒だけが4pxに切れます。切れた細い粒が64pxおきに並ぶため、粒の並びのリズムがそこだけ崩れます。濃さを大きくすると縦や横のすじとして見つけられます。この道具は黙って割り切れる数に直したりせず、6pxと言われたら6pxで作って、端が切れることを画面に書きます。
模様を動かして、テレビの砂嵐のようにできますか?
この道具では作れません。細かい点が高速でちらつく映像は目が疲れますし、パソコンやスマートフォンの設定で「動きを減らす」を選んでいる人もいます。書き出すCSSにも、動きの指定は1行も入れていません。ウェブアクセシビリティの達成基準2.2.2も、5秒以上ひとりでに動き続けるものには止める手段を用意するよう求めています。
平らな背景色に、紙のような手ざわりを足す粒を作ります。種(シード)を決めておけば、同じ模様に何度でも戻ってこられます。
まっさらな1色は、画面だと少しのっぺりします
紙は細かい繊維でできていて、表面で光がこまかく散ります。手ざわりが見えるのはそのためです。 ところが画面の背景を1色で塗ると、その散らばりがまったく無い面になります。 きれいではあるのですが、のっぺりとも見えます。
そこでごく薄いざらつきを重ねます。この道具の既定は濃さ6、つまり色の256段のうち上下に6段だけ動かす量です。 近づいて探せば粒が見えますが、離れると「なんとなく質感がある」くらいにしか感じません。その、わずかな差が「平ら」を壊します。
濃さを20や30まで上げると、紙ではなくざらざらした模様そのものになります。 どちらが正しいということはありません。文字を上に置くなら、薄いほうが読みやすいとだけ言えます。
ただの乱数だと、気に入った模様を二度と作れません
ここがこの道具のいちばん大事なところです。画面を開くたびにその場で乱数を引く作りにすると、模様は毎回変わります。 「さっきのがよかった」と思っても、もう二度と同じものは出てきません。
だからこの道具は乱数を1回も引いていません。粒の場所と種を混ぜて計算した数を、そのまま濃さにしています。 種が同じなら、計算の答えも同じ。だから模様も同じです。 種は画面に必ず出してあるので、書き留めておけばいつでも戻ってこられます。
へえ: 種を1つ増やすだけで、模様は似ても似つかないものになります
種の1と2はとなりどうしの数ですが、出てくる模様に似たところはありません。 種をそのまま使わず、掛け算とビットのずらしでかき混ぜてから使っているためです。
この混ぜ方にはアバランチ(なだれ)という性質があります。 入れる数を1ビットだけ変えると、出てくる32ビットのおよそ半分が変わる、というものです。実際に数えてみると平均で16ビットちょうど前後になります。単体テストでも数え直していて、 15から17のあいだに入らなければ落ちるようにしてあります。
へえ: 種は約43億通り。作れる模様のほうは9,865桁あります
種は32ビットの数なので、全部で4,294,967,296通り(0から4,294,967,295まで)です。43億通りと聞くと、 いくらでも作れそうに思えます。
ところがタイルには粒が64×64=4,096個あって、1粒に256段の濃さを自由に置けるとすると、模様は256の4,096乗通り。 これは9,865桁の数です。 43億は10桁ですから、この道具が触れているのは、その海のごく一部でしかありません。
「無限に作れます」と書いてある道具を見かけたら、たいていは種の数ぶんしか作れません。それでも43億通りあれば、 一生かかっても見尽くせない量ではあります。
繰り返しても継ぎ目が出ないのは、ざらざらだからです
CSSの背景は、小さな正方形をタイルのように敷きつめて広い面を埋めます。 この道具が作るのは64×64pxの1枚です。
ふつう、模様を繰り返すと境目に線が見えます。 タイルの右端と、その右にくっつく次のタイルの左端が、つながっていないからです。だから模様を作る道具は、 たいてい「端をつなぐ」ための工夫をしています。
ところが、ざらざらにはその問題がありません。1粒ずつの濃さが隣の粒とまったく関係なく決まっているので、 タイルの端も内側もまったく同じ性質です。 右端と次の左端がつながっていないのは本当ですが、内側の粒どうしだって、はじめからつながっていません。 だから継ぎ目は、粒と粒の境目に紛れて見えなくなります。
この道具は、それを数でも確かめられるようにしてあります。 画面に出ている「継ぎ目の段差」は、右端の画素と、その右隣(=次のタイルの左端)の色の違いの平均。 となりに並べてある「粒の境目」は、タイルの中で粒が切り替わるところの平均です。この2つがほぼ同じ(比が1に近い)なら、継ぎ目はただの粒の境目と見分けがつきません。
なお、隣とつながって波打つ「なめらかな模様」は話がまったく別で、 端をつなぐための専用の作り方が要ります。ここで作っているのは隣どうしが無関係な粒のほうです。
それでも気をつけることが2つあります
1つめは粒の大きさです。粒はタイルの中に整数個ならんでいてほしいので、64を割り切る数(1・2・4・8)だけを選べるようにしてあります。 たとえば6pxにすると、64÷6は10個と余り4なので、端の粒だけが4pxに切れます。この細い列が64pxおきに並ぶと、 粒の並びのリズムがそこだけ崩れて、すじとして見つかります。 道具の中に「そろわない見本」を残してあるので、押して確かめてみてください。
2つめはCSSで引き伸ばさないことです。書き出すCSSにbackground-size: 64px 64px; と実寸を書いているのはそのためで、 大きく引き伸ばすとブラウザが画素と画素のあいだを混ぜ、タイルの境目でだけ混ぜ方が変わって、そこに線が出ます。
「継ぎ目」とは別に「繰り返しに気づくこと」もあります。 同じ並びが64pxごとに出てくるので、濃さが強いと目がその周期に気づきます。 薄くすればまず気づきません。タイルを大きくしても減りますが、画像の重さは1辺の2乗で増えます。
うすさを「透明」で作らなかったわけ
薄いざらつきは、濃い粒を透けさせて作るのがいちばん簡単です。 でもこの道具はそうしていません。粒の色の値そのものを、地の色に近づけています。 理由は2つあります。
1つめは、透けさせると仕上がりが1枚では決まらないことです。 下に何色を敷いたかで見え方が変わるので、書き出したPNGを別の場所に貼ると濃さが変わります。 色の値そのものを動かしておけば、その1枚で完成しています。
2つめは文字の読みやすさです。透けさせた層を文字に重ねると、文字と背景の明るさの差(コントラスト比)が、決めたはずの値より縮みます。 しかも縮んだことは、色の指定をいくら見返しても分かりません。 このサイトが文字に透明度を掛けないことにしているのも同じ理由です。
模様は、止めたまま出します
ざらざらは、動かすとテレビの砂嵐になります。見た目には面白いのですが、 細かい点が速くちらつく映像は目が疲れます。 パソコンやスマートフォンには「動きを減らす」という設定があり、 ウェブのページはその設定を読み取って動きを止めることができます (CSSの prefers-reduced-motion)。
ウェブアクセシビリティの達成基準2.2.2(新しいタブで開きます)も、ひとりでに5秒以上動き続けるものには止める手段を用意するよう求めています。 この道具は最初から動かさないので、書き出すCSSにも動きの指定は1行もありません。
粒の濃さは、こうやって決まっています
乱数には大きく2つの作り方があります。1つは前の値から次の値を作って、順番に並べていく作り(流れ)。 もう1つは場所を渡すと、その場所の値がすぐ返ってくる作りです。 この道具は後者を選びました。理由が2つあります。
1つめは、タイルの外の座標を聞けることです。 「右端のさらに右」を計算できるからこそ、継ぎ目の段差を画像を並べずに数で検算できます。
2つめは、種に0を使えることです。流れの作りでよく使われるxorshiftという手順は、0を入れるとずっと0のままになります。 0は自分自身に戻ってしまう、輪から外れた数だからです。 すると種に0が使えず、こっそり別の数にすり替えることになります。黙ってすり替えるのは、この道具のいちばん嫌うところなので、 場所ごとに計算する作りにしました。
計算の出どころ: かき混ぜはMurmurHash3 の仕上げ(fmix32)(新しいタブで開きます)、言葉から数への畳み込みはFNV-1a(32ビット)(新しいタブで開きます)、掛け算に使う定数2,654,435,769は2の32乗を黄金比で割った数です。 単体テストが、FNV-1aの公表されている検査値 (a なら e40c292c)との一致と、黄金比の定数の計算し直しを 毎回確かめています。