// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using System.Collections.Generic; using UnityEngine; namespace Microsoft.MixedReality.Toolkit.UI { // Basic value types within a shader public enum ShaderPropertyType { Color, Float, Range, TexEnv, Vector, None } /// /// Obsolete container. Only exists to support backward compatibility to copy values from old scriptableobjects /// [System.Serializable] public struct ShaderProperties { public string Name; public ShaderPropertyType Type; public Vector2 Range; } /// /// Collection of shader and material utilities /// public static class InteractableThemeShaderUtils { /// /// Get a MaterialPropertyBlock and copy the designated properties /// public static MaterialPropertyBlock InitMaterialPropertyBlock(GameObject gameObject, List props) { MaterialPropertyBlock materialBlock = GetPropertyBlock(gameObject); Renderer renderer = gameObject.GetComponent(); if (renderer != null) { Material material = GetValidMaterial(renderer); if (material != null) { foreach (ThemeStateProperty prop in props) { switch (prop.Type) { case ThemePropertyTypes.Color: Color color = material.GetVector(prop.ShaderPropertyName); materialBlock.SetColor(prop.ShaderPropertyName, color); break; case ThemePropertyTypes.Texture: Texture tex = material.GetTexture(prop.ShaderPropertyName); if (tex != null) { materialBlock.SetTexture(prop.ShaderPropertyName, tex); } break; case ThemePropertyTypes.ShaderFloat: case ThemePropertyTypes.ShaderRange: float value = material.GetFloat(prop.ShaderPropertyName); materialBlock.SetFloat(prop.ShaderPropertyName, value); break; default: break; } } } gameObject.GetComponent().SetPropertyBlock(materialBlock); } return materialBlock; } /// /// Get the MaterialPropertyBlock from a renderer on a gameObject /// public static MaterialPropertyBlock GetPropertyBlock(GameObject gameObject) { MaterialPropertyBlock materialBlock = new MaterialPropertyBlock(); Renderer renderer = gameObject.GetComponent(); if (renderer != null) { renderer.GetPropertyBlock(materialBlock); } return materialBlock; } /// /// Grab the shared material to avoid creating new material instances and breaking batching. /// Because MaterialPropertyBlocks are used for setting material properties the shared material is /// used to set the initial state of the MaterialPropertyBlock(s) before mutating state. /// public static Material GetValidMaterial(Renderer renderer) { Material material = null; if (renderer != null) { material = renderer.sharedMaterial; } return material; } } }