Yaminabe

らくがきぶろぐ

Yaminabe:10/637
てすと:Yaminabeちゃんは生まれたばかりのブログです みんなで仲よく使ってね

※170607 補足記事をアップしました うにばな スクリーンスペース系のシェーダに関するTips

 

 

今回は”エフェクト用のシェーダに関するアイデア”の補足でGrabTextureを使用する場合のパーティクルのカラー合成をしてみます。

GrabTextureは背景からテクスチャにキャプチャした画像をカラー合成の対象にできる命令で スクリーンサイズのスナップショットをテクスチャに展開します。

GrabTexture命令で 取り込んだテクスチャにシェーダでモデルのカラーを合成をしてやれば ”エフェクト用のシェーダに関するアイデア”で使用したシェーダと同じような効果がねらえます。カラーを合成する式は

これも以前掲載した フォトショップの合成式を使用することが出来るため フォトショップ上の見た目と同等の表現が期待出来て デザイナーにとっては非常にありがたい機能です。 ただしGrabTexture命令は処理負荷が高く現在のモバイルやスマホで動作させるには重ためなので気をつけてください。

 

【fig1】

grabtest

 

 

今回作成したサンプルシェーダコードは以下の通りです

■ 『BlendTest(GrabTex) . shader" 』

Shader "Custom/Particles/BlendTest(GrabTex)" {

    Properties {

        _TintColor ( "Tint Color", Color ) = ( 0.5, 0.5, 0.5, 0.5 )
        _MainTex ( "Particle Texture", 2D ) = "white" {}
  
    }

    Category {

        Tags { "Queue"="Transparent" "RenderType"="Opaque" }
       
          Blend One OneMinusSrcAlpha
         Alphatest Greater 0.1
         ZWrite On
        
        SubShader {

            GrabPass { 
                                                 
                Name "BASE"
                Tags { "LightMode" = "Always" }
  
            }


            Pass {
                Name "BASE"
                Tags { "LightMode" = "Always" }

                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag
                #pragma multi_compile_particles
                #include "UnityCG.cginc"
                #pragma target 3.0

                struct appdata_t {
                    float4 vertex : POSITION;
                    float2 texcoord: TEXCOORD0;
                };

                struct v2f {
                    float4 vertex : POSITION;
                    float4 uvgrab : TEXCOORD0;     
                    float2 uvmain : TEXCOORD2;
                };
   
                sampler2D _GrabTexture;
                float4 _GrabTexture_TexelSize;

                sampler2D _MainTex;
                float4 _MainTex_ST;
               
                fixed4 _TintColor;
              

                v2f vert ( appdata_t v ) {

                    v2f o;

                    o.vertex = mul( UNITY_MATRIX_MVP, v.vertex );
                    #if UNITY_UV_STARTS_AT_TOP
                    float scale = -1.0;
                    #else
                    float scale = 1.0;
                    #endif
                    o.uvgrab.xy = ( float2( o.vertex.x, ( o.vertex.y * scale ) ) + o.vertex.w ) * 0.5;
                    o.uvgrab.zw = o.vertex.zw;           
                    o.uvmain = TRANSFORM_TEX( v.texcoord, _MainTex );

                    return o;

                }


                half4 frag( v2f i ) : COLOR {
            
                   half4 col = tex2Dproj( _GrabTexture, UNITY_PROJ_COORD( i.uvgrab ) );
                   
                   col.a = 0;
                 
                   half4 base = tex2D( _MainTex, i.uvmain);      
                  // このようなブレンド式を使用してもよいです
                 //  return float4( (base.rgb < 0.5 ? (2.0 * base.rgb * col.rgb) : (1.0 - 2.0 * (1.0 - base.rgb) * (1.0 - col).rgb)).rgb , base.a);

                    return float4(base.rgb + _TintColor * pow(base.rgb,2.0 )* col.rgb , base.a);
            

                }
                ENDCG
            }
           
          
        }

    }

}

 

■ GrabTextureの取得は GrabPassをk術するだけです samplerの指定とセットなので記述漏れしないようにしてください

GrabPass
                                                 
                Name "BASE"
                Tags { "LightMode" = "Always" }
  
            }

・・・・・・・・・・・・・・・・・・・・・・・

sampler2D _GrabTexture;

・・・・・・・・・・・・・・・・・・・・・・・

o.uvgrab.xy = ( float2( o.vertex.x, ( o.vertex.y * scale ) ) + o.vertex.w ) * 0.5;
o.uvgrab.zw = o.vertex.zw;
      

 

half4 col = tex2Dproj( _GrabTexture, UNITY_PROJ_COORD( i.uvgrab ) );

Unityのマクロ関数 UNITY_PROJ_COORD にワールド頂点座標を与えることによってカメラのプロジェクション方向から見たスクリーン座標のUV値に変換されます。

Tags { "Queue"="Transparent" "RenderType"="Opaque" } タグはレンダーキュー(Queue)に透明(Transparent)が指定してあればアルファを考慮したソートが行われるため RenderTypeは無視しても構いません。

■Blend One OneMinusSrcAlpha は <背景 1 :前景 1-alpha値> で合成を指定します。アルファ抜きの場合はこれを使用。

ZWriteをOnにするのを忘れないように depthバッファの書き込みが行われないと正確なソートが行われません。

Alphatest Greater 0.1 はしきい値(例の場合0.1)を境界にして透明部分の抜け具合を決定します。


Blend One OneMinusSrcAlpha
        Alphatest Greater 0.1
         ZWrite On


 

■ライブラリの種類によっては取り込んだテクスチャのUV座標のV方向(スクリーン座標のY軸方向)が上下逆になることがあるので

UNITY_UV_STARTS_AT_TOP の変数を監視してテクスチャUVのV方向に−1を掛けてフリップする必要があります


#if UNITY_UV_STARTS_AT_TOP
                    float scale = -1.0;
                    #else
                    float scale = 1.0;
                    #endif

 

■カラー合成式に関してはどのような書き方してももちろん構いません 見た目でより良い結果になるようにしてください。

 

フォトショップのブレンド式 を使用する場合   

return float4( ( base.rgb < 0.5 ? (2.0 * base.rgb * col.rgb) : (1.0 - 2.0 * (1.0 - base.rgb) * (1.0 - col.rgb).rgb)).rgb , base.a );
              

● 加算と乗算を組み合わせる場合

return float4( base.rgb + _TintColor * pow(base.rgb,2.0 )* col.rgb , base.a );

テクスチャはアルファ抜きしたものを使用しますが、 カラーの明度からアルファマスクを計算して取得することも出来ます

【Example】

float alpha =Luminance(color.rgb) ;

たとえばUnityのマクロ関数Luminanceを使用します RGB値カラーを輝度値 に変換する関数で "UnityCG.cginc"ファイルに記述されています

Luminance( ) の代入はfloat3型ですので float4型のカラーを渡すときは 「color.rgb」というようにSwizzleで記述します。

inline fixed Luminance( fixed3 c )
{
    return dot( c, fixed3(0.22, 0.707, 0.071) );
}

 


【追記】

リファレンスには下のように GrabPassにオプションパラメータとしてテクスチャのスケールが指定できると書いてありますが コンパイルが通ったことがありません Unity公式フォーラムでもバグ扱いされていてだれも使い方をわかってないようなんですが、どうやって使用するんでしょう? ご存じの方がいればコメント頂きたいのです。

GrabPass {

    TextureScale 0.5 

   TextureSize 256

    BorderScale 0.3

// following are regular pass commands

    Tags { "LightMode" = "VertexLit" }

    Name "BASE"

}

 

今回は以上です 次回はなるべくはために更新するつもりですが 少しレベルを上げるかもしれませんので頑張って読解してみてください。

質問がある方はコメント欄にどうぞ

 

それではまた

 

 

drawMeshTest

■webプレイヤー

https://dl.dropboxusercontent.com/u/18978109/DrawMeshTest/DrawMeshTest.html

 

Unity公式のフォーラムで大量のメッシュを描画する方法として有効だというはなしのGraphics.DrawMesh命令を簡単に解説します

Unityの新しいバージョンでプロパティブロックまわりが改良されたそうなので プロパティブロックを使用してサンプルを作成してみました

< どこが新規に変わったのかいまいちわからないのですが >

 

ちなみに情報としては古めなので すでにほかのところに詳しい記事があるかもしれませんが、ここの管理人は怠けものなので国内の記事はあまり見ていません。







■Graphics.DrawMesh

● static function DrawMesh(mesh: Mesh, position: Vector3, rotation: Quaternion, material: Material, layer: int, camera: Camera = null, submeshIndex: int = 0, properties: MaterialPropertyBlock = null): void;

● static function DrawMesh(mesh: Mesh, matrix: Matrix4x4, material: Material, layer: int, camera: Camera = null, submeshIndex: int = 0, properties: MaterialPropertyBlock = null): void;

 

【パラメータ】

mesh描画するメッシュデータ

positionメッシュの位置。

rotation      メッシュの回転。

matrixメッシュの変換行列(位置、回転、その他の変換)。

materialマテリアルを指定する。

layerレイヤを使用する。

camera    :デフォルトはNULL。メッシュはすべてのカメラで描画されますが 指定がある場合指定されたカメラでレンダリングします。

submeshIndex描画するメッシュのどのサブセット。これは、複数の材料で構成されたメッシュに適用される。

propertiesメッシュが描画される直前にマテリアルにプロパティ変更を適用します。※MaterialPropertyBlock

 

DrawMesh命令は1フレームごとにメッシュを描画します。通常のゲームオブジェクトと同様にシェーディングされ影が落ちてプロジェクターの影響を受けることができます。デフォルト状態ではすべてのカメラにレンダリングされますが特定のカメラを指定することもできます。

ゲームオブジェクトの作成と管理のオーバーヘッドを避けて大量のメッシュを描画したい場合DrawMesh命令は有効に機能します。DrawMeshはすぐにメッシュを描画せず Updateの後にレンダリングパイプラインにデータを送り、そのあと通常のレンダリングプロセスの一部としてレンダリングされます。 すぐにメッシュを描画したい場合は、Graphics.DrawMeshNowを使用します。

DrawMeshはすぐにメッシュの描画がされないため、関数の呼び出しの時に材料特性を変更すると、メッシュはそれらをピックアップすることはありません。あなたは、同じマテリアルを用いてメッシュのシリーズを描きたいのですが、すこしだけマテリアルのプロパティ(例えば色を変更)をする場合は、MaterialPropertyBlockのパラメータを使用します。

 





■MaterialPropertyBlock

MaterialPropertyBlockGraphics.DrawMeshによって使用されているRenderer.SetPropertyBlockです。、同じマテリアルで複数のオブジェクトを描画するような場合、たとえばメッシュの色を変更したい場合シェーダ内のプロパティの値を部分的に変更することで対応します。

 

【機能】

AddColor            : カラープロパティを追加します。

AddFloat             :フロート型プロパティを追加します。

AddMatrix         : マトリックス型プロパティを追加します。

AddTexture       :テクスチャ型プロパティを追加します。

AddVector         :ベクター型プロパティを追加します。

Clear                  : プロパティ値のクリア。

GetFloat             : プロパティブロックからフロートを取得します。

GetMatrix          : プロパティブロックから行列を取得します。

GetTexture        : プロパティブロックからテクスチャを取得します。

GetVector          : プロパティブロックからベクトルを取得します。

 

 

【Example】

public class  XXXXX : MonoBehaviour
{

     private MaterialPropertyBlock _PropertyBlock; 
     private int _ColorPropertyId ;

 

void Start()
{

               _PropertyBlock    = new MaterialPropertyBlock();
               _ColorPropertyId = Shader.PropertyToID("_Color");

}

void Update() 
{

               _PropertyBlock.Clear(); 
               _PropertyBlock.AddColor(_ColorPropertyId, Color.white);    
            
  Graphics.DrawMesh( Mesh, Position , Rotation, Material, 0, MainCamera, 0,_PropertyBlock);

  }

}

 

PropertyBlock を効率よく使用するためには1つのブロックを作成してDrawMeshをコールするたびにブロックを再利用する方法です。

Graphics.DrawMesh()の前に使用ブロックをクリアし AddXXX を使用して値を追加します。

指定できるプロパティは使用しているシェーダ内で登録されているプロパティとなります。 複数のシェーダを使用する場合はShader.Find(シェーダ名)で書き換え対象のシェーダを指定する必要があります。

 

 

●DrawMeshManager.cs

using System.Collections.Generic;
using UnityEngine;
using Assets;

public class DrawMeshManager : MonoBehaviour
{
   
    public Mesh ObjMesh;
    public Material Material1;
   
    public Camera MainCamera;
    public Transform Player;
    public float ForceDrawWithinDistance = 50.0f;
   
    public int Maxval = 100;
    public float  Scaler = 2.0f;   
   
    private List Objs = new List();
   
    private MaterialPropertyBlock _PropertyBlock;
    private int _ColorPropertyId ;
   
   
    private void Start()
    {
       
        MainCamera = Camera.main;                
        float Offset=(Maxval*Scaler/2.0f)-Maxval*Scaler;
        int ObjectType = 0;
       
        for(var x=0 ; x        {                
            ObjectType = x%2;          
            for(var y=0 ; y            {                   
                for(var z=0 ; z                {    
                                                                
                    ObjData newObj = new ObjData( ObjectType,
                                            new Vector3((float)x*Scaler+Offset,(float)y*Scaler+Offset,(float)z*Scaler+Offset),
                                            Quaternion.Euler(0, 0 ,0));

                    Objs.Add(newObj);                                       
        
                }
           }
           
        }
       
        _PropertyBlock = new MaterialPropertyBlock();
        _ColorPropertyId = Shader.PropertyToID("_Color");       
        
    }

   
    private void Update()
    {
       

        Vector3 playerPosition = Player.position;
        var FrustumPlanes = GeometryUtility.CalculateFrustumPlanes(MainCamera);

        
        float _timer = Time.timeSinceLevelLoad;               
        var ObjBounds = ObjMesh.bounds;
       
        foreach (var Obj in Objs)
        {
                        
        //    int ObjType   = Obj.ObjType; // メッシュオブジェクトを複数定義する場合に使用する
            
                ObjBounds.center = Obj.WorldPosition;

       
            float distance = Vector3.Distance(Obj.WorldPosition, playerPosition);

       
            if (distance < ForceDrawWithinDistance || GeometryUtility.TestPlanesAABB(FrustumPlanes, ObjBounds))
            {
                   
                float ofst = Mathf.Sin((Obj.WorldPosition.y + _timer)/4.0f)*1.5f;
                                
                _PropertyBlock.Clear();
                _PropertyBlock.AddColor(_ColorPropertyId, Obj.Color);   
                Graphics.DrawMesh(ObjMesh, Obj.WorldPosition + new Vector3(ofst,0,ofst) , Obj.Rotation, Material1, 0, MainCamera, 0,_PropertyBlock);
                                          
                    
            }
        }
    }
}

●ObjData.cs 【構造体クラス】

using System;
using UnityEngine;


namespace Assets
{
    public class ObjData
    {
        private  int _ObjType;
        private  Vector3 _WorldPosition;
        private  Quaternion _Rotation;
        private  Color _Color;
       

        public ObjData(int ObjType, Vector3 worldPosition, Quaternion rotation)
        {
            _ObjType = ObjType;
            _WorldPosition = worldPosition;
            _Rotation = rotation;
           
            if (ObjType == 0)
            {
               
                _Color = Color.white;
               
            }
            else
            {

               _Color = new Color(1.0f,0.2f,0.05f);
               
            }      
            
        }

        public Vector3 WorldPosition
        {
            get { return _WorldPosition; }
        }
        public Quaternion Rotation
        {
            get { return _Rotation; }
        }
        public int ObjType
        {
            get { return _ObjType; }
        }       
        public Color Color
        {
            get { return _Color; }
        }
       
    }
}

いままでは配列で管理して結合した後GPUに転送という方法が知られていましたが それにに比べると メモリ消費も少なくて なにより頭を悩ませることがないのがいいですね。

画像のStatisticsで表示されるDrawCall数は3000を越えていますが FPS値はふつうに高いままなので Unityの中身はわからないので想像ですが、おそらくCPU側でGraphics.Draw関数をコールした回数だと思われます。VRAMへの描画は1フレームで行われているらしいです。

左のGUIのFPS表示はエディタから実行した数値です。 PCの環境にもよりますがwebプレイヤーでは60フレーム程度はでていると思います。

Unityのツリーシステムなどでは メモリ使用量はモデルの頂点数分の合計となるためかなり大きめな数値となっています おそらくは内部でメッシュをマージして転送する方法を行っているのだと思いますが、今回のDrawMesh関数を使用するサンプルはアップデート内部でシェーダにモデル1つ分のデータを送るだけなのでGPU側のメモリはほとんど消費されていません

それからスキンモデルにもDrawMwshを使用してみたいところなのですが現時点ではスキンウェイトのモデルはダイナミックバッチがかからない仕様になっているそうなのです

スキニングのフィルターがブラックボックスなので調べてみないとわかりませんが、アニメーションするキャラクターを大量に配置したい場合はスキンウェイト用のシェーダを自作する必要があるかもしれません。

 

 

こんばんは 予告通り 「三つ目時 」=テレビ東京標準時の木曜夜7時半の更新です。

だれもわからないだろうけどw

 

今回はノーマル法線とノーマルマップの合成に関してのはなしです。

 

sample_1sample_2

sample_3image022

●たっきゅんのガ☆チンコ開発日記 http://takkun.nyamuuuu.net/blog2/archives/1627

● ISO-IEC 18026 - Clause 8, Spatial reference frames

のほうから画像だけお借りしました 不都合があればお申し出ください

--------------------------------------------------------------------------------------------------------------------------------------------------------

 

ノーマルマップはオブジェクトの法線ベクトルをテクスチャ画像のカラー値に置き換えたものです。

接空間 (Tangent Space) ポリゴン面の法線に対して垂直に接する面の座標空間です。グーローシェーディングがかかっている場合はポリゴン面上の法線はポリゴンを構成する頂点の法線がグラデーションで補完された値になります。

図のようにノーマル法線方向をZ軸 ポリゴンのUV空間 U方向をX軸 V方向をY軸と見立てます。

ノーマルマップは X軸成分をRカラー値、Y軸成分をGカラー値に置き換えて ポリゴン上のポイントではテクスチャのRカラー値によって法線はTangent方向へ傾くように計算され Gカラー値によってBinormal方向に傾くように計算されます。 それによってポイントあたりの法線方向が歪められてライト計算に反映されると凹凸が表現できるという仕組みです。

テクスチャカラーのRGB成分は整数値の0~255または0~1で定義されていますので 0.5を中心としてそれより小さければマイナスの値 大きければプラスの値とみなして扱います。

 

Unityのシェーダで接空間 (Tangent Space)データを使用する場合はシェーダー入力の構造体にappdata_tanを指定します。 これで取得できるのはモデルのAssetデータの変換時に計算されたタンジェント値です。

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

もちろんappdata_fullですべてのデータを取得しても構いませんがデータはなるべく使用するものだけにしたほうが軽量化出来ますので そこら辺はケースバイケースで判断してください。

binormalは以下の式で計算出来ます。

float3 binormal = cross( IN.normal, IN.tangent.xyz ) * IN.tangent.w;

あまりにざっくりなので解説しますと 2つのベクトルに対して外積(cross)をとることで直行するベクトルを算出することができます。(INはシェーダinput構造体を表します)

上の式ではnormalとtangentをcross(外積)とることでbinomal(副法線)を算出しています。ベクトルのw成分は

vector(ベクトルの方向(x,y,z)、ベクトルの大きさw)で定義されるベクトルの大きさ成分wをかけています。

cross(外積)を用いた2つのベクトルに直行するベクトルを求める式は たとえばポリゴンを自前で生成した時に

法線を求める用途などにも使われます。 あとポリゴン面の表裏判定などですかね。

 

これが法線計算の基本ですが これを理解していると例えば 波のようにポリゴンをうねらせたりといったモデルを

変形させた時にシェーダー内部でノーマルを計算させたり 自前でポリゴン生成をするときに法線の計算をしたりという応用ができます。

 

●TANGENTの計算式

float3 tangent;

float3 c1 = cross(Normal, float3(0.0, 0.0, 1.0));
float3 c2 = cross(Normal, float3(0.0, 1.0, 0.0));

if (length(c1)>length(c2))
{
    tangent = c1;
}
else
{
    tangent = c2;
}

tangent = normalize(tangent);

●BINORMALの計算式

float3 binormal;

binormal = cross(Normal, tangent);
binormal = normalize(binormal);

 

補足>ノーマルベクトルをタンジェント空間に投影するコードが以下のようになっています ノーマルを再計算させたい時に参考にしてみてください

ノーマルベクトルとポリゴンのタンジェント空間座標(UVZ)の内積をとって角度変換し0~1の範囲に丸めているだけです。


float3 normalTS;

normalTS.x = dot(normal, Input.binormal);
normalTS.y = dot(normal, Input.tangent);
normalTS.z = dot(normal, Input.normal);

normalTS = normalize(normalTS);

return float4(normalTS * 0.5 + 0.5, 1);

 

< ここまでが基本の解説でした>

 

NormalMap - Polycount Wiki     http://wiki.polycount.com/NormalMap#TSNM

これを読めば大丈夫じゃないかというのが PolyCount Wiki のノーマルマップの解説です 英語ですけど解説図が多いのでほぼ眺めるだけでも内容は理解できると思います。

このサイトを紹介すればよかっただけのような気もしますね・・・

 

 

 ■今回のお題 ノーマルマップの合成で質感のクオリティアップを図ります。      

 

●メリットとしては

モデル全体を覆うノーマルマップとデティール用のノーマルマップそれぞれが あまり大きなテクスチャを使用しなくてもモデルのデティールアップが図れることが挙げられます。たとえば壁などで細かい質感を出すために高解像度テクスチャを使用しなくてもわりとラフなテクスチャでも十分見栄えのする質感表現が可能になります。

ノーマルマップ自体は多少重た目なのですが、シェーダ内でLOD命令を使用してカメラからの距離に応じてシェーダの式を切り替えることで軽量化できるかと思います。 ビルドインシェーダーのウォーターシェーダ を参考にしてみてください。

 

 

■オーバーレイを使用する合成の例
オーバーレイの式を利用したノーマルマップの合成ですがオーバーレイはカラーの数値が
0.5を境に合成式を変化させます。 以前パーティクルのアイデア1で加算と乗算を重ねあわせましたが 
それとほぼ同じです。たとえば背景に対してブレンド式を適用すればカラー部分を強調したままの
加算が再現できます。
 

 BlendOverlayf(base, blend)     (base < 0.5 ? (2.0 * base * blend) : (1.0 - 2.0 * (1.0 - base) * (1.0 - blend)))

   
      float4 norm   = tex2D(_BumpMap, IN.uv_BumpMap);
      float4 norm2 = tex2D(_BumpMap2, IN.uv_BumpMap2);
      dest = norm2<0.5 ? 2*norm*norm2 : 1-2*(1-norm)*(1-norm2);
      dest = lerp(norm2, dest, _Opacity);
      o.Normal = UnpackNormal(dest);

 

例) フォトショップのオーバーレイモードを使用してノーマルマップを調整することができます

normalmapfilter

NVIDIA のフォトショップ用ノーマルマップフィルタでノーマルマップを生成した場合すこし薄めのノーマルマップが仕上がると思います。 この場合フォトショップでレイヤーを使用してノーマルマップの深さをコントロールすることが出来て

下図のようにオーバーレイモードで同じノーマルマップをレイヤーに複製して重ねます。レイヤーのオペーシティ(濃度)をコントロールしてノーマルの深さをコントロールします。

もちろん部分的にレイヤー切り貼りで重ねれば すこしコントラストを強めたい部分だけに作用します。

overlay

 

■ノーマライズを使用する合成の例   

図はUDK(アンリアルエディターのシェーダーツリー)のノーマルマップをブレンドするサンプルです

NormBlend1

内容は2つのマップのノーマル成分を加算してノーマライズするだけという単純なものですが オーバーレイ計算の式では条件判定に三項演算子を使用していました 以前解説したようにシェーダーはif条件式が苦手なのでできれば避けたいところです。ノーマライズ版のほうが多少軽めかもしれません。ただノーマライズもそんなに軽い関数ではないので状況によって実装して比べてみるしか無いですかね。

 
   
float4 norm   = tex2D(_BumpMap, IN.uv_BumpMap);
     float4 norm2 = tex2D(_BumpMap2, IN.uv_BumpMap2);
                o.Normal  = normalize(float3(norm.xy + norm2 .xy, norm.z));

 

補足> normalize, dot, inversesqrt などのオペレータはUnityが最適なコードに変換するので自作のものを使用しないこと。 pow, exp, log, cos, sin, tan などの計算関数は非常に重たいのでなるべくテクスチャ参照(例えばカラーカーブをテクスチャで用意したもの)などを利用することがあげられています。

●    Unity - Optimizing Graphics Performance

 

その他の方法については以下のリンクに詳しい情報が掲載されていますので参照してみてください

Blending in Detail - Self Shadow http://blog.selfshadow.com/publications/blending-in-detail/

 

シェーダを実装した画像

DetailMap 

 

■ 『 Diffuse Detail Bump.shader 』

Shader "custom/Diffuse Detail Bump"{

Properties {

_Color ("Main Color", Color) = (1,1,1,1)
_MainTex ("Base (RGB)", 2D) = "white" {}
_DetailMap ("Detail (RGB)", 2D) = "gray" {}
_BumpMap ("Normalmap", 2D) = "bump" {}
_DetailBumpMap ("Normalmap(Detail)", 2D) = "bump" {}
_DetailScale("DetailScale", Range (0.01, 1)) = 0.4

}

SubShader {

Tags { "RenderType"="Opaque" }
LOD 250

CGPROGRAM

#pragma surface surf Lambert

#include “UnityCG.cginc”

sampler2D _MainTex;
sampler2D _DetailMap;
sampler2D _BumpMap;
sampler2D _DetailBumpMap;
fixed4 _Color;
half _DetailScale;



 struct Input { float2 uv_MainTex;
float2 uv_DetailMap;
float2 uv_DetailBumpMap;
                       };

void surf (Input IN, inout SurfaceOutput o)
{
// デティールマップ(カラー)をテクスチャカラーと合成する
fixed4  c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
            c.rgb *= tex2D(_DetailMap,IN.uv_DetailMap).rgb*2;

// 2つのノーマルマップから法線ベクトルをフェッチして合成する
fixed4 Normal1 = tex2D(_BumpMap, IN.uv_MainTex);
fixed4 Normal2 = tex2D( _DetailBumpMap ,IN.uv_DetailBumpMap) * float4 (_DetailScale,_DetailScale,0,0);

//アウトプットノーマルに法線ベクトルをセットする
            o.Normal = UnpackNormal (Normal1+Normal2);

// アウトプットカラーをセットする
            o.Albedo = c.rgb; 
            o.Alpha   = c.a;
}
ENDCG
}
Fallback "Diffuse"
}


 fixed4   Normal2 = tex2D( _DetailBumpMap ,IN.uv_DetailBumpMap) * float4 (_DetailScale,_DetailScale,0,0);

画像の例ではこの式の部分を以下の例のように書き換えてあります

例)

#include “UnityCG.cginc”

float4 _DetailBumpMap_ST;

……………….

float2    UVCoord = IN.uv_MainTex * _DetailBumpMap_ST.xy

             Normal2 = tex2D( _DetailBumpMap , UVCoord) * float4 (_DetailScale,_DetailScale,0,0);

 

UVがメインテクスチャと同じものを使用する場合はテクスチャスロットのoffsetの数値を使用してこのように
記述します。 
”テクスチャ名+_ST”のUnityマクロの使用法は以前の”パーティクルのアイデア2”の記事を参照してください。 
 

Tips>

ノーマルマップは基本的にRとGのチャンネルしか使用しないためBやAlphaチャンネルは空いた状態ですので、テクスチャの枚数を圧縮したい場合はこの空きチャンネルを利用することが出来ます。 一般にはAO(アンビエントオクルージョンマップ)やマスクテクスチャなどをいれるようです。 スマホなどのテクスチャ枚数が処理速度に影響が出やすいものはなるべくあいているチャンネルを利用してテクスチャ枚数を減らすことでメモリ効率がよくなります。

 

 

記事が長くなりすぎましたので ノーマルマップ生成方法やツールの使用法などの解説はまた後日にします。 

その気になれば10年後も可能とい(ry

もうすこし内容をつめようと思ってたんですけどねー すこし中途半端な感じになってしまいました次回への課題にします。

 

ではまた

 

やみなべ 夜の部はっじまるよー

 

前回の続き

 

今日は朝から

「屋上へ行こうぜ…久しぶりに…キレちまったよ…」 を発声して

セルフトレーニングを繰り返していましたが 今日は何も言ってこなかった(´・ω・`)?

スケジュールあけてたのに時間が余っちゃったから この記事を書いてます


そいえば うちに屋上なかったな


今晩は適当にニュースをみつくろってみました






■都知事がなんとなくIPSのあの人に似ている件 (特に顔らへん

デーブ・スペクター (@dave_spector)
都知事生命の危機→残念ながら五輪終です

あー安定してるなー この人ほんとは日本人でしょ

 

疑惑の金の使途に関する発言が2転3転している都知事ですが 個人献金でも政治資金でもどっちもアウトなんですけど どうするんでしょうか? そういえば徳洲会代表の目立つネクタイは気道を通す手術でのどに穴を開けたのを隠しているのでは? だそうです。

つぎはカジノ方面に捜査が向かうのではという噂ですが、さてどうなるんでしょうね。

 

 

■ 嶋大輔お兄さんが (´;ω;`)ウッ…

銭トラブルから以前の所属事務所に訴えられ自宅差し押さえの危機にあると週刊誌で報じ
られた元タレントの嶋大輔氏(49)が、スポニチ本誌の取材に応じ、係争中であることを
認めた上で、返済の意思などについては「(代理人の)弁護士にお任せしていますので、お
話しすることはできないんです」とコメントした。

中略)

「私はもう芸能界から引退しているので…」という嶋氏。芸能界復帰については「ありま
せん」と、きっぱり答えた。

http://www.sponichi.co.jp/entertainment/news/2013/11/19/kiji/K20131119007041190.html

 

久しぶりにみた嶋大輔お兄さんは こんなことになっていました

ImageStream

すっごい太い(こなみかん)

わたし 特撮関係はアニメより専門なわけですが、戦隊系で子供たちのヒーロだった嶋大輔お兄さんが大変なことになっているようです

ライブマンではリーダー のレッドファルコン役 頭が悪そうだけど頭がいい博士という難しい役どころを自然にこなす 演技派俳優の一面も持つタレントさんでしたね

芸能界引退でのぞんだ前回の選挙でしたが まさかの自民党公認取り消しでした

石破茂幹事長との面接があったそうですが 何言ったんでしょう「自分 原発とか反対なんで」みたいなことかな

石破さんは東電株主で娘は東電勤務だもん まさかねー (*´・д・)(・д・`*)ネー

内定を一本に絞ってほかを全部蹴ったら 内定取り消しになったでござる的な絶望の状況

芸能界 政界 に居場所がなくなってしまいましたが スタイルを活かして つぎは

角界(おすもうさん)とかどうでしょうか?

つっぱることが勲章の世界ですし!」

ってなんか大喜利みたいになってるんですけど

 

 

 

■ 疑惑のライセンス 食品偽装問題

 

『クレアおばさんのシチュー』 はクレアおばさんが作っていません 誤表記です

 

『かっぱ寿司』はかっぱが握っていません 誤表記です

※『かっぱ寿司』は基本 魚のネタが回っていなので、ほぼかっぱだけ寿司と捉えるとあながち間違っているとも言えません。 検証が必要なようです

 

『るみばあちゃんのさぬきうどん』 は全国展開中 るみばあちゃんは働き過ぎです

そういえば『伯方の塩』 がメキシコ産ということもトリビアの泉で明らかにされました

 

『魔法少女まど★カレー』『プリキュアカレー』「提督のカレー」

ちょっとお店で買うのが恥ずかしい「まゆしぃのトウットゥルー ビーフカレー」

 

352d1ed25e2d2bb4e6463b2904a01dd326cb0f30a272b7b4e00818405c711dd0uF4JTTN

2-201306111840resize_image (2)

 

プリキュアが作ってないし入ってないだろうから これは誤表記といえるのではないでしょうか ですが

メーカー:「誤表記ではありません われわれの業界ではご褒美です」

客:「あっ(察し)」

といった展開が予想されます 今回は観察対象に置くことにいたしましょう

 

カレーってゅうのゎ。

たべると9割以上が う●こになる。。。

そしてう●こも、9割以上がう●こ。。。

そぅ。。これゎもぅ。。。

カレー≒う●こってゅうコト。。。

毎日ぅまれる一億のう●こ。。。

もぅマヂ無理。。。

福神漬たべょ。。。。

 

すいません管理人は頭がオカシイのでご勘弁を・・

PK2013110202100059_size0

おふくろの味とかいいがかりだよね 男のコックが作ったらイカンのか?

おふくろ風ならいいってことかな? じゃああそこで採れた農産物とか国産風にしなきゃだめじゃん

まさに風評被害 そして伝説の呂布

 

 

偽装の専門家のご意見】

高須:どうしてあんなことに目くじらを立てるかねえ。医者の立場からすると、おいしくて、健康に害がなければ、何も問題はない。
ブラックタイガーだろうが車えびだろうが、お客さんはおいしく食べて、納得してお金を払っているわけだしね。

──つまり、高須院長としては食品偽装も問題なしってことですか?

高須:そうだよ。だって、もし本物の車えびを使っていても、ブラックタイガーで作った料理のほうがおいしかったら、そっちのほうが勝ちでしょ?
「全然おいしくない!」っていうクレームがきてるんならダメだけど、味に文句を言っているわけじゃないからね。

──食材そのものの偽装ともうひとつ、産地の偽装という問題もあります。中国産なのに国産と偽ったりとか。

高須:中国産だと有害な物質が入っているかもしれないから…っていう背景があるとしたら、それは問題あり。
健康を害する可能性があるものを、安全だと言って出すのはいただけないね。
ただ、品質に問題がなくて、「中国産より国産のほうが高級そう」みたいなイメージだけで偽装しているんなら、まあいいんじゃない?
結局、お客はそれも気づかないし。

──別に産地は気にしない、と。

高須:そう。おいしければいいんだよ。産地が違ったからって文句なんか言わない。
たとえばさあ、銀座のクラブの女だと思って貢いでいたら、実は池袋のクラブの女だったから、貢いだ分を返してもらった…なんて恥ずかしいもん(笑い)。

──確かに、それは男としてみっともないです。

高須:銀座と池袋は別として、食材については、結局お客さんのほうがその違いを見抜けなかったってことでしょ。
裏を返せば、偽装がわからないくらいにおいしい料理を作ったシェフの腕が素晴らしいってことだよ。
「偽装しやがってけしからん!」ってホテルに返金を求めるんじゃなくて、「そんなにおいしい料理をありがとう!」ってシェフにチップを払いに行くべきだよね(笑い)。

(中略)
ちなみに、美容整形も同じだと思うよ。重要なのはおいしいかどうか。
整形手術をしたからといって、騙しているわけではないからね。むしろ、美しくなれば周りのみんなも喜ぶんだから。


http://www.news-postseven.com/archives/20131123_228205.html

 

まあ日本の美食文化の行き着いた先ですね

 

 

 

私の知り合いに 美食家がいまして 山岡士郎っていうんですけどね

しょちゅう言ってることが変わるんですよ

80391f2a

こいつのせいで日本中の子供が 米が食えなくなり 味噌が食えなくなり 醤油が食えなくなり

お母さんに怒られて ご飯ぬきの目にあわされたんですよ (許さん

 

 

gon0831az-img536x600-1383972703mzaw7o72447_201311191112426fdsooo_201311191107390b2s

 

ヤフオクで14万以上の値段をつけたらしい 原作者も認めるニセモノ なんだけど

本人が納得してるならいいんじゃないかな?

 

 

 

■:急

ご存知ですか 年金基金の投資運用担当の約9割が素人で 年間兆単位の損だしてるんですってよ奥さん

「お父ちゃんが 駅前で使徒を倒して こづかい倍にしてやるよ」 みたいなもんでしょ

なんで人の金で気持よくギャンブルするんでしょうね? お父ちゃんのほうがある意味信用できたりするし

で いままた国民の知らないところでギャンブルがおこなわれているわけですよ

sy-nt-20131116-1-ns-big

これね 福島原発の使用済燃料棒のUFOキャッチャー

だいたい2000本程度と発表されているんですけど 共用プールのものも合わせると6375本だそうです

1回でもしくじると北半球に1000年間人が住めなくなるんですって

レートが点:北半球 \(^o^)/

ちなみにエヴァンゲリオンは原子力発電のメタファーだそうですよ・・

 

そいえば近代麻雀オリジナルの『ムダヅモ無き改革』 思い出しちゃった

はじめのほうは点Fー15イーグルとかやってたけど 5巻ぐらいで点:地球とかインフレってたよね

最近は腹を改造強化した安倍総理が登場したり 再び盛り上がっている様子。

でもリアル政治のほうがまじギャンブル状態だから あんまり笑えなくなってきた。

 

リアルでもムダヅモしないでほしいものですね。

 

 

BAvLJ8eCYAElKeAtmpimg0906172151n120090617220807787

SXSbAb5d979d08a13441abd976876248624561dc711a1

7d8ad5e5

 

2007080900520081027131504

d25f9aab0996c1aa74feca4cb8418fb7t02200163_0480035512053480939img_473108_11138537_2

img7706bb79zikdzj

 

t72

 

 

 

 

■トヨタ、アニメ『ラブライブ!』の販売用公式痛車を公開

ン_? 微妙なんだが

【国立音ノ木坂学院公用車バージョン AQUA】

販売価格:386万4000円(別途登録諸費用)

629118

 

【国立音ノ木坂学院公用車バージョン TOYOTA86】

販売価格:287万7000円(別途登録諸費用)

629113

 

【プリウス霊柩車】 おまけ

販売価格:787万5000円

7b81e60c

なんとなく継ぎ目部分の処理があまいですがカコイイ 霊柩車がきたら親指を隠すと教えられた世代なのだが

普通車に溶け込みすぎて隠すタイミングがむずかしいデス。

 

 

■テクノ歌謡で脳みそくすぐっちゃうよ

もうすぐ春ということで 今回は春を感じさせる曲をピックアップしてみました

テクノ歌謡というジャンルをご存知でしょうか YMOがブームになった80年代以降に歌謡曲とテクノポップを

合体させて魔改造をほどこした ちょっとスカした歌謡曲で、いまだとPerfumeなんかが近いんじゃないでしょうか。

シンセサイザーの「ミョーン」とか「はにゃ〜ん」というFM音は、あいかわらず脳にきます 中毒性高ー

初期は無国籍オリエンタルムードな曲が多いのですがおそらくYMOの影響です まあ仕掛け人がYMO関係だったりするんですけどね

 

「すみれ」とか「一風堂」 と聞いて今の子はラーメンが思い浮かぶかもですが ラーメン関係ないから

土屋昌巳で検索するとおすすめに研ナオコがでてくるあたりにYoutubeの悪意を感じざるを得ません

作詞:大貫妙子 作曲:EPO という自分得な布陣 香坂みゆきさんはアイドルなのに歌上手すぎだったな

香坂さんヒットした曲はこれだけなんですけど この歌大好きなので生んでくれてありがとうですよ

歌詞が「春先 神戸に 見に来てね」と聞こえることから 同年開催の『神戸ポートアイランド博覧会』

との関連が噂されてました。 否定してましたけど そこ言っちゃったらステマにならないし真実は闇のなかです

コーセー化粧品のCMソング スマッシュヒットだったこの曲ですが隠れた名曲です。

レコードの初回プレスのみ発売でCD化されてないんですよ 残念 そこっ!岸田劉生とか言わないように

資生堂のキャンペーンソングでした EPOは年配の方だと同時期のひょうきん族EDのほうが印象があるかも

アイマスの生っすかスペシャルで三浦あずささんがカバーしてるので興味のある人はチェックしてみてみては

うちの姉がこの歌好きでよく歌ってました 歌詞にさりげなく落語家の名前とか入れ込んじゃうあたりが

オリエンタルな昭和のテクノ歌謡 細野さんぽいです。

むかし友達が新井薫子のファンでした 理由は「あの娘を見てると 可愛そうな気持ちになるから・・」

なんか失礼な感じですけど ふつうのアイドルからいきなりテクノ歌謡への転身はたしかに痛々しかったかも

大ヒットしたカネボウのCMソング 松本隆・細野晴臣コンビなんですが あんまりっぽくない気がしますね

味覚糖のスナック 『おさつどきっ』に影響を与えたかは知りませぬ

『夏のミラージュ』 は管理人の趣味です 聞きたくなっただけ

そういえば『きまぐれオレンジ☆ロード』 に超能力設定って必要だったんですかね? ふつうにラブコメでよかった気g

 

 

 

ということで 本日はこれまで ジ・エンドにゃんですよ☆彡

 

つかれた

↑このページのトップヘ