Separate functions

This commit is contained in:
Masataka SUMI 2021-06-02 19:31:54 +09:00
parent 0182e974bf
commit f857935bbd
7 changed files with 107 additions and 34 deletions

View File

@ -31,7 +31,7 @@ Shader "Hidden/VRM10/vrmc_materials_mtoon"
_EmissionMap ("emissiveTexture", 2D) = "white" {} // Unity specified name
// Rim Lighting
_RimMatcapTex ("mtoon.matcapTexture", 2D) = "black" {}
_MatcapTex ("mtoon.matcapTexture", 2D) = "black" {}
_RimColor ("mtoon.parametricRimColorFactor", Color) = (0, 0, 0, 1)
_RimFresnelPower ("mtoon.parametricRimFresnelPowerFactor", Float) = 5.0
_RimLift ("mtoon.parametricRimLiftFactor", Float) = 0

View File

@ -24,8 +24,9 @@ struct Varyings
#if defined(_NORMALMAP)
half4 tangentWS : TEXCOORD3;
#endif
UNITY_FOG_COORDS(4)
UNITY_LIGHTING_COORDS(5,6)
float3 viewDirWS : TEXCOORD4;
UNITY_FOG_COORDS(5)
UNITY_LIGHTING_COORDS(6,7)
float4 pos : SV_POSITION; // UnityCG macro specified name. Accurately "positionCS"
UNITY_VERTEX_INPUT_INSTANCE_ID
UNITY_VERTEX_OUTPUT_STEREO

View File

@ -10,4 +10,43 @@ inline half3 mtoon_linearstep(half3 start, half3 end, half t)
return min(max((t - start) / (end - start), 0.0), 1.0);
}
inline bool MToon_IsPerspective()
{
return unity_OrthoParams.w != 1.0;
}
inline float3 MToon_GetWorldSpaceNormalizedViewDir(float3 positionWS)
{
if (MToon_IsPerspective())
{
return normalize(_WorldSpaceCameraPos.xyz - positionWS);
}
else
{
return normalize(UNITY_MATRIX_V[2].xyz);
}
}
inline half3x3 MToon_GetTangentToWorld(half3 normalWS, half4 tangentWS)
{
const half3 normalizedNormalWS = normalize(normalWS);
const half3 normalizedTangentWS = normalize(tangentWS.xyz);
const half3 normalizedBitangentWS = normalize(tangentWS.w * cross(normalizedNormalWS, normalizedTangentWS));
return half3x3(normalizedTangentWS, normalizedBitangentWS, normalizedNormalWS);
}
inline bool MToon_IsForwardBasePass()
{
#if defined(UNITY_PASS_FORWARDBASE)
return true;
#elif defined(UNITY_PASS_FORWARDADD)
return false;
#else
// ????
return false;
#endif
}
#endif

View File

@ -34,11 +34,8 @@ half4 MToonFragment(Varyings input) : SV_Target
// 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));
const half3 normalWS = normalize(mul(normalTS, MToon_GetTangentToWorld(input.normalWS, input.tangentWS)));
#else
const half3 normalWS = normalize(input.normalWS);
#endif
@ -47,9 +44,10 @@ half4 MToonFragment(Varyings input) : SV_Target
const UnityLighting unityLighting = GetUnityLighting(input, normalWS);
// Get MToon Lighting
MToonLightingInput lightingInput;
lightingInput.normalWS = normalWS;
MToonInput lightingInput;
lightingInput.uv = uv;
lightingInput.normalWS = normalWS;
lightingInput.viewDirWS = input.viewDirWS;
lightingInput.litColor = litColor.rgb;
lightingInput.alpha = alpha;
const half4 col = GetMToonLighting(unityLighting, lightingInput);

View File

@ -26,6 +26,8 @@ Varyings MToonVertex(Attributes v) // v is UnityCG macro specified name.
output.tangentWS = half4(UnityObjectToWorldDir(v.tangentOS), tangentSign);
#endif
output.viewDirWS = MToon_GetWorldSpaceNormalizedViewDir(output.positionWS);
UNITY_TRANSFER_FOG(output, output.positionWS);
UNITY_TRANSFER_LIGHTING(output, v.texcoord1.xy);

View File

@ -9,7 +9,7 @@ UNITY_DECLARE_TEX2D(_ShadeTex);
UNITY_DECLARE_TEX2D(_BumpMap);
UNITY_DECLARE_TEX2D(_ShadingShiftTex);
UNITY_DECLARE_TEX2D(_EmissionMap);
UNITY_DECLARE_TEX2D(_RimMatcapTex);
UNITY_DECLARE_TEX2D(_MatcapTex);
UNITY_DECLARE_TEX2D(_RimTex);
UNITY_DECLARE_TEX2D(_OutlineWidthTex);
UNITY_DECLARE_TEX2D(_UvAnimMaskTex);

View File

@ -5,50 +5,83 @@
#include "./vrmc_materials_mtoon_input.hlsl"
#include "./vrmc_materials_mtoon_unity_lighting.hlsl"
struct MToonLightingInput
struct MToonInput
{
float2 uv;
half3 normalWS;
half3 viewDirWS;
half3 litColor;
half alpha;
};
half4 GetMToonLighting(UnityLighting lighting, MToonLightingInput input)
inline half GetMToonLighting_Reflectance(UnityLighting lighting, MToonInput input)
{
const half dotNL = dot(input.normalWS, lighting.directLightDirection);
const half shadingInput = lerp(-1, 1, mtoon_linearstep(-1, 1, dotNL) * lighting.directLightAttenuation);
const half shadingShift = UNITY_SAMPLE_TEX2D(_ShadingShiftTex, input.uv).r * _ShadingShiftTexScale + _ShadingShiftFactor;
const half shadingToony = _ShadingToonyFactor;
const half shading = mtoon_linearstep(-1.0 + shadingToony, +1.0 - shadingToony, shadingInput + shadingShift);
return mtoon_linearstep(-1.0 + shadingToony, +1.0 - shadingToony, shadingInput + shadingShift);
}
// lighting
#if defined(UNITY_PASS_FORWARDBASE)
const half3 shadeColor = UNITY_SAMPLE_TEX2D(_ShadeTex, input.uv).rgb * _ShadeColor.rgb;
inline half3 GetMToonLighting_BasicLighting(UnityLighting unityLight, MToonInput input, half reflectance)
{
if (MToon_IsForwardBasePass())
{
const half3 shadeColor = UNITY_SAMPLE_TEX2D(_ShadeTex, input.uv).rgb * _ShadeColor.rgb;
const half3 direct = lerp(shadeColor, input.litColor, shading) * lighting.directLightColor;
const half3 indirect = input.litColor * lerp(lighting.indirectLight, lighting.indirectLightEqualized, _GiEqualization);
const half3 direct = lerp(shadeColor, input.litColor, reflectance) * unityLight.directLightColor;
const half3 indirect = input.litColor * lerp(unityLight.indirectLight, unityLight.indirectLightEqualized, _GiEqualization);
#elif defined(UNITY_PASS_FORWARDADD)
const half3 direct = input.litColor * shading * lighting.directLightColor * 0.5;
const half3 indirect = 0;
return direct + indirect;
}
else
{
const half3 direct = input.litColor * reflectance * unityLight.directLightColor * 0.5;
const half3 indirect = 0;
#else
const half3 direct = 0; // unexpected
const half3 indirect = 0;
return direct + indirect;
}
}
#endif
inline half3 GetMToonLighting_Emissive(MToonInput input)
{
if (MToon_IsForwardBasePass())
{
return UNITY_SAMPLE_TEX2D(_EmissionMap, input.uv).rgb * _EmissionColor.rgb;
}
else
{
return 0;
}
}
// emission
#if defined(UNITY_PASS_FORWARDBASE)
const half3 emission = UNITY_SAMPLE_TEX2D(_EmissionMap, input.uv).rgb * _EmissionColor.rgb;
#elif defined(UNITY_PASS_FORWARDADD)
const half3 emission = 0;
#else
const half3 emission = 0; // unexpected
#endif
inline half3 GetMToonLighting_Rim(MToonInput input, half3 lighting)
{
if (MToon_IsForwardBasePass())
{
const half3 worldUpWS = half3(0, 1, 0);
const half3 matcapRightWS = cross(input.viewDirWS, worldUpWS);
const half2 matcapUv = float2(dot(matcapRightWS, input.normalWS), dot(worldUpWS, input.normalWS)) * 0.5 + 0.5;
const half3 matcapFactor = UNITY_SAMPLE_TEX2D(_MatcapTex, matcapUv).rgb;
const half3 parametricRimFactor = pow(saturate(1.0 - dot(input.normalWS, input.viewDirWS) + _RimLift), _RimFresnelPower) * _RimColor.rgb;
const half3 rimLightingFactor = lerp(half3(1, 1, 1), lighting, _RimLightingMix);
return (matcapFactor + parametricRimFactor) * UNITY_SAMPLE_TEX2D(_RimTex, input.uv).rgb * rimLightingFactor;
}
else
{
return 0;
}
}
half4 GetMToonLighting(UnityLighting unityLight, MToonInput input)
{
const half reflectance = GetMToonLighting_Reflectance(unityLight, input);
const half3 col = direct + indirect + emission;
const half3 lighting = GetMToonLighting_BasicLighting(unityLight, input, reflectance);
const half3 emissive = GetMToonLighting_Emissive(input);
const half3 rim = GetMToonLighting_Rim(input, lighting);
const half3 col = lighting + emissive + rim;
return half4(col, input.alpha);
}