在unity3D(使用版本2018.4.11)中,我们设置一个场景,放上一个Plane,一个立方体,一个球体,放置一个平行光以及一个点光源。
打开Lighting设置面板,我们设置环境模式为baked
我们再把点光源和平行光的模式改成baked
ok,现在我们开始生成光照贴图,
我们场景很简单,很快生成好了贴图,效果如下,
我们把光源全都禁掉,拖动plane,能看到光影贴图已经生成了。ok,我们自己先来写一个shader,解决掉基本的纹理采样的逻辑。
Shader "Unlit/Texture_02"
{
Properties
{
_MainTex("Main Tex",2D) = ""{}
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
float4 _MainTex_ST;
struct v2f
{
float2 uv : TEXCOORD0;
float4 pos : SV_POSITION;
};
v2f vert (appdata_full v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);
return o;
}
fixed4 frag (v2f i) : COLOR
{
fixed4 color = tex2D(_MainTex,i.uv);
return color;
}
ENDCG
}
}
}
好,我们来把这个shader用在上面的场景中的所有物体,看看结果,
我们发现好像一团糟啊,什么都看不清了,OK,我们来修改下shader,加入unity自己的光照贴图,我加上了注释说明,
Shader "Unlit/Texture_01"
{
Properties
{
_MainTex("Main Tex",2D) = ""{}
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
//unity内置烘培好的光照贴图
sampler2D unity_Lightmap;
sampler2D _MainTex;
float4 _MainTex_ST;
//unity内置光照贴图的缩放偏移量
float4 unity_LightmapST;
struct v2f
{
float2 uv : TEXCOORD0;
float4 pos : SV_POSITION;
float2 uv2:TEXCOORD1;
};
v2f vert (appdata_full v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);
//生成光照贴图的uv
o.uv2 = v.texcoord1.xy*unity_LightmapST.xy + unity_LightmapST.zw;
return o;
}
fixed4 frag (v2f i) : COLOR
{
//对光照贴图进行采样
float3 lm = DecodeLightmap(tex2D(unity_Lightmap,i.uv2));
fixed4 color = tex2D(_MainTex,i.uv);
//将光照贴图采样后的结果和物体本身贴图采样结果进行相乘
//乘以2是为了提高亮度
color.rgb*=lm*2;
return color;
}
ENDCG
}
}
}
我们再来看下效果,
哦HO~,光照贴图出来了,和自带的Standard的着色器效果差不多,好吧,基本就是这样,内容很简单,其实如果要实际运用到项目中要考虑的东西很多,我们通过这样一个简单的实验,大概知道光照贴图是怎么工作的。