准备烘焙环境:
用standard的shader,进行烘焙。
使用高质量的lightmap编码,其实也即是对应HDR模式。RGBA16 sFloat
然后我们将一个物体的shader,换成下面的:
Shader "Unlit/SampleLightmap"
{
SubShader
{
Tags { "RenderType"="Opaque" }
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile _ LIGHTMAP_ON
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float2 uv2 : TEXCOORD1;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
float2 lightmapUV : TEXCOORD1;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
o.lightmapUV = v.uv2.xy * unity_LightmapST.xy + unity_LightmapST.zw;
return o;
}
inline half3 DecodeLightmap2(fixed4 color, half4 decodeInstructions)
{
#if defined(UNITY_LIGHTMAP_DLDR_ENCODING)
return half3(1, 0, 0);
#elif defined(UNITY_LIGHTMAP_RGBM_ENCODING)
return half3(0, 1, 0);
#else //defined(UNITY_LIGHTMAP_FULL_HDR)
return half3(0, 0, 1);
#endif
}
inline half3 DecodeLightmap2(fixed4 color)
{
return DecodeLightmap2(color, unity_Lightmap_HDR);
}
fixed4 frag (v2f i) : SV_Target
{
#if defined(LIGHTMAP_ON)
half4 bakedColorTex = UNITY_SAMPLE_TEX2D(unity_Lightmap, i.lightmapUV.xy);
half3 bakedColor = DecodeLightmap2(bakedColorTex);
return fixed4(bakedColor, 1);
#else
return fixed4(0, 1, 0, 1);
#endif
}
ENDCG
}
}
}
走到了这里:
inline half3 DecodeLightmap2(fixed4 color, half4 decodeInstructions)
{
#if defined(UNITY_LIGHTMAP_DLDR_ENCODING)
return half3(1, 0, 0);
#elif defined(UNITY_LIGHTMAP_RGBM_ENCODING)
return half3(0, 1, 0);
#else //defined(UNITY_LIGHTMAP_FULL_HDR)
return half3(0, 0, 1); //高质量模式,走到了这里
#endif
}
换个模式:Low Quality
此时贴图格式变为:RGBA8 sRGB格式
此时走到:
inline half3 DecodeLightmap2(fixed4 color, half4 decodeInstructions)
{
#if defined(UNITY_LIGHTMAP_DLDR_ENCODING)
return half3(1, 0, 0);
#elif defined(UNITY_LIGHTMAP_RGBM_ENCODING)
return half3(0, 1, 0); //低质量走到了这里:Low Quality
#else //defined(UNITY_LIGHTMAP_FULL_HDR)
return half3(0, 0, 1);
#endif
}
下面换成Normal Quality试试:
没变化,也就是收pc下只用了:UNITY_LIGHTMAP_RGBM_ENCODING和UNITY_LIGHTMAP_FULL_HDR
前者对应得是Low/Normal Quality后者对应的是High Quality。
在官方文档中:https://docs.unity3d.com/Manual/Lightmaps-TechnicalInformation.html
Choosing High Quality will enable HDR
lightmap support, whereas Normal Quality will switch to using RGBM encoding. Low Quality will switch to dLDR encoding on mobile platforms, on other platforms it is equivalent to Normal Quality.
这里对于pc平台下,只有HDR和RGBM两种模式,不会用到dLDR。
假如我们使用的是低质量或者是normal quality:则是打开了宏:UNITY_LIGHTMAP_RGBM_ENCODING
看下unity自己的UnityCG.cginc中的:
inline half3 DecodeLightmap( fixed4 color, half4 decodeInstructions)
{
#if defined(UNITY_LIGHTMAP_DLDR_ENCODING)
return DecodeLightmapDoubleLDR(color, decodeInstructions);
#elif defined(UNITY_LIGHTMAP_RGBM_ENCODING)
return DecodeLightmapRGBM(color, decodeInstructions);
#else //defined(UNITY_LIGHTMAP_FULL_HDR)
return color.rgb;
#endif
}
我们将其移植到自己的shader中:
inline half3 DecodeLightmap2(fixed4 color, half4 decodeInstructions)
{
#if defined(UNITY_LIGHTMAP_DLDR_ENCODING)
return half3(1, 0, 0);
#elif defined(UNITY_LIGHTMAP_RGBM_ENCODING)
return DecodeLightmapRGBM(color, unity_Lightmap_HDR); //low/normal quality是这个宏
#else //defined(UNITY_LIGHTMAP_FULL_HDR)
return half3(0, 0, 1);
#endif
}
打开帧调试器:
因为这里使用的是linear space,所以unity_Lightmap_HDR的x是5的2.2次方。
在这个博客中:https://blog.csdn.net/wodownload2/article/details/105114964
和https://docs.unity3d.com/Manual/Lightmaps-TechnicalInformation.html
中提到:
RGBM encoding. RGBM encoding stores a color in the RGB channels and a multiplier (M) in the alpha channel. The range of RGBM lightmaps goes from 0 to 34.49(52.2) in linear space, and from 0 to 5 in gamma space.
所以就对应起来了。
我们切换成gamma模式:
此时:unity_Lightmap_HDR变为如下:
如果切换成高质量:
此时,没有用到unity_Lightmap_HDR自动优化掉了。
inline half3 DecodeLightmap( fixed4 color, half4 decodeInstructions)
{
#if defined(UNITY_LIGHTMAP_DLDR_ENCODING)
return DecodeLightmapDoubleLDR(color, decodeInstructions);
#elif defined(UNITY_LIGHTMAP_RGBM_ENCODING)
return DecodeLightmapRGBM(color, decodeInstructions);
#else //defined(UNITY_LIGHTMAP_FULL_HDR) //high quality走到了这里
return color.rgb;
#endif
}
补充:
1、在pc平台下,即使切换到了Low Quality,也不会打开宏UNITY_LIGHTMAP_DLDR_ENCODING
只会有两个质量的选择:Normal Quality——》对应RGBM编码格式;以及High Quality——》对应HDR编码格式。选取了Low Quliaty——》对应的还是RGBM格式。
2、在切换到android平台下,那么三者都有对应的编码格式了:
Low Quliaty——》dLDR
Normal Quality——》对应RGBM编码格式
High Quality——》对应HDR编码格式
打包的时候,选择切换平台: