Added SurfaceFeatureFlags;

Added OutlineScope;
Added AngelRingScope;

Change up Outline pass
This commit is contained in:
Misaki
2025-01-29 21:54:17 +09:00
parent 018300e046
commit d8b12a0ca9
18 changed files with 249 additions and 248 deletions

View File

@@ -32,7 +32,7 @@ struct UTSData
struct UTSSurfaceData
{
uint materialFeatures;
uint surfaceFeatures;
real3 baseColor;
real3 firstShadingColor;
@@ -56,7 +56,7 @@ struct UTSSurfaceData
struct UtsBSDFData
{
uint materialFeatures;
uint surfaceFeatures;
real3 diffuseColor;
real3 firstShadingDiffuseColor;
@@ -87,7 +87,7 @@ UTSSurfaceData ConvertSurfaceDataToUTSSurfaceData(SurfaceData surfaceData)
UTSSurfaceData output;
ZERO_INITIALIZE(UTSSurfaceData, output);
output.materialFeatures = surfaceData.materialFeatures;
output.surfaceFeatures = surfaceData.materialFeatures;
output.baseColor = surfaceData.baseColor;
output.alpha = 1.0;
output.normalWS = surfaceData.normalWS;
@@ -110,7 +110,7 @@ UTSSurfaceData GetUTSSurfaceData(FragInputs input, float3 V)
UTSSurfaceData output;
//ZERO_INITIALIZE(UTSSurfaceData, output);
output.materialFeatures = 0;
output.surfaceFeatures = _SurfaceFeatures;
float4 mainTexture = SAMPLE_TEXTURE2D(_BaseColorMap, sampler_BaseColorMap, TRANSFORM_TEX(input.texCoord0, _BaseColorMap));
output.baseColor = mainTexture.rgb * _BaseColor.rgb;
@@ -200,7 +200,7 @@ UtsBSDFData ConvertUTSSurfaceDataToUTSBSDFData(UTSSurfaceData surfaceData)
{
UtsBSDFData output;
output.materialFeatures = surfaceData.materialFeatures;
output.surfaceFeatures = surfaceData.surfaceFeatures;
output.diffuseColor = UtsComputeDiffuseColor(surfaceData.baseColor, surfaceData.metallic, 0.05);
output.firstShadingDiffuseColor = UtsComputeDiffuseColor(surfaceData.firstShadingColor, surfaceData.metallic, 0.05);
@@ -298,12 +298,6 @@ PreLightData GetPreLightData_UTS(float3 V, PositionInputs posInput, inout UtsBSD
// Construct a right-handed view-dependent orthogonal basis around the normal
preLightData.orthoBasisViewNormal = GetOrthoBasisViewNormal(V, N, preLightData.NdotV);
preLightData.ltcTransformCoat = 0.0;
if (HasFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT))
{
preLightData.ltcTransformCoat = SampleLtcMatrix(CLEAR_COAT_PERCEPTUAL_ROUGHNESS, clampedNdotV, LTCLIGHTINGMODEL_GGX);
}
return preLightData;
}

View File

@@ -154,7 +154,7 @@ float GetHairShadow(PositionInputs posInput, float3 L)
float2 samplingPoint = (posInput.positionSS + shadowLength * viewLightDir.xy * (_ScreenSize.xy / float2(1920.0f, 1080.0f))) * _ScreenSize.zw; // Use 1080p as the reference resolution to achieve consistent shadow lengths across various screen resolutions.
// Then sample the hair buffer, to see if the fragment lands in shadow.
float2 scaledUVs = samplingPoint * _HairShadowRTHandleScale; // We have to including the scaling factor for our shadow map since we are not going to allocate new texture if the rendering resolution changed.
float2 scaledUVs = samplingPoint * _HairShadowRTHandleScale.xy; // We have to including the scaling factor for our shadow map since we are not going to allocate new texture if the rendering resolution changed.
float hairDepth = SAMPLE_TEXTURE2D(_HairShadowTex, s_trilinear_clamp_sampler, scaledUVs).r;
float shadowMask = posInput.deviceDepth <= hairDepth + _HairShadowDepthBias ? 1 : 0; // Hair < Face means Hair are closer to camera
// Note that we have LinearEyeDepth in the buffer. A comparison of depth is needed so that we don't project the shadow of hair behind the face.

View File

@@ -1,4 +1,6 @@
TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex);
TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);
TEXTURE2D(_1st_ShadeMap);
TEXTURE2D(_2nd_ShadeMap);
@@ -12,9 +14,16 @@ sampler _Set_HighColorMask;
sampler _Set_RimLightMask;
sampler _NormalMapForMatCap;
sampler _Set_MatcapMask;
// sampler2D _ClippingMask;
TEXTURE2D(_ClippingMask);
sampler _AngelRing_Sampler;
sampler _Outline_Sampler;
sampler _OutlineTex;
sampler _BakedNormal;
TEXTURE2D(_AngelRingColorMap);
SAMPLER(sampler_AngelRingColorMap);
TEXTURE2D(_OutlineWidthMap);
SAMPLER(sampler_OutlineWidthMap);
TEXTURE2D(_OutlineColorMap);
SAMPLER(sampler_OutlineColorMap);
TEXTURE2D(_BakedNormalMap);
SAMPLER(sampler_BakedNormalMap);

View File

@@ -5,16 +5,15 @@ float4 _Color;
fixed _Use_BaseAs1st;
fixed _Use_1stAs2nd;
fixed _Is_LightColor_Base;
float4 _MainTex_ST;
float4 _1st_ShadeMap_ST;
float4 _1st_ShadeColor;
fixed _Is_LightColor_1st_Shade;
float4 _2nd_ShadeMap_ST;
float4 _2nd_ShadeColor;
fixed _Is_LightColor_2nd_Shade;
fixed _Is_NormalMapToBase;
fixed _Set_SystemShadowsToBase;
float _SurfaceFeatures;
float _Tweak_SystemShadowsLevel;
float _ShadowBias;
float _SDFShadowLevel;
@@ -126,7 +125,6 @@ float _Clipping_Level;
fixed _Inverse_Clipping;
float _Tweak_transparency;
fixed _AngelRing;
float4 _AngelRing_Sampler_ST;
float _BaseColorVisible;
float _BaseColorOverridden;
@@ -152,10 +150,6 @@ float _RimLightVisible;
float _RimLightOverridden;
float4 _RimLightMaskColor;
float _OutlineVisible;
float _OutlineOverridden;
float4 _OutlineMaskColor;
float _ComposerMaskMode;
int _ClippingMatteMode;
@@ -163,32 +157,17 @@ float _GI_Intensity;
float _Light_Intensity_Multiplier;
float4 _AngelRing_Color;
fixed _Is_LightColor_AR;
float4 _AngelRingColor;
float4 _AngelRingColorMap_ST;
float _AR_Intensity;
float _AR_ShadowIntensity;
float _AR_OffsetU;
float _AR_OffsetV;
fixed _ARSampler_AlphaOn;
// Unity Toon Shader Outline
float _Outline_Width;
float _Farthest_Distance;
float _Nearest_Distance;
float4 _Outline_Sampler_ST;
float4 _Outline_Color;
fixed _Is_BlendBaseColor;
float _Offset_Z;
float4 _OutlineTex_ST;
fixed _Is_OutlineTex;
float4 _BakedNormal_ST;
fixed _Is_BakedNormal;
float _OutlineWidth;
float4 _OutlineColor;
fixed _AlbedoAffectOutline;
float _OutlineFadeIn;
float _OutlineFadeOut;
fixed _UseSmoothedNormal;
float _ZOverDrawMode;
//
#if defined(_UTS_TOON_EV_PER_MODEL)
// not in materials
int _ToonLightHiCutFilter;

View File

@@ -67,37 +67,7 @@ void Frag(PackedVaryingsToPS packedInput,
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(packedInput);
FragInputs input = UnpackVaryingsMeshToFragInputs(packedInput.vmesh);
#ifdef _IS_CLIPPING_MASK
if (_ClippingMaskMode != 0)
{
discard;
}
#endif
#ifdef _IS_CLIPPING_MATTE
if (_ClippingMatteMode != 0)
{
discard;
}
#endif // _IS_CLIPPING_MATTE
#if defined(UTS_DEBUG_SHADOWMAP_NO_OUTLINE)
discard;
#endif
//v.2.0.5
if (_ZOverDrawMode > 0.99f)
{
#ifdef _DEPTHOFFSET_ON
outputDepth = posInput.deviceDepth;
#endif
#ifdef UNITY_VIRTUAL_TEXTURING
outVTFeedback = builtinData.vtPackedFeedback;
#endif
outColor = float4(1.0f, 1.0f, 1.0f, 1.0f); // but nothing should be drawn except Z value as colormask is set to 0
return;
}
_Color = _BaseColor;
float4 objPos = mul(unity_ObjectToWorld, float4(0, 0, 0, 1));
float4 Set_UV0 = input.texCoord0;
@@ -114,7 +84,7 @@ void Frag(PackedVaryingsToPS packedInput,
float3 ambientSkyColor = envLightSource_SkyboxIntensity.rgb > 0.0 ? envLightSource_SkyboxIntensity : envLightSource_GradientEquator;
ambientSkyColor *= GetCurrentExposureMultiplier();
float4 _BlendingTex_var = SAMPLE_TEXTURE2D(_HairBlendingMap, sampler_HairBlendingMap, TRANSFORM_TEX(Set_UV0, _MainTex));
float4 _BlendingTex_var = SAMPLE_TEXTURE2D(_HairBlendingMap, sampler_HairBlendingMap, TRANSFORM_TEX(Set_UV0, _BaseColorMap));
outColor = float4(_BlendingTex_var.rgb * ambientSkyColor, _BlendingTex_var.a);
#ifdef _DEPTHOFFSET_ON

View File

@@ -128,27 +128,11 @@ void Frag(PackedVaryingsToPS packedInput,
#if defined(UTS_DEBUG_SHADOWMAP_NO_OUTLINE)
discard;
#endif
//v.2.0.5
if (_ZOverDrawMode > 0.99f)
{
#ifdef _DEPTHOFFSET_ON
outputDepth = posInput.deviceDepth;
#endif
#ifdef UNITY_VIRTUAL_TEXTURING
outVTFeedback = builtinData.vtPackedFeedback;
#endif
outColor = float4(1.0f, 1.0f, 1.0f, 1.0f); // but nothing should be drawn except Z value as colormask is set to 0
return;
}
_Color = _BaseColor;
float4 objPos = mul(unity_ObjectToWorld, float4(0, 0, 0, 1));
float4 Set_UV0 = input.texCoord0;
float4 uv0 = input.texCoord0;
// The following temporary definition of unity_AmbientEquator is for HDRP only.
// The following temporary definition of unity_AmbientEquator is for HDRP only.
//float4 unity_AmbientEquator = float4(0.05, 0.05, 0.05, 1.0); //Todo.
//v.2.0.9
//float3 envLightSource_GradientEquator = unity_AmbientEquator.rgb > 0.05 ? unity_AmbientEquator.rgb : half3(0.05, 0.05, 0.05);
@@ -160,25 +144,15 @@ void Frag(PackedVaryingsToPS packedInput,
float3 ambientSkyColor = envLightSource_SkyboxIntensity.rgb > 0.0 ? envLightSource_SkyboxIntensity : envLightSource_GradientEquator;
ambientSkyColor *= GetCurrentExposureMultiplier() * 5.0f;
float4 _MainTex_var = SAMPLE_TEXTURE2D(_BaseColorMap, sampler_BaseColorMap, TRANSFORM_TEX(Set_UV0, _MainTex));
float3 Set_BaseColor = _BaseColor.rgb*_MainTex_var.rgb;
float3 _Is_BlendBaseColor_var = lerp(_Outline_Color.rgb * ambientSkyColor, (_Outline_Color.rgb * ambientSkyColor * Set_BaseColor * Set_BaseColor), _Is_BlendBaseColor);
//
float3 _OutlineTex_var = tex2D(_OutlineTex,TRANSFORM_TEX(Set_UV0, _OutlineTex)).xyz;
float4 overridingColor = lerp(_OutlineMaskColor, float4(_OutlineMaskColor.w, _OutlineMaskColor.w, _OutlineMaskColor.w, 1.0f), _ComposerMaskMode);
float maskEnabled = max(_OutlineOverridden, _ComposerMaskMode);
//v.2.0.7.5
#ifdef _IS_OUTLINE_CLIPPING_NO
float3 Set_Outline_Color = lerp(_Is_BlendBaseColor_var, _OutlineTex_var.rgb*_Outline_Color.rgb * ambientSkyColor, _Is_OutlineTex );
if (_OutlineVisible < 0.1)
{
// Todo.
// without this, something is drawn even if _OutlineVisible = 0, in AngelRing(HDRP)
discard;
}
Set_Outline_Color = lerp(Set_Outline_Color, overridingColor.xyz, maskEnabled);
float3 baseColor = SAMPLE_TEXTURE2D(_BaseColorMap, sampler_BaseColorMap, TRANSFORM_TEX(uv0, _BaseColorMap)).rgb;
baseColor *= _BaseColor.rgb;
float4 outlineColor = _OutlineColor;
#if _OUTLINE_COLOR_MAP
outlineColor *= SAMPLE_TEXTURE2D(_OutlineColorMap, sampler_OutlineColorMap, TRANSFORM_TEX(uv0, _BaseColorMap)).rgb;
#endif
outlineColor.rgb = lerp(outlineColor.rgb * ambientSkyColor, outlineColor.rgb * ambientSkyColor * baseColor, _AlbedoAffectOutline);
float3 volColor, volOpacity;
uint2 tileIndex = uint2(input.positionSS.xy) / GetTileSize();
@@ -187,32 +161,9 @@ void Frag(PackedVaryingsToPS packedInput,
float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);
EvaluateAtmosphericScattering(posInput, V, volColor, volOpacity); // Premultiplied alpha
Set_Outline_Color.xyz = Set_Outline_Color.xyz * (1 - volOpacity) + volColor * _OutlineVisible;
outColor =float4(Set_Outline_Color, _OutlineVisible );
outlineColor.rgb = outlineColor.rgb * (1 - volOpacity) + volColor;
outColor = outlineColor;
#elif _IS_OUTLINE_CLIPPING_YES
float4 _ClippingMask_var = SAMPLE_TEXTURE2D(_ClippingMask, sampler_MainTex, TRANSFORM_TEX(Set_UV0, _ClippingMask));
float Set_MainTexAlpha = _MainTex_var.a;
float _IsBaseMapAlphaAsClippingMask_var = lerp( _ClippingMask_var.r, Set_MainTexAlpha, _IsBaseMapAlphaAsClippingMask );
float _Inverse_Clipping_var = lerp( _IsBaseMapAlphaAsClippingMask_var, (1.0 - _IsBaseMapAlphaAsClippingMask_var), _Inverse_Clipping );
float Set_Clipping = saturate((_Inverse_Clipping_var+_Clipping_Level));
clip(Set_Clipping - 0.5);
float4 Set_Outline_Color = lerp( float4(_Is_BlendBaseColor_var, Set_Clipping), float4((_OutlineTex_var.rgb * _Outline_Color.rgb * ambientSkyColor),Set_Clipping), _Is_OutlineTex );
Set_Outline_Color = lerp(Set_Outline_Color, overridingColor, maskEnabled);
Set_Outline_Color.w *= _OutlineVisible;
uint2 tileIndex = uint2(input.positionSS.xy) / GetTileSize();
// input.positionSS is SV_Position
PositionInputs posInput = GetPositionInput(input.positionSS.xy, _ScreenSize.zw, input.positionSS.z, input.positionSS.w, input.positionRWS.xyz, tileIndex);
float3 V = GetWorldSpaceNormalizeViewDir(input.positionRWS);
float3 volColor, volOpacity;
EvaluateAtmosphericScattering(posInput, V, volColor, volOpacity); // Premultiplied alpha
Set_Outline_Color.xyz = Set_Outline_Color.xyz * (1 - volOpacity.x) + volColor * Set_Outline_Color.w;
outColor = Set_Outline_Color;
#endif
//outColor.rgb = ambientSkyColor;
#ifdef _DEPTHOFFSET_ON
outputDepth = posInput.deviceDepth;
#endif

View File

@@ -1,65 +1,28 @@
//Unity Toon Shader/HDRP
//nobuyuki@unity3d.com
//toshiyuki@unity3d.com (Universal RP/HDRP)
float4 objPos = mul(unity_ObjectToWorld, float4(0, 0, 0, 1));
float4 _Outline_Sampler_var = SAMPLE_TEXTURE2D_LOD(_OutlineWidthMap, sampler_OutlineWidthMap, TRANSFORM_TEX(inputMesh.uv0, _BaseColorMap), 0.0);
//v.2.0.4.3 baked Normal Texture for Outline
float3 normalDir = UnityObjectToWorldNormal(inputMesh.normalOS);
float3 tangentDir = normalize(mul(unity_ObjectToWorld, float4(inputMesh.tangentOS.xyz, 0.0)).xyz);
float3 bitangentDir = normalize(cross(normalDir, tangentDir) * inputMesh.tangentOS.w);
float3x3 tangentTransform = float3x3(tangentDir, bitangentDir, normalDir);
//end
float outlineWidth = (_OutlineWidth * 0.01 * smoothstep(_OutlineFadeOut, _OutlineFadeIn, distance(objPos.rgb, _WorldSpaceCameraPos)) * _Outline_Sampler_var.rgb).r;
//v.2.0.7.5
float4 _ClipCameraPos = mul(UNITY_MATRIX_VP, float4(_WorldSpaceCameraPos.xyz, 1));
#if 1
float4 objPos = mul(unity_ObjectToWorld, float4(0, 0, 0, 1));
float2 Set_UV0 = inputMesh.uv0;
float4 _Outline_Sampler_var = tex2Dlod(_Outline_Sampler, float4(TRANSFORM_TEX(Set_UV0, _Outline_Sampler), 0.0, 0));
//v.2.0.4.3 baked Normal Texture for Outline
float3 normalDir = UnityObjectToWorldNormal(inputMesh.normalOS);
float3 tangentDir = normalize(mul(unity_ObjectToWorld, float4(inputMesh.tangentOS.xyz, 0.0)).xyz);
float3 bitangentDir = normalize(cross(normalDir, tangentDir) * inputMesh.tangentOS.w);
float3x3 tangentTransform = float3x3(tangentDir, bitangentDir, normalDir);
//UnpackNormal() can't be used, and so as follows. Do not specify a bump for the texture to be used.
float4 _BakedNormal_var = (tex2Dlod(_BakedNormal, float4(TRANSFORM_TEX(Set_UV0, _BakedNormal), 0.0, 0)) * 2 - 1);
float3 _BakedNormalDir = normalize(mul(_BakedNormal_var.rgb, tangentTransform));
//end
float Set_Outline_Width = (_Outline_Width * 0.01 * smoothstep(_Farthest_Distance, _Nearest_Distance, distance(objPos.rgb, _WorldSpaceCameraPos)) * _Outline_Sampler_var.rgb).r;
Set_Outline_Width *= (1.0f - _ZOverDrawMode);
//v.2.0.7.5
float4 _ClipCameraPos = mul(UNITY_MATRIX_VP, float4(_WorldSpaceCameraPos.xyz, 1));
//v.2.0.7
#if defined(UNITY_REVERSED_Z)
//v.2.0.4.2 (DX)
_Offset_Z = _Offset_Z * -0.01;
#else
//OpenGL
_Offset_Z = _Offset_Z * 0.01;
#endif
float3 FinalNormal;
if(_UseSmoothedNormal == 1)
{
float3 normal = float3(inputMesh.uv1, 0);
normal.z = sqrt(1.0 - saturate(dot(normal.xy, normal.xy)));
FinalNormal = mul(normal, tangentTransform);
}
else
{
FinalNormal = lerp(inputMesh.normalOS, _BakedNormalDir, _Is_BakedNormal);
}
float3 bakedNormal = float3(inputMesh.uv1, 0);
bakedNormal.z = sqrt(1.0 - saturate(dot(bakedNormal.xy, bakedNormal.xy)));
float3 normalOS = lerp(inputMesh.normalOS, mul(bakedNormal, tangentTransform), _UseSmoothedNormal);
//v2.0.4
#ifdef _OUTLINE_NML
//v.2.0.4.3 baked Normal Texture for Outline
float3 normal = mul((float3x3)transpose(mul(UNITY_MATRIX_I_M, UNITY_MATRIX_I_V)), FinalNormal);
#elif _OUTLINE_POS
Set_Outline_Width = Set_Outline_Width * 2;
float signVar = dot(normalize(inputMesh.positionOS), normalize(inputMesh.normalOS)) < 0 ? -1 : 1;
float3 normal = mul((float3x3)transpose(mul(UNITY_MATRIX_I_M, UNITY_MATRIX_I_V)), signVar * normalize(inputMesh.positionOS));
#endif
// screen space width
float2 extendDir = normalize(TransformWViewToHClip(normal).xy);
float4 clipPos = UnityObjectToClipPos(inputMesh.positionOS);
clipPos.xy += extendDir * min(_Outline_MaxWidth, (clipPos.w * Set_Outline_Width));
clipPos.z = clipPos.z + _Offset_Z * _ClipCameraPos.z;
float3 normal = mul((float3x3)transpose(mul(UNITY_MATRIX_I_M, UNITY_MATRIX_I_V)), normalOS);
// screen space width
float2 extendDir = normalize(TransformWViewToHClip(normal).xy);
float4 clipPos = UnityObjectToClipPos(inputMesh.positionOS);
clipPos.xy += extendDir * min(_Outline_MaxWidth, (clipPos.w * outlineWidth));
//clipPos.z = clipPos.z + _Offset_Z * _ClipCameraPos.z;
float4 rws = mul(UNITY_MATRIX_I_P, clipPos); // use UNITY_MATRIX_I_P instead of unity_CameraInvProjection.
rws = mul(UNITY_MATRIX_I_V, rws); // use UNITY_MATRIX_I_V instead of unity_cameraToWorld.
#ifndef TESSELLATION_ON
varyingsType.vmesh.positionCS = clipPos;
#endif // TESSELLATION_ON
varyingsType.vmesh.positionRWS = rws.xyz;
#endif // #if 1
float4 rws = mul(UNITY_MATRIX_I_P, clipPos); // use UNITY_MATRIX_I_P instead of unity_CameraInvProjection.
rws = mul(UNITY_MATRIX_I_V, rws); // use UNITY_MATRIX_I_V instead of unity_cameraToWorld.
varyingsType.vmesh.positionCS = clipPos;
varyingsType.vmesh.positionRWS = rws.xyz;

View File

@@ -282,7 +282,7 @@ void Frag(PackedVaryingsToPS packedInput,
outColor = float4(outColor.rgb, Set_Opacity * ApplyChannelAlpha(channelAlpha));
#endif
#if MATERIAL_TYPE_FRONT_HAIR && ENABLE_UTS_HAIR_BLENDING
#if _MATERIAL_TYPE_FRONTHAIR && ENABLE_UTS_HAIR_BLENDING
float2 screenUV = posInput.positionNDC * _HairBlendingRTHandleScale.xy;
float4 hairBlendingMap = SAMPLE_TEXTURE2D(_HairBlendingTex, s_trilinear_clamp_sampler, screenUV);
outColor.rgb = lerp(outColor.rgb, hairBlendingMap.rgb, hairBlendingMap.a * _HairBlendingFactor);