Make material handling more intelligent and add incrementing queue

This commit is contained in:
Andrew Cassidy 2020-06-01 21:09:14 -07:00
parent 921a159262
commit c1b34d21a4
No known key found for this signature in database
GPG Key ID: 963017B38FD477A1
3 changed files with 86 additions and 40 deletions

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:a87abea70a75c8e4c1317f25f400276203608a8a6b1ddbeff91014a7986e0f74 oid sha256:b805b02f176fc212845fd04be41bf49ab22eae5b8a92e6fa404dc05f93ae1ded
size 27648 size 28160

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Smooth.Delegates;
using UnityEngine; using UnityEngine;
namespace ConformalDecals.MaterialModifiers { namespace ConformalDecals.MaterialModifiers {
@ -9,8 +10,6 @@ namespace ConformalDecals.MaterialModifiers {
public TextureMaterialProperty MainTextureProperty { get; set; } public TextureMaterialProperty MainTextureProperty { get; set; }
public Material parsedMaterial;
public bool UseBaseNormal { get; private set; } public bool UseBaseNormal { get; private set; }
private List<MaterialProperty> _materialProperties; private List<MaterialProperty> _materialProperties;
@ -19,6 +18,19 @@ namespace ConformalDecals.MaterialModifiers {
public String BaseNormalSrc { get; private set; } public String BaseNormalSrc { get; private set; }
public String BaseNormalDest { get; private set; } public String BaseNormalDest { get; private set; }
public Material DecalMaterial {
get {
if (_protoDecalMaterial == null) {
_protoDecalMaterial = MakeMaterial(_decalShader);
}
return _protoDecalMaterial;
}
}
private Shader _decalShader;
private Material _protoDecalMaterial;
private const string _normalTextureName = "_BumpMap"; private const string _normalTextureName = "_BumpMap";
public void Initialize(ConfigNode node, PartModule module) { public void Initialize(ConfigNode node, PartModule module) {
@ -30,15 +42,13 @@ namespace ConformalDecals.MaterialModifiers {
// Get shader // Get shader
var shaderString = node.GetValue("shader") ?? throw new FormatException("Missing shader name in material"); var shaderString = node.GetValue("shader") ?? throw new FormatException("Missing shader name in material");
var shaderRef = Shabby.Shabby.FindShader(shaderString); _decalShader = Shabby.Shabby.FindShader(shaderString);
// note to self: null coalescing does not work on UnityEngine classes // note to self: null coalescing does not work on UnityEngine classes
if (shaderRef == null) { if (_decalShader == null) {
throw new FormatException($"Shader not found: '{shaderString}'"); throw new FormatException($"Shader not found: '{shaderString}'");
} }
parsedMaterial = new Material(shaderRef);
// Get useBaseNormal value // Get useBaseNormal value
var useBaseNormalString = node.GetValue("useBaseNormal"); var useBaseNormalString = node.GetValue("useBaseNormal");
@ -95,7 +105,6 @@ namespace ConformalDecals.MaterialModifiers {
} }
_materialProperties.Add(property); _materialProperties.Add(property);
property.Modify(parsedMaterial);
} }
catch (Exception e) { catch (Exception e) {
@ -107,19 +116,28 @@ namespace ConformalDecals.MaterialModifiers {
module.Log($"Parsed {_materialProperties.Count} properties"); module.Log($"Parsed {_materialProperties.Count} properties");
} }
public void SetScale(Vector2 scale) { public void SetScale(Material material, Vector2 scale) {
foreach (var textureProperty in _textureMaterialProperties) { foreach (var textureProperty in _textureMaterialProperties) {
textureProperty.UpdateScale(parsedMaterial, scale); textureProperty.UpdateScale(material, scale);
} }
} }
public void SetOpacity(float opacity) { public void SetOpacity(Material material, float opacity) {
parsedMaterial.SetFloat(_opacityID, opacity); material.SetFloat(_opacityID, opacity);
} }
public void SetCutoff(float cutoff) { public void SetCutoff(Material material, float cutoff) {
parsedMaterial.SetFloat(_cutoffID, cutoff); material.SetFloat(_cutoffID, cutoff);
}
private Material MakeMaterial(Shader shader) {
var material = new Material(shader);
foreach (MaterialProperty property in _materialProperties) {
property.Modify(material);
}
return material;
} }
} }
} }

View File

@ -39,24 +39,39 @@ namespace ConformalDecals {
[KSPField] public bool opacityAdjustable = true; [KSPField] public bool opacityAdjustable = true;
[KSPField] public bool cutoffAdjustable = true; [KSPField] public bool cutoffAdjustable = true;
[KSPField] public Vector2 scaleRange = new Vector2(0, 4); [KSPField] public Vector2 scaleRange = new Vector2(0, 4);
[KSPField] public Vector2 depthRange = new Vector2(0, 4); [KSPField] public Vector2 depthRange = new Vector2(0, 4);
[KSPField] public Vector2 opacityRange = new Vector2(0, 1); [KSPField] public Vector2 opacityRange = new Vector2(0, 1);
[KSPField] public Vector2 cutoffRange = new Vector2(0, 1); [KSPField] public Vector2 cutoffRange = new Vector2(0, 1);
[KSPField] public Vector2 decalQueueRange = new Vector2(2100, 2400);
[KSPField] public bool updateBackScale = true; [KSPField] public bool updateBackScale = true;
[KSPField] public MaterialPropertyCollection materialProperties; [KSPField] public MaterialPropertyCollection materialProperties;
[KSPField] public Material decalMaterial;
private static int _decalQueueCounter = -1;
private List<ProjectionTarget> _targets; private List<ProjectionTarget> _targets;
private bool _isAttached; private bool _isAttached;
private Matrix4x4 _orthoMatrix; private Matrix4x4 _orthoMatrix;
private Bounds _decalBounds; private Bounds _decalBounds;
private Vector2 _backTextureBaseScale; private Vector2 _backTextureBaseScale;
private Material _backMaterial;
private Material _backMaterial;
private int DecalQueue {
get {
_decalQueueCounter++;
if (_decalQueueCounter > decalQueueRange.y || _decalQueueCounter < decalQueueRange.x) {
_decalQueueCounter = (int) decalQueueRange.x;
}
this.Log($"returning decal queue value {_decalQueueCounter}");
return _decalQueueCounter;
}
}
public override void OnLoad(ConfigNode node) { public override void OnLoad(ConfigNode node) {
this.Log("Loading module"); this.Log("Loading module");
@ -66,6 +81,9 @@ namespace ConformalDecals {
materialProperties = ScriptableObject.CreateInstance<MaterialPropertyCollection>(); materialProperties = ScriptableObject.CreateInstance<MaterialPropertyCollection>();
materialProperties.Initialize(materialNode, this); materialProperties.Initialize(materialNode, this);
// get decal material
decalMaterial = materialProperties.DecalMaterial;
// get aspect ratio from main texture, if it exists // get aspect ratio from main texture, if it exists
var mainTexture = materialProperties.MainTextureProperty; var mainTexture = materialProperties.MainTextureProperty;
if (mainTexture != null) { if (mainTexture != null) {
@ -134,44 +152,53 @@ namespace ConformalDecals {
var opacityField = Fields[nameof(opacity)]; var opacityField = Fields[nameof(opacity)];
var cutoffField = Fields[nameof(cutoff)]; var cutoffField = Fields[nameof(cutoff)];
if (scaleField.guiActiveEditor = scaleAdjustable) { scaleField.guiActiveEditor = scaleAdjustable;
depthField.guiActiveEditor = depthAdjustable;
opacityField.guiActiveEditor = opacityAdjustable;
cutoffField.guiActiveEditor = cutoffAdjustable;
if (scaleAdjustable) {
var minValue = Mathf.Max(Mathf.Epsilon, scaleRange.x); var minValue = Mathf.Max(Mathf.Epsilon, scaleRange.x);
var maxValue = Mathf.Max(minValue, scaleRange.y); var maxValue = Mathf.Max(minValue, scaleRange.y);
(scaleField.uiControlEditor as UI_FloatRange).minValue = minValue; ((UI_FloatRange) scaleField.uiControlEditor).minValue = minValue;
(scaleField.uiControlEditor as UI_FloatRange).maxValue = maxValue; ((UI_FloatRange) scaleField.uiControlEditor).maxValue = maxValue;
scaleField.uiControlEditor.onFieldChanged = OnSizeTweakEvent; scaleField.uiControlEditor.onFieldChanged = OnSizeTweakEvent;
} }
if (depthField.guiActiveEditor = depthAdjustable) { if (depthAdjustable) {
var minValue = Mathf.Max(Mathf.Epsilon, depthRange.x); var minValue = Mathf.Max(Mathf.Epsilon, depthRange.x);
var maxValue = Mathf.Max(minValue, depthRange.y); var maxValue = Mathf.Max(minValue, depthRange.y);
(depthField.uiControlEditor as UI_FloatRange).minValue = minValue; ((UI_FloatRange) depthField.uiControlEditor).minValue = minValue;
(depthField.uiControlEditor as UI_FloatRange).maxValue = maxValue; ((UI_FloatRange) depthField.uiControlEditor).maxValue = maxValue;
depthField.uiControlEditor.onFieldChanged = OnSizeTweakEvent; depthField.uiControlEditor.onFieldChanged = OnSizeTweakEvent;
} }
if (opacityField.guiActiveEditor = opacityAdjustable) { if (opacityAdjustable) {
var minValue = Mathf.Max(0, opacityRange.x); var minValue = Mathf.Max(0, opacityRange.x);
var maxValue = Mathf.Max(minValue, opacityRange.y); var maxValue = Mathf.Max(minValue, opacityRange.y);
maxValue = Mathf.Min(1, maxValue); maxValue = Mathf.Min(1, maxValue);
(opacityField.uiControlEditor as UI_FloatRange).minValue = minValue; ((UI_FloatRange) opacityField.uiControlEditor).minValue = minValue;
(opacityField.uiControlEditor as UI_FloatRange).maxValue = maxValue; ((UI_FloatRange) opacityField.uiControlEditor).maxValue = maxValue;
opacityField.uiControlEditor.onFieldChanged = OnMaterialTweakEvent; opacityField.uiControlEditor.onFieldChanged = OnMaterialTweakEvent;
} }
if (cutoffField.guiActiveEditor = cutoffAdjustable) { if (cutoffAdjustable) {
var minValue = Mathf.Max(0, cutoffRange.x); var minValue = Mathf.Max(0, cutoffRange.x);
var maxValue = Mathf.Max(minValue, cutoffRange.y); var maxValue = Mathf.Max(minValue, cutoffRange.y);
maxValue = Mathf.Min(1, maxValue); maxValue = Mathf.Min(1, maxValue);
(cutoffField.uiControlEditor as UI_FloatRange).minValue = minValue; ((UI_FloatRange) cutoffField.uiControlEditor).minValue = minValue;
(cutoffField.uiControlEditor as UI_FloatRange).maxValue = maxValue; ((UI_FloatRange) cutoffField.uiControlEditor).maxValue = maxValue;
cutoffField.uiControlEditor.onFieldChanged = OnMaterialTweakEvent; cutoffField.uiControlEditor.onFieldChanged = OnMaterialTweakEvent;
} }
} }
// instantiate decal material and set uniqueish queue
decalMaterial = Material.Instantiate(decalMaterial);
decalMaterial.renderQueue = DecalQueue;
// get back material if necessary // get back material if necessary
if (updateBackScale) { if (updateBackScale) {
this.Log("Getting material and base scale for back material"); this.Log("Getting material and base scale for back material");
@ -214,8 +241,8 @@ namespace ConformalDecals {
} }
private void OnMaterialTweakEvent(BaseField field, object obj) { private void OnMaterialTweakEvent(BaseField field, object obj) {
materialProperties.SetOpacity(opacity); materialProperties.SetOpacity(decalMaterial, opacity);
materialProperties.SetCutoff(cutoff); materialProperties.SetCutoff(decalMaterial, cutoff);
} }
private void OnVariantApplied(Part eventPart, PartVariant variant) { private void OnVariantApplied(Part eventPart, PartVariant variant) {
@ -326,11 +353,12 @@ namespace ConformalDecals {
} }
// update material scale // update material scale
materialProperties.SetScale(size); materialProperties.SetScale(decalMaterial, size);
} }
private void UpdateProjection() { private void UpdateProjection() {
if (!_isAttached) return; if (!_isAttached) return;
// project to each target object // project to each target object
foreach (var target in _targets) { foreach (var target in _targets) {
target.Project(_orthoMatrix, new OrientedBounds(decalProjectorTransform.localToWorldMatrix, _decalBounds), decalProjectorTransform); target.Project(_orthoMatrix, new OrientedBounds(decalProjectorTransform.localToWorldMatrix, _decalBounds), decalProjectorTransform);
@ -342,7 +370,7 @@ namespace ConformalDecals {
// render on each target object // render on each target object
foreach (var target in _targets) { foreach (var target in _targets) {
target.Render(materialProperties.parsedMaterial, part.mpb, camera); target.Render(decalMaterial, part.mpb, camera);
} }
} }
} }