高光反射Blinn-Phong模型

Bling-Phong模型的计算公式和Blinn的计算公式是一样的
但是夹角是不一样的.


代码如下:
得到平分线的方法:
用normalize()标准化两个向量的和.
对比图:

// Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
Shader"Allen/09-Specular Fragment Blinn-Phong"{
       Properties{
              _Diffuse("_Diffuse Color",Color)=(1,1,1,1)//定义一个颜色.
              _Gloss("_Gloss",Range(8,200))=10//定义一个高光反射的强度
              _GlossColor("_GlossColor",Color)=(0.5,0.5,0.5,1)
       }
       SubShader{
              Pass{
              Tags{"LightMode"="ForwardBase"}//设置光照模式
                     CGPROGRAM
#include   "Lighting.cginc" //这个相当于C#中的Using Unity;引入命名空间.
//可以用他来取得第一个直射光的颜色. _LightColor0
//还能取得第一个直射光的位置 _worldSpaceLightPos0
#pragma   vertex vert
#pragma   fragment frag                    
                      fixed4   _Diffuse; //上面虽然定义了这个属性,但是这里用的时候还是要声明
                      half   _Gloss;
                      fixed4   _GlossColor;
                      struct   a2v {
                           float4  vertex : POSITION;
                            float3   normal : NORMAL;
                     
                     };
                      struct   v2f{
                            float4   position:SV_POSITION;
                            float3   worldNormal:TEXCOORD0;
                            float3   worldVertex:TEXCOORD1;
                           
                     };
                     v2f   vert   (a2v v){
                           v2f f;
                           f.position=UnityObjectToClipPos(v.vertex);             
                            f.worldNormal=mul(v.normal,(float3x3)unity_WorldToObject);
                           f.worldVertex=mul(v.vertex , unity_WorldToObject).xyz;
                           return f;
                           
                     }
                      fixed4   frag (v2f f) : SV_Target{
                            fixed3   ambient=UNITY_LIGHTMODEL_AMBIENT.rgb; //得到环境光
                           //1 得到法线的单位向量
                            fixed3   normalDir= normalize (f.worldNormal);
                           //normalize()可以得到单位长度
                           //mul()可以让他从世界坐标转到模型坐标.
                           //这里的float3x3 可以让他强制转化为三维乘以三维
                           //2 得到直射光的向量
                            fixed3   lightDir= normalize (_WorldSpaceLightPos0.xyz);
                           //对于每一个顶点来说光的位置就是光的方向.因为光源是平行光
                           //这个_WorldSpaceLightPos0是通过上面的标记的Tags和引入的include从系统中得到的.
                           //3 获取漫反射的颜色
                            fixed3   diffuse =_LightColor0.rgb* max ( dot (normalDir,lightDir),0)*_Diffuse.rgb;
                           //_LightColor0是从上面的标记的Tags和引入的include从系统中得到的.
                           //_LightColor0.rgb 里面的rgb分别代表颜色的rgba ,a表示alpha透明的,这里不需要,所以省略
                           //dot,夹角,点乘 另外注释.
                           // 高光反射 Blinn-Phong模型

                           // 得到视野方向
                           //通过_WorldSpaceCamera.xyz就能得到当前相机的位置.
                            fixed3   viewDir= normalize (_WorldSpaceCameraPos.xyz - f.worldVertex);

                           //得到平行光和视野方向的平分线
                            fixed3   halfDir= normalize (lightDir+viewDir);
                           //得到高光反射
                            fixed3   specular = _LightColor0.rgb *   pow ( max ( dot (normalDir,halfDir),0),_Gloss);
                           //5 通过参数把顶点函数的颜色返回给片元函数,让GPU进行渲染.
                            fixed3   temp=(diffuse+ambient +_GlossColor*specular);
                           return   fixed4 (temp,1);
                     }
                     ENDCG
              }
       }
       FallBack"Diffuse"
}      

猜你喜欢

转载自blog.csdn.net/Allen_ZGD/article/details/80223575