Unity Shader基础的使用 基础、法线贴图及光照模型代码的注释

版本:unity 5.3.4  语言:C#

 

这边主要参考了猫也能学会Shader的文章。

 

话说之前是不是说暂时不研究Shader?没事哈,不要在意那么多细节,要的就是莽,疯狂加点就行了。

 

这边主要是把猫大写的Shader仔细注释了一下,以便以后查阅,暂时不系统的学习Shader。

 

Shader其实相当于一个后期的处理,在已经有的模型上加个特效什么的,让它的显示更加炫酷,Shader也算是学习Unity的一个重中之重。

 

下面发一下代码(主要做备忘用,不太了解的玩家可以参考一下猫大的文章):

//一个基础的Shader
Shader "Custom/Diffuse Texture" {
	Properties {
		/*
		 类型:
		 Color 一种颜色
		 2D 2的阶数大小的贴图
		 Rect 非2阶数大小的贴图
		 Cube 立方体纹理
		 Range(min, max) 介于最小值最大值的浮点数
		 Float 任意一个浮点数
		 Vector 一个四维数
		 */
		_Color ("Color", Color) = (0,0,0,1)	//一种颜色
		_MainTex ("Albedo (RGB)", 2D) = "white" {}	//2阶数大小的贴图
		_Glossiness ("Smoothness", Range(0,1)) = 0.5	//浮点数
		_Metallic ("Metallic", Range(0,1)) = 0.0	//浮点数
	}
	SubShader {
		/*
		 重要的Tags:
		 "RenderType"="Transparent" 透明、半透明像素渲染
		 "ForceNoShadowCasting"="True" 从不产生阴影
		 "Queue"="xxx" 渲染顺序队列,主要参数:
				"Backgroung" 最早调用,用来渲染天空盒或者背景 1000
				"Geometry" 渲染非透明物体,默认值 2000
				"AlphaText" 用来渲染经过Alpha Test的像素(这个不太理解) 2450
				"Transparent" 从后往前的顺序渲染透明物体 3000
				"Overlay" 渲染叠加效果,渲染的最后阶段,镜头光晕之类 4000
		*/
		Tags { "RenderType"="Opaque" }	//渲染非透明物时执行
		LOD 200	//Level of Detail,该值不能小于unity中设定的值,我的工程中该值为0,而且最高只能设置为7(不是很明白)
		
		CGPROGRAM	//脚本开始,这边用的是Cg/HLSL语言,主要用于Dx的程序,如果是运行在OpenGL上的程序,unity会转化为GLSL语言,或者可以选择直接写GLSL语言的Shader,但显然使用Cg\HLSL有更好的移植性
		
		// surface表明是一个表面着色器,surf 代码名称,Standard 光照模型
		#pragma surface surf Standard fullforwardshadows

		// Shader模型的版本为3.0
		#pragma target 3.0

		sampler2D _MainTex;	//需要处理的贴图放在这里,注意这里的_MainTex是前面声明过的属性

		struct Input {
			float2 uv_MainTex;	//算是一个长度为2的float数组,uv前缀表示贴图上点的二维坐标
		};

		half _Glossiness;
		half _Metallic;
		fixed4 _Color;

		/*
		 SurfaceOutputStandard的结构(教程中的是SurfaceOutput,这边应该是U5的新特性吧)
		 struct SurfaceOutputStandard
		 {
			fixed3 Albedo;	//漫反射颜色
			fixed3 Normal;	//切线空间法线
			half3 Emission;	//自发光
			half Metallic;	//金属度,0为非金属,1为金属
			half Smoothness;	//光泽度,0为非常粗糙,1为非常光滑
			half Occlusion;	//遮挡(默认1)
			fixed Alpha;	//透明度
		 }
		 SurfaceOutput中是Specular镜面高光、Gloss发光强度代替了Metallic、Smoothness、Occlusion
		
		*/

		// 主处理函数,输入输出必须按规定写
		void surf (Input IN, inout SurfaceOutputStandard o) {
			// 对一个点进行采样
			fixed4 c = tex2D(_MainTex, IN.uv_MainTex); //* _Color;
			o.Albedo = c.rgb;
			o.Metallic = _Metallic;
			o.Smoothness = _Glossiness;
			o.Alpha = c.a;
		}
		ENDCG	//脚本结束
	}
	FallBack "Diffuse"
}

//一个带法线贴图、光照模型的Shader
Shader "Custom/Normal Mapping" {
	Properties {
		_MainTex ("Base (RGB)", 2D) = "white" {}	//原本的贴图
		_Bump("Bump", 2D) = "bump"{}	//法线贴图
		_Snow("Snow Level", Range(0, 1)) = 0	//雪等级
		_SnowColor("Snow Color", Color) = (1.0, 1.0, 1.0, 1.0)	//雪颜色
		_SnowDirection("Snow Direction", Vector) = (0, 1, 0)	//雪的方向
		_SnowDepth("Snow Depth", Range(0, 0.3)) = 0.1	//雪的深度
	}
	SubShader {

		Tags { "RenderType"="Opaque" }
		LOD 200
		
		CGPROGRAM
		
		#pragma surface surf CustomDiffuse vertex:vert	//vertex:vert表明我们会改变顶点,并且会使用vert函数来做处理

		// 定义自己的光照模型
		//#pragma surface surf CustomDiffuse
		/*
		 参数:SurfaceOutput 经过表面计算后的输入;lightDir 光线方向;atten 光衰减系数
		*/
		half4 LightingCustomDiffuse(SurfaceOutput s, half3 lightDir, half atten) {
			half difLight = max(0, dot(s.Normal, lightDir));	//点积调整当前点的亮度
			difLight = difLight * 0.5 + 0.5;	//低光下增亮效果(半条命),范围从0-1到0.5-1
			half4 col;
			col.rgb = s.Albedo * _LightColor0.rgb * (difLight * atten * 2);	//根据物体的颜色、光颜色、光亮度、衰减度计算当前点的颜色,2是历史问题,U5中已经移除,但我们这边还保留着
			col.a = s.Alpha;
			return col;
		}

		sampler2D _MainTex;
		sampler2D _Bump;
		float _Snow;
		float4 _SnowColor;
		float4 _SnowDirection;
		float _SnowDepth;

		struct Input {
			float2 uv_MainTex;
			float2 uv_Bump;
			float3 worldNormal; INTERNAL_DATA	//当前点在世界中的法线值
		};

		void vert(inout appdata_full v)
		{
			float4 sn = mul(transpose(_Object2World), _SnowDirection);	//把积雪方向的矩阵转换到世界矩阵
			if (dot(v.normal, sn.xyz) >= lerp(1, -1, (_Snow * 2) / 3))
			{
				v.vertex.xyz += (sn.xyz + v.normal) * _SnowDepth * _Snow;
			}
		}

		void surf (Input IN, inout SurfaceOutput o) {	//使用自己的光照模型时,参数为SurfaceOutput,而不是SurfaceOutputStandard
			half4 c = tex2D(_MainTex, IN.uv_MainTex);
			o.Normal = UnpackNormal(tex2D(_Bump, IN.uv_Bump));

			// 世界中的法线方与垂直方向做点积,计算出1到-1的值,如果大于雪的阈值,则显示白色
			if (dot(WorldNormalVector(IN, o.Normal), _SnowDirection.xyz) > lerp(1, -1, _Snow))
			{
				o.Albedo = _SnowColor.rgb;
			}
			else
			{
				o.Albedo = c.rgb;
			}

			o.Alpha = c.a;
		}
		ENDCG
	}
	FallBack "Diffuse"
}

 

基本上来说,跟猫大那时候的版本差不多,不过注意的是Unity5.0时代基础创建的Shader使用的是Standard的一个光照模型,所以这边要注意一下,我在代码中也有标明。

你可能感兴趣的:(Unity起航)