Make material handling more intelligent and add incrementing queue

pull/13/head
Andrew Cassidy 4 years ago
parent 921a159262
commit c1b34d21a4
No known key found for this signature in database
GPG Key ID: 963017B38FD477A1

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

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

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

Loading…
Cancel
Save