diff --git a/Editor/WF_ShaderCustomEditor.cs b/Editor/WF_ShaderCustomEditor.cs index a99bb34a..e7872d14 100644 --- a/Editor/WF_ShaderCustomEditor.cs +++ b/Editor/WF_ShaderCustomEditor.cs @@ -56,6 +56,15 @@ public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] pro } // 描画 materialEditor.ShaderProperty(prop, prop.displayName); + + if (prop.name == "_TS_BaseTex") { + Rect position = EditorGUILayout.GetControlRect(true, 24); + Rect fieldpos = EditorGUI.PrefixLabel(position, new GUIContent("[SH] Shade Color Suggest", "ベース色をもとに1影2影色を設定します")); + fieldpos.height = 20; + if (GUI.Button(fieldpos, "APPLY")) { + SuggestShadowColor(materialEditor.targets); + } + } } EditorGUILayout.Space(); @@ -65,6 +74,42 @@ public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] pro materialEditor.EnableInstancingField(); //materialEditor.DoubleSidedGIField(); } + + private void SuggestShadowColor(object[] targets) { + foreach (object obj in targets) { + Material m = obj as Material; + if (m == null) { + continue; + } + Undo.RecordObject(m, "shade color change"); + // ベース色を取得 + Color baseColor = m.GetColor("_TS_BaseColor"); + float hur, sat, val; + Color.RGBToHSV(baseColor, out hur, out sat, out val); + // 影1 + Color shade1Color = Color.HSVToRGB(ShiftHur(hur, sat, 0.6f), sat + 0.1f, val * 0.9f); + m.SetColor("_TS_1stColor", shade1Color); + // 影2 + Color shade2Color = Color.HSVToRGB(ShiftHur(hur, sat, 0.4f), sat + 0.15f, val * 0.8f); + m.SetColor("_TS_2ndColor", shade2Color); + } + } + + private static float ShiftHur(float hur, float sat, float mul) { + if (sat < 0.05f) { + return 4 / 6f; + } + // R = 0/6f, G = 2/6f, B = 4/6f + float[] COLOR = { 0 / 6f, 2 / 6f, 4 / 6f, 6 / 6f }; + // Y = 1/6f, C = 3/6f, M = 5/6f + float[] LIMIT = { 1 / 6f, 3 / 6f, 5 / 6f, 10000 }; + for (int i = 0; i < COLOR.Length; i++) { + if (hur < LIMIT[i]) { + return (hur - COLOR[i]) * mul + COLOR[i]; + } + } + return hur; + } } internal class MaterialToggleNoKwdDrawer : MaterialPropertyDrawer diff --git a/Matcaps/CubeMap/WorldSnapshot-JustH.png b/Matcaps/CubeMap/WorldSnapshot-JustH.png new file mode 100644 index 00000000..6585b8de Binary files /dev/null and b/Matcaps/CubeMap/WorldSnapshot-JustH.png differ diff --git a/Matcaps/CubeMap/WorldSnapshot-JustH.png.meta b/Matcaps/CubeMap/WorldSnapshot-JustH.png.meta new file mode 100644 index 00000000..190b5ab0 --- /dev/null +++ b/Matcaps/CubeMap/WorldSnapshot-JustH.png.meta @@ -0,0 +1,107 @@ +fileFormatVersion: 2 +guid: 93b2cfaf5c290f74a81f3584fb7df22a +TextureImporter: + fileIDToRecycleName: + 8900000: generatedCubemap + externalObjects: {} + serializedVersion: 4 + mipmaps: + mipMapMode: 0 + enableMipMap: 1 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + grayScaleToAlpha: 0 + generateCubemap: 5 + cubemapConvolution: 1 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: 2 + aniso: -1 + mipBias: -1 + wrapU: 0 + wrapV: 0 + wrapW: 0 + nPOTScale: 1 + lightmap: 0 + compressionQuality: 50 + spriteMode: 0 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 0 + alphaIsTransparency: 0 + spriteTessellationDetail: -1 + textureType: 0 + textureShape: 2 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + platformSettings: + - buildTarget: DefaultTexturePlatform + maxTextureSize: 256 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 1 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Standalone + maxTextureSize: 256 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 1 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: Android + maxTextureSize: 256 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 1 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + - buildTarget: WebGL + maxTextureSize: 256 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 1 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + spritePackingTag: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Shaders/Unlit_WF_FakeFur_TransCutout.shader b/Shaders/Unlit_WF_FakeFur_TransCutout.shader index 52cc250a..eef5154b 100644 --- a/Shaders/Unlit_WF_FakeFur_TransCutout.shader +++ b/Shaders/Unlit_WF_FakeFur_TransCutout.shader @@ -18,7 +18,7 @@ Shader "UnlitWF/WF_FakeFur_TransCutout" { /* * authors: - * ver:2019/05/26 whiteflare, + * ver:2019/07/13 whiteflare, */ Properties { @@ -46,6 +46,7 @@ Shader "UnlitWF/WF_FakeFur_TransCutout" { _FurShadowPower ("Fur ShadowPower", Range(0, 1)) = 0 [IntRange] _FurRepeat ("Fur Repeat", Range(1, 8)) = 3 + _FurVector ("Fur Static Vector", Vector) = (0, 0, 0, 0) // 色変換 [Header(Color Change)] @@ -155,7 +156,6 @@ Shader "UnlitWF/WF_FakeFur_TransCutout" { #pragma fragment frag_fakefur_cutoff #define _CL_ENABLE - #define _HL_ENABLE #define _TS_ENABLE #pragma target 5.0 diff --git a/Shaders/Unlit_WF_FakeFur_Transparent.shader b/Shaders/Unlit_WF_FakeFur_Transparent.shader index 5cb5e27f..614c0136 100644 --- a/Shaders/Unlit_WF_FakeFur_Transparent.shader +++ b/Shaders/Unlit_WF_FakeFur_Transparent.shader @@ -18,7 +18,7 @@ Shader "UnlitWF/WF_FakeFur_Transparent" { /* * authors: - * ver:2019/05/26 whiteflare, + * ver:2019/07/13 whiteflare, */ Properties { @@ -45,6 +45,7 @@ Shader "UnlitWF/WF_FakeFur_Transparent" { _FurShadowPower ("Fur ShadowPower", Range(0, 1)) = 0 [IntRange] _FurRepeat ("Fur Repeat", Range(1, 8)) = 3 + _FurVector ("Fur Static Vector", Vector) = (0, 0, 0, 0) // 色変換 [Header(Color Change)] @@ -156,7 +157,6 @@ Shader "UnlitWF/WF_FakeFur_Transparent" { #pragma fragment frag_fakefur #define _CL_ENABLE - #define _HL_ENABLE #define _TS_ENABLE #pragma target 5.0 diff --git a/Shaders/Unlit_WF_UnToon_Mobile_Texture.shader b/Shaders/Unlit_WF_UnToon_Mobile_Texture.shader index 68261d1d..087312fd 100644 --- a/Shaders/Unlit_WF_UnToon_Mobile_Texture.shader +++ b/Shaders/Unlit_WF_UnToon_Mobile_Texture.shader @@ -18,7 +18,7 @@ Shader "UnlitWF/UnToon_Mobile/WF_UnToon_Texture" { /* * authors: - * ver:2019/06/26 whiteflare, + * ver:2019/07/13 whiteflare, */ Properties { @@ -35,8 +35,6 @@ Shader "UnlitWF/UnToon_Mobile/WF_UnToon_Texture" { [Enum(OFF,0,BRIGHT,80,DARK,97,BLACK,100)] _GL_Level ("Anti-Glare", Float) = 97 _GL_BrendPower ("Blend Light Color", Range(0, 1)) = 0.8 - [Toggle(_)] - _GL_CastShadow ("Cast Shadows", Range(0, 1)) = 1 // 法線マップ [Header(NormalMap)] diff --git a/Shaders/Unlit_WF_UnToon_Mobile_TransCutout.shader b/Shaders/Unlit_WF_UnToon_Mobile_TransCutout.shader index 86802821..3f4b333b 100644 --- a/Shaders/Unlit_WF_UnToon_Mobile_TransCutout.shader +++ b/Shaders/Unlit_WF_UnToon_Mobile_TransCutout.shader @@ -18,7 +18,7 @@ Shader "UnlitWF/UnToon_Mobile/WF_UnToon_TransCutout" { /* * authors: - * ver:2019/06/26 whiteflare, + * ver:2019/07/13 whiteflare, */ Properties { @@ -35,8 +35,6 @@ Shader "UnlitWF/UnToon_Mobile/WF_UnToon_TransCutout" { [Enum(OFF,0,BRIGHT,80,DARK,97,BLACK,100)] _GL_Level ("Anti-Glare", Float) = 97 _GL_BrendPower ("Blend Light Color", Range(0, 1)) = 0.8 - [Toggle(_)] - _GL_CastShadow ("Cast Shadows", Range(0, 1)) = 1 // Alpha [Header(Transparent Alpha)] diff --git a/Shaders/Unlit_WF_UnToon_Mobile_Transparent.shader b/Shaders/Unlit_WF_UnToon_Mobile_Transparent.shader index 8b81117b..c264dba4 100644 --- a/Shaders/Unlit_WF_UnToon_Mobile_Transparent.shader +++ b/Shaders/Unlit_WF_UnToon_Mobile_Transparent.shader @@ -18,7 +18,7 @@ Shader "UnlitWF/UnToon_Mobile/WF_UnToon_Transparent" { /* * authors: - * ver:2019/06/26 whiteflare, + * ver:2019/07/13 whiteflare, */ Properties { @@ -35,8 +35,6 @@ Shader "UnlitWF/UnToon_Mobile/WF_UnToon_Transparent" { [Enum(OFF,0,BRIGHT,80,DARK,97,BLACK,100)] _GL_Level ("Anti-Glare", Float) = 97 _GL_BrendPower ("Blend Light Color", Range(0, 1)) = 0.8 - [Toggle(_)] - _GL_CastShadow ("Cast Shadows", Range(0, 1)) = 1 // Alpha [Header(Transparent Alpha)] @@ -45,6 +43,7 @@ Shader "UnlitWF/UnToon_Mobile/WF_UnToon_Transparent" { [NoScaleOffset] _AL_MaskTex ("[AL] Alpha Mask Texture", 2D) = "white" {} _AL_Power ("[AL] Power", Range(0, 2)) = 1.0 + _AL_Fresnel ("[AL] Fresnel Power", Range(0, 2)) = 0 [Enum(OFF,0,ON,1)] _AL_ZWrite ("[AL] ZWrite", int) = 0 @@ -142,6 +141,7 @@ Shader "UnlitWF/UnToon_Mobile/WF_UnToon_Transparent" { #pragma target 3.0 #define _AL_ENABLE + #define _AL_FRESNEL_ENABLE #define _ES_ENABLE #define _HL_ENABLE #define _TR_ENABLE diff --git a/Shaders/Unlit_WF_UnToon_Tess_Transparent.shader b/Shaders/Unlit_WF_UnToon_Tess_Transparent.shader index 94634a3d..9869b449 100644 --- a/Shaders/Unlit_WF_UnToon_Tess_Transparent.shader +++ b/Shaders/Unlit_WF_UnToon_Tess_Transparent.shader @@ -18,7 +18,7 @@ Shader "UnlitWF/UnToon_Tessellation/WF_UnToon_Tess_Transparent" { /* * authors: - * ver:2019/06/26 whiteflare, + * ver:2019/07/13 whiteflare, */ Properties { @@ -43,6 +43,7 @@ Shader "UnlitWF/UnToon_Tessellation/WF_UnToon_Tess_Transparent" { [NoScaleOffset] _AL_MaskTex ("[AL] Alpha Mask Texture", 2D) = "white" {} _AL_Power ("[AL] Power", Range(0, 2)) = 1.0 + _AL_Fresnel ("[AL] Fresnel Power", Range(0, 2)) = 0 [Enum(OFF,0,ON,1)] _AL_ZWrite ("[AL] ZWrite", int) = 0 @@ -205,6 +206,7 @@ Shader "UnlitWF/UnToon_Tessellation/WF_UnToon_Tess_Transparent" { #pragma target 5.0 #define _AL_ENABLE + #define _AL_FRESNEL_ENABLE #define _CL_ENABLE #define _ES_ENABLE #define _MT_ENABLE @@ -240,6 +242,7 @@ Shader "UnlitWF/UnToon_Tessellation/WF_UnToon_Tess_Transparent" { #pragma target 5.0 #define _AL_ENABLE + #define _AL_FRESNEL_ENABLE #define _CL_ENABLE #define _ES_ENABLE #define _HL_ENABLE diff --git a/Shaders/Unlit_WF_UnToon_Tess_Transparent3Pass.shader b/Shaders/Unlit_WF_UnToon_Tess_Transparent3Pass.shader index d07e6635..4eed62ad 100644 --- a/Shaders/Unlit_WF_UnToon_Tess_Transparent3Pass.shader +++ b/Shaders/Unlit_WF_UnToon_Tess_Transparent3Pass.shader @@ -18,7 +18,7 @@ Shader "UnlitWF/UnToon_Tessellation/WF_UnToon_Tess_Transparent3Pass" { /* * authors: - * ver:2019/06/26 whiteflare, + * ver:2019/07/13 whiteflare, */ Properties { @@ -43,6 +43,7 @@ Shader "UnlitWF/UnToon_Tessellation/WF_UnToon_Tess_Transparent3Pass" { [NoScaleOffset] _AL_MaskTex ("[AL] Alpha Mask Texture", 2D) = "white" {} _AL_Power ("[AL] Power", Range(0, 2)) = 1.0 + _AL_Fresnel ("[AL] Fresnel Power", Range(0, 2)) = 0 _AL_CutOff ("[AL] Cutoff Threshold", Range(0, 1)) = 0.9 [Enum(OFF,0,ON,1)] _AL_ZWrite ("[AL] ZWrite", int) = 0 @@ -207,6 +208,7 @@ Shader "UnlitWF/UnToon_Tessellation/WF_UnToon_Tess_Transparent3Pass" { #pragma target 5.0 #define _AL_ENABLE + #define _AL_FRESNEL_ENABLE #define _CL_ENABLE #define _HL_ENABLE #define _MT_ENABLE @@ -242,6 +244,7 @@ Shader "UnlitWF/UnToon_Tessellation/WF_UnToon_Tess_Transparent3Pass" { #pragma target 5.0 #define _AL_ENABLE + #define _AL_FRESNEL_ENABLE #define _CL_ENABLE #define _MT_ENABLE #define _NM_ENABLE @@ -276,6 +279,7 @@ Shader "UnlitWF/UnToon_Tessellation/WF_UnToon_Tess_Transparent3Pass" { #pragma target 5.0 #define _AL_ENABLE + #define _AL_FRESNEL_ENABLE #define _CL_ENABLE #define _HL_ENABLE #define _MT_ENABLE diff --git a/Shaders/Unlit_WF_UnToon_Transparent.shader b/Shaders/Unlit_WF_UnToon_Transparent.shader index 436ff5df..cbd63b18 100644 --- a/Shaders/Unlit_WF_UnToon_Transparent.shader +++ b/Shaders/Unlit_WF_UnToon_Transparent.shader @@ -18,7 +18,7 @@ Shader "UnlitWF/WF_UnToon_Transparent" { /* * authors: - * ver:2019/06/26 whiteflare, + * ver:2019/07/13 whiteflare, */ Properties { @@ -43,6 +43,7 @@ Shader "UnlitWF/WF_UnToon_Transparent" { [NoScaleOffset] _AL_MaskTex ("[AL] Alpha Mask Texture", 2D) = "white" {} _AL_Power ("[AL] Power", Range(0, 2)) = 1.0 + _AL_Fresnel ("[AL] Fresnel Power", Range(0, 2)) = 0 [Enum(OFF,0,ON,1)] _AL_ZWrite ("[AL] ZWrite", int) = 0 @@ -193,6 +194,7 @@ Shader "UnlitWF/WF_UnToon_Transparent" { #pragma target 3.0 #define _AL_ENABLE + #define _AL_FRESNEL_ENABLE #define _CL_ENABLE #define _ES_ENABLE #define _MT_ENABLE @@ -226,6 +228,7 @@ Shader "UnlitWF/WF_UnToon_Transparent" { #pragma target 3.0 #define _AL_ENABLE + #define _AL_FRESNEL_ENABLE #define _CL_ENABLE #define _ES_ENABLE #define _HL_ENABLE diff --git a/Shaders/Unlit_WF_UnToon_Transparent3Pass.shader b/Shaders/Unlit_WF_UnToon_Transparent3Pass.shader index 528485b7..1b86a86b 100644 --- a/Shaders/Unlit_WF_UnToon_Transparent3Pass.shader +++ b/Shaders/Unlit_WF_UnToon_Transparent3Pass.shader @@ -18,7 +18,7 @@ Shader "UnlitWF/WF_UnToon_Transparent3Pass" { /* * authors: - * ver:2019/06/26 whiteflare, + * ver:2019/07/13 whiteflare, */ Properties { @@ -43,6 +43,7 @@ Shader "UnlitWF/WF_UnToon_Transparent3Pass" { [NoScaleOffset] _AL_MaskTex ("[AL] Alpha Mask Texture", 2D) = "white" {} _AL_Power ("[AL] Power", Range(0, 2)) = 1.0 + _AL_Fresnel ("[AL] Fresnel Power", Range(0, 2)) = 0 _AL_CutOff ("[AL] Cutoff Threshold", Range(0, 1)) = 0.9 [Enum(OFF,0,ON,1)] _AL_ZWrite ("[AL] ZWrite", int) = 0 @@ -195,6 +196,7 @@ Shader "UnlitWF/WF_UnToon_Transparent3Pass" { #pragma target 3.0 #define _AL_ENABLE + #define _AL_FRESNEL_ENABLE #define _CL_ENABLE #define _HL_ENABLE #define _MT_ENABLE @@ -228,6 +230,7 @@ Shader "UnlitWF/WF_UnToon_Transparent3Pass" { #pragma target 3.0 #define _AL_ENABLE + #define _AL_FRESNEL_ENABLE #define _CL_ENABLE #define _MT_ENABLE #define _NM_ENABLE @@ -260,6 +263,7 @@ Shader "UnlitWF/WF_UnToon_Transparent3Pass" { #pragma target 3.0 #define _AL_ENABLE + #define _AL_FRESNEL_ENABLE #define _CL_ENABLE #define _HL_ENABLE #define _MT_ENABLE diff --git a/Shaders/Unlit_WF_UnToon_Transparent_Outline.shader b/Shaders/Unlit_WF_UnToon_Transparent_Outline.shader index f2308d5f..ac0e4f59 100644 --- a/Shaders/Unlit_WF_UnToon_Transparent_Outline.shader +++ b/Shaders/Unlit_WF_UnToon_Transparent_Outline.shader @@ -18,7 +18,7 @@ Shader "UnlitWF/WF_UnToon_Transparent_Outline" { /* * authors: - * ver:2019/06/26 whiteflare, + * ver:2019/07/13 whiteflare, */ Properties { @@ -43,6 +43,7 @@ Shader "UnlitWF/WF_UnToon_Transparent_Outline" { [NoScaleOffset] _AL_MaskTex ("[AL] Alpha Mask Texture", 2D) = "white" {} _AL_Power ("[AL] Power", Range(0, 2)) = 1.0 + _AL_Fresnel ("[AL] Fresnel Power", Range(0, 2)) = 0 [Enum(OFF,0,ON,1)] _AL_ZWrite ("[AL] ZWrite", int) = 0 diff --git a/Shaders/Unlit_WF_UnToon_Transparent_Outline_3Pass.shader b/Shaders/Unlit_WF_UnToon_Transparent_Outline_3Pass.shader index d9ba0cec..75869e90 100644 --- a/Shaders/Unlit_WF_UnToon_Transparent_Outline_3Pass.shader +++ b/Shaders/Unlit_WF_UnToon_Transparent_Outline_3Pass.shader @@ -18,7 +18,7 @@ Shader "UnlitWF/WF_UnToon_Transparent_Outline_3Pass" { /* * authors: - * ver:2019/06/26 whiteflare, + * ver:2019/07/13 whiteflare, */ Properties { @@ -43,6 +43,7 @@ Shader "UnlitWF/WF_UnToon_Transparent_Outline_3Pass" { [NoScaleOffset] _AL_MaskTex ("[AL] Alpha Mask Texture", 2D) = "white" {} _AL_Power ("[AL] Power", Range(0, 2)) = 1.0 + _AL_Fresnel ("[AL] Fresnel Power", Range(0, 2)) = 0 _AL_CutOff ("[AL] Cutoff Threshold", Range(0, 1)) = 0.9 [Enum(OFF,0,ON,1)] _AL_ZWrite ("[AL] ZWrite", int) = 0 diff --git a/Shaders/WF_Common.cginc b/Shaders/WF_Common.cginc index 8a751c38..2aa2b91e 100644 --- a/Shaders/WF_Common.cginc +++ b/Shaders/WF_Common.cginc @@ -20,7 +20,7 @@ /* * authors: - * ver:2019/06/26 whiteflare, + * ver:2019/07/13 whiteflare, */ #define _MATCAP_VIEW_CORRECT_ENABLE @@ -211,24 +211,47 @@ int _AL_Source; float _AL_Power; sampler2D _AL_MaskTex; + float _AL_Fresnel; #ifndef _AL_CustomValue #define _AL_CustomValue 1 #endif - inline void affectAlpha(float2 uv, inout float4 color) { + inline float pickAlpha(float2 uv, float power, float alpha) { if (_AL_Source == 1) { - color.a = tex2D(_AL_MaskTex, uv).r * _AL_Power * _AL_CustomValue; + return tex2D(_AL_MaskTex, uv).r * power; } else if (_AL_Source == 2) { - color.a = tex2D(_AL_MaskTex, uv).a * _AL_Power * _AL_CustomValue; + return tex2D(_AL_MaskTex, uv).a * power; } else { - color.a = color.a * _AL_Power * _AL_CustomValue; + return alpha * power; } } + + inline void affectAlpha(float2 uv, inout float4 color) { + float orig = color.a; + + // ベースアルファ + color.a = pickAlpha(uv, _AL_Power * _AL_CustomValue, orig); + } + + inline void affectAlphaWithFresnel(float2 uv, float3 normal, float3 viewdir, inout float4 color) { + float orig = color.a; + + // ベースアルファ + color.a = pickAlpha(uv, _AL_Power * _AL_CustomValue, orig); + + #ifdef _AL_FRESNEL_ENABLE + // フレネルアルファ + float maxValue = pickAlpha(uv, max(_AL_Power, _AL_Fresnel) * _AL_CustomValue, orig); + float fa = 1 - abs( dot( SafeNormalizeVec3(normal), SafeNormalizeVec3(viewdir) ) ); + color.a = lerp( color.a, maxValue, fa * fa * fa * fa ); + #endif + } #else - #define affectAlpha(uv, color) color.a = 1.0 + #define affectAlpha(uv, color) color.a = 1.0 + #define affectAlphaWithFresnel(uv, normal, viewdir, color) color.a = 1.0 #endif //////////////////////////// diff --git a/Shaders/WF_FakeFur.cginc b/Shaders/WF_FakeFur.cginc index 0315719a..81884de7 100644 --- a/Shaders/WF_FakeFur.cginc +++ b/Shaders/WF_FakeFur.cginc @@ -20,7 +20,7 @@ /* * authors: - * ver:2019/05/26 whiteflare, + * ver:2019/07/13 whiteflare, */ #include "WF_Common.cginc" @@ -36,32 +36,20 @@ struct v2g { float2 uv : TEXCOORD0; float4 ls_vertex : TEXCOORD1; - float4 ls_light_dir : TEXCOORD2; - float3 light_color : COLOR0; - float3 light_power : COLOR1; - #ifdef _TS_ENABLE - float shadow_power : COLOR2; - #endif - float3 normal : TEXCOORD3; - float2 uv2 : TEXCOORD7; + float3 normal : TEXCOORD2; UNITY_VERTEX_OUTPUT_STEREO + float2 uv2 : TEXCOORD3; + float3 waving : TEXCOORD4; }; struct g2f { - float4 vertex : SV_POSITION; float2 uv : TEXCOORD0; float4 ls_vertex : TEXCOORD1; - float4 ls_light_dir : TEXCOORD2; - float3 light_color : COLOR0; - float3 light_power : COLOR1; - #ifdef _TS_ENABLE - float shadow_power : COLOR2; - #endif - float3 normal : TEXCOORD3; - float2 uv2 : TEXCOORD7; - float height : COLOR3; - UNITY_FOG_COORDS(8) + float3 normal : TEXCOORD2; UNITY_VERTEX_OUTPUT_STEREO + float2 uv2 : TEXCOORD3; + float height : COLOR0; + float4 vertex : SV_POSITION; }; float _CutOffLevel; @@ -81,59 +69,16 @@ UNITY_INITIALIZE_OUTPUT(v2g, o); UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); -// ここから UnToon と同じ o.uv = TRANSFORM_TEX(v.uv, _MainTex); o.ls_vertex = v.vertex; - o.ls_light_dir = calcLocalSpaceLightDir( float4(0, 0, 0, v.vertex.w) ); - - float3 ambientColor = OmniDirectional_ShadeSH9(); - - // 影コントラスト - #ifdef _TS_ENABLE - if (TGL_ON(_TS_Enable)) { - float3 lightColorMain = calcLocalSpaceLightColor(o.ls_vertex, o.ls_light_dir.w); - float3 lightColorSub4 = OmniDirectional_Shade4PointLights( - unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0, - 0 < o.ls_light_dir.w ? unity_LightColor[0].rgb : float3(0, 0, 0), - unity_LightColor[1].rgb, - unity_LightColor[2].rgb, - unity_LightColor[3].rgb, - unity_4LightAtten0, - mul(unity_ObjectToWorld, o.ls_vertex) - ); - float main = saturate(calcBrightness( lightColorMain )); - float sub4 = saturate(calcBrightness( lightColorSub4 )); - float ambient = saturate(calcBrightness( ambientColor )); - o.shadow_power = saturate( abs(main - sub4) / max(main + sub4, 0.0001) ) * 0.5 + 0.5; - o.shadow_power = min( o.shadow_power, 1 - smoothstep(0.8, 1, abs(o.ls_light_dir.y)) * 0.5 ); - o.shadow_power = min( o.shadow_power, 1 - saturate(ambient) * 0.5 ); - } - #endif - - // ライトカラーブレンド - { - float3 lightColorMain = _LightColor0.rgb; - float3 lightColorSub4 = OmniDirectional_Shade4PointLights( - unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0, - unity_LightColor[0].rgb, - unity_LightColor[1].rgb, - unity_LightColor[2].rgb, - unity_LightColor[3].rgb, - unity_4LightAtten0, - mul(unity_ObjectToWorld, o.ls_vertex) - ); - float3 color = max(lightColorMain + lightColorSub4 + ambientColor, float3(0.001, 0.001, 0.001)); - color = saturate( color / calcBrightness(color) ); - o.light_color = (color - 1) * _GL_BrendPower + 1; - } - o.normal = normalize(v.normal.xyz); - - SET_ANTIGLARE_LEVEL(v.vertex, o.light_power); -// ここまで UnToon と同じ - o.uv2 = TRANSFORM_TEX(v.uv, _FurNoiseTex); + float3 tangent = normalize(v.tangent.xyz); + float3 bitangent = cross(o.normal, tangent) * v.tangent.w; + float3x3 tangentTransform = float3x3(tangent, bitangent, o.normal); + o.waving = mul(_FurVector.xyz, tangentTransform); + return o; } @@ -143,12 +88,6 @@ UNITY_TRANSFER_VERTEX_OUTPUT_STEREO(g2f, o); o.uv = p.uv; o.ls_vertex = p.ls_vertex; - o.ls_light_dir = p.ls_light_dir; - o.light_color = p.light_color; - o.light_power = p.light_power; - #ifdef _TS_ENABLE - o.shadow_power = p.shadow_power; - #endif o.normal = p.normal; o.uv2 = p.uv2; return o; @@ -158,7 +97,6 @@ o.ls_vertex = lerp(vb, vu, height); o.vertex = UnityObjectToClipPos( o.ls_vertex ); o.height = height; - UNITY_TRANSFER_FOG(o, o.vertex); } inline v2g lerp_v2g(v2g x, v2g y, float div) { @@ -166,14 +104,9 @@ UNITY_INITIALIZE_OUTPUT(v2g, o); o.uv = lerp(x.uv, y.uv, div); o.ls_vertex = lerp(x.ls_vertex, y.ls_vertex, div); - o.ls_light_dir = lerp(x.ls_light_dir, y.ls_light_dir, div); - o.light_color = lerp(x.light_color, y.light_color, div); - o.light_power = lerp(x.light_power, y.light_power, div); - #ifdef _TS_ENABLE - o.shadow_power = lerp(x.shadow_power, y.shadow_power, div); - #endif o.normal = lerp(x.normal, y.normal, div); o.uv2 = lerp(x.uv2, y.uv2, div); + o.waving = lerp(x.waving, y.waving, div); return o; } @@ -182,7 +115,7 @@ float4 vu[3] = vb; { for (uint i = 0; i < 3; i++) { - vu[i].xyz += v[i].normal.xyz * _FurHeight; + vu[i].xyz += (v[i].normal.xyz + v[i].waving.xyz) * _FurHeight; } } { @@ -196,117 +129,60 @@ } } - [maxvertexcount(32)] + [maxvertexcount(64)] void geom_fakefur(triangle v2g v[3], inout TriangleStream triStream) { UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(v[0]); - float4 vb[3] = { v[0].ls_vertex, v[1].ls_vertex, v[2].ls_vertex }; - float4 vu[3] = vb; - { - for (uint i = 0; i < 3; i++) { - vu[i].xyz += v[i].normal.xyz * _FurHeight; - } - } - { - v2g c = lerp_v2g(v[0], lerp_v2g(v[1], v[2], 0.5), 2.0 / 3.0); - for (uint i = 0; i < _FurRepeat; i++) { - float rate = i / (float) _FurRepeat; - v2g v2[3] = { lerp_v2g(v[0], c, rate), lerp_v2g(v[1], c, rate), lerp_v2g(v[2], c, rate) }; - fakefur(v2, triStream); - } + v2g c = lerp_v2g(v[0], lerp_v2g(v[1], v[2], 0.5), 2.0 / 3.0); + for (uint i = 0; i < _FurRepeat; i++) { + float rate = i / (float) _FurRepeat; + v2g v2[3] = { lerp_v2g(v[0], c, rate), lerp_v2g(v[1], c, rate), lerp_v2g(v[2], c, rate) }; + fakefur(v2, triStream); } } - fixed4 frag_fakefur(g2f i) : SV_Target { - -// ここから UnToon と同じ + fixed4 frag_fakefur(g2f gi) : SV_Target { UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); + v2f i = (v2f) 0; + i.uv = gi.uv; + i.ls_vertex = gi.ls_vertex; + i.normal = gi.normal; + i.ls_light_dir = calcLocalSpaceLightDir( float4(0, 0, 0, i.ls_vertex.w) ); + + // 環境光取得 + float3 ambientColor = OmniDirectional_ShadeSH9(); + // 影コントラスト + calcToonShadeContrast(i.ls_vertex, i.ls_light_dir, ambientColor, i.shadow_power); + // Anti-Glare とライト色ブレンドを同時に計算 + i.light_color = calcLightColorVertex(i.ls_vertex, ambientColor); + // メイン float4 color = PICK_MAIN_TEX2D(_MainTex, i.uv) * _Color; // 色変換 affectColorChange(color); - // BumpMap - float3 ls_normal = i.normal; - float3 ls_bump_normal = i.normal; - - // ビュー空間法線 - float3 vs_normal = calcMatcapVector(i.ls_vertex, ls_normal); - float3 vs_bump_normal = calcMatcapVector(i.ls_vertex, ls_bump_normal); - - // Highlight - affectMatcapColor(lerp(vs_normal, vs_bump_normal, _HL_BlendNormal), i.uv, color); - // カメラとライトの位置関係: -1(逆光) ~ +1(順光) - float3 ws_light_dir = UnityObjectToWorldDir(i.ls_light_dir); // ワールド座標系にてangle_light_cameraを計算する(モデル回転には依存しない) - float3 ws_camera_dir = worldSpaceViewDir( float4(0, 0, 0, i.ls_vertex.w) ); - float angle_light_camera = dot( SafeNormalizeVec2(ws_light_dir.xz), SafeNormalizeVec2(ws_camera_dir.xz) ) - * (1 - smoothstep(0.9, 1, ws_light_dir.y)) * (1 - smoothstep(0.9, 1, ws_camera_dir.y)); - + float angle_light_camera = calcAngleLightCamera(i); // 階調影 - #ifdef _TS_ENABLE - if (TGL_ON(_TS_Enable)) { - float boostlight = 0.5 + 0.25 * SAMPLE_MASK_VALUE(_TS_MaskTex, i.uv, _TS_InvMaskVal).r; - float brightness = dot(lerp(ls_normal, ls_bump_normal, _TS_BlendNormal), i.ls_light_dir.xyz) * (1 - boostlight) + boostlight; - // ビュー相対位置シフト - brightness *= smoothstep(-1.01, -1.0 + (_TS_1stBorder + _TS_2ndBorder) / 2, angle_light_camera); - // 影色計算 - float3 base_color = NON_ZERO_VEC3( _TS_BaseColor.rgb * PICK_SUB_TEX2D(_TS_BaseTex, _MainTex, i.uv).rgb ); - float3 shadow_color_1st = _TS_1stColor.rgb * PICK_SUB_TEX2D(_TS_1stTex, _MainTex, i.uv).rgb / base_color.rgb; - float3 shadow_color_2nd = _TS_2ndColor.rgb * PICK_SUB_TEX2D(_TS_2ndTex, _MainTex, i.uv).rgb / base_color.rgb; - shadow_color_1st = lerp(float3(1, 1, 1), shadow_color_1st, i.shadow_power * _TS_Power * _TS_1stColor.a); - shadow_color_2nd = lerp(float3(1, 1, 1), shadow_color_2nd, i.shadow_power * _TS_Power * _TS_2ndColor.a); - // 色計算 - color.rgb *= saturate(lerp( - lerp(shadow_color_2nd, shadow_color_1st, smoothstep(_TS_2ndBorder - max(_TS_Feather, 0.001), _TS_2ndBorder, brightness) ), - float3(1, 1, 1), - smoothstep(_TS_1stBorder, _TS_1stBorder + max(_TS_Feather, 0.001), brightness))); - } - #endif - - // リムライト - #ifdef _TR_ENABLE - if (TGL_ON(_TR_Enable)) { - // vs_normalからリムライト範囲を計算 - float2 rim_uv = vs_normal.xy; - rim_uv.x *= _TR_PowerSide + 1; - rim_uv.y *= (_TR_PowerTop + _TR_PowerBottom) / 2 + 1; - rim_uv.y += (_TR_PowerTop - _TR_PowerBottom) / 2; - // 順光の場合はリムライトを暗くする - float3 rimPower = saturate(1 - angle_light_camera) * _TR_Color.a * SAMPLE_MASK_VALUE(_TR_MaskTex, i.uv, _TR_InvMaskVal).rgb; - // 色計算 - color.rgb = lerp(color.rgb, color.rgb + (_TR_Color.rgb - MEDIAN_GRAY) * rimPower, - smoothstep(1, 1.05, length(rim_uv)) ); - } - #endif + affectToonShade(i, i.normal, i.normal, angle_light_camera, color); - // ライトカラーブレンド - color.rgb *= i.light_color.rgb; - // Anti-Glare - affectAntiGlare(i.light_power, color); + // Anti-Glare とライト色ブレンドを同時に計算 + color.rgb *= i.light_color; // Alpha affectAlpha(i.uv, color); - - // EmissiveScroll - affectEmissiveScroll(i.ls_vertex, i.uv, color); - // Alpha は 0-1 にクランプ color.a = saturate(color.a); -// ここまで UnToon と同じ float4 maskTex = tex2D(_FurMaskTex, i.uv); - if (maskTex.r < 0.01 || maskTex.r <= i.height) { + if (maskTex.r < 0.01 || maskTex.r <= gi.height) { discard; } - float3 noise = tex2D(_FurNoiseTex, i.uv2).rgb; - color = saturate( float4( color - (1 - noise) * _FurShadowPower, calcBrightness(noise) - pow(i.height, 3)) ); - - // fog - UNITY_APPLY_FOG(i.fogCoord, color); + float3 noise = tex2D(_FurNoiseTex, gi.uv2).rgb; + color = saturate( float4( color - (1 - noise) * _FurShadowPower, calcBrightness(noise) - pow(gi.height, 3)) ); return color; } diff --git a/Shaders/WF_UnToon.cginc b/Shaders/WF_UnToon.cginc index a041478d..e717356c 100644 --- a/Shaders/WF_UnToon.cginc +++ b/Shaders/WF_UnToon.cginc @@ -20,7 +20,7 @@ /* * authors: - * ver:2019/06/26 whiteflare, + * ver:2019/07/13 whiteflare, */ #include "WF_Common.cginc" @@ -45,12 +45,18 @@ #define SAMPLE_MASK_VALUE(tex, uv, inv) saturate( TGL_OFF(inv) ? PICK_SUB_TEX2D(tex, _MainTex, uv).rgb : 1 - PICK_SUB_TEX2D(tex, _MainTex, uv).rgb ) #define SAMPLE_MASK_VALUE_LOD(tex, uv, inv) saturate( TGL_OFF(inv) ? tex2Dlod(tex, float4(uv.x, uv.y, 0, 0)).rgb : 1 - tex2Dlod(tex, float4(uv.x, uv.y, 0, 0)).rgb ) - #define NON_ZERO_VEC3(v) max(v, float3(0.00390625, 0.00390625, 0.00390625)) + #define NZF 0.00390625 + #define NON_ZERO_FLOAT(v) max(v, NZF) + #define NON_ZERO_VEC3(v) max(v, float3(NZF, NZF, NZF)) #if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON) #define _LMAP_ENABLE #endif + //////////////////////////// + // main structure + //////////////////////////// + struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; @@ -90,6 +96,10 @@ float _AL_CutOff; float _GL_BrendPower; + //////////////////////////// + // Normal Map + //////////////////////////// + #ifdef _NM_ENABLE float _NM_Enable; // 1st NormalMap @@ -103,8 +113,44 @@ float _DetailNormalMapScale; DECL_SUB_TEX2D(_NM_2ndMaskTex); float _NM_InvMaskVal; + + inline void affectBumpNormal(v2f i, out float3 ls_bump_normal, inout float4 color) { + float3 ls_normal = i.normal; + if (TGL_ON(_NM_Enable)) { + // 1st NormalMap + float3 normalTangent = UnpackScaleNormal( PICK_SUB_TEX2D(_BumpMap, _MainTex, i.uv), _BumpScale ); + + // 2nd NormalMap + if (_NM_2ndType == 1) { // BLEND + float dtlPower = SAMPLE_MASK_VALUE(_NM_2ndMaskTex, i.uv, _NM_InvMaskVal); + float3 dtlNormalTangent = UnpackScaleNormal( PICK_MAIN_TEX2D(_DetailNormalMap, i.uv_dtl), _DetailNormalMapScale); + normalTangent = lerp(normalTangent, BlendNormals(normalTangent, dtlNormalTangent), dtlPower); + } + else if (_NM_2ndType == 2) { // SWITCH + float dtlPower = SAMPLE_MASK_VALUE(_NM_2ndMaskTex, i.uv, _NM_InvMaskVal); + float3 dtlNormalTangent = UnpackScaleNormal( PICK_MAIN_TEX2D(_DetailNormalMap, i.uv_dtl), _DetailNormalMapScale); + normalTangent = lerp(normalTangent, dtlNormalTangent, dtlPower); + } + + // 法線計算 + float3x3 tangentTransform = float3x3(i.tangent, i.bitangent, i.normal); // vertex周辺のlocal法線空間 + ls_bump_normal = mul( normalTangent, tangentTransform); + // NormalMap は陰影として描画する(ls_bump_normal自体は後でも使う) + // 影側を暗くしすぎないために、ls_normal と ls_bump_normal の差を加算することで明暗を付ける + color.rgb += (dot(ls_bump_normal, i.ls_light_dir.xyz) - dot(ls_normal, i.ls_light_dir.xyz)) * _NM_Power; + } + else { + ls_bump_normal = ls_normal; + } + } + #else + #define affectBumpNormal(i, ls_bump_normal, color) ls_bump_normal = i.normal #endif + //////////////////////////// + // Metallic + //////////////////////////// + #ifdef _MT_ENABLE float _MT_Enable; float _MT_Metallic; @@ -162,8 +208,85 @@ return specular; } + inline void affectMetallic(v2f i, float3 ls_normal, float3 ls_bump_normal, inout float4 color) { + if (TGL_ON(_MT_Enable)) { + float3 ls_metal_normal = lerp(ls_normal, ls_bump_normal, _MT_BlendNormal); + float power = _MT_Metallic * SAMPLE_MASK_VALUE(_MT_MaskTex, i.uv, _MT_InvMaskVal); + if (0.01 < power) { + // リフレクション + float metal_lod = (1 - _MT_Smoothness) * 10; + float3 reflection; + if (_MT_CubemapType == 1) { // ADDITION + reflection + = pickReflectionProbe(i.ls_vertex, ls_metal_normal, metal_lod) + + pickReflectionCubemap(_MT_Cubemap, _MT_Cubemap_HDR, i.ls_vertex, ls_metal_normal, metal_lod); + } + else if (_MT_CubemapType == 2) { // ONLY_SECOND_MAP + reflection + = pickReflectionCubemap(_MT_Cubemap, _MT_Cubemap_HDR, i.ls_vertex, ls_metal_normal, metal_lod); + } + else { // OFF + reflection + = pickReflectionProbe(i.ls_vertex, ls_metal_normal, metal_lod); + } + if (TGL_ON(_MT_Monochrome)) { + reflection = calcBrightness(reflection); + } + // スペキュラ + float3 specular = float3(0, 0, 0); + if (TGL_ON(_MT_Specular)) { + specular = pickSpecular(i.ls_vertex, ls_metal_normal, _MT_Smoothness); + } + color.rgb = lerp(color.rgb, + lerp(color.rgb * reflection.rgb, color.rgb + reflection.rgb, _MT_BlendType) + specular.rgb, + power); + } + } + } + #else + #define affectMetallic(i, ls_normal, ls_bump_normal, color) #endif + //////////////////////////// + // Light Matcap + //////////////////////////// + + #ifdef _HL_ENABLE + float _HL_Enable; + int _HL_CapType; + sampler2D _HL_MatcapTex; // MainTexと大きく構造が異なるので独自のサンプラーを使う + float3 _HL_MatcapColor; + float _HL_Power; + float _HL_BlendNormal; + DECL_SUB_TEX2D(_HL_MaskTex); + float _HL_InvMaskVal; + + #define _HL_Range 1 + + inline void affectMatcapColor(float2 matcapVector, float2 mask_uv, inout float4 color) { + if (TGL_ON(_HL_Enable)) { + // matcap サンプリング + float2 matcap_uv = matcapVector.xy * 0.5 * _HL_Range + 0.5; + float3 matcap_color = tex2D(_HL_MatcapTex, saturate(matcap_uv)).rgb; + // maskcolor 決定 + float3 matcap_mask = SAMPLE_MASK_VALUE(_HL_MaskTex, mask_uv, _HL_InvMaskVal).rgb; + float3 lightcap_power = saturate(matcap_mask * _HL_MatcapColor * 2); // _HL_MatcapColorは灰色を基準とするので2倍する + float3 shadecap_power = (1 - lightcap_power) * MAX3(matcap_mask.r, matcap_mask.g, matcap_mask.b); + // 合成 + float3 median_color = _HL_CapType == 0 ? MEDIAN_GRAY : float3(0, 0, 0); + float3 lightcap_color = saturate( (matcap_color - median_color) * lightcap_power ); + float3 shadecap_color = saturate( (median_color - matcap_color) * shadecap_power ); + color.rgb += (lightcap_color - shadecap_color) * _HL_Power; + } + } + #else + #define affectMatcapColor(matcapVector, mask_uv, color) + #endif + + //////////////////////////// + // ToonShade + //////////////////////////// + #ifdef _TS_ENABLE float _TS_Enable; float4 _TS_BaseColor; @@ -179,8 +302,58 @@ float _TS_BlendNormal; DECL_SUB_TEX2D(_TS_MaskTex); float _TS_InvMaskVal; + + inline void calcToonShadeContrast(float4 ls_vertex, float4 ls_light_dir, float3 ambientColor, out float shadow_power) { + if (TGL_ON(_TS_Enable)) { + float3 lightColorMain = calcLocalSpaceLightColor(ls_vertex, ls_light_dir.w); + float3 lightColorSub4 = OmniDirectional_Shade4PointLights( + unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0, + 0 < ls_light_dir.w ? unity_LightColor[0].rgb : float3(0, 0, 0), + unity_LightColor[1].rgb, + unity_LightColor[2].rgb, + unity_LightColor[3].rgb, + unity_4LightAtten0, + mul(unity_ObjectToWorld, ls_vertex) + ); + float main = saturate(calcBrightness( lightColorMain )); + float sub4 = saturate(calcBrightness( lightColorSub4 )); + float ambient = saturate(calcBrightness( ambientColor )); + shadow_power = saturate( abs(main - sub4) / max(main + sub4, 0.0001) ) * 0.5 + 0.5; + shadow_power = min( shadow_power, 1 - smoothstep(0.8, 1, abs(ls_light_dir.y)) * 0.5 ); + shadow_power = min( shadow_power, 1 - saturate(ambient) * 0.5 ); + } else { + shadow_power = 0; + } + } + + inline void affectToonShade(v2f i, float3 ls_normal, float3 ls_bump_normal, float angle_light_camera, inout float4 color) { + if (TGL_ON(_TS_Enable)) { + float boostlight = 0.5 + 0.25 * SAMPLE_MASK_VALUE(_TS_MaskTex, i.uv, _TS_InvMaskVal).r; + float brightness = dot(lerp(ls_normal, ls_bump_normal, _TS_BlendNormal), i.ls_light_dir.xyz) * (1 - boostlight) + boostlight; + // ビュー相対位置シフト + brightness *= smoothstep(-1.01, -1.0 + (_TS_1stBorder + _TS_2ndBorder) / 2, angle_light_camera); + // 影色計算 + float3 base_color = NON_ZERO_VEC3( _TS_BaseColor.rgb * PICK_SUB_TEX2D(_TS_BaseTex, _MainTex, i.uv).rgb ); + float3 shadow_color_1st = _TS_1stColor.rgb * PICK_SUB_TEX2D(_TS_1stTex, _MainTex, i.uv).rgb / base_color.rgb; + float3 shadow_color_2nd = _TS_2ndColor.rgb * PICK_SUB_TEX2D(_TS_2ndTex, _MainTex, i.uv).rgb / base_color.rgb; + shadow_color_1st = lerp(float3(1, 1, 1), shadow_color_1st, i.shadow_power * _TS_Power * _TS_1stColor.a); + shadow_color_2nd = lerp(float3(1, 1, 1), shadow_color_2nd, i.shadow_power * _TS_Power * _TS_2ndColor.a); + // 色計算 + color.rgb *= saturate(lerp( + lerp(shadow_color_2nd, shadow_color_1st, smoothstep(_TS_2ndBorder - max(_TS_Feather, 0.001), _TS_2ndBorder, brightness) ), + float3(1, 1, 1), + smoothstep(_TS_1stBorder, _TS_1stBorder + max(_TS_Feather, 0.001), brightness))); + } + } + #else + #define calcToonShadeContrast(ls_vertex, ls_light_dir, ambientColor, shadow_power) + #define affectToonShade(i, ls_normal, ls_bump_normal, angle_light_camera, color) #endif + //////////////////////////// + // Rim Light + //////////////////////////// + #ifdef _TR_ENABLE float _TR_Enable; float4 _TR_Color; @@ -189,8 +362,29 @@ float _TR_PowerBottom; DECL_SUB_TEX2D(_TR_MaskTex); float _TR_InvMaskVal; + + inline void affectRimLight(v2f i, float3 vs_normal, float angle_light_camera, inout float4 color) { + if (TGL_ON(_TR_Enable)) { + // vs_normalからリムライト範囲を計算 + float2 rim_uv = vs_normal.xy; + rim_uv.x *= _TR_PowerSide + 1; + rim_uv.y *= (_TR_PowerTop + _TR_PowerBottom) / 2 + 1; + rim_uv.y += (_TR_PowerTop - _TR_PowerBottom) / 2; + // 順光の場合はリムライトを暗くする + float3 rimPower = saturate(1 - angle_light_camera) * _TR_Color.a * SAMPLE_MASK_VALUE(_TR_MaskTex, i.uv, _TR_InvMaskVal).rgb; + // 色計算 + color.rgb = lerp(color.rgb, color.rgb + (_TR_Color.rgb - MEDIAN_GRAY) * rimPower, + smoothstep(1, 1.05, length(rim_uv)) ); + } + } + #else + #define affectRimLight(i, vs_normal, angle_light_camera, color) #endif + //////////////////////////// + // Outline + //////////////////////////// + #ifdef _TL_ENABLE float _TL_Enable; float4 _TL_LineColor; @@ -198,44 +392,40 @@ sampler2D _TL_MaskTex; // vert内で取得するので独自のサンプラーを使う float _TL_InvMaskVal; float _TL_Z_Shift; - #endif - - #ifdef _HL_ENABLE - float _HL_Enable; - int _HL_CapType; - sampler2D _HL_MatcapTex; // MainTexと大きく構造が異なるので独自のサンプラーを使う - float3 _HL_MatcapColor; - float _HL_Power; - float _HL_BlendNormal; - DECL_SUB_TEX2D(_HL_MaskTex); - float _HL_InvMaskVal; - - #define _HL_Range 1 - inline void affectMatcapColor(float2 matcapVector, float2 mask_uv, inout float4 color) { - if (TGL_ON(_HL_Enable)) { - // matcap サンプリング - float2 matcap_uv = matcapVector.xy * 0.5 * _HL_Range + 0.5; - float3 matcap_color = tex2D(_HL_MatcapTex, saturate(matcap_uv)).rgb; - // maskcolor 決定 - float3 matcap_mask = SAMPLE_MASK_VALUE(_HL_MaskTex, mask_uv, _HL_InvMaskVal).rgb; - float3 lightcap_power = saturate(matcap_mask * _HL_MatcapColor * 2); // _HL_MatcapColorは灰色を基準とするので2倍する - float3 shadecap_power = (1 - lightcap_power) * MAX3(matcap_mask.r, matcap_mask.g, matcap_mask.b); - // 合成 - float3 median_color = _HL_CapType == 0 ? MEDIAN_GRAY : float3(0, 0, 0); - float3 lightcap_color = saturate( (matcap_color - median_color) * lightcap_power ); - float3 shadecap_color = saturate( (median_color - matcap_color) * shadecap_power ); - color.rgb += (lightcap_color - shadecap_color) * _HL_Power; + inline void affectOutline(inout float4 color) { + if (TGL_ON(_TL_Enable)) { + // アウトライン色をベースと合成 + color.rgb = lerp(color.rgb, _TL_LineColor.rgb, _TL_LineColor.a); } } - #else - - #define affectMatcapColor(matcapVector, mask_uv, color) - + #define affectOutline(color) #endif - float3 pickLightmapLod(float2 uv_lmap, float3 ls_normal) { + //////////////////////////// + // common function + //////////////////////////// + + inline float3 calcLightColorVertex(float4 ls_vertex, float3 ambientColor) { + float3 lightColorMain = _LightColor0.rgb; + float3 lightColorSub4 = OmniDirectional_Shade4PointLights( + unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0, + unity_LightColor[0].rgb, + unity_LightColor[1].rgb, + unity_LightColor[2].rgb, + unity_LightColor[3].rgb, + unity_4LightAtten0, + mul(unity_ObjectToWorld, ls_vertex) + ); + float3 color = lightColorMain + lightColorSub4 + ambientColor; + float power = calcBrightness(color); + float3 light_color = (saturate( NON_ZERO_VEC3(color) / NON_ZERO_FLOAT(power) ) - 1) * _GL_BrendPower + 1; + light_color *= saturate( power * 2 + (100 - _GL_Level) * 0.01 ); + return light_color; + } + + inline float3 pickLightmapLod(float2 uv_lmap, float3 ls_normal) { float3 color = float3(0, 0, 0); float3 ws_normal = UnityObjectToWorldNormal(ls_normal); #ifdef LIGHTMAP_ON @@ -267,6 +457,28 @@ return color; } + inline float calcAngleLightCamera(v2f i) { + // カメラとライトの位置関係: -1(逆光) ~ +1(順光) + float3 ws_light_dir = UnityObjectToWorldDir(i.ls_light_dir); // ワールド座標系にてangle_light_cameraを計算する(モデル回転には依存しない) + float3 ws_camera_dir = worldSpaceViewDir( float4(0, 0, 0, i.ls_vertex.w) ); + float angle_light_camera = dot( SafeNormalizeVec2(ws_light_dir.xz), SafeNormalizeVec2(ws_camera_dir.xz) ) + * (1 - smoothstep(0.9, 1, ws_light_dir.y)) * (1 - smoothstep(0.9, 1, ws_camera_dir.y)); + if (isInMirror()) { + angle_light_camera = 0; // 鏡の中のときは、視差問題が生じないように強制的に 0 にする + } + return angle_light_camera; + } + + #ifdef _LMAP_ENABLE + #define WF_GET_AMBIENT pickLightmapLod(v.uv_lmap, o.normal) + #else + #define WF_GET_AMBIENT OmniDirectional_ShadeSH9() + #endif + + //////////////////////////// + // vertex&fragment shader + //////////////////////////// + v2f vert(in appdata v, out float4 vertex : SV_POSITION) { v2f o; @@ -287,52 +499,12 @@ o.uv_dtl = TRANSFORM_TEX(v.uv, _DetailNormalMap); #endif - float3 ambientColor = - #ifdef _LMAP_ENABLE - pickLightmapLod(v.uv_lmap, o.normal); - #else - OmniDirectional_ShadeSH9(); - #endif - + // 環境光取得 + float3 ambientColor = WF_GET_AMBIENT; // 影コントラスト - #ifdef _TS_ENABLE - if (TGL_ON(_TS_Enable)) { - float3 lightColorMain = calcLocalSpaceLightColor(o.ls_vertex, o.ls_light_dir.w); - float3 lightColorSub4 = OmniDirectional_Shade4PointLights( - unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0, - 0 < o.ls_light_dir.w ? unity_LightColor[0].rgb : float3(0, 0, 0), - unity_LightColor[1].rgb, - unity_LightColor[2].rgb, - unity_LightColor[3].rgb, - unity_4LightAtten0, - mul(unity_ObjectToWorld, o.ls_vertex) - ); - float main = saturate(calcBrightness( lightColorMain )); - float sub4 = saturate(calcBrightness( lightColorSub4 )); - float ambient = saturate(calcBrightness( ambientColor )); - o.shadow_power = saturate( abs(main - sub4) / max(main + sub4, 0.0001) ) * 0.5 + 0.5; - o.shadow_power = min( o.shadow_power, 1 - smoothstep(0.8, 1, abs(o.ls_light_dir.y)) * 0.5 ); - o.shadow_power = min( o.shadow_power, 1 - saturate(ambient) * 0.5 ); - } - #endif - + calcToonShadeContrast(o.ls_vertex, o.ls_light_dir, ambientColor, o.shadow_power); // Anti-Glare とライト色ブレンドを同時に計算 - { - float3 lightColorMain = _LightColor0.rgb; - float3 lightColorSub4 = OmniDirectional_Shade4PointLights( - unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0, - unity_LightColor[0].rgb, - unity_LightColor[1].rgb, - unity_LightColor[2].rgb, - unity_LightColor[3].rgb, - unity_4LightAtten0, - mul(unity_ObjectToWorld, o.ls_vertex) - ); - float3 color = lightColorMain + lightColorSub4 + ambientColor; - float power = calcBrightness(color); - o.light_color = (saturate( color / max(0.001, power) ) - 1) * _GL_BrendPower + 1; - o.light_color *= saturate( power * 2 + (100 - _GL_Level) * 0.01 ); - } + o.light_color = calcLightColorVertex(o.ls_vertex, ambientColor); UNITY_TRANSFER_INSTANCE_ID(v, o); UNITY_TRANSFER_FOG(o, vertex); @@ -348,143 +520,33 @@ // 色変換 affectColorChange(color); - // BumpMap float3 ls_normal = i.normal; - float3 ls_bump_normal = i.normal; - - #ifdef _NM_ENABLE - if (TGL_ON(_NM_Enable)) { - // 1st NormalMap - float3 normalTangent = UnpackScaleNormal( PICK_SUB_TEX2D(_BumpMap, _MainTex, i.uv), _BumpScale ); - - // 2nd NormalMap - if (_NM_2ndType == 1) { // BLEND - float dtlPower = SAMPLE_MASK_VALUE(_NM_2ndMaskTex, i.uv, _NM_InvMaskVal); - float3 dtlNormalTangent = UnpackScaleNormal( PICK_MAIN_TEX2D(_DetailNormalMap, i.uv_dtl), _DetailNormalMapScale); - normalTangent = lerp(normalTangent, BlendNormals(normalTangent, dtlNormalTangent), dtlPower); - } - else if (_NM_2ndType == 2) { // SWITCH - float dtlPower = SAMPLE_MASK_VALUE(_NM_2ndMaskTex, i.uv, _NM_InvMaskVal); - float3 dtlNormalTangent = UnpackScaleNormal( PICK_MAIN_TEX2D(_DetailNormalMap, i.uv_dtl), _DetailNormalMapScale); - normalTangent = lerp(normalTangent, dtlNormalTangent, dtlPower); - } - - // 法線計算 - float3x3 tangentTransform = float3x3(i.tangent, i.bitangent, i.normal); // vertex周辺のlocal法線空間 - ls_bump_normal = mul( normalTangent, tangentTransform); - // NormalMap は陰影として描画する(ls_bump_normal自体は後でも使う) - // 影側を暗くしすぎないために、ls_normal と ls_bump_normal の差を加算することで明暗を付ける - color.rgb += (dot(ls_bump_normal, i.ls_light_dir.xyz) - dot(ls_normal, i.ls_light_dir.xyz)) * _NM_Power; - } - #endif - - // メタリック - #ifdef _MT_ENABLE - if (TGL_ON(_MT_Enable)) { - float3 ls_metal_normal = lerp(ls_normal, ls_bump_normal, _MT_BlendNormal); - float power = _MT_Metallic * SAMPLE_MASK_VALUE(_MT_MaskTex, i.uv, _MT_InvMaskVal); - if (0.01 < power) { - // リフレクション - float metal_lod = (1 - _MT_Smoothness) * 10; - float3 reflection; - if (_MT_CubemapType == 1) { // ADDITION - reflection - = pickReflectionProbe(i.ls_vertex, ls_metal_normal, metal_lod) - + pickReflectionCubemap(_MT_Cubemap, _MT_Cubemap_HDR, i.ls_vertex, ls_metal_normal, metal_lod); - } - else if (_MT_CubemapType == 2) { // ONLY_SECOND_MAP - reflection - = pickReflectionCubemap(_MT_Cubemap, _MT_Cubemap_HDR, i.ls_vertex, ls_metal_normal, metal_lod); - } - else { // OFF - reflection - = pickReflectionProbe(i.ls_vertex, ls_metal_normal, metal_lod); - } - if (TGL_ON(_MT_Monochrome)) { - reflection = calcBrightness(reflection); - } - // スペキュラ - float3 specular = float3(0, 0, 0); - if (TGL_ON(_MT_Specular)) { - specular = pickSpecular(i.ls_vertex, ls_metal_normal, _MT_Smoothness); - } - color.rgb = lerp(color.rgb, - lerp(color.rgb * reflection.rgb, color.rgb + reflection.rgb, _MT_BlendType) + specular.rgb, - power); - } - } - #endif + float3 ls_bump_normal; + affectBumpNormal(i, ls_bump_normal, color); // ビュー空間法線 float3 vs_normal = calcMatcapVector(i.ls_vertex, ls_normal); float3 vs_bump_normal = calcMatcapVector(i.ls_vertex, ls_bump_normal); + // カメラとライトの位置関係: -1(逆光) ~ +1(順光) + float angle_light_camera = calcAngleLightCamera(i); + // メタリック + affectMetallic(i, ls_normal, ls_bump_normal, color); // Highlight affectMatcapColor(lerp(vs_normal, vs_bump_normal, _HL_BlendNormal), i.uv, color); - - // カメラとライトの位置関係: -1(逆光) ~ +1(順光) - float3 ws_light_dir = UnityObjectToWorldDir(i.ls_light_dir); // ワールド座標系にてangle_light_cameraを計算する(モデル回転には依存しない) - float3 ws_camera_dir = worldSpaceViewDir( float4(0, 0, 0, i.ls_vertex.w) ); - float angle_light_camera = dot( SafeNormalizeVec2(ws_light_dir.xz), SafeNormalizeVec2(ws_camera_dir.xz) ) - * (1 - smoothstep(0.9, 1, ws_light_dir.y)) * (1 - smoothstep(0.9, 1, ws_camera_dir.y)); - #ifdef USING_STEREO_MATRICES - if (isInMirror()) { - angle_light_camera = 0; // 両目かつ鏡の中のときは、視差問題が生じないように強制的に 0 にする - } - #endif - // 階調影 - #ifdef _TS_ENABLE - if (TGL_ON(_TS_Enable)) { - float boostlight = 0.5 + 0.25 * SAMPLE_MASK_VALUE(_TS_MaskTex, i.uv, _TS_InvMaskVal).r; - float brightness = dot(lerp(ls_normal, ls_bump_normal, _TS_BlendNormal), i.ls_light_dir.xyz) * (1 - boostlight) + boostlight; - // ビュー相対位置シフト - brightness *= smoothstep(-1.01, -1.0 + (_TS_1stBorder + _TS_2ndBorder) / 2, angle_light_camera); - // 影色計算 - float3 base_color = NON_ZERO_VEC3( _TS_BaseColor.rgb * PICK_SUB_TEX2D(_TS_BaseTex, _MainTex, i.uv).rgb ); - float3 shadow_color_1st = _TS_1stColor.rgb * PICK_SUB_TEX2D(_TS_1stTex, _MainTex, i.uv).rgb / base_color.rgb; - float3 shadow_color_2nd = _TS_2ndColor.rgb * PICK_SUB_TEX2D(_TS_2ndTex, _MainTex, i.uv).rgb / base_color.rgb; - shadow_color_1st = lerp(float3(1, 1, 1), shadow_color_1st, i.shadow_power * _TS_Power * _TS_1stColor.a); - shadow_color_2nd = lerp(float3(1, 1, 1), shadow_color_2nd, i.shadow_power * _TS_Power * _TS_2ndColor.a); - // 色計算 - color.rgb *= saturate(lerp( - lerp(shadow_color_2nd, shadow_color_1st, smoothstep(_TS_2ndBorder - max(_TS_Feather, 0.001), _TS_2ndBorder, brightness) ), - float3(1, 1, 1), - smoothstep(_TS_1stBorder, _TS_1stBorder + max(_TS_Feather, 0.001), brightness))); - } - #endif - + affectToonShade(i, ls_normal, ls_bump_normal, angle_light_camera, color); // リムライト - #ifdef _TR_ENABLE - if (TGL_ON(_TR_Enable)) { - // vs_normalからリムライト範囲を計算 - float2 rim_uv = vs_normal.xy; - rim_uv.x *= _TR_PowerSide + 1; - rim_uv.y *= (_TR_PowerTop + _TR_PowerBottom) / 2 + 1; - rim_uv.y += (_TR_PowerTop - _TR_PowerBottom) / 2; - // 順光の場合はリムライトを暗くする - float3 rimPower = saturate(1 - angle_light_camera) * _TR_Color.a * SAMPLE_MASK_VALUE(_TR_MaskTex, i.uv, _TR_InvMaskVal).rgb; - // 色計算 - color.rgb = lerp(color.rgb, color.rgb + (_TR_Color.rgb - MEDIAN_GRAY) * rimPower, - smoothstep(1, 1.05, length(rim_uv)) ); - } - #endif - + affectRimLight(i, vs_normal, angle_light_camera, color); // Outline - #ifdef _TL_ENABLE - if (TGL_ON(_TL_Enable)) { - // アウトライン色をベースと合成 - color.rgb = lerp(color.rgb, _TL_LineColor.rgb, _TL_LineColor.a); - } - #endif + affectOutline(color); // Anti-Glare とライト色ブレンドを同時に計算 color.rgb *= i.light_color; // Alpha - affectAlpha(i.uv, color); - + affectAlphaWithFresnel(i.uv, ls_normal, localSpaceViewDir(i.ls_vertex), color); // EmissiveScroll affectEmissiveScroll(i.ls_vertex, i.uv, color); @@ -497,6 +559,10 @@ return color; } + //////////////////////////// + // カットアウト用 fragment shader + //////////////////////////// + float4 frag_cutout_upper(v2f i) : SV_Target { float4 color = frag(i); clip(color.a - _AL_CutOff); @@ -509,14 +575,15 @@ return color; } - // アウトライン用 + //////////////////////////// + // アウトライン用 vertex&fragment shader + //////////////////////////// v2f vert_outline(appdata v, out float4 vertex : SV_POSITION) { // 通常の vert を使う v2f o = vert(v, vertex); // SV_POSITION を上書き - #ifdef _TL_ENABLE if (TGL_ON(_TL_Enable)) { // マスクテクスチャ参照 @@ -539,14 +606,14 @@ } else { vertex = UnityObjectToClipPos( float3(0, 0, 0) ); } - #else - vertex = UnityObjectToClipPos( float3(0, 0, 0) ); #endif return o; } - // アウトラインキャンセラパス + //////////////////////////// + // アウトラインキャンセラ用 vertex&fragment shader + //////////////////////////// sampler2D _UnToonTransparentOutlineCanceller; @@ -567,7 +634,9 @@ return tex2Dproj(_UnToonTransparentOutlineCanceller, UNITY_PROJ_COORD(i.uv_grab)); } - // EmissiveScroll専用パス + //////////////////////////// + // EmissiveScroll専用パス用 vertex&fragment shader + //////////////////////////// float _ES_Z_Shift; diff --git a/Shaders/WF_UnToon_Tessellation.cginc b/Shaders/WF_UnToon_Tessellation.cginc index 4da5d0bd..18c51219 100644 --- a/Shaders/WF_UnToon_Tessellation.cginc +++ b/Shaders/WF_UnToon_Tessellation.cginc @@ -20,7 +20,7 @@ /* * authors: - * ver:2019/06/26 whiteflare, + * ver:2019/07/13 whiteflare, */ #include "WF_UnToon.cginc" @@ -36,7 +36,7 @@ float _TessFactor; float _Smoothing; - sampler2D _DispMap; // vert内で取得するので独自のサンプラーを使う + sampler2D _DispMap; // vert内で取得するので独自のサンプラーを使う float _DispMapScale; float _DispMapLevel; @@ -82,9 +82,9 @@ } o.ls_vertex.xyz += MUL_BARY(phg, xyz) * _Smoothing / 2.0; - // Displacement HeightMap - float disp = SAMPLE_MASK_VALUE_LOD(_DispMap, float4(o.uv, 0, 0), 0).r * _DispMapScale - _DispMapLevel; - o.ls_vertex.xyz += o.normal * disp * 0.01; + // Displacement HeightMap + float disp = SAMPLE_MASK_VALUE_LOD(_DispMap, float4(o.uv, 0, 0), 0).r * _DispMapScale - _DispMapLevel; + o.ls_vertex.xyz += o.normal * disp * 0.01; #undef MUL_BARY diff --git a/__UnityPackage/Unlit_WF_ShaderSuite_20190713.unitypackage b/__UnityPackage/Unlit_WF_ShaderSuite_20190713.unitypackage new file mode 100644 index 00000000..7596003c Binary files /dev/null and b/__UnityPackage/Unlit_WF_ShaderSuite_20190713.unitypackage differ diff --git a/__UnityPackage/Unlit_WF_ShaderSuite_20190713.unitypackage.meta b/__UnityPackage/Unlit_WF_ShaderSuite_20190713.unitypackage.meta new file mode 100644 index 00000000..5e05325d --- /dev/null +++ b/__UnityPackage/Unlit_WF_ShaderSuite_20190713.unitypackage.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 8b91fbee76aaac249a61c02c2b541f0b +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: