Skip to content

Commit edd707e

Browse files
authored
Merge pull request #343 from acezen3d/texture-props
[ME] Add `AnisoLevel`, `FilterMode`, `WrapMode` config for texture properties
2 parents 02b496b + e7382ce commit edd707e

File tree

5 files changed

+130
-35
lines changed

5 files changed

+130
-35
lines changed

Guides/Material Editor Guide/shader_manifest_template.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,18 @@
6363
<Property Name="{{PropertyName}}" Type="Texture" DefaultValueAssetBundle="{{default_texture_asset_bundle_path.unity3d}}" DefaultValue="{{default_texture_asset_name}}"/>
6464
<!-- Example: <Property Name="PropertyName" Type="Texture" DefaultValueAssetBundle="shader_assets.unity3d" DefaultValue="default_texture_a"/> -->
6565
<!-- -->
66+
<!-- Optional `AnisoLevel` attribute -->
67+
<Property Name="{{PropertyName}}" Type="Texture" AnisoLevel="{{aniso_level: 0-16}}"/>
68+
<!-- Example: <Property Name="PropertyName" Type="Texture" AnisoLevel="16"/> -->
69+
<!-- -->
70+
<!-- Optional `FilterMode` attribute -->
71+
<Property Name="{{PropertyName}}" Type="Texture" FilterMode="{{filter_mode: Point = 0, Bilinear = 1, Trilinear = 2}}"/>
72+
<!-- Example: <Property Name="PropertyName" Type="Texture" FilterMode="2"/> -->
73+
<!-- -->
74+
<!-- Optional `WrapMode` attribute -->
75+
<Property Name="{{PropertyName}}" Type="Texture" WrapMode="{{wrap_mode: Repeat = 0, Clamp = 1, Mirror = 2, MirrorOnce = 3}}"/>
76+
<!-- Example: <Property Name="PropertyName" Type="Texture" WrapMode="0"/> -->
77+
<!-- -->
6678
<!-- Optional `Hidden` attribute -->
6779
<Property Name="{{PropertyName}}" Type="Texture" Hidden="{{boolean}}"/>
6880
<!-- Example: <Property Name="PropertyName" Type="Texture" Hidden="True"/> -->

src/MaterialEditor.Base/MaterialAPI.cs

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,7 @@ public static bool SetProjectorIgnoreLayers(GameObject gameObject, string projec
664664
//Add layer to mask
665665
else if (!inMask && ignore)
666666
projector.ignoreLayers |= (1 << layer);
667+
return true;
667668
}
668669
}
669670
return false;
@@ -680,23 +681,38 @@ public static bool SetProjectorIgnoreLayers(GameObject gameObject, string projec
680681
public static bool SetTexture(GameObject gameObject, string materialName, string propertyName, Texture value)
681682
{
682683
bool didSet = false;
684+
if (value == null) return didSet;
685+
683686
var materials = GetObjectMaterials(gameObject, materialName);
684687
for (var i = 0; i < materials.Count; i++)
685688
{
686689
var material = materials[i];
687-
if (material.HasProperty($"_{propertyName}"))
690+
if (!material.HasProperty($"_{propertyName}")) continue; // Todo, should check if it is a texture
691+
692+
var oldTex = material.GetTexture($"_{propertyName}");
693+
if (oldTex != null)
688694
{
689-
if (value != null)
690-
{
691-
var tex = material.GetTexture($"_{propertyName}");
692-
if (tex == null)
693-
value.wrapMode = TextureWrapMode.Repeat;
694-
else
695-
value.wrapMode = tex.wrapMode;
696-
}
697-
material.SetTexture($"_{propertyName}", value);
698-
didSet = true;
695+
value.anisoLevel = oldTex.anisoLevel;
696+
value.filterMode = oldTex.filterMode;
697+
value.wrapMode = oldTex.wrapMode;
699698
}
699+
else
700+
{
701+
// Texture default values
702+
value.anisoLevel = 1;
703+
value.filterMode = FilterMode.Bilinear;
704+
value.wrapMode = TextureWrapMode.Repeat;
705+
}
706+
707+
// The shader has the final say over these properties, not the texture itself.
708+
var texturePropertyData = MaterialEditorPluginBase.XMLShaderProperties[MaterialEditorPluginBase.XMLShaderProperties.ContainsKey(material.shader.NameFormatted()) ? material.shader.NameFormatted() : "default"]
709+
.Where(p => p.Value.Name == propertyName && p.Value.Type == ShaderPropertyType.Texture).FirstOrDefault().Value;
710+
if (texturePropertyData.AnisoLevel.HasValue) value.anisoLevel = texturePropertyData.AnisoLevel.Value;
711+
if (texturePropertyData.FilterMode.HasValue) value.filterMode = texturePropertyData.FilterMode.Value;
712+
if (texturePropertyData.WrapMode.HasValue) value.wrapMode = texturePropertyData.WrapMode.Value;
713+
714+
material.SetTexture($"_{propertyName}", value);
715+
didSet = true;
700716
}
701717
return didSet;
702718
}
@@ -711,8 +727,8 @@ public static bool SetTexture(GameObject gameObject, string materialName, string
711727
/// <returns>True if the value was set, false if it could not be set</returns>
712728
public static bool SetTextureOffset(GameObject gameObject, string materialName, string propertyName, Vector2? value)
713729
{
714-
if (value == null) return false;
715730
bool didSet = false;
731+
if (value == null) return didSet;
716732

717733
var materials = GetObjectMaterials(gameObject, materialName);
718734
for (var i = 0; i < materials.Count; i++)
@@ -737,8 +753,8 @@ public static bool SetTextureOffset(GameObject gameObject, string materialName,
737753
/// <returns>True if the value was set, false if it could not be set</returns>
738754
public static bool SetTextureScale(GameObject gameObject, string materialName, string propertyName, Vector2? value)
739755
{
740-
if (value == null) return false;
741756
bool didSet = false;
757+
if (value == null) return didSet;
742758

743759
var materials = GetObjectMaterials(gameObject, materialName);
744760
for (var i = 0; i < materials.Count; i++)
@@ -764,13 +780,14 @@ public static bool SetTextureScale(GameObject gameObject, string materialName, s
764780
public static bool SetShader(GameObject gameObject, string materialName, string shaderName, bool preserveRenderQueue = false)
765781
{
766782
bool didSet = false;
767-
if (shaderName.IsNullOrEmpty()) return false;
783+
if (shaderName.IsNullOrEmpty()) return didSet;
784+
768785
MaterialEditorPluginBase.LoadedShaders.TryGetValue(shaderName, out var shaderData);
769786

770787
if (shaderData?.Shader == null)
771788
{
772789
MaterialEditorPluginBase.Logger.Log(BepInEx.Logging.LogLevel.Warning | BepInEx.Logging.LogLevel.Message, $"Could not load shader:{shaderName}");
773-
return false;
790+
return didSet;
774791
}
775792
if (!MaterialEditorPluginBase.XMLShaderProperties.TryGetValue(shaderName, out var shaderPropertyDataList))
776793
shaderPropertyDataList = new Dictionary<string, MaterialEditorPluginBase.ShaderPropertyData>();
@@ -831,7 +848,7 @@ public static bool SetShader(GameObject gameObject, string materialName, string
831848
public static bool SetRenderQueue(GameObject gameObject, string materialName, int? value)
832849
{
833850
bool didSet = false;
834-
if (value == null) return false;
851+
if (value == null) return didSet;
835852

836853
var list = GetObjectMaterials(gameObject, materialName);
837854
for (var i = 0; i < list.Count; i++)

src/MaterialEditor.Base/NormalMapManager.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public bool ConvertNormalMap(ref Texture tex, string propertyName, bool unpack)
4242
{
4343
try
4444
{
45-
if (!NormalMapProperties.Any(x => propertyName.Contains(x)))
45+
if (!NormalMapProperties.Contains(propertyName))
4646
return false;
4747

4848
if (tex == null || IsBrokenTexture(tex))
@@ -159,6 +159,9 @@ protected virtual Texture ConvertNormalMap(Texture src, bool unpack = false)
159159
Graphics.Blit(readableTex, rt);
160160
RenderTexture.active = cur;
161161

162+
rt.wrapMode = src.wrapMode;
163+
rt.anisoLevel = src.anisoLevel;
164+
rt.filterMode = src.filterMode;
162165
return rt;
163166
}
164167

src/MaterialEditor.Base/PluginBase.cs

Lines changed: 65 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ public partial class MaterialEditorPluginBase : BaseUnityPlugin
129129
/// When enabled, normalmaps get converted from DXT5 compressed (red) normals back to normal OpenGL (blue/purple) normals
130130
/// </summary>
131131
public static ConfigEntry<bool> ConvertNormalmapsOnExport { get; set; }
132-
132+
133133
/// <summary>
134134
/// Init logic, do not call
135135
/// </summary>
@@ -259,11 +259,12 @@ private static void LoadXML()
259259
ShaderPropertyType propertyType = (ShaderPropertyType)Enum.Parse(typeof(ShaderPropertyType), shaderPropertyElement.GetAttribute("Type"));
260260
string defaultValue = shaderPropertyElement.GetAttribute("DefaultValue");
261261
string defaultValueAB = shaderPropertyElement.GetAttribute("DefaultValueAssetBundle");
262-
string hidden = shaderPropertyElement.GetAttribute("Hidden");
262+
string anisoLevel = shaderPropertyElement.GetAttribute("AnisoLevel");
263+
string filterMode = shaderPropertyElement.GetAttribute("FilterMode");
264+
string wrapMode = shaderPropertyElement.GetAttribute("WrapMode");
263265
string range = shaderPropertyElement.GetAttribute("Range");
264266
string min = null;
265267
string max = null;
266-
string category = shaderPropertyElement.GetAttribute("Category");
267268
if (!range.IsNullOrWhiteSpace())
268269
{
269270
var rangeSplit = range.Split(',');
@@ -273,7 +274,16 @@ private static void LoadXML()
273274
max = rangeSplit[1];
274275
}
275276
}
276-
ShaderPropertyData shaderPropertyData = new ShaderPropertyData(propertyName, propertyType, defaultValue, defaultValueAB, hidden, min, max, category);
277+
string hidden = shaderPropertyElement.GetAttribute("Hidden");
278+
string category = shaderPropertyElement.GetAttribute("Category");
279+
280+
ShaderPropertyData shaderPropertyData = new ShaderPropertyData(
281+
propertyName, propertyType,
282+
defaultValue, defaultValueAB,
283+
anisoLevel, filterMode, wrapMode,
284+
min, max,
285+
hidden, category
286+
);
277287

278288
XMLShaderProperties["default"][propertyName] = shaderPropertyData;
279289
}
@@ -417,22 +427,34 @@ public class ShaderPropertyData
417427
/// </summary>
418428
public string DefaultValue;
419429
/// <summary>
420-
/// Default value of the shader property when loaded from an asset bundle.
430+
/// Default value of the shader property when loaded from an asset bundle, like a texture.
421431
/// </summary>
422432
public string DefaultValueAssetBundle;
423433
/// <summary>
424-
/// Indicates whether the shader property is hidden.
434+
/// Should only be used with texture properties. The `anisoLevel` of the texture, 0-16.
425435
/// </summary>
426-
public bool Hidden;
436+
public int? AnisoLevel;
427437
/// <summary>
428-
/// Minimum value of the shader property, if applicable.
438+
/// Should only be used with texture properties. The `filterMode` of the texture.
439+
/// </summary>
440+
public FilterMode? FilterMode;
441+
/// <summary>
442+
/// Should only be used with texture properties. The `wrapMode` of the texture.
443+
/// </summary>
444+
public TextureWrapMode? WrapMode;
445+
/// <summary>
446+
/// Should only be used with float properties. Minimum value displayed on the slider, if applicable.
429447
/// </summary>
430448
public float? MinValue;
431449
/// <summary>
432-
/// Maximum value of the shader property, if applicable.
450+
/// Should only be used with float properties. Maximum value displayed on the slider, if applicable.
433451
/// </summary>
434452
public float? MaxValue;
435453
/// <summary>
454+
/// Indicates whether the shader property is hidden.
455+
/// </summary>
456+
public bool Hidden;
457+
/// <summary>
436458
/// Category of the shader property.
437459
/// </summary>
438460
public string Category;
@@ -443,18 +465,45 @@ public class ShaderPropertyData
443465
/// <param name="name">Name of the shader property.</param>
444466
/// <param name="type">Type of the shader property.</param>
445467
/// <param name="defaultValue">Default value of the shader property.</param>
446-
/// <param name="defaultValueAB">Default value of the shader property when loaded from an asset bundle.</param>
468+
/// <param name="defaultValueAB">Default value of the shader property when loaded from an asset bundle, like a texture.</param>
469+
/// <param name="anisoLevel">Should only be used with texture properties. The `anisoLevel` of the texture, 0-16.</param>
470+
/// <param name="filterMode">Should only be used with texture properties. The `filterMode` of the texture.</param>
471+
/// <param name="wrapMode">Should only be used with texture properties. The `wrapMode` of the texture.</param>
472+
/// <param name="minValue">Should only be used with float properties. Minimum value displayed on the slider, if applicable.</param>
473+
/// <param name="maxValue">Should only be used with float properties. Maximum value displayed on the slider, if applicable.</param>
447474
/// <param name="hidden">Indicates whether the shader property is hidden.</param>
448-
/// <param name="minValue">Minimum value of the shader property.</param>
449-
/// <param name="maxValue">Maximum value of the shader property.</param>
450475
/// <param name="category">Category of the shader property.</param>
451-
public ShaderPropertyData(string name, ShaderPropertyType type, string defaultValue = null, string defaultValueAB = null, string hidden = null, string minValue = null, string maxValue = null, string category = null)
476+
public ShaderPropertyData(
477+
string name, ShaderPropertyType type,
478+
string defaultValue = null, string defaultValueAB = null,
479+
string anisoLevel = null, string filterMode = null, string wrapMode = null,
480+
string minValue = null, string maxValue = null,
481+
string hidden = null, string category = null
482+
)
452483
{
453484
Name = name;
454485
Type = type;
455486
DefaultValue = defaultValue.IsNullOrEmpty() ? null : defaultValue;
456487
DefaultValueAssetBundle = defaultValueAB.IsNullOrEmpty() ? null : defaultValueAB;
457-
Hidden = bool.TryParse(hidden, out bool result) && result;
488+
489+
if (!anisoLevel.IsNullOrWhiteSpace())
490+
{
491+
int.TryParse(anisoLevel, out int outAnisoLevel);
492+
AnisoLevel = Mathf.Clamp(outAnisoLevel, 0, 16);
493+
}
494+
495+
if (!filterMode.IsNullOrWhiteSpace())
496+
{
497+
int.TryParse(filterMode, out int outFilterMode);
498+
if (Enum.IsDefined(typeof(FilterMode), outFilterMode)) FilterMode = (FilterMode)outFilterMode;
499+
}
500+
501+
if (!wrapMode.IsNullOrWhiteSpace())
502+
{
503+
int.TryParse(wrapMode, out int outWrapMode);
504+
if (Enum.IsDefined(typeof(TextureWrapMode), outWrapMode)) WrapMode = (TextureWrapMode)outWrapMode;
505+
}
506+
458507
if (!minValue.IsNullOrWhiteSpace() && !maxValue.IsNullOrWhiteSpace())
459508
{
460509
if (float.TryParse(minValue, out float min) && float.TryParse(maxValue, out float max))
@@ -463,6 +512,8 @@ public ShaderPropertyData(string name, ShaderPropertyType type, string defaultVa
463512
MaxValue = max;
464513
}
465514
}
515+
516+
Hidden = bool.TryParse(hidden, out bool result) && result;
466517
Category = category;
467518
}
468519
}

0 commit comments

Comments
 (0)