この記事はNihon University Advent Calendar 2024の24日目の記事です。
この記事はJava版1.21.4向けの記事です。
リソースパックは、Java版(PC版)とBedrock版(コンソール版)のどちらにも存在しますが、これらは仕様が大きく異なるのでご注意ください。
この記事は、Minecraftのリソースパック機能について紹介する記事であり、リソースパックシェーダーのチュートリアルを目的とするものではありません。
はじめに
Minecraftには、プレイヤーがMinecraftをカスタマイズするための仕組みがたくさん用意されています。
しかし、Minecraftをカスタムする機能としてMod、ShaderPack、Pluginなどが非常に有名である一方、ResourcePack
やDataPack
が日の目を見ることはあまりないように感じています。
この記事では、Java版Minecraftに用意されているリソースパック機能の一つであるリソパシェーダーについて私が学習したことを共有して、
「リソースパックってこんなことまでできるのかスゲー」
という気持ちを一方的に共有したい(?)と思います。
シェーダーってなに?
そもそも、シェーダーとはなんでしょうか?シェーダーはシェーディングに利用されます。シェーディングとは、物体に陰影を与えることで立体感をだす処理のことを指します。
ResourcePacksってなに?
では、この記事で紹介している「リソースパック」ってどんなものでしょうか?Minecraft Wiki日本語版では、このように紹介されています。
リソースパック(英:Resource Pack)は、テクスチャ、翻訳文や言語、フォント、サウンド、モデル、およびエンドポエムやスプラッシュテキストなどを、ゲーム本体を書き換えることなくカスタマイズするための仕組みである。
つまり、リソースパックを使うことで、Minecraftの見た目や音を、プログラムを変更せずに 自由にカスタマイズすることができます!
リソパシェーダーってなに?
名前の通り、リソパシェーダー(リソースパックシェーダー / Resource Pack Shader)は リソースパックで作成するシェーダー のことです。GLSLで記述します。
Minecraftには、影Modを代表とするShaderPackという仕組みがありますが、これはModの一部でリソパシェーダーとは大きく異なります。
作ろう!リソパシェーダー
1. リソースパックを作ろう!
リソパの基本
リソースパックは、.minecraft/resourcepacks
に格納します。リソースパックは以下のような形となります。
testResourcePack
├─ assets
│ └─ minecraft
│ ├─ models
│ ├─ sounds
│ ├─ textures
│ └─ shaders
├─ pack.mcmeta
└─ pack.png
pack.mcmeta
には、以下のような内容を記述します。pack_formatにはリソースパックのバージョンを記載します。46
はMinecraft 1.21.4に対応しています。
参照:Mincraft Wiki / Pack format
{
"pack": {
"pack_format": 46,
"description": "モノクロなリソパシェーダー"
}
}
おすすめの環境
エディタ:
VSCode拡張機能:
2. リソパシェーダーの構成
リソパシェーダーの構成1(Coreとpost)
リソパシェーダーは大きく分けて、
Core shaders
Post-processing shaders
の二つに分類することができます。 それぞれの役割は以下のようになっています。
名前 | 役割 | イメージ |
---|---|---|
Core | 画面上に見える物体のレンダリング | |
post | 2Dになった画像(映像)をレンダリング |
参考:Guide to vanilla shaders
リソパシェーダーの構成2(json / vsh / fsh)
Coreシェーダーとpostシェーダーは以下のようなファイルで構成されています。
json
vsh
fsh
それぞれのファイルには以下のような役割があります。また、vshとfshはGLSLで記述します。
名前 | 役割 |
---|---|
json | vsh、fshファイルを呼び出す vsh、fshに渡すデータを指定する |
vsh | 頂点データを編集する |
fsh | 色データを指定する |
リソパシェーダーは、
core(json→vsh→fsh) → post(json→vsh→fsh)
の順に処理されます。
参考:【リソパシェーダー紹介】第1回 リソパシェーダーとは?
3. Re: リソパシェーダーを作ろう
この記事では、ブロックをモノクロにするリソパシェーダーを作成してみます。
シェーダーファイルの準備
Minecraftの中で、ブロックはterrain.vsh
とterrain.fsh
というファイルを使ってシェーディングされています。今回はブロック色のみを変更したいので、リソースパックにはterrain.fsh
のみを追加します。このファイルは作成したリソースパックのshaders
に追加しておきます。それぞれのシェーダーファイルの担当については以下のページが参考になります。
以前は、ブロックの種類によって異なるシェーダーファイルが使われていましたが、Minecraft 1.21.2以降はすべて、terrainというファイルで処理されるように変更されました。
また、リソースパックを導入する前のMinecraftで利用されているシェーダーファイルは、以下のページを参照できます。
こちらが、通常、Minecraftで利用されているterrain.fsh
です。
#version 150
#moj_import <minecraft:fog.glsl>
uniform sampler2D Sampler0;
uniform vec4 ColorModulator;
uniform float FogStart;
uniform float FogEnd;
uniform vec4 FogColor;
in float vertexDistance;
in vec4 vertexColor;
in vec2 texCoord0;
out vec4 fragColor;
void main() {
vec4 color = texture(Sampler0, texCoord0) * vertexColor * ColorModulator;
#ifdef ALPHA_CUTOUT
if (color.a < ALPHA_CUTOUT) {
discard;
}
#endif
fragColor = linear_fog(color, vertexDistance, FogStart, FogEnd, FogColor);
}
コードの追加
terrain.fsh
にコードを付け加えていきます。このシェーダーファイルでは最終的にfragColor
という変数が out
しているので、Minecraftで描画されるブロックの色味は、この変数で決定していることが分かります。一番下のこの行を書き換えれば、描画されるブロックの色味は異なるものになるはずです!
fragColor = linear_fog(color, vertexDistance, FogStart, FogEnd, FogColor);
そこで、上のコードを以下のように書き換えると、
- fragColor = linear_fog(color, vertexDistance, FogStart, FogEnd, FogColor);
+ float brightness = dot(color.rgb, vec3(0.299, 0.587, 0.114));
+ float levels = 10.0;
+ brightness = floor(brightness * levels) / (levels - 1.0);
+ fragColor = vec4(vec3(brightness), 1.0);
float brightness = dot(color.rgb, vec3(0.299, 0.587, 0.114));
float levels = 10.0;
brightness = floor(brightness * levels) / (levels - 1.0);
fragColor = vec4(vec3(brightness), 1.0);
このコードでは、テクスチャの色味にもろもろ加工した変数colorのrgb値とvec3(0.299, 0.587, 0.114)
という定数のドット積をとったのちに、10段階にスケーリングしています。ちなみに、vec3(0.299, 0.587, 0.114)
は、人間の視覚に基づいた重みらしいです。こちらの記事を参考にしました。
完成
この処理をいろいろなシェーダーファイルに追加すれば、エンティティや空の色をモノクロにすることもできます。
まとめ
Minecraftをカスタマイズする機能は、ModやPluginだけではありません!
この記事を通して、ResourcePack や DataPack の面白さが布教できたら嬉しいです。