Shader fixes and legacy shader code

feature-better-tweakables
Andrew Cassidy 4 years ago
parent 0aaf0088d8
commit be641272ad

@ -5,6 +5,7 @@
#include "Lighting.cginc"
#define CLIP_MARGIN 0.1
#define EDGE_MARGIN 0.01
// UNIFORM VARIABLES
// Projection matrix, normal, and tangent vectors
@ -36,6 +37,7 @@ float4 _Decal_ST;
#ifdef DECAL_SPECMAP
sampler2D _SpecMap;
float4 _SpecMap_ST;
// specular color is declared in a unity CGINC for some reason??
fixed _Shininess;
#endif //DECAL_SPECMAP
@ -146,7 +148,7 @@ inline float BoundsDist(float3 p, float3 normal, float3 projNormal) {
return 10 * max(q.x, q.y); // 2D pseudo SDF
#else
float dist = max(max(q.x, q.y), q.z); // pseudo SDF
float ndist = -dot(normal, projNormal); // SDF to normal
float ndist = EDGE_MARGIN - dot(normal, projNormal); // SDF to normal
return 10 * max(dist, ndist); // return intersection
#endif
}

@ -85,7 +85,6 @@ fixed4 frag_forward(v2f IN) : SV_Target
// declare data
DecalSurfaceInput i;
SurfaceOutput o;
fixed4 c = 0;
// setup world-space TBN vectors
UNITY_EXTRACT_TBN(IN);
@ -162,10 +161,10 @@ fixed4 frag_forward(v2f IN) : SV_Target
WorldNormal.z = dot(_unity_tbn_2, o.Normal);
WorldNormal = normalize(WorldNormal);
o.Normal = WorldNormal;
//call modified KSP lighting function
c += LightingBlinnPhongDecal(o, lightDir, worldViewDir, atten);
float4 c = LightingBlinnPhongDecal(o, lightDir, worldViewDir, atten);
// Forward base emission and ambient/vertex lighting
#ifdef UNITY_PASS_FORWARDBASE
c.rgb += o.Emission;
@ -177,7 +176,7 @@ fixed4 frag_forward(v2f IN) : SV_Target
#ifdef UNITY_PASS_FORWARDADD
c.rgb *= o.Alpha;
#endif
return c;
}

@ -1,19 +1,37 @@
Shader "ConformalDecals/Decal/Standard"
Shader "ConformalDecals/Decal/Standard"
{
Properties
{
[Header(Texture Maps)]
[Header(Decal)]
_Decal("Decal Texture", 2D) = "gray" {}
[Toggle(DECAL_SDF_ALPHA)] _Decal_SDF_Alpha ("SDF in Alpha", int) = 0
[Header(Normal)]
[Toggle(DECAL_BASE_NORMAL)] _BaseNormal ("Use Base Normal", int) = 0
[Toggle(DECAL_BUMPMAP)] _Decal_BumpMap ("Has BumpMap", int) = 0
_BumpMap("Bump Map", 2D) = "bump" {}
_EdgeWearStrength("Edge Wear Strength", Range(0,500)) = 100
_EdgeWearOffset("Edge Wear Offset", Range(0,1)) = 0.1
[Header(Specularity)]
[Toggle(DECAL_SPECMAP)] _Decal_SpecMap ("Has SpecMap", int) = 0
_SpecMap ("Specular Map)", 2D) = "black" {}
_SpecColor ("_SpecColor", Color) = (0.25, 0.25, 0.25, 1)
_Shininess ("Shininess", Range (0.03, 10)) = 0.3
[Header(Emissive)]
[Toggle(DECAL_EMISSIVE)] _Decal_Emissive ("Has Emissive", int) = 0
_Emissive("_Emissive", 2D) = "black" {}
_EmissiveColor("_EmissiveColor", Color) = (0,0,0,1)
_Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
_DecalOpacity("Opacity", Range(0,1) ) = 1
_Background("Background Color", Color) = (0.9,0.9,0.9,0.7)
[Enum(UnityEngine.Rendering.CullMode)] _Cull ("Cull", int) = 2
[Toggle] _ZWrite ("ZWrite", Float) = 1.0
[Toggle(DECAL_PREVIEW)] _Preview ("Preview", int) = 0
[Header(Effects)]
@ -27,12 +45,13 @@ Shader "ConformalDecals/Decal/Standard"
{
Tags { "Queue" = "Geometry+100" "IgnoreProjector" = "true" "DisableBatching" = "true"}
Cull [_Cull]
Ztest LEqual
Pass
{
Name "FORWARD"
Tags { "LightMode" = "ForwardBase" }
ZWrite [_ZWrite]
ZTest LEqual
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
@ -57,9 +76,12 @@ Shader "ConformalDecals/Decal/Standard"
Pass
{
Name "FORWARD_ADD"
Name "FORWARD"
Tags { "LightMode" = "ForwardAdd" }
ZWrite Off
ZTest LEqual
Blend One One
Offset -1, -1
CGPROGRAM
#pragma vertex vert_forward

@ -65,7 +65,12 @@ PART
scaleRange = 0.1, 4
scaleMode = AVERAGE
shader = ConformalDecals/Paint/Specular
shader = ConformalDecals/Decal/Standard
KEYWORD {
name = DECAL_SDF_ALPHA
value = false
}
TEXTURE {
name = _Decal
@ -108,7 +113,7 @@ PART
MODULE {
IDENTIFIER { name = ModuleConformalDecal }
DATA {
shader = ConformalDecals/Paint/SpecularSDF
KEYWORD { name = DECAL_SDF_ALPHA }
tile = 128, 2, 128, 112
}
}
@ -123,7 +128,7 @@ PART
MODULE {
IDENTIFIER { name = ModuleConformalDecal }
DATA {
shader = ConformalDecals/Paint/SpecularSDF
KEYWORD { name = DECAL_SDF_ALPHA }
tile = 256, 2, 128, 112
}
}
@ -138,7 +143,7 @@ PART
MODULE {
IDENTIFIER { name = ModuleConformalDecal }
DATA {
shader = ConformalDecals/Paint/SpecularSDF
KEYWORD { name = DECAL_SDF_ALPHA }
tile = 384, 2, 128, 112
}
}
@ -153,7 +158,7 @@ PART
MODULE {
IDENTIFIER { name = ModuleConformalDecal }
DATA {
shader = ConformalDecals/Paint/SpecularSDF
KEYWORD { name = DECAL_SDF_ALPHA }
tile = 690, 4, 330, 118
}
}
@ -168,7 +173,7 @@ PART
MODULE {
IDENTIFIER { name = ModuleConformalDecal }
DATA {
shader = ConformalDecals/Paint/SpecularSDF
KEYWORD { name = DECAL_SDF_ALPHA }
tile = 898, 4, 122, 118
}
}
@ -183,7 +188,7 @@ PART
MODULE {
IDENTIFIER { name = ModuleConformalDecal }
DATA {
shader = ConformalDecals/Paint/SpecularSDF
KEYWORD { name = DECAL_SDF_ALPHA }
tile = 6, 126, 196, 132
}
}
@ -198,7 +203,7 @@ PART
MODULE {
IDENTIFIER { name = ModuleConformalDecal }
DATA {
shader = ConformalDecals/Paint/SpecularSDF
KEYWORD { name = DECAL_SDF_ALPHA }
tile = 210, 122, 94, 94
}
}
@ -213,7 +218,7 @@ PART
MODULE {
IDENTIFIER { name = ModuleConformalDecal }
DATA {
shader = ConformalDecals/Paint/SpecularSDF
KEYWORD { name = DECAL_SDF_ALPHA }
tile = 8, 262, 192, 70
}
}
@ -242,7 +247,7 @@ PART
MODULE {
IDENTIFIER { name = ModuleConformalDecal }
DATA {
shader = ConformalDecals/Paint/SpecularSDF
KEYWORD { name = DECAL_SDF_ALPHA }
tile = 508, 332, 262, 112
}
}
@ -257,7 +262,7 @@ PART
MODULE {
IDENTIFIER { name = ModuleConformalDecal }
DATA {
shader = ConformalDecals/Paint/SpecularSDF
KEYWORD { name = DECAL_SDF_ALPHA }
tile = 202, 218, 164, 114
}
}
@ -272,7 +277,7 @@ PART
MODULE {
IDENTIFIER { name = ModuleConformalDecal }
DATA {
shader = ConformalDecals/Paint/SpecularSDF
KEYWORD { name = DECAL_SDF_ALPHA }
tile = 366, 218, 164, 114
}
}
@ -347,7 +352,7 @@ PART
MODULE {
IDENTIFIER { name = ModuleConformalDecal }
DATA {
shader = ConformalDecals/Paint/SpecularSDF
KEYWORD { name = DECAL_SDF_ALPHA }
tile = 326, 426, 164, 20
}
}
@ -363,7 +368,7 @@ PART
MODULE {
IDENTIFIER { name = ModuleConformalDecal }
DATA {
shader = ConformalDecals/Paint/SpecularSDF
KEYWORD { name = DECAL_SDF_ALPHA }
tile = 776, 388, 48, 48
}
}
@ -378,7 +383,7 @@ PART
MODULE {
IDENTIFIER { name = ModuleConformalDecal }
DATA {
shader = ConformalDecals/Paint/SpecularSDF
KEYWORD { name = DECAL_SDF_ALPHA }
tile = 328, 456, 48, 48
}
}
@ -393,7 +398,7 @@ PART
MODULE {
IDENTIFIER { name = ModuleConformalDecal }
DATA {
shader = ConformalDecals/Paint/SpecularSDF
KEYWORD { name = DECAL_SDF_ALPHA }
tile = 376, 456, 48, 48
}
}
@ -408,7 +413,7 @@ PART
MODULE {
IDENTIFIER { name = ModuleConformalDecal }
DATA {
shader = ConformalDecals/Paint/SpecularSDF
KEYWORD { name = DECAL_SDF_ALPHA }
tile = 424, 456, 48, 48
}
}
@ -423,7 +428,7 @@ PART
MODULE {
IDENTIFIER { name = ModuleConformalDecal }
DATA {
shader = ConformalDecals/Paint/SpecularSDF
KEYWORD { name = DECAL_SDF_ALPHA }
tile = 472, 456, 48, 48
}
}
@ -438,7 +443,7 @@ PART
MODULE {
IDENTIFIER { name = ModuleConformalDecal }
DATA {
shader = ConformalDecals/Paint/SpecularSDF
KEYWORD { name = DECAL_SDF_ALPHA }
tile = 520, 456, 48, 48
}
}
@ -453,7 +458,7 @@ PART
MODULE {
IDENTIFIER { name = ModuleConformalDecal }
DATA {
shader = ConformalDecals/Paint/SpecularSDF
KEYWORD { name = DECAL_SDF_ALPHA }
tile = 568, 456, 48, 48
}
}
@ -468,7 +473,7 @@ PART
MODULE {
IDENTIFIER { name = ModuleConformalDecal }
DATA {
shader = ConformalDecals/Paint/SpecularSDF
KEYWORD { name = DECAL_SDF_ALPHA }
tile = 614, 456, 48, 48
}
}
@ -483,7 +488,7 @@ PART
MODULE {
IDENTIFIER { name = ModuleConformalDecal }
DATA {
shader = ConformalDecals/Paint/SpecularSDF
KEYWORD { name = DECAL_SDF_ALPHA }
tile = 662, 456, 48, 48
}
}
@ -498,7 +503,7 @@ PART
MODULE {
IDENTIFIER { name = ModuleConformalDecal }
DATA {
shader = ConformalDecals/Paint/SpecularSDF
KEYWORD { name = DECAL_SDF_ALPHA }
tile = 710, 456, 48, 48
}
}
@ -513,7 +518,7 @@ PART
MODULE {
IDENTIFIER { name = ModuleConformalDecal }
DATA {
shader = ConformalDecals/Paint/SpecularSDF
KEYWORD { name = DECAL_SDF_ALPHA }
tile = 758, 456, 48, 48
}
}
@ -528,7 +533,10 @@ PART
MODULE {
IDENTIFIER { name = ModuleConformalDecal }
DATA {
shader = ConformalDecals/Paint/Diffuse
TEXTURE {
name = _SpecMap
remove = true
}
tile = 826, 360, 196, 150
opacity = 1

@ -64,7 +64,7 @@ PART
scaleMode = MINIMUM
cutoffAdjustable = false
shader = ConformalDecals/Paint/Specular
shader = ConformalDecals/Decal/Standard
TEXTURE {
name = _Decal

@ -62,7 +62,7 @@ PART
scaleRange = 0.05, 0.5
cutoffAdjustable = false
shader = ConformalDecals/Paint/Specular
shader = ConformalDecals/Decal/Standard
TEXTURE {
name = _Decal

@ -53,5 +53,13 @@ PART
defaultDepth = 0.2
defaultCutoff = 0
shader = ConformalDecals/Decal/Standard
TEXTURE {
name = _SpecMap
textureUrl = ConformalDecals/Assets/Decal-Spec
autoScale = true
}
}
}

@ -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")) {

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

@ -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) { }
}
}

@ -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) {

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

@ -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!");

@ -2,6 +2,12 @@ v0.2.0
------
- New Parts:
- CDL-3 Surface Base Decal: A set of conformal decals based on the symbols from the movie Moon designed by Gavin Rothery
- Changes:
- New "KEYWORD" material modifier, allowing for shader features to be enabled and disabled.
- material modifiers can now be removed in variants by setting `remove = true` inside them.
- Unified all shaders into a single "Standard" shader with variants supporting any combination of bump, specular and emissive maps, plus SDF alphas.
- Old shaders are remapped to Standard shader plus keywords automatically.
- New SDF-based antialiasing for when decals extend to their borders, i.e. on opaque flags.
- Fixes:
- Fixed WIDTH and HEIGHT scale modes being flipped
- Removed debug log statements

Loading…
Cancel
Save