Shader fixes and legacy shader code

This commit is contained in:
2020-07-02 19:40:00 -07:00
parent 0aaf0088d8
commit be641272ad
16 changed files with 191 additions and 52 deletions

View File

@ -6,8 +6,36 @@ namespace ConformalDecals {
public static class DecalConfig {
private static Texture2D _blankNormal;
private static List<string> _shaderBlacklist;
private static int _decalLayer = 31;
private static bool _selectableInFlight = false;
private static int _decalLayer = 31;
private static bool _selectableInFlight;
private struct LegacyShaderEntry {
public string name;
public string[] keywords;
}
private static readonly Dictionary<string, LegacyShaderEntry> LegacyShaderPairs = new Dictionary<string, LegacyShaderEntry>() {
["ConformalDecals/Feature/Bumped"] = new LegacyShaderEntry() {
name = "ConformalDecals/Decal/Standard",
keywords = new[] {"DECAL_BUMPMAP"}
},
["ConformalDecals/Paint/Diffuse"] = new LegacyShaderEntry() {
name = "ConformalDecals/Decal/Standard",
keywords = new string[] { }
},
["ConformalDecals/Paint/Specular"] = new LegacyShaderEntry() {
name = "ConformalDecals/Decal/Standard",
keywords = new[] {"DECAL_SPECMAP"}
},
["ConformalDecals/Paint/DiffuseSDF"] = new LegacyShaderEntry() {
name = "ConformalDecals/Decal/Standard",
keywords = new[] {"DECAL_SDF_ALPHA"}
},
["ConformalDecals/Paint/SpecularSDF"] = new LegacyShaderEntry() {
name = "ConformalDecals/Decal/Standard",
keywords = new[] {"DECAL_SDF_ALPHA", "DECAL_SPECMAP"}
},
};
public static Texture2D BlankNormal => _blankNormal;
@ -23,6 +51,18 @@ namespace ConformalDecals {
return _shaderBlacklist.Contains(shaderName);
}
public static bool IsLegacy(string shaderName, out string newShader, out string[] keywords) {
if (LegacyShaderPairs.TryGetValue(shaderName, out var entry)) {
newShader = entry.name;
keywords = entry.keywords;
return true;
}
newShader = null;
keywords = null;
return false;
}
private static void ParseConfig(ConfigNode node) {
foreach (var blacklist in node.GetNodes("SHADERBLACKLIST")) {
foreach (var shaderName in blacklist.GetValuesList("shader")) {

View File

@ -1,4 +1,5 @@
using UnityEngine;
// ReSharper disable InconsistentNaming
namespace ConformalDecals {
@ -12,5 +13,6 @@ namespace ConformalDecals {
public static readonly int _DecalTangent = Shader.PropertyToID("_DecalTangent");
public static readonly int _EdgeWearStrength = Shader.PropertyToID("_EdgeWearStrength");
public static readonly int _ProjectionMatrix = Shader.PropertyToID("_ProjectionMatrix");
public static readonly int _ZWrite = Shader.PropertyToID("_ZWrite");
}
}

View File

@ -14,12 +14,14 @@ namespace ConformalDecals.MaterialProperties {
[SerializeField] protected int _propertyID;
[SerializeField] protected string _propertyName;
public abstract void Modify(Material material);
public virtual void ParseNode(ConfigNode node) {
if (node == null) throw new ArgumentNullException(nameof(node));
PropertyName = node.GetValue("name");
}
public abstract void Modify(Material material);
public virtual void Remove(Material material) { }
}
}

View File

@ -30,12 +30,20 @@ namespace ConformalDecals.MaterialProperties {
public Shader DecalShader => _shader;
public IEnumerable<Material> Materials {
get {
yield return PreviewMaterial;
yield return DecalMaterial;
}
}
public Material DecalMaterial {
get {
if (_decalMaterial == null) {
_decalMaterial = new Material(_shader);
_decalMaterial.SetInt(DecalPropertyIDs._Cull, (int) CullMode.Off);
_decalMaterial.SetInt(DecalPropertyIDs._ZWrite, 0);
_decalMaterial.renderQueue = RenderQueue;
}
@ -50,6 +58,7 @@ namespace ConformalDecals.MaterialProperties {
_previewMaterial.EnableKeyword("DECAL_PREVIEW");
_previewMaterial.SetInt(DecalPropertyIDs._Cull, (int) CullMode.Back);
_previewMaterial.SetInt(DecalPropertyIDs._ZWrite, 1);
}
return _previewMaterial;
@ -142,6 +151,20 @@ namespace ConformalDecals.MaterialProperties {
}
}
public bool RemoveProperty(string propertyName) {
if (_materialProperties.TryGetValue(propertyName, out var property)) {
foreach (var material in Materials) {
property.Remove(material);
}
_materialProperties.Remove(propertyName);
Destroy(property);
return true;
}
return false;
}
public MaterialTextureProperty AddTextureProperty(string propertyName, bool isMain = false) {
var newProperty = AddProperty<MaterialTextureProperty>(propertyName);
if (isMain) _mainTexture = newProperty;
@ -164,6 +187,8 @@ namespace ConformalDecals.MaterialProperties {
string propertyName = "";
if (!ParseUtil.ParseStringIndirect(ref propertyName, node, "name")) throw new ArgumentException("node has no name");
if (ParseUtil.ParseBool(node, "remove", true)) RemoveProperty(propertyName);
var newProperty = AddOrGetProperty<T>(propertyName);
newProperty.ParseNode(node);
@ -178,13 +203,22 @@ namespace ConformalDecals.MaterialProperties {
if (string.IsNullOrEmpty(shaderName)) {
if (_shader == null) {
Debug.Log("Using default decal shader");
shaderName = "ConformalDecals/Paint/Diffuse";
shaderName = "ConformalDecals/Decal/Standard";
}
else {
return;
}
}
if (DecalConfig.IsLegacy(shaderName, out var newShader, out var keywords)) {
Debug.LogWarning($"[ConformalDecals] Part is using shader {shaderName}, which has been replaced by {newShader}.");
shaderName = newShader;
foreach (var keyword in keywords) {
var newProperty = AddOrGetProperty<MaterialKeywordProperty>(keyword);
newProperty.value = true;
}
}
var shader = Shabby.Shabby.FindShader(shaderName);
if (shader == null) throw new FormatException($"Unable to find specified shader '{shaderName}'");
@ -239,8 +273,9 @@ namespace ConformalDecals.MaterialProperties {
}
public void UpdateMaterials() {
UpdateMaterial(DecalMaterial);
UpdateMaterial(PreviewMaterial);
foreach (var material in Materials) {
UpdateMaterial(material);
}
}
public void UpdateMaterial(Material material) {

View File

@ -70,6 +70,13 @@ namespace ConformalDecals.MaterialProperties {
if (_propertyName != "_Decal") material.EnableKeyword("DECAL" + _propertyName.ToUpper());
}
public override void Remove(Material material) {
if (material == null) throw new ArgumentNullException(nameof(material));
base.Remove(material);
if (_propertyName != "_Decal") material.DisableKeyword("DECAL" + _propertyName.ToUpper());
}
public void SetScale(Vector2 scale) {
_scale = scale;
}

View File

@ -19,7 +19,7 @@ namespace ConformalDecals {
// CONFIGURABLE VALUES
[KSPField] public string shader = "ConformalDecals/Paint/Diffuse";
[KSPField] public string shader = "ConformalDecals/Decal/Standard";
[KSPField] public string decalFront = "Decal-Front";
[KSPField] public string decalBack = "Decal-Back";
@ -170,6 +170,12 @@ namespace ConformalDecals {
// set shader
materialProperties.SetShader(shader);
materialProperties.AddOrGetProperty<MaterialKeywordProperty>("DECAL_BASE_NORMAL").value = useBaseNormal;
// add keyword nodes
foreach (var keywordNode in node.GetNodes("KEYWORD")) {
materialProperties.ParseProperty<MaterialKeywordProperty>(keywordNode);
}
// add texture nodes
foreach (var textureNode in node.GetNodes("TEXTURE")) {
@ -199,8 +205,6 @@ namespace ConformalDecals {
else if (tileIndex >= 0) {
materialProperties.UpdateTile(tileIndex, tileSize);
}
}
catch (Exception e) {
this.LogException("Exception parsing partmodule", e);
@ -208,6 +212,10 @@ namespace ConformalDecals {
UpdateMaterials();
foreach (var keyword in _decalMaterial.shaderKeywords) {
this.Log($"keyword: {keyword}");
}
if (HighLogic.LoadedSceneIsEditor) {
UpdateTweakables();
}
@ -221,7 +229,7 @@ namespace ConformalDecals {
opacity = defaultOpacity;
cutoff = defaultCutoff;
wear = defaultWear;
// QUEUE PART FOR ICON FIXING IN VAB
DecalIconFixer.QueuePart(part.name);
}
@ -260,13 +268,13 @@ namespace ConformalDecals {
OnAttach();
}
}
// handle flight events
if (HighLogic.LoadedSceneIsFlight) {
GameEvents.onPartWillDie.Add(OnPartWillDie);
if (part.parent == null) part.explode();
Part.layerMask |= 1 << DecalConfig.DecalLayer;
decalColliderTransform.gameObject.layer = DecalConfig.DecalLayer;
@ -351,7 +359,7 @@ namespace ConformalDecals {
part.Die();
}
}
protected void OnAttach() {
if (part.parent == null) {
this.LogError("Attach function called but part has no parent!");