FurShell: remove scale-influence, curvature scales with player scale
Drop the _FurScaleInfluence blend (fur stays a constant world length at any avatar size, as tuned to influence 0) and scale the gravity curvature droop by the avatar world scale (_FurObjScale) instead, so the bend tracks the player: hider 0.5 => smaller droop, hunter 1.5 => bigger droop. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
41d5b87e9e
commit
9d16524ded
2 files changed
+20
-35
No files matched your search
@@ -41,11 +41,6 @@ namespace Chameleon.Components
|
||||
// direction so the flat shell slices merge into continuous strands at the rim instead of squished
|
||||
// dots. 0 = off (footprint stays circular everywhere).
|
||||
[SerializeField, Range(0f, 5f)] float _silhouetteStretch = 2f;
|
||||
// How much the avatar's world scale drives the fur SIZE. 1 = fully proportional (small avatar => small
|
||||
// fur, like the body). 0 = constant world size (same absolute fur length at any avatar scale). Fully
|
||||
// proportional fur reads as too short on the small hider and too long on the big hunter, so dial this
|
||||
// down to keep the fur closer to a fixed world length; the curl keeps its shape at any setting.
|
||||
[SerializeField, Range(0f, 1f)] float _furScaleInfluence = 0.5f;
|
||||
|
||||
[Header("Shading")]
|
||||
// Optional albedo (strand-colour) override for the standalone prototype; a sibling MeshPainter's
|
||||
@@ -124,7 +119,6 @@ namespace Chameleon.Components
|
||||
static readonly int WindFrequencyId = Shader.PropertyToID("_WindFrequency");
|
||||
static readonly int WindDirectionId = Shader.PropertyToID("_WindDirection");
|
||||
static readonly int FurObjScaleId = Shader.PropertyToID("_FurObjScale");
|
||||
static readonly int FurScaleInfluenceId = Shader.PropertyToID("_FurScaleInfluence");
|
||||
static readonly int XRayColorId = Shader.PropertyToID("_XRayColor");
|
||||
static readonly int XRayPulseSpeedId = Shader.PropertyToID("_XRayPulseSpeed");
|
||||
static readonly int XRayPulseStrengthId = Shader.PropertyToID("_XRayPulseStrength");
|
||||
@@ -264,14 +258,11 @@ namespace Chameleon.Components
|
||||
_mpb.SetFloat(WindFrequencyId, _windFrequency);
|
||||
_mpb.SetVector(WindDirectionId, new Vector4(_windDirection.x, _windDirection.y, 0f, 0f));
|
||||
|
||||
// Avatar world scale (uniform via PlayerScaler) = the scale baked into the instance matrix used
|
||||
// for the shell extrusion, so the shader can scale the curvature droop in lockstep and keep the
|
||||
// curl proportional at any player size (hider 0.5 / hunter 1.5). Read from lossyScale because
|
||||
// the raw object matrix does NOT carry the per-instance scale in the RenderMeshInstanced path.
|
||||
// Avatar world scale (uniform via PlayerScaler). The shader keeps the fur a CONSTANT world length
|
||||
// but scales the gravity droop by this, so the bend tracks the player (hider 0.5 / hunter 1.5).
|
||||
// Read from lossyScale because the raw object matrix does NOT carry the per-instance scale in the
|
||||
// RenderMeshInstanced path.
|
||||
_mpb.SetFloat(FurObjScaleId, transform.lossyScale.y);
|
||||
// Blend the fur size between fully proportional to the avatar (1) and a constant world size (0):
|
||||
// the shader pre-divides the object-space displacement so the net world length follows this.
|
||||
_mpb.SetFloat(FurScaleInfluenceId, _furScaleInfluence);
|
||||
|
||||
// Mirror the sibling painter's live body X-ray reveal onto the fur so the strands glow WITH the
|
||||
// reveal (see-through camo) instead of hiding it under opaque fur. Same colour/pulse/flash the
|
||||
|
||||
@@ -60,13 +60,10 @@ Shader "Custom/FurShell"
|
||||
_WindFrequency("Wind Spatial Frequency", Range(0.0, 10.0)) = 1.0
|
||||
_WindDirection("Wind Direction (object XZ)", Vector) = (1, 0, 0, 0)
|
||||
|
||||
// Avatar world scale, pushed by FurShellRenderer (transform.lossyScale). Drives the curvature droop
|
||||
// so the curl stays proportional at any player size; 1 = authored size (see the vertex shader).
|
||||
// Avatar world scale, pushed by FurShellRenderer (transform.lossyScale). The fur keeps a CONSTANT
|
||||
// world length at any player size, but the gravity droop scales with this so the bend tracks the
|
||||
// avatar: small hider => small droop, big hunter => big droop. 1 = authored size (vertex shader).
|
||||
[HideInInspector] _FurObjScale("Object Scale (driven by FurShellRenderer)", Float) = 1
|
||||
// How strongly the avatar scale drives the fur SIZE: 1 = fully proportional (fur shrinks/grows with the
|
||||
// avatar), 0 = constant world size (same absolute fur length at any avatar scale). Proportional fur
|
||||
// reads as too short on the small hider and too long on the big hunter, so this blends between them.
|
||||
[HideInInspector] _FurScaleInfluence("Scale Influence (driven by FurShellRenderer)", Range(0, 1)) = 0.5
|
||||
|
||||
[Header(XRay Reveal)]
|
||||
// See-through reveal glow mirrored from the sibling MeshPainter's body X-ray so the fur strands glow
|
||||
@@ -150,7 +147,6 @@ Shader "Custom/FurShell"
|
||||
float _WindFrequency;
|
||||
float4 _WindDirection;
|
||||
float _FurObjScale;
|
||||
float _FurScaleInfluence;
|
||||
half4 _XRayColor;
|
||||
half _XRayPulseSpeed;
|
||||
half _XRayPulseStrength;
|
||||
@@ -202,16 +198,14 @@ Shader "Custom/FurShell"
|
||||
float count = max(_ShellCount, 1.0);
|
||||
float h = (count <= 1.0) ? 0.0 : (float)shellIndex / (count - 1.0);
|
||||
|
||||
// Effective fur-size scale. The instance matrix already multiplies the object-space fur
|
||||
// displacement by the avatar's world scale (_FurObjScale), so at full influence the fur is
|
||||
// fully proportional (small avatar => small fur, like the body). _FurScaleInfluence blends
|
||||
// that toward a CONSTANT world size (influence 0 => same absolute fur length at any avatar
|
||||
// size), because fully proportional fur reads as too short on the small hider and too long on
|
||||
// the big hunter. dispComp pre-divides the object-space offset so that after the matrix's
|
||||
// *_FurObjScale the NET world displacement equals effScale, not _FurObjScale.
|
||||
// The instance matrix multiplies the object-space fur displacement by the avatar's world scale
|
||||
// (objScale), so a naive extrusion shrinks/grows 1:1 with the player - too short on the small
|
||||
// hider, too long on the big hunter. To keep the fur a CONSTANT world length (same absolute
|
||||
// length at any size) we pre-divide the object-space offset by objScale; after the matrix's
|
||||
// *objScale the net world displacement is then 1x. Wind sway shares this so it stays a constant
|
||||
// world size too. (The gravity droop below intentionally does NOT - it scales with objScale.)
|
||||
float objScale = max(_FurObjScale, 1e-4);
|
||||
float effScale = lerp(1.0, objScale, _FurScaleInfluence);
|
||||
float dispComp = effScale / objScale;
|
||||
float dispComp = 1.0 / objScale;
|
||||
|
||||
// extrude along the normal; bend the tips down with h^2 for a gravity/curl droop.
|
||||
// The (h + 0.02) lifts the whole stack a hair off the surface: the root (h=0) would else
|
||||
@@ -237,12 +231,12 @@ Shader "Custom/FurShell"
|
||||
// RenderMeshInstanced path - when it falls back to identity the droop follows the mesh's own
|
||||
// local down, so on the rotated player the fur hung sideways instead of toward true down.
|
||||
float3 positionWS = TransformObjectToWorld(posOS);
|
||||
// Curl droop in world down. It uses the SAME effScale as the extrusion above (not the raw
|
||||
// _FurObjScale), so the curl keeps its SHAPE relative to the fur length at any avatar size and
|
||||
// at any influence setting - dialing the length toward constant carries the droop with it
|
||||
// instead of leaving it too strong on the shrunk hider / too weak on the grown hunter. Applied
|
||||
// after moving to world space, so the droop follows true world down regardless of player rotation.
|
||||
positionWS.y -= _Curvature * _ShellLength * h * h * effScale;
|
||||
// Curl droop in world down, scaled by the avatar's world size (objScale) so the bend tracks the
|
||||
// player: a bigger avatar gets a proportionally bigger droop, a smaller one a smaller one. The
|
||||
// fur length above is a CONSTANT world size, so scaling only the droop keeps the bend reading
|
||||
// right relative to the body at every player scale (hider 0.5 / hunter 1.5). Applied after
|
||||
// moving to world space, so the droop follows true world down regardless of player rotation.
|
||||
positionWS.y -= _Curvature * _ShellLength * h * h * objScale;
|
||||
|
||||
VertexNormalInputs vn = GetVertexNormalInputs(input.normalOS);
|
||||
|
||||
|
||||
Reference in new issue
Block a user