796 lines
37 KiB
GLSL
796 lines
37 KiB
GLSL
// NiloToon Character Fur Shader
|
|
// Single-material fur shader with Base + Fur Shell rendering
|
|
// Requires NiloToonFurRendererFeature to be added to URP Renderer
|
|
//
|
|
// Usage:
|
|
// 1. Add NiloToonFurRendererFeature to your URP Renderer Asset
|
|
// 2. Apply this shader to your mesh material (single material slot)
|
|
|
|
Shader "Universal Render Pipeline/NiloToon/NiloToon_Character_Fur"
|
|
{
|
|
Properties
|
|
{
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Base Color
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
[Header(Base Color)]
|
|
[Space(5)]
|
|
[MainTexture] _BaseMap("Base Map", 2D) = "white" {}
|
|
[HDR][MainColor] _BaseColor("Base Color", Color) = (1,1,1,1)
|
|
_Cutoff("Alpha Cutoff", Range(0.0, 1.0)) = 0.5
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Normal Map
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
[Header(Normal Map)]
|
|
[Space(5)]
|
|
[Toggle(_NORMALMAP)] _UseNormalMap("Enable Normal Map", Float) = 0
|
|
[Normal] _BumpMap("Normal Map", 2D) = "bump" {}
|
|
_BumpScale("Normal Scale", Range(0, 2)) = 1.0
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Fur Settings
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
[Header(Fur Shape)]
|
|
[Space(5)]
|
|
_FurNoiseMask("Fur Noise Mask", 2D) = "white" {}
|
|
_FurMask("Fur Mask (where fur appears)", 2D) = "white" {}
|
|
_FurLengthMask("Fur Length Mask", 2D) = "white" {}
|
|
_FurVector("Fur Direction (XYZ) + Length (W)", Vector) = (0, 0, 1, 0.02)
|
|
[Normal] _FurVectorTex("Fur Direction Map (Normal)", 2D) = "bump" {}
|
|
_FurVectorScale("Fur Direction Scale", Range(-10, 10)) = 1.0
|
|
_FurGravity("Fur Gravity", Range(0, 1)) = 0.25
|
|
_FurRandomize("Fur Randomize", Range(0, 1)) = 0.1
|
|
_FurAO("Fur Ambient Occlusion", Range(0, 1)) = 0.5
|
|
|
|
[Header(Shell Layers)]
|
|
[Space(5)]
|
|
[IntRange] _FurLayerNum("Fur Layer Count", Range(1, 3)) = 2
|
|
_FurRootOffset("Fur Root Offset", Range(-1, 0)) = 0
|
|
|
|
[Header(Fur Rim Light)]
|
|
[Space(5)]
|
|
[HDR] _FurRimColor("Fur Rim Color", Color) = (1, 1, 1, 1)
|
|
_FurRimFresnelPower("Fur Rim Fresnel Power", Range(0.01, 50)) = 3.0
|
|
_FurRimAntiLight("Fur Rim Anti-Light", Range(0, 1)) = 0.5
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Toon Shading (NiloToon Style)
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
[Header(Cel Shading)]
|
|
[Space(5)]
|
|
_CelShadeMidPoint("Cel Shade Mid Point", Range(-1, 1)) = 0
|
|
_CelShadeSoftness("Cel Shade Softness", Range(0, 1)) = 0.1
|
|
|
|
[Header(Shadow Color)]
|
|
[Space(5)]
|
|
[Toggle(_SHADOW_COLOR)] _EnableShadowColor("Enable Shadow Color", Float) = 0
|
|
[HDR] _ShadowColor("Shadow Tint Color", Color) = (1, 1, 1, 1)
|
|
_ShadowBrightness("Shadow Brightness", Range(0, 2)) = 1.0
|
|
|
|
[Header(HSV Adjustment in Shadow)]
|
|
[Space(5)]
|
|
_ShadowHueShift("Shadow Hue Shift", Range(-0.5, 0.5)) = 0
|
|
_ShadowSaturationBoost("Shadow Saturation Boost", Range(0, 2)) = 1.0
|
|
_ShadowValueMultiplier("Shadow Value Multiplier", Range(0, 2)) = 1.0
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// MatCap
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
[Header(MatCap Additive)]
|
|
[Space(5)]
|
|
[Toggle(_MATCAP_ADD)] _UseMatCapAdd("Enable MatCap (Add)", Float) = 0
|
|
_MatCapAddMap("MatCap Add Map", 2D) = "black" {}
|
|
[HDR] _MatCapAddColor("MatCap Add Color", Color) = (1, 1, 1, 1)
|
|
_MatCapAddIntensity("MatCap Add Intensity", Range(0, 5)) = 1.0
|
|
_MatCapAddMask("MatCap Add Mask", 2D) = "white" {}
|
|
|
|
[Header(MatCap Multiply)]
|
|
[Space(5)]
|
|
[Toggle(_MATCAP_MUL)] _UseMatCapMul("Enable MatCap (Multiply)", Float) = 0
|
|
_MatCapMulMap("MatCap Multiply Map", 2D) = "white" {}
|
|
_MatCapMulIntensity("MatCap Multiply Intensity", Range(0, 2)) = 1.0
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Rim Light (General)
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
[Header(Rim Light)]
|
|
[Space(5)]
|
|
[Toggle(_RIMLIGHT)] _UseRimLight("Enable Rim Light", Float) = 0
|
|
[HDR] _RimLightColor("Rim Light Color", Color) = (1, 1, 1, 1)
|
|
_RimLightPower("Rim Light Power", Range(0.01, 20)) = 5.0
|
|
_RimLightIntensity("Rim Light Intensity", Range(0, 5)) = 1.0
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Emission
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
[Header(Emission)]
|
|
[Space(5)]
|
|
[Toggle(_EMISSION)] _UseEmission("Enable Emission", Float) = 0
|
|
_EmissionMap("Emission Map", 2D) = "white" {}
|
|
[HDR] _EmissionColor("Emission Color", Color) = (0, 0, 0, 1)
|
|
_EmissionIntensity("Emission Intensity", Range(0, 10)) = 1.0
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Occlusion
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
[Header(Occlusion)]
|
|
[Space(5)]
|
|
[Toggle(_OCCLUSIONMAP)] _UseOcclusion("Enable Occlusion Map", Float) = 0
|
|
_OcclusionMap("Occlusion Map", 2D) = "white" {}
|
|
_OcclusionStrength("Occlusion Strength", Range(0, 1)) = 1.0
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Outline
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
[Header(Outline)]
|
|
[Space(5)]
|
|
_OutlineWidth("Outline Width", Range(0, 10)) = 1.0
|
|
[HDR] _OutlineColor("Outline Color", Color) = (0, 0, 0, 1)
|
|
_OutlineWidthMask("Outline Width Mask", 2D) = "white" {}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Rendering Options
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
[Header(Rendering Options)]
|
|
[Space(5)]
|
|
[Enum(UnityEngine.Rendering.CullMode)] _Cull("Cull Mode", Float) = 2
|
|
[Enum(UnityEngine.Rendering.CullMode)] _FurCull("Fur Cull Mode", Float) = 0
|
|
[Enum(Off, 0, On, 1)] _ZWrite("ZWrite", Float) = 1
|
|
_FurZWrite("Fur ZWrite", Float) = 0
|
|
[Enum(UnityEngine.Rendering.CompareFunction)] _ZTest("ZTest", Float) = 4
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Dissolve (NiloToonPerCharacterRenderController)
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
[HideInInspector] _DissolveAmount("_DissolveAmount", Range(0,1)) = 0
|
|
[HideInInspector] _DissolveMode("_DissolveMode", Integer) = 0
|
|
[HideInInspector] _DissolveThresholdMap("_DissolveThresholdMap", 2D) = "linearGrey" {}
|
|
[HideInInspector] _DissolveThresholdMapTilingX("_DissolveThresholdMapTilingX", Float) = 1
|
|
[HideInInspector] _DissolveThresholdMapTilingY("_DissolveThresholdMapTilingY", Float) = 1
|
|
[HideInInspector] _DissolveNoiseStrength("_DissolveNoiseStrength", Float) = 1
|
|
[HideInInspector] _DissolveBorderRange("_DissolveBorderRange", Float) = 0.02
|
|
[HideInInspector] _DissolveBorderTintColor("_DissolveBorderTintColor", Color) = (1, 3, 6, 1)
|
|
[HideInInspector] _AllowPerCharacterDissolve("_AllowPerCharacterDissolve", Float) = 1
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Per-Character Color Controls (NiloToonPerCharacterRenderController)
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
[HideInInspector] _PerCharacterBaseColorMultiply("_PerCharacterBaseColorMultiply", Float) = 1
|
|
[HideInInspector] _PerCharacterBaseColorTint("_PerCharacterBaseColorTint", Color) = (1, 1, 1, 1)
|
|
[HideInInspector] _PerCharacterTintColor("_PerCharacterTintColor", Color) = (1, 1, 1, 1)
|
|
[HideInInspector] _PerCharacterAddColor("_PerCharacterAddColor", Color) = (0, 0, 0, 0)
|
|
[HideInInspector] _PerCharEffectDesaturatePercentage("_PerCharEffectDesaturatePercentage", Range(0,1)) = 0
|
|
[HideInInspector] _PerCharEffectLerpColor("_PerCharEffectLerpColor", Color) = (1, 1, 0, 0)
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Per-Character Rim Light (NiloToonPerCharacterRenderController)
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
[HideInInspector] _UsePerCharacterRimLightIntensity("_UsePerCharacterRimLightIntensity", Float) = 0
|
|
[HideInInspector] _PerCharacterRimLightIntensity("_PerCharacterRimLightIntensity", Float) = 2
|
|
[HideInInspector] _PerCharacterRimLightColor("_PerCharacterRimLightColor", Color) = (1, 1, 1, 1)
|
|
[HideInInspector] _PerCharacterRimLightSharpnessPower("_PerCharacterRimLightSharpnessPower", Float) = 4
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// BaseMap Override (NiloToonPerCharacterRenderController)
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
[HideInInspector] _PerCharacterBaseMapOverrideAmount("_PerCharacterBaseMapOverrideAmount", Range(0,1)) = 0
|
|
[HideInInspector] _PerCharacterBaseMapOverrideTintColor("_PerCharacterBaseMapOverrideTintColor", Color) = (1, 1, 1, 1)
|
|
[HideInInspector] _PerCharacterBaseMapOverrideMap("_PerCharacterBaseMapOverrideMap", 2D) = "white" {}
|
|
[HideInInspector] _PerCharacterBaseMapOverrideBlendMode("_PerCharacterBaseMapOverrideBlendMode", Float) = 0
|
|
[HideInInspector] _PerCharacterBaseMapOverrideUVOption("_PerCharacterBaseMapOverrideUVOption", Float) = 0
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Character Area Color Fill (NiloToonPerCharacterRenderController)
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
[HideInInspector] _ShouldRenderCharacterAreaColorFill("_ShouldRenderCharacterAreaColorFill", Float) = 0
|
|
[HideInInspector] _CharacterAreaColorFillColor("_CharacterAreaColorFillColor", Color) = (1, 1, 1, 1)
|
|
[HideInInspector] _CharacterAreaColorFillTexture("_CharacterAreaColorFillTexture", 2D) = "white" {}
|
|
[HideInInspector] _CharacterAreaColorFillUVOption("_CharacterAreaColorFillUVOption", Float) = 0
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Dither Opacity (NiloToonPerCharacterRenderController)
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
[HideInInspector] _DitherOpacity("_DitherOpacity", Range(0,1)) = 1
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Dither Fadeout (NiloToonPerCharacterRenderController)
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
[HideInInspector] _DitherFadeoutAmount("_DitherFadeoutAmount", Range(0,1)) = 0
|
|
[HideInInspector] _DitherFadeoutNormalScaleFix("_DitherFadeoutNormalScaleFix", Float) = 1
|
|
[HideInInspector] _AllowPerCharacterDitherFadeout("_AllowPerCharacterDitherFadeout", Float) = 1
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Perspective Removal (NiloToonPerCharacterRenderController)
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
[HideInInspector] _PerspectiveRemovalAmount("_PerspectiveRemovalAmount", Range(0,1)) = 0
|
|
[HideInInspector] _PerspectiveRemovalRadius("_PerspectiveRemovalRadius", Float) = 5
|
|
[HideInInspector] _PerspectiveRemovalStartHeight("_PerspectiveRemovalStartHeight", Float) = 1
|
|
[HideInInspector] _PerspectiveRemovalEndHeight("_PerspectiveRemovalEndHeight", Float) = 0
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// ZOffset (NiloToonPerCharacterRenderController)
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
[HideInInspector] _PerCharacterZOffset("_PerCharacterZOffset", Float) = 0
|
|
|
|
// Hidden
|
|
[HideInInspector] _Surface("__surface", Float) = 0.0
|
|
[HideInInspector] _Blend("__blend", Float) = 0.0
|
|
[HideInInspector] _QueueOffset("Queue offset", Float) = 0.0
|
|
}
|
|
|
|
SubShader
|
|
{
|
|
Tags
|
|
{
|
|
"RenderType" = "Opaque"
|
|
"RenderPipeline" = "UniversalPipeline"
|
|
"UniversalMaterialType" = "Lit"
|
|
"IgnoreProjector" = "True"
|
|
"Queue" = "Geometry"
|
|
}
|
|
LOD 300
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Pass 0: ForwardLit - Base Surface (Full NiloToon Style)
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
Pass
|
|
{
|
|
Name "ForwardLit"
|
|
Tags { "LightMode" = "UniversalForward" }
|
|
|
|
Cull [_Cull]
|
|
ZWrite On
|
|
ZTest LEqual
|
|
Blend One Zero
|
|
|
|
HLSLPROGRAM
|
|
#pragma target 4.5
|
|
|
|
// Shader Features
|
|
#pragma shader_feature_local _NORMALMAP
|
|
#pragma shader_feature_local _SHADOW_COLOR
|
|
#pragma shader_feature_local _MATCAP_ADD
|
|
#pragma shader_feature_local _MATCAP_MUL
|
|
#pragma shader_feature_local _RIMLIGHT
|
|
#pragma shader_feature_local _EMISSION
|
|
#pragma shader_feature_local _OCCLUSIONMAP
|
|
#pragma multi_compile_local _ _NILOTOON_DISSOLVE
|
|
#pragma multi_compile_local _ _NILOTOON_DITHER_FADEOUT
|
|
|
|
// URP Keywords
|
|
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
|
|
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
|
|
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS
|
|
#pragma multi_compile_fragment _ _SHADOWS_SOFT
|
|
#pragma multi_compile_fog
|
|
|
|
// GPU Instancing
|
|
#pragma multi_compile_instancing
|
|
#pragma instancing_options renderinglayer
|
|
|
|
#pragma vertex vert
|
|
#pragma fragment frag
|
|
|
|
#define NILOTOON_FUR_BASE_PASS
|
|
#include "NiloToonCharacterFur_HLSL/NiloToonCharacterFur_Shared.hlsl"
|
|
#include "NiloToonCharacterFur_HLSL/NiloToonCharacterFur_Fragment.hlsl"
|
|
ENDHLSL
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Pass 1: Fur Shell Pass (Geometry Shader) - Standard single target
|
|
// Rendered by NiloToonFurRendererFeature via "NiloToonFurShell" LightMode
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
Pass
|
|
{
|
|
Name "FurShell"
|
|
Tags { "LightMode" = "NiloToonFurShell" }
|
|
|
|
Cull [_FurCull]
|
|
ZWrite [_FurZWrite]
|
|
ZTest LEqual
|
|
Blend SrcAlpha OneMinusSrcAlpha, One OneMinusSrcAlpha
|
|
|
|
HLSLPROGRAM
|
|
#pragma target 4.5
|
|
#pragma require geometry
|
|
|
|
// Shader Features
|
|
#pragma shader_feature_local _NORMALMAP
|
|
#pragma shader_feature_local _SHADOW_COLOR
|
|
#pragma shader_feature_local _MATCAP_ADD
|
|
#pragma shader_feature_local _MATCAP_MUL
|
|
#pragma shader_feature_local _RIMLIGHT
|
|
#pragma shader_feature_local _EMISSION
|
|
#pragma shader_feature_local _OCCLUSIONMAP
|
|
#pragma multi_compile_local _ _NILOTOON_DISSOLVE
|
|
#pragma multi_compile_local _ _NILOTOON_DITHER_FADEOUT
|
|
|
|
// URP Keywords
|
|
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
|
|
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
|
|
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS
|
|
#pragma multi_compile_fragment _ _SHADOWS_SOFT
|
|
#pragma multi_compile_fog
|
|
|
|
// GPU Instancing
|
|
#pragma multi_compile_instancing
|
|
#pragma instancing_options renderinglayer
|
|
|
|
#pragma vertex vert_fur
|
|
#pragma geometry geom_fur
|
|
#pragma fragment frag_fur
|
|
|
|
#define NILOTOON_FUR_SHELL_PASS
|
|
#include "NiloToonCharacterFur_HLSL/NiloToonCharacterFur_Shared.hlsl"
|
|
#include "NiloToonCharacterFur_HLSL/NiloToonCharacterFur_Geometry.hlsl"
|
|
#include "NiloToonCharacterFur_HLSL/NiloToonCharacterFur_Fragment.hlsl"
|
|
ENDHLSL
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Pass 1.5: Fur Shell Mask Pass (Geometry Shader)
|
|
// Renders fur shells to mask buffer only (white where fur is rendered)
|
|
// Used for fur area detection in post-processing
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
Pass
|
|
{
|
|
Name "FurShellMask"
|
|
Tags { "LightMode" = "NiloToonFurShellMask" }
|
|
|
|
Cull [_FurCull]
|
|
ZWrite On // Write depth to prevent outline from rendering over fur
|
|
ZTest LEqual // Standard depth test
|
|
Blend One Zero // Just overwrite
|
|
|
|
HLSLPROGRAM
|
|
#pragma target 4.5
|
|
#pragma require geometry
|
|
|
|
// Dissolve support
|
|
#pragma multi_compile_local _ _NILOTOON_DISSOLVE
|
|
#pragma multi_compile_local _ _NILOTOON_DITHER_FADEOUT
|
|
|
|
// GPU Instancing
|
|
#pragma multi_compile_instancing
|
|
#pragma instancing_options renderinglayer
|
|
|
|
#pragma vertex vert_fur
|
|
#pragma geometry geom_fur
|
|
#pragma fragment frag_fur_mask
|
|
|
|
#define NILOTOON_FUR_SHELL_PASS
|
|
#define NILOTOON_FUR_MASK_PASS
|
|
#include "NiloToonCharacterFur_HLSL/NiloToonCharacterFur_Shared.hlsl"
|
|
#include "NiloToonCharacterFur_HLSL/NiloToonCharacterFur_Geometry.hlsl"
|
|
#include "NiloToonCharacterFur_HLSL/NiloToonCharacterFur_Fragment.hlsl"
|
|
ENDHLSL
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Pass 2: Outline (NiloToon Style)
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
Pass
|
|
{
|
|
Name "Outline"
|
|
Tags { "LightMode" = "NiloToonOutline" }
|
|
|
|
Cull Front
|
|
ZWrite [_ZWrite]
|
|
ZTest [_ZTest]
|
|
|
|
HLSLPROGRAM
|
|
#pragma target 4.5
|
|
|
|
#pragma multi_compile_instancing
|
|
#pragma instancing_options renderinglayer
|
|
#pragma multi_compile_fog
|
|
#pragma multi_compile_local _ _NILOTOON_DISSOLVE
|
|
#pragma multi_compile_local _ _NILOTOON_DITHER_FADEOUT
|
|
|
|
#pragma vertex vert_outline
|
|
#pragma fragment frag_outline
|
|
|
|
#define NILOTOON_FUR_OUTLINE_PASS
|
|
#include "NiloToonCharacterFur_HLSL/NiloToonCharacterFur_Shared.hlsl"
|
|
#include "NiloToonCharacterFur_HLSL/NiloToonCharacterFur_Fragment.hlsl"
|
|
|
|
Varyings vert_outline(Attributes input)
|
|
{
|
|
Varyings output = (Varyings)0;
|
|
UNITY_SETUP_INSTANCE_ID(input);
|
|
UNITY_TRANSFER_INSTANCE_ID(input, output);
|
|
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
|
|
|
|
float outlineWidth = _OutlineWidth * 0.001;
|
|
float outlineMask = SAMPLE_TEXTURE2D_LOD(_OutlineWidthMask, sampler_OutlineWidthMask, input.uv, 0).r;
|
|
outlineWidth *= outlineMask;
|
|
|
|
// FOV-aware outline width
|
|
float fovFactor = unity_OrthoParams.w > 0.5 ? 1.0 : (2.0 * abs(UNITY_MATRIX_P[1][1]));
|
|
outlineWidth *= fovFactor;
|
|
|
|
float3 posOS = input.positionOS.xyz + input.normalOS * outlineWidth;
|
|
output.positionWS = TransformObjectToWorld(posOS);
|
|
output.positionCS = TransformObjectToHClip(posOS);
|
|
output.uv = input.uv;
|
|
|
|
// Apply Perspective Removal to outline
|
|
output.positionCS = NiloDoPerspectiveRemoval(
|
|
output.positionCS,
|
|
output.positionWS,
|
|
_NiloToonGlobalPerCharHeadBonePosWSArray[_CharacterID],
|
|
_PerspectiveRemovalRadius,
|
|
_PerspectiveRemovalAmount,
|
|
_PerspectiveRemovalStartHeight,
|
|
_PerspectiveRemovalEndHeight
|
|
);
|
|
|
|
// Apply per-character Z offset
|
|
if (_PerCharacterZOffset != 0)
|
|
{
|
|
output.positionCS.z += _PerCharacterZOffset * output.positionCS.w;
|
|
}
|
|
|
|
output.fogFactor = ComputeFogFactor(output.positionCS.z);
|
|
|
|
return output;
|
|
}
|
|
|
|
half4 frag_outline(Varyings input) : SV_Target
|
|
{
|
|
// Apply Dither Fadeout to outline (FIRST)
|
|
#if _NILOTOON_DITHER_FADEOUT
|
|
NiloDoDitherFadeoutClip(input.positionCS.xy, 1.0 - _DitherFadeoutAmount * _AllowPerCharacterDitherFadeout);
|
|
#endif
|
|
|
|
// Apply dissolve to outline
|
|
#if _NILOTOON_DISSOLVE
|
|
half3 dummyColor = half3(1, 1, 1);
|
|
ApplyDissolve(dummyColor, input.uv, input.positionWS, input.positionCS);
|
|
#endif
|
|
|
|
half4 color = _OutlineColor;
|
|
color.rgb = MixFog(color.rgb, input.fogFactor);
|
|
return color;
|
|
}
|
|
ENDHLSL
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Pass 3: ShadowCaster
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
Pass
|
|
{
|
|
Name "ShadowCaster"
|
|
Tags { "LightMode" = "ShadowCaster" }
|
|
|
|
ZWrite On
|
|
ZTest LEqual
|
|
ColorMask 0
|
|
Cull [_Cull]
|
|
|
|
HLSLPROGRAM
|
|
#pragma target 4.5
|
|
|
|
#pragma multi_compile_instancing
|
|
#pragma instancing_options renderinglayer
|
|
#pragma multi_compile_local _ _NILOTOON_DISSOLVE
|
|
#pragma multi_compile_local _ _NILOTOON_DITHER_FADEOUT
|
|
|
|
#pragma vertex ShadowPassVertex
|
|
#pragma fragment ShadowPassFragment
|
|
|
|
#define NILOTOON_FUR_SHADOW_PASS
|
|
#include "NiloToonCharacterFur_HLSL/NiloToonCharacterFur_Shared.hlsl"
|
|
#include "NiloToonCharacterFur_HLSL/NiloToonCharacterFur_Fragment.hlsl"
|
|
|
|
float3 _LightDirection;
|
|
float3 _LightPosition;
|
|
|
|
float4 GetShadowPositionHClip(Attributes input)
|
|
{
|
|
float3 positionWS = TransformObjectToWorld(input.positionOS.xyz);
|
|
float3 normalWS = TransformObjectToWorldNormal(input.normalOS);
|
|
|
|
#if _CASTING_PUNCTUAL_LIGHT_SHADOW
|
|
float3 lightDirectionWS = normalize(_LightPosition - positionWS);
|
|
#else
|
|
float3 lightDirectionWS = _LightDirection;
|
|
#endif
|
|
|
|
float4 positionCS = TransformWorldToHClip(ApplyShadowBias(positionWS, normalWS, lightDirectionWS));
|
|
|
|
#if UNITY_REVERSED_Z
|
|
positionCS.z = min(positionCS.z, UNITY_NEAR_CLIP_VALUE);
|
|
#else
|
|
positionCS.z = max(positionCS.z, UNITY_NEAR_CLIP_VALUE);
|
|
#endif
|
|
|
|
return positionCS;
|
|
}
|
|
|
|
Varyings ShadowPassVertex(Attributes input)
|
|
{
|
|
Varyings output = (Varyings)0;
|
|
UNITY_SETUP_INSTANCE_ID(input);
|
|
UNITY_TRANSFER_INSTANCE_ID(input, output);
|
|
|
|
output.uv = input.uv;
|
|
output.positionWS = TransformObjectToWorld(input.positionOS.xyz);
|
|
output.positionCS = GetShadowPositionHClip(input);
|
|
|
|
// Apply Perspective Removal to shadow casting
|
|
output.positionCS = NiloDoPerspectiveRemoval(
|
|
output.positionCS,
|
|
output.positionWS,
|
|
_NiloToonGlobalPerCharHeadBonePosWSArray[_CharacterID],
|
|
_PerspectiveRemovalRadius,
|
|
_PerspectiveRemovalAmount,
|
|
_PerspectiveRemovalStartHeight,
|
|
_PerspectiveRemovalEndHeight
|
|
);
|
|
|
|
// Apply per-character Z offset
|
|
if (_PerCharacterZOffset != 0)
|
|
{
|
|
output.positionCS.z += _PerCharacterZOffset * output.positionCS.w;
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
half4 ShadowPassFragment(Varyings input) : SV_TARGET
|
|
{
|
|
half alpha = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.uv).a * _BaseColor.a;
|
|
clip(alpha - _Cutoff);
|
|
|
|
// Apply dissolve to shadow casting
|
|
#if _NILOTOON_DISSOLVE
|
|
half3 dummyColor = half3(1, 1, 1);
|
|
ApplyDissolve(dummyColor, input.uv, input.positionWS, input.positionCS);
|
|
#endif
|
|
|
|
return 0;
|
|
}
|
|
ENDHLSL
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Pass 4: DepthOnly
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
Pass
|
|
{
|
|
Name "DepthOnly"
|
|
Tags { "LightMode" = "DepthOnly" }
|
|
|
|
ZWrite On
|
|
ColorMask R
|
|
Cull [_Cull]
|
|
|
|
HLSLPROGRAM
|
|
#pragma target 4.5
|
|
|
|
#pragma multi_compile_instancing
|
|
#pragma instancing_options renderinglayer
|
|
#pragma multi_compile_local _ _NILOTOON_DISSOLVE
|
|
#pragma multi_compile_local _ _NILOTOON_DITHER_FADEOUT
|
|
|
|
#pragma vertex DepthOnlyVertex
|
|
#pragma fragment DepthOnlyFragment
|
|
|
|
#define NILOTOON_FUR_DEPTH_PASS
|
|
#include "NiloToonCharacterFur_HLSL/NiloToonCharacterFur_Shared.hlsl"
|
|
#include "NiloToonCharacterFur_HLSL/NiloToonCharacterFur_Fragment.hlsl"
|
|
|
|
Varyings DepthOnlyVertex(Attributes input)
|
|
{
|
|
Varyings output = (Varyings)0;
|
|
UNITY_SETUP_INSTANCE_ID(input);
|
|
UNITY_TRANSFER_INSTANCE_ID(input, output);
|
|
|
|
output.uv = input.uv;
|
|
output.positionWS = TransformObjectToWorld(input.positionOS.xyz);
|
|
output.positionCS = TransformObjectToHClip(input.positionOS.xyz);
|
|
|
|
// Apply Perspective Removal to depth
|
|
output.positionCS = NiloDoPerspectiveRemoval(
|
|
output.positionCS,
|
|
output.positionWS,
|
|
_NiloToonGlobalPerCharHeadBonePosWSArray[_CharacterID],
|
|
_PerspectiveRemovalRadius,
|
|
_PerspectiveRemovalAmount,
|
|
_PerspectiveRemovalStartHeight,
|
|
_PerspectiveRemovalEndHeight
|
|
);
|
|
|
|
// Apply per-character Z offset
|
|
if (_PerCharacterZOffset != 0)
|
|
{
|
|
output.positionCS.z += _PerCharacterZOffset * output.positionCS.w;
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
half DepthOnlyFragment(Varyings input) : SV_TARGET
|
|
{
|
|
half alpha = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.uv).a * _BaseColor.a;
|
|
clip(alpha - _Cutoff);
|
|
|
|
// Apply dissolve to depth
|
|
#if _NILOTOON_DISSOLVE
|
|
half3 dummyColor = half3(1, 1, 1);
|
|
ApplyDissolve(dummyColor, input.uv, input.positionWS, input.positionCS);
|
|
#endif
|
|
|
|
return input.positionCS.z;
|
|
}
|
|
ENDHLSL
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Pass 5: DepthNormals
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
Pass
|
|
{
|
|
Name "DepthNormals"
|
|
Tags { "LightMode" = "DepthNormals" }
|
|
|
|
ZWrite On
|
|
Cull [_Cull]
|
|
|
|
HLSLPROGRAM
|
|
#pragma target 4.5
|
|
|
|
#pragma multi_compile_instancing
|
|
#pragma instancing_options renderinglayer
|
|
#pragma multi_compile_local _ _NILOTOON_DISSOLVE
|
|
#pragma multi_compile_local _ _NILOTOON_DITHER_FADEOUT
|
|
|
|
#pragma vertex DepthNormalsVertex
|
|
#pragma fragment DepthNormalsFragment
|
|
|
|
#define NILOTOON_FUR_DEPTHNORMALS_PASS
|
|
#include "NiloToonCharacterFur_HLSL/NiloToonCharacterFur_Shared.hlsl"
|
|
#include "NiloToonCharacterFur_HLSL/NiloToonCharacterFur_Fragment.hlsl"
|
|
|
|
Varyings DepthNormalsVertex(Attributes input)
|
|
{
|
|
Varyings output = (Varyings)0;
|
|
UNITY_SETUP_INSTANCE_ID(input);
|
|
UNITY_TRANSFER_INSTANCE_ID(input, output);
|
|
|
|
output.uv = input.uv;
|
|
output.positionWS = TransformObjectToWorld(input.positionOS.xyz);
|
|
output.positionCS = TransformObjectToHClip(input.positionOS.xyz);
|
|
output.normalWS = TransformObjectToWorldNormal(input.normalOS);
|
|
|
|
// Apply Perspective Removal to depth normals
|
|
output.positionCS = NiloDoPerspectiveRemoval(
|
|
output.positionCS,
|
|
output.positionWS,
|
|
_NiloToonGlobalPerCharHeadBonePosWSArray[_CharacterID],
|
|
_PerspectiveRemovalRadius,
|
|
_PerspectiveRemovalAmount,
|
|
_PerspectiveRemovalStartHeight,
|
|
_PerspectiveRemovalEndHeight
|
|
);
|
|
|
|
// Apply per-character Z offset
|
|
if (_PerCharacterZOffset != 0)
|
|
{
|
|
output.positionCS.z += _PerCharacterZOffset * output.positionCS.w;
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
float4 DepthNormalsFragment(Varyings input) : SV_TARGET
|
|
{
|
|
half alpha = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.uv).a * _BaseColor.a;
|
|
clip(alpha - _Cutoff);
|
|
|
|
// Apply dissolve to depth normals
|
|
#if _NILOTOON_DISSOLVE
|
|
half3 dummyColor = half3(1, 1, 1);
|
|
ApplyDissolve(dummyColor, input.uv, input.positionWS, input.positionCS);
|
|
#endif
|
|
|
|
return float4(normalize(input.normalWS) * 0.5 + 0.5, 0);
|
|
}
|
|
ENDHLSL
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Pass 6: NiloToonPrepassBuffer (Base mesh only)
|
|
// For NiloToon Bloom / Tonemapping character area detection - base mesh
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
Pass
|
|
{
|
|
Name "NiloToonPrepassBuffer"
|
|
Tags { "LightMode" = "NiloToonPrepassBuffer" }
|
|
|
|
ZWrite On
|
|
ZTest LEqual
|
|
Cull [_Cull]
|
|
|
|
HLSLPROGRAM
|
|
#pragma target 4.5
|
|
|
|
#pragma multi_compile_instancing
|
|
#pragma instancing_options renderinglayer
|
|
#pragma multi_compile_local _ _NILOTOON_DISSOLVE
|
|
#pragma multi_compile_local _ _NILOTOON_DITHER_FADEOUT
|
|
|
|
#pragma vertex PrepassBufferVertexBase
|
|
#pragma fragment PrepassBufferFragmentBase
|
|
|
|
#define NILOTOON_FUR_PREPASSBUFFER_PASS
|
|
#include "NiloToonCharacterFur_HLSL/NiloToonCharacterFur_Shared.hlsl"
|
|
#include "NiloToonCharacterFur_HLSL/NiloToonCharacterFur_Fragment.hlsl"
|
|
|
|
Varyings PrepassBufferVertexBase(Attributes input)
|
|
{
|
|
Varyings output = (Varyings)0;
|
|
UNITY_SETUP_INSTANCE_ID(input);
|
|
UNITY_TRANSFER_INSTANCE_ID(input, output);
|
|
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
|
|
|
|
output.uv = input.uv;
|
|
output.positionWS = TransformObjectToWorld(input.positionOS.xyz);
|
|
output.positionCS = TransformObjectToHClip(input.positionOS.xyz);
|
|
|
|
// Apply Perspective Removal to prepass buffer
|
|
output.positionCS = NiloDoPerspectiveRemoval(
|
|
output.positionCS,
|
|
output.positionWS,
|
|
_NiloToonGlobalPerCharHeadBonePosWSArray[_CharacterID],
|
|
_PerspectiveRemovalRadius,
|
|
_PerspectiveRemovalAmount,
|
|
_PerspectiveRemovalStartHeight,
|
|
_PerspectiveRemovalEndHeight
|
|
);
|
|
|
|
// Apply per-character Z offset
|
|
if (_PerCharacterZOffset != 0)
|
|
{
|
|
output.positionCS.z += _PerCharacterZOffset * output.positionCS.w;
|
|
}
|
|
|
|
output.furLayer = -1; // Base mesh marker
|
|
return output;
|
|
}
|
|
|
|
float4 PrepassBufferFragmentBase(Varyings input) : SV_TARGET
|
|
{
|
|
UNITY_SETUP_INSTANCE_ID(input);
|
|
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
|
|
|
// Base mesh alpha clip
|
|
half alpha = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.uv).a * _BaseColor.a;
|
|
clip(alpha - _Cutoff);
|
|
|
|
// Apply dissolve to prepass buffer
|
|
#if _NILOTOON_DISSOLVE
|
|
half3 dummyColor = half3(1, 1, 1);
|
|
ApplyDissolve(dummyColor, input.uv, input.positionWS, input.positionCS);
|
|
#endif
|
|
|
|
// Output: character visible area = 1
|
|
return float4(0, 1, 0, 1);
|
|
}
|
|
ENDHLSL
|
|
}
|
|
|
|
// Note: Fur shell prepass is handled via MRT in the FurShellMRT pass
|
|
// When WriteToPrepassBuffer is enabled, FurShellMRT outputs to both:
|
|
// - SV_Target0: Main color buffer
|
|
// - SV_Target1: PrepassBuffer (character mask with jagged fur silhouette)
|
|
}
|
|
|
|
FallBack "Universal Render Pipeline/Lit"
|
|
CustomEditor "NiloToonURP.ShaderGUI.NiloToonCharacterFurShaderGUI"
|
|
}
|