343 lines
11 KiB
C#
343 lines
11 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.Rendering;
|
|
|
|
public class OvrAvatarMaterialManager : MonoBehaviour
|
|
{
|
|
public enum TextureType
|
|
{
|
|
DiffuseTextures = 0,
|
|
NormalMaps = 1,
|
|
RoughnessMaps = 2,
|
|
Count = 3
|
|
}
|
|
|
|
[Serializable]
|
|
public struct AvatarComponentMaterialProperties
|
|
{
|
|
public ovrAvatarBodyPartType TypeIndex;
|
|
|
|
public Color Color;
|
|
|
|
public Texture2D[] Textures;
|
|
|
|
[Range(0f, 1f)]
|
|
public float DiffuseIntensity;
|
|
|
|
[Range(0f, 10f)]
|
|
public float RimIntensity;
|
|
|
|
[Range(0f, 1f)]
|
|
public float ReflectionIntensity;
|
|
}
|
|
|
|
[Serializable]
|
|
public struct AvatarTextureArrayProperties
|
|
{
|
|
public Texture2D[] Textures;
|
|
|
|
public Texture2DArray TextureArray;
|
|
}
|
|
|
|
[Serializable]
|
|
public struct AvatarMaterialPropertyBlock
|
|
{
|
|
public Vector4[] Colors;
|
|
|
|
public float[] DiffuseIntensities;
|
|
|
|
public float[] RimIntensities;
|
|
|
|
public float[] ReflectionIntensities;
|
|
}
|
|
|
|
[Serializable]
|
|
public class AvatarMaterialConfig
|
|
{
|
|
public AvatarComponentMaterialProperties[] ComponentMaterialProperties;
|
|
|
|
public AvatarMaterialPropertyBlock MaterialPropertyBlock;
|
|
}
|
|
|
|
public Texture2D[] DiffuseFallbacks;
|
|
|
|
public Texture2D[] NormalFallbacks;
|
|
|
|
private Renderer TargetRenderer;
|
|
|
|
private AvatarTextureArrayProperties[] TextureArrays;
|
|
|
|
private OvrAvatarTextureCopyManager TextureCopyManager;
|
|
|
|
private readonly string[] TextureTypeToShaderProperties = new string[3] { "_MainTex", "_NormalMap", "_RoughnessMap" };
|
|
|
|
public List<ReflectionProbeBlendInfo> ReflectionProbes = new List<ReflectionProbeBlendInfo>();
|
|
|
|
public AvatarMaterialConfig LocalAvatarConfig;
|
|
|
|
public AvatarMaterialConfig DefaultAvatarConfig;
|
|
|
|
private AvatarMaterialPropertyBlock LocalAvatarMaterialPropertyBlock;
|
|
|
|
private Shader CombinedShader;
|
|
|
|
public static string AVATAR_SHADER_LOADER = "OvrAvatar/Avatar_Mobile_Loader";
|
|
|
|
public static string AVATAR_SHADER_MAINTEX = "_MainTex";
|
|
|
|
public static string AVATAR_SHADER_NORMALMAP = "_NormalMap";
|
|
|
|
public static string AVATAR_SHADER_ROUGHNESSMAP = "_RoughnessMap";
|
|
|
|
public static string AVATAR_SHADER_COLOR = "_BaseColor";
|
|
|
|
public static string AVATAR_SHADER_DIFFUSEINTENSITY = "_DiffuseIntensity";
|
|
|
|
public static string AVATAR_SHADER_RIMINTENSITY = "_RimIntensity";
|
|
|
|
public static string AVATAR_SHADER_REFLECTIONINTENSITY = "_ReflectionIntensity";
|
|
|
|
public static string AVATAR_SHADER_CUBEMAP = "_Cubemap";
|
|
|
|
public static string AVATAR_SHADER_ALPHA = "_Alpha";
|
|
|
|
public static string AVATAR_SHADER_LOADING_DIMMER = "_LoadingDimmer";
|
|
|
|
public static string AVATAR_SHADER_IRIS_COLOR = "_MaskColorIris";
|
|
|
|
public static string AVATAR_SHADER_LIP_COLOR = "_MaskColorLips";
|
|
|
|
public static string AVATAR_SHADER_BROW_COLOR = "_MaskColorBrows";
|
|
|
|
public static string AVATAR_SHADER_LASH_COLOR = "_MaskColorLashes";
|
|
|
|
public static string AVATAR_SHADER_SCLERA_COLOR = "_MaskColorSclera";
|
|
|
|
public static string AVATAR_SHADER_GUM_COLOR = "_MaskColorGums";
|
|
|
|
public static string AVATAR_SHADER_TEETH_COLOR = "_MaskColorTeeth";
|
|
|
|
public static string AVATAR_SHADER_LIP_SMOOTHNESS = "_LipSmoothness";
|
|
|
|
private const float LOADING_ANIMATION_AMPLITUDE = 0.5f;
|
|
|
|
private const float LOADING_ANIMATION_PERIOD = 0.35f;
|
|
|
|
private const float LOADING_ANIMATION_CURVE_SCALE = 0.25f;
|
|
|
|
private const float LOADING_ANIMATION_DIMMER_MIN = 0.3f;
|
|
|
|
private void Awake()
|
|
{
|
|
TextureCopyManager = base.gameObject.AddComponent<OvrAvatarTextureCopyManager>();
|
|
}
|
|
|
|
public void CreateTextureArrays()
|
|
{
|
|
for (int i = 0; i < 5; i++)
|
|
{
|
|
LocalAvatarConfig.ComponentMaterialProperties[i].Textures = new Texture2D[3];
|
|
DefaultAvatarConfig.ComponentMaterialProperties[i].Textures = new Texture2D[3];
|
|
}
|
|
TextureArrays = new AvatarTextureArrayProperties[3];
|
|
}
|
|
|
|
public void SetRenderer(Renderer renderer)
|
|
{
|
|
TargetRenderer = renderer;
|
|
TargetRenderer.GetClosestReflectionProbes(ReflectionProbes);
|
|
}
|
|
|
|
public void OnCombinedMeshReady()
|
|
{
|
|
InitTextureArrays();
|
|
SetMaterialPropertyBlock();
|
|
StartCoroutine(RunLoadingAnimation());
|
|
}
|
|
|
|
public void InitTextureArrays()
|
|
{
|
|
AvatarComponentMaterialProperties avatarComponentMaterialProperties = LocalAvatarConfig.ComponentMaterialProperties[0];
|
|
for (int i = 0; i < TextureArrays.Length && i < avatarComponentMaterialProperties.Textures.Length; i++)
|
|
{
|
|
TextureArrays[i].TextureArray = new Texture2DArray(avatarComponentMaterialProperties.Textures[0].height, avatarComponentMaterialProperties.Textures[0].width, LocalAvatarConfig.ComponentMaterialProperties.Length, avatarComponentMaterialProperties.Textures[0].format, true, (QualitySettings.activeColorSpace != ColorSpace.Gamma) ? true : false)
|
|
{
|
|
filterMode = FilterMode.Trilinear
|
|
};
|
|
TextureArrays[i].Textures = new Texture2D[LocalAvatarConfig.ComponentMaterialProperties.Length];
|
|
for (int j = 0; j < LocalAvatarConfig.ComponentMaterialProperties.Length; j++)
|
|
{
|
|
TextureArrays[i].Textures[j] = LocalAvatarConfig.ComponentMaterialProperties[j].Textures[i];
|
|
}
|
|
ProcessTexturesWithMips(TextureArrays[i].Textures, avatarComponentMaterialProperties.Textures[i].height, TextureArrays[i].TextureArray);
|
|
}
|
|
}
|
|
|
|
private void ProcessTexturesWithMips(Texture2D[] textures, int texArrayResolution, Texture2DArray texArray)
|
|
{
|
|
for (int i = 0; i < textures.Length; i++)
|
|
{
|
|
int num = texArrayResolution;
|
|
int num2 = textures[i].mipmapCount - 1;
|
|
for (int num3 = num2; num3 >= 0; num3--)
|
|
{
|
|
int mipSize = texArrayResolution / num;
|
|
TextureCopyManager.CopyTexture(textures[i], texArray, num3, mipSize, i);
|
|
num /= 2;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void SetMaterialPropertyBlock()
|
|
{
|
|
if (TargetRenderer != null)
|
|
{
|
|
for (int i = 0; i < LocalAvatarConfig.ComponentMaterialProperties.Length; i++)
|
|
{
|
|
LocalAvatarConfig.MaterialPropertyBlock.Colors[i] = LocalAvatarConfig.ComponentMaterialProperties[i].Color;
|
|
LocalAvatarConfig.MaterialPropertyBlock.DiffuseIntensities[i] = LocalAvatarConfig.ComponentMaterialProperties[i].DiffuseIntensity;
|
|
LocalAvatarConfig.MaterialPropertyBlock.RimIntensities[i] = LocalAvatarConfig.ComponentMaterialProperties[i].RimIntensity;
|
|
LocalAvatarConfig.MaterialPropertyBlock.ReflectionIntensities[i] = LocalAvatarConfig.ComponentMaterialProperties[i].ReflectionIntensity;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ApplyMaterialPropertyBlock()
|
|
{
|
|
MaterialPropertyBlock materialPropertyBlock = new MaterialPropertyBlock();
|
|
materialPropertyBlock.SetVectorArray(AVATAR_SHADER_COLOR, LocalAvatarConfig.MaterialPropertyBlock.Colors);
|
|
materialPropertyBlock.SetFloatArray(AVATAR_SHADER_DIFFUSEINTENSITY, LocalAvatarConfig.MaterialPropertyBlock.DiffuseIntensities);
|
|
materialPropertyBlock.SetFloatArray(AVATAR_SHADER_RIMINTENSITY, LocalAvatarConfig.MaterialPropertyBlock.RimIntensities);
|
|
materialPropertyBlock.SetFloatArray(AVATAR_SHADER_REFLECTIONINTENSITY, LocalAvatarConfig.MaterialPropertyBlock.ReflectionIntensities);
|
|
TargetRenderer.GetClosestReflectionProbes(ReflectionProbes);
|
|
if (ReflectionProbes != null && ReflectionProbes.Count > 0 && ReflectionProbes[0].probe.texture != null)
|
|
{
|
|
materialPropertyBlock.SetTexture(AVATAR_SHADER_CUBEMAP, ReflectionProbes[0].probe.texture);
|
|
}
|
|
for (int i = 0; i < TextureArrays.Length; i++)
|
|
{
|
|
materialPropertyBlock.SetTexture(TextureTypeToShaderProperties[i], TextureArrays[i].TextureArray);
|
|
}
|
|
TargetRenderer.SetPropertyBlock(materialPropertyBlock);
|
|
}
|
|
|
|
public static ovrAvatarBodyPartType GetComponentType(string objectName)
|
|
{
|
|
if (objectName.Contains("0"))
|
|
{
|
|
return ovrAvatarBodyPartType.Body;
|
|
}
|
|
if (objectName.Contains("1"))
|
|
{
|
|
return ovrAvatarBodyPartType.Clothing;
|
|
}
|
|
if (objectName.Contains("2"))
|
|
{
|
|
return ovrAvatarBodyPartType.Eyewear;
|
|
}
|
|
if (objectName.Contains("3"))
|
|
{
|
|
return ovrAvatarBodyPartType.Hair;
|
|
}
|
|
if (objectName.Contains("4"))
|
|
{
|
|
return ovrAvatarBodyPartType.Beard;
|
|
}
|
|
return ovrAvatarBodyPartType.Count;
|
|
}
|
|
|
|
public void ValidateTextures()
|
|
{
|
|
AvatarComponentMaterialProperties[] componentMaterialProperties = LocalAvatarConfig.ComponentMaterialProperties;
|
|
int[] array = new int[3];
|
|
TextureFormat[] array2 = new TextureFormat[3];
|
|
for (int i = 0; i < componentMaterialProperties.Length; i++)
|
|
{
|
|
for (int j = 0; j < componentMaterialProperties[i].Textures.Length; j++)
|
|
{
|
|
if (componentMaterialProperties[i].Textures[j] == null)
|
|
{
|
|
string text = componentMaterialProperties[i].TypeIndex.ToString();
|
|
TextureType textureType = (TextureType)j;
|
|
throw new Exception(text + "Invalid: " + textureType);
|
|
}
|
|
array[j] = componentMaterialProperties[i].Textures[j].height;
|
|
array2[j] = componentMaterialProperties[i].Textures[j].format;
|
|
}
|
|
}
|
|
for (int k = 0; k < 3; k++)
|
|
{
|
|
for (int l = 1; l < componentMaterialProperties.Length; l++)
|
|
{
|
|
if (componentMaterialProperties[l - 1].Textures[k].height != componentMaterialProperties[l].Textures[k].height)
|
|
{
|
|
object[] obj = new object[8]
|
|
{
|
|
componentMaterialProperties[l].TypeIndex.ToString(),
|
|
" Mismatching Resolutions: ",
|
|
null,
|
|
null,
|
|
null,
|
|
null,
|
|
null,
|
|
null
|
|
};
|
|
TextureType textureType2 = (TextureType)k;
|
|
obj[2] = textureType2.ToString();
|
|
obj[3] = " ";
|
|
obj[4] = componentMaterialProperties[l - 1].Textures[k].height;
|
|
obj[5] = " vs ";
|
|
obj[6] = componentMaterialProperties[l].Textures[k].height;
|
|
obj[7] = " Ensure you are using ASTC texture compression on Android or turn off CombineMeshes";
|
|
throw new Exception(string.Concat(obj));
|
|
}
|
|
if (componentMaterialProperties[l - 1].Textures[k].format != componentMaterialProperties[l].Textures[k].format)
|
|
{
|
|
string text2 = componentMaterialProperties[l].TypeIndex.ToString();
|
|
TextureType textureType3 = (TextureType)k;
|
|
throw new Exception(text2 + " Mismatching Formats: " + textureType3.ToString() + " Ensure you are using ASTC texture compression on Android or turn off CombineMeshes");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private IEnumerator RunLoadingAnimation()
|
|
{
|
|
CombinedShader = TargetRenderer.sharedMaterial.shader;
|
|
int srcBlend = TargetRenderer.sharedMaterial.GetInt("_SrcBlend");
|
|
int dstBlend = TargetRenderer.sharedMaterial.GetInt("_DstBlend");
|
|
bool transparentQueue = TargetRenderer.sharedMaterial.IsKeywordEnabled("_ALPHATEST_ON");
|
|
int renderQueue = TargetRenderer.sharedMaterial.renderQueue;
|
|
string renderTag = TargetRenderer.sharedMaterial.GetTag("RenderType", false);
|
|
TargetRenderer.sharedMaterial.shader = Shader.Find(AVATAR_SHADER_LOADER);
|
|
TargetRenderer.sharedMaterial.SetColor(AVATAR_SHADER_COLOR, Color.white);
|
|
while (TextureCopyManager.GetTextureCount() > 0)
|
|
{
|
|
float distance = (0.5f * Mathf.Sin(Time.timeSinceLevelLoad / 0.35f) + 0.5f) * 0.25f + 0.3f;
|
|
TargetRenderer.sharedMaterial.SetFloat(AVATAR_SHADER_LOADING_DIMMER, distance);
|
|
yield return null;
|
|
}
|
|
TargetRenderer.sharedMaterial.SetFloat(AVATAR_SHADER_LOADING_DIMMER, 1f);
|
|
TargetRenderer.sharedMaterial.shader = CombinedShader;
|
|
TargetRenderer.sharedMaterial.SetOverrideTag("RenderType", renderTag);
|
|
TargetRenderer.sharedMaterial.SetInt("_SrcBlend", srcBlend);
|
|
TargetRenderer.sharedMaterial.SetInt("_DstBlend", dstBlend);
|
|
if (transparentQueue)
|
|
{
|
|
TargetRenderer.sharedMaterial.EnableKeyword("_ALPHATEST_ON");
|
|
TargetRenderer.sharedMaterial.EnableKeyword("_ALPHABLEND_ON");
|
|
TargetRenderer.sharedMaterial.EnableKeyword("_ALPHAPREMULTIPLY_ON");
|
|
}
|
|
else
|
|
{
|
|
TargetRenderer.sharedMaterial.DisableKeyword("_ALPHATEST_ON");
|
|
TargetRenderer.sharedMaterial.DisableKeyword("_ALPHABLEND_ON");
|
|
TargetRenderer.sharedMaterial.DisableKeyword("_ALPHAPREMULTIPLY_ON");
|
|
}
|
|
TargetRenderer.sharedMaterial.renderQueue = renderQueue;
|
|
ApplyMaterialPropertyBlock();
|
|
}
|
|
}
|