3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Nihon UniversityAdvent Calendar 2024

Day 24

【Minecraft】デタパについて書かれてたからリソパシェーダーについて(GLSL)

Last updated at Posted at 2024-12-23

この記事はNihon University Advent Calendar 2024の24日目の記事です。

この記事はJava版1.21.4向けの記事です。
リソースパックは、Java版(PC版)とBedrock版(コンソール版)のどちらにも存在しますが、これらは仕様が大きく異なるのでご注意ください。

この記事は、Minecraftのリソースパック機能について紹介する記事であり、リソースパックシェーダーのチュートリアルを目的とするものではありません。


はじめに

Minecraftには、プレイヤーがMinecraftをカスタマイズするための仕組みがたくさん用意されています。

しかし、Minecraftをカスタムする機能としてMod、ShaderPack、Pluginなどが非常に有名である一方、ResourcePackDataPackが日の目を見ることはあまりないように感じています。

この記事では、Java版Minecraftに用意されているリソースパック機能の一つであるリソパシェーダーについて私が学習したことを共有して、
「リソースパックってこんなことまでできるのかスゲー」
という気持ちを一方的に共有したい(?)と思います。

シェーダーってなに?

そもそも、シェーダーとはなんでしょうか?シェーダーはシェーディングに利用されます。シェーディングとは、物体に陰影を与えることで立体感をだす処理のことを指します。
shader_image.png

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.mcmeta
{
  "pack": {
    "pack_format": 46,
    "description": "モノクロなリソパシェーダー"
  }
}

おすすめの環境

エディタ:

VSCode拡張機能:

2. リソパシェーダーの構成

リソパシェーダーの構成1(Coreとpost)

リソパシェーダーは大きく分けて、

  1. Core shaders
  2. Post-processing shaders

の二つに分類することができます。 それぞれの役割は以下のようになっています。

名前 役割 イメージ
Core 画面上に見える物体のレンダリング core_image.png
post 2Dになった画像(映像)をレンダリング post_image.png

参考:Guide to vanilla shaders


リソパシェーダーの構成2(json / vsh / fsh)

Coreシェーダーとpostシェーダーは以下のようなファイルで構成されています。

  1. json
  2. vsh
  3. fsh

それぞれのファイルには以下のような役割があります。また、vshとfshはGLSLで記述します。

名前 役割
json vsh、fshファイルを呼び出す
vsh、fshに渡すデータを指定する
vsh 頂点データを編集する
fsh 色データを指定する

全体の流れを図にするとこのようになります。
shader_flow_image.png

リソパシェーダーは、
core(json→vsh→fsh) → post(json→vsh→fsh)
の順に処理されます。

参考:【リソパシェーダー紹介】第1回 リソパシェーダーとは?

3. Re: リソパシェーダーを作ろう

この記事では、ブロックをモノクロにするリソパシェーダーを作成してみます。

シェーダーファイルの準備

Minecraftの中で、ブロックはterrain.vshterrain.fshというファイルを使ってシェーディングされています。今回はブロック色のみを変更したいので、リソースパックにはterrain.fshのみを追加します。このファイルは作成したリソースパックのshadersに追加しておきます。それぞれのシェーダーファイルの担当については以下のページが参考になります。

以前は、ブロックの種類によって異なるシェーダーファイルが使われていましたが、Minecraft 1.21.2以降はすべて、terrainというファイルで処理されるように変更されました。

また、リソースパックを導入する前のMinecraftで利用されているシェーダーファイルは、以下のページを参照できます。

こちらが、通常、Minecraftで利用されているterrain.fshです。

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で描画されるブロックの色味は、この変数で決定していることが分かります。一番下のこの行を書き換えれば、描画されるブロックの色味は異なるものになるはずです!

2024-12-24_00.05.48.png

元のコード
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);

2024-12-24_00.05.39.png

新しいコード
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だけではありません!
この記事を通して、ResourcePackDataPack の面白さが布教できたら嬉しいです。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?