v050522 対応



mmV 公式サイト


dokon ちゃんとこのカスタムシェーダページ
ハーフトーン と nonAA は使える。おもろい。

本リファレンスはぶっちゃけ適当です。むしろサンプルファイル以外あんま意味無いです。
本家サイトに上がってる SS っぽい事をやるにはどーすりゃえぇねん!っていう人向け。
まぁ適当に流し読みしてサンプルファイルから欲しい情報だけ引っぺがしてくださいな。

ちなみに本家サイトとはそこはかとなく関係してるけど多分ドッチかが問題起こしても我関せずを通すと思うので、それなりに大きい器でお願いしますね!

リンクとか参考誘導とかは御自由に!解析とかもしてないんで気軽に飛ばしてくれィ。

まずは書くまでも無いけど一応基本操作からいこう。

mmV / 基本操作説明
開く
 050522 対応フォーマット
 .mqo|.zip|.mmz
任意の mqo を ドラッグ & ドロップ で mmViewer.exe に放り込む

.mqo が入っている .zip ファイルを ドラッグ & ドロップ で mmViewer.exe に放り込む
  (.zip 内に複数の .mqo が入っている場合 .zip の中を検索して最初にヒットした .mqo を読み込む)

.mqo が入っている .mmz ファイルを ドラッグ & ドロップ で mmViewer.exe に放り込む
  (.mmz 内に複数の .mqo が入っている場合 .mmz の中を検索して最初にヒットした .mqo を読み込む)

mmv.exe を実行して出てくるダイアログから開きたいファイルを選択
閉じる
左ボタンダブルクリックから終了を選択
アクティブな状態で alt + F4
ウィンドウを移動させる
左ボタンドラッグ
ウィンドウサイズを調整する
ctrl + 左ボタンドラッグ
ウィンドウの背景を透過させる
左ボタンダブルクリック から 透過表示 を選択
視点を回転させる
右ボタンドラッグ
視点を移動させる
中ボタンドラッグ / スクリーン固定
shift + 左ボタンドラッグ / xz 固定
shift + 右ボタンドラッグ / y 固定
視点を拡大縮小させる
左ボタン + 右ボタン を同時にドラッグ
マウスホィール を 回転
光源位置 を変える NEW v050521
ctrl + 右ボタンドラッグ
オブジェクトを常時回転させる
左ボタンダブルクリック から 自動回転 を選択

んじゃカスタムシェーダ関連ズラリと行きますか〜。
基本は上述の通り、サンプルを落としてその中のファイルを引っ張ってくるだけでオッケーなので、
堅苦しげなテキスト部分はまるっとすりっとスルーしてくれてもイイかも知れない!

まぁ適当に頑張って!

cel_paint.frag / 基本的に弄る必要無し
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
//------------------------------------------------------------
// 似非cel_paint

//------------------------------------------------------------
uniform sampler2D mmv_tex0;

uniform sampler2D mmv_tex2; // EXテクスチャ1
uniform sampler2D mmv_tex3; // EXテクスチャ2

//------------------------------------------------------------
varying vec3 VERTEX_NORMAL;	// 法線ベクトル
varying vec3 VERTEX_LIGHT;	// ライトベクトル
varying vec3 VERTEX_LIGHT2;	// ライトベクトル
varying vec3 VERTEX_EYE;	// 視線ベクトル

// ------------------------------------------------------------
// フラグメントシェーダプログラム
// ------------------------------------------------------------
void main( void )
{
	vec3	N	= normalize(VERTEX_NORMAL);	// 法線ベクトル
	vec3	L	= normalize(VERTEX_LIGHT);	// ライトベクトル
	vec3	L2	= normalize(VERTEX_LIGHT2);	// ライトベクトル
	vec3	E	= normalize(VERTEX_EYE);	// 視線ベクトル
	vec3	R	= reflect( L, N );			// 反射ベクトル
	
	//色
	vec3	color	= texture2D( mmv_tex0, gl_TexCoord[ 0 ].st ).rgb;	//マテリアル色
	float	a		= texture2D( mmv_tex0, gl_TexCoord[ 0 ].st ).a;	//不透明度
	color	= gl_FrontMaterial.diffuse.rgb;	//マテリアル色
	a		= gl_FrontMaterial.diffuse.a;	//不透明度
	
	float	dif		= max( dot( N, L ), 0.0 );			//拡散強度(光の強さ)
	float	dif2	= max( dot( N, L2 ), 0.0 ) * 0.45;	//拡散強度(光の強さ)
	dif	= min( dif + dif2 + 0.1, 1.0 );
	dif	= dif * (254.0/256.0) + (1.0/256.0);		//オフセット
	
	vec3	cel1	= texture2D( mmv_tex2, vec2( dif, 0.5 ) ).rgb;	//乗算
	vec3	cel2	= texture2D( mmv_tex3, vec2( dif, 0.5 ) ).rgb;	//加算

	//スペキュラ
	float	powr	= gl_FrontMaterial.shininess;	//反射の強さ
	float	s_dif	= gl_FrontMaterial.specular.r;	//反射光(rgb同じ)
	
    float	spec	= pow( max( dot( R, E ), 0.0 ), powr ) * s_dif;
	
	
	gl_FragColor	= vec4( color * ( cel1 + cel2 ) + vec3( spec ), a );	//出力

	//アウトライン
	if( dot( E, N ) > -0.2 ){
		gl_FragColor	= vec4( 0, 0, 0, a );
	}
}

[eof]
LW の グラディエント や unReal、3dsMax の グラデーションランプ 等に代表される種類のセルシェーダ。
mmV では階調やら色相の変化を画像で定義する。

line28,29 はラデ用おまじないだそうですyp!



サンプルは公式ページからダウンロードしてチョーダイな!(承認済)

ほんじゃま、サンプルは本家の人の奴をパクって来てもらって、wond なり reset に入っている .mms、画像を見ていこう。

mmV ver050521 から .mms の書式が変わったので、とりあえず最新版を落としにかかれ!

尚サンプルとして使わせてもらってる wond と reset に入っている .mms も最新版に更新されているので、
既に落とした人ももう一度落としなおしときましょー。

・まず .mms ありき
 カスタムシェーダ全般に言える事だけど、mmV ではマテリアル毎に .mms という設定ファイルを作る必要がある。
 このファイルは普通にテキストエディタで編集できるので、とりあえず開いてみると、下の用な内容が書かれている。

****.mms / マテリアル毎に自分で用意する必要有り
001
002
003
004
005
#ConfigFile Ver1.00
@VertexShader,cel_paint.vert
@FragmentShader,cel_paint.frag
@ExTexture,Hada1.bmp
@ExTexture,Hada2.bmp
[eof]
 1 行目が使用するコンフィグファイルのバージョン、
 2 行目が使用するバーテックスシェーダの種類、
 3 行目は使用するフラグメントシェーダの種類、
 4 行目からは使用するテクスチャを記述する。

 .mms のファイル名は .mqo のマテリアル名と同じにしなければならない。(例 mat1.mms)
 フルシーンカスタムシェーダとなるとマテリアルの数だけ .mms が必要になるので効率化が必要になる。
  複雑なファイル構成になった場合、公開時に拡張子を .zip から .mmz にしてしまった方が初心者に優しい。

2 行目のバーテックスシェーダは特に弄るところは無いので、サンプルに同梱されてる物をそのまま使おう。
 バーテックスシェーダ (.vert) と フラグメントシェーダ (.frag) の違いについてはあまり気にしなくていい。
 知りたい人はググればそれなりに出てくるので、適当スタンスな本リファではあんま言及しないどく。なんかムズげだし。めどいし。

で、 3 行目のフラグメントシェーダには、現在 3 種類ある。

・cel_paint.frag
 これは .mms で定義したマテリアルに対して、シェーダしか使わない場合に使用するプログラム。
 つまりテクスチャを使わず、素の状態のマテリアルにセルペイント設定が付加される。
 要するにテクスチャ使わないならコレを使えばオッケー。
 4 行目 に階調設定画像(後述)、5 行目に 加算色画像(後述)を宣言する。

 尚、mmV は仕様上 Phong と Constant 以外はシカトするので、必ずどちらかの設定にすること。

・cel_paint_t.frag
 cel_paint.frag のテクスチャ使用版。
 使用するマップは mqo で定義されているモノを自動で読み込むので .mms で再定義する必要はない。(mmv_tex0)

・cel_paint_ts.frag
 cel_paint_t.frag に更に遮光マップが追加されたモノ。
 文字通りの意味のマップだった気がするけどどう使うのかワカランのでパス。

以上の 3 種類を用途に合わせて使い分ける。
 基本的に下に行くにつれて追加されてるだけだから cel_paint_ts.frag でいいじゃんって思うかもしれないけど、
 作者の罠で「必要な情報がないと 0x0000000 が返されるよん」とかプログラマーっぽい専門用語が待っているので、
 やっぱり使い分けるところは使い分けた方がいいみたいなのであります?

・****1.bmp


 ほんで .mms の 4 行目はシェーディングの階調を設定する画像。
 なんの事は無い、ただのグレースケールのグラデーション画像を用意するだけ。
 基本的に右が光源側、左が陰側になるので、右を白、左を黒にするのさえ守れば、間は好きなようにしていい。
 ちなみに陰側を明るくすればフレネルっぽくする事も出来るからベロア素材の再現も可能、かな?
 ま、サンプル画像みれば大体判るっしょ。



▲ このマップを使うと ▼ こうなる



ほんでもって



▲ このマップを使うと ▼ こうなる




・****2.bmp


 で、5 行目はシェーディングに「加算合成される色」の画像。
 画像のサイズやルールは上と同じで、右が光源側、左が陰側。
 具体的にどういう事かっつーと、原田さんみたいな「髪の表が金で裏が紫」みたいな事が出来るんだと思いねえ。

 Cypher'S TufT の ほし さん流に言うなら「六角 Free の明るい面と暗い面の色を個別に設定出来る」みたいなモンかな。
 とはいえ加算合成なので明るくは出来ても暗くは出来ないのでちびっと注意。
 完全にマップでカラー制御をしたい場合は .frag の編集が必要になる。

cel_paint.frag / 編集個所 -before
048
	gl_FragColor	= vec4( color * ( cel1 + cel2 ) + vec3( spec ), a );	//出力

これを

cel_paint.frag / 編集個所 -after
048
	gl_FragColor	= vec4( cel1, a );	//出力

こうすれば line 38 で定義されている cel1 のパラメータがカラーに代入される。
この場合、階調設定用のグラデは必要なく、割り当てたいマップの階調がそのまま出るのである意味では楽。
 つーかかなり楽。寧ろマップ一枚でカラーまで制御できるならこれだけでいいじゃんっていう話。



例えば ▲ このマップを使うと ▼ こうなる



 これら制御系の画像はサイズに厳密な指定は無いので、自分が制御しやすいサイズでいい。と思う。
 後はサンプルファイルから欲しい情報だけぶっこ抜くと宜しい!

ちなみに、デフォルト状態の line 48 の cel1 の部分を cel2 にすれば加算合成から乗算合成に変更可能。
内容に一通り目を通せばスペキュラの追加や排除も結構簡単に出来るので、思いついたらやってみると新しい発見があるかも!


shadow.vert / 弄る必要有り
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
//------------------------------------------------------------

//------------------------------------------------------------

//------------------------------------------------------------
//頂点シェーダ
//------------------------------------------------------------
void main( void )
{
	//ライト座標変換
	mat4	rot_mat	= gl_ModelViewMatrixInverse;
	rot_mat[ 0 ][ 3 ]	= 0.0;
	rot_mat[ 1 ][ 3 ]	= 0.0;
	rot_mat[ 2 ][ 3 ]	= 0.0;

	rot_mat[ 3 ][ 0 ]	= 0.0;
	rot_mat[ 3 ][ 1 ]	= 0.0;
	rot_mat[ 3 ][ 2 ]	= 0.0;
	
	vec4	L	= vec4( 800,800,600,1 ) ;
	L	= rot_mat * L;
	
	//座標変換
	gl_Position	= gl_Vertex;
	
	float	m	= L.y / L.x;
	float	n	= L.y / L.z;
	
	gl_Position.x	= -1.0 / m * gl_Position.y + gl_Position.x;
	gl_Position.z	= -1.0 / n * gl_Position.y + gl_Position.z;
	gl_Position.y	= 0.0;

	gl_Position	= gl_ModelViewMatrix  * gl_Position;
	gl_Position	= gl_ProjectionMatrix * gl_Position;
}

[eof]
床に影を落とす為のバーテックスシェーダ。

( 800,800,600,1 ) の部分がそれぞれ (x,y,z,w)
単位はメタッコ準拠なので小さい数値を入れても変化は殆ど無い。ダイナミックに行け!

これは床に投影される影用の光源座標で、シェーディング用の光源座標ではない。
ちなみに w は 1 のままでオーケー。この w は 同次座標 つって、まぁ知りたい人はググって下さいな!

 余談ながら、mmV v050521 から 光源位置 の調整が出来るようになったけど、
 このシェーダはそれとは独立したモノなので光源を動かしても追従しない。
 多分近い内に実光源と同期出来るようになると思われる。



sampleFile.download

★ 小ワザ ★
メタッコは透明オブジェクトの中にあるオブジェクトが「階層として」透明オブジェクトより上にある場合、
中にあるオブジェクトを完全に無視する。
ま、リアルタイムモノなら大体どれも同じだけど、描画順の話ですな。

ほんで、このドロップシャドウプログラムはオブジェクトを直接変形させて表示させているので、
mqo を開けば影用のモデルが存在する。
これを利用して、影を「特定のエリアから食み出さないようにする」という事が可能だ。
また、マップで制御すればより複雑な干渉が可能になる。

尚、この影オブジェクトにマップを当てる事も可能だと思われるが、
原理を考えれば恐ろしい事になるのは目に見えているのでお勧めしない。


ibl.frag / 弄る必要無し
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
//------------------------------------------------------------
// 似非 IBL

//------------------------------------------------------------
uniform sampler2D mmv_tex2; // EXテクスチャ2

//------------------------------------------------------------
varying vec3 VERTEX_NORMAL;	// 法線ベクトル
varying vec3 VERTEX_LIGHT;	// ライトベクトル
varying vec3 VERTEX_LIGHT2;	// ライトベクトル
varying vec3 VERTEX_EYE;	// 視線ベクトル

// ------------------------------------------------------------
// フラグメントシェーダプログラム
// ------------------------------------------------------------
void main( void )
{
	vec3	N	= normalize(VERTEX_NORMAL);	// 法線ベクトル
	vec3	E	= normalize(VERTEX_EYE);	// 視線ベクトル
	vec3	R	= reflect( E, N );		// 反射ベクトル
	vec3	color	= gl_FrontMaterial.diffuse.rgb;	//マテリアル色
	
	//反射
	float	R_u	= ( -atan( N.z, N.x ) / 3.1415926535 + 1.0 ) / 2.0;
//	float	R_v	= ( -N.y + 1.0 ) / 2.0;
	float	R_v	= acos( N.y ) / 3.1415926535;
	
	gl_FragColor	= vec4( texture2D( mmv_tex2, vec2( R_u, R_v ) ).rgb * color, 1.0 );
}

[eof]
IBL(ImageBasedLighting)を胡散臭く行う為のフラグメントシェーダ。
バーテックスシェーダは cel_paint.vert を使用するので、そちらの同梱も忘れずに。



sampleFile.download


env.frag / 弄る必要無し
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
//------------------------------------------------------------
// 似非 環境マップ

//------------------------------------------------------------
uniform sampler2D mmv_tex2; // EXテクスチャ2

//------------------------------------------------------------
varying vec3 VERTEX_NORMAL;	// 法線ベクトル
varying vec3 VERTEX_LIGHT;	// ライトベクトル
varying vec3 VERTEX_LIGHT2;	// ライトベクトル
varying vec3 VERTEX_EYE;	// 視線ベクトル

// ------------------------------------------------------------
// フラグメントシェーダプログラム
// ------------------------------------------------------------
void main( void )
{
	vec3	N	= normalize(VERTEX_NORMAL);	// 法線ベクトル
	vec3	E	= normalize(VERTEX_EYE);	// 視線ベクトル
	vec3	R	= reflect( E, N );			// 反射ベクトル
	
	//反射
	float	R_u	= ( -atan( R.z, R.x ) / 3.1415926535 + 1.0 ) / 2.0;
//	float	R_v	= ( -R.y + 1.0 ) / 2.0;
	float	R_v	= acos( R.y ) / 3.1415926535;
	
	gl_FragColor	= vec4( texture2D( mmv_tex2, vec2( R_u, R_v ) ).rgb, 1.0 );
}

[eof]
環境マップをヤンワリと行う為のフラグメントシェーダ。
こちらもバーテックスシェーダは cel_paint.vert を使用するので忘れずに同梱すべし。



sampleFile.download


prlx.vert / 弄る必要無し
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
//------------------------------------------------------------
// バンプマップ(パララックスマップ)

//------------------------------------------------------------
uniform sampler2D mmv_tex0;

uniform sampler2D mmv_tex2;

//------------------------------------------------------------
varying vec3 VERTEX_NORMAL;	// 法線ベクトル
varying vec3 VERTEX_LIGHT;	// ライトベクトル
varying vec3 VERTEX_EYE;	// 視線ベクトル

varying vec3 O;

// ------------------------------------------------------------
// フラグメントシェーダプログラム
// ------------------------------------------------------------
void main( void )
{
	vec3	L	= normalize(VERTEX_LIGHT);	// ライトベクトル
	vec3	E	= normalize(VERTEX_EYE);	// 視線ベクトル
	vec3	N	= normalize(VERTEX_NORMAL);	// 法線ベクトル
	vec3	NM	= texture2D( mmv_tex2, gl_TexCoord[ 0 ].st ).rgb;
	
	vec2	Tex;
	Tex.x	= gl_TexCoord[ 0 ].x + 0.01 * NM.x * -E.x;
	Tex.y	= gl_TexCoord[ 0 ].y + 0.01 * NM.x * -E.y;
//	Tex		= gl_TexCoord[ 0 ].st;
	
	NM	= texture2D( mmv_tex2, Tex.st ).rgb;
	vec3	NM_L	= texture2D( mmv_tex2, vec2( Tex.s - 1.0 / 512.0, Tex.t ) ).rgb;
	vec3	NM_T	= texture2D( mmv_tex2, vec2( Tex.s, Tex.t - 1.0 / 512.0 ) ).rgb;
	
	N	= normalize( vec3( NM_L.x - NM.x, NM_T.x - NM.x, 0.7 ) );
	
	vec3	H	= reflect( L, N );			// ハーフベクトル
	
	
	//色
	vec3	color	= texture2D( mmv_tex0, Tex ).rgb;	//マテリアル色
	float	a		= texture2D( mmv_tex0, Tex ).a;		//不透明度
	
	float	dif		= max( dot( N, L ), 0.0 );			//拡散強度(光の強さ)
	dif	= dif * 0.8 + 0.2;

	//スペキュラ
	float	powr	= gl_FrontMaterial.shininess;	//反射の強さ
	float	s_dif	= gl_FrontMaterial.specular.r;	//反射光(rgb同じ)
	
	float	spec	= pow( max( dot( H, E ), 0.0 ), powr ) * s_dif;
	
	
	gl_FragColor	= vec4( O, a );	//出力
	gl_FragColor	= vec4( color * dif+ vec3( spec ), a );	//出力
}

[eof]
最新技術を駆使して擬似的に凹凸を付ける最新技術なシェーダ



sampleFile.download

バンプ用マップは基本的にグレースケールが望ましい。
カラーでも良いけど輝度の問題が発生するのでやっぱグレースケールのが安心。サイズも小さいしね!



カラー用マップはあくまでも色だけにしておくと綺麗に見える。
凹凸はプログラムがやってくれるから、陰影によるディテールを書き込むと逆に浮いてしまうので注意。
んでも、あくまで擬似凹凸なので、深めの溝とかはちゃんと描いた方がいい。



尚、コメントアウトされている line 29 を有効にして、line 27,28 をコメントアウトすると通常のバンプマッピングになる。
視差による面の補正処理が無くなるので平坦な感じになる。と思うよ!


ファーシェーダはかなりの勢いでインチキというか、そもそも使い方が違う気がする上にメタッコでもほぼ同様に見えるので説明はオミット!
原理説明するよりサンプル見たほうが早いのでサンプルおいときます。ションボリしてください。


sampleFile.download


古典的ミラーは mmV のシェーダやら機能じゃなくてただのメタッコ小技なので説明はオミット!
こっちもサンプルおいときます。ガッカリはしないかもしれないけど文字通り古典的なワザです。


sampleFile.download









powered by ntny.
technicalSupported by hheaven.

for all mmV users. thanks.