Implements basic components of mtoon10.

This commit is contained in:
Masataka SUMI
2021-05-31 20:18:34 +09:00
parent 8ec0bfca40
commit 44067be1fc
46 changed files with 696 additions and 378 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d4b26a27a0aab424c9022e525037a718
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3f051e7d892a4bccbcc8fd1f4c2ca162
timeCreated: 1622456532

View File

@@ -0,0 +1,9 @@
namespace VRMShaders.VRM10.MToon10.Editor
{
public enum AlphaMode
{
Opaque = 0,
Cutout = 1,
Transparent = 2,
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 4915ab0041b841b6aa0cdfecae764008
timeCreated: 1622453782

View File

@@ -0,0 +1,8 @@
namespace VRMShaders.VRM10.MToon10.Editor
{
public enum TransparentWithZWriteMode
{
Off = 0,
On = 1,
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d5df515a36d3460891b348872459476f
timeCreated: 1622456521

View File

@@ -0,0 +1,64 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityEngine.Rendering;
namespace VRMShaders.VRM10.MToon10.Editor
{
public class MToonInspector : ShaderGUI
{
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
{
var props = PropExtensions.PropertyNames
.ToDictionary(x => x.Key, x => FindProperty(x.Value, properties));
var materials = materialEditor.targets.Select(x => x as Material).ToArray();
EditorGUILayout.LabelField("Rendering", EditorStyles.boldLabel);
EditorGUILayout.BeginVertical(GUI.skin.box);
{
EditorGUILayout.LabelField("Mode", EditorStyles.boldLabel);
if (PopupEnum<AlphaMode>("Alpha Mode", props[Prop.AlphaMode], materialEditor))
{
Validate(materials);
}
if (PopupEnum<TransparentWithZWriteMode>("Transparent With ZWrite Mode", props[Prop.TransparentWithZWrite], materialEditor))
{
Validate(materials);
}
}
EditorGUILayout.EndVertical();
EditorGUILayout.Space();
base.OnGUI(materialEditor, properties);
}
private static void Validate(Material[] materials)
{
foreach (var material in materials)
{
new MToonValidator(material).Validate();
}
}
private static bool PopupEnum<T>(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;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b8b6f1e6a8a133a4987361f178d9f548
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,80 @@
using System;
using UnityEngine;
using UnityEngine.Rendering;
namespace VRMShaders.VRM10.MToon10.Editor
{
public sealed class MToonValidator
{
private readonly Material _material;
public MToonValidator(Material material)
{
_material = material;
}
public void Validate()
{
var alphaMode = (AlphaMode) _material.GetInt(Prop.AlphaMode);
var zWriteMode = (TransparentWithZWriteMode) _material.GetInt(Prop.TransparentWithZWrite);
SetUnityRenderSettings(_material, alphaMode, zWriteMode);
}
private static void SetUnityRenderSettings(Material material, AlphaMode alphaMode, TransparentWithZWriteMode zWriteMode)
{
material.SetInt(Prop.AlphaMode, (int) alphaMode);
material.SetInt(Prop.TransparentWithZWrite, (int) zWriteMode);
switch (alphaMode)
{
case AlphaMode.Opaque:
material.SetOverrideTag(UnityRenderTag.Key, UnityRenderTag.OpaqueValue);
material.SetInt(Prop.UnitySrcBlend, (int) BlendMode.One);
material.SetInt(Prop.UnityDstBlend, (int) BlendMode.Zero);
material.SetInt(Prop.UnityZWrite, (int) UnityZWriteMode.On);
material.SetInt(Prop.UnityAlphaToMask, (int) UnityAlphaToMaskMode.Off);
material.SetKeyword(UnityAlphaModeKeyword.AlphaTest, false);
material.SetKeyword(UnityAlphaModeKeyword.AlphaBlend, false);
material.SetKeyword(UnityAlphaModeKeyword.AlphaPremultiply, false);
material.renderQueue = (int) RenderQueue.Geometry;
break;
case AlphaMode.Cutout:
material.SetOverrideTag(UnityRenderTag.Key, UnityRenderTag.TransparentCutoutValue);
material.SetInt(Prop.UnitySrcBlend, (int) BlendMode.One);
material.SetInt(Prop.UnityDstBlend, (int) BlendMode.Zero);
material.SetInt(Prop.UnityZWrite, (int) UnityZWriteMode.On);
material.SetInt(Prop.UnityAlphaToMask, (int) UnityAlphaToMaskMode.On);
material.SetKeyword(UnityAlphaModeKeyword.AlphaTest, true);
material.SetKeyword(UnityAlphaModeKeyword.AlphaBlend, false);
material.SetKeyword(UnityAlphaModeKeyword.AlphaPremultiply, false);
material.renderQueue = (int) RenderQueue.AlphaTest;
break;
case AlphaMode.Transparent when zWriteMode == TransparentWithZWriteMode.Off:
material.SetOverrideTag(UnityRenderTag.Key, UnityRenderTag.TransparentValue);
material.SetInt(Prop.UnitySrcBlend, (int) BlendMode.SrcAlpha);
material.SetInt(Prop.UnityDstBlend, (int) BlendMode.OneMinusSrcAlpha);
material.SetInt(Prop.UnityZWrite, (int) UnityZWriteMode.Off);
material.SetInt(Prop.UnityAlphaToMask, (int) UnityAlphaToMaskMode.Off);
material.SetKeyword(UnityAlphaModeKeyword.AlphaTest, false);
material.SetKeyword(UnityAlphaModeKeyword.AlphaBlend, true);
material.SetKeyword(UnityAlphaModeKeyword.AlphaPremultiply, false);
material.renderQueue = (int) RenderQueue.Transparent;
break;
case AlphaMode.Transparent when zWriteMode == TransparentWithZWriteMode.On:
material.SetOverrideTag(UnityRenderTag.Key, UnityRenderTag.TransparentValue);
material.SetInt(Prop.UnitySrcBlend, (int) BlendMode.SrcAlpha);
material.SetInt(Prop.UnityDstBlend, (int) BlendMode.OneMinusSrcAlpha);
material.SetInt(Prop.UnityZWrite, (int) UnityZWriteMode.On);
material.SetInt(Prop.UnityAlphaToMask, (int) UnityAlphaToMaskMode.Off);
material.SetKeyword(UnityAlphaModeKeyword.AlphaTest, false);
material.SetKeyword(UnityAlphaModeKeyword.AlphaBlend, true);
material.SetKeyword(UnityAlphaModeKeyword.AlphaPremultiply, false);
material.renderQueue = (int) RenderQueue.GeometryLast + 1; // Transparent First
break;
default:
SetUnityRenderSettings(material, AlphaMode.Opaque, TransparentWithZWriteMode.Off);
break;
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 18b52251a22d40ccbfc16c4a89d09c51
timeCreated: 1622453963

View File

@@ -0,0 +1,29 @@
using UnityEngine;
namespace VRMShaders.VRM10.MToon10.Editor
{
public static class MaterialExtensions
{
public static void SetKeyword(this Material mat, string keyword, bool isEnabled)
{
if (isEnabled)
{
mat.EnableKeyword(keyword);
}
else
{
mat.DisableKeyword(keyword);
}
}
public static int GetInt(this Material mat, Prop prop)
{
return mat.GetInt(prop.ToName());
}
public static void SetInt(this Material mat, Prop prop, int val)
{
mat.SetInt(prop.ToName(), val);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 173b50f65d2a44109cc67a84f18bde53
timeCreated: 1622456072

View File

@@ -0,0 +1,22 @@
namespace VRMShaders.VRM10.MToon10.Editor
{
public enum Prop
{
// Rendering
AlphaMode,
TransparentWithZWrite,
AlphaCutoff,
RenderQueueOffsetNumber,
DoubleSided,
// Lighting
BaseColorFactor,
// Unity Required
UnityCullMode,
UnitySrcBlend,
UnityDstBlend,
UnityZWrite,
UnityAlphaToMask,
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: aea6e3bb9944499e94c1026d60104432
timeCreated: 1622453772

View File

@@ -0,0 +1,29 @@
using System.Collections.Generic;
namespace VRMShaders.VRM10.MToon10.Editor
{
public static class PropExtensions
{
private static readonly Dictionary<Prop, string> _propertyNames = new Dictionary<Prop, string>
{
[Prop.AlphaMode] = "_AlphaMode",
[Prop.TransparentWithZWrite] = "_TransparentWithZWrite",
[Prop.AlphaCutoff] = "_Cutoff",
[Prop.RenderQueueOffsetNumber] = "_RenderQueueOffset",
[Prop.DoubleSided] = "_DoubleSided",
[Prop.BaseColorFactor] = "_Color",
[Prop.UnityCullMode] = "_M_CullMode",
[Prop.UnitySrcBlend] = "_M_SrcBlend",
[Prop.UnityDstBlend] = "_M_DstBlend",
[Prop.UnityZWrite] = "_M_ZWrite",
[Prop.UnityAlphaToMask] = "_M_AlphaToMask",
};
public static IReadOnlyDictionary<Prop, string> PropertyNames => _propertyNames;
public static string ToName(this Prop prop)
{
return PropertyNames[prop];
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3c8828cd778c400f81b8a1c93b54ee50
timeCreated: 1622454119

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 5b210153ed9c4949ad794ca34f18e1b1
timeCreated: 1622456318

View File

@@ -0,0 +1,9 @@
namespace VRMShaders.VRM10.MToon10.Editor
{
public static class UnityAlphaModeKeyword
{
public const string AlphaTest = "_ALPHATEST_ON";
public const string AlphaBlend = "_ALPHABLEND_ON";
public const string AlphaPremultiply = "_ALPHAPREMULTIPLY_ON";
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1e9a4286845a4c998a402e50da51ecc9
timeCreated: 1622456299

View File

@@ -0,0 +1,8 @@
namespace VRMShaders.VRM10.MToon10.Editor
{
public enum UnityAlphaToMaskMode
{
Off = 0,
On = 1,
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d254dee2e3b3407abcdc3f6f84b3cd59
timeCreated: 1622456292

View File

@@ -0,0 +1,10 @@
namespace VRMShaders.VRM10.MToon10.Editor
{
public static class UnityRenderTag
{
public const string Key = "RenderType";
public const string OpaqueValue = "Opaque";
public const string TransparentCutoutValue = "TransparentCutout";
public const string TransparentValue = "Transparent";
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: df547717467444c29ff3dcec1e555e17
timeCreated: 1622456295

View File

@@ -0,0 +1,8 @@
namespace VRMShaders.VRM10.MToon10.Editor
{
public enum UnityZWriteMode
{
Off = 0,
On = 1,
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 4c80d709af9c46f9b57290659de4c1c6
timeCreated: 1622456288

View File

@@ -0,0 +1,15 @@
{
"name": "VRMShaders.VRM10.MToon10.Editor",
"references": [],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: e3216dcc79b326b47b307c06b99c7331
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,4 +1,4 @@
Shader "VRM10/vrmc_materials_mtoon"
Shader "Hidden/VRM10/vrmc_materials_mtoon"
{
Properties
{
@@ -10,7 +10,7 @@ Shader "VRM10/vrmc_materials_mtoon"
_DoubleSided ("doubleSided", Int) = 0
// Lighting
_Color ("pbrMetallicRoughness.baseColorFactor", Color) = (1,1,1,1) // Unity specified name
_Color ("pbrMetallicRoughness.baseColorFactor", Color) = (1, 1, 1, 1) // Unity specified name
_MainTex ("pbrMetallicRoughness.baseColorTexture", 2D) = "white" {} // Unity specified name
_ShadeColor ("mtoon.shadeColorFactor", Color) = (1, 1, 1, 1)
_ShadeTex ("mtoon.shadeMultiplyTexture", 2D) = "white" {}
@@ -27,12 +27,12 @@ Shader "VRM10/vrmc_materials_mtoon"
_GiEqualization ("mtoon.giEqualizationFactor", Range(0, 1)) = 0.9
// Emission
_EmissionColor ("emissiveFactor", Color) = (0, 0, 0) // Unity specified name
_EmissionColor ("emissiveFactor", Color) = (0, 0, 0, 1) // Unity specified name
_EmissionMap ("emissiveTexture", 2D) = "white" {} // Unity specified name
// Rim Lighting
_RimMatcapTex ("mtoon.matcapTexture", 2D) = "black" {}
_RimColor ("mtoon.parametricRimColorFactor", Color) = (0, 0, 0)
_RimColor ("mtoon.parametricRimColorFactor", Color) = (0, 0, 0, 1)
_RimFresnelPower ("mtoon.parametricRimFresnelPowerFactor", Float) = 5.0
_RimLift ("mtoon.parametricRimLiftFactor", Float) = 0
_RimTex ("mtoon.rimMultiplyTexture", 2D) = "white" {}
@@ -42,8 +42,8 @@ Shader "VRM10/vrmc_materials_mtoon"
_OutlineWidthMode ("mtoon.outlineWidthMode", Int) = 0
_OutlineWidth ("mtoon.outlineWidthFactor", Float) = 0
_OutlineWidthTex ("mtoon.outlineWidthMultiplyTexture", 2D) = "white" {} // channel G
_OutlineColor ("mtoon.outlineColorFactor", Color) = (0, 0, 0)
_OutlineLightingMix ("mtoon.outlineLightingMixFactor", Float) = 1 // default 0
_OutlineColor ("mtoon.outlineColorFactor", Color) = (0, 0, 0, 1)
_OutlineLightingMix ("mtoon.outlineLightingMixFactor", Float) = 1
// UV Animation
_UvAnimMaskTex ("mtoon.uvAnimationMaskTexture", 2D) = "white" {} // channel B
@@ -52,14 +52,14 @@ Shader "VRM10/vrmc_materials_mtoon"
_UvAnimRotationSpeed ("mtoon.uvAnimationRotationSpeedFactor", Float) = 0
// Unity ShaderPass Mode
[HideInInspector] _M_CullMode ("_CullMode", Float) = 2.0
[HideInInspector] _M_SrcBlend ("_SrcBlend", Float) = 1.0
[HideInInspector] _M_DstBlend ("_DstBlend", Float) = 0.0
[HideInInspector] _M_ZWrite ("_ZWrite", Float) = 1.0
[HideInInspector] _M_AlphaToMask ("_AlphaToMask", Float) = 0.0
_M_CullMode ("_CullMode", Float) = 2.0
_M_SrcBlend ("_SrcBlend", Float) = 1.0
_M_DstBlend ("_DstBlend", Float) = 0.0
_M_ZWrite ("_ZWrite", Float) = 1.0
_M_AlphaToMask ("_AlphaToMask", Float) = 0.0
// etc
[HideInInspector] _M_DebugMode ("_DebugMode", Float) = 0.0
_M_DebugMode ("_DebugMode", Float) = 0.0
}
SubShader
@@ -77,55 +77,28 @@ Shader "VRM10/vrmc_materials_mtoon"
ZWrite [_M_ZWrite]
ZTest LEqual
BlendOp Add, Max
AlphaToMask [_M_AlphaToMask]
AlphaToMask Off
CGPROGRAM
HLSLPROGRAM
#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 "./vrmc_materials_mtoon_sm3.hlsl"
#pragma vertex vert_forward_base
#pragma fragment frag_forward
// Unity defined keywords
#pragma multi_compile_fwdbase
#pragma multi_compile_fog
// #pragma multi_compile_instancing
ENDCG
#pragma multi_compile_instancing
#pragma multi_compile_local __ _ALPHATEST_ON _ALPHABLEND_ON
#pragma multi_compile_local __ _NORMALMAP
#pragma multi_compile_local __ _UVANIMATION
#pragma vertex MToonVertex
#pragma fragment MToonFragment
#include "./vrmc_materials_mtoon_forward_vertex.hlsl"
#include "./vrmc_materials_mtoon_forward_fragment.hlsl"
ENDHLSL
}
// Built-in Forward Base Outline Pass
Pass
{
Name "FORWARD_BASE_ONLY_OUTLINE"
Tags { "LightMode" = "ForwardBase" }
Cull Front
Blend [_M_SrcBlend] [_M_DstBlend]
ZWrite [_M_ZWrite]
ZTest LEqual
Offset 1, 1
BlendOp Add, Max
AlphaToMask [_M_AlphaToMask]
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 "./vrmc_materials_mtoon_sm3.hlsl"
#pragma vertex vert_forward_base_outline
#pragma fragment frag_forward
#pragma multi_compile_fwdbase
#pragma multi_compile_fog
// #pragma multi_compile_instancing
ENDCG
}
// Built-in Forward Add Pass
Pass
{
@@ -139,21 +112,27 @@ Shader "VRM10/vrmc_materials_mtoon"
BlendOp Add, Max
AlphaToMask [_M_AlphaToMask]
CGPROGRAM
HLSLPROGRAM
#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 "./vrmc_materials_mtoon_sm3.hlsl"
#pragma vertex vert_forward_add
#pragma fragment frag_forward
// Unity defined keywords
#pragma multi_compile_fwdadd_fullshadows
#pragma multi_compile_fog
ENDCG
#pragma multi_compile_instancing
#pragma multi_compile_local __ _ALPHATEST_ON _ALPHABLEND_ON
#pragma multi_compile_local __ _NORMALMAP
#pragma multi_compile_local __ _UVANIMATION
#pragma vertex MToonVertex
#pragma fragment MToonFragment
#include "./vrmc_materials_mtoon_forward_vertex.hlsl"
#include "./vrmc_materials_mtoon_forward_fragment.hlsl"
ENDHLSL
}
// Built-in Shadow Rendering Pass
// Shadow rendering pass
Pass
{
Name "ShadowCaster"
@@ -165,15 +144,23 @@ Shader "VRM10/vrmc_materials_mtoon"
CGPROGRAM
#pragma target 3.0
#pragma multi_compile _ _ALPHATEST_ON _ALPHABLEND_ON
// Unity defined keywords
#pragma multi_compile_shadowcaster
#pragma multi_compile_local __ _ALPHATEST_ON _ALPHABLEND_ON
// Use unity standard shadow implementation.
// internal usage:
// keywords: _ALPHATEST_ON _ALPHABLEND_ON
// variables: _MainTex.a _Color.a _Cutoff
#pragma vertex vertShadowCaster
#pragma fragment fragShadowCaster
#include "UnityStandardShadow.cginc"
ENDCG
}
}
Fallback "Unlit/Texture"
CustomEditor "MToon.MToonInspector"
CustomEditor "VRMShaders.VRM10.MToon10.Editor.MToonInspector"
}

View File

@@ -0,0 +1,34 @@
#ifndef VRMC_MATERIALS_MTOON_ATTRIBUTE_INCLUDED
#define VRMC_MATERIALS_MTOON_ATTRIBUTE_INCLUDED
#include <UnityCG.cginc>
#include <AutoLight.cginc>
struct Attributes
{
float4 vertex : POSITION; // UnityCG macro specified name. Accurately "positionOS"
float3 normalOS : NORMAL;
#if defined(_NORMALMAP)
float4 tangentOS : TANGENT;
#endif
float2 texcoord0 : TEXCOORD0;
float2 texcoord1 : TEXCOORD1;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varyings
{
float2 uv : TEXCOORD0;
float3 positionWS : TEXCOORD1;
half3 normalWS : TEXCOORD2;
#if defined(_NORMALMAP)
half4 tangentWS : TEXCOORD3;
#endif
UNITY_FOG_COORDS(4)
UNITY_LIGHTING_COORDS(5,6)
float4 pos : SV_POSITION; // UnityCG macro specified name. Accurately "positionCS"
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO
};
#endif

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 82d864eead0e48f79295fe490a6d614f
timeCreated: 1622450640

View File

@@ -1,282 +0,0 @@
#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)
UNITY_SHADOW_COORDS(8)
//UNITY_VERTEX_INPUT_INSTANCE_ID // necessary only if any instanced properties are going to be accessed in the fragment Shader.
UNITY_VERTEX_OUTPUT_STEREO
};
inline v2f InitializeV2F(appdata_full v, float4 projectedVertex, float isOutline)
{
v2f o;
UNITY_INITIALIZE_OUTPUT(v2f, o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
//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;
UNITY_TRANSFER_SHADOW(o, o._ShadowCoord);
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);
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
// const
const float PI_2 = 6.28318530718;
const float EPS_COL = 0.00001;
// uv
float2 mainUv = TRANSFORM_TEX(i.uv0, _MainTex);
// uv anim
float 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;
alpha = (alpha - _Cutoff) / max(fwidth(alpha), EPS_COL) + 0.5; // Alpha to Coverage
clip(alpha - _Cutoff);
alpha = 1.0; // Discarded, otherwise it should be assumed to have full opacity
#endif
#ifdef _ALPHABLEND_ON
alpha = _Color.a * mainTex.a;
#if !_ALPHATEST_ON && SHADER_API_D3D11 // Only enable this on D3D11, where I tested it
clip(alpha - 0.0001); // Slightly improves rendering with layered transparency
#endif
#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

View File

@@ -0,0 +1,8 @@
#ifndef VRMC_MATERIALS_MTOON_DEFINE_INCLUDED
#define VRMC_MATERIALS_MTOON_DEFINE_INCLUDED
// define
static const float PI_2 = 6.28318530718;
static const float EPS_COL = 0.00001;
#endif

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: cfd10dec96ea4e3f9fad70e2e5dc148e
timeCreated: 1622451960

View File

@@ -0,0 +1,57 @@
#ifndef VRMC_MATERIALS_MTOON_FORWARD_FRAGMENT_INCLUDED
#define VRMC_MATERIALS_MTOON_FORWARD_FRAGMENT_INCLUDED
#include <UnityCG.cginc>
#include <AutoLight.cginc>
#include "./vrmc_materials_mtoon_define.hlsl"
#include "./vrmc_materials_mtoon_input.hlsl"
#include "./vrmc_materials_mtoon_attribute.hlsl"
#include "./vrmc_materials_mtoon_lighting.hlsl"
#include "./vrmc_materials_mtoon_uv.hlsl"
#include "./vrmc_materials_mtoon_unity_lighting.hlsl"
half4 MToonFragment(Varyings input) : SV_Target
{
// Get MToon UV (with UVAnimation)
const float2 uv = GetMToonUv(input.uv);
// Get LitColor with Alpha
const half4 litColor = UNITY_SAMPLE_TEX2D(_MainTex, uv) * _Color;
// Alpha Test
#if defined(_ALPHATEST_ON)
const half rawAlpha = _Color.a;
const half tmpAlpha = (rawAlpha - _Cutoff) / max(fwidth(rawAlpha), 0.00001) + 0.5; // Alpha to Coverage
clip(tmpAlpha - _Cutoff);
const half alpha = 1.0;
#elif defined(_ALPHABLEND_ON)
const half alpha = litColor.a;
clip(alpha - EPS_COL);
#else
const half alpha = 1.0;
#endif
// Get Normal in WorldSpace from Normalmap if available
#if defined(_NORMALMAP)
const half3 bitangent = input.tangentWS.w * cross(normalize(input.normalWS), normalize(input.tangentWS.xyz));
const half3x3 tangentToWorld = half3x3(normalize(input.tangentWS.xyz), normalize(bitangent), normalize(input.normalWS));
const half3 normalTS = normalize(UnpackNormalWithScale(UNITY_SAMPLE_TEX2D(_BumpMap, uv), _BumpScale));
const half3 normalWS = normalize(mul(normalTS, tangentToWorld));
#else
const half3 normalWS = normalize(input.normalWS);
#endif
// Get Unity Lighting
const UnityLighting unityLighting = GetUnityLighting(input, normalWS);
// Get MToon Lighting
const half4 col = GetMToonLighting(unityLighting.directLight, unityLighting.indirectLight, uv, litColor, alpha);
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
#endif

View File

@@ -1,9 +1,9 @@
fileFormatVersion: 2
guid: 22be54a117660824da79e2b52a710d59
timeCreated: 1514120022
licenseType: Free
guid: 3717321cda361ad48abfc6b4fcb7a320
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,35 @@
#ifndef VRMC_MATERIALS_MTOON_FORWARD_VERTEX_INCLUDED
#define VRMC_MATERIALS_MTOON_FORWARD_VERTEX_INCLUDED
#include <UnityCG.cginc>
#include <AutoLight.cginc>
#include "./vrmc_materials_mtoon_define.hlsl"
#include "./vrmc_materials_mtoon_input.hlsl"
#include "./vrmc_materials_mtoon_attribute.hlsl"
Varyings MToonVertex(Attributes v) // v is UnityCG macro specified name.
{
Varyings output = (Varyings)0;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_TRANSFER_INSTANCE_ID(v, output);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
output.pos = UnityObjectToClipPos(v.vertex);
output.positionWS = mul(unity_ObjectToWorld, v.vertex);
output.uv = TRANSFORM_TEX(v.texcoord0, _MainTex);
output.normalWS = UnityObjectToWorldNormal(v.normalOS);
#if defined(_NORMALMAP)
const half tangentSign = v.tangentOS.w * unity_WorldTransformParams.w;
output.tangentWS = half4(UnityObjectToWorldDir(v.tangentOS), tangentSign);
#endif
UNITY_TRANSFER_FOG(output, output.positionWS);
UNITY_TRANSFER_LIGHTING(output, v.texcoord1.xy);
return output;
}
#endif

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 26b921255f4e4d62a8c0ec730521831f
timeCreated: 1622458970

View File

@@ -0,0 +1,50 @@
#ifndef VRMC_MATERIALS_MTOON_INPUT_INCLUDED
#define VRMC_MATERIALS_MTOON_INPUT_INCLUDED
#include <UnityShaderVariables.cginc>
// Textures
UNITY_DECLARE_TEX2D(_MainTex);
UNITY_DECLARE_TEX2D(_ShadeTex);
UNITY_DECLARE_TEX2D(_BumpMap);
UNITY_DECLARE_TEX2D(_ShadingShiftTex);
UNITY_DECLARE_TEX2D(_EmissionMap);
UNITY_DECLARE_TEX2D(_RimMatcapTex);
UNITY_DECLARE_TEX2D(_RimTex);
UNITY_DECLARE_TEX2D(_OutlineWidthTex);
UNITY_DECLARE_TEX2D(_UvAnimMaskTex);
CBUFFER_START(UnityPerMaterial)
// Vector
float4 _MainTex_ST;
// Colors
half4 _Color;
half4 _ShadeColor;
half4 _ShadingShiftColor;
half4 _ShadingToonyColor;
half4 _EmissionColor;
half4 _RimColor;
half4 _OutlineColor;
// Floats
half _Cutoff;
half _BumpScale;
half _ShadingShiftTexScale;
half _GiEqualization;
half _RimFresnelPower;
half _RimLift;
half _RimLightingMix;
half _OutlineWidth;
half _OutlineLightingMix;
half _UvAnimScrollXSpeed;
half _UvAnimScrollYSpeed;
half _UvAnimRotationSpeed;
CBUFFER_END
// No Using on shader
// half _AlphaMode;
// half _TransparentWithZWrite;
// half _RenderQueueOffset;
// half _DoubleSided;
// half _OutlineWidthMode;
#endif

View File

@@ -1,9 +1,9 @@
fileFormatVersion: 2
guid: 5aae6ba3f344c0e43914d19a64704aba
timeCreated: 1514120022
licenseType: Free
guid: c7f37d6d268db6f4da25955d0ca7cb01
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,13 @@
#ifndef VRMC_MATERIALS_MTOON_LIGHTING_INCLUDED
#define VRMC_MATERIALS_MTOON_LIGHTING_INCLUDED
#include "./vrmc_materials_mtoon_input.hlsl"
half4 GetMToonLighting(half3 directLight, half3 indirectLight, float2 uv, half4 litColor, half alpha)
{
const half4 albedo = litColor;
return half4(albedo.rgb * (directLight + indirectLight), alpha);
}
#endif

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 54d13d2ffd7249259772084874b76659
timeCreated: 1622449184

View File

@@ -1,22 +0,0 @@
#include "./vrmc_materials_mtoon_core.hlsl"
v2f vert_forward_base(appdata_full v)
{
UNITY_SETUP_INSTANCE_ID(v);
v.normal = normalize(v.normal);
return InitializeV2F(v, UnityObjectToClipPos(v.vertex), 0);
}
v2f vert_forward_base_outline(appdata_full v)
{
UNITY_SETUP_INSTANCE_ID(v);
v.normal = normalize(v.normal);
return InitializeV2F(v, CalculateOutlineVertexClipPosition(v), 1);
}
v2f vert_forward_add(appdata_full v)
{
UNITY_SETUP_INSTANCE_ID(v);
v.normal = normalize(v.normal);
return InitializeV2F(v, UnityObjectToClipPos(v.vertex), 0);
}

View File

@@ -0,0 +1,41 @@
#ifndef VRMC_MATERIALS_MTOON_UNITY_LIGHTING_INCLUDED
#define VRMC_MATERIALS_MTOON_UNITY_LIGHTING_INCLUDED
#include <UnityCG.cginc>
#include <AutoLight.cginc>
#include <Lighting.cginc>
#include "./vrmc_materials_mtoon_input.hlsl"
#include "./vrmc_materials_mtoon_attribute.hlsl"
struct UnityLighting
{
half3 directLight;
half3 indirectLight;
};
UnityLighting GetUnityLighting(Varyings input, half3 normalWS)
{
UNITY_LIGHT_ATTENUATION(atten, input, input.positionWS);
const half3 lightDir = normalize(UnityWorldSpaceLightDir(input.positionWS));
const half3 lightColor = _LightColor0.rgb;
const half dotNL = dot(lightDir, normalWS);
#if defined(UNITY_PASS_FORWARDBASE)
const half3 indirect = ShadeSH9(half4(normalWS, 1));
const half3 direct = lightColor * max(0, dotNL) * atten;
#elif defined(UNITY_PASS_FORWARDADD)
const half3 indirect = 0;
const half3 direct = lightColor * max(0, dotNL) * atten;
#else
const half3 indirect = half3(1, 1, 0); // error
const half3 direct = 0;
#endif
UnityLighting output = (UnityLighting) 0;
output.directLight = direct;
output.indirectLight = indirect;
return output;
}
#endif

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 08491980bb224017bbb8e432761db8c4
timeCreated: 1622450586

View File

@@ -0,0 +1,26 @@
#ifndef VRMC_MATERIALS_MTOON_UV_INCLUDED
#define VRMC_MATERIALS_MTOON_UV_INCLUDED
#include <UnityCG.cginc>
#include "./vrmc_materials_mtoon_define.hlsl"
#include "./vrmc_materials_mtoon_input.hlsl"
float2 GetMToonUv(float2 geometryUv)
{
// get raw uv with _MainTex_ST
const float2 uvRaw = TRANSFORM_TEX(geometryUv, _MainTex);
#if defined(_UVANIMATION)
const float uvAnimationCoef = UNITY_SAMPLE_TEX2D(_UvAnimMaskTex, uvRaw).b * _Time.y;
const float2 uvAnimationAdd = uvAnimationCoef * float2(_UvAnimScrollXSpeed, _UvAnimScrollYSpeed);
const float rotateRad = uvAnimationCoef * _UvAnimRotationSpeed * PI_2;
const float2 rotatePivot = float2(0.5, 0.5);
const float2 uv = mul(float2x2(cos(rotateRad), -sin(rotateRad), sin(rotateRad), cos(rotateRad)), uvRaw + uvAnimationAdd - rotatePivot) + rotatePivot;
#else
const float2 uv = uvRaw;
#endif
return uv;
}
#endif

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1381f11f525a4d90a57348ada020ea01
timeCreated: 1622451732