UnityShader学习笔记 基础纹理

单张纹理

Shader "Custom/SingleTexture" 
{
	Properties 
	{
		_Color("Color Tint" , Color) = (1,1,1,1)
		_MainTex("Main Tex",2D) = "white" { }
		_Specular("Specular" , Color) = (1,1,1,1)
		_Gloss("Gloss" , Range(8.0,256)) = 20
	}
	SubShader 
	{
		Pass
		{
			Tags { "LightMode" = "ForwardBase" }

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

			fixed4 _Color;
			sampler2D _MainTex;
			fixed4 _MainTex_ST;
			fixed4 _Specular;
			float _Gloss;

			struct a2v
			{
				float4 vertex : POSITION;
				float3 normal : NORMAL;
				float4 texcoord : TEXCOORD0; 
			};
			struct v2f
			{
				float4 pos : SV_POSITION;
				float3 worldNormal : TEXCOORD0;
				float3 worldPos : TEXCOORD1;
				float2 uv : TEXCOORD2;
			};

			v2f vert(a2v v)
			{
				v2f o;

				o.pos = UnityObjectToClipPos( v.vertex);
				o.worldNormal = UnityObjectToWorldNormal(v.normal);
				o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
				//o.uv = v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;
				o.uv = TRANSFORM_TEX(v.texcoord , _MainTex);
				return o;
			}

			fixed4 frag(v2f i) : SV_Target
			{
				fixed3 worldNormal = normalize(i.worldNormal);
				fixed3 worldLightDir = normalize( UnityWorldSpaceLightDir(i.worldPos));

				fixed3 albedo = tex2D(_MainTex, i.uv).rgb * _Color.rgb;
				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;

				fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(worldNormal, worldLightDir));
				
				fixed3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));
				fixed3 halfDir = normalize(worldLightDir + viewDir);
				fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0 , dot(worldNormal , halfDir)), _Gloss);
				
				return fixed4(ambient + diffuse + specular , 1.0);
			}
			ENDCG
		}
	}
	FallBack "Diffuse"
}

与其他属性不同的是,如果为纹理类型的属性声明了一个sampler2D 类型的变量,那么还需要额外声明一个float4类型的变量且名字必须为纹理名_ST

在进行顶点变换时,有两种方式:

//o.uv = v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;
o.uv = TRANSFORM_TEX(v.texcoord , _MainTex);

两个参数分别为顶点纹理坐标和纹理名

 

纹理属性的相关知识:

 

 

凹凸映射

凹凸映射的两种主要方法:高度映射和法线纹理

高度纹理:

高度图:存储模型表面凹凸程度的图,颜色越浅该位置的表面越向外凸起,颜色越深该位置的表面越向里凹

法线纹理:

法线纹理中存储的是表面的法线方向,但是由于法线方向的分量范围是[-1, 1] ,而像素的分量范围是[0, 1],那么需要做一个映射,

同时,做完纹理采样后,需要做一次反向得映射,得到原先得法线方向

法线纹理中存储的法线的方向的坐标空间有两种:模型空间的法线纹理和切线空间的法线纹理

两种纹理方式得使用得优点:

 

在切线空间下计算:

Shader "Custom/NormalMapTangentSpace" 
{
	Properties 
	{
		_Color("Color Tint" , Color) = (1,1,1,1)
		_MainTex("Main Tex",2D) = "white" { }
		_BumpMap("Normal Map" , 2D) = "bump" {}
		_BumpScale("Bump Scale", Float) = 1.0
		_Specular("Specular" , Color) = (1,1,1,1)
		_Gloss("Gloss" , Range(8.0,256)) = 20
	}
	SubShader 
	{
		Pass
		{
			Tags { "LightMode" = "ForwardBase" }

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

			fixed4 _Color;
			sampler2D _MainTex;
			float4 _MainTex_ST;
			
			sampler2D _BumpMap;
			float4 _BumpMap_ST;
			float _BumpScale;

			fixed4 _Specular;
			float _Gloss;

			struct a2v
			{
				float4 vertex : POSITION;
				float3 normal : NORMAL;
				float4 tangent : TANGENT; 
				float4 texcoord : TEXCOORD0;
			};
			struct v2f
			{
				float4 pos : SV_POSITION;
				float4 uv : TEXCOORD0;
				float3 lightDir : TEXCOORD1;
				float3 viewDir : TEXCOORD2;			
			};

			v2f vert(a2v v)
			{
				v2f o;

				o.pos = UnityObjectToClipPos( v.vertex);
				o.uv.xy = v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;
				o.uv.zw = v.texcoord.xy * _BumpMap_ST.xy + _BumpMap_ST.zw;

				float3 binormal = cross(normalize(v.normal),normalize(v.tangent.xyz))*v.tangent.w;
				float3x3 rotation = float3x3(v.tangent.xyz,binormal,v.normal);

				//TANGENT_SPACE_ROTATION;

				o.lightDir = mul(rotation , ObjSpaceLightDir(v.vertex)).xyz;
				o.viewDir = mul(rotation , ObjSpaceViewDir(v.vertex)).xyz;
				return o;
			}

			fixed4 frag(v2f i) : SV_Target
			{
				fixed3 tangentLightDir = normalize(i.lightDir);
				fixed3 tangentViewDir = normalize( i.viewDir);

				fixed4 packedNormal = tex2D(_BumpMap , i.uv.zw);
				fixed3 tangentNormal;

				tangentNormal = UnpackNormal(packedNormal);
				tangentNormal.xy*=_BumpScale;
				tangentNormal.z = sqrt(1.0-saturate(dot(tangentNormal.xy,tangentNormal.xy)));

				fixed3 albedo = tex2D(_MainTex, i.uv).rgb * _Color.rgb;
				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;

				fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(tangentNormal, tangentLightDir));
				
				fixed3 halfDir = normalize(tangentLightDir + tangentViewDir);
				fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0 , dot(tangentNormal , halfDir)), _Gloss);
				
				return fixed4(ambient + diffuse + specular , 1.0);
			}
			ENDCG
		}
	}
	FallBack "Diffuse"
}

 

 

在世界空间下计算:

Shader "Custom/NormalMapWorldSpace" 
{
	Properties 
	{
		_Color("Color Tint" , Color) = (1,1,1,1)
		_MainTex("Main Tex",2D) = "white" { }
		_BumpMap("Normal Map" , 2D) = "bump" {}
		_BumpScale("Bump Scale", Float) = 1.0
		_Specular("Specular" , Color) = (1,1,1,1)
		_Gloss("Gloss" , Range(8.0,256)) = 20
	}
	SubShader 
	{
		Pass
		{
			Tags { "LightMode" = "ForwardBase" }

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

			fixed4 _Color;
			sampler2D _MainTex;
			float4 _MainTex_ST;
			
			sampler2D _BumpMap;
			float4 _BumpMap_ST;
			float _BumpScale;

			fixed4 _Specular;
			float _Gloss;

			struct a2v
			{
				float4 vertex : POSITION;
				float3 normal : NORMAL;
				float4 tangent : TANGENT; 
				float4 texcoord : TEXCOORD0;
			};
			struct v2f
			{
				float4 pos : SV_POSITION;
				float4 uv : TEXCOORD0;
				float4 TtoW0 : TEXCOORD1;
				float4 TtoW1 : TEXCOORD2;
				float4 TtoW2 : TEXCOORD3;				
			};

			v2f vert(a2v v)
			{
				v2f o;

				o.pos = UnityObjectToClipPos( v.vertex);
				o.uv.xy = v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;
				o.uv.zw = v.texcoord.xy * _BumpMap_ST.xy + _BumpMap_ST.zw;

				float3 worldPos = mul(unity_ObjectToWorld , v.vertex).xyz;
				float3 worldNormal = UnityObjectToWorldNormal(v.normal);
				float3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz);
				float3 worldBinormal = cross(worldNormal , worldTangent) * v.tangent.w;
				
				o.TtoW0 = float4(worldTangent.x,worldBinormal.x,worldNormal.x,worldPos.x);
				o.TtoW1 = float4(worldTangent.y,worldBinormal.y,worldNormal.y,worldPos.y);
				o.TtoW2 = float4(worldTangent.z,worldBinormal.z,worldNormal.z,worldPos.z);

				return o;
			}

			fixed4 frag(v2f i) : SV_Target
			{
				float3 worldPos = float3(i.TtoW0.w,i.TtoW1.w,i.TtoW2.w);
				fixed3 lightDir = normalize(UnityWorldSpaceLightDir(worldPos));
				fixed3 viewDir = normalize(UnityWorldSpaceViewDir(worldPos));

				fixed3 bump = UnpackNormal (tex2D(_BumpMap , i.uv.zw));
				bump.xy *= _BumpScale;
				bump.z = sqrt(1.0 - saturate(dot(bump.xy , bump.xy)));
				bump = normalize (half3(dot(i.TtoW0.xyz ,  bump) ,dot(i.TtoW1.xyz , bump) ,dot(i.TtoW2.xyz , bump)));

				fixed3 albedo = tex2D(_MainTex, i.uv).rgb * _Color.rgb;
				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;

				fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(bump, lightDir));
				
				fixed3 halfDir = normalize(lightDir + viewDir);
				fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0 , dot(bump , halfDir)), _Gloss);
				
				return fixed4(ambient + diffuse + specular , 1.0);
			}
			ENDCG
		}
	}
	FallBack "Diffuse"
}

 

渐变纹理

Shader "Custom/Ramp" 
{
	Properties 
	{
		_Color ("Color Tint", Color) = (1,1,1,1)
		_RampTex ("RampTex", 2D) = "white" {}
		_Specular ("Specular", Color) = (1,1,1,1)
		_Gloss ("Gloss", Range(8.0,256)) = 20
	}
	SubShader 
	{
		Pass
		{
			Tags { "LightMode" = "ForwardBase" }
			CGPROGRAM

			#pragma vertex vert
			#pragma fragment frag

			#include "Lighting.cginc"

			fixed4 _Color;
			sampler2D _RampTex;
			float4 _RampTex_ST;
			fixed4 _Specular;
			float _Gloss;

			struct a2f
			{
				float4 vertex : POSITION;
				float3 normal : NORMAL;
				float4 texcoord : TEXCOORD0;
			};

			struct v2f
			{
				float4 pos : SV_POSITION;
				float3 worldNormal : TEXCOORD0;
				float3 worldPos : TEXCOORD1;
				float2 uv : TEXCOORD2;
			};

			v2f vert(a2f v)
			{
				v2f o;
				o.pos = UnityObjectToClipPos( v.vertex);
				o.worldNormal = UnityObjectToWorldNormal (v.normal);
				o.worldPos = mul (unity_ObjectToWorld, v.vertex).xyz;
				o.uv = TRANSFORM_TEX(v.texcoord , _RampTex);

				return o;
			}

			fixed4 frag(v2f i) : SV_Target
			{
				fixed3 worldNormal = normalize(i.worldNormal);
				fixed3 worldLightDir = normalize (UnityWorldSpaceLightDir(i.worldPos));

				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;

				fixed halfLambert = 0.5 * dot(worldNormal , worldLightDir)+0.5;
				fixed3 diffuseColor = tex2D(_RampTex, fixed2(halfLambert, halfLambert)).rgb * _Color.rgb;
				
				
				fixed3 diffuse = _LightColor0.rgb * diffuseColor;

				fixed3 viewDir = normalize (UnityWorldSpaceViewDir(i.worldPos));
				fixed3 halfDir = normalize (worldLightDir + viewDir);
				fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0 , dot(worldNormal, halfDir)), _Gloss);
				return fixed4(ambient + diffuse + specular , 1.0);
			}

			ENDCG
		}
	}
	FallBack "Diffuse"
}

 

遮罩纹理

Shader "Custom/Mask" 
{
	Properties 
	{
		_Color("Color Tint" , Color) = (1,1,1,1)
		_MainTex("Main Tex",2D) = "white" { }
		_BumpMap("Normal Map" , 2D) = "bump" {}
		_BumpScale("Bump Scale", Float) = 1.0
		_SpecularMask("Specular Mask" , 2D) = "white" {}
		_SpecularScale("Specular Scale" , Float) = 1.0
		_Specular("Specular" , Color) = (1,1,1,1)
		_Gloss("Gloss" , Range(8.0,256)) = 20
	}
	SubShader 
	{
		Pass
		{
			Tags { "LightMode" = "ForwardBase" }

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

			fixed4 _Color;
			sampler2D _MainTex;
			float4 _MainTex_ST;
			
			sampler2D _BumpMap;
			float _BumpScale;

			sampler2D _SpecularMask;
			float _SpecularScale;

			fixed4 _Specular;
			float _Gloss;

			struct a2v
			{
				float4 vertex : POSITION;
				float3 normal : NORMAL;
				float4 tangent : TANGENT; 
				float4 texcoord : TEXCOORD0;
			};
			struct v2f
			{
				float4 pos : SV_POSITION;
				float2 uv : TEXCOORD0;
				float3 lightDir : TEXCOORD1;
				float3 viewDir : TEXCOORD2;			
			};

			v2f vert(a2v v)
			{
				v2f o;

				o.pos = UnityObjectToClipPos( v.vertex);
				o.uv.xy = v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;

				TANGENT_SPACE_ROTATION;

				o.lightDir = mul(rotation , ObjSpaceLightDir(v.vertex)).xyz;
				o.viewDir = mul(rotation , ObjSpaceViewDir(v.vertex)).xyz;
				return o;
			}

			fixed4 frag(v2f i) : SV_Target
			{
				fixed3 tangentLightDir = normalize(i.lightDir);
				fixed3 tangentViewDir = normalize( i.viewDir);

				fixed3 tangentNormal = UnpackNormal(tex2D(_BumpMap,i.uv));
				tangentNormal.xy*=_BumpScale;
				tangentNormal.z = sqrt(1.0-saturate(dot(tangentNormal.xy,tangentNormal.xy)));

				fixed3 albedo = tex2D(_MainTex, i.uv).rgb * _Color.rgb;
				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;

				fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(tangentNormal, tangentLightDir));
				
				fixed3 halfDir = normalize(tangentLightDir + tangentViewDir);
				fixed specularMask = tex2D(_SpecularMask , i.uv).r * _SpecularScale;
				
				fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0 , dot(tangentNormal , halfDir)), _Gloss) * specularMask;
				
				return fixed4(ambient + diffuse + specular , 1.0);
			}
			ENDCG
		}
	}
	FallBack "Diffuse"
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值