
|
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 をコメントアウトすると通常のバンプマッピングになる。 視差による面の補正処理が無くなるので平坦な感じになる。と思うよ! | |

