レンダリング (1.20.1)¶
解説する必要のある事柄が多すぎるため、レンダリングするうえでの最小限の知識を解説しています。
技術スタック¶
GPU¶
GPUで描画されている。
OpenGL¶
グラフィックスドライバと通信するための規格。
ステートマシンとなっているため、設定した値は戻すまで状態が維持されます。
そこでバニラのメソッドはうまくラッピングし、カバーしています。
LWJGL¶
MinecraftはLWJGLというライブラリを経由してOpenGLで描画しています。
基本的にはOpenGLのコマンドを直接叩くことは少なく、用意されたAPIを通して描画します。
Blaze3D¶
MinecraftがOpenGLを直接叩く代わりに用意した静的クラス群。
Mod制作では、GLコマンドを直接叩くのではなく、用意されたAPI(RenderSystem等)を通して描画します。
JOML¶
数学ライブラリとしては主にJOMLが使用されています。
座標系¶
座標系は大きく3つあり、それぞれ異なる用途を持っています。 (Minecraftにおいて明確に定義されているわけではない)
それらの座標系は主に PoseStack によって操作、管理されています。
(レンダリングAPIで解説)
様々な座標系がありますが、結果的にはスクリーン座標系に変換され描画されます。
ワールド座標系¶
ゲーム内のブロックやエンティティが存在する絶対的な座標。
ゲーム内で通常使うXYZ座標がこれにあたります。
軸
- X+: 東 (East)
- Y+: 上 (Up)
- Z+: 南 (South)
ビュー座標系¶
カメラを中心とした座標系。
スクリーン座標系¶
インベントリ画面やHUD(ホットバー、体力等)を描画する際の2D座標。
原点(0,0): 画面の左上隅。
軸
- X+ 右へ
- Y+ 下へ (ワールド座標とYの向きが逆なので注意!)
- Z+: 奥(深度+)
ローカル座標系¶
個々のオブジェクトを中心とした相対的な座標系。
座標変換¶
基本的に以下の流れで座標変換されます。
graph LR
L[ローカル座標系] --> W[ワールド座標系];
W --> V[ビュー座標系];
V --> S[スクリーン座標系];
テクスチャ座標(UV)¶
モデルの頂点には、テクスチャのどの部分を貼り付けるかという情報(UV)を持たせます。
スクリーン座標系と同じ軸と原点を持っていて、U,Vどちらも範囲は0.0~1.0です。
- 開始位置: (u0, v0)
- 終了位置: (u1, v1)
を持ちます。
Info
JSONモデルでは、UVはピクセル単位で指定しますが、シェーダーに送られる際には、テクスチャアトラス内での位置として変換されたUV値として扱われます。
描画方法¶
頂点¶
OpenGLにおいて、すべての物体は頂点の集まりによって構成されています。
頂点とは、3Dモデルを構成する最小単位の点のことです。
主な値(Minecraftにおいて)
- Position: 位置情報
- Color: 色情報
- UV: テクスチャ座標
- Normal(法線): 光の当たり方等を計算するために必要
- ライトマップ: 光のテクスチャ
- オーバーレイテクスチャ: ダメージ表現やTNTの点滅等に使われるテクスチャのUVの指定
レンダリングパイプライン¶
ラスタライズ¶
頂点で構成された図形を、フラグメントに変換する処理。
塗りつぶすピクセルごとに頂点の情報(色、UV、法線等)を線形補間して割り当てます。
フラグメント(Fragment)¶
ピクセルになる前の計算途中のデータです。
ピクセル座標、深度値、テクスチャ座標等、線形補間されたデータを持ちます。
Fragment Shader¶
フラグメントシェーダーは、フラグメントの情報を元に、最終的な色を決定するシェーダープログラムです。
つまり、描画する色を決定するシェーダープログラムです。
例
#version 150
in vec4 vertexColor;
uniform vec4 ColorModulator;
out vec4 fragColor;
void main() {
vec4 color = vertexColor;
if (color.a == 0.0) {
discard;
}
fragColor = color * ColorModulator;
}
Vertex Shader¶
頂点シェーダーは、頂点の情報を元に、最終的な位置を決定するシェーダープログラムです。
例