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│Comments(2)TrackBack(0) Clip to Evernote Unity3d | シリーズ講座

トラックバックURL

この記事へのコメント

1. Posted by cyah   2012年08月13日 11:48
一応最後まで読んでみましたが、内容をほとんど理解できませんでした。
(グラボが必要程度しか頭に入っていませんね。情けない)
そういえば最近はビデオのエンコードにもGPUを利用するソフトがありますね。
2. Posted by ぶぎょう17   2012年08月13日 13:39
cyahさん>コメントありがとうございます。
えーと 次回からのエディターで編集するところが本番ですので
これは 理解できなくてもいいのです、
エディターで編集するときに ああこういうことかと振り返ることで
学習効果が上がる。。はずw

この記事にコメントする

名前:
URL:
  情報を記憶: 評価: 顔