Fix : Fur 디졸브 기능 버그 패치

This commit is contained in:
KINDNICK 2025-12-16 23:50:13 +09:00
parent e3f18d8726
commit ec5e2fb8f5
3 changed files with 59 additions and 16 deletions

View File

@ -213,6 +213,11 @@ Shader "Universal Render Pipeline/NiloToon/NiloToon_Character_Fur"
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
[HideInInspector] _PerCharacterZOffset("_PerCharacterZOffset", Float) = 0
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Character Bound (for dissolve)
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
[HideInInspector] _CharacterBoundRadius("_CharacterBoundRadius", Float) = 2.5
// Hidden
[HideInInspector] _Surface("__surface", Float) = 0.0
[HideInInspector] _Blend("__blend", Float) = 0.0

View File

@ -46,49 +46,82 @@ void ApplyDissolve(inout half3 color, float2 uv, float3 positionWS, float4 posit
half dissolveMapThresholdMapValue = 0;
// UV1 - sample .g channel (matching NiloToonCharacter)
if(_DissolveMode == DISSOLVEMODE_UV1)
{
float2 dissolveUV = uv * uvTiling;
dissolveMapThresholdMapValue = SAMPLE_TEXTURE2D(_DissolveThresholdMap, sampler_DissolveThresholdMap, dissolveUV).r;
dissolveMapThresholdMapValue = SAMPLE_TEXTURE2D(_DissolveThresholdMap, sampler_DissolveThresholdMap, dissolveUV).g;
}
// WorldSpaceNoise - 3-axis multiplication (matching NiloToonCharacter)
else if(_DissolveMode == DISSOLVEMODE_WorldSpaceNoise)
{
float2 dissolveUV = positionWS.xz * uvTiling;
float noise = SAMPLE_TEXTURE2D(_DissolveThresholdMap, sampler_DissolveThresholdMap, dissolveUV).g * noiseStrength;
dissolveMapThresholdMapValue = SAMPLE_TEXTURE2D(_DissolveThresholdMap, sampler_DissolveThresholdMap, dissolveUV).r + noise;
float2 dissolveUV;
dissolveUV = positionWS.xz * uvTiling;
dissolveMapThresholdMapValue = SAMPLE_TEXTURE2D(_DissolveThresholdMap, sampler_DissolveThresholdMap, dissolveUV).g;
dissolveUV = positionWS.xy * uvTiling;
dissolveMapThresholdMapValue *= SAMPLE_TEXTURE2D(_DissolveThresholdMap, sampler_DissolveThresholdMap, dissolveUV).g;
dissolveUV = positionWS.yz * uvTiling;
dissolveMapThresholdMapValue *= SAMPLE_TEXTURE2D(_DissolveThresholdMap, sampler_DissolveThresholdMap, dissolveUV).g;
}
// WorldSpaceVerticalUpward - use character bound data from global arrays
else if(_DissolveMode == DISSOLVEMODE_WorldSpaceVerticalUpward)
{
float2 dissolveUV = positionWS.xz * uvTiling;
float noise = SAMPLE_TEXTURE2D(_DissolveThresholdMap, sampler_DissolveThresholdMap, dissolveUV).g * noiseStrength;
dissolveMapThresholdMapValue = saturate(positionWS.y * 0.1 + noise);
// Calculate character bound from center pos and radius (same as NiloToonCharacter)
float3 characterBoundCenterPosWS = _NiloToonGlobalPerCharBoundCenterPosWSArray[_CharacterID];
float characterBoundBottom = characterBoundCenterPosWS.y - _CharacterBoundRadius;
float characterBoundTop = characterBoundCenterPosWS.y + _CharacterBoundRadius;
dissolveMapThresholdMapValue = invLerpClamp(characterBoundBottom, characterBoundTop, positionWS.y + noise);
}
// WorldSpaceVerticalDownward - use character bound data from global arrays
else if(_DissolveMode == DISSOLVEMODE_WorldSpaceVerticalDownward)
{
float2 dissolveUV = positionWS.xz * uvTiling;
float noise = SAMPLE_TEXTURE2D(_DissolveThresholdMap, sampler_DissolveThresholdMap, dissolveUV).g * noiseStrength;
dissolveMapThresholdMapValue = saturate((1 - positionWS.y * 0.1) + noise);
// Calculate character bound from center pos and radius (same as NiloToonCharacter)
float3 characterBoundCenterPosWS = _NiloToonGlobalPerCharBoundCenterPosWSArray[_CharacterID];
float characterBoundBottom = characterBoundCenterPosWS.y - _CharacterBoundRadius;
float characterBoundTop = characterBoundCenterPosWS.y + _CharacterBoundRadius;
dissolveMapThresholdMapValue = invLerpClamp(characterBoundTop, characterBoundBottom, positionWS.y + noise);
}
// ScreenSpaceNoise - use character bound 2D rect UV (matching NiloToonCharacter)
else if(_DissolveMode == DISSOLVEMODE_ScreenSpaceNoise)
{
float2 screenUV = positionCS.xy / positionCS.w;
float2 dissolveUV = screenUV * uvTiling;
float noise = SAMPLE_TEXTURE2D(_DissolveThresholdMap, sampler_DissolveThresholdMap, dissolveUV).g * noiseStrength;
dissolveMapThresholdMapValue = SAMPLE_TEXTURE2D(_DissolveThresholdMap, sampler_DissolveThresholdMap, dissolveUV).r + noise;
// Calculate character bound 2D rect UV using Calc3DSphereTo2DUV (same as NiloToonCharacter)
float3 characterBoundCenterPosWS = _NiloToonGlobalPerCharBoundCenterPosWSArray[_CharacterID];
float2 characterBound2DRectUV01 = Calc3DSphereTo2DUV(positionWS, characterBoundCenterPosWS, _CharacterBoundRadius);
// since the default bounding sphere is 2.5m, when compared to world space, it should have 2.5x Tiling
float2 dissolveUV = characterBound2DRectUV01 * uvTiling * 2.5;
dissolveMapThresholdMapValue = SAMPLE_TEXTURE2D(_DissolveThresholdMap, sampler_DissolveThresholdMap, dissolveUV).g;
}
// ScreenSpaceVerticalUpward
else if(_DissolveMode == DISSOLVEMODE_ScreenSpaceVerticalUpward)
{
float2 screenUV = positionCS.xy / positionCS.w;
float2 dissolveUV = screenUV * uvTiling;
// Calculate character bound 2D rect UV using Calc3DSphereTo2DUV (same as NiloToonCharacter)
float3 characterBoundCenterPosWS = _NiloToonGlobalPerCharBoundCenterPosWSArray[_CharacterID];
float2 characterBound2DRectUV01 = Calc3DSphereTo2DUV(positionWS, characterBoundCenterPosWS, _CharacterBoundRadius);
// since the default bounding sphere is 2.5m, when compared to world space, it should have 2.5x Tiling
float2 dissolveUV = characterBound2DRectUV01 * uvTiling * 2.5;
float noise = SAMPLE_TEXTURE2D(_DissolveThresholdMap, sampler_DissolveThresholdMap, dissolveUV).g * noiseStrength;
dissolveMapThresholdMapValue = saturate(screenUV.y + noise);
dissolveMapThresholdMapValue = saturate(characterBound2DRectUV01.y + noise);
}
// ScreenSpaceVerticalDownward
else if(_DissolveMode == DISSOLVEMODE_ScreenSpaceVerticalDownward)
{
float2 screenUV = positionCS.xy / positionCS.w;
float2 dissolveUV = screenUV * uvTiling;
// Calculate character bound 2D rect UV using Calc3DSphereTo2DUV (same as NiloToonCharacter)
float3 characterBoundCenterPosWS = _NiloToonGlobalPerCharBoundCenterPosWSArray[_CharacterID];
float2 characterBound2DRectUV01 = Calc3DSphereTo2DUV(positionWS, characterBoundCenterPosWS, _CharacterBoundRadius);
// since the default bounding sphere is 2.5m, when compared to world space, it should have 2.5x Tiling
float2 dissolveUV = characterBound2DRectUV01 * uvTiling * 2.5;
float noise = SAMPLE_TEXTURE2D(_DissolveThresholdMap, sampler_DissolveThresholdMap, dissolveUV).g * noiseStrength;
dissolveMapThresholdMapValue = saturate((1 - screenUV.y) + noise);
dissolveMapThresholdMapValue = saturate((1 - characterBound2DRectUV01.y) + noise);
}
half dissolve = dissolveMapThresholdMapValue - finalDissolveAmount;

View File

@ -13,6 +13,7 @@
#include "../../ShaderLibrary/NiloUtilityHLSL/NiloBlendEquationUtil.hlsl"
#include "../../ShaderLibrary/NiloUtilityHLSL/NiloDitherFadeoutClipUtil.hlsl"
#include "../../ShaderLibrary/NiloUtilityHLSL/NiloPerspectiveRemovalUtil.hlsl"
#include "../../ShaderLibrary/NiloUtilityHLSL/NiloUVCalculateUtil.hlsl"
//------------------------------------------------------------------------------------------------------------------------------
// NiloToon Global Light Override Variables (from NiloToonCharacterMainLightOverrider)
@ -189,6 +190,9 @@ CBUFFER_START(UnityPerMaterial)
// ZOffset
half _PerCharacterZOffset;
// Character Bound (for dissolve)
float _CharacterBoundRadius;
// Character ID (for accessing global arrays)
uint _CharacterID;
CBUFFER_END
@ -204,6 +208,7 @@ CBUFFER_END
float3 _NiloToonGlobalPerCharHeadBonePosWSArray[MAX_CHARACTER_COUNT];
float3 _NiloToonGlobalPerCharFaceForwardDirWSArray[MAX_CHARACTER_COUNT];
float3 _NiloToonGlobalPerCharFaceUpwardDirWSArray[MAX_CHARACTER_COUNT];
float3 _NiloToonGlobalPerCharBoundCenterPosWSArray[MAX_CHARACTER_COUNT];
//------------------------------------------------------------------------------------------------------------------------------
// Texture Declarations (all textures declared unconditionally to avoid compilation issues)