逐顶点漫反射

///逐顶点漫反射
Shader"unity shader book/chapter 6/Diffuse Vertex_Leve1"{
    //属性
    
Properties{
        //声明一个color类型的属性
        _Diffuse("Diffuse",Color) = (1,1,1,1)
    }

        //
      
 Subshader{
        //顶点/片元着色器代码写在Pass里
    
    pass {
        //指明光照模式
  
     Tags{"LightMode" = "ForwardBase"}

            //CG 代码
            CGPROGRAM

//定义顶点着色器名字
#pragma vertex vert
//定义片元着色器名字
#pragma fragment frag
//内置文件
#include "Lighting.cginc"

                //定义一个和Properties中属性相对应的变量,由于颜色属性的取值范围是0到1,所以用fixed精度来储存它
              
 fixed4 _Diffuse;////////漫反射公式中的——漫反射颜色

        //定义了顶点着色器的输入结构体
      
 struct a2v {
            float4 vertex:POSITION;

            //模型顶点法线信息的储存
          
 float3 normal:NORMAL;///////漫反射公式中的——顶点法线
        };
        //定义了顶点着色器的输出结构体,同时也是片元着色器的输入结构体
      
 struct v2f {
            float4 pos:SV_POSITION;

            //顶点着色器中计算得到的光照元素(TEXCOORD0)
          
 float3 color:COLOR;
        };

        ///漫反射计算在顶点着色器中进行(由于是逐顶点的漫反射光照)
        
v2f vert(a2v v) {
            //定义返回值 o
         
   v2f o;
            //Transform the vertex from object space to projection space.将顶点位置从模型空间转换到裁剪空间
                      //UNITY_MATRIX_MVP:unity内置的 模型*世界*投影矩阵
          
 o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
            //Get ambient term. 得到周围的环境光部分
          
 fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
            //Transfrom the normal from object space to world space. 转换法线从模型转换到世界
            /*顶点变化矩阵矩阵的逆矩阵对法线进行变化,
            得到模型空间到世界空间的变化矩阵的逆矩阵_World2Object,
            然后通过调换他在mul函数中的位置,得到和转置矩阵相同的乘法矩阵*/
          
 fixed3 worldNormal = normalize(mul(v.normal, (float3x3)_World2Object));
            //得到世界空间下的光源方向
            
fixed3 worldLight = normalize(_WorldSpaceLightPos0.xyz);
            /*为了防止点积为负,使用saturate函数,是cg提供的一种函数,可以把参数截取到[0.1]的范围
            最后再与光源的颜色和强度以及材质的漫反射颜色相乘即可得到最终的漫反射光照部分*/

            //漫反射公式:diffuse=(入射光线的颜色和强度*材质的漫反射系数)*saturate(表面法线和光源方向的点积)
          
 fixed3 diffuse = _LightColor0.rgb*_Diffuse.rgb*saturate(dot(worldNormal, worldLight));

            //对环境光和漫反射光部分相加,得到最终光照
          
 o.color = ambient + diffuse;

            return o;
        }

        //片元着色器只需要把顶点颜色输出
      
 fixed4 frag(v2f i) :SV_Target{
            return fixed4(i.color,1.0);
        }

            ENDCG
            
    }
    }
        //把回调函数设置为Diffuse
      
 Fallback"Diffuse"
}


漫反射公式:C diffuse=(C light * M diffuse)max(0, <N*<L)

(入射光线 的颜色和强度 * 材质 的漫反射系数)max(0, 表面法线 *光源方向的点积)

  • dot(A,B)   :返回两值得点积
  • Max(A,B)  :返回两值中较大的
  • normalize(V)  :对向量进行范数归一化或者范围(最大最小)归一化
  • LightMode :是Pass标签的一种, 定义pass在unity的光照流水线中的角色

UNITY_LIGHTMODEL_AMBIENT.xyz :    环境光

UNITY_MATRIX_MVP:  unity内置的 模型*世界*投影矩阵    

_WorldSpaceLightPos0.xyz: 世界空间坐标下的光源   

逐顶点着色器计算在顶点着色器中,顶点着色器的输出是片元着色器的输入


呵呵,两天才搞懂一个简单的漫反射,,,路漫漫啊,八月,新的开始,希望每天都有学习,每天都有进步

2018/8/1

猜你喜欢

转载自blog.csdn.net/ABigDeal/article/details/81334801