Unity Shader入门学习(1):基础shader

这篇博客介绍了Unity Shader的基础知识,包括基础光照shader结合贴图的使用,逐步引入了法线贴图,实现了渐变纹理、高光遮罩和边缘光效果,最后讲解了如何实现透明效果。
摘要由CSDN通过智能技术生成

 1.基础光照shader+贴图

//理解shader代码的最重要一步,就是将渲染流水线的步骤与 代码对应

Shader "01"{//这里指定的路径与名字与文件名名不要求一致

	Properties{//属性
	//格式:属性名(显示出来的属性名,类型)=默认值
		_Color("Color",Color) = (1,1,1,1)//颜色
		_Specular("Specular",Color) = (1,1,1,1)//高光颜色
		_Gloss("Gloss",Range(8.0,256)) = 20//光泽度。(cos角的指数)。一般大于10

		_MainTex("Main Tex",2D)="write"{}//贴图
	}

	SubShader{
	//子属性,可以有多个。用来控制效果。而不同的子属性用来适配不同的显卡 。
	//显卡运行效果时,从第一个subshader开始,若效果都可以实现(由显卡性能决定),则使用第一个subshader,否则自动运行下一个
	//subshader内至少有一个pass块。(pass相当于方法)shader代码就是在pass块里编写的

	Tags {"RenderType" = "Opaque" }
		
		pass {
			Tags{"LightMode" = "ForwardBase"}

			CGPROGRAM                  //Begin

			#pragma vertex vert  
			//顶点函数。这里声明了顶点函数的函数名
			#pragma fragment frag 
			//片元函数。这里声明了片元函数的函数名
			//顶点函数处理顶点,将顶点坐标,从模型空间转换到剪裁空间(处理位置)
			//片元函数处理像素,决定具体像素显示声明(颜色值)

			#include "Lighting.cginc"
		    //取得第一个直射光的颜色_LightColor0 第一个直射光的位置_WorldSpaceLightPos0(即方向)

			fixed4 _Color;
			fixed4 _Specular;
			float _Gloss;
			sampler2D _MainTex;
			float4 _MainTex_ST;//纹理属性。ST意指缩放与平移。此值可以让我们获得纹理的缩放平移值
			//_MainTex_ST.xy存缩放,_MainTex_ST.zw存平移
			//这里声明的变量名不是随意起的。是用  _纹理名_ST 的格式固定声明的。

			struct a2v {
				float4 vertex : POSITION;//语义POSITION指模型空间下的顶点位置
				float3 normal :NORMAL;//语义指模型空间下法线
				float4 texcoord:TEXCOORD0;
			};
			
			struct v2f {
				float4 pos : SV_POSITION;// SV_POSITION指裁剪空间下定点位置。与f.pos = UnityObjectToClipPos(v.vertex);联系
				float3 WorldNormal:TEXCOORD0;
				float3 WorldPos : TEXCOORD1;
				float2 uv:TEXCOORD2;//用于存储纹理坐标
			};

			//顶点函数。如	#pragma vertex vert 所声明
			//顶点shder最重要的工作就是f.pos = UnityObjectToClipPos(v.vertex);即把顶点坐标从模型空间转化到齐次裁剪空间
			v2f vert(a2v v) {
				v2f f;

				f.WorldNormal= UnityObjectToWorldNormal(v.normal);//法线世界化
				//f.WorldNormal = normalize(mul(unity_ObjectToWorld, v.normal));

				f.WorldPos = mul(unity_ObjectToWorld, v.vertex);//点坐标世界化
				//点坐标世界化,是方便通过世界坐标下的点作为一些内置函数的参数,获取光照方向,视线方向等

				f.pos = UnityObjectToClipPos(v.vertex);//点坐标片元化。从模型空间转换到裁剪空间

				f.uv=TRANSFORM_TEX(v.texcoord,_MainTex);
				//f.uv=v.texcoord.xy*_MainTex_ST.xy+_MainTex_ST.zw;
				//_MainTex_ST.xy对纹理进行缩放,_MainTex_ST.zw对纹理偏移

				return f;
			}

			//片元shader主要的功能就是决定片元的颜色。
			//而片元颜色(姑且理解为像素颜色,实际片元是包含像素,深度等信息的集合)又由光照颜色和贴图决定
			//片元包含了比RGBA更多的信息,比如可能有深度值,法线,纹理坐标等等信息。
			fixed4 frag(v2f f) :SV_TARGET0{
			//在frag方法里实现光照就是逐像素光照。相应的,在vert方法里写就是逐顶点光照。

				fixed3 lightDir = normalize(UnityWorldSpaceLightDir(f.WorldPos));
				//单位化光的方向.求光的方向需要知道点的世界坐标,再利用方法UnityWorldSpaceLightDir求得

				fixed3 worldNormal=normalize(f.WorldNormal);
				//单位化法线的方向

				fixed3 albedo =tex2D(_MainTex,f.uv).rgb* _Color.rgb;//albedo是反照率(非镜面),这里指物体本身颜色?
				//tex2D函数负责对纹理进行采样

				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT * albedo;	//ambient是环境光.
				//环境光乘以albedo后才能使背光处(但受环境光)的物体也显示出颜色

				fixed3 diffuse = _LightColor0.rgb * albedo *( dot(worldNormal,lightDir)*0.5+0.5);//半兰伯特光照模型
				//fixed3 diffuse = _LightColor0.rgb * albedo * max(0,dot(f.WorldNormal,lightDir));//兰伯特光照模型
				//取得漫反射颜色:光色*albedo*max(光与法线夹角的cos,0)

				fixed3 viewDir = normalize(UnityWorldSpaceViewDir(f.WorldPos));//单位化视线方向。需要知道点的世界坐标
				fixed3 halfDir = normalize(lightDir + viewDir);//求视线与光线的中间向量(原理想想计算机图形学)
				fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0,dot(worldNormal,halfDir)),_Gloss);//pow方法指取指数。
				//利用Blinn-Phong光照模型取得高光。此模型的核心是取得了视野方向与入射光中向量与法线向量的夹角。如果运用phong模型,则取出射光与视野方向的夹角

				return fixed4(ambient + diffuse + specular , 1);
			}
			ENDCG              //end
		}
	}


	FallBack "Diffuse"//用来指定一个后备方案。
}

  • 13
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值