2012年08月

2012年08月27日

うにばな(pragmaってなんですか)




”#pragma strict” のキーワードで検索が多かったので 説明しますね。


Unityは

UnityScript(拡張Javascript アクションスクリプトにちょっと似てる)、
C#(オリジナルとちょっと作法が違う)、
Boo(Pythonぽい でもなんかちがう)

などのスクリプトで記述できますが
#pragma文は 主にUnityScriptのスクリプト文中の先頭で宣言します。
UnityScript(Java)は変数の型をコンパイル時に自動的に判別する 推論型の型付けを行なってくれます。
これは 型を気にせずにざっくりとスクリプトを書くことが出来るため スクリプトにあまり馴染みのない人などが
記述するときに多少助けになることがあると思います。
ですが その便利さに反して実行スピードが若干犠牲になるため 本格的にゲームを作る場合には
的確に型宣言および型指定をしてやる必要があります。

”#pragma"には『strict』のほかに『implicit』『downcast』といった仲間があります。


■”#pragma strict”を宣言した場合。
例)


#pragma strict

foo = 5; // これは X



#pragma strict

var foo = 5; // これは ○

➀は型宣言で”var”が記述されていません Javaの場合 変数名=数値 の形で書くだけで
型宣言なしのローカルな変数が認められています。 
”#pragma strict”を指定すると あいまいな型はコンパイルエラーがでるので きちんと型宣言しないといけません。

■”#pragma implicit”を宣言した場合。

例)

#pragma strict
#pragma implicit

foo = 5;


// ”#pragma implicit” を指定した場合”#pragma strict”の記述をしていても 変数を宣言なしで使用することが出来ます。


■#pragma strict だけを記述した場合 代入先の変数の型に型変換(キャスト)で正確に値を渡さない場合エラーが帰ります。


#pragma strict

var go : GameObject ;

var clone : GameObject = Instantiate (go);

// キャスト(型変換)をしないとInstanciate関数はObject型を返しますのでGameObject型の”clone"に代入された時点でエラーになります



#pragma strict

var go : GameObject ;

var clone : GameObject = Instantiate (go) as GameObject ;

// 型変換"as”を指定することでInstanciate関数はGameObject型に型付けされました これはエラーになりません。


”#pragma downcast”を使用すると ”#pragma strict”を使用していた場合でも 値の代入時の型の相違でエラーを返しません

#pragma strict
#pragma downcast

var go : GameObject ;

var clone : GameObject = Instantiate (go); // これはOk





例文は以下のサイトを参考にしました
http://forum.unity3d.com/threads/63114-What-is-pragma-implicit-and-pragma-downcast


補足ですが プロジェクトが巨大になるとごくまれに、どうしてもキャストがコンパイルで通らないような場合があります。
特に外部スクリプトから変数を参照する場合などに発生することがあるようです。
そういう場合には他の箇所をデバッグ後に #pragma strict をはずしてみてください。
コンパイラの自動判別で何型かに適当に割りつけて実行してくれると思います。
ゲームの中で数回実行される程度の箇所であれば 修正に時間をさくのは無駄です。




追記:

技術文書などでよく目にする文字列に『foo』や『bar』 今回のサンプルにも使用されていますが

日本語で例えると 『なんとか』や『ほにゃらら』といった その箇所に好きな名前を当てはめて使用してください
という『仮の名前(単語)』を意味しています。

これを メタ構文変数(Metasyntactic variable) と情報処理の世界では呼んでいます。

ほかにも
 foo, bar, baz, qux, quux, corge, grault, garply, waldo, fred, plugh, xyzzy, thud 

などのようなバリエーションがあります。この順番はABC‥に相当するので入れ替えないで使用してください。

日本語圏にも同様のメタ変数があります。

「hoge」「fuga」「piyo」

などです 日本語のスクリプトを解説するサイトを巡ると目にすることがあるかと思います。

それから よく関数の内部で ”do something” という文例が出てくることがありますが
これは直訳して『何か実行する』 つまり 『好きなようにスクリプトを書いてください』ということを意味しています。
そういう名前のコマンドがあるわけではないので勘違いしないようにしてください。


これらが検索でとても多いので 一応メモ的に書いておきました。

長くプログラムを書いている人や 情報の専門の人にはあたりまえのことかもですけど
はじめてゲーム作りたい人にはわかんないですよねw



うにばな 今後の予定ですが

シェーダーの記事をとりあえずやっつけます。
その後 エネミーAIの考察、 ネットワーク関連、 モーションまわりのTips なんていう予定をたてています。
その合間に自作ゲームの記事を挟む感じでしょうか

ただし 今回その時期と場所は指定しないので その気になれば10年後 20(ry

いや 場所はここなんですけどね
過度な期待はしないでください(みなみけの4期 程度の期待感でおまちください)



それでは また

akinow at 16:16|PermalinkComments(2)TrackBack(0) Clip to Evernote Unity3d 

2012年08月24日

ぶごうさんがんばらない

17


こんにちは ぶぎょうです 頑張ったら負けかなーと思ってます


17さいになりました 







(うそです)





誕生日です すでに一ヶ月前ですが 




そういえば年末に誕生日イラスト+1枚を贈ったので ひょっとしたらイラストでお返しがもらえるかも
と ちょっとだけ期待して 『ぶぎょう17さいになりました』 とコメしたら 

『18さいになったらアダルトおっけーだね』みたいな返しをされて終了



生まれてスイマセン。。


yaruochan





幕張の免許センターまで免許の更新に行ってきました

(ちなみに本文中の画像は全て借り物です カメラが空気を読んで故障しました)



今日で免許更新の期限切れ 自分を後が無い状況に追い込むことで最高の力を発揮するために
あえて最終日を選択した そんな めんどくさがり屋さん



幕張本郷へ ごー

久しぶりの外出で出会った 先進技術を駆使した合衆国千葉の維新機械たち

no title

津田沼駅なかに設置された次世代自販機。 ガイアの夜明けで紹介された『acure』
何が次世代かってーと 全画面が液晶でジュースが全部写真画像。時間ごとに画面に全画面CMが流れる。
そして内蔵カメラで近寄った人の顔を分析し おすすめジュースを表示してくれる スゲー無駄機能
老けた容貌の小学生がマムシドリンクやワンカップをおすすめされるかもな そんな素敵な未来自販機です。



keisei-4822--

合衆国千葉が誇る ちょうつがいを蛇腹でコーティングした未来バス 『シーガル幕張』
シーゲル梶原みたいでかっこいいですね

img_1195597_34234983_3

日本語、英語、中国語、韓国語の4ヶ国語の停留所表示と乗り継ぎ電車発着時間と駅到着時間が
表示される未来液晶パネル  (ただし見ている人はいない)





日本人のやつらは未来に生きてるなー







そして免許センター到着  もう五年も経ったのに景色が変わんねー

f0fbf64378eeb10e3db9edba17294ab4


なんといっても わたくしゴールド免許なので教習はたったの30分です

でもさ 『別室行き!!』 病歴があると別室に連れて行かれるのよ で 中でお話し
しかし その後あっさり免許更新 たったの1時間30分

なんといっても  ゴールド免許ですから 蟹座のゴールド免許ですから

あと待合室でスイカの匂いがしたんですけど カブトムシ飼ってたりします?




帰りの電車

幕張~津田沼間にJRと京成の線路が並んでいるいわゆるバトルポイントがあります。
京急線の平和島あたりにもそんな感じのところがあるらしいですが
そこで時間が合えば並走する電車のスピード比べを見ることが出来るんですよ

気分は”電車でD”で複線ドリフト が脳内で再生されました
画質はS-VHSの3倍モードくらいでしょうか 



20051217a
Double_Drift
20050501_1


レンタルビデオ屋に行くとなぜか『あ』の場所に置いてある『頭文字(イニシャル)D』
のパロディ作品『電車でD』です。  ちょっとタイトーのあれっぽいのもはいってますね

もとは同人誌ですが、何年前か『複線ドリフト』で話題になりました テッちゃん(電車マニア)と走り屋を
むすびつける記念スべき作品ですね その後同人でゲーム化 そしてでんせつへ

夏のコミケの最新作?が 本編さながらのBGMと大量の読み上げボイスは外注だそうです(実はこの部分の開発費がすごいことになってるとか。。。)
男性声優の確保が意外に難しいんですよね 同人でも需要がありそうなんですけどね。







そういえば 久しぶりに外に出たら 子どもたちにおっきな声で挨拶されました

子供は純粋やー やはり人として 敬う相手をしってるんやな

と言う話を知人にしたところ

ぶぎょうさん 最近の子供は学校で 

不審者には大きな声で挨拶せぇ 奴ら慣れとらんから 挨拶されるとひるむで

という教育をされているらしいです

img_952405_27592054_0


images






定番ですが 伊武雅刀おいておきます





と 今回ここまでで記事を閉めようと思ったところで 衝撃画像がやってきました

2077658c


スペインの歴史あるフレスコ画をおばちゃんが勝手に(司祭に断ったらしい)修復してしまい。
やあ メンゴメンゴ修復失敗したわ〜という そんなお話です。
キリストが、『毛むくじゃらの猿になったよ(原文まま)』 という感想は的を得ています。 
今後 修正はするけど うまくいかなかったら写真で覆ってしまおうという なんとも腰砕けな話。

絵心のない人は なぜ困難に立ち向かってしまうのか?
なぜホームページで絵の書き方講座をはじめてしまうのか?
なぜUFOにさらわれてしまうのか?



謎は深まるばかりでございます(by 鈴木健ニ)


とりあえず こっち見んな

akinow at 17:48|PermalinkComments(10)TrackBack(0) Clip to Evernote 日記 

2012年08月12日

うにばな(シェーダ的なもの2−2)

Cgでシェーダのプロパティにアクセスする


シェーダは、プロパティブロック内でプロパティを宣言します。それらのプロパティにアクセスする場合は、Cgのシェーダプログラムを、同じ名前と一致するタイプでCg変数を宣言する必要があります。


例は提供されている頂点プログラムとフラグメントプログラム:シェーダーチュートリアル


http://docs.unity3d.com/Documentation/Manual/ShaderTut2.html


たとえば、これらのシェーダのプロパティは:


_MyColor ("Some Color", Color) = (1,1,1,1) 
_MyVector ("Some Vector", Vector) = (0,0,0,0)
_MyFloat ("My float", Float) = 0.5
_MyTexture ("Texture", 2D) = "white" {}
_MyCubemap ("Cubemap", CUBE) = "" {}

としてCgコードにアクセスするために宣言されます。


float4の_MyColor
float4の_MyVector
floatの_MyFloat;
sampler2Dの _MyTexture
samplerCUBEの _MyCubemap

Cgはまた必須ではありませんが uniformを受け入れることができ、


uniform float4 _MyColor。

Cgは変数の型は、この方法にShaderLabマップのプロパティの型:



  • ColorとVectorのプロパティにマップするfloat4。

  • RangeとFloatプロパティにマップするfloat。

  • Textureのプロパティにマップするsampler2D 通常の2Dテクスチャのための変数。

  • CUBEとRECTtexturesマップのための samplerCUBEとsamplerRECTそれぞれの変数。


頂点プログラムに頂点データを転送


http://docs.unity3d.com/Documentation/Components/SL-ShaderPrograms.html


Cgの頂点プログラム、頂点データは構造体として渡される必要があります。いくつかの一般的に使用される頂点の構造体で定義されている UnityCG.cgincファイルが含まれており、ほとんどのケースでは、それらを使用するだけで十分です。構造は次の通りです。



  • appdata_base:頂点座標と、法線と ひとつのテクスチャ座標で構成されています。

  • appdata_tan:頂点座標、接線、法線と ひとつのテクスチャ座標で構成されています。


たとえば、このシェーダの色は、メッシュはそれの法線に基づいておりappdata_baseを頂点プログラム入力として:


Shader "VertexInputSimple" {
SubShader {
Pass {
CGPROGRAM
#pragma vertex vert
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
fixed4 color : COLOR;
};
v2f vert (appdata_base v)
{
v2f o;
o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
o.color.xyz = v.normal * 0.5 + 0.5;
return o;
}
ENDCG
}
}
}

別の頂点データにアクセスしたい場合は、頂点の構造を自分で宣言する必要があります。構造体のメンバーがでなければなりません


以下 構造体のリスト:



  • float4 vertex 頂点の位置

  • float3 normal 頂点の法線

  • float4 texcoord 最初のUV座標

  • float4 texcoord1 第二のUV座標

  • float4 tangent 接線ベクトル(法線マッピングに使用されます)

  • float4 color 頂点単位の色


ShaderLab構文:Pass


Passブロックはオブジェクトのジオメトリを一度レンダリングします。


構文


Pass { [Name and Tags] [RenderSetup] [TextureSetup] }
基本的なパス・コマンドは、、レンダリングのセットアップコマンドのオプションのリストに続いて使用するテクスチャのオプションのリストが含まれています。

Name and tags


パスは名前と任意の数のタグで定義することができます。名前/値の文字列はPassをレンダリングエンジンに渡す意図で使用されます。


Render Setup


パスは、グラフィックスハードウェアのさまざまな状態を設定します。例えば、アルファブレンディングは、フォグが使用されるときオンにする必要があります。それぞれコマンドは以下のとおりです。


Material { Material Block }
頂点ライティングパイプラインで使用するマテリアルを定義します。詳細についてはマテリアルのページを参照 http://docs.unity3d.com/Documentation/Components/SL-Material.html
Lighting On | Off
頂点ライティングをオンまたはオフにします。詳細についてはマテリアルのページを参照
 Cull Back | Front | Off
ポリゴンカリングモードを設定します。
ZTest (Less | Greater | LEqual | GEqual | Equal | NotEqual | Always)
深さのテストモードを設定します。
ZWRITE ON | OFF
深さ(Zデプス)の書き込みモードを設定します。
Fog { Fog Block }
フォグのパラメータを設定します。
AlphaTest (Less | Greater | LEqual | GEqual | Equal | NotEqual | Always) CutoffValue
アルファテストが有効になります。
Blend SourceBlendMode DestBlendMode
アルファブレンディングモードを設定します。
Color Color value
頂点ライティングがオフになっている場合に使用する色を設定します。
ColorMask RGB | A | 0 | any combination of R, G, B, A
色書き込みマスクを設定します。ColorMask 0書き込むとすべてのカラーチャンネルのレンダリングをオフにします。
Offset OffsetFactor , OffsetUnits
オフセットの深さを設定します。
SeparateSpecular ON | OFF
頂点ライティングのための独立したスペキュラカラーをオンまたはオフにします。詳細についてはマテリアルのページを参照。 http://docs.unity3d.com/Documentation/Components/SL-Material.html
ColorMaterial AmbientAndDiffuse | Emission
頂点ライティングを計算するときに頂点単位の色を使用します。詳細についてはマテリアルのページを参照。http://docs.unity3d.com/Documentation/Components/SL-Material.html

テクスチャーのセットアップ


レンダリングステートの設定後に、SetTextureのコマンドを使用して適用するテクスチャとそのコンバインモードの数を指定することができますhttp://docs.unity3d.com/Documentation/Components/SL-SetTexture.html


SetTexture texture property { [Combine options] }


テクスチャーのセットアップは固定機能マルチテクスチャパイプラインを設定しますが、カスタムのフラグメントシェーダが使用されている場合無視されます。http://docs.unity3d.com/Documentation/Components/SL-ShaderPrograms.html


細部


Per-pixel Lighting (ピクセル単位のライティング)

ピクセル単位のライティングパイプラインは複数のパスでオブジェクトをレンダリングすることによって動作します。Unityは、環境光との任意の頂点ライトを取得するために一度オブジェクトをレンダリングしそれから、別々に追加されたパス内のオブジェクトに影響を与える各ピクセルのライティングをレンダリングします。パイプラインのレンダリング詳細を参照してください。http://docs.unity3d.com/Documentation/Components/SL-RenderPipeline.html


Per-vertex Lightig (頂点単位のライティング)

頂点単位のライティングは、各頂点に対して計算されている標準Direct3D/OpenGL照明モデルです。


Lighting onでON状態になります。照明によって影響されるMaterialブロックColorMaterialとSeparateSpecularコマンドを使用します。詳細についてはマテリアルのページを参照。


以下も参照してください


共通の機能を再利用したり、さまざまなハイエンドなエフェクトを実装するために使用できるいくつかの特別なパスがあります。



  • UsePass 別のシェーダから指定された名前のパスが含まれています。


http://docs.unity3d.com/Documentation/Components/SL-UsePass.html



  • GrabPass 後のパスで使用するために、テクスチャに画面の内容をつかむ。


http://docs.unity3d.com/Documentation/Components/SL-GrabPass.html 


ShaderLab syntax: SubShader Tags




    • Background -このレンダーキューは、任意の他の人の前にレンダリングされます。これは、スカイボックスなどに使用されます。

    • Geometry (デフォルト) -ほとんどのオブジェクトに使用されます。不透明なジオメトリは、このキューを使用しています。

    • AlphaTest -アルファテストされたジオメトリはこのキューを使用しています。すべてのジオメトリオブジェクトが描画された後、アルファテストされたオブジェクトをレンダリングする方が効率的なのです。

    • Transparent -このレンダリング・キューはGeometry とAlphaTestの後に描画され 後ろから手前に向かって描画されます。アルファブレンド(深度バッファへの書き込みのないもの 例えばガラス、パーティクルエフェクト)がここに書き込まれます。

    • Overlay -このレンダーキューはオーバーレイ効果を意図しています。最後にレンダリングされたもの(レンズフレアなど)はここに書き込まれる必要があります。



Shader "Transparent Queue Example" {
SubShader {
Tags {"Queue" = "Transparent" }
Pass {
//シェーダの本体 }
}
}

シェーダのパフォーマンス向上


必要なものだけを計算するようにします。たとえば マテリアルごとに色を割りつけられるようにすれば柔軟なシェーダになりますが、常に白に設定しておくことで計算が軽くなりレンダリング能力が向上します。

頂点シェーダに比べてピクセルシェーダは大変多くのピクセルを演算しなければならないため頂点シェーダの中でピクセルシェーダの計算を移動して行ったほうが処理負荷が軽減できます。 またシェーダ外部のスクリプトで計算された値をシェーダに設定することでも同様に処理が軽くなります。


一般的なサーフェスシェーダ

サーフェスシェーダは照明との対話シェーダを書くために最適です。しかし、そのデフォルトのオプションは、 "一般的ケース"に調整されています。多くのケースでは、シェーダの実行速度を向上させたり、サイズを小さくするために、それらを調整することができます。

approxview ビュー方向(鏡面など)を使用してシェーダのディレクティブは、ビュー方向ではなく、ピクセルごとの正規化された頂点ごとになります。これは時に十分良い効果があります。

halfasview スペキュラシェーダタイプも速くなります。ハーフベクトル(照明の方向とビューベクトルとの中間のベクトル)を計算され頂点ごとに正規化されます。ライティング機能はビューベクトルの代わりにハーフベクトルを受け取ります。

noforwardadd シェーダが完全に前方レンダリングでディレクショナルライトを一つだけサポートするようになります。残りのライトは頂点ごとに光や球面調和関数としての効果を持つことができます。これは、シェーダを小さくし、複数のライトが存在して 1パスでレンダリングを確認するために最適です。


noambientは、周囲の照明や シェーダ上の球面調和ライトを無効にします。これは若干速くなる可能性があります。


●計算の精度
CG / HLSLでシェーダを作成するとき、3つの基本的な種類の数値があります:float、harfとfixed(同様に、それらのベクトル・行列、例えばhalf3、float4x4 など)

●float:高精度浮動小数点。一般的に32ビット、普通のプログラミング言語のfloat型。

●half:培地精度浮動小数点。精度は-60000から60000 3.3桁の範囲で、一般的に16ビット。

●fixed:低精度の固定小数点。-2.0から2.0の範囲と256分1の精度で、一般的に11ビット。

可能な限り最小の精度を使用します。これは、iOSやAndroidなどのモバイルプラットフォーム上で特に重要です。例えば以下のとおり

●色と単位長さベクトルについては、fixedを使用。
●範囲と精度が良好である場合はharfを使用、それ以外の場合floatを使用します。
モバイルプラットフォームでは、フラグメントシェーダ内で可能な限り低精度を維持することです。ほとんどのモバイルGPU上で、(lowp /fixed)低精度型にswizzleを適用する場合 fixed/ lowpと高精度タイプ間の変換の場合などは非常に演算コストがかかります。

swizzleの動作は"xy" を "xyyy", "wz" を "wzzz”に変換するなど

●アルファテスト

固定機能であるAlphaTestや同等な機能clip()はプラットフォームによりパフォーマンスに差異があります。

一般的にはほとんどのプラットフォームでは完全に透明なピクセルをカリングすることは小規模な利点ですが IOSおよびいくつかのAndroidデバイスで採用されているPowerVRの GPU上でのアルファテストは非常に負荷が高いです。そこで "パフォーマンスの最適化"としてこれを使用しないと描画が遅くなります。

●カラーマスク

いくつかのプラットフォーム(モバイルGPUなど)上で使用して、ColorMaskを用いていくつかのチャネルを除外することで、描画速度の向上が期待できます。





ShaderLab 組み込みの値


Unityは、シェーダのための組み込みの値をいくつか提供しています。現在のオブジェクトの変換行列、時間などです。


あなたが他のプロパティを使用したようにするだけでShaderLabでそれらを使用することができます、唯一の違いは、組込されている値のためを宣言する必要がないことです。
組み込み値を使用する際プログラマブルシェーダに”UnityCG.cginc”を含む必要があります


http://docs.unity3d.com/Documentation/Components/SL-ShaderPrograms.html


●Transformations


float4x4 UNITY_MATRIX_MVP現行モデル*ビュー*射影行列
float4x4 UNITY_MATRIX_MV現在のモデル*ビュー行列
float4x4 UNITY_MATRIX_P現在の射影行列
float4x4 UNITY_MATRIX_T_MVモデル*ビュー行列の転置
float4x4 UNITY_MATRIX_IT_MVモデル*ビューの逆行列
float4x4 UNITY_MATRIX_TEXTURE0 to UNITY_MATRIX_TEXTURE3テクスチャ変換行列
float4x4 _Object2World現在のモデル行列
float4x4 _World2Object現在のワールド行列の逆行列
float3 _WorldSpaceCameraPosカメラのワールド空間の位置
float4 unity_Scalexyzのコンポーネントが使用されていない; 。wは、一様にスケーリングされたオブジェクトのスケールを含んでいます。

●Lighting

例えばライトモデル*ライトカラーは次のとおりです。プレーンShaderLabでは、末尾にゼロを付加することにより、次のプロパティにアクセスする_ModelLightColor0。Cgのシェーダで、それらは単一の要素を持つ配列として公開され、Cg同じように_ModelLightColor [0]



UNITY_LIGHTMODEL_AMBIENT
現在のアンビエントカラー。

Name Type Value


_ModelLightColor float4 Materialのメインカラー * Lightカラー


_SpecularLightColor float4 Materialのスペキュラカラー * Lightカラー


_ObjectSpaceLightPos float4 オブジェクト空間でのライトの位置. wコンポーネント


は ディレクショナルライトの場合0、それ以外のライトは1 。


_Light2World float4x4 ワールド空間行列でのライト座標


_World2Light float4x4 ライト空間行列へワールド座標


_Object2Light float4x4 ライト空間行列へのオブジェクト座標


Various



  • float4 _Time : Time (t/20, t, t*2, t*3),シェーダ内でアニメーションをするために使用

  • float4 _SinTime : Sine of time: (t/8, t/4, t/2, t)

  • float4 _CosTime : Cosine of time: (t/8, t/4, t/2, t)

  • float4 _ProjectionParams :

    xは反転射影行列を使用してレンダリングする場合は負、1.0または-1.0 、yはカメラのnearplaneでzはカメラのfarplaneであるwは1/FarPlaneです。

  • float4 _ScreenParams :

    xは現在のレンダーターゲットのピクセル単位の幅です。yは現在のレンダーターゲットのピクセル単位の高さzは、 1.0 + 1.0/widthですwは 1.0 + 1.0/heightです。


GLSLシェーダプログラム


CG / HSLシェーダプログラムの使用に加えて、OpenGLシェーディング言語(GLSL)シェーダを直接書き込むことができます。


しかし、GLSLの使用は、Mac OS XやOpenGL ES 2.0互換のモバイルデバイスを対象としています。たいていの場合、Unityは、CG / HLSLを最適化されたGLSLにクロスコンパイルします(これはモバイル・プラットフォームのデフォルトで行われ、必要に応じてデスクトッププラットフォーム用に#pragma GLSLを記述することでオンにすることができます)。


GLSLスニペット


GLSLプログラムのスニペットは、GLSLPROGRAMとENDGLSLキーワードの間に書かれています


GLSLでは、シェーダ関数のエントリポイントはmain()関数で定義されます。


UnityがGLSLシェーダをロードするとき、各GLSLスニペットで#ifdef VERTEX .. #endifと#ifdefのFRAGMENT .. #endifの。頂点プログラムとフラグメントプログラムの両方を含める必要があります。


インクルードファイルは、.glslinc拡張子で提供される UnityCG.glslincファイルです。



その他: Unityに内蔵されているシェーダのソースに関しては↓からダウンロードしてください。

http://www.unity3d.com/support/resources/assets/built-in-shaders



akinow at 19:45|PermalinkComments(2)TrackBack(0) Clip to Evernote Unity3d | シリーズ講座

うにばな(シェーダ的なもの2−1)



サーフェスシェーダの作成

ライティングとの対話シェーダを書くことは複雑です。そこに異なるライトの種類、異なるの影のオプション、異なるレンダリングパス(フォワードおよび遅延レンダリング)は、シェーダはすべてその複雑さを処理する必要があります。
unityのサーフェスシェーダでは、低レベルの頂点/ピクセルシェーダプログラムを使用するよりも点灯シェーダを作成することがはるかに容易にコードを生成するアプローチとなります
。サーフェスシェーダに独自の言語は使用しません。すべてのコード生成は手で書かなければいけません。CG / HLSLでシェーダコードを記述します。


いくつかの例については、サーフェスシェーダの例サーフェスシェーダのカスタムライティングの例を見てください。


どのように動作するのか


入力として必要なすべてのUVまたはデータを受け取り、 "サーフェス機能"を定義し、SurfaceOutput出力に必要な値を満たします。SurfaceOutputは、基本的にはサーフェスのプロパティ(アルベドカラー、法線、放射、スペキュラなどです)。Cg / HLSLでこのコードを記述します。
サーフェスシェーダコンパイラは、必要な値が入力されているか、出力の値は全て満たされているかを判別しその後に、
頂点とピクセルシェーダを生成します、同様にレンダリングパスがフォワードレンダリングとディファードレンダリングに値を渡します。



表面シェーダの標準出力の構造



struct SurfaceOutput {
half3 Albedo;
half3 Normal;
half3 Emission;
half Specular;
half Gloss;
half Alpha;
};


サーフェスシェーダの例


http://docs.unity3d.com/Documentation/Components/SL-SurfaceShaderExamples.html


カスタムライティングの例


http://docs.unity3d.com/Documentation/Components/SL-SurfaceShaderLightingExamples.html


サーフェスシェーダのコンパイルディレクティブ


サーフェスシェーダは他のシェーダと同じようにCGPROGRAM..ENDCG、の内部に配置されます。
相違点は次のとおりです。



  • SubShaderの内側に配置する必要がありますPassのブロックではありません。サーフェスシェーダは 複数のPassを含むようにコンパイルされます。

  • #pragma surface を用いて...ディレクティブはサーフェスシェーダを示しています。


#pragma surfaceディレクティブは、次のとおりです。


    #pragma surface surfaceFunction lightModel [optionalparams]

必要なパラメータ:



  • surfaceFunction -Cg関数はサーフェスシェーダコードで定義されます。

  • 関数は、void surf (Input IN, inout SurfaceOutput o) といったフォームが必要で入力はユーザが定義する構造体です。surfaceFunctionには任意のテクスチャ座標とサーフェス機能で必要とされる自動変数を含める必要があります。

  • lightModel -使用する照明モデル。内蔵のものはLambert(拡散)とBlinnPhong(鏡面)。

  • カスタムライティングモデル    を 参照してください。


             http://docs.unity3d.com/Documentation/Components/SL-SurfaceShaderLighting.html


オプションのパラメータ:




  • alpha -アルファブレンドモード。半透明シェーダに使用します。

  • alphatest:VariableName -アルファテストモード。透明カットアウトシェーダに使用します。カットオフ値のVariableNameは、float変数になっています。

  • VertexVertexFunction -カスタム頂点変更機能。例:樹皮シェーダを参照してください。

  • finalcolor:ColorFunction -カスタム最終的な色の変更機能。サーフェスシェーダの例を参照してください。 http://docs.unity3d.com/Documentation/Components/SL-SurfaceShaderExamples.html

  • exclude_path:prepassまたはexclude_path:forward -指定された描画パスを生成しません。

  • addshadow -シャドウキャスターとコレクターのパスを追加します。一般的にカスタム頂点の変更で使用するので、その影のキャスティングは、任意の手続きの頂点アニメーションを取得します。

  • dualforward -dual lightmaps をフォワードレンダリングパスで使用します。

  • fullforwardshadows -フォワードレンダリングパスですべてのシャドウタイプのサポートをします。

  • decal:add- 加算デカールシェーダ(例えばterrain AddPass)。

  • decal:blend -半透明デカールシェーダ。

  • softvegetationは -ソフトベジテーションがオンになっている場合、サーフェスシェーダのみがレンダリングされるようにします。

  • noambientは、 -環境光や ​​球面調和ライトを適用しない。

  • novertexlightsは -フォワードレンダリングで任意の球面調和関数または頂点単位のライトを適用しない。

  • nolightmap -このシェーダでのライトマップのサポートを無効にします(シェーダは小さくなります)。

  • nodirlightmapは -このシェーダでのディレクションライトマップのサポートを無効にします(シェーダが小さくなります)

  • noforwardaddは -フォワードレンダリング添加パスを無効にします。

  • ひとつのディレクショナルライトを作成し他のすべてのライトを頂点単位でper-vertex/SH(頂点単位のSpherical Harmonics =球面調和関数を用いた環境光マッピング)に割り付けますたいへんシェーダが小さくなります)

  • approxviewは -正規化されたビューの方向をピクセル単位でなく頂点単位で計算します。これは高速ですが、カメラがサーフェス表面に近づくとビューの方向が完全には正しくなりません。

  • halfasviewは -ライティング機能の代わりに、ビュー方向にハーフベクトルを渡します。頂点ごとにハーフ方向が計算され正規化されます。これは速いですが完全に正しくはなりません。


追記:#pragma debugをCGPROGRAM 内部に書くことで、コンパイラは生成された多くのコメントコードを切り離します。シェーダインスペクタでコンパイルされた後シェーダを見ることができます。



サーフェスシェーダの入力構造



入力構造の入力部は一般的にシェーダが必要とするテクスチャ座標を持っています。テクスチャ座標は 名前を付ける必要があり、”UV”テクスチャ名(またはUV2を指定で2番目のテクスチャ座標セットを使用する)。



入力構造体に入れることができる追加の値:



  • float3 VIEWDIRは -リムライティング等、視差効果を計算するためのビューの方向が含まれています

  • float4 COLOR-頂点単位の色の補間が含まれています。

  • float4 screenPosは -反射効果のためのスクリーンスペース座標が含まれています。例えばWetStreetシェーダなど

  • float3 worldPosは -ワールド空間の位置座標が含まれています。

  • float3 worldReflは -ワールド空間の反射ベクトルが含まれます。これはサーフェスシェーダがo.Normalに書き込みをしていない場合です。例:リフレクト拡散シェーダを参照してください。

  • float3 worldNormalは -ワールド空間の法線ベクトルが含まれます。ただしサーフェスシェーダがo.Normalに書き込みをしていない場合

  • float3 worldRefl。INTERNAL_DATAは -ワールド空間の反射ベクトルが含まれます。これはサーフェスシェーダがo.Normalに書き込む場合です。ピクセル単位の法線マップに基づいて反射ベクトルを取得するには、(IN、o.Normal)WorldReflectionVector。例:リフレクト・バンプシェーダを参照してください。

  • float3 worldNormal。INTERNAL_DATAは -ワールド空間の法線ベクトルが含まれます。これはサーフェスシェーダがo.Normalに書き込む場合です。 ピクセル単位の法線マップに基づいて、法線ベクトルを取得するには、WorldNormalVectorを(IN、o.Normal)


サーフェスシェーダの例




サーフェスシェーダのカスタムライティングモデル


サーフェスシェーダ書き込み時に、サーフェスの性質を記述している(アルベド、色、法線、...)とライティングの相互作用はライティングモデルにより計算されます。ビルトインのライティングモデルはランバート(拡散照明)とBlinnPhong(スペキュラライティング)。


カスタムライティングモデルを使用するときにはサーフェスシェーダで行うことが可能ですライティングモデルは、いくつかのCG / HLSL関数の組み合わせ以上の何物でもありません。ビルトインランバートBlinnPhongのモデルは、Lighting.cgincで定義されています。


windowsの場合 (Unityインストールパス /Data/ CGIncludes / Lighting.cginc


Macの場合 /Applications/Unity/Unity.app/Contents/CGIncludes/Lighting.cginc


ライティングモデルの宣言


ライティングモデルは通常Lightingで始まる名前を持ついくつかの機能です。シェーダファイルまたはインクルードファイルのいずれかでどこでも宣言することができます。関数は次のとおりです。



  1. half4 Lighting名前(SurfaceOutput S、half3 lightDir、 harf atten) これは、

  2. ライトモデルのフォワードレンダリングパス使用時ビュー方向に依存しません。(例えば、拡散)。

  3. half4 Lighting名前(SurfaceOutput S、half3 lightDir、half3 ViewDir、harf atten) ライトモデルのフォワードレンダリングパス使用時ビュー方向に依存します。

  4. half4 Lighting名前 _PrePass(SurfaceOutput s、half4 light) これはディファードライティングパスで使用されます。


すべての関数を宣言する必要がないことに注意してください。照明モデルはビューの方向を使用してもしなくてもいいです。ライティングモデルは、ディファードライティングではライティングモデルが動作しない場合は_PrePass機能を宣言していないと思います  それを使用するすべてのシェーダはフォワードレンダリングのみを転送するようにコンパイルされています。


デコードの方向ライトマップは、フォワードおよびディファードのライティング機能と同様の方法でいくつかの状況でカスタマイズする必要があります。あなたのライティングモデルがビュー方向に依存しているかどうかに応じて以下の関数のいずれかを使用します。両関数は自動的にフォワードおよびディファードのレンダリングパスを処理します。



  1. half4 Lighting名前 _DirLightmap(SurfaceOutput S、fixed4 color、fixed4 scale、bool surfFuncWritesNormal) これはビュー方向に依存して表示(例えば、拡散)されないライティングモデルに使用されます。

  2. half4 Lighting名前 _DirLightmap(SurfaceOutput S、fixed4 color、fixed4 scale、half3 ViewDir、bool surfFuncWritesNormal、out half3 specColor) これは、ビューの方向依存しているライティングモデルに使用されます。



http://docs.unity3d.com/Documentation/Components/SL-SurfaceShaderLightingExamples.html




バーテックスシェーダおよびフラグメントシェーダを作成


ShaderLabのシェーダは別のグラフィックスハードウェアのための複数のシェーダの実装が含まれている固定機能ハードウェアの状態などを設定し、マテリアルのインスペクタに表示されるプロパティを記述します。実際のプログラマブルシェーダ-頂点プログラムとフラグメントプログラムなどが-全体のShaderLabの"シェーダ"というコンセプトのほんの一部です。
シェーダチュートリアル基本的な導入のために。ここでは、低レベルのハードウェアシェーダと呼ぶシェーダプログラムを見てください。


あなたがライティングとの対話シェーダを作成したい場合は、サーフェスシェーダのマニュアルを見てください。。このページの残りの部分(例えば、特殊効果、Unityのライトと相互作用しないシェーダを想定しています画像効果など)

シェーダプログラムは、どこかの内部に、シェーダテキストの"スニペット"を埋め込 ​​むことにより、CG / HLSL言語で書かれたパスのコマンドを実行します。それは通常、以下のようになります。


 Pass {
// ... the usual pass state setup ...
CGPROGRAM
// compilation directives for this snippet, e.g.:
#pragma vertex vert
#pragma fragment frag
// the Cg code itself
ENDCG
// ... the rest of pass setup ...
}

Cgのスニペット(挿入テキスト)


Cgプログラムのスニペットは、CGPROGRAMとENDCGの間に書かれます。


スニペットの開始時にコンパイル・ディレクティブ(指示)は#pragma文で与えることができます。Unityによって認識されるディレクティブは次のとおりです。



  • #pragma vertex name -nameはバーテックスプログラムを示します。

  • #pragma fragment name -nameはフラグメントプログラムを示します。

  • の#pragma fragmentoption option-追加オプションはOpenGLのフラグメントプログラムにコンパイルされます。ARBフラグメントプログラムの使用可能なオプションのリストの仕様を参照してください。http://www.opengl.org/registry/specs/ARB/fragment_program.txt

  • このディレクティブは非OpenGLをターゲットにコンパイルされたプログラムまたは頂点プログラムには影響を与えません。

  • #pragma target name -シェーダターゲットにコンパイルする。シェーダターゲット詳細を参照してください。

  • #pragma only_renderers space sepatratesd names-のみ与えられたレンダラのためにシェーダをコンパイルします。デフォルトでは、シェーダは、すべてのレンダラー用にコンパイルされています。レンダラ詳細を参照してください。

  • の#pragma exclude_renderers space separated names -指定されたレンダラのためにシェーダをコンパイルしないでください。デフォルトでは、シェーダは、すべてのレンダラー用にコンパイルされています。レンダラー詳細を参照してください。

  • http://docs.unity3d.com/Documentation/Components/SL-ShaderPrograms.html#renderers

  • #pragma glsl -デスクトップOpenGLのプラットフォーム用のシェーダをコンパイルするとき、(代わりに、ARB頂点/フラグメントプログラムでのデフォルト設定の)GLSLにCg / HLSLに変換する


各スニペットは、バーテックスプログラム、フラグメントプログラム、またはその両方を含める必要があります。したがって、#pragma vertexまたは#pragma fragment またはその両方は必要に応じて指示されます。





akinow at 19:43|PermalinkComments(0)TrackBack(0) Clip to Evernote Unity3d | シリーズ講座

うにばな(シェーダ的なもの1−2)


ベクトル計算の基本



no title


ベクトルはvector(x,y,z)で表現されるある座標からある座標までの差分で、方向と長さを表現する事ができます。
ベクトルは合成でき上図のようにベクトルAとベクトルBを合成したベクトルA+Bとして扱うことができます。



no title



ベクトルは長さを持っていますが、方向を表現したいとき大きさ(長さ)を持っていると扱いにくいので大きさが1の単位ベクトルにして扱います。
これを正規化(normalize)と呼んで シェーダの関数ではnormalize(Vector)を使用します。



no title



ゲームでよく使われる計算に内積があります。2つの交差したベクトルを掛けたものが内積でCosθの値をとります。つまり2つのベクトルが平行な場合1直角の場合0を取ります。



シェーダ関数はdot(a,b)を使用します。外積はcross(a,b)


ベクトルの内積および外積をどのようにゲームで使用するかの例は以下のとおりです。


ベクトル内積の概要





図のようにaベクトルをbベクトルへ投影したベクトルa'があったとします。

このa'の長さにbベクトルの長さをかけた値が内積の大きさです。

ただし2つのベクトルが鈍角であれば内積はマイナス値になります。

2つのベクトルが直角の時は内積は0です。


内積の用途


ゲームプログラミングではベクトルの内積を次のような用途に使います。

・2つのベクトルが直交するか

・2つのベクトルが平行か

・2つのベクトルの向き(鋭角、鈍角かどうか)判定

・2つのベクトルの角度

・点が平面の表側、裏側どちらにあるか判定

・平面上に点があるか

・片方のベクトルをもう片方へ射影したベクトルの計算


ベクトル外積の概要

外積を行うとベクトルa,bに直行するベクトルが作られます。

そのときのベクトルの長さは、ベクトルa,bで平行四辺形を作ったときの面積を表します。

図のようにかける順番によって得られるベクトルの向きが変わります。


外積の用途

ゲームプログラミングではベクトルの外積を次のような用途に使います。

・2つのベクトルに垂直なベクトルを求める。

・ポリゴンの向き(法線ベクトル)を求める。

・2つのベクトルが所属する平面において左右の位置関係を知る

・平面上の三角形と点の内外判定

・ポリゴンの面積を計る

・平面上の閉領域の面積を計る

・平面上の閉領域の向き(時計回りか、反時計回り)

http://www.sousakuba.com/Programming/gs_gaiseki.html


マテリアルのシェーダーでの計算例



no title


no title



L:LightDirection(光源方向のベクトル)
V:ViewDirection(視線方向=カメラ方向のベクトル)
H:HarfVector(ハーフベクトル=ポリゴン面の法線とライト方向Lの中間に向かうベクトル)
N:Normal(ポリゴン平面の法線方向)
Shininess:(光沢成分の乗数)
La:LightAmbient(ライトの環境光成分)
Ld:LightDiffuse(ライトのデフューズ成分)
Ls:LightSpecular(ライトのスペキュラー成分)
Lo=_Color(マテリアルカラー)
Lo(s) =_Speculer(マテリアルのスペキュラ)


頂点シェーダでの例です 関数で動作がわからない箇所はHLSLの対応表をUnityのビルトイン関数は"UnityCG.cginc"ファイルを参照して検証してみてください。
v2fはstructで定義された構造体です。構造体名”o”で定義される値がv2f型で頂点シェーダに戻ります


v2f vert( appdata_base i)
{
v2f o;
o.position = mul( glstate.matrix.mvp, i.vertex );
float3 n =mul(glstate.matrix.invtransview[0],float4(i.normal,1));
float LdotN=saturate( dot( glstate.light[0].position,n));
o.color = glstate.lightmodel.ambient*_Color
o.color += LdotN * _Color * glstate.light[0].diffuse;

float3 L = ObjSpaceLightDir(i.vertex);
float3 V = ObjSpaceViewDir( i.vertex);
float3 H = normalize(L + V );

float NdotH = dot(i.normal , H);
o.color += _Specular * pow(NdotH,_Shiniess *128);
return o;
}


http://en.wikipedia.org/wiki/Blinn%E2%80%93Phong_shading_model

http://ja.wikipedia.org/wiki/Phong%E3%81%AE%E5%8F%8D%E5%B0%84%E3%83%A2%E3%83%87%E3%83%AB

http://es.scribd.com/doc/90634580/109/The-Blinn-Phong-Shaders

http://www.arcsynthesis.org/gltut/Illumination/Tut11%20BlinnPhong%20Model.html


http://asura.iaigiri.com/OpenGL/gl28.html



●スクリプトからシェーダーへのアクセス

シェーダにアクセスする場合 最初に
renderer.material.shader=Shader.Find( "シェーダの名前" );
を使用してどのシェーダにアクセスするかを定義します。
オブジェクトにmaterialが複数使用されている場合もありますのでこれを実行してください。
※使用されているシェーダ名プロパティがわからない場合シェーダファイルを調べても良いですが
アニメーションウィンドウを開いてマテリアルのアニメーションキーの名前を調べても良いです。
シェーダにプロパティが存在するか問い合わせるにはHasPropertyを使用して
renderer.material.HasProperty("プロパティ名") とします戻り値はboolean型です。

例:シェーダにフロート型の値を設定する場合

function Start () {   // ”Glossy ”というシェーダを探してマテリアルに設定します

    renderer.material.shader = Shader.Find(" Glossy");
}

function Update () {
//値Shininessのアニメーション ここではtimeと1.0の間を往復させています
var shininess : float =
Mathf.PingPong (Time.time, 1.0);
renderer.material.SetFloat( "_Shininess", shininess );
}

マテリアルクラスのメンバ


Variables
shader:使用されているマテリアルに設定されたシェーダ.
color:メインマテリアルのカラー.
mainTexture:メインマテリアルのテクスチャ.
mainTextureOffset:メインテクスチャのオフセット.
mainTextureScale:メインテクスチャのスケール.
passCount:現在使用しているマテリアルのパス数取得(Read Only)
renderQueue: 現在のマテリアルのレンダーキューを設定する(int型)


Constructors

Material:Textにshaderの本体を記述してrenderer.material = new Material( shaderText );でマテリアルをテンポラリとして扱える。要するにスクリプトからマテリアルを一時的に生成できます。


Functions
SetColor:指定したカラーの値をセットします.
GetColor:指定したカラーから値を取得します.
SetVector:指定したベクトル値に値をセットします.
GetVector:指定したベクトル値から値を取得します.
SetTexture:指定したテクスチャプロパティにテクスチャをセットします.
GetTexture:指定したテクスチャプロパティからテクスチャを取得します(返り値はtexture型)
SetTextureOffset:指定したテクスチャのオフセット変位を与えます 移動量はvector2型.
GetTextureOffset:指定したテクスチャのオフセット変位を取得します.
SetTextureScale:指定したテクスチャにスケール値を与えます .
GetTextureScale:指定したテクスチャからスケール値を取得します .
SetMatrix:シェーダーにマトリックス変換行列をセットします.
GetMatrix:シェーダからマトリックス変換行列を取得します.
SetFloat:指定した値にフロート型の値をセットします.
GetFloat:指定した値からフロート型の値を取得します.
HasProperty:シェーダで指定した名前のプロパティが使用されているか問い合わせます.
GetTag:シェーダからタグを取得します (返り値はString型)
Lerp:2つのマテリアルの名前とリープ値を設定することでマテリアルをブレンドします.
SetPass:Activate the given pass for rendering.
CopyPropertiesFromMaterial:他のマテリアルから現在のマテリアルにプロパティをコピーします.


追記:関連して”テクスチャの回転”で検索がありましたので サンプルを載せておきます。


■MatrixRotation サンプル


http://docs.unity3d.com/Documentation/ScriptReference/Material.SetMatrix.html



var rotateSpeed = 30;
var texture : Texture;

function Start() {

var m : Material = new Material (
"Shader \"Rotating Texture\" {" +
"Properties { _MainTex (\"Base\", 2D) = \"white\" {} }" +
"SubShader {" +
" Pass {" +
" Material { Diffuse (1,1,1,0) Ambient (1,1,1,0) }" +
" Lighting On" +
" SetTexture [_MainTex] {" +
" matrix [_Rotation]" +
" combine texture * primary double, texture" +
" }" +
" }" +
"}" +
"}"
);
m.mainTexture = texture;
renderer.material = m;
}

function Update() {

var rot = Quaternion.Euler (0, 0, Time.time * rotateSpeed);
var m = Matrix4x4.TRS (Vector3.zero, rot, Vector3(1,1,1) );
renderer.material.SetMatrix ("_Rotation", m);
}


マトリクスのトランスフォーム


TRS (pos : Vector3, q : Quaternion, s : Vector3) : Matrix4x4


新規にマテリアルを生成してUpDate文の中でMatrixに回転成分を与えて_Rotationに値を設定します。TRS関数は(移動、回転(Quartterinion),スケール)を設定することでMatrixに値を返します。マトリックス変換の基本となる変換行列は以下のとおりです。



no title
no title
no title



マトリックス変換をシェーダの中でも行うことができます。


例:
void surf (Input IN, inout SurfaceOutput o) {

   float4 oColor;

   float2 UV;

UV =IN.uv_MainTex;

float4 sine = sin(_Time*_StretchTime);
float4 cosine = cos(_Time*_StretchTime);
pulsateMatrix._m00 = pulsateMatrix._m11 = cosine;
pulsateMatrix._m10 = -sine;
pulsateMatrix._m01 = sine;

float4 temp = float4 (UV.x, UV.y, 0, 0);
temp = mul(pulsateMatrix,temp);

UV.x = temp.x;
UV.y = temp.y;

oColor = tex2D(_MainTex, UV);
o.Albedo = oColor.rgb;
o.Alpha = oColor.a
}


先に説明した通り4×4行列のメンバに変換のための三角関数を埋めこむのでz軸回転の行列を
使用してx,yの値をU,vに代入します

_m00, _m01, _m02, _m03    cosθ -sinθ 0 0
_m10, _m11, _m12, _m13 →  sinθ cosθ 0 0
_m20, _m21, _m22, _m23    0  0 0 0
_m30, _m31, _m32, _m33    0  0 0 0

_m00 =_m11 = cosine;
_m10 = -sine;  
_m01 = sine;


シェーダでのテクスチャのマトリックス変換は可能ですが、GPUに負荷がかかるため
GPUの強力なPCでの開発に関しては問題無さそうですが モバイル機器の開発では
スクリプトで計算をしてシェーダに値を設定したほうが安定しそうな気はします。



akinow at 17:39|PermalinkComments(0)TrackBack(0) Clip to Evernote Unity3d | シリーズ講座