From f857935bbd755dcdef8ffabc358207eb5c3cc58e Mon Sep 17 00:00:00 2001 From: Masataka SUMI Date: Wed, 2 Jun 2021 19:31:54 +0900 Subject: [PATCH] Separate functions --- .../VRM10/vrmc_materials_mtoon.shader | 2 +- .../VRM10/vrmc_materials_mtoon_attribute.hlsl | 5 +- .../VRM10/vrmc_materials_mtoon_define.hlsl | 39 +++++++++ ...vrmc_materials_mtoon_forward_fragment.hlsl | 10 +-- .../vrmc_materials_mtoon_forward_vertex.hlsl | 2 + .../VRM10/vrmc_materials_mtoon_input.hlsl | 2 +- .../VRM10/vrmc_materials_mtoon_lighting.hlsl | 81 +++++++++++++------ 7 files changed, 107 insertions(+), 34 deletions(-) diff --git a/Assets/VRMShaders/VRM10/MToon10/Resources/VRM10/vrmc_materials_mtoon.shader b/Assets/VRMShaders/VRM10/MToon10/Resources/VRM10/vrmc_materials_mtoon.shader index b4c78f4ec..4384fbe73 100644 --- a/Assets/VRMShaders/VRM10/MToon10/Resources/VRM10/vrmc_materials_mtoon.shader +++ b/Assets/VRMShaders/VRM10/MToon10/Resources/VRM10/vrmc_materials_mtoon.shader @@ -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 diff --git a/Assets/VRMShaders/VRM10/MToon10/Resources/VRM10/vrmc_materials_mtoon_attribute.hlsl b/Assets/VRMShaders/VRM10/MToon10/Resources/VRM10/vrmc_materials_mtoon_attribute.hlsl index 903500a5e..f1aa1e87b 100644 --- a/Assets/VRMShaders/VRM10/MToon10/Resources/VRM10/vrmc_materials_mtoon_attribute.hlsl +++ b/Assets/VRMShaders/VRM10/MToon10/Resources/VRM10/vrmc_materials_mtoon_attribute.hlsl @@ -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 diff --git a/Assets/VRMShaders/VRM10/MToon10/Resources/VRM10/vrmc_materials_mtoon_define.hlsl b/Assets/VRMShaders/VRM10/MToon10/Resources/VRM10/vrmc_materials_mtoon_define.hlsl index 5067bfea9..04845a980 100644 --- a/Assets/VRMShaders/VRM10/MToon10/Resources/VRM10/vrmc_materials_mtoon_define.hlsl +++ b/Assets/VRMShaders/VRM10/MToon10/Resources/VRM10/vrmc_materials_mtoon_define.hlsl @@ -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 diff --git a/Assets/VRMShaders/VRM10/MToon10/Resources/VRM10/vrmc_materials_mtoon_forward_fragment.hlsl b/Assets/VRMShaders/VRM10/MToon10/Resources/VRM10/vrmc_materials_mtoon_forward_fragment.hlsl index 48fd5fd07..8bedbb8ed 100644 --- a/Assets/VRMShaders/VRM10/MToon10/Resources/VRM10/vrmc_materials_mtoon_forward_fragment.hlsl +++ b/Assets/VRMShaders/VRM10/MToon10/Resources/VRM10/vrmc_materials_mtoon_forward_fragment.hlsl @@ -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); diff --git a/Assets/VRMShaders/VRM10/MToon10/Resources/VRM10/vrmc_materials_mtoon_forward_vertex.hlsl b/Assets/VRMShaders/VRM10/MToon10/Resources/VRM10/vrmc_materials_mtoon_forward_vertex.hlsl index a28cb05ca..d4603c81b 100644 --- a/Assets/VRMShaders/VRM10/MToon10/Resources/VRM10/vrmc_materials_mtoon_forward_vertex.hlsl +++ b/Assets/VRMShaders/VRM10/MToon10/Resources/VRM10/vrmc_materials_mtoon_forward_vertex.hlsl @@ -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); diff --git a/Assets/VRMShaders/VRM10/MToon10/Resources/VRM10/vrmc_materials_mtoon_input.hlsl b/Assets/VRMShaders/VRM10/MToon10/Resources/VRM10/vrmc_materials_mtoon_input.hlsl index 5870fd6f6..fd738a6cc 100644 --- a/Assets/VRMShaders/VRM10/MToon10/Resources/VRM10/vrmc_materials_mtoon_input.hlsl +++ b/Assets/VRMShaders/VRM10/MToon10/Resources/VRM10/vrmc_materials_mtoon_input.hlsl @@ -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); diff --git a/Assets/VRMShaders/VRM10/MToon10/Resources/VRM10/vrmc_materials_mtoon_lighting.hlsl b/Assets/VRMShaders/VRM10/MToon10/Resources/VRM10/vrmc_materials_mtoon_lighting.hlsl index 69ed4bb1d..904151711 100644 --- a/Assets/VRMShaders/VRM10/MToon10/Resources/VRM10/vrmc_materials_mtoon_lighting.hlsl +++ b/Assets/VRMShaders/VRM10/MToon10/Resources/VRM10/vrmc_materials_mtoon_lighting.hlsl @@ -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); }