プログラミング系のネタをまとめていきます。

Unityのシェーダー


Unityは既存のシェーダー言語(Cg/HLSL)を拡張した、独自の言語が用意されています。
ShaderLabという名称っぽい。
fixed function shader固定機能シェーダー
vertex and fragment shader頂点ごとの処理、ピクセルごとの処理
surface shaderライティング、シャドー、マテリアルなどの表現

fixed function shader


固定機能のシェーダーで、マテリアルのパラメータ、ライティング、テクスチャなど、基本的な設定で描画します。

シェーダーチュートリアル1

サンプルコード


以下、ビルトインのVertexLitです。
fixed function shader は、SubShader{}内です。

Shader "VertexLit" {
    Properties {
        _Color ("Main Color", Color) = (1,1,1,0.5)
        _SpecColor ("Spec Color", Color) = (1,1,1,1)
        _Emission ("Emmisive Color", Color) = (0,0,0,0)
        _Shininess ("Shininess", Range (0.01, 1)) = 0.7
        _MainTex ("Base (RGB)", 2D) = "white" { }
    }

    SubShader {
        Pass {
            Material {
                Diffuse [_Color]
                Ambient [_Color]
                Shininess [_Shininess]
                Specular [_SpecColor]
                Emission [_Emission]
            }
            Lighting On
            SeparateSpecular On
            SetTexture [_MainTex] {
                constantColor [_Color]
                Combine texture * primary DOUBLE, texture * constant
            }
        }
    }
} 

Shader

Shader "VertexLit"
ダブルクォートで囲った部分が、インスペクタのShader選択メニューに登録される。

インスペクタのプロパティ


_Color ("Main Color", Color) = (1,1,1,0.5)
_Colorシェーダー内の名称
"Main Color"インスペクタで表示される名称
Colorプロパティの型
(1,1,1,0.5)初期値

数値、スライダー

name ("display name", Range (min, max)) = number	// floatのみ
name ("display name", Float) = number
name ("display name", Int) = number

Color, Vector

name ("display name", Color) = (number,number,number,number)
name ("display name", Vector) = (number,number,number,number)

Rectangle

name ("display name", Rect) = "name" { options }

Texture

name ("display name", 2D) = "defaulttexture" {}
name ("display name", 3D) = "defaulttexture" {}
name ("display name", Cube) = "defaulttexture" {}	// キューブマップ

Combine

Combine ColorPart, AlphaPart
カラー、アルファそれぞれのブレンド計算。
  • texture : テクスチャカラー
  • primary : 頂点カラー。Materialブロックで指定された、ライト計算されたもの。

vertex shader, fragment shader


頂点処理、ピクセル処理を記述するシェーダー。
独自のライト計算を定義したい場合は、surface shaderを使う。

シェーダーチュートリアル2

SubShader


Shader "MyShaderName" {
    Properties {
        // ... properties here ...
    }
    SubShader {
        // ... subshader for graphics hardware A ...
        Pass {
            // ... pass commands ...
        }
        // ... more passes if needed ...
    }
    SubShader {
        // ... subshader for graphics hardware B ...
    }
    // ... Optional fallback ...
    FallBack "VertexLit"
}

それぞれのシェーダー(SubShader)ブロックは、異なるハードウェアに合わせて記述されたシェーダー。
Unityは、実行環境で動作するシェーダー(SubShader)を一つ選んで実行します。
その際、先頭から順に見て、最初に見つかった動作するものが選ばれます。

FallBack "VertexLit"
ターゲットプラットフォームがどのSubShaderもサポートしていない場合に、動作させるシェーダーを指定する。


SubShaderの詳細について

Pass


1つの描画パスを Pass{}で囲う。
vertex, fragment shader はこのPass内に、Cg言語で記述する。

SubShader内に複数の Pass{} を記述できる。

	Pass{
		// ... the usual pass state setup ...

		CGPROGRAM
		
		#pragma vertex vert		// 頂点シェーダーの関数名(この例では vert)
		#pragma fragment frag	// フラグメントシェーダーの関数名(この例では frag)

		// ここに Cg コードを記述

		ENDCG
		
		// ... the rest of pass setup ...
	}

Passの詳細について

また、UsePassコマンドを使うことで、ほかのシェーダーのPassを呼び出せる。
その際、呼び出すPassにはNameコマンドで名前付けしておく必要がある。

UsePassについて
Nameについて

Blending


記述例

SubShader{
	Blend SrcAlpha OneMinusSrcAlpha
	
	Pass{
	}
}

SubShader{
	Pass{
		Blend SrcAlpha OneMinusSrcAlpha
		
		CGPROGRAM
		ENDCG
	}
}


一般的なブレンディング


Blend SrcAlpha OneMinusSrcAlpha // Alpha blending
Blend One One // Additive
Blend OneMinusDstColor One // Soft Additive
Blend DstColor Zero // Multiplicative
Blend DstColor SrcColor // 2x Multiplicative

Cgコード内でプロパティを参照


Shader "Tutorial/Textured Colored" {
	Properties {
	    _Color ("Main Color", Color) = (1,1,1,0.5)
	    _MainTex ("Texture", 2D) = "white" { }
	}
	
	SubShader {
		Pass {
			CGPROGRAM
			
			//---- 略 ----

			float4 _Color;		// プロパティと同じ名前で定義する
			sampler2D _MainTex;	// プロパティと同じ名前で定義する

			//---- 略 ----
			
			half4 frag (v2f i) : COLOR
			{
			    half4 texcol = tex2D (_MainTex, i.uv);	// _MainTexを参照
			    return texcol * _Color;					// _Colorを参照
			}
			
			ENDCG
		}
	}
	Fallback "VertexLit"
}

詳細はこちら

CGPROGRAM〜ENDCG で使用できるpragma

  • #pragma vertex (name) : 頂点シェーダーの関数名を指定
  • #pragma fragment (name) : フラグメントシェーダーの関数名を指定
  • #pragma fragmentoption option : OpenGLのフラグメントオプション。ARB fragment program
  • #pragma target (name) : (name) = default → vertex shader 1.1 pixel shader 2.0 / (name) = 3.0 → vertex shader 3.0 pixel shader 3.0
  • #pragma only_renderers (space separated names) :コンパイルするレンダラーを指定する。(d3d9, opengl, gles, xbox360, ps3, flash)
  • #pragma exclude_renderers (space separated names) :コンパイルしないレンダラーを指定する。(d3d9, opengl, gles, xbox360, ps3, flash)
  • #pragma glsl : プラットフォームがデスクトップの場合、コンパイル時、Cg/HLSL を GLSL に変換する。


Surface Shader


ライト計算を行うシェーダー。

シェーダーチュートリアル3

サーフェイスシェーダーから出力されるデータ構造

struct SurfaceOutput {
    half3 Albedo;
    half3 Normal;
    half3 Emission;
    half Specular;
    half Gloss;
    half Alpha;
};
Albedo:入射した光をどれだけ反射するか、という値。Diffuseとほぼ同じっぽい。

Surface Shaderの指定


#pragma surface surfaceFunction lightModel [optionalparams]
  • surfaceFunction:シェーダー関数名。関数はvoid surfaceFunction(Input IN, inout SurfaceOutput o)という形式。
  • lightModel:ライトモデル。ビルトインの Lambert or BlinnPhong を指定する。(カスタムのライトモデルを作成することも出来るっぽい)
  • optionalparams:以下のオプションを指定できます。
alpha
alphatest
vertex頂点シェーダーを指定
finalcolorピクセルシェーダーを指定
exclude_path
addshadow
dualforward
fullforwardshadows
decal
softvegetation
noambient
novertexlights
nolightmap
nodirlightmap
noforwardadd
approxview
halfsview

入力データ

struct Input で必要なものだけ定義します。
float3viewDir視線方向
float4color(COLORセマンティックを付ける)頂点カラー
float4screenPosスクリーン上の座標
float3worldPosワールド座標
float3worldReflワールドリフレクションベクトル
float3worldNormalワールド法線ベクトル
float3worldRefl
float3worldNormal


Surface Shaderサンプル
いろいろな効果の例があります。
vertex shader, pixel shader との併用例もあります。

UnityCG.cginc


各種構造体、関数などが含まれる、よくお世話になるファイル。
パスは
(Unityインストールフォルダ)/Editor/Data/CGIncludes/UnityCG.cginc

頂点シェーダーに渡される構造体


struct appdata_base {
    float4 vertex : POSITION;
    float3 normal : NORMAL;
    float4 texcoord : TEXCOORD0;
};

struct appdata_tan {
    float4 vertex : POSITION;
    float4 tangent : TANGENT;
    float3 normal : NORMAL;
    float4 texcoord : TEXCOORD0;
};

struct appdata_full {
    float4 vertex : POSITION;
    float4 tangent : TANGENT;
    float3 normal : NORMAL;
    float4 texcoord : TEXCOORD0;
    float4 texcoord1 : TEXCOORD1;
    fixed4 color : COLOR;
#if defined(SHADER_API_XBOX360)
	half4 texcoord2 : TEXCOORD2;
	half4 texcoord3 : TEXCOORD3;
	half4 texcoord4 : TEXCOORD4;
	half4 texcoord5 : TEXCOORD5;
#endif
};

汎用へルパー関数

float3 WorldSpaceViewDir (float4 v)ワールド空間の,特定のオブジェクト空間の頂点位置からカメラに向かった,(正規化されていない)方向。
float3 ObjSpaceViewDir (float4 v)オブジェクト空間の,特定のオブジェクト空間の頂点位置からカメラに向かった,(正規化されていない)方向。
float2 ParallaxOffset (half h, half height, half3 viewDir)視差法線マッピングのUVオフセットを計算。
fixed Luminance (fixed3 c)色を輝度(グレースケール)に変換します
fixed3 DecodeLightmap (fixed4 color)Unityライトマップの色をデコードします(プラットフォームにより,RGBMあるいはdLDR)
float4 EncodeFloatRGBA (float v)精度の低いレンダリングターゲットを格納するため,0〜1の範囲の浮動小数点をRGBAcolorにエンコードします。
float DecodeFloatRGBA (float4 enc)RGBA colorをfloatにデコードします。
float2 EncodeFloatRG (float v)float4 EncodeFloatRGBA (float v) のカラーチャンネル2つ版
float DecodeFloatRG (float2 enc)float DecodeFloatRGBA (float4 enc) のカラーチャンネル2つ版
float2 EncodeViewNormalStereo (float3 n)ビュー空間法線を0〜1の範囲の二つの数字にエンコードします。
float3 DecodeViewNormalStereo (float4 enc4)enc4.xyからビュー空間法線をデコードします。
参考

ビルトイン シェーダ includeファイル
http://docs.unity3d.com/ja/current/Manual/SL-Built...

HLSL組み込み関数

ret floor(x)指定された値以下の最大の整数を返します。
ret saturate(x)指定された値を 0 〜 1 の範囲にクランプします。
ret distance(x, y)2 つのベクトルの間の距離スカラーを返します。

参考

公式サイト:Shader Reference

Tags

Queueタグ


描画順の指定。Rendering Order。

定義済みのQueueについて。
Queue種類説明優先度
Background一番最初に描画されるキュー。スカイボックスなど。1000
Geometryデフォルト2000
AlphaTestαテストを行うオブジェクト2450
Transparentアルファブレンドを行うオブジェクト
デプスバッファに書き込まないものはこれを推奨
3000
Overlayポストエフェクト、UIなど4000

Tags { "Queue" = "Geometry+1" }
という使い方も可能。

RenderTypeタグ


シェーダーを定義済みのグループで分ける。

Camera.RenderWithShader または Camera.SetReplacementShader でシェーダーを置き換えた時、
描画対象は replacementTagが示すもの(RenderyTypeで指定された種類)のものを描画する。

参考サイト

LigtModeタグ


ライティングパイプライン(Rendering Path)によってシェーダーを切り替えるためのタグ。
SubShader内で、LigtModeによって有効なPassブロックを切り替えられる。

詳細はこちら
http://docs.unity3d.com/Documentation/Components/S...


また、ライティングパイプラインは
  • Cameraコンポーネントの Rendering Path
  • PlayerSettings - Other Settings - Rendering Path (PC, Mac & Linux Standalone)
で変更できる。

ハードウェア毎に対応しているライトモードの一覧
http://docs.unity3d.com/Documentation/Components/R...


※ビルトインシェーダーの VertexLit(Normal-VertexLit.shader) で使われているので、そちらを参考に。


同Wiki内記事も参考に。
ライティング
レンダリングパス


PreviewTypeタグ


マテリアルのインスペクタプレビューに、Planeメッシュで表示される。

Unity4.3から追加されている。
https://unity3d.com/jp/node/2737

IgnoreProjectorタグ


"True"が設定されている場合、プロジェクター(Projectors)の効果を受けなくなる。

Projectorについて

公式ドキュメント

ビルトインシェーダー概要


ビルトインで沢山のシェーダーが用意されていますが、それぞれの詳細について簡単に整理してみます。

基本

フルパス効果QueueRenderType
Diffuseライトあり(Lambert)
カラーあり
Opaque
Diffuse DetailDiffuseに加えて、
_MainTexと_Detail(2倍)の掛けあわせ
Opaque
DecalDiffuseの上に_DecalTexを重ねる感じOpaque
Specular_SpecColor, _Shininessで、光の強い反射を指定Opaque
VertexLitDiffuse, Ambient,Shininess
Specular, Emission
(ライトモードによって計算が違う)
Opaque
Bumped DiffuseDiffuse
バンプマッピング
Opaque
Bumped SpecularSpecular
バンプマッピング
Opaque
Parallax DiffuseDiffuse
パララックスマッピング
Opaque
Parallax SpecularSpecular
パララックスマッピング
Opaque

※Specular の場合はライトモデルが BlinnPhong になっている。
#pragma surface surf BlinnPhong

Unlit系


ライティング無し。
ライトマップ無し。
マテリアルカラー無し。
フルパス効果QueueRenderType
Unlit/TextureテクスチャカラーそのままTransparentOpaque
Unlit/Transparentアルファブレンド
ZWrite Off
TransparentTransparent
Unlit/Transparent Cutout_Cutoffより小さいα値のピクセルを破棄するAlphaTestTransparentCutout

グラフィックス技術

パララックスマッピング(視差マッピング)


バンプマッピングの改良版。
法線マップ+高さマップ によって、視点からの距離で凹凸表現を強調する。

http://game.watch.impress.co.jp/docs/20050512/scct...

Menu

メインコンテンツ

機器

Macツール

各種情報

Wiki内検索

おまかせリンク

Androidアプリ

AdSense

技術書


管理人のみ編集できます