예제 #1
0
파일: OvrAvatar.cs 프로젝트: Geli25/COPA
    private OvrAvatarSkinnedMeshPBSV2RenderComponent AddSkinnedMeshRenderPBSV2Component(
        IntPtr renderPart,
        GameObject go,
        ovrAvatarRenderPart_SkinnedMeshRenderPBS_V2 skinnedMeshRenderPBSV2,
        OvrAvatarMaterialManager materialManager,
        bool isBodyPartZero,
        bool isControllerModel)
    {
        OvrAvatarSkinnedMeshPBSV2RenderComponent skinnedMeshRenderer = go.AddComponent <OvrAvatarSkinnedMeshPBSV2RenderComponent>();

        skinnedMeshRenderer.Initialize(
            renderPart,
            skinnedMeshRenderPBSV2,
            materialManager,
            ThirdPersonLayer.layerIndex,
            FirstPersonLayer.layerIndex,
            renderPartCount++,
            isBodyPartZero && CombineMeshes,
            LevelOfDetail,
            isBodyPartZero && EnableExpressive,
            this,
            isControllerModel);

        return(skinnedMeshRenderer);
    }
예제 #2
0
    private void InitializeSingleComponentMaterial(IntPtr renderPart, int lodIndex)
    {
        ovrAvatarPBSMaterialState materialState =
            CAPI.ovrAvatarSkinnedMeshRenderPBSV2_GetPBSMaterialState(renderPart);

        int componentType = (int)OvrAvatarMaterialManager.GetComponentType(gameObject.name);

        var defaultProperties = AvatarMaterialManager.DefaultAvatarConfig.ComponentMaterialProperties;

        var diffuseTexture  = OvrAvatarComponent.GetLoadedTexture(materialState.albedoTextureID);
        var normalTexture   = OvrAvatarComponent.GetLoadedTexture(materialState.normalTextureID);
        var metallicTexture = OvrAvatarComponent.GetLoadedTexture(materialState.metallicnessTextureID);

        if (diffuseTexture == null)
        {
            diffuseTexture = AvatarMaterialManager.DiffuseFallbacks[lodIndex];
        }

        if (normalTexture == null)
        {
            normalTexture = AvatarMaterialManager.NormalFallbacks[lodIndex];
        }

        if (metallicTexture == null)
        {
            metallicTexture = AvatarMaterialManager.DiffuseFallbacks[lodIndex];
        }

        mesh.sharedMaterial.SetTexture(OvrAvatarMaterialManager.AVATAR_SHADER_MAINTEX, diffuseTexture);
        mesh.sharedMaterial.SetTexture(OvrAvatarMaterialManager.AVATAR_SHADER_NORMALMAP, normalTexture);
        mesh.sharedMaterial.SetTexture(OvrAvatarMaterialManager.AVATAR_SHADER_ROUGHNESSMAP, metallicTexture);

        mesh.sharedMaterial.SetVector(OvrAvatarMaterialManager.AVATAR_SHADER_COLOR,
                                      materialState.albedoMultiplier);

        mesh.sharedMaterial.SetFloat(OvrAvatarMaterialManager.AVATAR_SHADER_DIFFUSEINTENSITY,
                                     defaultProperties[componentType].DiffuseIntensity);

        mesh.sharedMaterial.SetFloat(OvrAvatarMaterialManager.AVATAR_SHADER_RIMINTENSITY,
                                     defaultProperties[componentType].RimIntensity);

        mesh.sharedMaterial.SetFloat(OvrAvatarMaterialManager.AVATAR_SHADER_BACKLIGHTINTENSITY,
                                     defaultProperties[componentType].BacklightIntensity);

        mesh.sharedMaterial.SetFloat(OvrAvatarMaterialManager.AVATAR_SHADER_REFLECTIONINTENSITY,
                                     defaultProperties[componentType].ReflectionIntensity);

        mesh.GetClosestReflectionProbes(AvatarMaterialManager.ReflectionProbes);
        if (AvatarMaterialManager.ReflectionProbes != null &&
            AvatarMaterialManager.ReflectionProbes.Count > 0)
        {
            mesh.sharedMaterial.SetTexture(OvrAvatarMaterialManager.AVATAR_SHADER_CUBEMAP,
                                           AvatarMaterialManager.ReflectionProbes[0].probe.texture);
        }

#if UNITY_EDITOR
        mesh.sharedMaterial.EnableKeyword("FIX_NORMAL_ON");
#endif
        mesh.sharedMaterial.EnableKeyword("PBR_LIGHTING_ON");
    }
예제 #3
0
    private void AddRenderParts(
        OvrAvatarComponent ovrComponent,
        ovrAvatarComponent component,
        Transform parent)
    {
        for (UInt32 renderPartIndex = 0; renderPartIndex < component.renderPartCount; renderPartIndex++)
        {
            GameObject renderPartObject = new GameObject();
            renderPartObject.name = GetRenderPartName(component, renderPartIndex);
            renderPartObject.transform.SetParent(parent);
            IntPtr renderPart             = GetRenderPart(component, renderPartIndex);
            ovrAvatarRenderPartType  type = CAPI.ovrAvatarRenderPart_GetType(renderPart);
            OvrAvatarRenderComponent ovrRenderPart;
            switch (type)
            {
            case ovrAvatarRenderPartType.SkinnedMeshRender:
                ovrRenderPart = AddSkinnedMeshRenderComponent(renderPartObject, CAPI.ovrAvatarRenderPart_GetSkinnedMeshRender(renderPart));
                break;

            case ovrAvatarRenderPartType.SkinnedMeshRenderPBS:
                ovrRenderPart = AddSkinnedMeshRenderPBSComponent(renderPartObject, CAPI.ovrAvatarRenderPart_GetSkinnedMeshRenderPBS(renderPart));
                break;

            case ovrAvatarRenderPartType.ProjectorRender:
                ovrRenderPart = AddProjectorRenderComponent(renderPartObject, CAPI.ovrAvatarRenderPart_GetProjectorRender(renderPart));
                break;

            case ovrAvatarRenderPartType.SkinnedMeshRenderPBS_V2:
            {
                OvrAvatarMaterialManager materialManager = null;

                if (ovrComponent.name == "body")
                {
                    materialManager = DefaultBodyMaterialManager;
                }
                else if (ovrComponent.name.Contains("hand"))
                {
                    materialManager = DefaultHandMaterialManager;
                }

                ovrRenderPart = AddSkinnedMeshRenderPBSV2Component(
                    renderPart,
                    renderPartObject,
                    CAPI.ovrAvatarRenderPart_GetSkinnedMeshRenderPBSV2(renderPart),
                    materialManager);
            }
            break;

            default:
                throw new NotImplementedException(string.Format("Unsupported render part type: {0}", type.ToString()));
            }

            ovrComponent.RenderParts.Add(ovrRenderPart);
        }
    }
예제 #4
0
    internal void Initialize(
        IntPtr renderPart,
        ovrAvatarRenderPart_SkinnedMeshRenderPBS_V2 skinnedMeshRender,
        OvrAvatarMaterialManager materialManager,
        int thirdPersonLayer,
        int firstPersonLayer,
        int sortOrder,
        bool isCombinedMaterial,
        ovrAvatarAssetLevelOfDetail lod)
    {
        AvatarMaterialManager = materialManager;
        IsCombinedMaterial    = isCombinedMaterial;

        mesh = CreateSkinnedMesh(
            skinnedMeshRender.meshAssetID,
            skinnedMeshRender.visibilityMask,
            thirdPersonLayer,
            firstPersonLayer,
            sortOrder);

#if UNITY_ANDROID
        var singleComponentShader = "OvrAvatar/Avatar_Mobile_SingleComponent";
#else
        var singleComponentShader = "OvrAvatar/Avatar_PC_SingleComponent";
#endif

        var shader = IsCombinedMaterial
             ? Shader.Find("OvrAvatar/Avatar_Mobile_CombinedMesh")
             : Shader.Find(singleComponentShader);

        AvatarLogger.Log("Shader is: " + shader.name);

        mesh.sharedMaterial             = CreateAvatarMaterial(gameObject.name + "_material", shader);
        mesh.sharedMaterial.renderQueue = OvrAvatarMaterialManager.RENDER_QUEUE;

        bones = mesh.bones;

        if (IsCombinedMaterial)
        {
            AvatarMaterialManager.SetRenderer(mesh);
            InitializeCombinedMaterial(renderPart, (int)lod - 1);
            AvatarMaterialManager.OnCombinedMeshReady();
        }
    }
예제 #5
0
    private OvrAvatarSkinnedMeshPBSV2RenderComponent AddSkinnedMeshRenderPBSV2Component(
        IntPtr renderPart,
        GameObject gameObject,
        ovrAvatarRenderPart_SkinnedMeshRenderPBS_V2 skinnedMeshRenderPBSV2,
        OvrAvatarMaterialManager materialManager)
    {
        OvrAvatarSkinnedMeshPBSV2RenderComponent skinnedMeshRenderer = gameObject.AddComponent <OvrAvatarSkinnedMeshPBSV2RenderComponent>();

        skinnedMeshRenderer.Initialize(
            renderPart,
            skinnedMeshRenderPBSV2,
            materialManager,
            ThirdPersonLayer.layerIndex,
            FirstPersonLayer.layerIndex,
            renderPartCount++,
            gameObject.name.Contains("body") && CombineMeshes,
            LevelOfDetail);

        return(skinnedMeshRenderer);
    }
    void Start()
    {
        if (OvrAvatarSDKManager.Instance == null)
        {
            return;
        }
#if !UNITY_ANDROID
        if (CombineMeshes)
        {
            CombineMeshes = false;
            AvatarLogger.Log("Combined Meshes currently only supported on mobile");
        }
#endif
#if !UNITY_5_5_OR_NEWER
        if (CombineMeshes)
        {
            CombineMeshes = false;
            AvatarLogger.LogWarning("Combined Meshes requires Unity 5.5.0+");
        }
#endif
        materialManager = gameObject.AddComponent <OvrAvatarMaterialManager>();

        try
        {
            oculusUserIDInternal = UInt64.Parse(oculusUserID);
        }
        catch (Exception)
        {
            oculusUserIDInternal = 0;
            AvatarLogger.LogWarning("Invalid Oculus User ID Format");
        }

        // If no oculus ID is supplied then turn off combine meshes to prevent the texture arrays
        // being populated by invalid textures.
        if (oculusUserIDInternal == 0)
        {
            AvatarLogger.LogWarning("Oculus User ID set to 0. Provide actual user ID: " + gameObject.name);
            CombineMeshes = false;
        }

        AvatarLogger.Log("Starting OvrAvatar " + gameObject.name);
        AvatarLogger.Log(AvatarLogger.Tab + "LOD: " + LevelOfDetail.ToString());
        AvatarLogger.Log(AvatarLogger.Tab + "Combine Meshes: " + CombineMeshes);
        AvatarLogger.Log(AvatarLogger.Tab + "Force Mobile Textures: " + USE_MOBILE_TEXTURE_FORMAT);
        AvatarLogger.Log(AvatarLogger.Tab + "Oculus User ID: " + oculusUserIDInternal);

        Capabilities = 0;

        bool is3Dof      = false;
        var  headsetType = OVRPlugin.GetSystemHeadsetType();
        switch (headsetType)
        {
        case OVRPlugin.SystemHeadset.GearVR_R320:
        case OVRPlugin.SystemHeadset.GearVR_R321:
        case OVRPlugin.SystemHeadset.GearVR_R322:
        case OVRPlugin.SystemHeadset.GearVR_R323:
        case OVRPlugin.SystemHeadset.GearVR_R324:
        case OVRPlugin.SystemHeadset.GearVR_R325:
        case OVRPlugin.SystemHeadset.Oculus_Go:
            is3Dof = true;
            break;

        case OVRPlugin.SystemHeadset.Oculus_Quest:
        case OVRPlugin.SystemHeadset.Rift_S:
        case OVRPlugin.SystemHeadset.Rift_DK1:
        case OVRPlugin.SystemHeadset.Rift_DK2:
        case OVRPlugin.SystemHeadset.Rift_CV1:
        default:
            break;
        }

        // The SDK 3 DOF Arm Model requires the body skeleton to pose itself. It will crash without it
        // The likely use case here is trying to have an invisible body.
        // T45010595
        if (is3Dof && !EnableBody)
        {
            AvatarLogger.Log("Forcing the Body component for 3Dof hand tracking, and setting the visibility to 1st person");
            EnableBody      = true;
            ShowFirstPerson = true;
            ShowThirdPerson = false;
        }

        if (EnableBody)
        {
            Capabilities |= ovrAvatarCapabilities.Body;
        }
        if (EnableHands)
        {
            Capabilities |= ovrAvatarCapabilities.Hands;
        }
        if (EnableBase && EnableBody)
        {
            Capabilities |= ovrAvatarCapabilities.Base;
        }
        if (EnableExpressive)
        {
            Capabilities |= ovrAvatarCapabilities.Expressive;
        }

        // Enable body tilt on 6dof devices
        if (OVRPlugin.positionSupported)
        {
            Capabilities |= ovrAvatarCapabilities.BodyTilt;
        }

        ShowLeftController(StartWithControllers);
        ShowRightController(StartWithControllers);

        OvrAvatarSDKManager.AvatarSpecRequestParams avatarSpecRequest = new OvrAvatarSDKManager.AvatarSpecRequestParams(
            oculusUserIDInternal,
            this.AvatarSpecificationCallback,
            CombineMeshes,
            LevelOfDetail,
            USE_MOBILE_TEXTURE_FORMAT,
            LookAndFeelVersion,
            FallbackLookAndFeelVersion,
            EnableExpressive);

        OvrAvatarSDKManager.Instance.RequestAvatarSpecification(avatarSpecRequest);
        OvrAvatarSDKManager.Instance.AddLoadingAvatar(GetInstanceID());

        waitingForCombinedMesh = CombineMeshes;
        if (Driver != null)
        {
            Driver.Mode = UseSDKPackets ? OvrAvatarDriver.PacketMode.SDK : OvrAvatarDriver.PacketMode.Unity;
        }
    }
예제 #7
0
    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;
    }
예제 #8
0
    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);
        }
    }
예제 #9
0
    void Start()
    {
        if (OvrAvatarSDKManager.Instance == null)
        {
            return;
        }
#if !UNITY_ANDROID
        if (CombineMeshes)
        {
            CombineMeshes = false;
            AvatarLogger.Log("Combined Meshes currently only supported on mobile");
        }
#endif
#if !UNITY_5_5_OR_NEWER
        if (CombineMeshes)
        {
            CombineMeshes = false;
            AvatarLogger.LogWarning("Combined Meshes requires Unity 5.5.0+");
        }
#endif
        materialManager = gameObject.AddComponent <OvrAvatarMaterialManager>();

        try
        {
            oculusUserIDInternal = UInt64.Parse(oculusUserID);
        }
        catch (Exception)
        {
            oculusUserIDInternal = 0;
            AvatarLogger.LogWarning("Invalid Oculus User ID Format");
        }

        // If no oculus ID is supplied then turn off combine meshes to prevent the texture arrays
        // being populated by invalid textures.
        if (oculusUserIDInternal == 0)
        {
            AvatarLogger.LogWarning("Oculus User ID set to 0. Provide actual user ID: " + gameObject.name);
            CombineMeshes = false;
        }

        AvatarLogger.Log("Starting OvrAvatar " + gameObject.name);
        AvatarLogger.Log(AvatarLogger.Tab + "LOD: " + LevelOfDetail.ToString());
        AvatarLogger.Log(AvatarLogger.Tab + "Combine Meshes: " + CombineMeshes);
        AvatarLogger.Log(AvatarLogger.Tab + "Force Mobile Textures: " + USE_MOBILE_TEXTURE_FORMAT);
        AvatarLogger.Log(AvatarLogger.Tab + "Oculus User ID: " + oculusUserIDInternal);

        Capabilities = 0;
        if (EnableBody)
        {
            Capabilities |= ovrAvatarCapabilities.Body;
        }
        if (EnableHands)
        {
            Capabilities |= ovrAvatarCapabilities.Hands;
        }
        if (EnableBase && EnableBody)
        {
            Capabilities |= ovrAvatarCapabilities.Base;
        }
        if (EnableExpressive)
        {
            Capabilities |= ovrAvatarCapabilities.Expressive;
        }

        // Enable body tilt on 6dof devices
        if (OVRPlugin.positionSupported)
        {
            Capabilities |= ovrAvatarCapabilities.BodyTilt;
        }

        ShowLeftController(StartWithControllers);
        ShowRightController(StartWithControllers);

        OvrAvatarSDKManager.AvatarSpecRequestParams avatarSpecRequest = new OvrAvatarSDKManager.AvatarSpecRequestParams(
            oculusUserIDInternal,
            this.AvatarSpecificationCallback,
            CombineMeshes,
            LevelOfDetail,
            USE_MOBILE_TEXTURE_FORMAT,
            LookAndFeelVersion,
            FallbackLookAndFeelVersion,
            EnableExpressive);

        OvrAvatarSDKManager.Instance.RequestAvatarSpecification(avatarSpecRequest);
        OvrAvatarSDKManager.Instance.AddLoadingAvatar(GetInstanceID());

        waitingForCombinedMesh = CombineMeshes;
        if (Driver != null)
        {
            Driver.Mode = UseSDKPackets ? OvrAvatarDriver.PacketMode.SDK : OvrAvatarDriver.PacketMode.Unity;
        }
    }
    internal void Initialize(
        IntPtr renderPart,
        ovrAvatarRenderPart_SkinnedMeshRenderPBS_V2 skinnedMeshRender,
        OvrAvatarMaterialManager materialManager,
        int thirdPersonLayer,
        int firstPersonLayer,
        int sortOrder,
        bool isCombinedMaterial,
        ovrAvatarAssetLevelOfDetail lod,
        bool assignExpressiveParams,
        OvrAvatar avatar,
        bool isControllerModel)
    {
        AvatarMaterialManager = materialManager;
        IsCombinedMaterial    = isCombinedMaterial;

        mesh = CreateSkinnedMesh(
            skinnedMeshRender.meshAssetID,
            skinnedMeshRender.visibilityMask,
            thirdPersonLayer,
            firstPersonLayer,
            sortOrder);

        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 = Shader.Find("OvrAvatar/AvatarPBRV2Simple");
        }

        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)
            {
                // Initialize shader to use transparent render queue with alpha blending
                matArray[0].SetOverrideTag("RenderType", "Transparent");
                matArray[0].SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
                matArray[0].SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
                matArray[0].EnableKeyword("_ALPHATEST_ON");
                matArray[0].EnableKeyword("_ALPHABLEND_ON");
                matArray[0].EnableKeyword("_ALPHAPREMULTIPLY_ON");
                matArray[0].renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
            }
            else
            {
                // Initialize shader to use geometry render queue with no blending
                matArray[0].SetOverrideTag("RenderType", "Opaque");
                matArray[0].SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                matArray[0].SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
                matArray[0].DisableKeyword("_ALPHATEST_ON");
                matArray[0].DisableKeyword("_ALPHABLEND_ON");
                matArray[0].DisableKeyword("_ALPHAPREMULTIPLY_ON");
                matArray[0].renderQueue = (int)UnityEngine.Rendering.RenderQueue.Geometry;
            }
            // 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)
            {
                // Initialize shader to use transparent render queue with alpha blending
                mesh.sharedMaterial.SetOverrideTag("RenderType", "Transparent");
                mesh.sharedMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
                mesh.sharedMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
                mesh.sharedMaterial.EnableKeyword("_ALPHATEST_ON");
                mesh.sharedMaterial.EnableKeyword("_ALPHABLEND_ON");
                mesh.sharedMaterial.EnableKeyword("_ALPHAPREMULTIPLY_ON");
                mesh.sharedMaterial.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
            }
            else
            {
                // Initialize shader to use geometry render queue with no blending
                mesh.sharedMaterial.SetOverrideTag("RenderType", "Opaque");
                mesh.sharedMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                mesh.sharedMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
                mesh.sharedMaterial.DisableKeyword("_ALPHATEST_ON");
                mesh.sharedMaterial.DisableKeyword("_ALPHABLEND_ON");
                mesh.sharedMaterial.DisableKeyword("_ALPHAPREMULTIPLY_ON");
                mesh.sharedMaterial.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Geometry;
            }
        }
        bones = mesh.bones;

        if (IsCombinedMaterial)
        {
            AvatarMaterialManager.SetRenderer(mesh);
            InitializeCombinedMaterial(renderPart, (int)lod - 1);
            AvatarMaterialManager.OnCombinedMeshReady();
        }
    }
    private void InitializeSingleComponentMaterial(IntPtr renderPart, int lodIndex)
    {
        ovrAvatarPBSMaterialState materialState =
            CAPI.ovrAvatarSkinnedMeshRenderPBSV2_GetPBSMaterialState(renderPart);

        int componentType = (int)OvrAvatarMaterialManager.GetComponentType(gameObject.name);

        var defaultProperties = AvatarMaterialManager.DefaultAvatarConfig.ComponentMaterialProperties;

        var diffuseTexture  = OvrAvatarComponent.GetLoadedTexture(materialState.albedoTextureID);
        var normalTexture   = OvrAvatarComponent.GetLoadedTexture(materialState.normalTextureID);
        var metallicTexture = OvrAvatarComponent.GetLoadedTexture(materialState.metallicnessTextureID);

        if (diffuseTexture == null)
        {
            diffuseTexture = AvatarMaterialManager.DiffuseFallbacks[lodIndex];
        }

        if (normalTexture == null)
        {
            normalTexture = AvatarMaterialManager.NormalFallbacks[lodIndex];
        }

        if (metallicTexture == null)
        {
            metallicTexture = AvatarMaterialManager.DiffuseFallbacks[lodIndex];
        }

        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,
                                   defaultProperties[componentType].DiffuseIntensity);

        mesh.materials[0].SetFloat(OvrAvatarMaterialManager.AVATAR_SHADER_RIMINTENSITY,
                                   defaultProperties[componentType].RimIntensity);

        mesh.materials[0].SetFloat(OvrAvatarMaterialManager.AVATAR_SHADER_REFLECTIONINTENSITY,
                                   defaultProperties[componentType].ReflectionIntensity);

        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);
        }
    }