Assignment for RMIT Mixed Reality in 2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

347 lines
16 KiB

using UnityEngine;
using System.Collections.Generic;
using System;
using Oculus.Avatar;
public class OvrAvatarSkinnedMeshPBSV2RenderComponent : OvrAvatarRenderComponent
{
private OvrAvatarMaterialManager avatarMaterialManager;
private bool previouslyActive = false;
private bool isCombinedMaterial = false;
private ovrAvatarExpressiveParameters ExpressiveParameters;
private bool EnableExpressive = false;
private int blendShapeCount = 0;
private ovrAvatarBlendShapeParams blendShapeParams;
private const string MAIN_MATERIAL_NAME = "main_material";
private const string EYE_MATERIAL_NAME = "eye_material";
private const string DEFAULT_MATERIAL_NAME = "_material";
internal void Initialize(
IntPtr renderPart,
ovrAvatarRenderPart_SkinnedMeshRenderPBS_V2 skinnedMeshRender,
OvrAvatarMaterialManager materialManager,
int thirdPersonLayer,
int firstPersonLayer,
bool combinedMesh,
ovrAvatarAssetLevelOfDetail lod,
bool assignExpressiveParams,
OvrAvatar avatar,
bool isControllerModel)
{
avatarMaterialManager = materialManager;
isCombinedMaterial = combinedMesh;
mesh = CreateSkinnedMesh(
skinnedMeshRender.meshAssetID,
skinnedMeshRender.visibilityMask,
thirdPersonLayer,
firstPersonLayer);
EnableExpressive = assignExpressiveParams;
#if UNITY_ANDROID
var singleComponentShader = EnableExpressive
? avatar.Skinshaded_Expressive_VertFrag_SingleComponent
: avatar.Skinshaded_VertFrag_SingleComponent;
#else
var singleComponentShader = EnableExpressive
? avatar.Skinshaded_Expressive_SurfaceShader_SingleComponent
: avatar.Skinshaded_SurfaceShader_SingleComponent;
#endif
var combinedComponentShader = EnableExpressive
? avatar.Skinshaded_Expressive_VertFrag_CombinedMesh
: avatar.Skinshaded_VertFrag_CombinedMesh;
var mainShader = isCombinedMaterial ? combinedComponentShader : singleComponentShader;
if (isControllerModel)
{
mainShader = avatar.ControllerShader;
}
AvatarLogger.Log("OvrAvatarSkinnedMeshPBSV2RenderComponent Shader is: " + mainShader != null
? mainShader.name : "null");
if (EnableExpressive)
{
ExpressiveParameters = CAPI.ovrAvatar_GetExpressiveParameters(avatar.sdkAvatar);
var eyeShader = avatar.EyeLens;
Material[] matArray = new Material[2];
matArray[0] = CreateAvatarMaterial(gameObject.name + MAIN_MATERIAL_NAME, mainShader);
matArray[1] = CreateAvatarMaterial(gameObject.name + EYE_MATERIAL_NAME, eyeShader);
if (avatar.UseTransparentRenderQueue)
{
SetMaterialTransparent(matArray[0]);
}
else
{
SetMaterialOpaque(matArray[0]);
}
// Eye lens shader queue is transparent and set from shader
matArray[1].renderQueue = -1;
mesh.materials = matArray;
}
else
{
mesh.sharedMaterial = CreateAvatarMaterial(gameObject.name + DEFAULT_MATERIAL_NAME, mainShader);
if (avatar.UseTransparentRenderQueue && !isControllerModel)
{
SetMaterialTransparent(mesh.sharedMaterial);
}
else
{
SetMaterialOpaque(mesh.sharedMaterial);
}
}
bones = mesh.bones;
if (isCombinedMaterial)
{
avatarMaterialManager.SetRenderer(mesh);
InitializeCombinedMaterial(renderPart, (int)lod);
avatarMaterialManager.OnCombinedMeshReady();
}
blendShapeParams = new ovrAvatarBlendShapeParams();
blendShapeParams.blendShapeParamCount = 0;
blendShapeParams.blendShapeParams = new float[64];
blendShapeCount = mesh.sharedMesh.blendShapeCount;
}
public void UpdateSkinnedMeshRender(
OvrAvatarComponent component,
OvrAvatar avatar,
IntPtr renderPart)
{
ovrAvatarVisibilityFlags visibilityMask
= CAPI.ovrAvatarSkinnedMeshRenderPBSV2_GetVisibilityMask(renderPart);
ovrAvatarTransform localTransform
= CAPI.ovrAvatarSkinnedMeshRenderPBSV2_GetTransform(renderPart);
UpdateSkinnedMesh(avatar, bones, localTransform, visibilityMask, renderPart);
bool isActive = gameObject.activeSelf;
if (mesh != null && !previouslyActive && isActive)
{
if (!isCombinedMaterial)
{
InitializeSingleComponentMaterial(renderPart, (int)avatar.LevelOfDetail - 1);
}
}
if (blendShapeCount > 0)
{
const float BLEND_MULTIPLIER = 100.0f;
CAPI.ovrAvatarSkinnedMeshRender_GetBlendShapeParams(renderPart, ref blendShapeParams);
for (uint i = 0; i < blendShapeParams.blendShapeParamCount && i < blendShapeCount; i++)
{
float value = blendShapeParams.blendShapeParams[i];
mesh.SetBlendShapeWeight((int)i, value * BLEND_MULTIPLIER);
}
}
previouslyActive = isActive;
}
private void InitializeSingleComponentMaterial(IntPtr renderPart, int lodIndex)
{
ovrAvatarPBSMaterialState materialState =
CAPI.ovrAvatarSkinnedMeshRenderPBSV2_GetPBSMaterialState(renderPart);
int componentType = (int)OvrAvatarMaterialManager.GetComponentType(gameObject.name);
Texture2D diffuseTexture = OvrAvatarComponent.GetLoadedTexture(materialState.albedoTextureID);
Texture2D normalTexture = OvrAvatarComponent.GetLoadedTexture(materialState.normalTextureID);
Texture2D metallicTexture = OvrAvatarComponent.GetLoadedTexture(materialState.metallicnessTextureID);
if (diffuseTexture != null)
{
avatarMaterialManager.AddTextureIDToTextureManager(materialState.albedoTextureID, true);
}
else
{
diffuseTexture = OvrAvatarSDKManager.Instance.GetTextureCopyManager().FallbackTextureSets[lodIndex].DiffuseRoughness;
}
diffuseTexture.anisoLevel = 4;
if (normalTexture != null)
{
avatarMaterialManager.AddTextureIDToTextureManager(materialState.normalTextureID, true);
}
else
{
normalTexture = OvrAvatarSDKManager.Instance.GetTextureCopyManager().FallbackTextureSets[lodIndex].Normal;
}
normalTexture.anisoLevel = 4;
if (metallicTexture != null)
{
avatarMaterialManager.AddTextureIDToTextureManager(materialState.metallicnessTextureID, true);
}
else
{
metallicTexture = OvrAvatarSDKManager.Instance.GetTextureCopyManager().FallbackTextureSets[lodIndex].DiffuseRoughness;
}
metallicTexture.anisoLevel = 16;
mesh.materials[0].SetTexture(OvrAvatarMaterialManager.AVATAR_SHADER_MAINTEX, diffuseTexture);
mesh.materials[0].SetTexture(OvrAvatarMaterialManager.AVATAR_SHADER_NORMALMAP, normalTexture);
mesh.materials[0].SetTexture(OvrAvatarMaterialManager.AVATAR_SHADER_ROUGHNESSMAP, metallicTexture);
mesh.materials[0].SetVector(OvrAvatarMaterialManager.AVATAR_SHADER_COLOR, materialState.albedoMultiplier);
mesh.materials[0].SetFloat(OvrAvatarMaterialManager.AVATAR_SHADER_DIFFUSEINTENSITY,
OvrAvatarMaterialManager.DiffuseIntensities[componentType]);
mesh.materials[0].SetFloat(OvrAvatarMaterialManager.AVATAR_SHADER_RIMINTENSITY,
OvrAvatarMaterialManager.RimIntensities[componentType]);
mesh.materials[0].SetFloat(OvrAvatarMaterialManager.AVATAR_SHADER_REFLECTIONINTENSITY,
OvrAvatarMaterialManager.ReflectionIntensities[componentType]);
mesh.GetClosestReflectionProbes(avatarMaterialManager.ReflectionProbes);
if (avatarMaterialManager.ReflectionProbes != null &&
avatarMaterialManager.ReflectionProbes.Count > 0)
{
mesh.materials[0].SetTexture(OvrAvatarMaterialManager.AVATAR_SHADER_CUBEMAP,
avatarMaterialManager.ReflectionProbes[0].probe.texture);
}
if (EnableExpressive)
{
mesh.materials[0].SetVector(OvrAvatarMaterialManager.AVATAR_SHADER_IRIS_COLOR,
ExpressiveParameters.irisColor);
mesh.materials[0].SetVector(OvrAvatarMaterialManager.AVATAR_SHADER_LIP_COLOR,
ExpressiveParameters.lipColor);
mesh.materials[0].SetVector(OvrAvatarMaterialManager.AVATAR_SHADER_BROW_COLOR,
ExpressiveParameters.browColor);
mesh.materials[0].SetVector(OvrAvatarMaterialManager.AVATAR_SHADER_LASH_COLOR,
ExpressiveParameters.lashColor);
mesh.materials[0].SetVector(OvrAvatarMaterialManager.AVATAR_SHADER_SCLERA_COLOR,
ExpressiveParameters.scleraColor);
mesh.materials[0].SetVector(OvrAvatarMaterialManager.AVATAR_SHADER_GUM_COLOR,
ExpressiveParameters.gumColor);
mesh.materials[0].SetVector(OvrAvatarMaterialManager.AVATAR_SHADER_TEETH_COLOR,
ExpressiveParameters.teethColor);
mesh.materials[0].SetFloat(OvrAvatarMaterialManager.AVATAR_SHADER_LIP_SMOOTHNESS,
ExpressiveParameters.lipSmoothness);
}
}
private void InitializeCombinedMaterial(IntPtr renderPart, int lodIndex)
{
ovrAvatarPBSMaterialState[] materialStates = CAPI.ovrAvatar_GetBodyPBSMaterialStates(renderPart);
if (materialStates.Length == (int)ovrAvatarBodyPartType.Count)
{
avatarMaterialManager.CreateTextureArrays();
var localProperties = avatarMaterialManager.LocalAvatarConfig.ComponentMaterialProperties;
AvatarLogger.Log("InitializeCombinedMaterial - Loading Material States");
for (int i = 0; i < materialStates.Length; i++)
{
localProperties[i].TypeIndex = (ovrAvatarBodyPartType)i;
localProperties[i].Color = materialStates[i].albedoMultiplier;
localProperties[i].DiffuseIntensity = OvrAvatarMaterialManager.DiffuseIntensities[i];
localProperties[i].RimIntensity = OvrAvatarMaterialManager.RimIntensities[i];
localProperties[i].ReflectionIntensity = OvrAvatarMaterialManager.ReflectionIntensities[i];
var diffuse = OvrAvatarComponent.GetLoadedTexture(materialStates[i].albedoTextureID);
var normal = OvrAvatarComponent.GetLoadedTexture(materialStates[i].normalTextureID);
var roughness = OvrAvatarComponent.GetLoadedTexture(materialStates[i].metallicnessTextureID);
if (diffuse != null)
{
localProperties[i].Textures[(int)OvrAvatarMaterialManager.TextureType.DiffuseTextures] = diffuse;
avatarMaterialManager.AddTextureIDToTextureManager(materialStates[i].albedoTextureID, false);
}
else
{
localProperties[i].Textures[(int)OvrAvatarMaterialManager.TextureType.DiffuseTextures] =
OvrAvatarSDKManager.Instance.GetTextureCopyManager().FallbackTextureSets[lodIndex].DiffuseRoughness;
}
localProperties[i].Textures[(int)OvrAvatarMaterialManager.TextureType.DiffuseTextures].anisoLevel = 4;
if (normal != null)
{
localProperties[i].Textures[(int)OvrAvatarMaterialManager.TextureType.NormalMaps] = normal;
avatarMaterialManager.AddTextureIDToTextureManager(materialStates[i].normalTextureID, false);
}
else
{
localProperties[i].Textures[(int)OvrAvatarMaterialManager.TextureType.NormalMaps] =
OvrAvatarSDKManager.Instance.GetTextureCopyManager().FallbackTextureSets[lodIndex].Normal;
}
localProperties[i].Textures[(int)OvrAvatarMaterialManager.TextureType.NormalMaps].anisoLevel = 4;
if (roughness != null)
{
localProperties[i].Textures[(int)OvrAvatarMaterialManager.TextureType.RoughnessMaps] = roughness;
avatarMaterialManager.AddTextureIDToTextureManager(materialStates[i].metallicnessTextureID, false);
}
else
{
localProperties[i].Textures[(int)OvrAvatarMaterialManager.TextureType.RoughnessMaps] =
OvrAvatarSDKManager.Instance.GetTextureCopyManager().FallbackTextureSets[lodIndex].DiffuseRoughness;
}
localProperties[i].Textures[(int)OvrAvatarMaterialManager.TextureType.RoughnessMaps].anisoLevel = 16;
AvatarLogger.Log(localProperties[i].TypeIndex.ToString());
AvatarLogger.Log(AvatarLogger.Tab + "Diffuse: " + materialStates[i].albedoTextureID);
AvatarLogger.Log(AvatarLogger.Tab + "Normal: " + materialStates[i].normalTextureID);
AvatarLogger.Log(AvatarLogger.Tab + "Metallic: " + materialStates[i].metallicnessTextureID);
}
if (EnableExpressive)
{
mesh.materials[0].SetVector(OvrAvatarMaterialManager.AVATAR_SHADER_IRIS_COLOR,
ExpressiveParameters.irisColor);
mesh.materials[0].SetVector(OvrAvatarMaterialManager.AVATAR_SHADER_LIP_COLOR,
ExpressiveParameters.lipColor);
mesh.materials[0].SetVector(OvrAvatarMaterialManager.AVATAR_SHADER_BROW_COLOR,
ExpressiveParameters.browColor);
mesh.materials[0].SetVector(OvrAvatarMaterialManager.AVATAR_SHADER_LASH_COLOR,
ExpressiveParameters.lashColor);
mesh.materials[0].SetVector(OvrAvatarMaterialManager.AVATAR_SHADER_SCLERA_COLOR,
ExpressiveParameters.scleraColor);
mesh.materials[0].SetVector(OvrAvatarMaterialManager.AVATAR_SHADER_GUM_COLOR,
ExpressiveParameters.gumColor);
mesh.materials[0].SetVector(OvrAvatarMaterialManager.AVATAR_SHADER_TEETH_COLOR,
ExpressiveParameters.teethColor);
mesh.materials[0].SetFloat(OvrAvatarMaterialManager.AVATAR_SHADER_LIP_SMOOTHNESS,
ExpressiveParameters.lipSmoothness);
}
avatarMaterialManager.ValidateTextures(materialStates);
}
}
private void SetMaterialTransparent(Material mat)
{
// Initialize shader to use transparent render queue with alpha blending
mat.SetOverrideTag("Queue", "Transparent");
mat.SetOverrideTag("RenderType", "Transparent");
mat.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
mat.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
mat.EnableKeyword("_ALPHATEST_ON");
mat.EnableKeyword("_ALPHABLEND_ON");
mat.EnableKeyword("_ALPHAPREMULTIPLY_ON");
mat.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
}
private void SetMaterialOpaque(Material mat)
{
// Initialize shader to use geometry render queue with no blending
mat.SetOverrideTag("Queue", "Geometry");
mat.SetOverrideTag("RenderType", "Opaque");
mat.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
mat.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
mat.DisableKeyword("_ALPHATEST_ON");
mat.DisableKeyword("_ALPHABLEND_ON");
mat.DisableKeyword("_ALPHAPREMULTIPLY_ON");
mat.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Geometry;
}
}