My code is a bit of a mess, but here.
/* SUPER SMASH BROS. FEUD - COMMON FIGHTER SHADER
* Is able to transition from default materials to metal or inked materials, and back. Masking transition effect adapted from code by SMG (ScandinavianMountainGoat), co-creator of open-source
* SSB Ultimate render library CrossMod. Written 2018-2019 by Ploaj and SMG, implemented in Unity surface shader Cg/HLSL format by Tabuu Forte Akugun. It supports composite PRM maps
*(Metallic/Roughness/Ambient Occlusion/Specularity) and composite NOR maps complete with generated Z+, noise maps and cavity textures.
*/
Shader "Super Smash Bros. Feud/Pseudo-HBSS Shader (For Stage Materials)"
{
Properties
{
[Toggle(USE_VERT_RGB)] _UseVertRGB("Use Vertex Colors?", Float) = 0
[Toggle(USE_VERT_ALPHA)]_VertAlpha("Use vertex color alpha?", Float) = 0
_Color("Main Color", Color) = (1.0,1.0,1.0,1.0)
_RimLightColor("Rim light color", Color) = (0.6,0.6,0.6,1.0)
_MainTex("Base Color Map (RGB+A)", 2D) = "white" {}
[Toggle(USE_TEX_ALPHA)]_TexAlpha("Use *.col alpha?", Float) = 0
[NoScaleOffset]_NormalMap("Normal Map (*_nor)", 2D) = "bump" {}
[Toggle(USE_PRM_MAP)]_UsePrm("Use a PRM Map?", Float) = 0
[NoScaleOffset]_PRMMap("PBR (PRM) Combined Map (*_prm)", 2D) = "white" {}
[Toggle(SKIN_MAT)]_SkinMat("Skin Map with SSS?", Float) = 0
_CustomVector30("Subsurface effect intensity", Vector) = (0,0,0,0)
_CustomVector11("Subsurface Scattering color for skin", Color) = (1,1,1,1)
[HideInInspector]_DefaultVertClr("", Color) = (0.5,0.5,0.5,1)
[Toggle(USE_EMISSIVE)]_EmissionMap("Check if using Emissive Texture.", Float) = 0
[NoScaleOffset]_EmiMap("Emissive Texture (*_emi)", 2D) = "black" {}
_FlashColor("Flash Color", Color) = (0,0,0,1)
_Cutoff("Alpha Cutoff", Range(0.01,1)) = 0.5
}
CGINCLUDE
#define UNITY_SETUP_BRDF_INPUT RoughnessSetup
ENDCG
SubShader
{
Tags { "Queue" = "AlphaTest" "RenderType" = "TransparentCutout" "IgnoreProjector" = "True"}
LOD 200
Pass
{
ColorMask 0
Lighting Off
ZWrite On
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f
{
float4 vertex : SV_POSITION;
float2 texcoord : TEXCOORD0;
};
sampler2D _MainTex;
fixed _Cutoff;
v2f vert(appdata_img v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.texcoord = v.texcoord;
return o;
}
fixed4 frag(v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.texcoord);
clip(col.a - _Cutoff);
return 0;
}
ENDCG
}
Pass
{
Tags {"LightMode" = "ShadowCaster"}
ColorMask 0
ZWrite On
Cull Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_shadowcaster
#include "UnityCG.cginc"
struct v2f
{
V2F_SHADOW_CASTER;
float2 texcoord : TEXCOORD1;
};
v2f vert(appdata_base v)
{
#if defined(PIXELSNAP_ON)
v.vertex = UnityPixelSnap(v.vertex);
#endif
v2f o;
TRANSFER_SHADOW_CASTER_NORMALOFFSET(o)
o.texcoord = v.texcoord;
return o;
}
sampler2D _MainTex;
fixed _Cutoff;
float4 frag(v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.texcoord);
clip(col.a - _Cutoff);
SHADOW_CASTER_FRAGMENT(i)
}
ENDCG
}
ColorMask 0
LOD 300
ZWrite On
// paste in forward rendering passes from Transparent/Diffuse
UsePass "Transparent/Diffuse/FORWARD"
CGPROGRAM
#include "UnityCG.cginc"
#include "UnityPBSLighting.cginc"
#pragma surface surf Standard vertex:vert fullforwardshadows decal:blend exclude_path:prepass
#pragma multi_compile _ PIXELSNAP_ON
#pragma shader_feature SKIN_MAT
#pragma shader_feature USE_VERT_RGB
#pragma shader_feature USE_TEX_ALPHA
#pragma shader_feature USE_PRM_MAP
#pragma shader_feature USE_CAV_MAP
#pragma shader_feature USE_EMISSIVE
#pragma shader_feature USE_VERT_ALPHA
#pragma target 3.0
sampler2D _MainTex;
sampler2D _InkTex;
sampler2D _NormalMap;
sampler2D _PRMMap;
sampler2D _SplatMap;
sampler2D _EmiMap;
sampler2D _InkBump;
sampler2D _MetalMap;
float4 _InkColor;
float4 _Color;
float4 _RimLightColor;
fixed _Cutoff;
struct Input
{
float2 uv_MainTex;
float3 worldRefl;
float3 viewDir;
float3 worldPos;
float4 vertexColor : COLOR;
INTERNAL_DATA
};
fixed4 _CustomVector11;
fixed4 _FlashColor;
fixed4 _DefaultVertClr;
float4 _CustomVector30;
// Generate the Z+ direction, or blue channel, of supplied normal map.
float GetNormalMapZ(float2 normalmap)
{
// Remap the 0 to 1 range of the normal map to -1 to 1.
float r = 2 * normalmap.r - 1.0;
float g = 2 * normalmap.g - 1.0;
// x*x + y*y + z*z = 1.0
float b = sqrt(1 - (r * r) + (g * g));
// Map back to 0 to 1 range to get the equivalent texture color.
return b * 0.5 + 0.5;
}
void vert(inout appdata_full v, out Input o) {
UNITY_INITIALIZE_OUTPUT(Input, o);
o.vertexColor = v.color;
}
void surf(Input IN, inout SurfaceOutputStandard o)
{
fixed4 c = tex2D(_MainTex, IN.uv_MainTex); // Albedo comes from a texture tinted by color
fixed4 nor = tex2D(_NormalMap, IN.uv_MainTex); // Use the normal map as is for now.
float blend = nor.b; // Set current nor.b as blend map.
float cav = nor.a; // Set current nor.a as cavity map.
nor.b = GetNormalMapZ(nor.rg); // Generate the .b, or Z+ channel, of the normal map.
nor.a = 1; // Cancel out Alpha on nor.
fixed4 prm = tex2D(_PRMMap, IN.uv_MainTex); // Init PRM map.
fixed3 vertRGB = IN.vertexColor.rgb; // Get vertex colors.
float sssBlend = _CustomVector30.x * prm.r; // Shading and color.
fixed4 emi = tex2D(_EmiMap, IN.uv_MainTex); // Emissive maps.
float3 albedoFinal; // Pre-final Albedo.
half rim = 1.0 - saturate(dot(normalize(IN.viewDir), o.Normal)); // Setup rimlights.
float texAlpha;
float vertAlpha;
#if USE_TEX_ALPHA
texAlpha = saturate(c.a * _Cutoff);
#else
texAlpha = 1;
#endif
#if USE_VERT_ALPHA
vertAlpha = IN.vertexColor.a;
#else
vertAlpha = 1;
#endif
o.Normal = UnpackNormal(nor);
float3 worldRefl = WorldReflectionVector(IN, o.Normal);
rim = 1.0 - saturate(dot(normalize(IN.viewDir), o.Normal));
#ifdef USE_PRM_MAP
#ifdef SKIN_MAT
albedoFinal = lerp((c.rgb * _Color), (c.rgb * _Color * _CustomVector11), sssBlend);
o.Metallic = 0;
o.Smoothness = 0;
#else
albedoFinal = c.rgb * _Color;
o.Metallic = prm.r * c.rgb;
o.Smoothness = 1 - prm.g;
#endif
o.Occlusion = prm.b;
#else
albedoFinal = c.rgb * _Color;
o.Metallic = 0;
o.Smoothness = 0;
#endif
#ifdef USE_VERT_RGB
o.Albedo = albedoFinal * IN.vertexColor.rgb;
#else
o.Albedo = albedoFinal * _DefaultVertClr;
#endif
#ifdef USE_EMISSIVE
o.Emission = _FlashColor.rgb + emi.rgb + (_RimLightColor * pow(rim, 3));
#else
o.Emission = _FlashColor.rgb + (_RimLightColor * pow(rim, 3));
#endif
o.Alpha = texAlpha * vertAlpha;
}
ENDCG
}
Fallback "VertexLit"
}