CG・コンテンツ制作
  1. CG・コンテンツ制作トップ
  2. DAIKIN CG Channel
  3. UsersNotes
  4. シェーダ
  5. RealtimeShader : リアルタイム・トゥーン・シェーダーを作ろう!! その2
SUITE USERS NOTES
リアルタイムシェーダー その2
リアルタイムのトゥーン・シェーダーを作ろう!!(OpenGL)
リアルタイムシェーダー編について
Emi_banner4
ここで紹介するリアルタイム・トゥーン・シェーダー は 他の編同様、
”このキャラクターに必要だったもの”としてリアルタイム・シェーダーをもまとめて紹介するかたちにします。
ですので、このキャラクター専用のシェーディング部分は当然出て来るのですが、
そこから発展して各自に合った内容に発展できたらと考えます。

今まで扱っていたものとは違う設定を見ることによって、
また新たな表現を模索するきっかけになれれば幸いです。

そんな←このキャラクターを中心とした、”とりとめもない”事例ですが、どうぞ参考にして頂ければと思います。
このキャラクターのファンになってくれたらもっとうれしい^_^ ;です。

fmt_ritaro_ml

rt_toon_shader_00 プロローグ
前回に続き、リアルタイム・シェーダーについての第2ページ目として記述です。
さー、いよいよオリジナリティーを含め、更に内容をグレードアップしていきます。
このキャラ独特のトゥーン表現を実現する為に、影の段数とかテキスチャーのブレンド具合とか工夫していきます。

一番最初のレンダリングのトゥーンのページにも書いた通り、
トゥーンとはNPR(ノン・フォトリアリスティック・レンダリング);
つまり写真のように現実的でないレンダリング手法の一例なのですから、
色々と新しい映像表現方法が実現できたらと考えます。

注意
RT_Toon を作ろう
 >> 6, 色のグラデーション設定の模索
 >> 7, シェーディングの調整
 >> 8, マルチ・テキスチャーの設定
パソコンのスペックWindowsXP SP3、Intel Core2Duo 3G、 RAM; 3G、NVIDIA Quadro FX1700



注意点!! < メールウェア > 
ここで御紹介しているFMT Toon Shadingは、色々な既存サンプルを参考にしつつも、自ら作成しているものです。
ですので、FMT Toon Shading をそのまま利用してもらっても結構なのですが、使用に関してはあくまでも自己責任でお願い致します。
また、そのまま利用の際には、特に商業利用に関しては、できればメールにて事前連絡をして頂けたらうれしいです。
作品公開可能な方は作品をお送りいただければ、UsersNotes内のギャラリーページに掲載させていただきますよ!
送り先は、siun-info@dc.comtec.daikin.co.jpです。
ココで紹介するものを参考にしつつ、もっとこんなものが製作できたよ--!!!っていう前向きの姿勢を期待するものであります。



RT_Toon を作ろう
6, 色のグラデーション設定の模索;マルチシェーディングの合成手段
さーて、第2段のはじまり,、はじまり・・・♪
今回は3段階実装と共に、If文のサンプルにもなっています。

シェーディングの二段目、三段目は1段目と同じパラメータを複製して使用します。
合成方法は1段目のToonDiffuseに対して、2段目三段目をlerpでアルファブレンディングするように重ねています。

if文の方ですが、UIにbool形式のものを追加して、チェックボックスがTrueかFalseかで切り分けるようにします。

bool useBaseMap
<
string UIName = "Use BaseMap";
> > = true;

例えば上記のチェックボックスはシェーダの中では

float4 bTex;
if (useBaseMap){
bTex = tex2D( BaseMap, IN.tVec1.xy );
} else {
bTex = float4( 1.0 );
}

という形で参照され、Trueだった場合はテクスチャがbTex として送り出され、Falseの場合はbTex が白一色として送り出されます。

そうすることで、チェックがオフのときはテクスチャが表示されないということになります。
同様にuseShadingはシェーディングそのものを使用しないようにする。
useShading2、useShading3はそれぞれシェーディングの2段目3段目をオフにするという意味がこめられています。

※マメ知識
VBSでも同じ事ができますが、if 変数{}(VBSの場合はif 変数 then)としたときはBoolとしての比較が出来て、
if 変数 =true {}(VBSの場合はif 変数 = True then)と表記したときと同じ効果があります。

//############################################################################//
//■FMT Toon Shading ver.006 ■                                                //
//----------------------------------------------------------------------------//
<中略>
//############################################################################//
//■パラメータUI作成、設定                                                    //
//マテリアルパラメータ                                                      //
//############################################################################//
<中略>

//シェードカラー[Base]-----------------------------------------------
float4 ShadeColor	
<
	string UIName =  "Shade Color";
	string UIObject = "RGBA";
	string UIWidget = "Color";
> = {0.2f, 0.2f, 0.2f, 1.0f};
//シェーディングの敷居値
float ShadingWidth
<
	string UIName =  "Shading Width";
	string UIWidget = "Slider";
	float UIMin = 0.0;
	float UIMax = 1.0;
	float UIStep = 0.01;
> = 0.0f;
//シェーディングのバイアス
float ShadingBias
<
	string UIName =  "Shading Bias";
	string UIWidget = "Slider";
	float UIMin = -1.0;
	float UIMax = 1.0;
	float UIStep = 0.01;
> = 0.0f;
//シェードカラー[2]-----------------------------------------------
bool useShading2
<
	string UIName =  "Use Shading 2";
> = false;
float4 ShadeColor2
<
	string UIName =  "Shade Color 2nd";
	string UIObject = "RGBA";
	string UIWidget = "Color";
> = {0.15f, 0.15f, 0.15f, 1.0f};
//シェーディングの敷居値2
float ShadingWidth2
<
	string UIName =  "Shading Width 2nd";
	string UIWidget = "Slider";
	float UIMin = 0.0;
	float UIMax = 1.0;
	float UIStep = 0.01;
> = 1.0f;
//シェーディングのバイアス2
float ShadingBias2
<
	string UIName =  "Shading Bias 2nd";
	string UIWidget = "Slider";
	float UIMin = -1.0;
	float UIMax = 1.0;
	float UIStep = 0.01;
> = -0.5f;
//シェードカラー[3]-----------------------------------------------
bool useShading3
<
	string UIName =  "Use Shading 3";
> = false;
float4 ShadeColor3
<
	string UIName =  "Shade Color 3rd";
	string UIObject = "RGBA";
	string UIWidget = "Color";
> = {0.1f, 0.1f, 0.1f, 1.0f};
//シェーディングの敷居値2
float ShadingWidth3
<
	string UIName =  "Shading Width 3rd";
	string UIWidget = "Slider";
	float UIMin = 0.0;
	float UIMax = 1.0;
	float UIStep = 0.01;
> = 1.0f;
//シェーディングのバイアス3
float ShadingBias3
<
	string UIName =  "Shading Bias 3rd";
	string UIWidget = "Slider";
	float UIMin = -1.0;
	float UIMax = 1.0;
	float UIStep = 0.01;
> = -0.3f;
//----------------------------------------------------------------------------//

<中略>
//############################################################################//
//■サーフェイスフラグメントシェーダプログラム                                //
//############################################################################//
float4 FMT_PixelShader(vertexOutput IN) : COLOR
{	
<中略>
	//明るいところをDiffuseColorに暗いところをShadeColorに
		ToonDiffuse = lerp( ShadeColor, DiffuseColor, hlambert1 );
		if (useShading2) { ToonDiffuse = lerp( ShadeColor2, ToonDiffuse, hlambert2 ); }
		if (useShading3) { ToonDiffuse = lerp( ShadeColor3, ToonDiffuse, hlambert3 ); }
	} else {
		ToonDiffuse = DiffuseColor;
	}


<中略>
//----------------------------------------------------------------------------//
//■更新履歴
//006/シェーディングを三段階にする処理を追加
//・シェーディングパラメータを二つ追加(一個目と内容は同じ)
//・2段目3段目を使うかどうかのチェックボックスを追加
//・そもそもシェーディングを使うかどうかのチェックボックスを追加
//・BaseMapテクスチャを適用するかどうかのチェックボックスを追加

宣言文は一緒



















シェーディングを3段階に設定




















































































複数のシェードカラー処理の
if文














これがファイルです >> FMT_ToonShading006.cgfx
では.Softimage上で実験してみましょう。このようなグラデーションを作成することが出来ます、綺麗ですね。
rt_toon_shader_40
こんなワークフロー発見!!

だんだん複雑になって来る各種設定値はPresetファイルとして保存することが出来ます。006_cgfx-rei01.Preset
このPresetファイル006_cgfx-rei01.Presetは読み込むCgFxファイルと各種値が全部入っています。
なので、このPresetファイルをRenderTree上にD&Dするだけですべての設定が完了済みで表示できます。
(読み込むべき .cgfxファイルの存在するディレクトリー位置は注意してください)
rt_toon_shader_42

ところが・・・、各色の境目のグラデーション幅を狭めるようにして、色の段差のグラデーションを実現しようとした場合
こんな感じになって、各色調整が難しいことになってしまいました。
rt_toon_shader_41
で、再度シェーディングについて考えることになりました。



RT_Toon を作ろう
7, シェーディングの調整
さーて、ここからの記述はSoftimage 2011になります。2011からリアルタイムシェーダーの管理が楽になりました。
詳しくは、FMTさんが書かれている、リアルタイムシェーダ活用2011のシェーダ管理を参考にしてください。

根本から直すのではなく、今まで作って来ている範囲内での調整をしてみました。

1)輪郭線の値が大きすぎて、使う領域が0.001~0.005と小さい~いので、1単位繰上げしました。
実モデルのデフォルトサイズにもよるのですが、そういえばこの輪郭のバイアスはMAX用のままでしたね。

2)テクスチャのアルファ対応
シェーダの286行目を観ていただければ分かるように、出力色のアルファ値にテクスチャのアルファが入っています。
float4 OutColor;
OutColor.rgb = result.rgb; //ディフューズカラーを設定
//OutColor.a = bTex.a;
OutColor.a = 1.0;

もうちょっと後の方で再度どれをアルファとしてみるかを再設定にしたいということで、しばらくは1.0Constを入れておきます。

3)値設定値の順番を変更
基本色、1色目、2色目、ハイライトとかっとアンドペーストで単純に定義順を移動させて並び順を変えることができます。
さて解説ですが、
パラメータの名前を変更して、
ハイライト と命名したシェーディングを加算に、そしてシャドウ3乗算にという計算に変更したのみになります。
あとはハイライトは内積の0の方ではなく1の方に色が乗るようにしています。
この合成方法をフォトショップのレイヤーに置き換えた画像をアップしました。
これで色と役割が少しわかりやすくなるかも知れません。
rt_toon_shader_43

//############################################################################//
//■FMT Toon Shading ver.007 ■                                                //
//----------------------------------------------------------------------------//
<中略>
//############################################################################//
//■パラメータUI作成、設定                                                    //
//マテリアルパラメータ                                                      //
//############################################################################//
<中略>
//############################################################################//
//■パラメータUI作成、設定                                                    //
//マテリアルパラメータ                                                     //
//############################################################################//
//■輪郭用パラメータ
//輪郭線の太さ
float Bias
<
	string UIName =  "OutLine Bold";
	string UIWidget = "Slider";
	float UIMin = 0.0;
	float UIMax = 10.0;
	float UIStep = 0.1;
> = 0.2f;
//輪郭カラー
float4 BorderColor	
<
	string UIName =  "Border Color";
	string UIObject = "RGBA";
	string UIWidget = "Color";
> = {0.0f, 0.0f, 0.0f, 1.0f};

//■サーフェイス用パラメータ
//
bool useBaseMap
<
	string UIName =  "Use BaseMap";
> = true;
//
bool useShading
<
	string UIName =  "Use AllShading";
> = true;
//ディフューズカラーfloat4 DiffuseColor : Diffuse と記載することもある
float4 BaseColor	
<
	string UIName =  "Base Color";
	string UIObject = "RGBA";
	string UIWidget = "Color";
> = {0.929f, 0.702f, 0.369f, 1.0f};
//シェードカラー[Base]-----------------------------------------------
float4 Layer1Color	
<
	string UIName =  "Layer1 Color";
	string UIObject = "RGBA";
	string UIWidget = "Color";
> = {0.737f, 0.545f, 0.202f, 1.0f};
//シェーディングの敷居値
float ShadingWidth
<
	string UIName =  "Weight Bias";
	string UIWidget = "Slider";
	float UIMin = 0.0;
	float UIMax = 1.0;
	float UIStep = 0.01;
> = 0.0f;
//シェーディングのバイアス
float ShadingBias
<
	string UIName =  "Weight Gain";
	string UIWidget = "Slider";
	float UIMin = -1.0;
	float UIMax = 1.0;
	float UIStep = 0.01;
> = 0.0f;
//シェードカラー[3]-----------------------------------------------
bool useShading3
<
	string UIName =  "Use Shading 3";
> = false;
float4 ShadeColor3
<
	string UIName =  "Shade Color 3rd";
	string UIObject = "RGBA";
	string UIWidget = "Color";
> = {0.1f, 0.1f, 0.1f, 1.0f};
//シェーディングの敷居値2
float ShadingWidth3
<
	string UIName =  "Shading Width 3rd";
	string UIWidget = "Slider";
	float UIMin = 0.0;
	float UIMax = 1.0;
	float UIStep = 0.01;
> = 0.75f;

//シェーディングのバイアス2
float ShadingBias3
<
	string UIName =  "Shading Bias 3rd";
	string UIWidget = "Slider";
	float UIMin = -1.0;
	float UIMax = 1.0;
	float UIStep = 0.01;
> = -0.3f;
//シェードカラー[2]:ハイライトカラー------------------------------
bool useShading2
<
	string UIName =  "Use Hilight";
> = false;
float4 HighlightColor
<
	string UIName =  "Highlight Color";
	string UIObject = "RGBA";
	string UIWidget = "Color";
> = {1.00f, 0.722f, 0.809f, 0.821f};
//シェーディングの敷居値2
float ShadingWidth2
<
	string UIName =  "Blur";
	string UIWidget = "Slider";
	float UIMin = 0.0;
	float UIMax = 1.0;
	float UIStep = 0.01;
> = 0.75f;
//シェーディングのバイアス2
float ShadingBias2
<
	string UIName =  "Cover";
	string UIWidget = "Slider";
	float UIMin = -1.0;
	float UIMax = 1.0;
	float UIStep = 0.01;
> = 0.4f;

//----------------------------------------------------------------------------//
<中略>
######################################################################//
//■サーフェイスフラグメントシェーダプログラム                                //
//############################################################################//
float4 FMT_PixelShader(vertexOutput IN) : COLOR
{	
	float4 bTex;
	if (useBaseMap){
		bTex = tex2D( BaseMap, IN.tVec1.xy );
	} else {
		bTex = float4( 1.0 );
	}

	float4 ToonDiffuse;
	if (useShading){
	//	頂点シェーダから法線ベクトルをIN
		float3 wNormalVec;
		wNormalVec = normalize( IN.wVec0.xyz );

	//ライトベクトルを取得
		float3 wLightVec;
		wLightVec = normalize( -dirlight_vec0.xyz );

	//内積を計算
		float dif;
		dif = dot( wNormalVec, wLightVec );
	//ハーフランバートに変更
		float hlambert1;
		float hlambert2;
		float hlambert3;
		hlambert1 = clamp( ( dif + 1.0 ) * 0.5, 0.0, 1.0 ) - ShadingBias;
		if (useShading2) { hlambert2 = ( clamp( ( dif + 1.0 ) * 0.5, 0.0, 1.0 ) - ShadingBias2 ) * HighlightColor.a; }
		if (useShading3) { hlambert3 = clamp( ( dif + 1.0 ) * 0.5, 0.0, 1.0 ) - ShadingBias3; }

	//トゥーンのシェーディング幅を調整するための式
		hlambert1 = smoothstep( ShadingWidth / 2, 1.0 - ShadingWidth / 2, hlambert1 );
		if (useShading2) { hlambert2 = smoothstep( ShadingWidth2 / 2, 1.0 - ShadingWidth2 / 2, hlambert2 ); }
		if (useShading3) { hlambert3 = smoothstep( ShadingWidth3 / 2, 1.0 - ShadingWidth3 / 2, hlambert3 ); }

	//明るいところをDiffuseColorに暗いところをShadeColorに
		ToonDiffuse = lerp( Layer1Color, BaseColor, float4(hlambert1) );
		if (useShading2) { ToonDiffuse += ( HighlightColor * hlambert2 ); }
		if (useShading3) { ToonDiffuse *= lerp( ShadeColor3, float4( 1.0 ), hlambert3 ); }
	} else {
		ToonDiffuse = BaseColor;
	}

	float4 result;
	result = ToonDiffuse * bTex;

	float4 OutColor;
	OutColor.rgb = result.rgb;	//ディフューズカラーを設定
	//OutColor.a = bTex.a;
	OutColor.a = 1.0;

	return OutColor;

}

<中略>
//----------------------------------------------------------------------------//
//■更新履歴
//007/シェーディングの役割を少し変更
//・追加シェーディング2をハイライトという役割に変更し加算演算へ変更
//・追加シェーディング3をシャドウと明確に分けるために乗算に変更






















輪郭線
1単位繰上げ










値設定値の
順番を変更






































































































































ハイライト
を加算に

シャドウ3
を乗算に

ハイライトは
内積1








1.0Const












これがファイルです >> FMT_ToonShading007.cgfx

色の作り込み感覚がまた違うのですが、前回より気分的に楽に綺麗な色が作り上げられます。
rt_toon_shader_44
色の段差を絞り込んでいっても、ハイライト自身は全体にかかる感じなので、変な色合いになり難いです。
rt_toon_shader_45
肌の色もぐんと探索できるようになりました。
rt_toon_shader_46



RT_Toon を作ろう
8, マルチ・テキスチャーの設定
マルチテクスチャから再考ということで、まずはもう一枚テクスチャを設定できるように、セマンティックを追加します。

49~60行目
//レイヤーテクスチャ�
texture LayerTexture001
<
string ResourceName = "Layermap001.dds";
string ResourceType = "2D";
>;
sampler2D LayerMap001 = sampler_state
{
Texture = <LayerTexture001>;
MinFilter = LinearMipMapLinear;
MagFilter = Linear;
};

次にstruct appdataに追加した分のテクスチャに使うUV値を設定できるようにTEXCOORD1を追加しました。
この時に、どっちがどのテクスチャのUVか分かりやすいように変数名を変更しています。
float4 Basemap_uv : TEXCOORD0; //UVデータ1
float4 Layermap001_uv : TEXCOORD1; //UVデータ2

ここまで来ている人はもう書かなくてもお分かりだと思いますが、頂点シェーダでピクセルシェーダへUV値を渡す記述をします。

284行目285行目
OUT.tVec1 = IN.Basemap_uv;
OUT.tVec2 = IN.Layermap001_uv;

struct vertexOutput にもう一つ分のUV値を追加して、
float4 tVec1 : TEXCOORD1; //UVデータ1
float4 tVec2 : TEXCOORD2; //UVデータ2

フラグメントシェーダ内にテクスチャをUV値で展開する記述を追加します。
float4 bTex;
if (useBaseMap){
bTex = tex2D( BaseMap, float2( IN.tVec1.x * BaseU, IN.tVec1.y * BaseV ) );
} else {
bTex = float4( 1.0 );
}
float4 l1Tex;
if (useLayerMap001){
l1Tex = tex2D( LayerMap001, float2( IN.tVec2.x * Layer001U, IN.tVec2.y * Layer001V ));
} else {
l1Tex = float4( 1.0, 1.0, 1.0, 0.0 );
}

これで変数 l1Texが2枚目のテクスチャとなったわけです。
シェーダ内の記述しだいでいかようにも使えます。

ここでちょっと以前と違うと思われた方も多いと思います。
・・・そうです。
float2( IN.tVec2.x * Layer001U, IN.tVec2.y * Layer001V )と UVの書き方が変わっていますね。
Ritaroさんの要望により、テクスチャのUV値それぞれにリピートを設定するために、
上のほうで追記しているUIのセマンティックをそれぞれのU値V値に掛け算しています。
掛け算をすることで、それぞれの最大値が増えていきますのでリピートされていくのです。
意外と簡単ですよね^^ (簡単じゃないよ~ < 横やりプスッ > )

そうやってリピートされた上でピクセルに展開されたテクスチャは
310行目の一文で合成されてbTex として使用されます。
bTex = lerp( bTex, l1Tex, l1Tex.a );

lerp関数もここではもうおなじみなのであえて解説するな、という方も多いかと思いますが、一応。
bTex(BaseMap展開)l1Tex(LayerMap001展開)l1Tex.a(LayerMap001展開後のアルファ値)
アルファブレンディングしています。

とりあえずこれでテクスチャ二枚を設定できて、合成するというところまで準備が出来ました。

※注意
ちなみに現時点でそれぞれリソースのアルファの扱いがFIXしていないので、
このバージョンでは
OutColor.a = 1.0;
として出力アルファを1つまり抜きなしに設定しています。
このあと頂点アルファでテクスチャブレンディングとか、結構特殊な処理を追加していくので、アルファの扱いが決まったらまた復活させます。

//############################################################################//
//■FMT Toon Shading ver.008 ■                                                //
//----------------------------------------------------------------------------//
<中略>
//############################################################################//
//■テクスチャ入力、設定                                                      //
//############################################################################//
	//ベーステクスチャ
texture BaseTexture
<
	string ResourceName = "Basemap.dds";
	string ResourceType = "2D";
>;
sampler2D BaseMap = sampler_state
{
	Texture = <BaseTexture>;
	MinFilter = LinearMipMapLinear;
	MagFilter = Linear;
};

	//レイヤーテクスチャ�
texture LayerTexture001
<
	string ResourceName = "Layermap001.dds";
	string ResourceType = "2D";
>;
sampler2D LayerMap001 = sampler_state
{
	Texture = <LayerTexture001>;
	MinFilter = LinearMipMapLinear;
	MagFilter = Linear;
};

//############################################################################//
//■パラメータUI作成、設定                                                    //
//マテリアルパラメータ                                                      //
//############################################################################//
<中略>

//■サーフェイス用パラメータ
//テクスチャを表示/非表示
//[Base]-----------------------
bool useBaseMap
<
	string UIName =  "Use BaseMap";
> = true;
float BaseU
<
	string UIName =  "-- Repeat U";
	string UIWidget = "Slider";
	float UIMin = 1.0;
	float UIMax = 16.0;
	float UIStep = 0.01;
> = 1.0f;
float BaseV
<
	string UIName =  "-- Repeat V";
	string UIWidget = "Slider";
	float UIMin = 1.0;
	float UIMax = 16.0;
	float UIStep = 0.01;
> = 1.0f;
//[Layer001]-----------------------
bool useLayerMap001
<
	string UIName =  "Use LayerMap001";
> = true;
float Layer001U
<
	string UIName =  "-- Repeat U";
	string UIWidget = "Slider";
	float UIMin = 1.0;
	float UIMax = 16.0;
	float UIStep = 0.01;
> = 1.0f;
float Layer001V
<
	string UIName =  "-- Repeat V";
	string UIWidget = "Slider";
	float UIMin = 1.0;
	float UIMax = 16.0;
	float UIStep = 0.01;
> = 1.0f;

<中略>
//############################################################################//
//■XSIからデータを取得し、変数を定義する構造体「appdata」                    //
//############################################################################//
struct appdata
{
	float4 pos : POSITION;	//頂点データ
	float4 nrml : NORMAL0;	//法線データ
	float4 Basemap_uv : TEXCOORD0;	//UVデータ1
	float4 Layermap001_uv : TEXCOORD1;	//UVデータ2
};
//----------------------------------------------------------------------------//

//############################################################################//
//■頂点シェーダタからフラグメントデータへ渡す構造体「vertexOutput」          //
//頂点シェーダのOUTの変数名と一致しなければいけません                       //
//############################################################################//
struct vertexOutput 
{
	float4 	hpos : POSITION;	//頂点データ
	float4	wVec0 : TEXCOORD0;	//法線データ
	float4	tVec1 : TEXCOORD1;	//UVデータ1
	float4	tVec2 : TEXCOORD2;	//UVデータ2
};
//----------------------------------------------------------------------------//

<中略>
//############################################################################//
//■サーフェイス頂点シェーダプログラム                                        //
//############################################################################//
vertexOutput FMT_VertexShader(appdata IN)
{
	vertexOutput OUT;

	// ポジションデータをワールド空間へ変換しOUT
	float4 Po = float4(IN.pos.xyz, 1.0);
	OUT.hpos = mul(WorldViewProj, Po);

	//	ワールド空間に変換した法線をOUT
	float4 N = float4(IN.nrml.xyz, 0.0);
	OUT.wVec0 = mul(WorldIT, N);

	OUT.tVec1 = IN.Basemap_uv;
	OUT.tVec2 = IN.Layermap001_uv;

	return OUT;
}
//----------------------------------------------------------------------------//

//############################################################################//
//■サーフェイスフラグメントシェーダプログラム                                //
//############################################################################//
float4 FMT_PixelShader(vertexOutput IN) : COLOR
{	
	float4 bTex;
	if (useBaseMap){
		bTex = tex2D( BaseMap, float2( IN.tVec1.x * BaseU, IN.tVec1.y * BaseV ) );
	} else {
		bTex = float4( 1.0 );
	}
	float4 l1Tex;
	if (useLayerMap001){
		l1Tex = tex2D( LayerMap001, float2( IN.tVec2.x * Layer001U, IN.tVec2.y * Layer001V ) );
	} else {
		l1Tex = float4( 1.0, 1.0, 1.0, 0.0 );
	}

	bTex = lerp( bTex, l1Tex, l1Tex.a );


<中略>
//----------------------------------------------------------------------------//
//■更新履歴
//008/まずはテクスチャの二枚目を設定する
//・テクスチャ入力、設定をもう一つ追加(LayerTexture001)
//・TEXCOORDを追加してUVを二つ設定できるようにする
//・フラグメントシェーダでUV2個めが使えるように
//・UVそれぞれにリピート回数を設定できるように
//・tex2D()で展開するBasemapのUVそれぞれにリピートパラメータをかけてリピート回数を設定できるように
//・暫定処理で2枚目のアルファを元に1枚目のテクスチャとアルファブレンディング★
























もう一枚テクスチャを設定




















Use BaseMap

Use LayerMap001

の設定













































TEXCOORD1;
の追加










もう一つ分のUV値
を追加





















テクスチャのUV値

















テクスチャをUV値で展開
する部分の追記




bTex として合成される

これがファイルです>>FMT_ToonShading008.cgfx

シェーディングの上にテキスチャーが追加されました。
2つの異なるUVテキスチャープロジェクションを使い分けられ、UVのリピート値を変更するとインターラクティブに変化していきます。
2枚目のテキスチャーのアルファー値によるブレンディングがこんな感じになっています。

rt_toon_shader_47

という訳で、次回はリアルタイムシェーダー その3です。
乞う、ご期待!!
戻る 次へ

お気軽にお問い合わせください

Daikin CG News お申し込み

CGクリエイター向けのセミナー・イベントやキャンペーン、製品情報をメールマガジンでお届けします。(登録無料)

Twitter

ページの先頭へ