6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Minecraftで葉っぱを風で揺らそう!

Last updated at Posted at 2021-03-05

前回:光に色をつける方法
次回:未定

#はじめに

風で葉っぱなどの植物が揺れる!

これも影Modならではの要素ですよね。

今回はVertexシェーダーを使って、葉っぱを風で揺らしてみましょう!

#Vertexとは?

今まではFragmentという、主に色を担当するシェーダーファイルをいじっていたのですが、Vertexは座標系の操作をするシェーダーになります。

形を変えたり移動させたりしてくれるものだと思ってくれて構いません。

それではいじっていきましょう!

#基本

今回は、主に地形の座標系を操作する「gbuffers_terrain.vsh」を編集していきます!

#version 120

varying vec2 lmcoord;
varying vec2 texcoord;
varying vec4 glcolor;

void main() {
	gl_Position = ftransform();
	texcoord = (gl_TextureMatrix[0] * gl_MultiTexCoord0).xy;
	lmcoord  = (gl_TextureMatrix[1] * gl_MultiTexCoord1).xy;
	glcolor = gl_Color;
}

基本的な構文はFragmentと変わらないです。

gl_Position = ftransform();

これで「ftransform()」という基本的な座標の情報を「gl_Position」に入れることで、Minecraftの座標の情報が決定されています。

直接「gl_Position」を編集し、風の表現をしていきましょう!

#風の表現

葉っぱを風で揺らしていくのですが、Minecraftには風なんて無いですよね。

風の代わりに、「frameTimeCounter」という、ゲーム起動時からの時間の情報が入っている変数を使います!

「frameTimeCounter」はそのままでは使うことができず、「uniform」で呼び出す必要があります。

uniform float frameTimeCounter;

「void main() {」よりも上にこれを書くと、呼び出すことができます!

「frameTimeCounter」はそのままだと使いずらいので、「sin()」という関数を使って周期的にします。

gl_Position.x += sin(frameTimeCounter);

こちらのコードを書いてみましょう。

「=」や「*=」を使うと座標の根幹が変わってしまうので、「+=」で足し算しています。

5ap9e-dvwic.gif

何も指定していないので、すべてのブロックが揺れています...

葉っぱだけを指定するために、「mc_Entity」を使用して、ブロックのIDを選択します!

attribute vec4 mc_Entity;

「mc_Entity」は、「uniform」と同じような感じで「attribute」で定義すれば使えるようになります。

if(mc_Entity.x == 18.0){
gl_Position.x += sin(frameTimeCounter);
}

葉っぱのデータは18なので、ifを使って葉っぱを指定します。
(ブロックのIDは、mc_EntityのX座標に入っています)

MinecraftのWikiにIDの情報が載っていたので、参考にしてみてください。
(ここに書かれているIDはすべて正確ではないので、そこは自力で探し出すしかないようです...)

Wikiはこちら

f53f0-kxw7a.gif

葉っぱだけ動かせましたが、揺れが大きすぎですね...

if(mc_Entity.x == 18.0){
gl_Position.x += sin(frameTimeCounter*3.0)*0.02;
}

少し調整してみましょう、

6f9o3-8isi5.gif

だいぶマシになりましたが、まだまだ動きが単純ですよね...

チャンクの座標を使って、動きを複雑にしてみましょう!

if(mc_Entity.x == 18.0){
gl_Position.x += sin(frameTimeCounter*3.0 + gl_Vertex.x + gl_Vertex.y + gl_Vertex.z)*0.03;
}

「gl_Vertex」に、チャンクの座標の情報が入っています。

上のコードでは、X、Y、Zの情報を一気に足すことで動きを複雑にしています。

それでは動かしてみましょう!

sfccw-22p3e.gif

いい感じに揺らせましたね!

数値は好きなように調整してください!

このままだと洞窟などの屋内でも揺れてしまうのですが、前回までに学んだことを使えばきっと改善できるはずです...

#おわりに

葉っぱを揺らすことによって、Vertexシェーダーの基礎を学べたかと思います!

それでは次回で会いましょう!さようなら~

6
1
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
6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?