shader 入门 一 顶点片元shader

Shader"XiaoSen/Last"   // “面板上的名字/shader名字”,第一个名字可以用于分类,如不同平台,不同效果等的区分
{
	//属性可以没有
	Properties
	{
		//变量名   面板显示的名字   类型   默认值
		//_Diffuse("DiffuseColor",Color) = (1,1,1,1)  //颜色
		_Color("MainColor",Color) = (1,1,1,1)
		_MainTexture("Main Tex",2D) = "white"{} //贴图
	    _Specular("SpecularColor",Color) = (1,1,1,1)
		_Gloss("Gloss",Range(10,200)) = 20  //范围值
		_Alpha("Alpha",Range(0,1)) = 1
		_Normalmap("NormalMap",2D) = "bump"{} //法线贴图 不能使用颜色,bump使用模型自带法线  切线空间 所有的计算空间要保持一致
		_BumpScale("BumpScale",Float) = 1//凹凸参数
	}
		//Tags{ "Queue" = "Transparent" "IngnoreProjector" = "True" "RenderType" = "Transparent" }//对所有pass块都起作用  透明渲染队列
		//SubShader至少有一个
		SubShader{
		pass
		{
		    Tags{ "LoghtMode" = "ForwardBase" }//pass 内的只对内部起作用 1,定义光照模式
            Cull off//剔除, off:双面渲染 back: 反面剔除 front :正面剔除 (如面片)
			
            ZWrite Off //深度写模式 是否此物体的像素深度会被记录 默认记录 off:不记录 ,通常用于半透明物体
			Blend SrcAlpha OneMinusSrcAlpha //alpha混合模式 
             Fog{Fog Block}//雾效

			CGPROGRAM //CG程序入口
			//顶点函数  声明一个顶点函数#pragma固定格式
			//顶点坐标是基于模型的中心  
			//吧顶点坐标从模型空间转换到剪裁空间(游戏环境到视野相机屏幕上)
#pragma vertex  vert
			//片元函数  返回模型对应的屏幕上的每一个像素的颜色值
#pragma fragment frag
#include "Lighting.cginc" //引入unity自带类库 2,得到unity内置光照变量 
		
			//变量声明 d名字要对应上方属性变量名
			// fixed4 _Diffuse;
			float _Alpha;//透明度
			fixed4 _Color;
			sampler2D _MainTexture;
			fixed4 _Specular;
			float4 _MainTexture_ST;//获取属性值 名字固定,前边是纹理属性名,后边是固定,前两个值代表tilling。后两个代表offset 
			half _Gloss;
			sampler2D _Normalmap;
			float4 _Normalmap_ST;//
			float _BumpScale;

			//结构体,可作参数使用
			struct a2v {
				float4 vertex:POSITION;//通过语义告诉系统参数是干嘛的比如 POSITION 告诉系统我需要顶点坐标
				//切线空间的确定是通过模型空间的法线和切线确定的 
				float3 normal:NORMAL;//法线 模型空间
				float4 tangent:TANGENT;//切线tangent.w是用来确定切线空间的坐标轴方向的
				float4 textCoord:TEXCOORD0;
			};
			struct v2f {
				float4 svPos:SV_POSITION;//SV_POSITION解释返回值,意思是返回值是裁剪空间下的顶点坐标
				//float3 worldNormal:TEXCOORD0;//文理坐标 
				float3 lightDir:TEXCOORD0;//切线空间下的平行光的方向
				float4 worldVertex:TEXCOORD1;
				float4 uv: TEXCOORD2; //获取顶点的纹理坐标//xy获取顶点的纹理坐标  zw存储法线贴图的文理坐标
			};

			//光照模型:是一个公式 使用它来计算在某个点的光照效果
			//标准光照模型  自发光 高光反射 漫反射  可以放到顶点函数也可以放到片元函数
			//高光反射 = 直射光颜色*pow(max(cos夹角, 0), 高光参数)  夹角:反射光方向和视野方向的夹角 参数一般 >= 10, 值越大高光范围也就越小
			//顶点函数
			v2f vert(a2v v) {
				v2f f;
				f.svPos = UnityObjectToClipPos(v.vertex);//矩阵函数
				//f.worldNormal = UnityObjectToWorldNormal(v.normal);
				f.worldVertex = mul(v.vertex, unity_WorldToObject);
				f.uv.xy = v.textCoord.xy*  _MainTexture_ST.xy + _MainTexture_ST.zw;//*缩放倍数xy--Tiling  +添加offset偏移0-1周期取值
				f.uv.zw = v.textCoord.xy*_Normalmap_ST.xy + _Normalmap_ST.zw;
				TANGENT_SPACE_ROTATION;//返回一个矩阵 rotation,用来把模型空间下的方向转换切线空间下
				fixed3 lightDir = normalize(WorldSpaceLightDir(f.worldVertex));
				// ObjSpaceLightDir(v.vertex);//得到模型空间下的平行光的方向
				f.lightDir = mul(rotation, ObjSpaceLightDir(v.vertex));
				//fixed3 reflectDir = normalize(reflect(-lightDir, normalDir));//反射光的方向
				return f;
			}
		   //片元函数
		   //从法线贴图里面去的的法线方向是在切线空间下的,所以把所以与法线有关的计算放到切线空间内
			fixed4 frag(v2f f) :SV_Target
			{
		    fixed4 normalColor = tex2D(_Normalmap,f.uv.zw);
			//fixed3 tangentNormal = normalColor.xyz * 2 - 1;//自己计算
			fixed3 tangentNormal = UnpackNormal(normalColor);//系统自带的方式
			tangentNormal.xy = tangentNormal.xy * _BumpScale;//

			//fixed3 normalDir = normalize(f.worldNormal);
			fixed3 lightDir = normalize(f.lightDir);
			fixed3 texColor = tex2D(_MainTexture, f.uv.xy)*_Color.rgb;// tex2D获取纹理颜色
		    //半兰伯特模型
			float halfLambert = dot(tangentNormal, lightDir)*0.5 + 0.5;//值域范围0-1
			fixed3 diffuse = _LightColor0.rgb*halfLambert*texColor;//_LightColor0.rgb 取得第一个直射光的颜色 
			//兰伯特模型
			//fixed3 diffuse = _LightColor0.rgb*max(dot(normalDir, lightDir), 0)*_Diffuse.rgb; //取得第一个直射光的颜色 漫反射的颜色 max取最大值 dot 点乘函数 
			
			fixed3 color = diffuse + UNITY_LIGHTMODEL_AMBIENT.rgb*texColor;//将环境光和纹理图进行融合 UNITY_LIGHTMODEL_AMBIENT.rgb:取得系统环境光
			return fixed4(color, _Alpha);
			}
			ENDCG //CG程序结束
	}
	}
		FallBack "VertexLit"  //预备方案
}

这是一个带凹凸,自调色兰伯特光照模型的shader,可以调节透明度等,记录一下最近所学,不妨使用

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值