Unityな日々(Unity Geek)

Unityで可視化アプリを開発するための試行錯誤の覚書

ShaderLabの基礎:Texture Combinersを理解する

f:id:yasuda0404:20150215211036p:plain

参考:ShaderLab syntax: Texture Combiners

基本的なVertex Lightingが計算された後、テクスチャが適用される。これはSetTexture()コマンドによっておこなわれる。

基本形は、SetTexture テクスチャ名 テクスチャブロックとなる。

※フラグメント・プログラムが有効な場合、SetTextureコマンドは無効になる。すなわち、ピクセル操作はすべてシェーダで行われる。

テクスチャブロックは、テクスチャがどのように適用されるかを指定するもので、combine,constantColor,matrixの3つからなる。

1. combine

テクスチャ同士をどのように合成するかの指定。

  • combine src1 * src2 2つのソースを乗算で合成。いずれよりも暗くなる。

  • combine src1 + src2 加算で合成。どちらよりも明るくなる。

  • combine src1 - src2 ソース1からソース2を減じる。

  • combine src1 +- src2 ソース1とソース2を加算し0.5を引く=符号付でソース2を加える。

  • combine src1 lerp (src2) src3 ソース2のアルファ値を使って、ソース1とソース3を内挿する。アルファ1の時ソース1となり、アルファ0のときソース3となる。

  • combine src1 * src2 + src3 ソース1にソース2のアルファ値を掛け、ソース3を加える。

  • combine src1 * src2 +- src3 ソース1にソース2のアルファ値を掛け、符号付でソース3を加える。

  • combine src1 * src2 - src3 ソース1にソース2のアルファ値を掛け、ソース3を引く。

ソース すべてのソースは次のどれかになる。

  • previous 直前のSetTextureの結果
  • primary ライティング計算結果の色、または、頂点カラー(バインドされている場合)
  • texture TextureNameで指定したテクスチャの色
  • constant ConstantColorで指定した色

モディファイヤ

  • 上の指定のあとにオプションとして、Double(2倍)、Quad(4倍)のキーワードを付加し、明度をあげることができる。
  • lerp以外のソースは、前に1をつけることでカラーは無効になる
  • ソースの後にalphaをつければ、アルファチャンネルのみを取り出す。

2. constantColor

combineコマンドで使われるコンスタントカラーを指定

3. matrix

matrix[マトリクス・プロパティ名] 与えたマトリクスでテクスチャ座標を変換する。

フラグメント・プログラミングができる前の古いグラフィック・カードは、テクスチャをひとつずつ重ね合わせながら色を計算していた。

「純粋な固定関数デバイス」 (OpenGL, OpenGL ES 1.1, Wii) は、各SetTextureの値が0~1に制限されていたが、それ以降 (Direct3D, OpenGL ES 2.0)はその制限がなくなった。これが、SetTextureの値に影響する恐れがある。

カラーとアルファの分離 通常、combineRGBカラーとアルファを同じ方法で合成するが、カラーとアルファを異なった方法で合成することも可能。 次のケースでは、RGBカラーは乗算で、アルファは加算で合成している。

SetTexture [_MainTex] { combine previous * texture, previous + texture }

スペキュラ・ハイライト 通常、プライマリ・カラーは、ディフューズ、アンビエント、スペキュラの合計になる。しかし、SeparateSpecularをOnにした場合は、スペキュラカラーはCombine合成計算の後で別に加えられる。 ビルトイン・頂点シェーダーではこちらの方法がデフォルト。


サンプル

1.アルファブレンディング

Baseテクスチャに、Alpha Blendedテクスチャの色を、Alppha Blendedテクスチャのアルファチャンネル値で合成。 最初の'previous'は、頂点カラーとライティングが適用された状態をさす。これがベースカラーとなる。

Shader "Examples/2 Alpha Blended Textures" {
    Properties {
        _MainTex ("Base (RGB)", 2D) = "white" {}
        _BlendTex ("Alpha Blended (RGBA) ", 2D) = "white" {}
    }
    SubShader {
        Pass {
            // Apply base texture
            SetTexture [_MainTex] {
                combine texture
            }
            // Blend in the alpha texture using the lerp operator
            SetTexture [_BlendTex] {
                combine texture lerp (texture) previous
            }
        }
    }
}


2.アルファ制御セルフ・イルミネーション

_MainTexのアルファ値でどこにライトを適用するかを決定する。 第1段階で、頂点カラーと白色を_MainTexのアルファ値で合成。 第2段階で、第1段階の結果に_MainTexのカラーを乗算。 ※アルファがすべて1であれば、_MainTexのカラーそのものになる。アルファが1より小さい部部分は色が弱くなる。

Shader "Examples/Self-Illumination" {
    Properties {
        _MainTex ("Base (RGB) Self-Illumination (A)", 2D) = "white" {}
    }
    SubShader {
        Pass {
            // Set up basic white vertex lighting
            Material {
                Diffuse (1,1,1,1)
                Ambient (1,1,1,1)
            }
            Lighting On

            // Use texture alpha to blend up to white (= full illumination)
            SetTexture [_MainTex] {
                constantColor (1,1,1,1)
                combine constant lerp(texture) previous
            }
            // Multiply in texture
            SetTexture [_MainTex] {
                combine previous * texture
            }
        }
    }
}


_MainTexのアルファ値を使って、_IlluminCol(=constant)previousを合成、それに_MainTexの色を乗算。イルミネーションを白色ではなく、任意のカラーに設定するもの。

Shader "Examples/Self-Illumination 2" {
    Properties {
        _IlluminCol ("Self-Illumination color (RGB)", Color) = (1,1,1,1)
        _MainTex ("Base (RGB) Self-Illumination (A)", 2D) = "white" {}
    }
    SubShader {
        Pass {
            // Set up basic white vertex lighting
            Material {
                Diffuse (1,1,1,1)
                Ambient (1,1,1,1)
            }
            Lighting On

            // Use texture alpha to blend up to white (= full illumination)
            SetTexture [_MainTex] {
                // Pull the color property into this blender
                constantColor [_IlluminCol]
                // And use the texture's alpha to blend between it and
                // vertex color
                combine constant lerp(texture) previous
            }
            // Multiply in texture
            SetTexture [_MainTex] {
                combine previous * texture
            }
        }
    }
}


すべてのLightを適用したもの。 最初のpreviousは、Diffuse,Ambient, Shiness, Specular, Emissionが適用された状態になる。そこに、_IlluminCol_MainTexのアルファ値で合成し、さらに_MainTexのカラーを乗算する。

Shader "Examples/Self-Illumination 3" {
    Properties {
        _IlluminCol ("Self-Illumination color (RGB)", Color) = (1,1,1,1)
        _Color ("Main Color", Color) = (1,1,1,0)
        _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 {
            // Set up basic vertex lighting
            Material {
                Diffuse [_Color]
                Ambient [_Color]
                Shininess [_Shininess]
                Specular [_SpecColor]
                Emission [_Emission]
            }
            Lighting On

            // Use texture alpha to blend up to white (= full illumination)
            SetTexture [_MainTex] {
                constantColor [_IlluminCol]
                combine constant lerp(texture) previous
            }
            // Multiply in texture
            SetTexture [_MainTex] {
                combine previous * texture
            }
        }
    }
}