diff --git a/CHANGELOG.md b/CHANGELOG.md index 9290b29..6907fbb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this package are documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [0.1.1] - 2020-10-07 +### Added + - Input texture channel selection. + ## [0.1.0] - 2020-05-16 ### Added - Packing tool that supports GPU and CPU channel packing. \ No newline at end of file diff --git a/Editor/SmartTextureImporter.cs b/Editor/SmartTextureImporter.cs index f479a4d..db766e5 100644 --- a/Editor/SmartTextureImporter.cs +++ b/Editor/SmartTextureImporter.cs @@ -1,11 +1,10 @@ using System.IO; using UnityEditor; -using UnityEditor.Experimental.AssetImporters; using UnityEngine; using Object = UnityEngine.Object; -[ScriptedImporter(k_SmartTextureVersion, k_SmartTextureExtesion)] -public class SmartTextureImporter : ScriptedImporter +[UnityEditor.AssetImporters.ScriptedImporter(k_SmartTextureVersion, k_SmartTextureExtesion)] +public class SmartTextureImporter : UnityEditor.AssetImporters.ScriptedImporter { public const string k_SmartTextureExtesion = "smartex"; public const int k_SmartTextureVersion = 1; @@ -66,7 +65,7 @@ static void CreateSmartTextureMenuItem() "Smart Texture Asset for Unity. Allows to channel pack textures by using a ScriptedImporter. Requires Smart Texture Package from https://github.com/phi-lira/SmartTexture. Developed by Felipe Lira."); } - public override void OnImportAsset(AssetImportContext ctx) + public override void OnImportAsset(UnityEditor.AssetImporters.AssetImportContext ctx) { int width = m_TexturePlatformSettings.maxTextureSize; int height = m_TexturePlatformSettings.maxTextureSize; diff --git a/Editor/SmartTextureImporterEditor.cs b/Editor/SmartTextureImporterEditor.cs index a313cab..93f119b 100644 --- a/Editor/SmartTextureImporterEditor.cs +++ b/Editor/SmartTextureImporterEditor.cs @@ -1,10 +1,9 @@ using System; using UnityEditor; -using UnityEditor.Experimental.AssetImporters; using UnityEngine; [CustomEditor(typeof(SmartTextureImporter), true)] -public class SmartTextureImporterEditor : ScriptedImporterEditor +public class SmartTextureImporterEditor : UnityEditor.AssetImporters.ScriptedImporterEditor { internal static class Styles { @@ -16,7 +15,16 @@ internal static class Styles EditorGUIUtility.TrTextContent("Alpha Channel", "This texture source channel will be packed into the Output texture alpha channel"), }; + public static readonly GUIContent[] labelSourceChannels = + { + EditorGUIUtility.TrTextContent("R", "Use red channel from the source testure."), + EditorGUIUtility.TrTextContent("G", "Use green channel from the source testure."), + EditorGUIUtility.TrTextContent("B", "Use blue channel from the source testure."), + EditorGUIUtility.TrTextContent("A", "Use alpha channel from the source testure."), + }; + public static readonly GUIContent invertColor = EditorGUIUtility.TrTextContent("Invert Color", "If enabled outputs the inverted color (1.0 - color)"); + public static readonly GUIContent sourceChannel = EditorGUIUtility.TrTextContent("Source Channel", "Which channel from the source texture to use as input."); public static readonly GUIContent readWrite = EditorGUIUtility.TrTextContent("Read/Write Enabled", "Enable to be able to access the raw pixel data from code."); public static readonly GUIContent generateMipMaps = EditorGUIUtility.TrTextContent("Generate Mip Maps"); public static readonly GUIContent streamingMipMaps = EditorGUIUtility.TrTextContent("Streaming Mip Maps"); @@ -42,10 +50,10 @@ internal static class Styles SerializedProperty[] m_InputTextures = new SerializedProperty[4]; SerializedProperty[] m_InputTextureSettings = new SerializedProperty[4]; - + SerializedProperty m_IsReadableProperty; SerializedProperty m_sRGBTextureProperty; - + SerializedProperty m_EnableMipMapProperty; SerializedProperty m_StreamingMipMaps; SerializedProperty m_StreamingMipMapPriority; @@ -62,19 +70,19 @@ internal static class Styles bool m_ShowAdvanced = false; const string k_AdvancedTextureSettingName = "SmartTextureImporterShowAdvanced"; - + public override void OnEnable() { base.OnEnable(); CacheSerializedProperties(); } - + public override void OnInspectorGUI() { serializedObject.Update(); - + m_ShowAdvanced = EditorPrefs.GetBool(k_AdvancedTextureSettingName, m_ShowAdvanced); - + EditorGUILayout.Space(); EditorGUILayout.LabelField("Input Textures", EditorStyles.boldLabel); using (new EditorGUI.IndentLevelScope()) @@ -86,7 +94,7 @@ public override void OnInspectorGUI() } EditorGUILayout.Space(); EditorGUILayout.Space(); - + EditorGUILayout.LabelField("Output Texture", EditorStyles.boldLabel); using (new EditorGUI.IndentLevelScope()) { @@ -123,8 +131,15 @@ void DrawInputTexture(int index) EditorGUILayout.PropertyField(m_InputTextures[index], Styles.labelChannels[index]); + SerializedProperty sourceChannel = m_InputTextureSettings[index].FindPropertyRelative("sourceChannel"); + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.PrefixLabel(Styles.sourceChannel); + sourceChannel.intValue = GUILayout.Toolbar(sourceChannel.intValue, Styles.labelSourceChannels); + EditorGUILayout.EndHorizontal(); + SerializedProperty invertColor = m_InputTextureSettings[index].FindPropertyRelative("invertColor"); invertColor.boolValue = EditorGUILayout.Toggle(Styles.invertColor, invertColor.boolValue); + EditorGUILayout.Space(); } @@ -187,7 +202,7 @@ void DrawTextureImporterSettings() } } } - + void CacheSerializedProperties() { SerializedProperty texturesProperty = serializedObject.FindProperty("m_InputTextures"); @@ -197,10 +212,10 @@ void CacheSerializedProperties() m_InputTextures[i] = texturesProperty.GetArrayElementAtIndex(i); m_InputTextureSettings[i] = settingsProperty.GetArrayElementAtIndex(i); } - + m_IsReadableProperty = serializedObject.FindProperty("m_IsReadable"); m_sRGBTextureProperty = serializedObject.FindProperty("m_sRGBTexture"); - + m_EnableMipMapProperty = serializedObject.FindProperty("m_EnableMipMap"); m_StreamingMipMaps = serializedObject.FindProperty("m_StreamingMipMaps"); m_StreamingMipMapPriority = serializedObject.FindProperty("m_StreamingMipMapPriority"); diff --git a/Runtime/TextureChannelPacker.cs b/Runtime/TextureChannelPacker.cs index 20cd558..0ebac4c 100644 --- a/Runtime/TextureChannelPacker.cs +++ b/Runtime/TextureChannelPacker.cs @@ -16,12 +16,24 @@ public struct TexturePackingSettings /// Outputs the inverted color (1.0 - color) /// public bool invertColor; + +/// +/// Contains settings which channel to use from the source texture (0 = R, G = 1, B = 2, A = 3) +/// + public int sourceChannel; } public static class TextureExtension { static Material s_PackChannelMaterial = null; + static readonly Vector4[] channelSelector = { + new Vector4(1f,0f,0f,0f), + new Vector4(0f,1f,0f,0f), + new Vector4(0f,0f,1f,0f), + new Vector4(0f,0f,0f,1f) + }; + private static Material packChannelMaterial { get @@ -52,6 +64,7 @@ public static void PackChannels(this Texture2D mask, Texture2D[] textures, Textu for (int i = 0; i < settings.Length; ++i) { settings[i].invertColor = false; + settings[i].sourceChannel = 0; } } @@ -92,6 +105,12 @@ public static void PackChannels(this Texture2D mask, Texture2D[] textures, Textu packChannelMaterial.SetTexture("_AlphaChannel", textures[3] != null ? textures[3] : Texture2D.blackTexture); packChannelMaterial.SetVector("_InvertColor", new Vector4(invertColor[0], invertColor[1], invertColor[2], invertColor[3])); + packChannelMaterial.SetVector("_RedSourceChannel", channelSelector[settings[0].sourceChannel]); + packChannelMaterial.SetVector("_GreenSourceChannel", channelSelector[settings[1].sourceChannel]); + packChannelMaterial.SetVector("_BlueSourceChannel", channelSelector[settings[2].sourceChannel]); + packChannelMaterial.SetVector("_AlphaSourceChannel", channelSelector[settings[3].sourceChannel]); + + var rt = RenderTexture.GetTemporary(width, height, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear); RenderTexture previous = RenderTexture.active; @@ -120,10 +139,10 @@ public static void PackChannels(this Texture2D mask, Texture2D[] textures, Textu Color[] maskPixels = new Color[pixelCount]; for (int i = 0; i < pixelCount; ++i) { - float r = (textures[0] != null) ? pixels[0][i].r : 0.0f; - float g = (textures[1] != null) ? pixels[1][i].r : 0.0f; - float b = (textures[2] != null) ? pixels[2][i].r : 0.0f; - float a = (textures[3] != null) ? pixels[3][i].r : 0.0f; + float r = (textures[0] != null) ? pixels[0][i][settings[0].sourceChannel] : 0.0f; + float g = (textures[1] != null) ? pixels[1][i][settings[0].sourceChannel] : 0.0f; + float b = (textures[2] != null) ? pixels[2][i][settings[0].sourceChannel] : 0.0f; + float a = (textures[3] != null) ? pixels[3][i][settings[0].sourceChannel] : 0.0f; if (settings[0].invertColor) r = 1.0f - r; diff --git a/Shaders/PackShader.shader b/Shaders/PackShader.shader index 0c8410c..7f0d080 100644 --- a/Shaders/PackShader.shader +++ b/Shaders/PackShader.shader @@ -15,6 +15,11 @@ Texture2D _BlueChannel; Texture2D _AlphaChannel; sampler sampler_point_clamp; + + //Returns channel with the highest value + half max4(half4 i) { + return max(max(max(i.r, i.g), i.b), i.a); + } ENDHLSL @@ -35,6 +40,10 @@ CBUFFER_START(UnityPerMaterial) float4 _RedChannel_TexelSize; half4 _InvertColor; + half4 _RedSourceChannel; + half4 _GreenSourceChannel; + half4 _BlueSourceChannel; + half4 _AlphaSourceChannel; CBUFFER_END float4 vert(float4 positionOS : POSITION) : SV_POSITION @@ -45,22 +54,22 @@ half4 frag(float4 positionHCS : SV_POSITION) : SV_Target { float2 uv = positionHCS * _RedChannel_TexelSize.xy; - half r = _RedChannel.Sample(sampler_point_clamp, uv).r; - half g = _GreenChannel.Sample(sampler_point_clamp, uv).r; - half b = _BlueChannel.Sample(sampler_point_clamp, uv).r; - half a = _AlphaChannel.Sample(sampler_point_clamp, uv).r; + half r = max4(_RedChannel.Sample(sampler_point_clamp, uv).rgba * _RedSourceChannel); + half g = max4(_GreenChannel.Sample(sampler_point_clamp, uv).rgba * _GreenSourceChannel); + half b = max4(_BlueChannel.Sample(sampler_point_clamp, uv).rgba * _BlueSourceChannel); + half a = max4(_AlphaChannel.Sample(sampler_point_clamp, uv).rgba * _AlphaSourceChannel); if (_InvertColor.x > 0.0) - r = 1.0 - r; + r = 1.0 - r; if (_InvertColor.g > 0.0) - g = 1.0 - g; + g = 1.0 - g; if (_InvertColor.b > 0.0) - b = 1.0 - b; + b = 1.0 - b; if (_InvertColor.a > 0.0) - a = 1.0 - a; + a = 1.0 - a; return half4(r, g, b, a); } ENDHLSL @@ -80,6 +89,10 @@ CBUFFER_START(UnityPerMaterial) float4 _RedChannel_TexelSize; half4 _InvertColor; + half4 _RedSourceChannel; + half4 _GreenSourceChannel; + half4 _BlueSourceChannel; + half4 _AlphaSourceChannel; CBUFFER_END float4 vert(float4 positionOS : POSITION) : SV_POSITION @@ -90,22 +103,22 @@ half4 frag(float4 positionHCS : SV_POSITION) : SV_Target { float2 uv = positionHCS * _RedChannel_TexelSize.xy; - half r = _RedChannel.Sample(sampler_point_clamp, uv).r; - half g = _GreenChannel.Sample(sampler_point_clamp, uv).r; - half b = _BlueChannel.Sample(sampler_point_clamp, uv).r; - half a = _AlphaChannel.Sample(sampler_point_clamp, uv).r; + half r = max4(_RedChannel.Sample(sampler_point_clamp, uv).rgba * _RedSourceChannel); + half g = max4(_GreenChannel.Sample(sampler_point_clamp, uv).rgba * _GreenSourceChannel); + half b = max4(_BlueChannel.Sample(sampler_point_clamp, uv).rgba * _BlueSourceChannel); + half a = max4(_AlphaChannel.Sample(sampler_point_clamp, uv).rgba * _AlphaSourceChannel); if (_InvertColor.x > 0.0) - r = 1.0 - r; + r = 1.0 - r; if (_InvertColor.g > 0.0) - g = 1.0 - g; + g = 1.0 - g; if (_InvertColor.b > 0.0) - b = 1.0 - b; + b = 1.0 - b; if (_InvertColor.a > 0.0) - a = 1.0 - a; + a = 1.0 - a; return half4(r, g, b, a); } ENDHLSL diff --git a/package.json b/package.json index 5eab71e..400b3ff 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "com.phi-lira.smarttexture", "description": "Allows to create smart texture assets for Unity.", - "version": "0.1.0", + "version": "0.1.1", "unity": "2019.3", "displayName": "Smart Texture", "dependencies": {