

とあるIT企業のインフラエンジニア。プライベートでは開発もちょっとやります。
※本ブログの内容はすべて個人の見解であり、所属する企業とは関連ありません。
2023/09/30 暫く更新停止中m




























291 [今日]
796 [昨日]
【マイクラ】ブロックを1つも触らずにMinecraftで現実世界を再現する2




お疲れ様です。
しらせです。
先日、Minecraftで1ブロックも触らずに地形を再現するネタを投稿しました。
【マイクラ】ブロックを1つも触らずにMinecraftで現実世界を再現する
今回はより実際の色合いを再現するためにスクリプトを変えながら試行錯誤してみた結果をまとめます。
もくじ
色を表現するには?
基本的な考え
前回ご紹介しましたように、画像をマインクラフトの地形に転写するためには、色とブロックを紐づけてあげる必要があります。
一般的な画像(※ここでは24bit画像)は、青(B)、緑(G)、赤(R)の3色についてそれぞれ0~255の256段階の強弱を組み合わせることで約1,677万の色合いを再現しています。
例えば青色ならB,G,R=255,0,0で、緑色ならB,G,R=0,255,0のように数値が大きい色が強く表現されます。
同様に光の三原色のように色を組み合わせることで別の色にもなります。
黄色であればB,G,R=0,255,255で表現され、ピンク色はB,G,R=255,0,255で表現されます。
マインクラフトのブロックは1,677万種類も無いですし、100%同じ色のブロックがあるわけでもありません。
そのため、主に石・草・テラコッタ・コンクリートブロックなどの地形用のブロックをベースに似た色を探すしかありません。
そこで考えたのが青緑赤をそれぞれざっくり3段階に分けて色を再現する方法でした。
分け方は前回ご紹介した通り、以下のように0~84,85~169,170~255などで分割する方法です。
すべてを3段階で表現すると以下のような対応関係が表せます。
どんな色のブロックが最適か?は自分の目で見て当てはめました。
白と黒の扱い
青緑赤をそれぞれ0~2の3段階で分割して27色で表現するのはそこそこ良いアイデアだったと思ってました。
ただ1点クリアしておくべきポイントがありました。
それが「黒」と「白」の扱いです。
例えば画像の方はB,G,R=90,80,80(=灰色)で表現される色のブロックが、上記のやり方で27色の変換を入れてしまうと最も近いB,G,R=128,42,42(=1,0,0:blue_concrete)に当たるブロックが選択されてしまいます。
本来であれば各色が10程度しか離れていないのであれば灰色が選択されるべきですが、極端な色のブロックが選択されるケースが出てしまいます。
そのために考えたのが白黒判定のロジックです。
青緑赤のそれぞれの数値が一定の範囲でのズレであれば白黒の判定を入れるというものです。
数値誤差に10を指定すると、0,9,3のような限りなく黒に近い色は黒ブロックを割り当て、0,40,30のように誤差を超える場合はカラーテーブルと対比させるというものです。
これにより白黒の判定が明確にできるようになりました。
再現上の問題
27色の表現でマインクラフトに転写した以下の2枚をご覧ください。
どちらも以下の写真をベースに書き出した結果です。
緑色の再現が微妙すぎて、片方は冬のような印象でもう片方は初夏を思わせる色合いになってしまっています。
こうなってしまう理由ですが、前述のカラーテーブルと色の判定に問題があります。
特に問題となるのが以下の箇所です。
緑色のきれいな色合いは青は少なく緑と赤が中間で散らばることで表現されます。
27色の表現ではこれができないのです。
つまりB,G,R=0,1,1にライムグリーンを入れると初夏になり、逆にdirt_pathブロックを入れると冬になるという問題でした。
これを解決する手段として色の分割を4段階に増やして64色にすることでした。
色の再現度を高める
ブロックの色の分析
ブロックの色抽出についても注意します。
草ブロックや石ブロックを近くで見ると、微妙に模様が入っているのが分かります。
感覚で色を判断してしまうと近い色を紐づけられないことが分かりましたので、ブロック1つ1つを青緑赤で分析しました。
マインクラフトのブロック画像データはjarファイルを解凍して以下のパスから確認ができます。
1.18.1.jar\assets\minecraft\textures\block
基本的なブロックはすべて16x16のPNG形式になっています。
一部のブロックは縦横比が異なっていたり、縁の表現のため枠1ピクセルだけ色が異なっていたりします。
そこでブロックの縁から1ピクセル削った中身の色をブロックごとに平均化して、16進数表記にしたときの2桁目をすべて分析してみました。
ファイル名の先頭にBGRが付いています。
64色化
前述の通り、27色ではきれいな色分けができないという問題がありました。
そこで考えたのがより細かく色を分けるという事です。
0~63,64~127,128~191,192~255の4区分で0~3の4段階で分けたうえで、それに近い色のブロックを紐づける作業です。
各色の中央値を判定用に使用します。
0~63は31、64~127は96などです。
各色の中央値をベースにして、色の分析を終えたブロックと最も近い色のブロックを紐づけてあげます。
めちゃくちゃ地道です。
出来上がったのが以下のカラーテーブルです。
同値の調整
64色の表現はこれでOKなのですが、やはり4段階という幅はまだ広いので正しい色合いにならないことがあります。
そこで考えたのが3色とも同じ区分の中で数値の差が大きい場合は無理やり段階を変える調整です。
例えば、色がそれぞれB,G,R=65,120,120だった場合を見てみます。
色としては暗い黄色というか、暗いカーキ色というか、、微妙な色です。
※アプリ:azpaint
この色は4分割での判定は1,1,1になってしまい色としてはB,G,R=96,96,96(=灰色)になってしまいます。
そこで、3色の平均から各色が一定の数値以上離れている場合は色の段階を増減させるロジックを入れてみます。
上記の例だと平均が約102になりますので、平均から20以上離れている場合は色の段階を増減させるように組み込むと、、、
青が1段階下がり0,1,1に調整されます。
すると、B,G,R=31,96,96に近い色に調整されるため、本来の色に近い色を表現できます。
これでも完全ではありませんが、、
実装した結果は…
これを実装した結果がこちら!!!
※黒が青く見える箇所は私の設定ミスです
かなり色が本物に近くなりました!像
元画像と並べてみると一目瞭然です。
コントラストが高まって季節感が表現されました。
まとめ
一応地形情報と組み合わせてみましたが、こちらもすごく自然な仕上がりになりました。
個人的には大満足で狙い通りの結果が出せました。
これ以上活用の幅はありませんので、あとは細々と一人で遊ぼうと思いますw
Windows10+.Net4.8で動く実行ファイル形式になっていますので、
もしアプリが欲しい!という方がいましたらTwitterなどでご連絡頂ければ公開も検討します^^;
以上
おつかれさまでした。