イラスト、モデリング、Unity、VR関連

unityとかblenderとかvr関連の作業メモ

三角波 サンプル断片

ギザギザ

 

			float4 frag(g2f i) :SV_Target {
				//float2 uv = i.uv*2-1;
				float2 uv = i.uv;
				uv = frac(uv*_Frec);
				//uv.x = uv.x*2 -1;
				float k=_Width;
				float x;
				float b=0.5;
				if(uv.y<=0.25){ //x = 4ky + b;
					x = 4*k*uv.y+b;
				}else if(uv.y>0.25 && uv.y<=0.75){ //x = -4ky + 2k + b
					x = -4*k*uv.y+2*k+b;
				}else{ //x = 4ky -4k + b
					x = 4*k*uv.y-4*k+b;
				}
				//if(i.type==0 && i.uv.x<=x) clip(-1);
				//if(i.type==1 && i.uv.x>x) clip(-1);
				if(i.type==1) clip(-1);
				if(i.uv.x<=x) return GetTexColor(0,i.uv);
				return GetTexColor(0,i.uv)*float4(1,0,0,1);

			}    

unity shader 特定部分のみsurfシェーダと同じライティングを使う方法

surfシェーダを使うと用意されているライティングを処理を行うことが出来るが、部分的にライティング処理を行いたい等が出来ない。

これを部分的に行う方法を書く。

 

まずは全体にライティング処理が施された状態で書きたいsurfシェーダを書く。

 

シェーダファイルをクリックすると、インスペクタにshow generated codeというボタンがあるので、それをクリック。これがラッパーであるsurfシェーダが本来のfragシェーダに変換されたコードである。

 

realtimeで検索すると、以下のような部分がヒットする

// realtime lighting: call lighting function
c += LightingStandard (o, worldViewDir, gi);
c.rgb += o.Emission;

ここがライティングを行ってる部分である。

surfIn変数が通常のsurfシェーダのInputに該当するものであるので、

このsurfIn変数の値を使って、ライティング処理したい部分としたくない部分を分岐させればよい。

 

ライティングしたくない部分は、

c += _Color;
c.rgb += _Emission;

のように使用したい色をそのまま加算すればよい。

 

ライティングしたい部分はそのまま

c += LightingStandard (o, worldViewDir, gi);
c.rgb += o.Emission;

と書けばよい。

 

素の状態だと、

c.rgb += o.Emission;

となっているが、LightingStandardで、Emissionの値がライティングに合わせて加工されているようである。

 

これでDirectionalライトの特定部分の無効化が完了した。

次はpoint light等の二個目以降のライトを無効化する処理を書く。

 

コードをForwardAddで検索し、下にスクロールしておくと、surf_frag関数内に

c += LightingStandard (o, worldViewDir, gi);

と再び記述されている部分がある。ここを先と同じように分岐させる。ライトを当てたい場合はこれをそのまま書く。

ただし、ライティングを当てたくない部分は先と違い、clip(-1);と分岐先で書く。

if(ライトを当てる){

  c += LightingStandard (o, worldViewDir, gi);

}else{

 clip(-1);

}

(摩訶不思議なのであるが、返り値として使用しているcの値を0などにしてもclip(-1)としないとライトの影響を受けてしまう。これ以降の関数を全てオフにしても結果は同じであった)

 

また、#ifdef等を使っていると、その分surf=>fragへの変換時に生成されるコードが増えるため変更箇所が多くなるのに注意。コピペするだけでいいといえばいいのだが #ifdefを使うのでなく通常の分岐を使えば変更箇所が少なくてすむ。

shader normal map + multi lighting

f:id:arumogina:20191125154428p:plain

参考:

【連載】Unity時代の3D入門 – 第9回「ノーマルマッピング」 – てっくぼっと!

【Unity】【シェーダ】Forward Renderingで複数のライトを取り扱う - LIGHT11

Shader "Arumogina/NormalMap"{
    Properties{
      _MainTex ("Texture", 2D) = "white" {}
      _NormalMap ("Normal map", 2D) = "bump" {}
    }
  
    SubShader{
      Tags { "RenderType"="Opaque" }
      Pass{
        Tags { "LightMode"="ForwardBase" }
          CGPROGRAM
          #pragma vertex vert
          #pragma fragment frag
          #pragma multi_compile_fwdbase
          #pragma target 3.0
  
          #include "UnityCG.cginc"
          #include "AutoLight.cginc"
          #include "UnityStandardUtils.cginc"
  
          struct appdata{
            half4 vertex : POSITION;
            half3 normal : NORMAL;
            half2 texcoord : TEXCOORD0;
            float4 tangent : TANGENT;
          };
  
          struct v2f{
            half4 pos : SV_POSITION;
            half2 uv : TEXCOORD0;
            half3 normal: TEXCOORD1;
            half3 ambient: TEXCOORD2;
            half3 worldPos: TEXCOORD3;
            half3 lightDir : TEXCOORD4;
            half3 viewDir : TEXCOORD5;
            half2 uv_nor : TEXCOORD6;
            LIGHTING_COORDS(6, 7)
          };
  
          sampler2D _MainTex;
          half4 _MainTex_ST;
          sampler2D _NormalMap;
          half4 _NormalMap_ST;
          half4 _LightColor0;
  
          v2f vert (appdata v){
            v2f o = (v2f)0;
            o.pos = UnityObjectToClipPos(v.vertex);
            o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
            o.uv_nor = TRANSFORM_TEX(v.texcoord, _NormalMap);
            o.normal = UnityObjectToWorldNormal(v.normal);
            o.worldPos = mul(unity_ObjectToWorld, v.vertex);
            TANGENT_SPACE_ROTATION;

            o.lightDir = mul(rotation, ObjSpaceLightDir(v.vertex));
            o.viewDir = mul(rotation, ObjSpaceViewDir(v.vertex));
            #if UNITY_SHOULD_SAMPLE_SH
              #if defined(VERTEXLIGHT_ON)
                o.ambient = Shade4PointLights(
                  unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0,
                  unity_LightColor[0].rgb, unity_LightColor[1].rgb,
                  unity_LightColor[2].rgb, unity_LightColor[3].rgb,
                  unity_4LightAtten0, o.worldPos, o.normal
                );
              #endif
              o.ambient = ShadeSHPerVertex(o.normal,o.ambient);
            #else
              o.ambient = 0;
            #endif
              TRANSFER_VERTEX_TO_FRAGMENT(o);
              return o;
            }
  
            fixed4 frag (v2f i) : SV_Target{
              half4 col = tex2D(_MainTex, i.uv);
              i.lightDir = normalize(i.lightDir);
              i.viewDir = normalize(i.viewDir);
              half3 halfDir = normalize(i.lightDir + i.viewDir);
              half3 normal = UnpackNormal(tex2D(_NormalMap, i.uv_nor));
              UNITY_LIGHT_ATTENUATION(attenuation, i, normal);
              half3 diff = saturate(dot(normal, i.lightDir)) * _LightColor0 * attenuation;
              col.rgb *= diff + i.ambient;
              return col;
            }
            ENDCG
          }//Pass
/*  
      Pass {
        Tags { "LightMode"="ForwardAdd" }
        Blend One One
        ZWrite Off
  
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag
        #pragma multi_compile_fwdadd
        #pragma target 3.0
  
        #include "UnityCG.cginc"
        #include "AutoLight.cginc"
  
        struct appdata{
          half4 vertex : POSITION;
          half3 normal : NORMAL;
          half2 texcoord : TEXCOORD0;
          float4 tangent : TANGENT;
        };
  
        struct v2f{
          half4 pos : SV_POSITION;
          half2 uv : TEXCOORD0;
          half3 normal: TEXCOORD1;
          half3 ambient: TEXCOORD2;
          half3 worldPos: TEXCOORD3;
          half3 lightDir : TEXCOORD4;
          half3 viewDir : TEXCOORD5;
          half2 uv_nor : TEXCOORD6;
          LIGHTING_COORDS(6, 7)
        };
  
        sampler2D _MainTex;
        sampler2D _NormalMap;
        half4 _MainTex_ST;
        half4 _NormalMap_ST;
        half4 _LightColor0;
  
        v2f vert (appdata v){
          v2f o = (v2f)0;
          o.pos = UnityObjectToClipPos(v.vertex);
          o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
          o.uv_nor = TRANSFORM_TEX(v.texcoord, _NormalMap);
          o.normal = UnityObjectToWorldNormal(v.normal);
          o.worldPos = mul(unity_ObjectToWorld, v.vertex);
  
          TANGENT_SPACE_ROTATION;
          float3 objSpaceLightPos = mul(unity_WorldToObject, _WorldSpaceLightPos0).xyz;
          if (_WorldSpaceLightPos0.w > 0) {
            o.lightDir = mul(rotation,objSpaceLightPos.xyz - v.vertex.xyz);
          }else {
            o.lightDir = mul(rotation,objSpaceLightPos);
          }
          o.viewDir = mul(rotation, ObjSpaceViewDir(v.vertex));
          TRANSFER_VERTEX_TO_FRAGMENT(o);
          return o;
        }
  
        half4 frag(v2f i) : COLOR{
          half4 col = tex2D(_MainTex, i.uv);
          i.lightDir = normalize(i.lightDir);
          i.viewDir = normalize(i.viewDir);
          half3 halfDir = normalize(i.lightDir + i.viewDir);
          half3 normal = UnpackNormal(tex2D(_NormalMap, i.uv_nor));
          UNITY_LIGHT_ATTENUATION(attenuation, i, normal);
          half3 diff = saturate(dot(normal, i.lightDir)) * _LightColor0 * attenuation;
          col.rgb *= diff + i.ambient;
          return col;
        }
      ENDCG
      }//pass
*/        
    }

    Fallback "Diffuse"
    //半透明を扱う場合
    //Fallback "Transparent/Cutout/Diffuse"
  }

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

Shader "LightTest-2"{
  Properties{
    _MainTex ("Texture", 2D) = "white" {}
    _NormalMap ("Normal map", 2D) = "bump" {}
  }

  SubShader{
    Tags { "RenderType"="Opaque" }
    Pass{
      Tags { "LightMode"="ForwardBase" }
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag
        #pragma multi_compile_fwdbase
        #pragma target 3.0

        #include "UnityCG.cginc"
        #include "AutoLight.cginc"
        #include "UnityStandardUtils.cginc"

        struct appdata{
          half4 vertex : POSITION;
          half3 normal : NORMAL;
          half2 texcoord : TEXCOORD0;
          float4 tangent : TANGENT;
        };

        struct v2f{
          half4 pos : SV_POSITION;
          half2 uv : TEXCOORD0;
          half3 normal: TEXCOORD1;
          half3 ambient: TEXCOORD2;
          half3 worldPos: TEXCOORD3;
          half3 lightDir : TEXCOORD4;
          half3 viewDir : TEXCOORD5;
          LIGHTING_COORDS(6, 7)
        };

        sampler2D _MainTex;
        half4 _MainTex_ST;
        sampler2D _NormalMap;
        half4 _LightColor0;

        v2f vert (appdata v){
          v2f o = (v2f)0;
          o.pos = UnityObjectToClipPos(v.vertex);
          o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
          o.normal = UnityObjectToWorldNormal(v.normal);
          o.worldPos = mul(unity_ObjectToWorld, v.vertex);
          TANGENT_SPACE_ROTATION;

          /*
          1pass目においてはこの処理は
          o.lightDir = mul(rotation, ObjSpaceLightDir(v.vertex));
          と同じ結果になる。
          float3 objSpaceLightPos = mul(unity_WorldToObject, _WorldSpaceLightPos0).xyz;
          if (_WorldSpaceLightPos0.w > 0) {
            o.lightDir = mul(rotation,objSpaceLightPos.xyz - v.vertex.xyz);
          }else {
            o.lightDir = mul(rotation,objSpaceLightPos);
          }
          */
          o.lightDir = mul(rotation, ObjSpaceLightDir(v.vertex));
          o.viewDir = mul(rotation, ObjSpaceViewDir(v.vertex));
          #if UNITY_SHOULD_SAMPLE_SH
            #if defined(VERTEXLIGHT_ON)
              o.ambient = Shade4PointLights(
                unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0,
                unity_LightColor[0].rgb, unity_LightColor[1].rgb,
                unity_LightColor[2].rgb, unity_LightColor[3].rgb,
                unity_4LightAtten0, o.worldPos, o.normal
              );
            #endif
            o.ambient = ShadeSHPerVertex(o.normal,o.ambient);
          #else
            o.ambient = 0;
          #endif
            TRANSFER_VERTEX_TO_FRAGMENT(o);
            return o;
          }

          fixed4 frag (v2f i) : SV_Target{
            half4 col = tex2D(_MainTex, i.uv);
            i.lightDir = normalize(i.lightDir);
            i.viewDir = normalize(i.viewDir);
            half3 halfDir = normalize(i.lightDir + i.viewDir);
            half3 normal = UnpackNormal(tex2D(_NormalMap, i.uv));
            UNITY_LIGHT_ATTENUATION(attenuation, i, normal);
            half3 diff = saturate(dot(normal, i.lightDir)) * _LightColor0 * attenuation;
            col.rgb *= diff + i.ambient;
            return col;
          }
          ENDCG
        }//Pass

    Pass {
      Tags { "LightMode"="ForwardAdd" }
      Blend One One
      ZWrite Off

      CGPROGRAM
      #pragma vertex vert
      #pragma fragment frag
      #pragma multi_compile_fwdadd
      #pragma target 3.0

      #include "UnityCG.cginc"
      #include "AutoLight.cginc"

      struct appdata{
        half4 vertex : POSITION;
        half3 normal : NORMAL;
        half2 texcoord : TEXCOORD0;
        float4 tangent : TANGENT;
      };

      struct v2f{
        half4 pos : SV_POSITION;
        half2 uv : TEXCOORD0;
        half3 normal: TEXCOORD1;
        half3 ambient: TEXCOORD2;
        half3 worldPos: TEXCOORD3;
        half3 lightDir : TEXCOORD4;
        half3 viewDir : TEXCOORD5;
        LIGHTING_COORDS(6, 7)
      };

      sampler2D _MainTex;
      sampler2D _NormalMap;
      half4 _MainTex_ST;
      half4 _LightColor0;

      v2f vert (appdata v){
        v2f o = (v2f)0;
        o.pos = UnityObjectToClipPos(v.vertex);
        o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
        o.normal = UnityObjectToWorldNormal(v.normal);
        o.worldPos = mul(unity_ObjectToWorld, v.vertex);

        TANGENT_SPACE_ROTATION;
        float3 objSpaceLightPos = mul(unity_WorldToObject, _WorldSpaceLightPos0).xyz;
        if (_WorldSpaceLightPos0.w > 0) {
          o.lightDir = mul(rotation,objSpaceLightPos.xyz - v.vertex.xyz);
        }else {
          o.lightDir = mul(rotation,objSpaceLightPos);
        }
        o.viewDir = mul(rotation, ObjSpaceViewDir(v.vertex));
        TRANSFER_VERTEX_TO_FRAGMENT(o);
        return o;
      }

      half4 frag(v2f i) : COLOR{
        half4 col = tex2D(_MainTex, i.uv);
        i.lightDir = normalize(i.lightDir);
        i.viewDir = normalize(i.viewDir);
        half3 halfDir = normalize(i.lightDir + i.viewDir);
        half3 normal = UnpackNormal(tex2D(_NormalMap, i.uv));
        UNITY_LIGHT_ATTENUATION(attenuation, i, normal);
        half3 diff = saturate(dot(normal, i.lightDir)) * _LightColor0 * attenuation;
        col.rgb *= diff + i.ambient;
        return col;
      }
    ENDCG
    }//pass
  }

  //影の生成のために必要
  //http://tsumikiseisaku.com/blog/shader-tutorial-transparent/  \
  Fallback "Diffuse"
  //半透明を扱う場合
  //Fallback "Transparent/Cutout/Diffuse"
}

shader lightingサンプル

【Unity】【シェーダ】Forward Renderingで複数のライトを取り扱う - LIGHT11

こちらの記事のコードをコピペし、コメントや解説等を加えたものです。

参考集:

unity ラインティング参考リンク - イラスト、モデリング、Unity、VR関連

単にライティングやりたいだけならsurfシェーダでやればいい

 

Shader "MultiLight"{
  Properties{
    _MainTex ("Texture", 2D) = "white" {}
  }

  SubShader{
    Tags { "RenderType"="Opaque" }
    Pass{
      //ディレクショナルライトの処理
      Tags { "LightMode"="ForwardBase" }
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag
        // VERTEXLIGHT_ONなどが定義されたバリアントが生成される
        #pragma multi_compile_fwdbase
        #pragma target 3.0

        #include "UnityCG.cginc"
        #include "AutoLight.cginc"
        #include "UnityStandardUtils.cginc"

        struct appdata{
          half4 vertex : POSITION;
          half3 normal : NORMAL;
          half2 texcoord : TEXCOORD0;
        };

        struct v2f{
          half4 pos : SV_POSITION;
          half2 uv : TEXCOORD0;
          half3 normal: TEXCOORD1;
          half3 ambient: TEXCOORD2;
          half3 worldPos: TEXCOORD3;
          /*
          AutoLight.cgincより

          #ifdef POINT
          #define LIGHTING_COORDS(idx1,idx2) unityShadowCoord3 _LightCoord : TEXCOORD##idx1; SHADOW_COORDS(idx2)
          #endif

          #ifdef SPOT
          #define LIGHTING_COORDS(idx1,idx2) unityShadowCoord4 _LightCoord : TEXCOORD##idx1; SHADOW_COORDS(idx2)
          #endif

          #ifdef DIRECTIONAL
          #define LIGHTING_COORDS(idx1,idx2) SHADOW_COORDS(idx1)
          #endif

          #ifdef POINT_COOKIE
          #define LIGHTING_COORDS(idx1,idx2) unityShadowCoord3 _LightCoord : TEXCOORD##idx1; SHADOW_COORDS(idx2)
          #endif

          #ifdef DIRECTIONAL_COOKIE
          #define LIGHTING_COORDS(idx1,idx2) unityShadowCoord2 _LightCoord : TEXCOORD##idx1; SHADOW_COORDS(idx2)
          #endif

          #define SHADOW_COORDS(idx1) unityShadowCoord4 _ShadowCoord : TEXCOORD##idx1;
          これは一例、マクロにより分岐している

          TRANSFER_VERTEX_TO_FRAGMENT(o);
          TRANSFER_SHADOW(o);
          を使うのに必要。
          */
          //4,5の数値はtexcoordの数値となる。
          LIGHTING_COORDS(4, 5)
        };

        sampler2D _MainTex;
        half4 _MainTex_ST;
        //これを定義すればライトの色を取得出来る
        half4 _LightColor0;

        v2f vert (appdata v){
          v2f o = (v2f)0;
          o.pos = UnityObjectToClipPos(v.vertex);
          o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
          o.normal = UnityObjectToWorldNormal(v.normal);
          o.worldPos = mul(unity_ObjectToWorld, v.vertex);

          //UNITY_SHOULD_SAMPLE_SH オブジェクトがstaticでなく、動的な場合に有効になる
          #if UNITY_SHOULD_SAMPLE_SH
            //VERTEXLIGHT_ON オブジェクトに影響を及ぼすポイントライトが Pixel Light Count よりも存在する場合にのみ ON になる。
            #if defined(VERTEXLIGHT_ON)
              //環境光等を取得
              //内部的には優先度の低い光を減衰を考慮しながら色を足し合わせている
              o.ambient = Shade4PointLights(
                unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0,
                unity_LightColor[0].rgb, unity_LightColor[1].rgb,
                unity_LightColor[2].rgb, unity_LightColor[3].rgb,
                unity_4LightAtten0, o.worldPos, o.normal
              );
            #endif
            //skyboxの光
            //頂点ごとに球面調和関数を使ってベイクされたライティングを復元する
            //内部でambientに加算している
            o.ambient = ShadeSHPerVertex(o.normal,o.ambient);
          #else
            o.ambient = 0;
          #endif
            /*
            #ifdef POINT
              #define TRANSFER_VERTEX_TO_FRAGMENT(a) a._LightCoord = mul(unity_WorldToLight, mul(unity_ObjectToWorld, v.vertex)).xyz; TRANSFER_SHADOW(a)
            #endif

            #ifdef SPOT
              #define TRANSFER_VERTEX_TO_FRAGMENT(a) a._LightCoord = mul(unity_WorldToLight, mul(unity_ObjectToWorld, v.vertex)); TRANSFER_SHADOW(a)
            #endif

            #ifdef DIRECTIONAL
              #define TRANSFER_VERTEX_TO_FRAGMENT(a) TRANSFER_SHADOW(a)
            #endif

            #ifdef POINT_COOKIE
              #define TRANSFER_VERTEX_TO_FRAGMENT(a) a._LightCoord = mul(unity_WorldToLight, mul(unity_ObjectToWorld, v.vertex)).xyz; TRANSFER_SHADOW(a)
            #endif

            #ifdef DIRECTIONAL_COOKIE
              #define TRANSFER_VERTEX_TO_FRAGMENT(a) a._LightCoord = mul(unity_WorldToLight, mul(unity_ObjectToWorld, v.vertex)).xy; TRANSFER_SHADOW(a)
            #endif

            #if defined(UNITY_NO_SCREENSPACE_SHADOWS)
              #define TRANSFER_SHADOW(a) a._ShadowCoord = mul( unity_WorldToShadow[0], mul( unity_ObjectToWorld, v.vertex ) );
            #else // UNITY_NO_SCREENSPACE_SHADOWS
              #define TRANSFER_SHADOW(a) a._ShadowCoord = ComputeScreenPos(a.pos);
            TRANSFER_SHADOWの定義はこれは一例。分岐が多数あり載せきれない
            */
            //基本的にはLIGHTING_COORDS(4, 5)で定義される_ShasowCoord変数に値を入れている。
            //この値はFallback "Diffuse"で利用され、castshadow,影が落とす処理が行われる。
            TRANSFER_VERTEX_TO_FRAGMENT(o);
            return o;
          }

          fixed4 frag (v2f i) : SV_Target{
            //clip(-1);
            half4 col = tex2D(_MainTex, i.uv);
            /*
            #ifdef SPOT
              #define UNITY_LIGHT_ATTENUATION(destName, input, worldPos) \
                unityShadowCoord3 lightCoord = mul(unity_WorldToLight, unityShadowCoord4(worldPos, 1)).xyz; \
                fixed shadow = UNITY_SHADOW_ATTENUATION(input, worldPos); \
                fixed destName = tex2D(_LightTexture0, dot(lightCoord, lightCoord).rr).UNITY_ATTEN_CHANNEL * shadow;
              #endif

            #ifdef DIRECTIONAL
              #define UNITY_LIGHT_ATTENUATION(destName, input, worldPos) fixed destName = UNITY_SHADOW_ATTENUATION(input, worldPos);

            ライトの種類で分岐して他にも定義されている。
            */
            //castshadow,落ちる影と、落ちた影の影響を計算している
            UNITY_LIGHT_ATTENUATION(attenuation, i, i.normal);
            half3 diff = max(0, dot(i.normal, _WorldSpaceLightPos0.xyz)) * _LightColor0 * attenuation;
            //half3 diff = max(0, dot(i.normal, _WorldSpaceLightPos0.xyz)) * _LightColor0;
            col.rgb *= diff + i.ambient;
            return col;
          }
          ENDCG
        }//Pass

    Pass {
      //spotなどディレクショナルライト以外のライトの処理
      //ただし、影の色がspotの色の影響を受けてしまう
      Tags { "LightMode"="ForwardAdd" }
      Blend One One
      ZWrite Off

      CGPROGRAM
      #pragma vertex vert
      #pragma fragment frag
      #pragma multi_compile_fwdadd
      #pragma target 3.0

      #include "UnityCG.cginc"
      #include "AutoLight.cginc"

      struct appdata{
        half4 vertex : POSITION;
        half3 normal : NORMAL;
        half2 texcoord : TEXCOORD0;
      };

      struct v2f{
        half4 pos : SV_POSITION;
        half2 uv : TEXCOORD0;
        half3 normal: TEXCOORD1;
        half3 ambient: TEXCOORD2;
        half3 worldPos: TEXCOORD3;
        LIGHTING_COORDS(4, 5)
      };

      sampler2D _MainTex;
      half4 _MainTex_ST;
      half4 _LightColor0;

      v2f vert (appdata v){
        v2f o = (v2f)0;
        o.pos = UnityObjectToClipPos(v.vertex);
        o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
        o.normal = UnityObjectToWorldNormal(v.normal);
        o.worldPos = mul(unity_ObjectToWorld, v.vertex);
        TRANSFER_VERTEX_TO_FRAGMENT(o);
        return o;
      }

      half4 frag(v2f i) : COLOR{
        //clip(-1);
        half4 col = tex2D(_MainTex, i.uv);
        // _WorldSpaceLightPos0.wはディレクショナルライトだったら0、それ以外は1となる
        half3 lightDir;
        if (_WorldSpaceLightPos0.w > 0) {
          lightDir = _WorldSpaceLightPos0.xyz - i.worldPos.xyz;
        }else {
          lightDir = _WorldSpaceLightPos0.xyz;
        }
        lightDir = normalize(lightDir);
        UNITY_LIGHT_ATTENUATION(attenuation, i, i.normal);
        half3 diff = max(0, dot(i.normal, lightDir)) * _LightColor0 * attenuation;
        col.rgb *= diff;
        return col;
      }
    ENDCG
    }//pass
  }

  //影の生成のために必要
  //http://tsumikiseisaku.com/blog/shader-tutorial-transparent/  \
  Fallback "Diffuse"
  //半透明を扱う場合
  //Fallback "Transparent/Cutout/Diffuse"
}

unity ラインティング参考リンク

基本的な原理が解説されているが、UNITY_LIGHT_ATTENUATIONなどunityの機能があまり使用されていない。

【連載】Unity時代の3D入門 – 第5回「拡散反射ライティング」 – てっくぼっと!

【連載】Unity時代の3D入門 – 第6回「鏡面反射ライティング」 – てっくぼっと!

【連載】Unity時代の3D入門 – 第9回「ノーマルマッピング」 – てっくぼっと!

 

とりあえず使えればいい人向け

http://alfa.hatenablog.jp/entry/2015/08/16/195933

 

複数のライトを扱う場合

【Unity】【シェーダ】Forward Renderingで複数のライトを取り扱う - LIGHT11

 

詳細だが、詳細過ぎて分からない

UnityでForwardのライトに対応したLambert反射モデルのシェーダを作成する | 測度ゼロの抹茶チョコ

Unity で Standard Surface Shader の変換後のコードを追ってみた (Forward) - 凹みTips

 

++用語

diffuse - 拡散反射光

speculer- 鏡面反射

ambient - 環境光

イラスト練習について

++モデリングのためにイラスト練習を始めた。

第一目的はフルスクラッチモデリング

第二目的はイラストスキル

 

++参考にしたサイト

イラスト初心者が1年間でここまで上達した理由と練習方法 | 画材大好き!くうこのイラスト帳

 

++++実際にやった練習法

++3Dモデルの模写、vroidの服を脱がせて撮影したものをクリスタに貼り付けて模写した。

上記のサイトで紹介されてる単純化や比率であるが、最初はやってみたのだが、それだけ出来ても、結局、体のラインが分からくて描けねぇ、となった。

なので、まずは体のラインをある程度覚えることを目標にした

 

まずは、モデルのラインをそのままなぞる。

次に模写、という手順を繰り返した。最初にラインをなぞってるのは、正しい線を覚えるため。

360度回転させたものを模写していけば、全体のラインを覚えられるだろうという考え。

 

github desktopでバックアップを取る(非プログラマ向け)

とりあえず、オンラインにバックアップ取って、バージョン管理っぽいことがしたい、みたいな雑な運用が出来れば十分という人向けです。

 

まずはgithubのアカウントを作成しましょう

The world’s leading software development platform · GitHub

 

githubデスクトップをダウンロードしましょう

GitHub Desktop | Simple collaboration from your desktop

 

githubデスクトップを開き、githubアカウントでログインしましょう。

(多分、githubデスクトップとgithubアカウントを連携させる処理があるはずなので、それをログインを書いてる)

 

File=>New Repositoryでリポジトリを作成

そのリポジトリのフォルダを開いて、.gitignoreというファイルを作成し、( .gitignore 、. (ドット)を忘れずに)

Temp/

と書き込み保存。

(Tempを除去しないとエラーが出る)

そのリポジトリのフォルダの中にバックアップしたいunityプロジェクトを移動。これでgithub desktopにファイルの一覧が表示されるはず

 

適当なコメントを書いてCommit to Mastarを押す。

これでローカルに変更が確定した状態で保存される。

githubと連携していれば右側にpush to originというボタンが出るのでそれを押す。

 

自動的にバックアップを取ってくれるわけではないので、適度に作業が終わったらcommit と push to originをやっていけばいいと思います。

 

SSDがぶっ飛ぶなどして、バックアップを丸ごとDLしたければgithubに行き、clone or downloadする

 

前にコミットした状態に戻す

gitを入れたあと、git reset使えばいいのだが、gitを入れたり入れたあとのコマンドライン操作の説明が面倒なので、知りたければググってください。(正直、このあたりはgithub desktopに搭載してほしい感ある

 

公式チュートリアル

GitHub Desktop を使った最初のリポジトリ作成方法 - GitHub ヘルプ