diff --git a/Assets/VRM/MToon/Shaders/MToonCore.cginc b/Assets/VRM/MToon/Shaders/MToonCore.cginc index 38c5d9c1c..204e6ca24 100644 --- a/Assets/VRM/MToon/Shaders/MToonCore.cginc +++ b/Assets/VRM/MToon/Shaders/MToonCore.cginc @@ -120,11 +120,11 @@ float4 frag_forward(v2f i) : SV_TARGET // const const float PI_2 = 6.28318530718; - const float EPS_COL = 0.00001; - + const half EPSILON_FP16 = 0.0009765625; + // uv float2 mainUv = TRANSFORM_TEX(i.uv0, _MainTex); - + // uv anim float uvAnim = tex2D(_UvAnimMaskTexture, mainUv).r * _Time.y; // translate uv in bottom-left origin coordinates. @@ -133,25 +133,25 @@ float4 frag_forward(v2f i) : SV_TARGET float rotateRad = _UvAnimRotation * PI_2 * uvAnim; const float2 rotatePivot = float2(0.5, 0.5); mainUv = mul(float2x2(cos(rotateRad), -sin(rotateRad), sin(rotateRad), cos(rotateRad)), mainUv - rotatePivot) + rotatePivot; - + // main tex half4 mainTex = tex2D(_MainTex, mainUv); - + // alpha half alpha = 1; #ifdef _ALPHATEST_ON alpha = _Color.a * mainTex.a; - alpha = (alpha - _Cutoff) / max(fwidth(alpha), EPS_COL) + 0.5; // Alpha to Coverage + alpha = (alpha - _Cutoff) / max(fwidth(alpha), EPSILON_FP16) + 0.5; // Alpha to Coverage clip(alpha - _Cutoff); alpha = 1.0; // Discarded, otherwise it should be assumed to have full opacity #endif #ifdef _ALPHABLEND_ON alpha = _Color.a * mainTex.a; -#if !_ALPHATEST_ON && SHADER_API_D3D11 // Only enable this on D3D11, where I tested it - clip(alpha - 0.0001); // Slightly improves rendering with layered transparency +#ifdef SHADER_API_D3D11 // Only enable this on D3D11, where I tested it + clip(alpha - EPSILON_FP16); // Slightly improves rendering with layered transparency #endif #endif - + // normal #ifdef _NORMALMAP half3 tangentNormal = UnpackScaleNormal(tex2D(_BumpMap, mainUv), _BumpScale); @@ -177,7 +177,7 @@ float4 frag_forward(v2f i) : SV_TARGET #else half lightAttenuation = shadowAttenuation * lerp(1, shadowAttenuation, _ReceiveShadowRate * tex2D(_ReceiveShadowTexture, mainUv).r); #endif - + // Decide albedo color rate from Direct Light half shadingGrade = 1.0 - _ShadingGradeRate * (1.0 - tex2D(_ShadingGradeTexture, mainUv).r); half lightIntensity = dotNL; // [-1, +1] @@ -188,8 +188,8 @@ float4 frag_forward(v2f i) : SV_TARGET // tooned. mapping from [minIntensityThreshold, maxIntensityThreshold] to [0, 1] half maxIntensityThreshold = lerp(1, _ShadeShift, _ShadeToony); half minIntensityThreshold = _ShadeShift; - lightIntensity = saturate((lightIntensity - minIntensityThreshold) / max(EPS_COL, (maxIntensityThreshold - minIntensityThreshold))); - + lightIntensity = saturate((lightIntensity - minIntensityThreshold) / max(EPSILON_FP16, (maxIntensityThreshold - minIntensityThreshold))); + // Albedo color half4 shade = _ShadeColor * tex2D(_ShadeTexture, mainUv); half4 lit = _Color * mainTex; @@ -197,7 +197,7 @@ float4 frag_forward(v2f i) : SV_TARGET // Direct Light half3 lighting = lightColor; - lighting = lerp(lighting, max(EPS_COL, max(lighting.x, max(lighting.y, lighting.z))), _LightColorAttenuation); // color atten + lighting = lerp(lighting, max(EPSILON_FP16, max(lighting.x, max(lighting.y, lighting.z))), _LightColorAttenuation); // color atten #ifdef MTOON_FORWARD_ADD #ifdef _ALPHABLEND_ON lighting *= step(0, dotNL); // darken if transparent. Because Unity's transparent material can't receive shadowAttenuation. @@ -215,9 +215,9 @@ float4 frag_forward(v2f i) : SV_TARGET #else half3 toonedGI = 0.5 * (ShadeSH9(half4(0, 1, 0, 1)) + ShadeSH9(half4(0, -1, 0, 1))); half3 indirectLighting = lerp(toonedGI, ShadeSH9(half4(worldNormal, 1)), _IndirectLightIntensity); - indirectLighting = lerp(indirectLighting, max(EPS_COL, max(indirectLighting.x, max(indirectLighting.y, indirectLighting.z))), _LightColorAttenuation); // color atten + indirectLighting = lerp(indirectLighting, max(EPSILON_FP16, max(indirectLighting.x, max(indirectLighting.y, indirectLighting.z))), _LightColorAttenuation); // color atten col += indirectLighting * lit; - + col = min(col, lit); // comment out if you want to PBR absolutely. #endif @@ -230,7 +230,7 @@ float4 frag_forward(v2f i) : SV_TARGET half3 mixedRimLighting = lighting + indirectLighting; #endif half3 rimLighting = lerp(staticRimLighting, mixedRimLighting, _RimLightingMix); - half3 rim = pow(saturate(1.0 - dot(worldNormal, worldView) + _RimLift), max(_RimFresnelPower, EPS_COL)) * _RimColor.rgb * tex2D(_RimTexture, mainUv).rgb; + half3 rim = pow(saturate(1.0 - dot(worldNormal, worldView) + _RimLift), max(_RimFresnelPower, EPSILON_FP16)) * _RimColor.rgb * tex2D(_RimTexture, mainUv).rgb; col += lerp(rim * rimLighting, half3(0, 0, 0), i.isOutline); // additive matcap diff --git a/Assets/VRM10/MToon10/Shaders/vrmc_materials_mtoon_geometry_alpha.hlsl b/Assets/VRM10/MToon10/Shaders/vrmc_materials_mtoon_geometry_alpha.hlsl index 99ac42678..e059f7af3 100644 --- a/Assets/VRM10/MToon10/Shaders/vrmc_materials_mtoon_geometry_alpha.hlsl +++ b/Assets/VRM10/MToon10/Shaders/vrmc_materials_mtoon_geometry_alpha.hlsl @@ -17,7 +17,7 @@ inline half GetMToonGeometry_Alpha(half4 litColor) else if (MToon_IsAlphaBlendOn()) { const half alpha = litColor.a; - clip(alpha - EPS_COL); + clip(alpha - EPSILON_FP16); // https://github.com/vrm-c/UniVRM/pull/2598 return alpha; } else diff --git a/Assets/VRM10/MToon10/Shaders/vrmc_materials_mtoon_lighting_mtoon.hlsl b/Assets/VRM10/MToon10/Shaders/vrmc_materials_mtoon_lighting_mtoon.hlsl index 87917ac54..b5b537cd4 100644 --- a/Assets/VRM10/MToon10/Shaders/vrmc_materials_mtoon_lighting_mtoon.hlsl +++ b/Assets/VRM10/MToon10/Shaders/vrmc_materials_mtoon_lighting_mtoon.hlsl @@ -123,7 +123,7 @@ inline half3 GetMToonLighting_Rim_Matcap(const MToonInput input) inline half3 GetMToonLighting_Rim(const UnityLighting unityLight, const MToonInput input, const half shadow) { - const half3 parametricRimFactor = pow(saturate(1.0 - dot(input.normalWS, input.viewDirWS) + _RimLift), max(_RimFresnelPower, EPS_COL)) * _RimColor.rgb; + const half3 parametricRimFactor = pow(saturate(1.0 - dot(input.normalWS, input.viewDirWS) + _RimLift), max(_RimFresnelPower, EPSILON_FP16)) * _RimColor.rgb; const half3 matcapFactor = GetMToonLighting_Rim_Matcap(input); const half3 directLightingFactor = unityLight.directLightColor * shadow; diff --git a/Assets/VRM10/MToon10/Shaders/vrmc_materials_mtoon_utility.hlsl b/Assets/VRM10/MToon10/Shaders/vrmc_materials_mtoon_utility.hlsl index fec4d535d..f6ce873dc 100644 --- a/Assets/VRM10/MToon10/Shaders/vrmc_materials_mtoon_utility.hlsl +++ b/Assets/VRM10/MToon10/Shaders/vrmc_materials_mtoon_utility.hlsl @@ -9,7 +9,8 @@ // define static const float PI_2 = 6.28318530718; -static const float EPS_COL = 0.00001; +// 2^-10 (min positive value of 16-bit floating point) +static const half EPSILON_FP16 = 0.0009765625; inline half mtoon_linearstep(const half start, const half end, const half t) {