< Summary

Class:DCL.Components.PBRMaterial
Assembly:MainScripts
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Components/Materials/PBRMaterial.cs
Covered lines:123
Uncovered lines:29
Coverable lines:152
Total lines:330
Line coverage:80.9% (123 of 152)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
Model()0%110100%
GetDataFromJSON(...)0%110100%
PBRMaterial()0%110100%
GetModel()0%2100%
GetClassId()0%2100%
AttachTo(...)0%2.032080%
ApplyChanges(...)0%440100%
SetupTransparencyMode()0%168050%
LoadMaterial(...)0%4.054085.71%
OnMaterialAttached(...)0%330100%
InitMaterial(...)0%8.518080%
OnShapeUpdated(...)0%220100%
OnMaterialDetached(...)0%440100%
SetMaterialTexture(...)0%4.054085.71%
AreSameTextureComponent(...)0%2.152066.67%
SwitchTextureComponent(...)0%220100%
Dispose()0%660100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Components/Materials/PBRMaterial.cs

#LineLine coverage
 1using DCL.Controllers;
 2using DCL.Helpers;
 3using DCL.Models;
 4using System.Collections;
 5using UnityEngine;
 6using UnityEngine.Rendering;
 7
 8namespace DCL.Components
 9{
 10    public class PBRMaterial : BaseDisposable
 11    {
 12        [System.Serializable]
 13        public class Model : BaseModel
 14        {
 15            [Range(0f, 1f)]
 6316            public float alphaTest = 0.5f;
 17
 6318            public Color albedoColor = Color.white;
 19            public string albedoTexture;
 6320            public Color ambientColor = Color.white;
 6321            public float metallic = 0.5f;
 6322            public float roughness = 0.5f;
 6323            public float microSurface = 1f; // Glossiness
 6324            public float specularIntensity = 1f;
 25
 26            public string alphaTexture;
 27            public string emissiveTexture;
 6328            public Color emissiveColor = Color.black;
 6329            public float emissiveIntensity = 2f;
 6330            public Color reflectionColor = Color.white; // Specular color
 6331            public Color reflectivityColor = Color.white;
 6332            public float directIntensity = 1f;
 6333            public float environmentIntensity = 1f;
 34            public string bumpTexture;
 35            public string refractionTexture;
 6336            public bool castShadows = true;
 37
 38            [Range(0, 4)]
 6339            public int transparencyMode = 4; // 0: OPAQUE; 1: ALPHATEST; 2: ALPHBLEND; 3: ALPHATESTANDBLEND; 4: AUTO (En
 40
 2241            public override BaseModel GetDataFromJSON(string json) { return Utils.SafeFromJson<Model>(json); }
 42        }
 43
 44        enum TransparencyMode
 45        {
 46            OPAQUE,
 47            ALPHA_TEST,
 48            ALPHA_BLEND,
 49            ALPHA_TEST_AND_BLEND,
 50            AUTO
 51        }
 52
 053        public Material material { get; set; }
 54        private string currentMaterialResourcesFilename;
 55
 56        const string MATERIAL_RESOURCES_PATH = "Materials/";
 57        const string PBR_MATERIAL_NAME = "ShapeMaterial";
 58
 59        DCLTexture albedoDCLTexture = null;
 60        DCLTexture alphaDCLTexture = null;
 61        DCLTexture emissiveDCLTexture = null;
 62        DCLTexture bumpDCLTexture = null;
 63
 1964        public PBRMaterial()
 65        {
 1966            model = new Model();
 67
 1968            LoadMaterial(PBR_MATERIAL_NAME);
 69
 1970            OnAttach += OnMaterialAttached;
 1971            OnDetach += OnMaterialDetached;
 1972        }
 73
 074        new public Model GetModel() { return (Model) model; }
 75
 076        public override int GetClassId() { return (int) CLASS_ID.PBR_MATERIAL; }
 77
 78        public override void AttachTo(IDCLEntity entity, System.Type overridenAttachedType = null)
 79        {
 2080            if (attachedEntities.Contains(entity))
 81            {
 082                return;
 83            }
 84
 2085            entity.RemoveSharedComponent(typeof(BasicMaterial));
 2086            base.AttachTo(entity);
 2087        }
 88
 89        public override IEnumerator ApplyChanges(BaseModel newModel)
 90        {
 2291            Model model = (Model) newModel;
 92
 2293            LoadMaterial(PBR_MATERIAL_NAME);
 94
 2295            material.SetColor(ShaderUtils.BaseColor, model.albedoColor);
 96
 2297            if (model.emissiveColor != Color.clear && model.emissiveColor != Color.black)
 98            {
 499                material.EnableKeyword("_EMISSION");
 100            }
 101
 102            // METALLIC/SPECULAR CONFIGURATIONS
 22103            material.SetColor(ShaderUtils.EmissionColor, model.emissiveColor * model.emissiveIntensity);
 22104            material.SetColor(ShaderUtils.SpecColor, model.reflectivityColor);
 105
 22106            material.SetFloat(ShaderUtils.Metallic, model.metallic);
 22107            material.SetFloat(ShaderUtils.Smoothness, 1 - model.roughness);
 22108            material.SetFloat(ShaderUtils.EnvironmentReflections, model.microSurface);
 22109            material.SetFloat(ShaderUtils.SpecularHighlights, model.specularIntensity * model.directIntensity);
 110
 111            // FETCH AND LOAD EMISSIVE TEXTURE
 22112            SetMaterialTexture(ShaderUtils.EmissionMap, model.emissiveTexture, emissiveDCLTexture);
 113
 22114            SetupTransparencyMode();
 115
 116            // FETCH AND LOAD TEXTURES
 22117            SetMaterialTexture(ShaderUtils.BaseMap, model.albedoTexture, albedoDCLTexture);
 22118            SetMaterialTexture(ShaderUtils.AlphaTexture, model.alphaTexture, alphaDCLTexture);
 22119            SetMaterialTexture(ShaderUtils.BumpMap, model.bumpTexture, bumpDCLTexture);
 120
 50121            foreach (IDCLEntity decentralandEntity in attachedEntities)
 122            {
 3123                InitMaterial(decentralandEntity.meshRootGameObject);
 124            }
 125
 22126            return null;
 127        }
 128
 129        private void SetupTransparencyMode()
 130        {
 22131            Model model = (Model) this.model;
 132
 133            // Reset shader keywords
 22134            material.DisableKeyword("_ALPHATEST_ON"); // Cut Out Transparency
 22135            material.DisableKeyword("_ALPHABLEND_ON"); // Fade Transparency
 22136            material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); // Transparent
 137
 22138            TransparencyMode transparencyMode = (TransparencyMode) model.transparencyMode;
 139
 22140            if (transparencyMode == TransparencyMode.AUTO)
 141            {
 14142                if (!string.IsNullOrEmpty(model.alphaTexture) || model.albedoColor.a < 1f) //AlphaBlend
 143                {
 0144                    transparencyMode = TransparencyMode.ALPHA_BLEND;
 0145                }
 146                else // Opaque
 147                {
 14148                    transparencyMode = TransparencyMode.OPAQUE;
 149                }
 150            }
 151
 152            switch (transparencyMode)
 153            {
 154                case TransparencyMode.OPAQUE:
 14155                    material.renderQueue = (int) UnityEngine.Rendering.RenderQueue.Geometry;
 14156                    material.SetFloat(ShaderUtils.AlphaClip, 0);
 14157                    break;
 158                case TransparencyMode.ALPHA_TEST: // ALPHATEST
 0159                    material.EnableKeyword("_ALPHATEST_ON");
 160
 0161                    material.SetInt(ShaderUtils.SrcBlend, (int) UnityEngine.Rendering.BlendMode.One);
 0162                    material.SetInt(ShaderUtils.DstBlend, (int) UnityEngine.Rendering.BlendMode.Zero);
 0163                    material.SetInt(ShaderUtils.ZWrite, 1);
 0164                    material.SetFloat(ShaderUtils.AlphaClip, 1);
 0165                    material.SetFloat(ShaderUtils.Cutoff, model.alphaTest);
 0166                    material.SetInt("_Surface", 0);
 0167                    material.renderQueue = (int) UnityEngine.Rendering.RenderQueue.AlphaTest;
 0168                    break;
 169                case TransparencyMode.ALPHA_BLEND: // ALPHABLEND
 8170                    material.EnableKeyword("_ALPHABLEND_ON");
 171
 8172                    material.SetInt(ShaderUtils.SrcBlend, (int) UnityEngine.Rendering.BlendMode.SrcAlpha);
 8173                    material.SetInt(ShaderUtils.DstBlend, (int) UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
 8174                    material.SetInt(ShaderUtils.ZWrite, 0);
 8175                    material.SetFloat(ShaderUtils.AlphaClip, 0);
 8176                    material.renderQueue = (int) UnityEngine.Rendering.RenderQueue.Transparent;
 8177                    material.SetInt("_Surface", 1);
 8178                    break;
 179                case TransparencyMode.ALPHA_TEST_AND_BLEND:
 0180                    material.EnableKeyword("_ALPHAPREMULTIPLY_ON");
 181
 0182                    material.SetInt(ShaderUtils.SrcBlend, (int) UnityEngine.Rendering.BlendMode.One);
 0183                    material.SetInt(ShaderUtils.DstBlend, (int) UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
 0184                    material.SetInt(ShaderUtils.ZWrite, 0);
 0185                    material.SetFloat(ShaderUtils.AlphaClip, 1);
 0186                    material.renderQueue = (int) UnityEngine.Rendering.RenderQueue.Transparent;
 0187                    material.SetInt("_Surface", 1);
 188                    break;
 189            }
 0190        }
 191
 192        private void LoadMaterial(string resourcesFilename)
 193        {
 41194            if (material == null || currentMaterialResourcesFilename != resourcesFilename)
 195            {
 19196                if (material != null)
 0197                    Object.Destroy(material);
 198
 19199                material = new Material(Utils.EnsureResourcesMaterial(MATERIAL_RESOURCES_PATH + resourcesFilename));
 200#if UNITY_EDITOR
 19201                material.name = "PBRMaterial_" + id;
 202#endif
 19203                currentMaterialResourcesFilename = resourcesFilename;
 204            }
 41205        }
 206
 207        void OnMaterialAttached(IDCLEntity entity)
 208        {
 20209            entity.OnShapeUpdated -= OnShapeUpdated;
 20210            entity.OnShapeUpdated += OnShapeUpdated;
 211
 20212            if (entity.meshRootGameObject != null)
 213            {
 17214                var meshRenderer = entity.meshRootGameObject.GetComponent<MeshRenderer>();
 215
 17216                if (meshRenderer != null)
 217                {
 17218                    InitMaterial(entity.meshRootGameObject);
 219                }
 220            }
 20221        }
 222
 223        void InitMaterial(GameObject meshGameObject)
 224        {
 35225            if (meshGameObject == null)
 226            {
 14227                return;
 228            }
 229
 21230            var meshRenderer = meshGameObject.GetComponent<MeshRenderer>();
 21231            if (meshRenderer == null)
 0232                return;
 21233            Model model = (Model) this.model;
 234
 21235            meshRenderer.shadowCastingMode = model.castShadows ? ShadowCastingMode.On : ShadowCastingMode.Off;
 21236            if (meshRenderer.sharedMaterial != material)
 237            {
 18238                MaterialTransitionController
 239                    matTransition = meshGameObject.GetComponent<MaterialTransitionController>();
 240
 18241                if (matTransition != null && matTransition.canSwitchMaterial)
 242                {
 0243                    matTransition.finalMaterials = new Material[] { material };
 0244                    matTransition.PopulateTargetRendererWithMaterial(matTransition.finalMaterials);
 245                }
 246
 18247                meshRenderer.sharedMaterial = material;
 18248                SRPBatchingHelper.OptimizeMaterial(material);
 249            }
 21250        }
 251
 252        private void OnShapeUpdated(IDCLEntity entity)
 253        {
 15254            if (entity != null)
 255            {
 15256                InitMaterial(entity.meshRootGameObject);
 257            }
 15258        }
 259
 260        void OnMaterialDetached(IDCLEntity entity)
 261        {
 20262            if (entity.meshRootGameObject == null)
 263            {
 16264                return;
 265            }
 266
 4267            entity.OnShapeUpdated -= OnShapeUpdated;
 268
 4269            var meshRenderer = entity.meshRootGameObject.GetComponent<MeshRenderer>();
 270
 4271            if (meshRenderer && meshRenderer.sharedMaterial == material)
 272            {
 4273                meshRenderer.sharedMaterial = null;
 274            }
 4275        }
 276
 277        void SetMaterialTexture(int materialPropertyId, string textureComponentId, DCLTexture cachedDCLTexture)
 278        {
 88279            if (!string.IsNullOrEmpty(textureComponentId))
 280            {
 19281                if (!AreSameTextureComponent(cachedDCLTexture, textureComponentId))
 282                {
 19283                    CoroutineStarter.Start(DCLTexture.FetchTextureComponent(scene, textureComponentId,
 284                        (fetchedDCLTexture) =>
 285                        {
 19286                            if (material != null)
 287                            {
 19288                                material.SetTexture(materialPropertyId, fetchedDCLTexture.texture);
 19289                                SwitchTextureComponent(cachedDCLTexture, fetchedDCLTexture);
 290                            }
 19291                        }));
 292                }
 19293            }
 294            else
 295            {
 69296                material.SetTexture(materialPropertyId, null);
 69297                cachedDCLTexture?.DetachFrom(this);
 298            }
 0299        }
 300
 301        bool AreSameTextureComponent(DCLTexture dclTexture, string textureId)
 302        {
 19303            if (dclTexture == null)
 19304                return false;
 0305            return dclTexture.id == textureId;
 306        }
 307
 308        void SwitchTextureComponent(DCLTexture cachedTexture, DCLTexture newTexture)
 309        {
 19310            cachedTexture?.DetachFrom(this);
 19311            cachedTexture = newTexture;
 19312            cachedTexture.AttachTo(this);
 19313        }
 314
 315        public override void Dispose()
 316        {
 19317            albedoDCLTexture?.DetachFrom(this);
 19318            alphaDCLTexture?.DetachFrom(this);
 19319            emissiveDCLTexture?.DetachFrom(this);
 19320            bumpDCLTexture?.DetachFrom(this);
 321
 19322            if (material != null)
 323            {
 19324                Utils.SafeDestroy(material);
 325            }
 326
 19327            base.Dispose();
 19328        }
 329    }
 330}