关于Unity里自发光材质的烘焙,一个是要加上Meta Pass,一个是要设置材质的Lightmap Flags设置为BakedEmissive
以下为烘焙自发光成功与失败的对比
第一点加上meta pass,以下为URP管线下通用Meta Pass,加载自定义的shader后面,把参数换成自己的参数名就好:
// This pass it not used during regular rendering, only for lightmap baking.
Pass
{
Name "Meta"
Tags{"LightMode" = "Meta"}
Cull Off
HLSLPROGRAM
#pragma only_renderers gles gles3 glcore d3d11
#pragma target 2.0
#pragma vertex vert_Meta
#pragma fragment frag_Meta
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/MetaInput.hlsl"
TEXTURE2D(_BaseMap); SAMPLER(sampler_BaseMap);
TEXTURE2D(_MetallicGlossMap); SAMPLER(sampler_MetallicGlossMap);
TEXTURE2D(_Emissionmap); SAMPLER(sampler_Emissionmap);
struct a2v_Meta
{
float4 positionOS : POSITION;
float3 normalOS : NORMAL;
float2 uv0 : TEXCOORD0;
float2 uv1 : TEXCOORD1;
float2 uv2 : TEXCOORD2;
#ifdef _TANGENT_TO_WORLD
float4 tangentOS : TANGENT;
#endif
};
struct v2f_Meta
{
float4 positionCS : SV_POSITION;
float2 uv : TEXCOORD0;
};
v2f_Meta vert_Meta(a2v_Meta input)
{
v2f_Meta output = (v2f_Meta)0;
output.positionCS = MetaVertexPosition(input.positionOS, input.uv1, input.uv2, unity_LightmapST, unity_DynamicLightmapST);
output.uv = TRANSFORM_TEX(input.uv0, _BaseMap);
return output;
}
half4 frag_Meta(v2f_Meta input) : SV_Target
{
SurfaceData surfaceData;
half4 albedoAlpha = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.uv);
surfaceData.albedo = albedoAlpha.rgb * _BaseColor.rgb;
surfaceData.alpha = albedoAlpha.a * _BaseColor.a;
half4 metallicGlossOcclusion = SAMPLE_TEXTURE2D(_MetallicGlossMap, sampler_MetallicGlossMap, input.uv);
surfaceData.metallic = _Metallic * metallicGlossOcclusion.r;
surfaceData.smoothness = _Smoothness * metallicGlossOcclusion.a;
surfaceData.specular = _SpecularColor.rgb;
surfaceData.emission = SAMPLE_TEXTURE2D(_Emissionmap, sampler_Emissionmap, input.uv).rgb * _Emission.rgb;
surfaceData.clearCoatMask = 0.0h;
surfaceData.clearCoatSmoothness = 0.0h;
BRDFData brdfData;
InitializeBRDFData(surfaceData.albedo, surfaceData.metallic, surfaceData.specular, surfaceData.smoothness, surfaceData.alpha, brdfData);
MetaInput metaInput;
metaInput.Albedo = brdfData.diffuse + brdfData.specular * brdfData.roughness * 0.5;
metaInput.SpecularColor = surfaceData.specular;
metaInput.Emission = surfaceData.emission;
return MetaFragment(metaInput);
}
ENDHLSL
}
第二点设置材质的Lightmap Flags,可以用代码mat.globalIlluminationFlags = MaterialGlobalIlluminationFlags.BakedEmissive来设置,或者在Debug模式下,把材质的LightmapFlags改为4
做了个小工具,便于美术在材质面板上,点击右上角的齿轮,就可以很轻松的设置哪些材质需要自发光烘焙
以下是代码,放进工程里就好
using UnityEngine;
using UnityEditor;
public class MaterialBakedEmissionTool : MonoBehaviour
{
// Start is called before the first frame update
[MenuItem("CONTEXT/Material/Set Baked Emission")]
public static void SetBakedEmission(MenuCommand menuCommand)
{
var mat = menuCommand.context as Material;
if (mat != null)
{
mat.globalIlluminationFlags = MaterialGlobalIlluminationFlags.BakedEmissive;
}
}
[MenuItem("CONTEXT/Material/Reset Baked Emission")]
public static void ResetBakedEmission(MenuCommand menuCommand)
{
var mat = menuCommand.context as Material;
if (mat != null)
{
mat.globalIlluminationFlags = MaterialGlobalIlluminationFlags.None;
}
}
}