Fix scaling issues when part is created

• KSP rescales the model object back to 1,1,1 on start, so don't use that for the model that gets scaled
• Some refactoring to consolidate property IDs
• rename some classes because I am indecisive
• Add and Get methods for MaterialPropertyCollection
• Make an attempt at a scale culling fix
feature-multiSDF
Andrew Cassidy 4 years ago
parent 5560eee368
commit da1fbf0f2a

@ -47,6 +47,7 @@ PART
decalFront = Decal-Front decalFront = Decal-Front
decalBack = Decal-Back decalBack = Decal-Back
decalModel = Decal-Model
useBaseNormal = false useBaseNormal = false

@ -48,6 +48,7 @@ PART
decalFront = Decal-Front decalFront = Decal-Front
decalBack = Decal-Back decalBack = Decal-Back
decalModel = Decal-Model
useBaseNormal = true useBaseNormal = true
} }

@ -49,8 +49,9 @@
</Reference> </Reference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="ConformalDecalConfig.cs" /> <Compile Include="DecalConfig.cs" />
<Compile Include="ConformalDecalIconFixer.cs" /> <Compile Include="DecalIconFixer.cs" />
<Compile Include="DecalPropertyIDs.cs" />
<Compile Include="MaterialModifiers\MaterialColorProperty.cs" /> <Compile Include="MaterialModifiers\MaterialColorProperty.cs" />
<Compile Include="MaterialModifiers\MaterialFloatProperty.cs" /> <Compile Include="MaterialModifiers\MaterialFloatProperty.cs" />
<Compile Include="MaterialModifiers\MaterialProperty.cs" /> <Compile Include="MaterialModifiers\MaterialProperty.cs" />

@ -2,7 +2,7 @@ using System.Collections.Generic;
using UnityEngine; using UnityEngine;
namespace ConformalDecals { namespace ConformalDecals {
public static class ConformalDecalConfig { public static class DecalConfig {
private static List<string> _shaderBlacklist; private static List<string> _shaderBlacklist;
public static bool IsBlacklisted(Shader shader) { public static bool IsBlacklisted(Shader shader) {

@ -3,7 +3,7 @@ using UnityEngine;
namespace ConformalDecals { namespace ConformalDecals {
[KSPAddon(KSPAddon.Startup.EditorAny, true)] [KSPAddon(KSPAddon.Startup.EditorAny, true)]
public class ConformalDecalIconFixer : MonoBehaviour { public class DecalIconFixer : MonoBehaviour {
private static readonly List<string> PartNames = new List<string>(); private static readonly List<string> PartNames = new List<string>();
public static void QueuePart(string name) { public static void QueuePart(string name) {
@ -11,12 +11,12 @@ namespace ConformalDecals {
} }
public void Start() { public void Start() {
foreach (var name in PartNames) { foreach (var partName in PartNames) {
Debug.Log($"Unf*&king decal preview on {name}"); Debug.Log($"Unf*&king decal preview on {partName}");
var partInfo = PartLoader.getPartInfoByName(name); var partInfo = PartLoader.getPartInfoByName(partName);
if (partInfo == null) { if (partInfo == null) {
Debug.Log($"Part {name} not found!"); Debug.Log($"Part {partName} not found!");
continue; continue;
} }
@ -24,21 +24,16 @@ namespace ConformalDecals {
var decalModule = partInfo.partPrefab.FindModuleImplementing<ModuleConformalDecalBase>(); var decalModule = partInfo.partPrefab.FindModuleImplementing<ModuleConformalDecalBase>();
if (partInfo == null) {
Debug.Log($"Part {name} has no decal module!");
continue;
}
var frontTransform = Part.FindHeirarchyTransform(icon.transform, decalModule.decalFront); var frontTransform = Part.FindHeirarchyTransform(icon.transform, decalModule.decalFront);
var backTransform = Part.FindHeirarchyTransform(icon.transform, decalModule.decalBack); var backTransform = Part.FindHeirarchyTransform(icon.transform, decalModule.decalBack);
if (frontTransform == null) { if (frontTransform == null) {
Debug.Log($"Part {name} has no frontTransform"); Debug.Log($"Part {partName} has no frontTransform");
continue; continue;
} }
if (backTransform == null) { if (backTransform == null) {
Debug.Log($"Part {name} has no backTransform"); Debug.Log($"Part {partName} has no backTransform");
continue; continue;
} }
@ -52,7 +47,8 @@ namespace ConformalDecals {
} }
backTransform.GetComponent<MeshRenderer>().material = decalModule.backMaterial; backTransform.GetComponent<MeshRenderer>().material = decalModule.backMaterial;
frontTransform.GetComponent<MeshRenderer>().material = decalModule.materialProperties.PreviewMaterial;
if (decalModule.updateBackScale) { if (decalModule.updateBackScale) {
backTransform.GetComponent<MeshRenderer>().material.SetTextureScale(PropertyIDs._MainTex, backScale); backTransform.GetComponent<MeshRenderer>().material.SetTextureScale(PropertyIDs._MainTex, backScale);
} }

@ -0,0 +1,15 @@
using UnityEngine;
// ReSharper disable InconsistentNaming
namespace ConformalDecals {
public static class DecalPropertyIDs {
public static readonly int _BumpMap = Shader.PropertyToID("_BumpMap");
public static readonly int _BumpMap_ST = Shader.PropertyToID("_BumpMap_ST");
public static readonly int _Cull = Shader.PropertyToID("_Cull");
public static readonly int _Cutoff = Shader.PropertyToID("_Cutoff");
public static readonly int _DecalNormal = Shader.PropertyToID("_DecalNormal");
public static readonly int _DecalOpacity = Shader.PropertyToID("_DecalOpacity");
public static readonly int _DecalTangent = Shader.PropertyToID("_DecalTangent");
public static readonly int _ProjectionMatrix = Shader.PropertyToID("_ProjectionMatrix");
}
}

@ -3,11 +3,19 @@ using System.Collections.Generic;
using System.Runtime.Serialization; using System.Runtime.Serialization;
using UniLinq; using UniLinq;
using UnityEngine; using UnityEngine;
using UnityEngine.Rendering;
namespace ConformalDecals.MaterialModifiers { namespace ConformalDecals.MaterialModifiers {
public class MaterialPropertyCollection : ScriptableObject, ISerializationCallbackReceiver { public class MaterialPropertyCollection : ScriptableObject, ISerializationCallbackReceiver {
private static readonly int OpacityId = Shader.PropertyToID("_DecalOpacity"); [SerializeField] private Shader _shader;
private static readonly int CutoffId = Shader.PropertyToID("_Cutoff"); [SerializeField] private MaterialTextureProperty _mainTexture;
[SerializeField] private string[] _serializedNames;
[SerializeField] private MaterialProperty[] _serializedProperties;
private Dictionary<string, MaterialProperty> _materialProperties;
private Material _decalMaterial;
private Material _previewMaterial;
public Shader DecalShader => _shader; public Shader DecalShader => _shader;
@ -16,6 +24,8 @@ namespace ConformalDecals.MaterialModifiers {
if (_decalMaterial == null) { if (_decalMaterial == null) {
_decalMaterial = new Material(_shader); _decalMaterial = new Material(_shader);
UpdateMaterial(_decalMaterial); UpdateMaterial(_decalMaterial);
_previewMaterial.SetInt(DecalPropertyIDs._Cull, (int) CullMode.Off);
} }
return _decalMaterial; return _decalMaterial;
@ -27,7 +37,9 @@ namespace ConformalDecals.MaterialModifiers {
if (_previewMaterial == null) { if (_previewMaterial == null) {
_previewMaterial = new Material(_shader); _previewMaterial = new Material(_shader);
UpdateMaterial(_previewMaterial); UpdateMaterial(_previewMaterial);
_previewMaterial.EnableKeyword("DECAL_PREVIEW"); _previewMaterial.EnableKeyword("DECAL_PREVIEW");
_previewMaterial.SetInt(DecalPropertyIDs._Cull, (int) CullMode.Back);
} }
return _previewMaterial; return _previewMaterial;
@ -50,41 +62,31 @@ namespace ConformalDecals.MaterialModifiers {
Debug.Log("No main texture specified! returning 1 for aspect ratio"); Debug.Log("No main texture specified! returning 1 for aspect ratio");
return 1; return 1;
} }
return MainTexture.AspectRatio; return MainTexture.AspectRatio;
} }
} }
[SerializeField] private string[] _serializedIDs;
[SerializeField] private MaterialProperty[] _serializedProperties;
[SerializeField] private Shader _shader;
[SerializeField] private MaterialTextureProperty _mainTexture;
private Dictionary<string, MaterialProperty> _materialProperties;
private Material _decalMaterial;
private Material _previewMaterial;
public void OnBeforeSerialize() { public void OnBeforeSerialize() {
Debug.Log($"Serializing MaterialPropertyCollection {this.GetInstanceID()}"); Debug.Log($"Serializing MaterialPropertyCollection {this.GetInstanceID()}");
if (_materialProperties == null) throw new SerializationException("Tried to serialize an unininitalized MaterialPropertyCollection"); if (_materialProperties == null) throw new SerializationException("Tried to serialize an uninitialized MaterialPropertyCollection");
_serializedIDs = _materialProperties.Keys.ToArray(); _serializedNames = _materialProperties.Keys.ToArray();
_serializedProperties = _materialProperties.Values.ToArray(); _serializedProperties = _materialProperties.Values.ToArray();
} }
public void OnAfterDeserialize() { public void OnAfterDeserialize() {
Debug.Log($"Deserializing MaterialPropertyCollection {this.GetInstanceID()}"); Debug.Log($"Deserializing MaterialPropertyCollection {this.GetInstanceID()}");
if (_serializedIDs == null) throw new SerializationException("ID array is null"); if (_serializedNames == null) throw new SerializationException("ID array is null");
if (_serializedProperties == null) throw new SerializationException("Property array is null"); if (_serializedProperties == null) throw new SerializationException("Property array is null");
if (_serializedProperties.Length != _serializedIDs.Length) throw new SerializationException("Material property arrays are different lengths."); if (_serializedProperties.Length != _serializedNames.Length) throw new SerializationException("Material property arrays are different lengths.");
_materialProperties ??= new Dictionary<string, MaterialProperty>(); _materialProperties ??= new Dictionary<string, MaterialProperty>();
for (var i = 0; i < _serializedIDs.Length; i++) { for (var i = 0; i < _serializedNames.Length; i++) {
var property = MaterialProperty.Instantiate(_serializedProperties[i]); var property = MaterialProperty.Instantiate(_serializedProperties[i]);
Debug.Log($"insantiating {property.GetType().Name} {property.GetInstanceID()}"); Debug.Log($"insantiating {property.GetType().Name} {property.GetInstanceID()}");
_materialProperties.Add(_serializedIDs[i], property); _materialProperties.Add(_serializedNames[i], property);
if (property is MaterialTextureProperty textureProperty) { if (property is MaterialTextureProperty textureProperty) {
_mainTexture = textureProperty; _mainTexture = textureProperty;
@ -98,7 +100,7 @@ namespace ConformalDecals.MaterialModifiers {
} }
public void AddProperty(MaterialProperty property) { public void AddProperty(MaterialProperty property) {
if (property == null) throw new ArgumentNullException("Tried to add a null property"); if (property == null) throw new ArgumentNullException(nameof(property));
_materialProperties.Add(property.name, property); _materialProperties.Add(property.name, property);
@ -107,16 +109,61 @@ namespace ConformalDecals.MaterialModifiers {
} }
} }
public T AddProperty<T>(string propertyName) where T : MaterialProperty {
if (_materialProperties.ContainsKey(propertyName)) throw new ArgumentException("property with that name already exists!");
var newProperty = MaterialProperty.CreateInstance<T>();
newProperty.PropertyName = propertyName;
_materialProperties.Add(propertyName, newProperty);
return newProperty;
}
public T GetProperty<T>(string propertyName) where T : MaterialProperty {
if (_materialProperties.ContainsKey(propertyName) && _materialProperties[propertyName] is T property) {
return property;
}
else {
return null;
}
}
public T AddOrGetProperty<T>(string propertyName) where T : MaterialProperty {
if (_materialProperties.ContainsKey(propertyName) && _materialProperties[propertyName] is T property) {
return property;
}
else {
return AddProperty<T>(propertyName);
}
}
public MaterialTextureProperty AddTextureProperty(string propertyName, bool isMain = false) {
var newProperty = AddProperty<MaterialTextureProperty>(propertyName);
if (isMain) MainTexture = newProperty;
return newProperty;
}
public MaterialTextureProperty GetTextureProperty(string propertyName) {
return GetProperty<MaterialTextureProperty>(propertyName);
}
public MaterialTextureProperty AddOrGetTextureProperty(string propertyName, bool isMain = false) {
if (_materialProperties.ContainsKey(propertyName) && _materialProperties[propertyName] is MaterialTextureProperty property) {
return property;
}
else {
return AddTextureProperty(propertyName, isMain);
}
}
public void ParseProperty<T>(ConfigNode node) where T : MaterialProperty { public void ParseProperty<T>(ConfigNode node) where T : MaterialProperty {
var name = node.GetValue("name"); var propertyName = node.GetValue("name");
if (string.IsNullOrEmpty(name)) throw new ArgumentException("node has no name"); if (string.IsNullOrEmpty(propertyName)) throw new ArgumentException("node has no name");
Debug.Log($"Parsing material property {name}"); Debug.Log($"Parsing material property {propertyName}");
T newProperty; T newProperty;
if (_materialProperties.ContainsKey(name)) { if (_materialProperties.ContainsKey(propertyName)) {
if (_materialProperties[name] is T property) { if (_materialProperties[propertyName] is T property) {
newProperty = property; newProperty = property;
property.ParseNode(node); property.ParseNode(node);
} }
@ -128,7 +175,7 @@ namespace ConformalDecals.MaterialModifiers {
newProperty = MaterialProperty.CreateInstance<T>(); newProperty = MaterialProperty.CreateInstance<T>();
Debug.Log($"Adding new material property of type {newProperty.GetType().Name} {newProperty.GetInstanceID()}"); Debug.Log($"Adding new material property of type {newProperty.GetType().Name} {newProperty.GetInstanceID()}");
newProperty.ParseNode(node); newProperty.ParseNode(node);
_materialProperties.Add(name, newProperty); _materialProperties.Add(propertyName, newProperty);
} }
if (newProperty is MaterialTextureProperty textureProperty && textureProperty.isMain) { if (newProperty is MaterialTextureProperty textureProperty && textureProperty.isMain) {
@ -170,11 +217,13 @@ namespace ConformalDecals.MaterialModifiers {
} }
public void SetOpacity(float opacity) { public void SetOpacity(float opacity) {
DecalMaterial.SetFloat(OpacityId, opacity); DecalMaterial.SetFloat(DecalPropertyIDs._DecalOpacity, opacity);
PreviewMaterial.SetFloat(DecalPropertyIDs._DecalOpacity, opacity);
} }
public void SetCutoff(float cutoff) { public void SetCutoff(float cutoff) {
DecalMaterial.SetFloat(CutoffId, cutoff); DecalMaterial.SetFloat(DecalPropertyIDs._Cutoff, cutoff);
PreviewMaterial.SetFloat(DecalPropertyIDs._Cutoff, cutoff);
} }
public void UpdateMaterials() { public void UpdateMaterials() {
@ -195,8 +244,11 @@ namespace ConformalDecals.MaterialModifiers {
public void UpdateMaterial(Material material) { public void UpdateMaterial(Material material) {
if (material == null) throw new ArgumentNullException(nameof(material)); if (material == null) throw new ArgumentNullException(nameof(material));
foreach (var entry in _materialProperties) { foreach (var entry in _materialProperties) {
Debug.Log($"Applying material property {entry.Key} {entry.Value.PropertyName} {entry.Value.GetInstanceID()}");
entry.Value.Modify(material); entry.Value.Modify(material);
} }
} }

@ -99,7 +99,7 @@ namespace ConformalDecals {
// find model transform // find model transform
if (string.IsNullOrEmpty(decalModel)) { if (string.IsNullOrEmpty(decalModel)) {
decalModelTransform = part.transform.Find("model"); decalModelTransform = decalFrontTransform;
} }
else { else {
decalModelTransform = part.FindModelTransform(decalModel); decalModelTransform = part.FindModelTransform(decalModel);
@ -135,7 +135,7 @@ namespace ConformalDecals {
} }
} }
ConformalDecalIconFixer.QueuePart(part.name); DecalIconFixer.QueuePart(part.name);
// set shader // set shader
materialProperties.SetShader(shader); materialProperties.SetShader(shader);
@ -149,6 +149,9 @@ namespace ConformalDecals {
UpdateScale(); UpdateScale();
UpdateProjection(); UpdateProjection();
} }
else {
UpdateScale();
}
} }
public override void OnAwake() { public override void OnAwake() {
@ -176,7 +179,6 @@ namespace ConformalDecals {
materialProperties.SetRenderQueue(DecalQueue); materialProperties.SetRenderQueue(DecalQueue);
UpdateMaterials(); UpdateMaterials();
UpdateScale();
if (HighLogic.LoadedSceneIsGame) { if (HighLogic.LoadedSceneIsGame) {
// set initial attachment state // set initial attachment state
@ -308,6 +310,9 @@ namespace ConformalDecals {
protected void UpdateMaterials() { protected void UpdateMaterials() {
materialProperties.UpdateMaterials(); materialProperties.UpdateMaterials();
materialProperties.SetOpacity(opacity);
materialProperties.SetCutoff(cutoff);
_decalMaterial = materialProperties.DecalMaterial; _decalMaterial = materialProperties.DecalMaterial;
_previewMaterial = materialProperties.PreviewMaterial; _previewMaterial = materialProperties.PreviewMaterial;
@ -345,7 +350,7 @@ namespace ConformalDecals {
if (renderer.gameObject.activeInHierarchy == false) continue; if (renderer.gameObject.activeInHierarchy == false) continue;
// skip blacklisted shaders // skip blacklisted shaders
if (ConformalDecalConfig.IsBlacklisted(renderer.material.shader)) continue; if (DecalConfig.IsBlacklisted(renderer.material.shader)) continue;
var meshFilter = renderer.GetComponent<MeshFilter>(); var meshFilter = renderer.GetComponent<MeshFilter>();
if (meshFilter == null) continue; // object has a meshRenderer with no filter, invalid if (meshFilter == null) continue; // object has a meshRenderer with no filter, invalid

@ -1,22 +1,13 @@
using ConformalDecals.MaterialModifiers;
using ConformalDecals.Util; using ConformalDecals.Util;
using UnityEngine;
namespace ConformalDecals { namespace ConformalDecals {
public class ModuleConformalDecalFlag : ModuleConformalDecalBase { public class ModuleConformalDecalFlag : ModuleConformalDecalBase {
[KSPField] public MaterialTextureProperty flagTextureProperty; private const string DefaultFlag = "Squad/Flags/default";
private const string defaultFlag = "Squad/Flags/default";
public override void OnLoad(ConfigNode node) { public override void OnLoad(ConfigNode node) {
base.OnLoad(node); base.OnLoad(node);
if (HighLogic.LoadedSceneIsGame) { UpdateFlag(GetDefaultFlag());
UpdateFlag(EditorLogic.FlagURL != string.Empty ? EditorLogic.FlagURL : HighLogic.CurrentGame.flagURL);
}
else {
UpdateFlag(defaultFlag);
}
} }
public override void OnStart(StartState state) { public override void OnStart(StartState state) {
@ -25,6 +16,8 @@ namespace ConformalDecals {
if (HighLogic.LoadedSceneIsGame) { if (HighLogic.LoadedSceneIsGame) {
GameEvents.onMissionFlagSelect.Add(UpdateFlag); GameEvents.onMissionFlagSelect.Add(UpdateFlag);
} }
UpdateFlag(GetDefaultFlag());
} }
public override void OnIconCreate() { public override void OnIconCreate() {
@ -37,6 +30,15 @@ namespace ConformalDecals {
base.OnDestroy(); base.OnDestroy();
} }
private string GetDefaultFlag() {
if (HighLogic.LoadedSceneIsGame) {
return EditorLogic.FlagURL != string.Empty ? EditorLogic.FlagURL : HighLogic.CurrentGame.flagURL;
}
else {
return DefaultFlag;
}
}
private void UpdateFlag(string flagUrl) { private void UpdateFlag(string flagUrl) {
this.Log($"Loading flag texture '{flagUrl}'."); this.Log($"Loading flag texture '{flagUrl}'.");
var flagTexture = GameDatabase.Instance.GetTexture(flagUrl, false); var flagTexture = GameDatabase.Instance.GetTexture(flagUrl, false);
@ -45,18 +47,7 @@ namespace ConformalDecals {
return; return;
} }
if (flagTextureProperty == null) { materialProperties.AddOrGetTextureProperty("_Decal", true).texture = flagTexture;
this.Log("Initializing flag property");
flagTextureProperty = ScriptableObject.CreateInstance<MaterialTextureProperty>();
flagTextureProperty.PropertyName = "_Decal";
flagTextureProperty.isMain = true;
materialProperties.AddProperty(flagTextureProperty);
materialProperties.MainTexture = flagTextureProperty;
}
else { }
flagTextureProperty.texture = flagTexture;
UpdateMaterials(); UpdateMaterials();
} }

@ -4,28 +4,28 @@ using UnityEngine.Rendering;
namespace ConformalDecals { namespace ConformalDecals {
public class ProjectionTarget { public class ProjectionTarget {
private static readonly int _projectionMatrixID = Shader.PropertyToID("_ProjectionMatrix");
private static readonly int _decalNormalID = Shader.PropertyToID("_DecalNormal");
private static readonly int _decalTangentID = Shader.PropertyToID("_DecalTangent");
// Target object data // Target object data
public readonly Transform target; public readonly Transform target;
private readonly Renderer _targetRenderer; private readonly Renderer _targetRenderer;
private readonly Mesh _targetMesh; private readonly Mesh _targetMesh;
private bool _projectionEnabled; private bool _projectionEnabled;
private readonly int _cullMode;
// property block // property block
private readonly MaterialPropertyBlock _decalMPB; private readonly MaterialPropertyBlock _decalMPB;
private static readonly int normalID = Shader.PropertyToID("_BumpMap");
private static readonly int normalIDST = Shader.PropertyToID("_BumpMap_ST");
public ProjectionTarget(MeshRenderer targetRenderer, Mesh targetMesh, bool useBaseNormal) { public ProjectionTarget(MeshRenderer targetRenderer, Mesh targetMesh, bool useBaseNormal) {
target = targetRenderer.transform; target = targetRenderer.transform;
_targetRenderer = targetRenderer; _targetRenderer = targetRenderer;
_targetMesh = targetMesh; _targetMesh = targetMesh;
_decalMPB = new MaterialPropertyBlock(); _decalMPB = new MaterialPropertyBlock();
var targetScale = target.lossyScale;
Debug.Log($"{target.name} scale = {targetScale}");
var targetDeterminant = (targetScale.x * targetScale.y * targetScale.z);
_cullMode = targetDeterminant < 0 ? (int) CullMode.Front : (int) CullMode.Back;
_decalMPB.SetInt(DecalPropertyIDs._Cull, 0);
} }
public void Project(Matrix4x4 orthoMatrix, OrientedBounds projectorBounds, Transform projector, bool useBaseNormal) { public void Project(Matrix4x4 orthoMatrix, OrientedBounds projectorBounds, Transform projector, bool useBaseNormal) {
@ -40,21 +40,21 @@ namespace ConformalDecals {
var decalNormal = projectorToTargetMatrix.MultiplyVector(Vector3.back).normalized; var decalNormal = projectorToTargetMatrix.MultiplyVector(Vector3.back).normalized;
var decalTangent = projectorToTargetMatrix.MultiplyVector(Vector3.right).normalized; var decalTangent = projectorToTargetMatrix.MultiplyVector(Vector3.right).normalized;
_decalMPB.SetMatrix(_projectionMatrixID, projectionMatrix); _decalMPB.SetMatrix(DecalPropertyIDs._ProjectionMatrix, projectionMatrix);
_decalMPB.SetVector(_decalNormalID, decalNormal); _decalMPB.SetVector(DecalPropertyIDs._DecalNormal, decalNormal);
_decalMPB.SetVector(_decalTangentID, decalTangent); _decalMPB.SetVector(DecalPropertyIDs._DecalTangent, decalTangent);
Debug.Log($"Projection enabled for {target.gameObject}"); Debug.Log($"Projection enabled for {target.gameObject}");
if (useBaseNormal && targetMaterial.HasProperty(normalID)) { if (useBaseNormal && targetMaterial.HasProperty(DecalPropertyIDs._BumpMap)) {
var normal = targetMaterial.GetTexture(normalID); var normal = targetMaterial.GetTexture(DecalPropertyIDs._BumpMap);
if (normal != null) { if (normal != null) {
_decalMPB.SetTexture(normalID, targetMaterial.GetTexture(normalID)); _decalMPB.SetTexture(DecalPropertyIDs._BumpMap, targetMaterial.GetTexture(DecalPropertyIDs._BumpMap));
var normalScale = targetMaterial.GetTextureScale(normalID); var normalScale = targetMaterial.GetTextureScale(DecalPropertyIDs._BumpMap);
var normalOffset = targetMaterial.GetTextureOffset(normalID); var normalOffset = targetMaterial.GetTextureOffset(DecalPropertyIDs._BumpMap);
_decalMPB.SetVector(normalIDST, new Vector4(normalScale.x, normalScale.y, normalOffset.x, normalOffset.y)); _decalMPB.SetVector(DecalPropertyIDs._BumpMap_ST, new Vector4(normalScale.x, normalScale.y, normalOffset.x, normalOffset.y));
} }
} }
} }

Loading…
Cancel
Save