前書き
キューブの見た目を更新する目的で動いています。
前回は Shader ができたところまで
simplestar-tech.hatenablog.com
今回はテクスチャを連番で結合する処理を作ります。
大分前に python の pillow で画像処理を書きましたが…
github.com
処理が遅すぎるのと
画像のエッジの引き延ばしを行っていなかったので、キューブ群を遠目で見ると結合部分が光ったり黒くなったり…とにかく見た目が良くない
その部分を今回は imagemagick を利用して解決していきます。
参考までに、昔のキューブの見た目は頑張ってこんなの
simplestar-tech.hatenablog.com
もう2年以上、技術選定を続けているという…今年は完成させるぞ!
simplestar-tech.hatenablog.com
Imagemagick の基本を習得
まずは Windows 環境で使えるように portable 版をダウンロードして展開し PATH を通しておきます。
imagemagick.org
以降、Windows 環境だと convert コマンドを magick にしなければバッティングする旨を imagemagick が教えてくれるので
magick コマンドを利用します。
そうしたことを念頭に次のマニュアルを完走して、imagemagick を身体になじませました。
Imagemagick での画像のエッジ引き延ばし
情報ソースはこちら
www.imagemagick.org
細かいことは置いとくと、次の倍率を指定するだけで余白を引き延ばすことができます。
(残念ながら distort は基本操作には出てこない)
magick in.png -set option:distort:viewport %[fx:w*(1+0.05)]x%[fx:h*(1+0.05)] -virtual-pixel Edge -distort SRT "0,0 1,1 0 %[fx:w/(2/0.05)],%[fx:h/(2/0.05)]" out.png
ちょっとだけ解説すると
distort:vieport が left, top 引き延ばし幅に関与&全体の幅高さ倍率指定
virtual^pixel Edge が right, bottom の引き延ばし幅に関与していて、要するに 1 引いた倍率を 1/2 倍で指定というながれ
画像を変換してタイル状に並べる
変換した画像を利用するという小技について、まずはおさらい。
こちらの画像を入力に(昔、自分が描いた絵です)
こちらの処理を実行すると
magick in.jpg -resize 200x200 -size 300x300 xc:blue +swap -gravity center -compose over -composite -mattecolor red -frame 10x10 exit.jpg
意味は、200x200 にアスペクト比を保ったまま縮小して、blue 一色で塗りつぶした 300x300 の画像を新規作成、並び順を入れ替えて、conposite により青を背景に重ね合わせて、10pixel 幅の赤いフレームを追加
という文(読めました?)
次の結果が得られます。
PowerShell で実行する複数ファイル作成とタイリングモンタージュ
以下の powershell は Windows 環境で imagemagick に PATH が通っていれば動きます。
テクスチャはこちらの有料アセット(single entity license)を購入したものを利用します。
Yughues PBR Nature Materials
assetstore.unity.com
tga ファイルは magick で変換すると上下逆転しますし、Specular は png に tga から変換すると背景色が真っ白に変わるので(本当は黒)
一度 jpg に中間ファイルを出して、上下反転しつつもなんとか
あと、ファイルによっては正方形ではないので正方形に直します。
加えて、左右に 8 pixel の余白を設けるように 1008 x 1008 に圧縮してタイリングしたいと思います。
を実現する Powershell が以下の通り
# [AO, Diffuse, Height, Normal, Specular] $target = "Specular" New-Item $target -ItemType Directory -Force $dir = "~\Assets\Yughues PBS Nature Materials" $imgs = Get-ChildItem -Recurse -Path "$dir\*$target.tga" foreach ($img in $imgs) { $fullName = $img.FullName $jpg = "$target\" + [io.path]::ChangeExtension($img.Name, "jpg") $id = identify $fullName $edge = 0.0158730 if ($id -like "*512x1024*") { magick $fullName -resize 504x1008 -flip -write mpr:i +delete mpr:i mpr:i +append -set option:distort:viewport "%[fx:w*(1+$edge)]x%[fx:h*(1+$edge)]" -virtual-pixel Edge -distort SRT "0,0 1,1 0 %[fx:w/(2/$edge)],%[fx:h/(2/$edge)]" -quality 100 $jpg } else { magick $fullName -resize 1008x1008 -flip -set option:distort:viewport "%[fx:w*(1+$edge)]x%[fx:h*(1+$edge)]" -virtual-pixel Edge -distort SRT "0,0 1,1 0 %[fx:w/(2/$edge)],%[fx:h/(2/$edge)]" -quality 100 $jpg } echo $jpg } montage "$target\*$target.jpg" -tile 8x8 -geometry 1024x1024 "0_$target.png"
出力されるテクスチャを使って、Height map を利用しつつ絵を作ることができました。
ステップ2はクリアです。
残すはゲーム内の UV 操作のみ
追記
余白をエッジ引き延ばしするのもよかった
だけど parallax で使う場合はかなり余白を利用することになるし、そこがエッジ引き延ばしだとまた不自然な見た目になったので
リピートラッピングする方法を考案しました。
次の命令は画像の上下左右ななめ方向すべてにタイリングする例です
magick in.jpg -resize 960x960 -flip -write mpr:i +delete mpr:i mpr:i mpr:i +append -write mpr:j +delete mpr:j mpr:j mpr:j -append -gravity center -crop 1024x1024+0+0 -quality 100 out.jpg
これをスクリプトにつなげると
# [AO, Diffuse, Height, Normal, Specular] $target = "Diffuse" New-Item $target -ItemType Directory -Force $dir = "D:\github\Unity\UniversalParallaxOffset\Assets\Yughues PBS Nature Materials" $imgs = Get-ChildItem -Recurse -Path "$dir\*$target.tga" foreach ($img in $imgs) { $fullName = $img.FullName $jpg = "$target\" + [io.path]::ChangeExtension($img.Name, "jpg") $id = identify $fullName if ($id -like "*512x1024*") { magick $fullName -resize 480x960 -flip -write mpr:i +delete mpr:i mpr:i +append -write mpr:j +delete mpr:j mpr:j mpr:j +append -write mpr:k +delete mpr:k mpr:k mpr:k -append -gravity center -crop 1024x1024+0+0 -quality 100 $jpg } else { magick $fullName -resize 960x960 -flip -write mpr:j +delete mpr:j mpr:j mpr:j +append -write mpr:k +delete mpr:k mpr:k mpr:k -append -gravity center -crop 1024x1024+0+0 -quality 100 $jpg } echo $jpg } montage "$target\*$target.jpg" -tile 8x8 -geometry 1024x1024 "0_$target.png"
期待通り