Unity3D — Shader 表面着色器 Surface Shader

文章目录

  • 基本数据类型
    • 代码示例
    • 法线贴图示例代码
    • 边缘发光示例代码

基本数据类型

float:32位浮点数
half:16位浮点数
int:32位整形
fixed:12位定点数,取值范围0-1之间的⼩数,或整数
bool:就。。。布尔型
string:字符串
以上的所有数据类型都可以加上2~4,类似vector2、vector3那种形式例如:

  • float2 pos = float2(0.3,0.5);//相当与Unity Vector2 xy
  • float3 vector3 = float3(1,1,1);//相当与Unity Vector3 xyz
  • float4 vector4 = float4(0,0,1,1);//相当与Unity Vector4 xyzw

sampler2D:纹理对象

代码示例

Shader "zhongdudu/six"
{
    Properties
    {
    	_DiffuseColor("漫反射颜色",Color)=(1,0,0,1)
    	_MainTex("纹理图片",2D)=""{}
    }
    
    //表面着色器中不需要添加Pass通道
    SubShader
    {
        
        CGPROGRAM //------CG语言的开始-----------
        //编译指令 surface:表面着色器 surf:自己取的函数名称,必须要定义  (光照模型模板)Lambert:漫反射                     
                                     // 加上alpha就可以支持设置alpha值了
        #pragma surface surf Lambert //alpha
        
		//声明属性变量
        fixed4 _DiffuseColor;
        sampler2D _MainTex; //纹理对象
		
		//Input结构体需要我们自己定义才可以使用
		struct Input
        {
        	//定义图片的uv坐标 命名格式 uv+属性名称如本示例的 _MainTex
            fixed2 uv_MainTex;
            //定义输入颜色
            float4 color:COLOR; //(语义绑定)
            
        };//别忘了加分号
        
        //表面着色器函数 Input输入 inout输出  SurfaceOutput结构体  IN 和 O是形参
        void surf(Input IN,inout SurfaceOutput o)
        {
            //设置输出RGB,只要是对于或等于3个值的表达就可以 比如float4 half3
            //或者使用_DiffuseColor.rgb/gba等等
            //Albedo half3类型 颜⾊纹理rgb
            //o.Albedo = float3(1,1,0);
            //o.Alpha = _DiffuseColor.a; 输出alpha
            
			//tex2D 通过uv查找贴图纹理的当前顶点颜⾊值,第一个参数是图片,第二个参数是这个图片的uv坐标
            //通过uv坐标查找纹理图片所对应的颜色值,赋给albedo
            o.Albedo = tex2D(_MainTex,IN.uv_MainTex).rgb;
            //叠加颜色值
            o.Albedo *= _DiffuseColor.rgb * 2;
            //o.Alpha = _DiffuseColor.a;
        }

        float number = 10;
        float2 pos = float2(0.3,0.5);//相当与Unity Vector2 xy
        float3 vector3 = float3(1,1,1);//相当与Unity Vector3 xyz
        float4 vector4 = float4(0,0,1,1);//相当与Unity Vector4 xyzw
        
        half2 h2 = half2(1,1);
        half3 h3 = half3(1,1,3);
        
        fixed a = 0.1;
        fixed3 color = fixed3(1,1,1);
        
        bool2 bl2 = bool2(false,true);
        //纹理
        sampler2D tex;

                
        ENDCG //----------CG语言的结束-----------
        
    }
}

法线贴图示例代码

Shader "zhongdudu/seven"
{
    Properties
    {
        _MainTex("纹理图片",2D)=""{}
        _BumpMap("法线贴图",2D)=""{}
        _MainCol("颜色",Color)=(1,1,1,1)
    }
    
    //表面着色器中不需要添加Pass通道
    SubShader
    {
        CGPROGRAM //------CG语言的开始-----------
        
        //编译指令 着色器名称 函数名称 光照模型
        #pragma surface surf Lambert
        
        //声明属性变量
        sampler2D _MainTex;
        sampler2D _BumpMap;
        
        fixed4 _MainCol;
        
        struct Input
        {
            //定义纹理图片的uv坐标
            fixed2 uv_MainTex;
            //定义法线贴图的uv坐标
            fixed2 uv_BumpMap;
            
        };//别忘了加分号
        
        //表面着色器函数
        void surf(Input IN,inout SurfaceOutput o)
        {
            //通过uv坐标查找纹理图片所对应的颜色值,赋给albedo
            o.Albedo = tex2D(_MainTex,IN.uv_MainTex).rgb;
            o.Albedo += _MainCol.rgb;
            //通过法线贴图的uv坐标查找法线贴图所对应的颜色值,修正之后赋给Normal  
            //UnpackNormal 返回对应的法线
            //Normal half3类型 法线,法向量(x,y,z)
            o.Normal = UnpackNormal(tex2D(_BumpMap,IN.uv_BumpMap));
        }
        
        ENDCG //----------CG语言的结束-----------
        
    }
}

边缘发光示例代码

Shader "zhongdudu/eight"
{
    Properties
    {
        _MainTex("纹理图片",2D)=""{}
        _BumpMap("法线贴图",2D)=""{}
        _MainCol("颜色",Color)=(1,1,1,1)
        _RimCol("发光颜色",Color)=(1,1,1,1)
        _Rim("发光强度",Range(0,10))=0.5
    }
    
    //表面着色器中不需要添加Pass通道
    SubShader
    {
        CGPROGRAM //------CG语言的开始-----------
        
        //编译指令 着色器名称 函数名称 光照模型
        #pragma surface surf Lambert
        
        //声明属性变量
        sampler2D _MainTex;
        sampler2D _BumpMap;
        fixed4 _RimCol;
        fixed4 _MainCol;
        half _Rim;
        
        struct Input
        {
            //定义纹理图片的uv坐标
            fixed2 uv_MainTex;
            //定义法线贴图的uv坐标
            fixed2 uv_BumpMap;
            //视图方向【顶点指向观察者的方向向量】
            //viewDir 视图⽅向 half3类型 除此还有:
            //half3类型 worldPos 世界坐标位置  half4类型 screenPos 屏幕空间位置(x,y,z,w)
            //half类型 镜⾯反射度 Specular 、光泽度 Gloss 、透明度 Alpha
            half3 viewDir;
            
        };//别忘了加分号
        
        //表面着色器函数
        void surf(Input IN,inout SurfaceOutput o)
        {
            //通过uv坐标查找纹理图片所对应的颜色值,赋给albedo
            o.Albedo = tex2D(_MainTex,IN.uv_MainTex).rgb;
            //添加法线贴图
            o.Normal = UnpackNormal(tex2D(_BumpMap,IN.uv_BumpMap));
            //求发光系数 对两个向量进行点乘
            //saturate 限制值函数(0,1)
            half rimPower = 1-saturate(dot(normalize(IN.viewDir),normalize(o.Normal)));
            //通过发光系数进行自发光【通过次方方式】
            //Emission half3类型 ⾃发光颜⾊rgb
            o.Emission = _RimCol * pow(rimPower,_Rim);
            //通过发光系数进行自发光【通过相乘方式】
            //o.Emission = _RimCol * rimPower * _Rim;
        }
        
        ENDCG //----------CG语言的结束-----------
        
    }
}

你可能感兴趣的:(Unity基础知识,unity,shader)