欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Unity基础纹理

程序员文章站 2022-06-10 23:48:46
...

为了使用纹理,首先需要在Properties语义块中添加一个纹理属性:

_MainTex("Main Tex", 2D) = "white"{}

然后需要在Cg代码片中声明和上述属性相匹配的变量:

sampler2D _MainTex;

此外,我们还需要为纹理类型的属性声明一个float4类型的变量_MainTex_ST.这个名字不是乱取的,在Unity中,需要使用纹理名_ST的方式来声明某个纹理的属性.S代表缩放,t代表平移.

接下来需要定义顶点着色器的输入和输出结构体:

			struct a2v
			{
				float4 vertex : POSITION;
				float3 normal : NORMAL;
				float4 texcoord : TEXCOORD0;//unity将模型的第一组纹理坐标存储到该变量中
			};
			struct v2f
			{
				float4 pos : SV_POSITION;
				float3 worldNormal : TEXCOORD0;
				float3 worldPos : TEXCOORD1;
				float2 uv : TEXCOORD2;//用于存储纹理坐标的变量uv
			};

使用TEXCOORD0语义声明了一个新的变量texcoord,这样Unity就会将模型的第一组纹理坐标存储到该变量中.
然后定义顶点着色器:

			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;//先使用缩放值对顶点纹理坐标进行缩放,然后使用
				//偏移属性对zw对结果进行偏移。
				//o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); unity内置宏可以计算上述偏移过程。
				return o;
			}

在顶点着色器中,先使用_MainTex_ST.xy对顶点纹理坐标进行缩放,然后在使用_MainTex_ST.zw对结果进行偏移. unity内置宏TRANSFORM_TEX也可以进行上面的计算过程.

然后是实现片元着色器,并在计算漫反射的时候使用纹理中的纹素值.

			fixed4 frag(v2f i) : SV_Target//SV_TARGET输出值将会存储到渲染目标中
			{
				fixed3 worldNormal = normalize(i.worldNormal);//归一化
				fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));//计算光线方向
				fixed3 albedo = tex2D(_MainTex, i.uv).rgb * _Color.rgb;//tex2D对纹理进行采样,第一个参数是被采样的纹理
				//第二个参数是一个float2类型的纹理坐标,它将返回计算得到的纹素值。
				//使用采样结果和颜色属性_Color的乘积作为材质的反射率albedo
				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);
			}

完整代码如下:

Shader "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" //使用Unity内置变量 如_LightColor0

			fixed4 _Color;
			sampler2D _MainTex;
			float4 _MainTex_ST;//使用纹理名_ST来声明某个纹理的属性,ST是缩放scale和平移translation的缩写
			//_MainTex_ST.xy存储缩放值,_MainTex_ST.zw存储偏移值,
			fixed4 _Specular;
			float _Gloss;



			struct a2v
			{
				float4 vertex : POSITION;
				float3 normal : NORMAL;
				float4 texcoord : TEXCOORD0;//unity将模型的第一组纹理坐标存储到该变量中
			};
			struct v2f
			{
				float4 pos : SV_POSITION;
				float3 worldNormal : TEXCOORD0;
				float3 worldPos : TEXCOORD1;
				float2 uv : TEXCOORD2;//用于存储纹理坐标的变量uv
			};
			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;//先使用缩放值对顶点纹理坐标进行缩放,然后使用
				//偏移属性对zw对结果进行偏移。
				//o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); unity内置宏可以计算上述偏移过程。
				return o;
			}

			fixed4 frag(v2f i) : SV_Target//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 halfLambert = dot(worldNormal,worldLightDir) * 0.5 +0.5;
				fixed3 diffuse = _LightColor0.rgb * albedo * halfLambert;
				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 "Specular"


}