diff --git a/MToon.meta b/MToon.meta new file mode 100644 index 0000000..1561eda --- /dev/null +++ b/MToon.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: bd324684e5355ad469723cbce9e86fca +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/MToon/Editor.meta b/MToon/Editor.meta new file mode 100644 index 0000000..59203d1 --- /dev/null +++ b/MToon/Editor.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 1b669562c8ecaee4c98c808d3971271b +folderAsset: yes +timeCreated: 1514224760 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/MToon/Editor/EditorUtils.cs b/MToon/Editor/EditorUtils.cs new file mode 100644 index 0000000..274c5c3 --- /dev/null +++ b/MToon/Editor/EditorUtils.cs @@ -0,0 +1,61 @@ +using System.IO; +using System.Text.RegularExpressions; +using UnityEditor; +using UnityEngine; + +namespace MToon +{ + public class EditorUtils + { + private static string BasePath { get { return Path.Combine(Application.dataPath, "VRM/MToon"); } } + + private static string ShaderFilePath { get { return Path.Combine(BasePath, "MToon/Resources/Shaders/MToon.shader"); } } + private static string ReadMeFilePath { get { return Path.Combine(BasePath, "README.md"); } } + private static string VersionFilePath { get { return Path.Combine(BasePath, "MToon/Scripts/UtilsVersion.cs"); } } + + + //[MenuItem("VRM/MToon Version Up")] + private static void VerUp(string version) + { + UpdateShaderFile(version); + UpdateReadMeFile(version); + UpdateVersionFile(version); + } + + private static void UpdateShaderFile(string version) + { + var file = File.ReadAllText(ShaderFilePath); + file = Regex.Replace( + file, + "(_MToonVersion \\(\"_MToonVersion\", Float\\) = )(\\d+)", + "${1}" + version + ); + File.WriteAllText(ShaderFilePath, file); + } + + private static void UpdateReadMeFile(string version) + { + version = "v" + version.Substring(0, version.Length - 1) + "." + version[version.Length - 1]; + + var file = File.ReadAllText(ReadMeFilePath); + file = Regex.Replace( + file, + "v(\\d+)\\.(\\d+)", + version + ); + File.WriteAllText(ReadMeFilePath, file); + } + + private static void UpdateVersionFile(string version) + { + var file = File.ReadAllText(VersionFilePath); + file = Regex.Replace( + file, + "(public const int VersionNumber = )(\\d+)(;)", + "${1}" + version + "${3}" + ); + File.WriteAllText(VersionFilePath, file); + + } + } +} \ No newline at end of file diff --git a/MToon/Editor/EditorUtils.cs.meta b/MToon/Editor/EditorUtils.cs.meta new file mode 100644 index 0000000..334cf67 --- /dev/null +++ b/MToon/Editor/EditorUtils.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 531922bb16b74a00b81445116c49b09c +timeCreated: 1559719559 \ No newline at end of file diff --git a/MToon/Editor/MToon.Editor.asmdef b/MToon/Editor/MToon.Editor.asmdef new file mode 100644 index 0000000..e60398d --- /dev/null +++ b/MToon/Editor/MToon.Editor.asmdef @@ -0,0 +1,12 @@ +{ + "name": "MToon.Editor", + "references": [ + "MToon" + ], + "optionalUnityReferences": [], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false +} \ No newline at end of file diff --git a/MToon/Editor/MToon.Editor.asmdef.meta b/MToon/Editor/MToon.Editor.asmdef.meta new file mode 100644 index 0000000..57face7 --- /dev/null +++ b/MToon/Editor/MToon.Editor.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: dddf8398e965f254cae2d7519d7f67d2 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/MToon/Editor/MToonInspector.cs b/MToon/Editor/MToonInspector.cs new file mode 100644 index 0000000..9705cda --- /dev/null +++ b/MToon/Editor/MToonInspector.cs @@ -0,0 +1,405 @@ +using System; +using System.Linq; +using UnityEditor; +using UnityEngine; +using UnityEngine.Rendering; + +namespace MToon +{ + public class MToonInspector : ShaderGUI + { + private static bool isAdvancedLightingPanelFoldout = false; + + private MaterialProperty _version; + private MaterialProperty _blendMode; + private MaterialProperty _bumpMap; + private MaterialProperty _bumpScale; + private MaterialProperty _color; + private MaterialProperty _cullMode; +// private MaterialProperty _outlineCullMode; + private MaterialProperty _cutoff; + + private MaterialProperty _debugMode; + private MaterialProperty _emissionColor; + private MaterialProperty _emissionMap; + private MaterialProperty _lightColorAttenuation; + private MaterialProperty _indirectLightIntensity; + private MaterialProperty _mainTex; + private MaterialProperty _outlineColor; + private MaterialProperty _outlineColorMode; + private MaterialProperty _outlineLightingMix; + private MaterialProperty _outlineWidth; + private MaterialProperty _outlineScaledMaxDistance; + private MaterialProperty _outlineWidthMode; + private MaterialProperty _outlineWidthTexture; + private MaterialProperty _receiveShadowRate; + private MaterialProperty _receiveShadowTexture; + private MaterialProperty _shadingGradeRate; + private MaterialProperty _shadingGradeTexture; + private MaterialProperty _shadeColor; + private MaterialProperty _shadeShift; + private MaterialProperty _shadeTexture; + private MaterialProperty _shadeToony; + private MaterialProperty _sphereAdd; + private MaterialProperty _rimColor; + private MaterialProperty _rimTexture; + private MaterialProperty _rimLightingMix; + private MaterialProperty _rimFresnelPower; + private MaterialProperty _rimLift; + private MaterialProperty _uvAnimMaskTexture; + private MaterialProperty _uvAnimScrollX; + private MaterialProperty _uvAnimScrollY; + private MaterialProperty _uvAnimRotation; + + public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties) + { + _version = FindProperty(Utils.PropVersion, properties); + _debugMode = FindProperty(Utils.PropDebugMode, properties); + _outlineWidthMode = FindProperty(Utils.PropOutlineWidthMode, properties); + _outlineColorMode = FindProperty(Utils.PropOutlineColorMode, properties); + _blendMode = FindProperty(Utils.PropBlendMode, properties); + _cullMode = FindProperty(Utils.PropCullMode, properties); +// _outlineCullMode = FindProperty(Utils.PropOutlineCullMode, properties); + _cutoff = FindProperty(Utils.PropCutoff, properties); + _color = FindProperty(Utils.PropColor, properties); + _shadeColor = FindProperty(Utils.PropShadeColor, properties); + _mainTex = FindProperty(Utils.PropMainTex, properties); + _shadeTexture = FindProperty(Utils.PropShadeTexture, properties); + _bumpScale = FindProperty(Utils.PropBumpScale, properties); + _bumpMap = FindProperty(Utils.PropBumpMap, properties); + _receiveShadowRate = FindProperty(Utils.PropReceiveShadowRate, properties); + _receiveShadowTexture = FindProperty(Utils.PropReceiveShadowTexture, properties); + _shadingGradeRate = FindProperty(Utils.PropShadingGradeRate, properties); + _shadingGradeTexture = FindProperty(Utils.PropShadingGradeTexture, properties); + _shadeShift = FindProperty(Utils.PropShadeShift, properties); + _shadeToony = FindProperty(Utils.PropShadeToony, properties); + _lightColorAttenuation = FindProperty(Utils.PropLightColorAttenuation, properties); + _indirectLightIntensity = FindProperty(Utils.PropIndirectLightIntensity, properties); + _rimColor = FindProperty(Utils.PropRimColor, properties); + _rimTexture = FindProperty(Utils.PropRimTexture, properties); + _rimLightingMix = FindProperty(Utils.PropRimLightingMix, properties); + _rimFresnelPower = FindProperty(Utils.PropRimFresnelPower, properties); + _rimLift = FindProperty(Utils.PropRimLift, properties); + _sphereAdd = FindProperty(Utils.PropSphereAdd, properties); + _emissionColor = FindProperty(Utils.PropEmissionColor, properties); + _emissionMap = FindProperty(Utils.PropEmissionMap, properties); + _outlineWidthTexture = FindProperty(Utils.PropOutlineWidthTexture, properties); + _outlineWidth = FindProperty(Utils.PropOutlineWidth, properties); + _outlineScaledMaxDistance = FindProperty(Utils.PropOutlineScaledMaxDistance, properties); + _outlineColor = FindProperty(Utils.PropOutlineColor, properties); + _outlineLightingMix = FindProperty(Utils.PropOutlineLightingMix, properties); + _uvAnimMaskTexture = FindProperty(Utils.PropUvAnimMaskTexture, properties); + _uvAnimScrollX = FindProperty(Utils.PropUvAnimScrollX, properties); + _uvAnimScrollY = FindProperty(Utils.PropUvAnimScrollY, properties); + _uvAnimRotation = FindProperty(Utils.PropUvAnimRotation, properties); + + var materials = materialEditor.targets.Select(x => x as Material).ToArray(); + Draw(materialEditor, materials); + } + + private void Draw(MaterialEditor materialEditor, Material[] materials) + { + EditorGUI.BeginChangeCheck(); + { + _version.floatValue = Utils.VersionNumber; + + EditorGUILayout.LabelField("Rendering", EditorStyles.boldLabel); + EditorGUILayout.BeginVertical(GUI.skin.box); + { + EditorGUILayout.LabelField("Mode", EditorStyles.boldLabel); + if (PopupEnum("Rendering Type", _blendMode, materialEditor)) + { + ModeChanged(materials, isBlendModeChangedByUser: true); + } + + if ((RenderMode) _blendMode.floatValue == RenderMode.TransparentWithZWrite) + { + EditorGUILayout.HelpBox("TransparentWithZWrite mode can cause problems with rendering.", MessageType.Warning); + } + + if (PopupEnum("Cull Mode", _cullMode, materialEditor)) + { + ModeChanged(materials); + } + } + EditorGUILayout.EndVertical(); + EditorGUILayout.Space(); + + EditorGUILayout.LabelField("Color", EditorStyles.boldLabel); + EditorGUILayout.BeginVertical(GUI.skin.box); + { + EditorGUILayout.LabelField("Texture", EditorStyles.boldLabel); + { + materialEditor.TexturePropertySingleLine(new GUIContent("Lit Color, Alpha", "Lit (RGB), Alpha (A)"), + _mainTex, _color); + + materialEditor.TexturePropertySingleLine(new GUIContent("Shade Color", "Shade (RGB)"), _shadeTexture, + _shadeColor); + } + var bm = (RenderMode) _blendMode.floatValue; + if (bm == RenderMode.Cutout) + { + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Alpha", EditorStyles.boldLabel); + { + materialEditor.ShaderProperty(_cutoff, "Cutoff"); + } + } + } + EditorGUILayout.EndVertical(); + EditorGUILayout.Space(); + + EditorGUILayout.LabelField("Lighting", EditorStyles.boldLabel); + EditorGUILayout.BeginVertical(GUI.skin.box); + { + { + materialEditor.ShaderProperty(_shadeToony, + new GUIContent("Shading Toony", + "0.0 is Lambert. Higher value get toony shading.")); + + // Normal + EditorGUI.BeginChangeCheck(); + materialEditor.TexturePropertySingleLine(new GUIContent("Normal Map [Normal]", "Normal Map (RGB)"), + _bumpMap, + _bumpScale); + if (EditorGUI.EndChangeCheck()) + { + materialEditor.RegisterPropertyChangeUndo("BumpEnabledDisabled"); + ModeChanged(materials); + } + } + EditorGUILayout.Space(); + + EditorGUI.indentLevel++; + { + isAdvancedLightingPanelFoldout = EditorGUILayout.Foldout(isAdvancedLightingPanelFoldout, "Advanced Settings", EditorStyles.boldFont); + + if (isAdvancedLightingPanelFoldout) + { + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.HelpBox( + "The default settings are suitable for Advanced Settings if you want to toony result.", + MessageType.Info); + if (GUILayout.Button("Use Default")) + { + _shadeShift.floatValue = 0; + _receiveShadowTexture.textureValue = null; + _receiveShadowRate.floatValue = 1; + _shadingGradeTexture.textureValue = null; + _shadingGradeRate.floatValue = 1; + _lightColorAttenuation.floatValue = 0; + _indirectLightIntensity.floatValue = 0.1f; + } + EditorGUILayout.EndHorizontal(); + + materialEditor.ShaderProperty(_shadeShift, + new GUIContent("Shading Shift", + "Zero is Default. Negative value increase lit area. Positive value increase shade area.")); + materialEditor.TexturePropertySingleLine( + new GUIContent("Shadow Receive Multiplier", + "Texture (R) * Rate. White is Default. Black attenuates shadows."), + _receiveShadowTexture, + _receiveShadowRate); + materialEditor.TexturePropertySingleLine( + new GUIContent("Lit & Shade Mixing Multiplier", + "Texture (R) * Rate. Compatible with UTS2 ShadingGradeMap. White is Default. Black amplifies shade."), + _shadingGradeTexture, + _shadingGradeRate); + materialEditor.ShaderProperty(_lightColorAttenuation, "LightColor Attenuation"); + materialEditor.ShaderProperty(_indirectLightIntensity, "GI Intensity"); + } + } + EditorGUI.indentLevel--; + } + EditorGUILayout.EndVertical(); + EditorGUILayout.Space(); + + EditorGUILayout.LabelField("Emission", EditorStyles.boldLabel); + EditorGUILayout.BeginVertical(GUI.skin.box); + { + TextureWithHdrColor(materialEditor, "Emission", "Emission (RGB)", + _emissionMap, _emissionColor); + + materialEditor.TexturePropertySingleLine(new GUIContent("MatCap", "MatCap Texture (RGB)"), + _sphereAdd); + } + EditorGUILayout.EndVertical(); + EditorGUILayout.Space(); + + EditorGUILayout.LabelField("Rim", EditorStyles.boldLabel); + EditorGUILayout.BeginVertical(GUI.skin.box); + { + TextureWithHdrColor(materialEditor, "Color", "Rim Color (RGB)", + _rimTexture, _rimColor); + + materialEditor.DefaultShaderProperty(_rimLightingMix, "Lighting Mix"); + + materialEditor.ShaderProperty(_rimFresnelPower, + new GUIContent("Fresnel Power", + "If you increase this value, you get sharpness rim light.")); + + materialEditor.ShaderProperty(_rimLift, + new GUIContent("Lift", + "If you increase this value, you can lift rim light.")); + } + EditorGUILayout.EndVertical(); + EditorGUILayout.Space(); + + + EditorGUILayout.LabelField("Outline", EditorStyles.boldLabel); + EditorGUILayout.BeginVertical(GUI.skin.box); + { + // Outline + EditorGUILayout.LabelField("Width", EditorStyles.boldLabel); + { + if (PopupEnum("Mode", _outlineWidthMode, materialEditor)) + { + ModeChanged(materials); + } + + if ((RenderMode) _blendMode.floatValue == RenderMode.Transparent && + (OutlineWidthMode) _outlineWidthMode.floatValue != OutlineWidthMode.None) + { + EditorGUILayout.HelpBox("Outline with Transparent material cause problem with rendering.", MessageType.Warning); + } + + var widthMode = (OutlineWidthMode) _outlineWidthMode.floatValue; + if (widthMode != OutlineWidthMode.None) + { + materialEditor.TexturePropertySingleLine( + new GUIContent("Width", "Outline Width Texture (RGB)"), + _outlineWidthTexture, _outlineWidth); + } + + if (widthMode == OutlineWidthMode.ScreenCoordinates) + { + materialEditor.ShaderProperty(_outlineScaledMaxDistance, "Width Scaled Max Distance"); + } + } + EditorGUILayout.Space(); + + EditorGUILayout.LabelField("Color", EditorStyles.boldLabel); + { + var widthMode = (OutlineWidthMode) _outlineWidthMode.floatValue; + if (widthMode != OutlineWidthMode.None) + { + EditorGUI.BeginChangeCheck(); + + if (PopupEnum("Mode", _outlineColorMode, materialEditor)) + { + ModeChanged(materials); + } + + var colorMode = (OutlineColorMode) _outlineColorMode.floatValue; + + materialEditor.ShaderProperty(_outlineColor, "Color"); + if (colorMode == OutlineColorMode.MixedLighting) + materialEditor.DefaultShaderProperty(_outlineLightingMix, "Lighting Mix"); + } + } + } + EditorGUILayout.EndVertical(); + EditorGUILayout.Space(); + + + EditorGUILayout.LabelField("UV Coordinates", EditorStyles.boldLabel); + EditorGUILayout.BeginVertical(GUI.skin.box); + { + // UV + EditorGUILayout.LabelField("Scale & Offset", EditorStyles.boldLabel); + { + materialEditor.TextureScaleOffsetProperty(_mainTex); + } + EditorGUILayout.Space(); + + EditorGUILayout.LabelField("Auto Animation", EditorStyles.boldLabel); + { + materialEditor.TexturePropertySingleLine(new GUIContent("Mask", "Auto Animation Mask Texture (R)"), _uvAnimMaskTexture); + materialEditor.ShaderProperty(_uvAnimScrollX, "Scroll X (per second)"); + materialEditor.ShaderProperty(_uvAnimScrollY, "Scroll Y (per second)"); + materialEditor.ShaderProperty(_uvAnimRotation, "Rotation (per second)"); + } + } + EditorGUILayout.EndVertical(); + EditorGUILayout.Space(); + + + EditorGUILayout.LabelField("Options", EditorStyles.boldLabel); + EditorGUILayout.BeginVertical(GUI.skin.box); + { + EditorGUILayout.LabelField("Debugging Options", EditorStyles.boldLabel); + { + if (PopupEnum("Visualize", _debugMode, materialEditor)) + { + ModeChanged(materials); + } + } + EditorGUILayout.Space(); + + EditorGUILayout.LabelField("Advanced Options", EditorStyles.boldLabel); + { +#if UNITY_5_6_OR_NEWER +// materialEditor.EnableInstancingField(); + materialEditor.DoubleSidedGIField(); +#endif + EditorGUI.BeginChangeCheck(); + materialEditor.RenderQueueField(); + if (EditorGUI.EndChangeCheck()) + { + ModeChanged(materials); + } + } + } + EditorGUILayout.EndVertical(); + EditorGUILayout.Space(); + } + EditorGUI.EndChangeCheck(); + } + + public override void AssignNewShaderToMaterial(Material material, Shader oldShader, Shader newShader) + { + base.AssignNewShaderToMaterial(material, oldShader, newShader); + + Utils.ValidateProperties(material, isBlendModeChangedByUser: true); + } + + private static void ModeChanged(Material[] materials, bool isBlendModeChangedByUser = false) + { + foreach (var material in materials) + { + Utils.ValidateProperties(material, isBlendModeChangedByUser); + } + } + + private static bool PopupEnum(string name, MaterialProperty property, MaterialEditor editor) where T : struct + { + EditorGUI.showMixedValue = property.hasMixedValue; + EditorGUI.BeginChangeCheck(); + var ret = EditorGUILayout.Popup(name, (int) property.floatValue, Enum.GetNames(typeof(T))); + var changed = EditorGUI.EndChangeCheck(); + if (changed) + { + editor.RegisterPropertyChangeUndo("EnumPopUp"); + property.floatValue = ret; + } + + EditorGUI.showMixedValue = false; + return changed; + } + + private static void TextureWithHdrColor(MaterialEditor materialEditor, string label, string description, + MaterialProperty texProp, MaterialProperty colorProp) + { + materialEditor.TexturePropertyWithHDRColor(new GUIContent(label, description), + texProp, + colorProp, +#if UNITY_2018_1_OR_NEWER +#else + new ColorPickerHDRConfig(minBrightness: 0, maxBrightness: 10, minExposureValue: -10, + maxExposureValue: 10), +#endif + showAlpha: false); + + } + } +} \ No newline at end of file diff --git a/MToon/Editor/MToonInspector.cs.meta b/MToon/Editor/MToonInspector.cs.meta new file mode 100644 index 0000000..cfe6932 --- /dev/null +++ b/MToon/Editor/MToonInspector.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 8b43baa9f62f04748bb167ad186f1b1a +timeCreated: 1514224771 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/MToon/LICENSE b/MToon/LICENSE new file mode 100644 index 0000000..2b51a7f --- /dev/null +++ b/MToon/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Masataka SUMI + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/MToon/LICENSE.meta b/MToon/LICENSE.meta new file mode 100644 index 0000000..7bba05a --- /dev/null +++ b/MToon/LICENSE.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 455e6a1ad28c94341a88a29164ed7b4c +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/MToon/README.md b/MToon/README.md new file mode 100644 index 0000000..60394f4 --- /dev/null +++ b/MToon/README.md @@ -0,0 +1,11 @@ +# MToon +Toon Shader with Unity Global Illumination + +## Tutorial +https://niconare.nicovideo.jp/watch/kn3485 + +## Version +v3.2 + +## Release Note +https://github.com/Santarh/MToon/releases diff --git a/MToon/README.md.meta b/MToon/README.md.meta new file mode 100644 index 0000000..c9d4b26 --- /dev/null +++ b/MToon/README.md.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: c14ccd806ab1ddb449000d109875cbdb +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/MToon/Runtime.meta b/MToon/Runtime.meta new file mode 100644 index 0000000..f8e901d --- /dev/null +++ b/MToon/Runtime.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 88551f898b0043c41b202eeb79752973 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/MToon/Runtime/Resources.meta b/MToon/Runtime/Resources.meta new file mode 100644 index 0000000..f1a215f --- /dev/null +++ b/MToon/Runtime/Resources.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9491ac346386a2b4e9f3c801c6786818 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/MToon/Runtime/Resources/Shaders.meta b/MToon/Runtime/Resources/Shaders.meta new file mode 100644 index 0000000..09aef81 --- /dev/null +++ b/MToon/Runtime/Resources/Shaders.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 221dcd8025c13ab42a51e886d7a7a92e +folderAsset: yes +timeCreated: 1516295202 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/MToon/Runtime/Resources/Shaders/MToon.shader b/MToon/Runtime/Resources/Shaders/MToon.shader new file mode 100644 index 0000000..48cf589 --- /dev/null +++ b/MToon/Runtime/Resources/Shaders/MToon.shader @@ -0,0 +1,162 @@ +Shader "VRM/MToon" +{ + Properties + { + _Cutoff ("Alpha Cutoff", Range(0, 1)) = 0.5 + _Color ("Lit Color + Alpha", Color) = (1,1,1,1) + _ShadeColor ("Shade Color", Color) = (0.97, 0.81, 0.86, 1) + [NoScaleOffset] _MainTex ("Lit Texture + Alpha", 2D) = "white" {} + [NoScaleOffset] _ShadeTexture ("Shade Texture", 2D) = "white" {} + _BumpScale ("Normal Scale", Float) = 1.0 + [Normal] _BumpMap ("Normal Texture", 2D) = "bump" {} + _ReceiveShadowRate ("Receive Shadow", Range(0, 1)) = 1 + [NoScaleOffset] _ReceiveShadowTexture ("Receive Shadow Texture", 2D) = "white" {} + _ShadingGradeRate ("Shading Grade", Range(0, 1)) = 1 + [NoScaleOffset] _ShadingGradeTexture ("Shading Grade Texture", 2D) = "white" {} + _ShadeShift ("Shade Shift", Range(-1, 1)) = 0 + _ShadeToony ("Shade Toony", Range(0, 1)) = 0.9 + _LightColorAttenuation ("Light Color Attenuation", Range(0, 1)) = 0 + _IndirectLightIntensity ("Indirect Light Intensity", Range(0, 1)) = 0.1 + [HDR] _RimColor ("Rim Color", Color) = (0,0,0) + [NoScaleOffset] _RimTexture ("Rim Texture", 2D) = "white" {} + _RimLightingMix ("Rim Lighting Mix", Range(0, 1)) = 0 + [PowerSlider(4.0)] _RimFresnelPower ("Rim Fresnel Power", Range(0, 100)) = 1 + _RimLift ("Rim Lift", Range(0, 1)) = 0 + [NoScaleOffset] _SphereAdd ("Sphere Texture(Add)", 2D) = "black" {} + [HDR] _EmissionColor ("Color", Color) = (0,0,0) + [NoScaleOffset] _EmissionMap ("Emission", 2D) = "white" {} + [NoScaleOffset] _OutlineWidthTexture ("Outline Width Tex", 2D) = "white" {} + _OutlineWidth ("Outline Width", Range(0.01, 1)) = 0.5 + _OutlineScaledMaxDistance ("Outline Scaled Max Distance", Range(1, 10)) = 1 + _OutlineColor ("Outline Color", Color) = (0,0,0,1) + _OutlineLightingMix ("Outline Lighting Mix", Range(0, 1)) = 1 + [NoScaleOffset] _UvAnimMaskTexture ("UV Animation Mask", 2D) = "white" {} + _UvAnimScrollX ("UV Animation Scroll X", Float) = 0 + _UvAnimScrollY ("UV Animation Scroll Y", Float) = 0 + _UvAnimRotation ("UV Animation Rotation", Float) = 0 + + [HideInInspector] _MToonVersion ("_MToonVersion", Float) = 32 + [HideInInspector] _DebugMode ("_DebugMode", Float) = 0.0 + [HideInInspector] _BlendMode ("_BlendMode", Float) = 0.0 + [HideInInspector] _OutlineWidthMode ("_OutlineWidthMode", Float) = 0.0 + [HideInInspector] _OutlineColorMode ("_OutlineColorMode", Float) = 0.0 + [HideInInspector] _CullMode ("_CullMode", Float) = 2.0 + [HideInInspector] _OutlineCullMode ("_OutlineCullMode", Float) = 1.0 + [HideInInspector] _SrcBlend ("_SrcBlend", Float) = 1.0 + [HideInInspector] _DstBlend ("_DstBlend", Float) = 0.0 + [HideInInspector] _ZWrite ("_ZWrite", Float) = 1.0 + } + + // for SM 3.0 + SubShader + { + Tags { "RenderType" = "Opaque" "Queue" = "Geometry" } + + // Forward Base + Pass + { + Name "FORWARD_BASE" + Tags { "LightMode" = "ForwardBase" } + + Cull [_CullMode] + Blend [_SrcBlend] [_DstBlend] + ZWrite [_ZWrite] + ZTest LEqual + BlendOp Add, Max + + CGPROGRAM + #pragma target 3.0 + #pragma shader_feature _ MTOON_DEBUG_NORMAL MTOON_DEBUG_LITSHADERATE + #pragma multi_compile _ _NORMALMAP + #pragma multi_compile _ _ALPHATEST_ON _ALPHABLEND_ON + #include "./MToonSM3.cginc" + #pragma vertex vert_forward_base + #pragma fragment frag_forward + #pragma multi_compile_fwdbase + #pragma multi_compile_fog +// #pragma multi_compile_instancing + ENDCG + } + + + // Forward Base Outline Pass + Pass + { + Name "FORWARD_BASE_ONLY_OUTLINE" + Tags { "LightMode" = "ForwardBase" } + + Cull [_OutlineCullMode] + Blend [_SrcBlend] [_DstBlend] + ZWrite [_ZWrite] + ZTest LEqual + Offset 1, 1 + BlendOp Add, Max + + CGPROGRAM + #pragma target 3.0 + #pragma shader_feature _ MTOON_DEBUG_NORMAL MTOON_DEBUG_LITSHADERATE + #pragma multi_compile _ MTOON_OUTLINE_WIDTH_WORLD MTOON_OUTLINE_WIDTH_SCREEN + #pragma multi_compile _ MTOON_OUTLINE_COLOR_FIXED MTOON_OUTLINE_COLOR_MIXED + #pragma multi_compile _ _NORMALMAP + #pragma multi_compile _ _ALPHATEST_ON _ALPHABLEND_ON + #define MTOON_CLIP_IF_OUTLINE_IS_NONE + #include "./MToonSM3.cginc" + #pragma vertex vert_forward_base_outline + #pragma fragment frag_forward + #pragma multi_compile_fwdbase + #pragma multi_compile_fog +// #pragma multi_compile_instancing + ENDCG + } + + + // Forward Add + Pass + { + Name "FORWARD_ADD" + Tags { "LightMode" = "ForwardAdd" } + + Cull [_CullMode] + Blend [_SrcBlend] One + ZWrite Off + ZTest LEqual + BlendOp Add, Max + + CGPROGRAM + #pragma target 3.0 + #pragma shader_feature _ MTOON_DEBUG_NORMAL MTOON_DEBUG_LITSHADERATE + #pragma multi_compile _ _NORMALMAP + #pragma multi_compile _ _ALPHATEST_ON _ALPHABLEND_ON + #define MTOON_FORWARD_ADD + #include "./MToonSM3.cginc" + #pragma vertex vert_forward_add + #pragma fragment frag_forward + #pragma multi_compile_fwdadd_fullshadows + #pragma multi_compile_fog + ENDCG + } + + // Shadow rendering pass + Pass + { + Name "ShadowCaster" + Tags { "LightMode" = "ShadowCaster" } + + Cull [_CullMode] + ZWrite On + ZTest LEqual + + CGPROGRAM + #pragma target 3.0 + #pragma multi_compile _ _ALPHATEST_ON _ALPHABLEND_ON + #pragma multi_compile_shadowcaster + #pragma vertex vertShadowCaster + #pragma fragment fragShadowCaster + #include "UnityStandardShadow.cginc" + ENDCG + } + } + + Fallback "Unlit/Texture" + CustomEditor "MToon.MToonInspector" +} diff --git a/MToon/Runtime/Resources/Shaders/MToon.shader.meta b/MToon/Runtime/Resources/Shaders/MToon.shader.meta new file mode 100644 index 0000000..dfa8450 --- /dev/null +++ b/MToon/Runtime/Resources/Shaders/MToon.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 1a97144e4ad27a04aafd70f7b915cedb +timeCreated: 1514111466 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/MToon/Runtime/Resources/Shaders/MToonCore.cginc b/MToon/Runtime/Resources/Shaders/MToonCore.cginc new file mode 100644 index 0000000..136d9f8 --- /dev/null +++ b/MToon/Runtime/Resources/Shaders/MToonCore.cginc @@ -0,0 +1,275 @@ +#ifndef MTOON_CORE_INCLUDED +#define MTOON_CORE_INCLUDED + +#include "Lighting.cginc" +#include "AutoLight.cginc" + +half _Cutoff; +fixed4 _Color; +fixed4 _ShadeColor; +sampler2D _MainTex; float4 _MainTex_ST; +sampler2D _ShadeTexture; +half _BumpScale; +sampler2D _BumpMap; +sampler2D _ReceiveShadowTexture; +half _ReceiveShadowRate; +sampler2D _ShadingGradeTexture; +half _ShadingGradeRate; +half _ShadeShift; +half _ShadeToony; +half _LightColorAttenuation; +half _IndirectLightIntensity; +sampler2D _RimTexture; +half4 _RimColor; +half _RimLightingMix; +half _RimFresnelPower; +half _RimLift; +sampler2D _SphereAdd; +half4 _EmissionColor; +sampler2D _EmissionMap; +sampler2D _OutlineWidthTexture; +half _OutlineWidth; +half _OutlineScaledMaxDistance; +fixed4 _OutlineColor; +half _OutlineLightingMix; +sampler2D _UvAnimMaskTexture; +float _UvAnimScrollX; +float _UvAnimScrollY; +float _UvAnimRotation; + +//UNITY_INSTANCING_BUFFER_START(Props) +//UNITY_INSTANCING_BUFFER_END(Props) + +struct v2f +{ + float4 pos : SV_POSITION; + float4 posWorld : TEXCOORD0; + half3 tspace0 : TEXCOORD1; + half3 tspace1 : TEXCOORD2; + half3 tspace2 : TEXCOORD3; + float2 uv0 : TEXCOORD4; + float isOutline : TEXCOORD5; + fixed4 color : TEXCOORD6; + UNITY_FOG_COORDS(7) + SHADOW_COORDS(8) + //UNITY_VERTEX_INPUT_INSTANCE_ID // necessary only if any instanced properties are going to be accessed in the fragment Shader. +}; + +inline v2f InitializeV2F(appdata_full v, float4 projectedVertex, float isOutline) +{ + v2f o; + UNITY_INITIALIZE_OUTPUT(v2f, o); + UNITY_SETUP_INSTANCE_ID(v); + //UNITY_TRANSFER_INSTANCE_ID(v, o); + + o.pos = projectedVertex; + o.posWorld = mul(unity_ObjectToWorld, v.vertex); + o.uv0 = v.texcoord; + half3 worldNormal = UnityObjectToWorldNormal(v.normal); + half3 worldTangent = UnityObjectToWorldDir(v.tangent); + half tangentSign = v.tangent.w * unity_WorldTransformParams.w; + half3 worldBitangent = cross(worldNormal, worldTangent) * tangentSign; + o.tspace0 = half3(worldTangent.x, worldBitangent.x, worldNormal.x); + o.tspace1 = half3(worldTangent.y, worldBitangent.y, worldNormal.y); + o.tspace2 = half3(worldTangent.z, worldBitangent.z, worldNormal.z); + o.isOutline = isOutline; + o.color = v.color; + TRANSFER_SHADOW(o); + UNITY_TRANSFER_FOG(o, o.pos); + return o; +} + +inline float4 CalculateOutlineVertexClipPosition(appdata_full v) +{ + float outlineTex = tex2Dlod(_OutlineWidthTexture, float4(TRANSFORM_TEX(v.texcoord, _MainTex), 0, 0)).r; + + #if defined(MTOON_OUTLINE_WIDTH_WORLD) + float3 worldNormalLength = length(mul((float3x3)transpose(unity_WorldToObject), v.normal)); + float3 outlineOffset = 0.01 * _OutlineWidth * outlineTex * worldNormalLength * v.normal; + float4 vertex = UnityObjectToClipPos(v.vertex + outlineOffset); + #elif defined(MTOON_OUTLINE_WIDTH_SCREEN) + float4 nearUpperRight = mul(unity_CameraInvProjection, float4(1, 1, UNITY_NEAR_CLIP_VALUE, _ProjectionParams.y)); + float aspect = abs(nearUpperRight.y / nearUpperRight.x); + float4 vertex = UnityObjectToClipPos(v.vertex); + float3 viewNormal = mul((float3x3)UNITY_MATRIX_IT_MV, v.normal.xyz); + float3 clipNormal = TransformViewToProjection(viewNormal.xyz); + float2 projectedNormal = normalize(clipNormal.xy); + projectedNormal *= min(vertex.w, _OutlineScaledMaxDistance); + projectedNormal.x *= aspect; + vertex.xy += 0.01 * _OutlineWidth * outlineTex * projectedNormal.xy * saturate(1 - abs(normalize(viewNormal).z)); // ignore offset when normal toward camera + #else + float4 vertex = UnityObjectToClipPos(v.vertex); + #endif + return vertex; +} + +float4 frag_forward(v2f i) : SV_TARGET +{ +#ifdef MTOON_CLIP_IF_OUTLINE_IS_NONE + #ifdef MTOON_OUTLINE_WIDTH_WORLD + #elif MTOON_OUTLINE_WIDTH_SCREEN + #else + clip(-1); + #endif +#endif + + //UNITY_TRANSFER_INSTANCE_ID(v, o); + + // const + const float PI_2 = 6.28318530718; + const float EPS_COL = 0.00001; + + // uv + float2 mainUv = TRANSFORM_TEX(i.uv0, _MainTex); + + // uv anim + half uvAnim = tex2D(_UvAnimMaskTexture, mainUv).r * _Time.y; + // translate uv in bottom-left origin coordinates. + mainUv += float2(_UvAnimScrollX, _UvAnimScrollY) * uvAnim; + // rotate uv counter-clockwise around (0.5, 0.5) in bottom-left origin coordinates. + float rotateRad = _UvAnimRotation * PI_2 * uvAnim; + const float2 rotatePivot = float2(0.5, 0.5); + mainUv = mul(float2x2(cos(rotateRad), -sin(rotateRad), sin(rotateRad), cos(rotateRad)), mainUv - rotatePivot) + rotatePivot; + + // main tex + half4 mainTex = tex2D(_MainTex, mainUv); + + // alpha + half alpha = 1; +#ifdef _ALPHATEST_ON + alpha = _Color.a * mainTex.a; + clip(alpha - _Cutoff); +#endif +#ifdef _ALPHABLEND_ON + alpha = _Color.a * mainTex.a; +#endif + + // normal +#ifdef _NORMALMAP + half3 tangentNormal = UnpackScaleNormal(tex2D(_BumpMap, mainUv), _BumpScale); + half3 worldNormal; + worldNormal.x = dot(i.tspace0, tangentNormal); + worldNormal.y = dot(i.tspace1, tangentNormal); + worldNormal.z = dot(i.tspace2, tangentNormal); +#else + half3 worldNormal = half3(i.tspace0.z, i.tspace1.z, i.tspace2.z); +#endif + float3 worldView = normalize(lerp(_WorldSpaceCameraPos.xyz - i.posWorld.xyz, UNITY_MATRIX_V[2].xyz, unity_OrthoParams.w)); + worldNormal *= step(0, dot(worldView, worldNormal)) * 2 - 1; // flip if projection matrix is flipped + worldNormal *= lerp(+1.0, -1.0, i.isOutline); + worldNormal = normalize(worldNormal); + + // Unity lighting + UNITY_LIGHT_ATTENUATION(shadowAttenuation, i, i.posWorld.xyz); + half3 lightDir = lerp(_WorldSpaceLightPos0.xyz, normalize(_WorldSpaceLightPos0.xyz - i.posWorld.xyz), _WorldSpaceLightPos0.w); + half3 lightColor = _LightColor0.rgb * step(0.5, length(lightDir)); // length(lightDir) is zero if directional light is disabled. + half dotNL = dot(lightDir, worldNormal); +#ifdef MTOON_FORWARD_ADD + half lightAttenuation = 1; +#else + half lightAttenuation = shadowAttenuation * lerp(1, shadowAttenuation, _ReceiveShadowRate * tex2D(_ReceiveShadowTexture, mainUv).r); +#endif + + // Decide albedo color rate from Direct Light + half shadingGrade = 1.0 - _ShadingGradeRate * (1.0 - tex2D(_ShadingGradeTexture, mainUv).r); + half lightIntensity = dotNL; // [-1, +1] + lightIntensity = lightIntensity * 0.5 + 0.5; // from [-1, +1] to [0, 1] + lightIntensity = lightIntensity * lightAttenuation; // receive shadow + lightIntensity = lightIntensity * shadingGrade; // darker + lightIntensity = lightIntensity * 2.0 - 1.0; // from [0, 1] to [-1, +1] + // tooned. mapping from [minIntensityThreshold, maxIntensityThreshold] to [0, 1] + half maxIntensityThreshold = lerp(1, _ShadeShift, _ShadeToony); + half minIntensityThreshold = _ShadeShift; + lightIntensity = saturate((lightIntensity - minIntensityThreshold) / max(EPS_COL, (maxIntensityThreshold - minIntensityThreshold))); + + // Albedo color + half4 shade = _ShadeColor * tex2D(_ShadeTexture, mainUv); + half4 lit = _Color * mainTex; + half3 col = lerp(shade.rgb, lit.rgb, lightIntensity); + + // Direct Light + half3 lighting = lightColor; + lighting = lerp(lighting, max(EPS_COL, max(lighting.x, max(lighting.y, lighting.z))), _LightColorAttenuation); // color atten +#ifdef MTOON_FORWARD_ADD +#ifdef _ALPHABLEND_ON + lighting *= step(0, dotNL); // darken if transparent. Because Unity's transparent material can't receive shadowAttenuation. +#endif + lighting *= 0.5; // darken if additional light. + lighting *= min(0, dotNL) + 1; // darken dotNL < 0 area by using half lambert + lighting *= shadowAttenuation; // darken if receiving shadow +#else + // base light does not darken. +#endif + col *= lighting; + + // Indirect Light +#ifdef MTOON_FORWARD_ADD +#else + half3 toonedGI = 0.5 * (ShadeSH9(half4(0, 1, 0, 1)) + ShadeSH9(half4(0, -1, 0, 1))); + half3 indirectLighting = lerp(toonedGI, ShadeSH9(half4(worldNormal, 1)), _IndirectLightIntensity); + indirectLighting = lerp(indirectLighting, max(EPS_COL, max(indirectLighting.x, max(indirectLighting.y, indirectLighting.z))), _LightColorAttenuation); // color atten + col += indirectLighting * lit; + + col = min(col, lit); // comment out if you want to PBR absolutely. +#endif + + // parametric rim lighting +#ifdef MTOON_FORWARD_ADD + half3 staticRimLighting = 0; + half3 mixedRimLighting = lighting; +#else + half3 staticRimLighting = 1; + half3 mixedRimLighting = lighting + indirectLighting; +#endif + half3 rimLighting = lerp(staticRimLighting, mixedRimLighting, _RimLightingMix); + half3 rim = pow(saturate(1.0 - dot(worldNormal, worldView) + _RimLift), _RimFresnelPower) * _RimColor.rgb * tex2D(_RimTexture, mainUv).rgb; + col += lerp(rim * rimLighting, half3(0, 0, 0), i.isOutline); + + // additive matcap +#ifdef MTOON_FORWARD_ADD +#else + half3 worldCameraUp = normalize(UNITY_MATRIX_V[1].xyz); + half3 worldViewUp = normalize(worldCameraUp - worldView * dot(worldView, worldCameraUp)); + half3 worldViewRight = normalize(cross(worldView, worldViewUp)); + half2 matcapUv = half2(dot(worldViewRight, worldNormal), dot(worldViewUp, worldNormal)) * 0.5 + 0.5; + half3 matcapLighting = tex2D(_SphereAdd, matcapUv); + col += lerp(matcapLighting, half3(0, 0, 0), i.isOutline); +#endif + + // Emission +#ifdef MTOON_FORWARD_ADD +#else + half3 emission = tex2D(_EmissionMap, mainUv).rgb * _EmissionColor.rgb; + col += lerp(emission, half3(0, 0, 0), i.isOutline); +#endif + + // outline +#ifdef MTOON_OUTLINE_COLOR_FIXED + col = lerp(col, _OutlineColor, i.isOutline); +#elif MTOON_OUTLINE_COLOR_MIXED + col = lerp(col, _OutlineColor * lerp(half3(1, 1, 1), col, _OutlineLightingMix), i.isOutline); +#else +#endif + + // debug +#ifdef MTOON_DEBUG_NORMAL + #ifdef MTOON_FORWARD_ADD + return float4(0, 0, 0, 0); + #else + return float4(worldNormal * 0.5 + 0.5, alpha); + #endif +#elif MTOON_DEBUG_LITSHADERATE + #ifdef MTOON_FORWARD_ADD + return float4(0, 0, 0, 0); + #else + return float4(lightIntensity * lighting, alpha); + #endif +#endif + + + half4 result = half4(col, alpha); + UNITY_APPLY_FOG(i.fogCoord, result); + return result; +} + +#endif // MTOON_CORE_INCLUDED diff --git a/MToon/Runtime/Resources/Shaders/MToonCore.cginc.meta b/MToon/Runtime/Resources/Shaders/MToonCore.cginc.meta new file mode 100644 index 0000000..6b68091 --- /dev/null +++ b/MToon/Runtime/Resources/Shaders/MToonCore.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: ef6682d138947ed4fbc8fbecfe75cd28 +timeCreated: 1514120022 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/MToon/Runtime/Resources/Shaders/MToonSM3.cginc b/MToon/Runtime/Resources/Shaders/MToonSM3.cginc new file mode 100644 index 0000000..cf3a093 --- /dev/null +++ b/MToon/Runtime/Resources/Shaders/MToonSM3.cginc @@ -0,0 +1,19 @@ +#include "./MToonCore.cginc" + +v2f vert_forward_base(appdata_full v) +{ + v.normal = normalize(v.normal); + return InitializeV2F(v, UnityObjectToClipPos(v.vertex), 0); +} + +v2f vert_forward_base_outline(appdata_full v) +{ + v.normal = normalize(v.normal); + return InitializeV2F(v, CalculateOutlineVertexClipPosition(v), 1); +} + +v2f vert_forward_add(appdata_full v) +{ + v.normal = normalize(v.normal); + return InitializeV2F(v, UnityObjectToClipPos(v.vertex), 0); +} diff --git a/MToon/Runtime/Resources/Shaders/MToonSM3.cginc.meta b/MToon/Runtime/Resources/Shaders/MToonSM3.cginc.meta new file mode 100644 index 0000000..843b34e --- /dev/null +++ b/MToon/Runtime/Resources/Shaders/MToonSM3.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 084281ffd8b1b8e4a8605725d3b0760b +timeCreated: 1514120022 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/MToon/Runtime/Resources/Shaders/MToonSM4.cginc b/MToon/Runtime/Resources/Shaders/MToonSM4.cginc new file mode 100644 index 0000000..538864b --- /dev/null +++ b/MToon/Runtime/Resources/Shaders/MToonSM4.cginc @@ -0,0 +1,37 @@ +#include "./MToonCore.cginc" + +appdata_full vert_forward_base_with_outline(appdata_full v) +{ + v.normal = normalize(v.normal); + return v; +} + +v2f vert_forward_add(appdata_full v) +{ + v.normal = normalize(v.normal); + return InitializeV2F(v, UnityObjectToClipPos(v.vertex), 0); +} + +[maxvertexcount(6)] +void geom_forward_base(triangle appdata_full IN[3], inout TriangleStream stream) +{ + v2f o; + +#if defined(MTOON_OUTLINE_WIDTH_WORLD) || defined(MTOON_OUTLINE_WIDTH_SCREEN) + for (int i = 2; i >= 0; --i) + { + appdata_full v = IN[i]; + v2f o = InitializeV2F(v, CalculateOutlineVertexClipPosition(v), 1); + stream.Append(o); + } + stream.RestartStrip(); +#endif + + for (int j = 0; j < 3; ++j) + { + appdata_full v = IN[j]; + v2f o = InitializeV2F(v, UnityObjectToClipPos(v.vertex), 0); + stream.Append(o); + } + stream.RestartStrip(); +} diff --git a/MToon/Runtime/Resources/Shaders/MToonSM4.cginc.meta b/MToon/Runtime/Resources/Shaders/MToonSM4.cginc.meta new file mode 100644 index 0000000..f6bdf05 --- /dev/null +++ b/MToon/Runtime/Resources/Shaders/MToonSM4.cginc.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 17d4e0f990fbc794ab41e4fcc196d559 +timeCreated: 1514120022 +licenseType: Free +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/MToon/Runtime/Scripts.meta b/MToon/Runtime/Scripts.meta new file mode 100644 index 0000000..cd2bf72 --- /dev/null +++ b/MToon/Runtime/Scripts.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0ab5610941331be4aa783815ce9ac0c5 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/MToon/Runtime/Scripts/Enums.cs b/MToon/Runtime/Scripts/Enums.cs new file mode 100644 index 0000000..fde05ed --- /dev/null +++ b/MToon/Runtime/Scripts/Enums.cs @@ -0,0 +1,44 @@ +namespace MToon +{ + public enum DebugMode + { + None = 0, + Normal = 1, + LitShadeRate = 2, + } + + public enum OutlineColorMode + { + FixedColor = 0, + MixedLighting = 1, + } + + public enum OutlineWidthMode + { + None = 0, + WorldCoordinates = 1, + ScreenCoordinates = 2, + } + + public enum RenderMode + { + Opaque = 0, + Cutout = 1, + Transparent = 2, + TransparentWithZWrite = 3, + } + + public enum CullMode + { + Off = 0, + Front = 1, + Back = 2, + } + + public struct RenderQueueRequirement + { + public int DefaultValue; + public int MinValue; + public int MaxValue; + } +} \ No newline at end of file diff --git a/MToon/Runtime/Scripts/Enums.cs.meta b/MToon/Runtime/Scripts/Enums.cs.meta new file mode 100644 index 0000000..5149027 --- /dev/null +++ b/MToon/Runtime/Scripts/Enums.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 9a3fb070d7eb4114b5cf387e2cd60391 +timeCreated: 1548858571 \ No newline at end of file diff --git a/MToon/Runtime/Scripts/MToon.asmdef b/MToon/Runtime/Scripts/MToon.asmdef new file mode 100644 index 0000000..e5f1f92 --- /dev/null +++ b/MToon/Runtime/Scripts/MToon.asmdef @@ -0,0 +1,3 @@ +{ + "name": "MToon" +} diff --git a/MToon/Runtime/Scripts/MToon.asmdef.meta b/MToon/Runtime/Scripts/MToon.asmdef.meta new file mode 100644 index 0000000..4daa4ce --- /dev/null +++ b/MToon/Runtime/Scripts/MToon.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: a9bc101fb0471f94a8f99fd242fdd934 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/MToon/Runtime/Scripts/MToonDefinition.cs b/MToon/Runtime/Scripts/MToonDefinition.cs new file mode 100644 index 0000000..7d208c0 --- /dev/null +++ b/MToon/Runtime/Scripts/MToonDefinition.cs @@ -0,0 +1,109 @@ +using UnityEngine; + +namespace MToon +{ + public class MToonDefinition + { + public MetaDefinition Meta; + public RenderingDefinition Rendering; + public ColorDefinition Color; + public LightingDefinition Lighting; + public EmissionDefinition Emission; + public MatCapDefinition MatCap; + public RimDefinition Rim; + public OutlineDefinition Outline; + public TextureUvCoordsDefinition TextureOption; + } + + public class MetaDefinition + { + public string Implementation; + public int VersionNumber; + } + + public class RenderingDefinition + { + public RenderMode RenderMode; + public CullMode CullMode; + public int RenderQueueOffsetNumber; + } + + public class ColorDefinition + { + public Color LitColor; + public Texture2D LitMultiplyTexture; + public Color ShadeColor; + public Texture2D ShadeMultiplyTexture; + public float CutoutThresholdValue; + } + + public class LightingDefinition + { + public LitAndShadeMixingDefinition LitAndShadeMixing; + public LightingInfluenceDefinition LightingInfluence; + public NormalDefinition Normal; + } + + public class LitAndShadeMixingDefinition + { + public float ShadingShiftValue; + public float ShadingToonyValue; + public float ShadowReceiveMultiplierValue; + public Texture2D ShadowReceiveMultiplierMultiplyTexture; + public float LitAndShadeMixingMultiplierValue; + public Texture2D LitAndShadeMixingMultiplierMultiplyTexture; + } + + public class LightingInfluenceDefinition + { + public float LightColorAttenuationValue; + public float GiIntensityValue; + } + + public class EmissionDefinition + { + public Color EmissionColor; + public Texture2D EmissionMultiplyTexture; + } + + public class MatCapDefinition + { + public Texture2D AdditiveTexture; + } + + public class RimDefinition + { + public Color RimColor; + public Texture2D RimMultiplyTexture; + public float RimLightingMixValue; + public float RimFresnelPowerValue; + public float RimLiftValue; + } + + public class NormalDefinition + { + public Texture2D NormalTexture; + public float NormalScaleValue; + } + + public class OutlineDefinition + { + public OutlineWidthMode OutlineWidthMode; + public float OutlineWidthValue; + public Texture2D OutlineWidthMultiplyTexture; + public float OutlineScaledMaxDistanceValue; + public OutlineColorMode OutlineColorMode; + public Color OutlineColor; + public float OutlineLightingMixValue; + } + + public class TextureUvCoordsDefinition + { + public Vector2 MainTextureLeftBottomOriginScale; + public Vector2 MainTextureLeftBottomOriginOffset; + public Texture2D UvAnimationMaskTexture; + public float UvAnimationScrollXSpeedValue; + public float UvAnimationScrollYSpeedValue; + public float UvAnimationRotationSpeedValue; + } +} \ No newline at end of file diff --git a/MToon/Runtime/Scripts/MToonDefinition.cs.meta b/MToon/Runtime/Scripts/MToonDefinition.cs.meta new file mode 100644 index 0000000..47c4a33 --- /dev/null +++ b/MToon/Runtime/Scripts/MToonDefinition.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 2849b99d94074fcf9e10c5ca3eab15a8 +timeCreated: 1548857282 \ No newline at end of file diff --git a/MToon/Runtime/Scripts/Utils.cs b/MToon/Runtime/Scripts/Utils.cs new file mode 100644 index 0000000..c4c29e0 --- /dev/null +++ b/MToon/Runtime/Scripts/Utils.cs @@ -0,0 +1,115 @@ +using System; +using UnityEngine; +using UnityEngine.Rendering; + +namespace MToon +{ + public static partial class Utils + { + public const string ShaderName = "VRM/MToon"; + + public const string PropVersion = "_MToonVersion"; + public const string PropDebugMode = "_DebugMode"; + public const string PropOutlineWidthMode = "_OutlineWidthMode"; + public const string PropOutlineColorMode = "_OutlineColorMode"; + public const string PropBlendMode = "_BlendMode"; + public const string PropCullMode = "_CullMode"; + public const string PropOutlineCullMode = "_OutlineCullMode"; + public const string PropCutoff = "_Cutoff"; + public const string PropColor = "_Color"; + public const string PropShadeColor = "_ShadeColor"; + public const string PropMainTex = "_MainTex"; + public const string PropShadeTexture = "_ShadeTexture"; + public const string PropBumpScale = "_BumpScale"; + public const string PropBumpMap = "_BumpMap"; + public const string PropReceiveShadowRate = "_ReceiveShadowRate"; + public const string PropReceiveShadowTexture = "_ReceiveShadowTexture"; + public const string PropShadingGradeRate = "_ShadingGradeRate"; + public const string PropShadingGradeTexture = "_ShadingGradeTexture"; + public const string PropShadeShift = "_ShadeShift"; + public const string PropShadeToony = "_ShadeToony"; + public const string PropLightColorAttenuation = "_LightColorAttenuation"; + public const string PropIndirectLightIntensity = "_IndirectLightIntensity"; + public const string PropRimColor = "_RimColor"; + public const string PropRimTexture = "_RimTexture"; + public const string PropRimLightingMix = "_RimLightingMix"; + public const string PropRimFresnelPower = "_RimFresnelPower"; + public const string PropRimLift = "_RimLift"; + public const string PropSphereAdd = "_SphereAdd"; + public const string PropEmissionColor = "_EmissionColor"; + public const string PropEmissionMap = "_EmissionMap"; + public const string PropOutlineWidthTexture = "_OutlineWidthTexture"; + public const string PropOutlineWidth = "_OutlineWidth"; + public const string PropOutlineScaledMaxDistance = "_OutlineScaledMaxDistance"; + public const string PropOutlineColor = "_OutlineColor"; + public const string PropOutlineLightingMix = "_OutlineLightingMix"; + public const string PropUvAnimMaskTexture = "_UvAnimMaskTexture"; + public const string PropUvAnimScrollX = "_UvAnimScrollX"; + public const string PropUvAnimScrollY = "_UvAnimScrollY"; + public const string PropUvAnimRotation = "_UvAnimRotation"; + public const string PropSrcBlend = "_SrcBlend"; + public const string PropDstBlend = "_DstBlend"; + public const string PropZWrite = "_ZWrite"; + + public const string KeyNormalMap = "_NORMALMAP"; + public const string KeyAlphaTestOn = "_ALPHATEST_ON"; + public const string KeyAlphaBlendOn = "_ALPHABLEND_ON"; + public const string KeyAlphaPremultiplyOn = "_ALPHAPREMULTIPLY_ON"; + public const string KeyOutlineWidthWorld = "MTOON_OUTLINE_WIDTH_WORLD"; + public const string KeyOutlineWidthScreen = "MTOON_OUTLINE_WIDTH_SCREEN"; + public const string KeyOutlineColorFixed = "MTOON_OUTLINE_COLOR_FIXED"; + public const string KeyOutlineColorMixed = "MTOON_OUTLINE_COLOR_MIXED"; + public const string KeyDebugNormal = "MTOON_DEBUG_NORMAL"; + public const string KeyDebugLitShadeRate = "MTOON_DEBUG_LITSHADERATE"; + + public const string TagRenderTypeKey = "RenderType"; + public const string TagRenderTypeValueOpaque = "Opaque"; + public const string TagRenderTypeValueTransparentCutout = "TransparentCutout"; + public const string TagRenderTypeValueTransparent = "Transparent"; + + public const int DisabledIntValue = 0; + public const int EnabledIntValue = 1; + + public static RenderQueueRequirement GetRenderQueueRequirement(RenderMode renderMode) + { + const int shaderDefaultQueue = -1; + const int firstTransparentQueue = 2501; + const int spanOfQueue = 50; + + switch (renderMode) + { + case RenderMode.Opaque: + return new RenderQueueRequirement() + { + DefaultValue = shaderDefaultQueue, + MinValue = shaderDefaultQueue, + MaxValue = shaderDefaultQueue, + }; + case RenderMode.Cutout: + return new RenderQueueRequirement() + { + DefaultValue = (int) RenderQueue.AlphaTest, + MinValue = (int) RenderQueue.AlphaTest, + MaxValue = (int) RenderQueue.AlphaTest, + }; + case RenderMode.Transparent: + return new RenderQueueRequirement() + { + DefaultValue = (int) RenderQueue.Transparent, + MinValue = (int) RenderQueue.Transparent - spanOfQueue + 1, + MaxValue = (int) RenderQueue.Transparent, + }; + case RenderMode.TransparentWithZWrite: + return new RenderQueueRequirement() + { + DefaultValue = firstTransparentQueue, + MinValue = firstTransparentQueue, + MaxValue = firstTransparentQueue + spanOfQueue - 1, + }; + default: + throw new ArgumentOutOfRangeException("renderMode", renderMode, null); + } + } + + } +} \ No newline at end of file diff --git a/MToon/Runtime/Scripts/Utils.cs.meta b/MToon/Runtime/Scripts/Utils.cs.meta new file mode 100644 index 0000000..bd4175c --- /dev/null +++ b/MToon/Runtime/Scripts/Utils.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 9d2012c170a74b3db0002f7ecda53622 +timeCreated: 1537557325 \ No newline at end of file diff --git a/MToon/Runtime/Scripts/UtilsGetter.cs b/MToon/Runtime/Scripts/UtilsGetter.cs new file mode 100644 index 0000000..a917955 --- /dev/null +++ b/MToon/Runtime/Scripts/UtilsGetter.cs @@ -0,0 +1,180 @@ +using System; +using UnityEngine; + +namespace MToon +{ + public static partial class Utils + { + public static MToonDefinition GetMToonParametersFromMaterial(Material material) + { + return new MToonDefinition + { + Meta = new MetaDefinition + { + Implementation = Implementation, + VersionNumber = material.GetInt(PropVersion), + }, + Rendering = new RenderingDefinition + { + RenderMode = GetBlendMode(material), + CullMode = GetCullMode(material), + RenderQueueOffsetNumber = GetRenderQueueOffset(material, GetRenderQueueOriginMode(material)), + }, + Color = new ColorDefinition + { + LitColor = GetColor(material, PropColor), + LitMultiplyTexture = GetTexture(material, PropMainTex), + ShadeColor = GetColor(material, PropShadeColor), + ShadeMultiplyTexture = GetTexture(material, PropShadeTexture), + CutoutThresholdValue = GetValue(material, PropCutoff), + }, + Lighting = new LightingDefinition + { + LitAndShadeMixing = new LitAndShadeMixingDefinition + { + ShadingShiftValue = GetValue(material, PropShadeShift), + ShadingToonyValue = GetValue(material, PropShadeToony), + ShadowReceiveMultiplierValue = GetValue(material, PropReceiveShadowRate), + ShadowReceiveMultiplierMultiplyTexture = GetTexture(material, PropReceiveShadowTexture), + LitAndShadeMixingMultiplierValue = GetValue(material, PropShadingGradeRate), + LitAndShadeMixingMultiplierMultiplyTexture = GetTexture(material, PropShadingGradeTexture), + }, + LightingInfluence = new LightingInfluenceDefinition + { + LightColorAttenuationValue = GetValue(material, PropLightColorAttenuation), + GiIntensityValue = GetValue(material, PropIndirectLightIntensity), + }, + Normal = new NormalDefinition + { + NormalTexture = GetTexture(material, PropBumpMap), + NormalScaleValue = GetValue(material, PropBumpScale), + }, + }, + Emission = new EmissionDefinition + { + EmissionColor = GetColor(material, PropEmissionColor), + EmissionMultiplyTexture = GetTexture(material, PropEmissionMap), + }, + MatCap = new MatCapDefinition + { + AdditiveTexture = GetTexture(material, PropSphereAdd), + }, + Rim = new RimDefinition + { + RimColor = GetColor(material, PropRimColor), + RimMultiplyTexture = GetTexture(material, PropRimTexture), + RimLightingMixValue = GetValue(material, PropRimLightingMix), + RimFresnelPowerValue = GetValue(material, PropRimFresnelPower), + RimLiftValue = GetValue(material, PropRimLift), + }, + Outline = new OutlineDefinition + { + OutlineWidthMode = GetOutlineWidthMode(material), + OutlineWidthValue = GetValue(material, PropOutlineWidth), + OutlineWidthMultiplyTexture = GetTexture(material, PropOutlineWidthTexture), + OutlineScaledMaxDistanceValue = GetValue(material, PropOutlineScaledMaxDistance), + OutlineColorMode = GetOutlineColorMode(material), + OutlineColor = GetColor(material, PropOutlineColor), + OutlineLightingMixValue = GetValue(material, PropOutlineLightingMix), + }, + TextureOption = new TextureUvCoordsDefinition + { + MainTextureLeftBottomOriginScale = material.GetTextureScale(PropMainTex), + MainTextureLeftBottomOriginOffset = material.GetTextureOffset(PropMainTex), + UvAnimationMaskTexture = GetTexture(material, PropUvAnimMaskTexture), + UvAnimationScrollXSpeedValue = GetValue(material, PropUvAnimScrollX), + UvAnimationScrollYSpeedValue = GetValue(material, PropUvAnimScrollY), + UvAnimationRotationSpeedValue = GetValue(material, PropUvAnimRotation), + }, + }; + } + + private static float GetValue(Material material, string propertyName) + { + return material.GetFloat(propertyName); + } + + private static Color GetColor(Material material, string propertyName) + { + return material.GetColor(propertyName); + } + + private static Texture2D GetTexture(Material material, string propertyName) + { + return (Texture2D) material.GetTexture(propertyName); + } + + private static RenderMode GetBlendMode(Material material) + { + if (material.IsKeywordEnabled(KeyAlphaTestOn)) + { + return RenderMode.Cutout; + } + else if (material.IsKeywordEnabled(KeyAlphaBlendOn)) + { + switch (material.GetInt(PropZWrite)) + { + case EnabledIntValue: + return RenderMode.TransparentWithZWrite; + case DisabledIntValue: + return RenderMode.Transparent; + default: + Debug.LogWarning("Invalid ZWrite Int Value."); + return RenderMode.Transparent; + } + } + else + { + return RenderMode.Opaque; + } + } + + private static CullMode GetCullMode(Material material) + { + switch ((CullMode) material.GetInt(PropCullMode)) + { + case CullMode.Off: + return CullMode.Off; + case CullMode.Front: + return CullMode.Front; + case CullMode.Back: + return CullMode.Back; + default: + Debug.LogWarning("Invalid CullMode."); + return CullMode.Back; + } + } + + private static OutlineWidthMode GetOutlineWidthMode(Material material) + { + if (material.IsKeywordEnabled(KeyOutlineWidthWorld)) return OutlineWidthMode.WorldCoordinates; + if (material.IsKeywordEnabled(KeyOutlineWidthScreen)) return OutlineWidthMode.ScreenCoordinates; + + return OutlineWidthMode.None; + } + + private static OutlineColorMode GetOutlineColorMode(Material material) + { + if (material.IsKeywordEnabled(KeyOutlineColorFixed)) return OutlineColorMode.FixedColor; + if (material.IsKeywordEnabled(KeyOutlineColorMixed)) return OutlineColorMode.MixedLighting; + + return OutlineColorMode.FixedColor; + } + + private static RenderMode GetRenderQueueOriginMode(Material material) + { + return GetBlendMode(material); + } + + private static int GetRenderQueueOffset(Material material, RenderMode originMode) + { + var rawValue = material.renderQueue; + var requirement = GetRenderQueueRequirement(originMode); + if (rawValue < requirement.MinValue || rawValue > requirement.MaxValue) + { + return 0; + } + return rawValue - requirement.DefaultValue; + } + } +} \ No newline at end of file diff --git a/MToon/Runtime/Scripts/UtilsGetter.cs.meta b/MToon/Runtime/Scripts/UtilsGetter.cs.meta new file mode 100644 index 0000000..db1134a --- /dev/null +++ b/MToon/Runtime/Scripts/UtilsGetter.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 6724aa45c8c349fabd5954a531301aa8 +timeCreated: 1557229569 \ No newline at end of file diff --git a/MToon/Runtime/Scripts/UtilsSetter.cs b/MToon/Runtime/Scripts/UtilsSetter.cs new file mode 100644 index 0000000..c9c25bb --- /dev/null +++ b/MToon/Runtime/Scripts/UtilsSetter.cs @@ -0,0 +1,267 @@ +using System; +using UnityEngine; +using UnityEngine.Rendering; + +namespace MToon +{ + public static partial class Utils + { + public static void SetMToonParametersToMaterial(Material material, MToonDefinition parameters) + { + { + var meta = parameters.Meta; + SetValue(material, PropVersion, meta.VersionNumber); + } + { + var rendering = parameters.Rendering; + ValidateBlendMode(material, rendering.RenderMode, isChangedByUser: true); + ValidateCullMode(material, rendering.CullMode); + ValidateRenderQueue(material, offset: rendering.RenderQueueOffsetNumber); + } + { + var color = parameters.Color; + SetColor(material, PropColor, color.LitColor); + SetTexture(material, PropMainTex, color.LitMultiplyTexture); + SetColor(material, PropShadeColor, color.ShadeColor); + SetTexture(material, PropShadeTexture, color.ShadeMultiplyTexture); + SetValue(material, PropCutoff, color.CutoutThresholdValue); + } + { + var lighting = parameters.Lighting; + { + var prop = lighting.LitAndShadeMixing; + SetValue(material, PropShadeShift, prop.ShadingShiftValue); + SetValue(material, PropShadeToony, prop.ShadingToonyValue); + SetValue(material, PropReceiveShadowRate, prop.ShadowReceiveMultiplierValue); + SetTexture(material, PropReceiveShadowTexture, prop.ShadowReceiveMultiplierMultiplyTexture); + SetValue(material, PropShadingGradeRate, prop.LitAndShadeMixingMultiplierValue); + SetTexture(material, PropShadingGradeTexture, prop.LitAndShadeMixingMultiplierMultiplyTexture); + } + { + var prop = lighting.LightingInfluence; + SetValue(material, PropLightColorAttenuation, prop.LightColorAttenuationValue); + SetValue(material, PropIndirectLightIntensity, prop.GiIntensityValue); + } + { + var prop = lighting.Normal; + SetTexture(material, PropBumpMap, prop.NormalTexture); + SetValue(material, PropBumpScale, prop.NormalScaleValue); + } + } + { + var emission = parameters.Emission; + SetColor(material, PropEmissionColor, emission.EmissionColor); + SetTexture(material, PropEmissionMap, emission.EmissionMultiplyTexture); + } + { + var matcap = parameters.MatCap; + SetTexture(material, PropSphereAdd, matcap.AdditiveTexture); + } + { + var rim = parameters.Rim; + SetColor(material, PropRimColor, rim.RimColor); + SetTexture(material, PropRimTexture, rim.RimMultiplyTexture); + SetValue(material, PropRimLightingMix, rim.RimLightingMixValue); + SetValue(material, PropRimFresnelPower, rim.RimFresnelPowerValue); + SetValue(material, PropRimLift, rim.RimLiftValue); + } + { + var outline = parameters.Outline; + SetValue(material, PropOutlineWidth, outline.OutlineWidthValue); + SetTexture(material, PropOutlineWidthTexture, outline.OutlineWidthMultiplyTexture); + SetValue(material, PropOutlineScaledMaxDistance, outline.OutlineScaledMaxDistanceValue); + SetColor(material, PropOutlineColor, outline.OutlineColor); + SetValue(material, PropOutlineLightingMix, outline.OutlineLightingMixValue); + ValidateOutlineMode(material, outline.OutlineWidthMode, outline.OutlineColorMode); + } + { + var textureOptions = parameters.TextureOption; + material.SetTextureScale(PropMainTex, textureOptions.MainTextureLeftBottomOriginScale); + material.SetTextureOffset(PropMainTex, textureOptions.MainTextureLeftBottomOriginOffset); + material.SetTexture(PropUvAnimMaskTexture, textureOptions.UvAnimationMaskTexture); + material.SetFloat(PropUvAnimScrollX, textureOptions.UvAnimationScrollXSpeedValue); + material.SetFloat(PropUvAnimScrollY, textureOptions.UvAnimationScrollYSpeedValue); + material.SetFloat(PropUvAnimRotation, textureOptions.UvAnimationRotationSpeedValue); + } + } + + /// + /// Validate properties and Set hidden properties, keywords. + /// if isBlendModeChangedByUser is true, renderQueue will set specified render mode's default value. + /// + /// + /// + public static void ValidateProperties(Material material, bool isBlendModeChangedByUser = false) + { + ValidateBlendMode(material, (RenderMode) material.GetFloat(PropBlendMode), isBlendModeChangedByUser); + ValidateNormalMode(material, material.GetTexture(PropBumpMap)); + ValidateOutlineMode(material, + (OutlineWidthMode) material.GetFloat(PropOutlineWidthMode), + (OutlineColorMode) material.GetFloat(PropOutlineColorMode)); + ValidateDebugMode(material, (DebugMode) material.GetFloat(PropDebugMode)); + ValidateCullMode(material, (CullMode) material.GetFloat(PropCullMode)); + + var mainTex = material.GetTexture(PropMainTex); + var shadeTex = material.GetTexture(PropShadeTexture); + if (mainTex != null && shadeTex == null) + { + material.SetTexture(PropShadeTexture, mainTex); + } + } + + private static void ValidateDebugMode(Material material, DebugMode debugMode) + { + switch (debugMode) + { + case DebugMode.None: + SetKeyword(material, KeyDebugNormal, false); + SetKeyword(material, KeyDebugLitShadeRate, false); + break; + case DebugMode.Normal: + SetKeyword(material, KeyDebugNormal, true); + SetKeyword(material, KeyDebugLitShadeRate, false); + break; + case DebugMode.LitShadeRate: + SetKeyword(material, KeyDebugNormal, false); + SetKeyword(material, KeyDebugLitShadeRate, true); + break; + } + } + + public static void ValidateBlendMode(Material material, RenderMode renderMode, bool isChangedByUser) + { + switch (renderMode) + { + case RenderMode.Opaque: + material.SetOverrideTag(TagRenderTypeKey, TagRenderTypeValueOpaque); + material.SetInt(PropSrcBlend, (int) BlendMode.One); + material.SetInt(PropDstBlend, (int) BlendMode.Zero); + material.SetInt(PropZWrite, EnabledIntValue); + SetKeyword(material, KeyAlphaTestOn, false); + SetKeyword(material, KeyAlphaBlendOn, false); + SetKeyword(material, KeyAlphaPremultiplyOn, false); + break; + case RenderMode.Cutout: + material.SetOverrideTag(TagRenderTypeKey, TagRenderTypeValueTransparentCutout); + material.SetInt(PropSrcBlend, (int) BlendMode.One); + material.SetInt(PropDstBlend, (int) BlendMode.Zero); + material.SetInt(PropZWrite, EnabledIntValue); + SetKeyword(material, KeyAlphaTestOn, true); + SetKeyword(material, KeyAlphaBlendOn, false); + SetKeyword(material, KeyAlphaPremultiplyOn, false); + break; + case RenderMode.Transparent: + material.SetOverrideTag(TagRenderTypeKey, TagRenderTypeValueTransparent); + material.SetInt(PropSrcBlend, (int) BlendMode.SrcAlpha); + material.SetInt(PropDstBlend, (int) BlendMode.OneMinusSrcAlpha); + material.SetInt(PropZWrite, DisabledIntValue); + SetKeyword(material, KeyAlphaTestOn, false); + SetKeyword(material, KeyAlphaBlendOn, true); + SetKeyword(material, KeyAlphaPremultiplyOn, false); + break; + case RenderMode.TransparentWithZWrite: + material.SetOverrideTag(TagRenderTypeKey, TagRenderTypeValueTransparent); + material.SetInt(PropSrcBlend, (int) BlendMode.SrcAlpha); + material.SetInt(PropDstBlend, (int) BlendMode.OneMinusSrcAlpha); + material.SetInt(PropZWrite, EnabledIntValue); + SetKeyword(material, KeyAlphaTestOn, false); + SetKeyword(material, KeyAlphaBlendOn, true); + SetKeyword(material, KeyAlphaPremultiplyOn, false); + break; + } + + if (isChangedByUser) + { + ValidateRenderQueue(material, offset: 0); + } + else + { + var requirement = GetRenderQueueRequirement(renderMode); + ValidateRenderQueue(material, offset: material.renderQueue - requirement.DefaultValue); + } + } + + private static void ValidateRenderQueue(Material material, int offset) + { + var requirement = GetRenderQueueRequirement(GetBlendMode(material)); + var value = Mathf.Clamp(requirement.DefaultValue + offset, requirement.MinValue, requirement.MaxValue); + material.renderQueue = value; + } + + private static void ValidateOutlineMode(Material material, OutlineWidthMode outlineWidthMode, + OutlineColorMode outlineColorMode) + { + var isFixed = outlineColorMode == OutlineColorMode.FixedColor; + var isMixed = outlineColorMode == OutlineColorMode.MixedLighting; + + switch (outlineWidthMode) + { + case OutlineWidthMode.None: + SetKeyword(material, KeyOutlineWidthWorld, false); + SetKeyword(material, KeyOutlineWidthScreen, false); + SetKeyword(material, KeyOutlineColorFixed, false); + SetKeyword(material, KeyOutlineColorMixed, false); + break; + case OutlineWidthMode.WorldCoordinates: + SetKeyword(material, KeyOutlineWidthWorld, true); + SetKeyword(material, KeyOutlineWidthScreen, false); + SetKeyword(material, KeyOutlineColorFixed, isFixed); + SetKeyword(material, KeyOutlineColorMixed, isMixed); + break; + case OutlineWidthMode.ScreenCoordinates: + SetKeyword(material, KeyOutlineWidthWorld, false); + SetKeyword(material, KeyOutlineWidthScreen, true); + SetKeyword(material, KeyOutlineColorFixed, isFixed); + SetKeyword(material, KeyOutlineColorMixed, isMixed); + break; + } + } + + private static void ValidateNormalMode(Material material, bool requireNormalMapping) + { + SetKeyword(material, KeyNormalMap, requireNormalMapping); + } + + private static void ValidateCullMode(Material material, CullMode cullMode) + { + switch (cullMode) + { + case CullMode.Back: + material.SetInt(PropCullMode, (int) CullMode.Back); + material.SetInt(PropOutlineCullMode, (int) CullMode.Front); + break; + case CullMode.Front: + material.SetInt(PropCullMode, (int) CullMode.Front); + material.SetInt(PropOutlineCullMode, (int) CullMode.Back); + break; + case CullMode.Off: + material.SetInt(PropCullMode, (int) CullMode.Off); + material.SetInt(PropOutlineCullMode, (int) CullMode.Front); + break; + } + } + + private static void SetValue(Material material, string propertyName, float val) + { + material.SetFloat(propertyName, val); + } + + private static void SetColor(Material material, string propertyName, Color color) + { + material.SetColor(propertyName, color); + } + + private static void SetTexture(Material material, string propertyName, Texture2D texture) + { + material.SetTexture(propertyName, texture); + } + + private static void SetKeyword(Material mat, string keyword, bool required) + { + if (required) + mat.EnableKeyword(keyword); + else + mat.DisableKeyword(keyword); + } + } +} \ No newline at end of file diff --git a/MToon/Runtime/Scripts/UtilsSetter.cs.meta b/MToon/Runtime/Scripts/UtilsSetter.cs.meta new file mode 100644 index 0000000..d49b036 --- /dev/null +++ b/MToon/Runtime/Scripts/UtilsSetter.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b24a672e82874c9fbfef9c2b2dfdab42 +timeCreated: 1557304397 \ No newline at end of file diff --git a/MToon/Runtime/Scripts/UtilsVersion.cs b/MToon/Runtime/Scripts/UtilsVersion.cs new file mode 100644 index 0000000..9e4fd5b --- /dev/null +++ b/MToon/Runtime/Scripts/UtilsVersion.cs @@ -0,0 +1,8 @@ +namespace MToon +{ + public static partial class Utils + { + public const string Implementation = "Santarh/MToon"; + public const int VersionNumber = 32; + } +} \ No newline at end of file diff --git a/MToon/Runtime/Scripts/UtilsVersion.cs.meta b/MToon/Runtime/Scripts/UtilsVersion.cs.meta new file mode 100644 index 0000000..b2f3ef4 --- /dev/null +++ b/MToon/Runtime/Scripts/UtilsVersion.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 4702d4b2c1414cc08b4382c3762eebab +timeCreated: 1557306172 \ No newline at end of file diff --git a/ShaderProperty/Runtime/VRM.meta b/ShaderProperty/Runtime/VRM.meta new file mode 100644 index 0000000..ee92a53 --- /dev/null +++ b/ShaderProperty/Runtime/VRM.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 739211b3c46c2264991ea499352ea61e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/ShaderProperty/Runtime/VRM/PreExportShaders_VRM.cs b/ShaderProperty/Runtime/VRM/PreExportShaders_VRM.cs new file mode 100644 index 0000000..f246304 --- /dev/null +++ b/ShaderProperty/Runtime/VRM/PreExportShaders_VRM.cs @@ -0,0 +1,16 @@ +namespace UniGLTF.ShaderPropExporter +{ + public static partial class PreExportShaders + { + const string VRM_TARGET_FOLDER = "VRM"; + [PreExportShaders] + public static SupportedShader[] VRMSupportedShaders = new SupportedShader[] + { + new SupportedShader(VRM_TARGET_FOLDER, "VRM/MToon"), + new SupportedShader(VRM_TARGET_FOLDER, "VRM/UnlitTexture"), + new SupportedShader(VRM_TARGET_FOLDER, "VRM/UnlitCutout"), + new SupportedShader(VRM_TARGET_FOLDER, "VRM/UnlitTransparent"), + new SupportedShader(VRM_TARGET_FOLDER, "VRM/UnlitTransparentZWrite"), + }; + } +} diff --git a/ShaderProperty/Runtime/VRM/PreExportShaders_VRM.cs.meta b/ShaderProperty/Runtime/VRM/PreExportShaders_VRM.cs.meta new file mode 100644 index 0000000..d0fd45c --- /dev/null +++ b/ShaderProperty/Runtime/VRM/PreExportShaders_VRM.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 625b5ee8b5811dc4a915a2fbb2cb319d +timeCreated: 1533035131 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/ShaderProperty/Runtime/VRM/VRM_MToon.cs b/ShaderProperty/Runtime/VRM/VRM_MToon.cs new file mode 100644 index 0000000..f5fc6f1 --- /dev/null +++ b/ShaderProperty/Runtime/VRM/VRM_MToon.cs @@ -0,0 +1,67 @@ +using System.Collections.Generic; + + +namespace UniGLTF.ShaderPropExporter +{ + public static partial class PreShaderPropExporter + { + [PreExportShader] + static KeyValuePair VRM_MToon + { + get + { + return new KeyValuePair( + "VRM/MToon", + new ShaderProps + { + Properties = new ShaderProperty[]{ +new ShaderProperty("_Cutoff", ShaderPropertyType.Range) +,new ShaderProperty("_Color", ShaderPropertyType.Color) +,new ShaderProperty("_ShadeColor", ShaderPropertyType.Color) +,new ShaderProperty("_MainTex", ShaderPropertyType.TexEnv) +,new ShaderProperty("_ShadeTexture", ShaderPropertyType.TexEnv) +,new ShaderProperty("_BumpScale", ShaderPropertyType.Float) +,new ShaderProperty("_BumpMap", ShaderPropertyType.TexEnv) +,new ShaderProperty("_ReceiveShadowRate", ShaderPropertyType.Range) +,new ShaderProperty("_ReceiveShadowTexture", ShaderPropertyType.TexEnv) +,new ShaderProperty("_ShadingGradeRate", ShaderPropertyType.Range) +,new ShaderProperty("_ShadingGradeTexture", ShaderPropertyType.TexEnv) +,new ShaderProperty("_ShadeShift", ShaderPropertyType.Range) +,new ShaderProperty("_ShadeToony", ShaderPropertyType.Range) +,new ShaderProperty("_LightColorAttenuation", ShaderPropertyType.Range) +,new ShaderProperty("_IndirectLightIntensity", ShaderPropertyType.Range) +,new ShaderProperty("_RimColor", ShaderPropertyType.Color) +,new ShaderProperty("_RimTexture", ShaderPropertyType.TexEnv) +,new ShaderProperty("_RimLightingMix", ShaderPropertyType.Range) +,new ShaderProperty("_RimFresnelPower", ShaderPropertyType.Range) +,new ShaderProperty("_RimLift", ShaderPropertyType.Range) +,new ShaderProperty("_SphereAdd", ShaderPropertyType.TexEnv) +,new ShaderProperty("_EmissionColor", ShaderPropertyType.Color) +,new ShaderProperty("_EmissionMap", ShaderPropertyType.TexEnv) +,new ShaderProperty("_OutlineWidthTexture", ShaderPropertyType.TexEnv) +,new ShaderProperty("_OutlineWidth", ShaderPropertyType.Range) +,new ShaderProperty("_OutlineScaledMaxDistance", ShaderPropertyType.Range) +,new ShaderProperty("_OutlineColor", ShaderPropertyType.Color) +,new ShaderProperty("_OutlineLightingMix", ShaderPropertyType.Range) +,new ShaderProperty("_UvAnimMaskTexture", ShaderPropertyType.TexEnv) +,new ShaderProperty("_UvAnimScrollX", ShaderPropertyType.Float) +,new ShaderProperty("_UvAnimScrollY", ShaderPropertyType.Float) +,new ShaderProperty("_UvAnimRotation", ShaderPropertyType.Float) +,new ShaderProperty("_MToonVersion", ShaderPropertyType.Float) +,new ShaderProperty("_DebugMode", ShaderPropertyType.Float) +,new ShaderProperty("_BlendMode", ShaderPropertyType.Float) +,new ShaderProperty("_OutlineWidthMode", ShaderPropertyType.Float) +,new ShaderProperty("_OutlineColorMode", ShaderPropertyType.Float) +,new ShaderProperty("_CullMode", ShaderPropertyType.Float) +,new ShaderProperty("_OutlineCullMode", ShaderPropertyType.Float) +,new ShaderProperty("_SrcBlend", ShaderPropertyType.Float) +,new ShaderProperty("_DstBlend", ShaderPropertyType.Float) +,new ShaderProperty("_ZWrite", ShaderPropertyType.Float) + + } + } + ); + } + } + } +} diff --git a/ShaderProperty/Runtime/VRM/VRM_MToon.cs.meta b/ShaderProperty/Runtime/VRM/VRM_MToon.cs.meta new file mode 100644 index 0000000..26afcbf --- /dev/null +++ b/ShaderProperty/Runtime/VRM/VRM_MToon.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 4629d794c8969c141a4724e182af082e +timeCreated: 1533542890 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/ShaderProperty/Runtime/VRM/VRM_UnlitCutout.cs b/ShaderProperty/Runtime/VRM/VRM_UnlitCutout.cs new file mode 100644 index 0000000..8695f72 --- /dev/null +++ b/ShaderProperty/Runtime/VRM/VRM_UnlitCutout.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; + + +namespace UniGLTF.ShaderPropExporter +{ + public static partial class PreShaderPropExporter + { + [PreExportShader] + static KeyValuePair VRM_UnlitCutout + { + get + { + return new KeyValuePair( + "VRM/UnlitCutout", + new ShaderProps + { + Properties = new ShaderProperty[]{ +new ShaderProperty("_MainTex", ShaderPropertyType.TexEnv) +,new ShaderProperty("_Cutoff", ShaderPropertyType.Range) + + } + } + ); + } + } + } +} diff --git a/ShaderProperty/Runtime/VRM/VRM_UnlitCutout.cs.meta b/ShaderProperty/Runtime/VRM/VRM_UnlitCutout.cs.meta new file mode 100644 index 0000000..3f6607d --- /dev/null +++ b/ShaderProperty/Runtime/VRM/VRM_UnlitCutout.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 611b546ea471ad34cb7d94740c63b558 +timeCreated: 1533542890 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/ShaderProperty/Runtime/VRM/VRM_UnlitTexture.cs b/ShaderProperty/Runtime/VRM/VRM_UnlitTexture.cs new file mode 100644 index 0000000..6a0ab5b --- /dev/null +++ b/ShaderProperty/Runtime/VRM/VRM_UnlitTexture.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; + + +namespace UniGLTF.ShaderPropExporter +{ + public static partial class PreShaderPropExporter + { + [PreExportShader] + static KeyValuePair VRM_UnlitTexture + { + get + { + return new KeyValuePair( + "VRM/UnlitTexture", + new ShaderProps + { + Properties = new ShaderProperty[]{ +new ShaderProperty("_MainTex", ShaderPropertyType.TexEnv) + + } + } + ); + } + } + } +} diff --git a/ShaderProperty/Runtime/VRM/VRM_UnlitTexture.cs.meta b/ShaderProperty/Runtime/VRM/VRM_UnlitTexture.cs.meta new file mode 100644 index 0000000..181adad --- /dev/null +++ b/ShaderProperty/Runtime/VRM/VRM_UnlitTexture.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 22a8083880389b3498f421e6a5c340d5 +timeCreated: 1533542890 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/ShaderProperty/Runtime/VRM/VRM_UnlitTransparent.cs b/ShaderProperty/Runtime/VRM/VRM_UnlitTransparent.cs new file mode 100644 index 0000000..2c75038 --- /dev/null +++ b/ShaderProperty/Runtime/VRM/VRM_UnlitTransparent.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; + + +namespace UniGLTF.ShaderPropExporter +{ + public static partial class PreShaderPropExporter + { + [PreExportShader] + static KeyValuePair VRM_UnlitTransparent + { + get + { + return new KeyValuePair( + "VRM/UnlitTransparent", + new ShaderProps + { + Properties = new ShaderProperty[]{ +new ShaderProperty("_MainTex", ShaderPropertyType.TexEnv) + + } + } + ); + } + } + } +} diff --git a/ShaderProperty/Runtime/VRM/VRM_UnlitTransparent.cs.meta b/ShaderProperty/Runtime/VRM/VRM_UnlitTransparent.cs.meta new file mode 100644 index 0000000..eeaf3b8 --- /dev/null +++ b/ShaderProperty/Runtime/VRM/VRM_UnlitTransparent.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 140d6538826e0eb448929d3e4bb2f1cd +timeCreated: 1533542890 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/ShaderProperty/Runtime/VRM/VRM_UnlitTransparentZWrite.cs b/ShaderProperty/Runtime/VRM/VRM_UnlitTransparentZWrite.cs new file mode 100644 index 0000000..8d03c4e --- /dev/null +++ b/ShaderProperty/Runtime/VRM/VRM_UnlitTransparentZWrite.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; + + +namespace UniGLTF.ShaderPropExporter +{ + public static partial class PreShaderPropExporter + { + [PreExportShader] + static KeyValuePair VRM_UnlitTransparentZWrite + { + get + { + return new KeyValuePair( + "VRM/UnlitTransparentZWrite", + new ShaderProps + { + Properties = new ShaderProperty[]{ +new ShaderProperty("_MainTex", ShaderPropertyType.TexEnv) + + } + } + ); + } + } + } +} diff --git a/ShaderProperty/Runtime/VRM/VRM_UnlitTransparentZWrite.cs.meta b/ShaderProperty/Runtime/VRM/VRM_UnlitTransparentZWrite.cs.meta new file mode 100644 index 0000000..6efeb43 --- /dev/null +++ b/ShaderProperty/Runtime/VRM/VRM_UnlitTransparentZWrite.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 165ec79b7aac1564a850fb3d3d19396e +timeCreated: 1533542890 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: