[UnityShader2]顶点片段着色器实例(一)

主要参考博客:http://blog.csdn.net/mobanchengshuang?viewmode=contents


1.模型自身坐标位置与颜色的映射

Shader "Custom/RGBCube" {  
    SubShader   
    {  
        Pass {  
        CGPROGRAM  
        #pragma vertex vert //顶点着色器入口函数声明  
        #pragma fragment frag // 片段着色器入口函数声明  
        //顶点输出结构体  
        struct vertexOutput {  
            //声明结构体的成员pos,类型为float类型的4元向量,语义为SV_POSITION,col同理;  
            float4 pos : SV_POSITION;  
            float4 col : TEXCOORD0;  
        };  
        //顶点着色器入口函数vert,与pragma第一条声明匹配,返回类型为刚刚定义的顶点输出结构体  
        vertexOutput vert(float4 vertexPos : POSITION)  
          
        {  
            vertexOutput output; //这里不需要struct关键字  
            //顶点着色器将数据写入输出结构体中。  
            output.pos = mul(UNITY_MATRIX_MVP, vertexPos);  
            //mul是顶点变换函数,UNITY_MATRIX_MVP是unity的内建矩阵,vertexPos是这个函数的形参  
            //此行代码的作用为将形参vertexPos(本例即Cube对象的顶点向量)按照unity的内建矩阵进行顶点变换  
            output.col = vertexPos + float4(0.5, 0.5, 0.5, 0.0);  
            //这行代码是实现RGB立方体的关键  
            //因为我们的直角坐标系原点没有在顶点上而是在cube的几何中心,故其值域为{-0,5,-0.5,-0.5,1}至{0.5,0.5,0.5,1}  
            //但是这里接受的类型为float4,可见第四元应该是无意义的常数1  
            //意思是vertexPos的值域为{-0.5,-0.5,-0.5,1}至{0.5,0.5,0.5,1}  
            //而对这个值域进行+{0.5,0.5,0.5,0}的矢量相加才能得到RGB (A恒定为1)的所有颜色区间  
              
            return output;  
            //将输出结构体返回,进入下一个环节(简单理解为给片段着色器)  
            //ps:更细致的环节有顶点变换-->顶点着色-->几何元的构建-->光栅化几何元  
            //-->片段着色-->略  
        }  
        //片段着色器入口函数frag,与pragma第二条声明匹配,返回类型为float4语义为COLOR,  
        //这里除了颜色没有其他的输出,所以没有输出结构体  
        float4 frag(vertexOutput input) : COLOR   
        //此函数的形参类型为顶点着色器的输出结构体,没有语义  
        //原因就在于片段着色器位于顶点着色器的下一个环节,参数按照这个顺序传递  
        {  
            //由于col属性已经在顶点着色器中计算,直接返回进入下一环节  
            //下一环节是什么这里不探讨了  
            return input.col;  
        }  
        ENDCG  
        }  
    }  
    //如果以上SubShader渲染失败则回滚采用Diffuse  
    FallBack "Diffuse"  
}
[UnityShader2]顶点片段着色器实例(一)_第1张图片


2.模型纹理坐标与颜色的映射

Shader "Custom/RGBCube" {  
    SubShader   
    {  
        Pass{
		CGPROGRAM  
		#pragma vertex vert  
		#pragma fragment frag  
		#include "UnityCG.cginc"  
		struct vertexOutput {  
		float4 pos : SV_POSITION;  
		float4 col : TEXCOORD0;  
		};  
		vertexOutput vert(appdata_full input)  
		{  
			vertexOutput output;  
			output.pos = mul(UNITY_MATRIX_MVP, input.vertex);  
			output.col = input.texcoord;  
			return output;  
		}  
		float4 frag(vertexOutput input) : COLOR  
		{  
			return input.col;  
		}  
		ENDCG}   
    }  
    //如果以上SubShader渲染失败则回滚采用Diffuse  
    FallBack "Diffuse"  
}
[UnityShader2]顶点片段着色器实例(一)_第2张图片


3.假彩色效果

Shader "Custom/RGBCube" {  
    SubShader   
    {  
        Pass{
		CGPROGRAM  
		#pragma vertex vert  
		#pragma fragment frag  
		#include "UnityCG.cginc"  
		struct vertexOutput {  
		float4 pos : SV_POSITION;  
		float4 col : TEXCOORD0;  
		};  
		vertexOutput vert(appdata_full input)  
		{  
			vertexOutput output;  
			output.pos = mul(UNITY_MATRIX_MVP, input.vertex);  
			output.col = float4(0.0, input.texcoord.y, 0.0, 1.0);  
			return output;  
		}  
		float4 frag(vertexOutput input) : COLOR  
		{  
			return input.col;  
		}  
		ENDCG}   
    }  
    //如果以上SubShader渲染失败则回滚采用Diffuse  
    FallBack "Diffuse"  
}
[UnityShader2]顶点片段着色器实例(一)_第3张图片


4.法向量与颜色的映射

Shader "Custom/RGBCube" {  
    SubShader   
    {  
        Pass{
		CGPROGRAM  
		#pragma vertex vert  
		#pragma fragment frag  
		#include "UnityCG.cginc"  
		struct vertexOutput {  
		float4 pos : SV_POSITION;  
		float4 col : TEXCOORD0;  
		};  
		vertexOutput vert(appdata_full input)  
		{  
			vertexOutput output;  
			output.pos = mul(UNITY_MATRIX_MVP, input.vertex);  
			output.col = float4((input.normal + float3(1.0, 1.0, 1.0)) / 2.0, 1.0); 
			return output;  
		}  
		float4 frag(vertexOutput input) : COLOR  
		{  
			return input.col;  
		}  
		ENDCG}   
    }  
    //如果以上SubShader渲染失败则回滚采用Diffuse  
    FallBack "Diffuse"  
}

[UnityShader2]顶点片段着色器实例(一)_第4张图片


5.裁剪效果

Shader "Custom/RGBCube" {  
    SubShader   
    {  
        Pass{  
        Cull Off // 关掉裁剪模式,作用后面再说  
        CGPROGRAM  
        #pragma vertex vert  
        #pragma fragment frag  
        #include "UnityCG.cginc"  
        struct vertexOutput {  
            float4 pos : SV_POSITION;  
            //由顶点着色器输出mesh信息中的纹理坐标,这个坐标是以对象为坐标系的  
            float4 posInObjectCoords : TEXCOORD0;  
        };  
        vertexOutput vert(appdata_full input)  
        {  
            vertexOutput output;  
            output.pos = mul(UNITY_MATRIX_MVP, input.vertex);  
            //直接把texcoord传递给片段着色器  
            output.posInObjectCoords = input.texcoord;  
            return output;  
        }  
        float4 frag(vertexOutput input) : COLOR  
        {  
            //当坐标的y值大于0.5的时候擦除片段  
            if (input.posInObjectCoords.y > 0.5)  
            {  
                discard;   
            }  
              
            //其余部分仍然按y值大小生成经度绿色球  
            return float4(0.0, input.posInObjectCoords.y , 0.0, 1.0);   
        }  
        ENDCG  
        }  
    }  
    //如果以上SubShader渲染失败则回滚采用Diffuse  
    FallBack "Diffuse"  
}
[UnityShader2]顶点片段着色器实例(一)_第5张图片


6.内部裁剪与外部裁剪

Shader "Custom/RGBCube" {  
    SubShader   
    {  
        Pass{  
        Cull front // 外部剪裁,那么这个通道可以理解为是给篮球的内表面上色  
        CGPROGRAM  
        #pragma vertex vert  
        #pragma fragment frag  
        #include "UnityCG.cginc"  
        struct vertexOutput {  
            float4 pos : SV_POSITION;  
            //由顶点着色器输出mesh信息中的纹理坐标,这个坐标是以对象为坐标系的  
            float4 posInObjectCoords : TEXCOORD0;  
        };  
        vertexOutput vert(appdata_full input)  
        {  
            vertexOutput output;  
            output.pos = mul(UNITY_MATRIX_MVP, input.vertex);  
            //直接把texcoord传递给片段着色器  
            output.posInObjectCoords = input.texcoord;  
            return output;  
        }  
        float4 frag(vertexOutput input) : COLOR  
        {  
            //当坐标的y值大于0.5的时候擦除片段  
            if (input.posInObjectCoords.y > 0.5)  
            {  
                discard;   
            }  
              
            //其余部分仍然按y值大小生成经度绿色球  
            return float4(0.0, input.posInObjectCoords.y , 0.0, 1.0);   
        }  
        ENDCG  
        }   
          
        Pass{  
        Cull back //内部剪裁,那么这个通道可以理解为是给篮球的外表面上色  
        CGPROGRAM  
        #pragma vertex vert  
        #pragma fragment frag  
        #include "UnityCG.cginc"  
        struct vertexOutput {  
            float4 pos : SV_POSITION;  
            //由顶点着色器输出mesh信息中的纹理坐标,这个坐标是以对象为坐标系的  
            float4 posInObjectCoords : TEXCOORD0;  
        };  
        vertexOutput vert(appdata_full input)  
        {  
            vertexOutput output;  
            output.pos = mul(UNITY_MATRIX_MVP, input.vertex);  
            //直接把texcoord传递给片段着色器  
            output.posInObjectCoords = input.texcoord;  
            return output;  
        }  
        float4 frag(vertexOutput input) : COLOR  
        {  
            //当坐标的y值大于0.5的时候擦除片段  
            if (input.posInObjectCoords.y > 0.5)  
            {  
                discard;   
            }  
              
            //其余部分仍然按y值大小生成经度红色球  
            return float4(input.posInObjectCoords.y, 0.0 , 0.0, 1.0);   
        }  
        ENDCG  
        }   
    }  
    //如果以上SubShader渲染失败则回滚采用Diffuse  
    FallBack "Diffuse"  
}
[UnityShader2]顶点片段着色器实例(一)_第6张图片


7.圆角矩形

Shader "Custom/RoundRect" {  
    Properties {  
        //两种内容模式,图片模式  
        _MainTex ("Base (RGB)", 2D) = "white" {}  
        //纯色模式  
        //_MainColor ("Color", COLOR) = (1,1,1,1)  
        //圆角半径,默认为0.1  
        _Radius("Radius",float) = 0.1  
    }  
    SubShader {  
          
        Pass{  
            CGPROGRAM  
			#pragma vertex vert 
            #pragma fragment frag  
             
            #include "UnityCG.cginc"  
            //获取3个属性 并传值到CG代码段  
            sampler2D _MainTex;  
			float _Radius;
            float4 _MainColor;  
              
			struct vertexOutput {
				float4 pos : SV_POSITION;
				//由顶点着色器输出mesh信息中的纹理坐标,这个坐标是以对象为坐标系的  
				float4 posInObjectCoords : TEXCOORD0;
			};
			vertexOutput vert(appdata_full input)
			{
				vertexOutput output;
				output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
				//直接把texcoord传递给片段着色器  
				output.posInObjectCoords = input.texcoord;
				return output;
			}
  
            //片段着色器入口函数  
			float4 frag(vertexOutput input) : COLOR
            {          
				float4 c = tex2D(_MainTex, input.posInObjectCoords);//将图片信息按坐标转换成颜色  
                //float4 c=_MainColor;  //纯色  
                  
                //x,y两个变元,区间均为[0,1]  
				float x = input.posInObjectCoords.x;
				float y = input.posInObjectCoords.y;
                  
				if (x < _Radius && y < _Radius)
				{
					if (pow((x - _Radius), 2) + pow(y - _Radius, 2) > pow(_Radius, 2))
						discard;
				}
				else if (x < _Radius && y > (1 - _Radius))
				{
					if (pow((x - _Radius), 2) + pow(y - (1 - _Radius), 2) > pow(_Radius, 2))
						discard;
				}
				else if (x > (1 - _Radius) && y < _Radius)
				{
					if (pow((x - (1 - _Radius)), 2) + pow(y - _Radius, 2) > pow(_Radius, 2))
						discard;
				}
				else if (x > (1 - _Radius) && y > (1 - _Radius))
				{
					if (pow((x - (1 - _Radius)), 2) + pow(y - (1 - _Radius), 2) > pow(_Radius, 2))
						discard;
				}
                return c;  
            }  
            ENDCG
		}  
    }   
    FallBack "Diffuse"  
}
[UnityShader2]顶点片段着色器实例(一)_第7张图片


8.漫反射

Shader "Esfog/Diffuse" 
{
    Properties 
    {
        _MainTex ("Base (RGB)", 2D) = "white" {}
    }
    SubShader 
    {
        Pass
        {
            Tags { "RenderType"="Opaque" "LightMode"="ForwardBase"}
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            uniform sampler2D _MainTex;
            uniform float4    _LightColor0;
            struct VertexOutput 
            {
                float4 pos:SV_POSITION;
                float2 uv_MainTex:TEXCOORD0;
                float3 normal:TEXCOORD1;
            };

            VertexOutput vert(appdata_base input)
            {
                VertexOutput o;
                o.pos = mul(UNITY_MATRIX_MVP,input.vertex);
                o.uv_MainTex = input.texcoord.xy;
                o.normal = normalize(mul(float4(input.normal,0),_World2Object));
                return o;
            }

            float4 frag(VertexOutput input):COLOR
            {
                float3 normalDir = normalize(input.normal);
                float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
                float3 Kd = tex2D(_MainTex,input.uv_MainTex).xyz;
                float3 diffuseReflection = Kd * _LightColor0.rgb * max(0,dot(normalDir,lightDir));
                return float4(diffuseReflection,1);
            }
            ENDCG
        }
    } 
    FallBack "Diffuse"
}
[UnityShader2]顶点片段着色器实例(一)_第8张图片


9.多光源漫反射

Shader "Esfog/Diffuse" 
{
    Properties 
    {
        _MainTex ("Base (RGB)", 2D) = "white" {}
    }
    SubShader 
    {
        Pass
        {
            Tags { "RenderType"="Opaque" "LightMode"="ForwardBase"}
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            uniform sampler2D _MainTex;
            uniform float4    _LightColor0;
            struct VertexOutput 
            {
                float4 pos:SV_POSITION;
                float2 uv_MainTex:TEXCOORD0;
                float3 normal:TEXCOORD1;
            };

            VertexOutput vert(appdata_base input)
            {
                VertexOutput o;
                o.pos = mul(UNITY_MATRIX_MVP,input.vertex);
                o.uv_MainTex = input.texcoord.xy;
                o.normal = normalize(mul(float4(input.normal,0),_World2Object));
                return o;
            }

            float4 frag(VertexOutput input):COLOR
            {
                float3 normalDir = normalize(input.normal);
                float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
                float3 Kd = tex2D(_MainTex,input.uv_MainTex).xyz;
                float3 diffuseReflection = Kd * _LightColor0.rgb * max(0,dot(normalDir,lightDir));
                return float4(diffuseReflection,1);
            }
            ENDCG
        }

		Pass
        {
            Tags { "RenderType"="Opaque" "LightMode"="ForwardAdd"}

			//此通道的片段着色器输出颜色时帧缓存已经有了颜色,所以需要混合  
			//混合模式为1比1          
			Blend One One 

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            uniform sampler2D _MainTex;
            uniform float4    _LightColor0;
            struct VertexOutput 
            {
                float4 pos:SV_POSITION;
                float2 uv_MainTex:TEXCOORD0;
                float3 normal:TEXCOORD1;
            };

            VertexOutput vert(appdata_base input)
            {
                VertexOutput o;
                o.pos = mul(UNITY_MATRIX_MVP,input.vertex);
                o.uv_MainTex = input.texcoord.xy;
                o.normal = normalize(mul(float4(input.normal,0),_World2Object));
                return o;
            }

            float4 frag(VertexOutput input):COLOR
            {
                float3 normalDir = normalize(input.normal);
                float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
                float3 Kd = tex2D(_MainTex,input.uv_MainTex).xyz;
                float3 diffuseReflection = Kd * _LightColor0.rgb * max(0,dot(normalDir,lightDir));
                return float4(diffuseReflection,1);
            }
            ENDCG
        }
    } 
    FallBack "Diffuse"
}
[UnityShader2]顶点片段着色器实例(一)_第9张图片


10.逐顶点的镜面反射



你可能感兴趣的:(shader)