您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

227 行
10 KiB

using UnityEngine;
using System.Collections.Generic;
namespace UnityEditor.Experimental.Rendering.HDPipeline
{
public class StandardsToHDLitMaterialUpgrader : MaterialUpgrader
{
static readonly string Standard = "Standard";
static readonly string Standard_Spec = "Standard (Specular setup)";
static readonly string Standard_Rough = "Standard (Roughness setup)";
public StandardsToHDLitMaterialUpgrader(string sourceShaderName, string destShaderName, MaterialFinalizer finalizer = null)
{
RenameShader(sourceShaderName, destShaderName, finalizer);
RenameTexture("_MainTex", "_BaseColorMap");
RenameColor("_Color", "_BaseColor");
RenameFloat("_Glossiness", "_Smoothness");
RenameTexture("_BumpMap", "_NormalMap");
RenameFloat("_BumpScale", "_NormalScale");
RenameTexture("_ParallaxMap", "_HeightMap");
RenameTexture("_EmissionMap", "_EmissiveColorMap");
RenameTexture("_DetailAlbedoMap", "_DetailMap");
RenameFloat("_UVSec", "_UVDetail");
SetFloat("_LinkDetailsWithBase", 0);
RenameFloat("_DetailNormalMapScale", "_DetailNormalScale");
RenameFloat("_Cutoff", "_AlphaCutoff");
RenameKeywordToFloat("_ALPHATEST_ON", "_AlphaCutoffEnable", 1f, 0f);
if (sourceShaderName == Standard)
{
SetFloat("_MaterialID", 1f);
}
if (sourceShaderName == Standard_Spec)
{
SetFloat("_MaterialID", 4f);
RenameColor("_SpecColor", "_SpecularColor");
RenameTexture("_SpecGlossMap", "_SpecularColorMap");
}
}
public override void Convert(Material srcMaterial, Material dstMaterial)
{
dstMaterial.hideFlags = HideFlags.DontUnloadUnusedAsset;
base.Convert(srcMaterial, dstMaterial);
// ---------- Mask Map ----------
// Metallic
bool hasMetallic = false;
Texture metallicMap = Texture2D.blackTexture;
if ( (srcMaterial.shader.name == Standard) || (srcMaterial.shader.name == Standard_Rough) )
{
hasMetallic = srcMaterial.GetTexture("_MetallicGlossMap") != null;
if (hasMetallic)
{
metallicMap = TextureCombiner.GetTextureSafe(srcMaterial, "_MetallicGlossMap", Color.white);
}
else
{
float metallicValue = Mathf.Pow(srcMaterial.GetFloat("_Metallic"), 2.2f); // Convert _Metallic value from Gamma to Linear
dstMaterial.SetFloat("_Metallic", metallicValue);
metallicMap = TextureCombiner.TextureFromColor(Color.white * metallicValue);
}
}
// Occlusion
bool hasOcclusion = srcMaterial.GetTexture("_OcclusionMap") != null;
Texture occlusionMap = Texture2D.whiteTexture;
if (hasOcclusion) occlusionMap = TextureCombiner.GetTextureSafe(srcMaterial, "_OcclusionMap", Color.white);
// Detail Mask
bool hasDetailMask = srcMaterial.GetTexture("_DetailMask") != null;
Texture detailMaskMap = Texture2D.whiteTexture;
if (hasDetailMask) detailMaskMap = TextureCombiner.GetTextureSafe(srcMaterial, "_DetailMask", Color.white);
// Smoothness
bool hasSmoothness = false;
Texture2D smoothnessMap = TextureCombiner.TextureFromColor(Color.grey);
if (srcMaterial.shader.name == Standard_Rough)
{
hasSmoothness = srcMaterial.GetTexture("_SpecGlossMap") != null;
if (hasSmoothness)
smoothnessMap = (Texture2D)TextureCombiner.GetTextureSafe(srcMaterial, "_SpecGlossMap", Color.grey);
}
else
{
string smoothnessTextureChannel = "_MainTex";
if ( srcMaterial.GetFloat("_SmoothnessTextureChannel") == 0 )
{
if (srcMaterial.shader.name == Standard) smoothnessTextureChannel = "_MetallicGlossMap";
if (srcMaterial.shader.name == Standard_Spec) smoothnessTextureChannel = "_SpecGlossMap";
}
smoothnessMap = (Texture2D) srcMaterial.GetTexture( smoothnessTextureChannel );
if (smoothnessMap != null)
{
hasSmoothness = true;
if (!TextureCombiner.TextureHasAlpha(smoothnessMap))
{
smoothnessMap = TextureCombiner.TextureFromColor(Color.white);
}
}
else
{
smoothnessMap = TextureCombiner.TextureFromColor(Color.white * srcMaterial.GetFloat("_Glossiness"));
}
}
// Build the mask map
if ( hasMetallic || hasOcclusion || hasDetailMask || hasSmoothness )
{
Texture2D maskMap;
TextureCombiner maskMapCombiner = new TextureCombiner(
metallicMap, 0, // R: Metallic from red
occlusionMap, 1, // G: Occlusion from green
detailMaskMap, 3, // B: Detail Mask from alpha
smoothnessMap, (srcMaterial.shader.name == Standard_Rough)?-4:3 // A: Smoothness Texture from inverse greyscale for roughness setup, or alpha
);
dstMaterial.SetFloat("_Metallic", 1f); // Force _Metallic value to 1, to use the value stored in the mask map without modification
string maskMapPath = AssetDatabase.GetAssetPath(srcMaterial);
maskMapPath = maskMapPath.Remove(maskMapPath.Length-4) + "_MaskMap.png";
maskMap = maskMapCombiner.Combine( maskMapPath );
dstMaterial.SetTexture("_MaskMap", maskMap);
}
dstMaterial.SetFloat("_AORemapMin", 1f - srcMaterial.GetFloat("_OcclusionStrength"));
// Specular Setup Specific
if (srcMaterial.shader.name == Standard_Spec)
{
// if there is a specular map, change the specular color to white
if (srcMaterial.GetTexture("_SpecGlossMap") != null ) dstMaterial.SetColor("_SpecularColor", Color.white);
}
// ---------- Height Map ----------
bool hasHeightMap = srcMaterial.GetTexture("_ParallaxMap") != null;
if (hasHeightMap) // Enable Parallax Occlusion Mapping
{
dstMaterial.SetFloat("_DisplacementMode", 2);
dstMaterial.SetFloat("_HeightPoMAmplitude", srcMaterial.GetFloat("_Parallax") * 2f);
}
// ---------- Detail Map ----------
bool hasDetailAlbedo = srcMaterial.GetTexture("_DetailAlbedoMap") != null;
bool hasDetailNormal = srcMaterial.GetTexture("_DetailNormalMap") != null;
if ( hasDetailAlbedo || hasDetailNormal )
{
Texture2D detailMap;
TextureCombiner detailCombiner = new TextureCombiner(
TextureCombiner.GetTextureSafe(srcMaterial, "_DetailAlbedoMap", Color.grey), 4, // Albedo (overlay)
TextureCombiner.GetTextureSafe(srcMaterial, "_DetailNormalMap", Color.grey), 1, // Normal Y
TextureCombiner.midGrey, 1, // Smoothness
TextureCombiner.GetTextureSafe(srcMaterial, "_DetailNormalMap", Color.grey), 0 // Normal X
);
string detailMapPath = AssetDatabase.GetAssetPath(srcMaterial);
detailMapPath = detailMapPath.Remove(detailMapPath.Length-4) + "_DetailMap.png";
detailMap = detailCombiner.Combine( detailMapPath );
dstMaterial.SetTexture("_DetailMap", detailMap);
}
// Blend Mode
int previousBlendMode = srcMaterial.GetInt("_Mode");
switch (previousBlendMode)
{
case 0: // Opaque
dstMaterial.SetFloat("_SurfaceType", 0);
dstMaterial.SetFloat("_BlendMode", 0);
dstMaterial.SetFloat("_AlphaCutoffEnable", 0);
dstMaterial.SetFloat("_EnableBlendModePreserveSpecularLighting", 1);
break;
case 1: // Cutout
dstMaterial.SetFloat("_SurfaceType", 0);
dstMaterial.SetFloat("_BlendMode", 0);
dstMaterial.SetFloat("_AlphaCutoffEnable", 1);
dstMaterial.SetFloat("_EnableBlendModePreserveSpecularLighting", 1);
break;
case 2: // Fade -> Alpha + Disable preserve specular
dstMaterial.SetFloat("_SurfaceType", 1);
dstMaterial.SetFloat("_BlendMode", 0);
dstMaterial.SetFloat("_AlphaCutoffEnable", 0);
dstMaterial.SetFloat("_EnableBlendModePreserveSpecularLighting", 0);
break;
case 3: // Transparent -> Alpha
dstMaterial.SetFloat("_SurfaceType", 1);
dstMaterial.SetFloat("_BlendMode", 0);
dstMaterial.SetFloat("_AlphaCutoffEnable", 0);
dstMaterial.SetFloat("_EnableBlendModePreserveSpecularLighting", 1);
break;
}
// Emission: Convert the HDR emissive color to ldr color + intensity
Color hdrEmission = srcMaterial.GetColor("_EmissionColor");
float intensity = Mathf.Max(hdrEmission.r, Mathf.Max(hdrEmission.g, hdrEmission.b));
if (intensity > 1f)
{
hdrEmission.r /= intensity;
hdrEmission.g /= intensity;
hdrEmission.b /= intensity;
}
else
intensity = 1f;
intensity = Mathf.Pow(intensity, 2.2f); // Gamma to Linear conversion
dstMaterial.SetColor("_EmissiveColor", hdrEmission);
dstMaterial.SetFloat("_EmissiveIntensity", intensity);
HDEditorUtils.ResetMaterialKeywords(dstMaterial);
}
}
}