diff --git a/README.md b/README.md
index 2381f8e..a12e35d 100644
--- a/README.md
+++ b/README.md
@@ -1,15 +1,17 @@
SoftMaskForUGUI
===
-Soft mask for uGUI element in Unity.
+Soft masking for uGUI elements in Unity.
+
+
[](https://github.com/mob-sakai/SoftMaskForUGUI/releases)
[](https://github.com/mob-sakai/SoftMaskForUGUI/releases)
-
+
[](https://github.com/mob-sakai/SoftMaskForUGUI/blob/master/LICENSE.txt)
[](http://makeapullrequest.com)
-<< [Description](#Description) | [WebGL Demo](#demo) | [Download](https://github.com/mob-sakai/SoftMaskForUGUI/releases) | [Usage](#usage) >>
+<< [Description](#Description) | [WebGL Demo](#demo) | [Download](https://github.com/mob-sakai/SoftMaskForUGUI/releases) | [Usage](#usage) | [Development Note](#development-note) >>
### What's new? [See changelog ](https://github.com/mob-sakai/SoftMaskForUGUI/blob/develop/CHANGELOG.md)
### Do you want to receive notifications for new releases? [Watch this repo ](https://github.com/mob-sakai/SoftMaskForUGUI/subscription)
@@ -19,6 +21,54 @@ Soft mask for uGUI element in Unity.
## Description
+SoftMask is a smooth masking component for uGUI elements in Unity.
+By using SoftMask instead of default Mask, rounded edges of UI elements can be expressed beautifully.
+
+
+
+#### Features
+
+* SoftMask is compatible with Mask.
+* You can adjust the visible part.
+
+* Text, Image, RawImage can be used as a masking.
+* Support multiple-sprites and SpriteAtlas.
+* Support up to 4 nested soft masks.
+
+* Support scroll view.
+
+* Support inversed soft mask.
+
+* Support overlay, camera space and world space.
+
+* Raycast is filtered only for the visible part.
+
+* Contain soft maskable UI shader.
+* Support soft masks in your custom shaders by adding just 3 lines. For details, please see [Development Note](#support-soft-masks-in-your-custom-shaders).
+* Adjust soft mask buffer size to improve performance.
+* Convert existing Mask to SoftMask from context menu.
+
+
+
+#### Future plans
+
+* Render the soft mask buffer only when needed to improve performance.
+* Add a SoftMaskable component to the child UI elements of SoftMask From the inspector.
+* Preview soft mask buffer in inspector.
+* Support TextMeshPro.
+* Component icon.
+
+#### Known issues
+
+* SceneView does not display SoftMask properly. It is displayed like Mask. ([By design](#why-is-not-it-displayed-properly-in-sceneview?))
+
+#### Components
+
+|Component|Description|Screenshot|
+|-|-|-|
+|SoftMask|Use instead of Mask for smooth masking.
**Show Mask Graphic:** Show the graphic that is associated with the Mask render area.
**Desampling Rate:** The desampling rate for soft mask buffer. The larger the value, the better the performance but the lower the quality.
**Softness:** The value used by the soft mask to select the area of influence defined over the soft mask's graphic.
**Ignore Parent:** Should the soft mask ignore parent soft masks?|
|
+|SoftMaskable|Add this component to Graphic under SoftMask for smooth masking.
**Inverse:** The graphic will be visible only in areas where no mask is present.|
|
+
@@ -34,16 +84,199 @@ Soft mask for uGUI element in Unity.
1. Download `*.unitypackage` from [Releases](https://github.com/mob-sakai/SoftMaskForUGUI/releases).
2. Import the package into your Unity project. Select `Import Package > Custom Package` from the `Assets` menu.

-3. Enjoy!
+3. Add SoftMask component instead of Mask component. Or, convert existing Mask component to SoftMask component from the context menu.
+
+4. Add SoftMaskable components to the child UI elements of SoftMask component.
+
+5. Adjust softness of SoftMask.
+
+6. Enjoy!
##### Requirement
-* Unity 5.5+ *(included Unity 2018.x)*
+* Unity 2017+ *(including Unity 2018.x)*
* No other SDK are required
+
+## Development Note
+
+#### Support soft masks in your custom shaders
+
+You can support soft masks in your custom shaders, by adding just 3 lines!
+
+1. Add `#pragma` and `#include`. `SOFTMASK_EDITOR` is a keyword for editor, not included in the build.
+```
+#include "Assets/Coffee/UIExtensions/SoftMaskForUGUI/SoftMask.cginc"
+#pragma shader_feature __ SOFTMASK_EDITOR
+```
+2. Apply a soft mask in the fragment shader. `IN.vertex` is clip position.
+```
+color.a *= SoftMask(IN.vertex);
+```
+
+For details, please see [UI-Default-SoftMask.shader](https://raw.githubusercontent.com/mob-sakai/SoftMaskForUGUI/master/Assets/Coffee/UIExtensions/SoftMaskForUGUI/Resources/UI-Default-SoftMask.shader).
+
+
+
+#### Why is not it displayed properly in SceneView?
+
+SoftMask calculates the final alpha value based on the value of each channel of the soft mask buffer.
+The soft mask buffer is a buffer generated based on GameView's screen space.
+
+Since SceneView has a view matrix and a projection matrix independent of GameView, the SceneView's camera can not refer to the soft mask buffer properly.
+
+Therefore, in GameView, it is displayed properly. but in ScreenView, it is displayed like default Mask.
+
+
+
+
+
+#### Tips: Convert component from context menu
+
+Converting components from the context menu is very convenient.
+You can convert multiple components at the same time, without having to remove the source components.
+
+
+
+If the destination component has the same properties as the source component, the value is set automatically.
+
+In addition, if the destination component is compatible with the source component, it will not lose its reference.
+For example, if `public Mask mask;` refers to a Mask, converting it to SoftMask in this way does not lose references.
+
+This way consists of two generic methods.
+
+```cs
+///
+/// Verify whether it can be converted to the specified component.
+///
+protected static bool CanConvertTo(Object context)
+ where T : MonoBehaviour
+{
+ return context && context.GetType() != typeof(T);
+}
+
+///
+/// Convert to the specified component.
+///
+protected static void ConvertTo(Object context) where T : MonoBehaviour
+{
+ var target = context as MonoBehaviour;
+ var so = new SerializedObject(target);
+ so.Update();
+
+ bool oldEnable = target.enabled;
+ target.enabled = false;
+
+ // Find MonoScript of the specified component.
+ foreach (var script in Resources.FindObjectsOfTypeAll())
+ {
+ if (script.GetClass() != typeof(T))
+ continue;
+
+ // Set 'm_Script' to convert.
+ so.FindProperty("m_Script").objectReferenceValue = script;
+ so.ApplyModifiedProperties();
+ break;
+ }
+
+ (so.targetObject as MonoBehaviour).enabled = oldEnable;
+}
+```
+
+In SoftMask, they are implemented as follows.
+* Mask and SoftMask can be converted to each other.
+* If conversion is not possible, gray out the context menu.
+
+```cs
+[MenuItem("CONTEXT/Mask/Convert To SoftMask", true)]
+static bool _ConvertToSoftMask(MenuCommand command)
+{
+ return CanConvertTo(command.context);
+}
+[MenuItem("CONTEXT/Mask/Convert To SoftMask", false)]
+static void ConvertToSoftMask(MenuCommand command)
+{
+ ConvertTo(command.context);
+}
+[MenuItem("CONTEXT/Mask/Convert To Mask", true)]
+static bool _ConvertToMask(MenuCommand command)
+{
+ return CanConvertTo(command.context);
+}
+[MenuItem("CONTEXT/Mask/Convert To Mask", false)]
+static void ConvertToMask(MenuCommand command)
+{
+ ConvertTo(command.context);
+}
+```
+
+For details, please see [SoftMaskEditor.cs](https://raw.githubusercontent.com/mob-sakai/SoftMaskForUGUI/master/Assets/Coffee/UIExtensions/SoftMaskForUGUI/Scripts/Editor/SoftMaskEditor.cs).
+
+
+
+#### Tips: Shader code for editor only
+
+Do you know how to implement shader code "for editor only"?
+SoftMask uses `SOFTMASK_EDITOR` keyword in shader code to determine whether it is running in the editor.
+
+`#pragma shader_feature __ SOFTMASK_EDITOR`
+
+`SOFTMASK_EDITOR` keyword is set from the editor script, but it is not set after it is built. Also, this shader variant will be excluded from build.
+
+```cs
+#if UNITY_EDITOR
+material = new Material(shader);
+material.hideFlags = HideFlags.HideAndDontSave;
+material.EnableKeyword("SOFTMASK_EDITOR");
+#endif
+```
+
+
+
+#### Tips: Shader code for SceneView only
+
+Do you know how to implement shader code "for SceneView only"?
+SoftMask understands that the current rendering is for SceneView, when SceneView's view projection matrix and UNITY_MATRIX_VP match.
+
+`fixed isSceneView = 1 - any(UNITY_MATRIX_VP - _SceneViewVP);`
+
+Actually, because of the movement operation in SceneView, use "approximate" instead of "match".
+
+```cs
+float4x4 _SceneViewVP;
+
+fixed Approximate(float4x4 a, float4x4 b)
+{
+ float4x4 d = abs(a - b);
+ return step(
+ max(d._m00,max(d._m01,max(d._m02,max(d._m03,
+ max(d._m10,max(d._m11,max(d._m12,max(d._m13,
+ max(d._m20,max(d._m21,max(d._m22,max(d._m23,
+ max(d._m30,max(d._m31,max(d._m32,d._m33))))))))))))))),
+ 0.01);
+}
+
+fixed isSceneView = Approximate(UNITY_MATRIX_VP, _SceneViewVP);
+```
+
+`_SceneViewVP` is set every frame from the editor script.
+
+```cs
+#if UNITY_EDITOR
+UnityEditor.EditorApplication.update += ()
+{
+ Camera cam = UnityEditor.SceneView.lastActiveSceneView.camera;
+ Matrix4x4 vp = cam.projectionMatrix * cam.worldToCameraMatrix;
+ material.SetMatrix("_SceneViewVP", vp);
+};
+#endif
+```
+
+
+
## License