高光效果

V为从顶点指向摄像机的向量,L为从光源指向顶点的向量,R为反射向量


求反射向量R的两种方式 :

1、CG中Reflect函数,可以直接计算出反射向量R

  R = Reflect(I , N); 

  // 参数 :入射光向量I :顶点指向光源的向量,即L的反向量         、   顶点的法向量     注 :都是在世界坐标系中的位置


2、L + R = 2 * cos(N , L) * N  ,当N、L都为单位向量时,cos(N,L) = dot(N,L) 是一个标量值,所以要乘上N,得到向量

      R = 2 * dot(N,L) * N - L


如何证明高亮

    当V与R重合的时候,最为高亮。所以,求得R与V的夹角,即可判断这个顶点是否有高光效果(光滑)



Phong模型

      环境光照(Ambient) + 漫反射光照(Diffuse) + 镜面高光(Specular)


L

   辅助函数WorldSpaceLightDir :参数为顶点在自身坐标系中的位置,函数返回值为 :在世界坐标系中,顶点指向光源位置的向量,所以求入射光线的向量L需要取反


N

   辅助函数UnityObjectToWorldNormal(v.normal),将法向量从自身坐标系变换到世界坐标系中,内部做了向量的规范化。


V

   辅助函数WorldSpaceViewDir(v.vertex) :求从顶点指向摄像机的向量,传入一个自身坐标系中的顶点的位置,返回一个世界坐标系中的从顶点指向摄像机的向量



  

Blinnphong与半角向量 :因为计算反射向量R时,也使用了一次dot操作,运行速度慢,所以可以使用Blinnphong模型和半角向量

      

H

    半角向量,L + V 得出的向量

      float3  H = L + V;

      H = normalize(H);





Shader  "Custom/MySpecular" {


     Properties

     {

          _SpecularColor("_Specular" , Color) = (1,1,1,1)         // 高亮光颜色

          _Shininess("Shininess" , range(1,64)) = 8   // 高亮系数

     }


     SubShader

     {

          Pass

          {

               tags{"LightMode" = "ForwardBase"}


               CGPROGRAM

               #pragma  multi_compile_fwdbase

               #pragma  vertex  vert

               #pragma  fragment  frag

               #include  "unitycg.cginc"

               #include  "lighting.cginc"


               float4  _SpecularColor;

               float  _Shininess;


               struct  v2f {

                      float4  pos : POSITION;

                      fixed4  color : COLOR;

               };


               v2f  vert(appdata_base v)

               {

                      v2f  o;

                      o.pos = mul(UNITY_MATRIX_MVP, v.vertex);


                      float3  L = normalize(WorldSpaceLightDir(v.vertex));   //世界坐标系中,从顶点指向光源的向量

                      float3  N = UnityObjectToWorldNormal(v.normal);     // 把顶点的法向量,从自身坐标系中变换到世界坐标系中

                      float3  V = normalize(WorldSpaceViewDir(v.vertex));   //世界坐标系中,从顶点指向摄像机的向量


                      // 1、Ambient  Color

                      o.color = UNITY_LIGHTMODEL_AMBIENT;


                     // 2、Diffuse  Color

                     float  ndotl = saturate(dot(N,L));

                     o.color += _LightColor0 * ndotl ;               //平行光的颜色


                     // 3、Specular  Color :高光系数的两种求法 :1、dot(R , V)       2、半角向量

                     // 1

                    求R的两种方式 :(1)、Reflect函数 ;   (2)、R = 2 * dot(N,L) * N - L

                    (1)、

                   //float3  I  = -WorldSpaceLightDir(v.vertex);            // 入射光向量I,从顶点指向光源

                   //float3  R = reflect(I , N);

                    (2)、

                   float3  R = 2 * dot(N , L) * N - L;

                   R = normalize(R);

                   float  specularScale = pow(saturate(dot(R,V)) , _Shininess);



                   // 2多用半角向量,运算速度快

                   float3  H = L + V ;

                   H = normalize(H);

                   float  specularScale = pow(saturate(dot(H , N)) , _Shininess) ; 


                   o.color.rgb  += _SpecularColor * specularScale;


                   return  o ;

               }


               fixed4  frag(v2f  IN) : COLOR

               {

                     return  IN.color ;

               }


               ENDCG

          }

     }

   

}



Phong模型 :要计算反射向量

Blinnphong模型 :要计算半角向量

计算这两个向量,都是为了计算高光




L :

   辅助函数WorldSpaceLightDir :参数为顶点在自身坐标系中的位置,函数返回值为 :在世界坐标系中,顶点指向光源位置的向量,所以求入射光线的向量L需要取反


N :

   辅助函数UnityObjectToWorldNormal(v.normal),将法向量从自身坐标系变换到世界坐标系中,内部做了向量的规范化。


V :

   辅助函数WorldSpaceViewDir(v.vertex) :求从顶点指向摄像机的向量,传入一个自身坐标系中的顶点的位置,返回一个世界坐标系中的从顶点指向摄像机的向量


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值