using UnityEngine; using UnityEngine.Rendering; namespace AllIn13DShader { public class PropertyOverride { public string propertyName { get; private set; } public string displayName { get; private set; } private AbstractEffectOverride effectOverride; public ShaderPropertyType shaderPropertyType; public PropertyOverrideType propertyOverrideType; public float floatValue; public int intValue; public Color colorValue; public Vector2 rangeLimits; public Vector4 vectorValue; public Texture texValue; public Vector4 tilingAndOffset; public bool isHDR; public bool hasTilingAndOffset; public string[] keywords; public PropertyOverride(AbstractEffectOverride effectOverride, int propertyIndex, Shader shader) { this.effectOverride = effectOverride; string propDescription = shader.GetPropertyName(propertyIndex); if(propDescription == "_FogOn") { this.propertyOverrideType = PropertyOverrideType.TOGGLE; this.keywords = new string[1] { "_FOG_ON" }; } else { this.propertyOverrideType = PropertyOverrideType.BASIC; this.keywords = new string[0]; } Initialize(propertyIndex, shader); } public PropertyOverride(AbstractEffectOverride effectOverride, EffectProperty effectProperty, Shader shader) { this.effectOverride = effectOverride; if (effectProperty.IsToggleProperty()) { this.propertyOverrideType = PropertyOverrideType.TOGGLE; } else if (effectProperty.IsEnumProperty()) { this.propertyOverrideType = PropertyOverrideType.ENUM; } if (this.propertyOverrideType != PropertyOverrideType.BASIC) { keywords = new string[effectProperty.propertyKeywords.Length]; for (int i = 0; i < effectProperty.propertyKeywords.Length; i++) { keywords[i] = effectProperty.propertyKeywords[i]; } } this.isHDR = effectProperty.isHDR; Initialize(effectProperty, shader); } private void Initialize(int propertyIndex, Shader shader) { string propertyName = shader.GetPropertyName(propertyIndex); string displayName = shader.GetPropertyDescription(propertyIndex); ShaderPropertyType shaderPropertyType = shader.GetPropertyType(propertyIndex); bool hasTilingAndOffset = shaderPropertyType == ShaderPropertyType.Texture && !shader.GetPropertyFlags(propertyIndex).HasFlag(ShaderPropertyFlags.NoScaleOffset); Initialize(propertyIndex, propertyName, displayName, shaderPropertyType, hasTilingAndOffset, shader); //if (this.shaderPropertyType == ShaderPropertyType.Range) //{ // this.rangeLimits = shader.GetPropertyRangeLimits(propertyIndex); //} } private void Initialize(EffectProperty effectProperty, Shader shader) { Initialize(effectProperty.propertyIndex, effectProperty.propertyName, effectProperty.displayName, effectProperty.shaderPropertyType, effectProperty.hasTilingAndOffset, shader); //this.propertyName = shader.GetPropertyName(effectProperty.propertyIndex); //this.displayName = shader.GetPropertyDescription(effectProperty.propertyIndex); //this.shaderPropertyType = shader.GetPropertyType(effectProperty.propertyIndex); //if (this.shaderPropertyType == ShaderPropertyType.Range) //{ // this.rangeLimits = shader.GetPropertyRangeLimits(effectProperty.propertyIndex); //} //InitializeDefaultValues(effectProperty.propertyIndex, shader); } private void Initialize(int propertyIndex, string propertyName, string displayName, ShaderPropertyType shaderPropertyType, bool hasTilingAndOffset, Shader shader) { this.tilingAndOffset = new Vector4(1f, 1f, 0f, 0f); this.propertyName = propertyName; this.displayName = displayName; this.shaderPropertyType = shaderPropertyType; this.hasTilingAndOffset = hasTilingAndOffset; if(shaderPropertyType == ShaderPropertyType.Range) { this.rangeLimits = shader.GetPropertyRangeLimits(propertyIndex); } InitializeDefaultValues(propertyIndex, shader); } private void InitializeDefaultValues(int propertyIndex, Shader shader) { switch (shaderPropertyType) { case ShaderPropertyType.Range: case ShaderPropertyType.Float: this.floatValue = shader.GetPropertyDefaultFloatValue(propertyIndex); break; case ShaderPropertyType.Vector: this.vectorValue = shader.GetPropertyDefaultVectorValue(propertyIndex); break; case ShaderPropertyType.Color: this.colorValue = shader.GetPropertyDefaultVectorValue(propertyIndex); break; case ShaderPropertyType.Int: this.intValue = (int)shader.GetPropertyDefaultFloatValue(propertyIndex); break; } } public override bool Equals(object obj) { bool res = false; if (obj is PropertyOverride) { PropertyOverride propertyOverride = (PropertyOverride)obj; res = (propertyName == propertyOverride.propertyName); } return res; } public override int GetHashCode() { int res = propertyName.GetHashCode(); return res; } public void ApplyChangesToMaterial(Material mat) { if(mat == null) { return; } if (this.propertyOverrideType == PropertyOverrideType.ENUM) { for(int i = 0; i < keywords.Length; i++) { string kw = (propertyName + "_" + keywords[i]).ToUpperInvariant(); mat.DisableKeyword(kw); if(i == floatValue) { mat.EnableKeyword(kw); } } } else if(this.propertyOverrideType == PropertyOverrideType.TOGGLE) { string kw = keywords[0]; if (floatValue > 0) { mat.EnableKeyword(kw); } else { mat.DisableKeyword(kw); } } switch (shaderPropertyType) { case ShaderPropertyType.Float: case ShaderPropertyType.Range: mat.SetFloat(propertyName, floatValue); break; case ShaderPropertyType.Color: mat.SetColor(propertyName, colorValue); break; case ShaderPropertyType.Texture: mat.SetTexture(propertyName, texValue); if (hasTilingAndOffset) { string propST = propertyName + "_ST"; mat.SetVector(propST, tilingAndOffset); } break; case ShaderPropertyType.Vector: mat.SetVector(propertyName, vectorValue); break; case ShaderPropertyType.Int: mat.SetInt(propertyName, intValue); break; } } public bool Remove() { bool res = false; if(effectOverride != null) { res = effectOverride.RemovePropertyOverride(this); } return res; } } }