【《Unity Shader入门精要》 提炼总结】(九)第九章·UV贴图&纹理概念介绍&单张纹理的应用&Shader常见函数总结

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/iceSony/article/details/84587428

本文由@唐三十胖子出品,转载请注明出处。  
文章链接:https://blog.csdn.net/iceSony/article/details/84587428

这篇文章将总结和提炼《Unity Shader入门精要》的第七章“基础纹理”的内容。

通过这篇文章,你可以知道

1)UV贴图概念与使用

2)纹理相关概念的介绍

3)简单的单张纹理的应用

4)前9章Shader常见函数总结

一.UV贴图概念与使用

虽然模型与贴图(包含UV贴图,法线贴图,渐变贴图,遮罩贴图)的制作是美工的活,但是程序需要知道相关的知识以及简单使用来进行shader的开发,其中最常见的修改就是下一章要涉及的法线贴图的shader开发。

上图来自网络,很明显这是个角色UV贴图,包含头部躯干四肢

首先美工在3Dmax制作模型导出的时候会有UV贴图的导出选项,美工需要进行模型的拆分

就像一个纸箱子,通过拆分会变成这样

UV贴图包含对模型上色的相关位置信息,之后可以在PS中进行相关上色修改

至于最终怎么穿上这层皮,是模型的事情:)    

模型包含了与贴图的对应信息,本篇不涉及。

二.简单的单张纹理的应用

在以后的开发我们会用到上面那样的模型uv贴图,现在用简单的入门

左边是使用漫反射的模型,右边是使用了材质贴图的模型

在shader中我们需要获取纹理颜色在法线上的影响,并最终与漫反射颜色进行混合

 

由于是漫反射的替换,我们这里使用之前写过的漫反射顶点着色器举例

对之前代码我们进行了修改,首先修改结构体

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

v2f多添加uv属性,从a2v新添加的属性texcoord中转化

 

顶点着色器

v2f vert(a2v v)
{
	v2f o;
	o.pos = UnityObjectToClipPos(v.pos);
	o.worldNormal = UnityObjectToWorldNormal(v.normal);
	o.uv = v.texcoord.xy*_MainTex_ST.xy + _MainTex_ST.zw;
	return o;
}

函数中添加一行o.uv = v.texcoord.xy*_MainTex_ST.xy + _MainTex_ST.zw;

翻译过来就是: uv坐标=材质uv坐标*材质uv缩放+材质uv偏移

事实上在以后的开发中你会遇到这个函数TRANSFORM_TEX,本质也是这句话

片元着色器

fixed4 frag(v2f i) : SV_Target
{
	float3 worldNormal = i.worldNormal;
	float3 worldLightDir = UnityWorldSpaceLightDir(worldNormal);
	float3 albedo = tex2D(_MainTex, i.uv).rgb;

	float3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz*albedo;

	float3 diffuse = _LightColor0.rgb * _Diffuse.rgb * max(0, dot(worldNormal, worldLightDir)) * albedo;

	return fixed4(ambient+diffuse,1.0);
}

函数中添加float3 albedo = tex2D(_MainTex, i.uv).rgb;

float3 diffuse=_LightColor0.rgb*_Diffuse.rgb*max(0,dot(worldNormal, worldLightDir))*halfLambert*albedo;

albedo的获取用到了tex2D函数对纹理进行采样,返回的albedo是该顶点下的材质颜色,在最后漫反射颜色结尾*albedo

 

完整代码如下

Shader "sony/Shader158"
{
	Properties
	{
		_Diffuse("漫反射系数",Color) = (1.0,1.0,1.0,1.0)
		_MainTex("主纹理",2D) = "white"{}
	}
		SubShader
	{
		Pass
	{
		Tags{ "LightMode" = "ForwardBase" }
		CGPROGRAM
		#include "lighting.cginc"
		#pragma vertex vert
		#pragma fragment frag
		float4 _Diffuse;
		sampler2D _MainTex;
		float4 _MainTex_ST;
		struct a2v
		{
			float4 pos : POSITION;
			float3 normal : NORMAL;
			float4 texcoord:TEXCOORD0;
		};
		struct v2f
		{
			float4 pos : SV_POSITION;
			float3 worldNormal : TEXCOORD0;
			float2 uv : TEXCOORD2;
		};
		v2f vert(a2v v)
		{
			v2f o;
			o.pos = UnityObjectToClipPos(v.pos);
			o.worldNormal = UnityObjectToWorldNormal(v.normal);
			o.uv = v.texcoord.xy*_MainTex_ST.xy + _MainTex_ST.zw;
			return o;
		}
		fixed4 frag(v2f i) : SV_Target
		{
			float3 worldNormal = i.worldNormal;
			float3 worldLightDir = UnityWorldSpaceLightDir(worldNormal);
			float3 albedo = tex2D(_MainTex, i.uv).rgb;

			float3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz*albedo;

			float3 diffuse = _LightColor0.rgb * _Diffuse.rgb * max(0, dot(worldNormal, worldLightDir)) * albedo;

			return fixed4(ambient+diffuse,1.0);
		}
			ENDCG
		}
	}
}

三.前九章Shader常见函数总结

坐标与法线的空间坐标转换

o.vert_pos = UnityObjectToClipPos(v.vert_pos);

o.normal = (mul(v.normal, (float3x3)unity_WorldToObject));

获取环境光颜色

float3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;

获取光线方向,颜色

float3 lightDir = UnityWorldSpaceLightDir(o.vert_pos);

 

获取视角方向   normalize必须加

float3 viewDir = normalize(_WorldSpaceCameraPos.xyz - o.normal);

获取反射光线方向

float3 reflectDir = -reflect(lightDir,o.normal);

 

UV坐标的设置与获取纹理信息

o.uv = v.texcoord.xy*_MainTex_ST.xy + _MainTex_ST.zw;

float3 albedo = tex2D(_MainTex, o.uv).rgb;

 

获取纹理属性

Properties中定义了_MainTex ,那么在CGPROGRAM中声明为:_MainTex_ST

 

下一章我们会介绍低模变高模的神奇应用:法线纹理

Thanks♪(・ω・)ノ感谢阅读

猜你喜欢

转载自blog.csdn.net/iceSony/article/details/84587428