Fur: Albedo-gekoppelte Länge, Toggle-Gate, Soft-Edge, World-Gravity, Pipette & FP-Hide

- Fur-Map trägt nur noch R = Länge (linearer Datenkanal); Farbe kommt per-texel
  aus der Live-Albedo-RT (an _BaseMap des Shell-Shaders gebunden)
- Toggle_Fur als echtes Gate (IsChannelActive = fur), Default aus, furLength 0.5
- Weicher Alpha-Übergang (radial/tip/length coverage) statt Hard-Clip; Transparent-
  Pass mit Depth-Bias (Offset -1,-1) gegen Body-Durchflimmern
- Root dunkler / Tip heller aus gemalter Farbe abgeleitet (kein Fix-Tint)
- Gravity/Curl in World-Space nach Transform (unabhängig von Mesh-Rotation)
- Pipette aktiviert Fur-Toggle immer; liest R-Kanal als Länge
- First-Person blendet FurShellRenderer mit aus
- Netzwerk (FlagFur), Undo, Persistence (fur.png R=Länge) mitgezogen

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Opus 4.8 committed 2026-07-03 23:40:58 +02:00
1 parent 7536e8ec8b
commit 1b783a39be
15 files changed
+254 -306

No files matched your search

@@ -44,7 +44,6 @@ public partial class PaintHud : MonoBehaviour
private const string ToggleFur = "Toggle_Fur";
private const string PickerAlbedo = "Picker_Albedo";
private const string PickerEmission = "Picker_Emission";
private const string PickerFur = "Picker_Fur";
private const string SliderAlbedoAlpha = "Slider_AlbedoAlpha";
private const string SliderEmissionAlpha = "Slider_EmissionAlpha";
private const string SliderMetallic = "Slider_Metallic";
@@ -65,8 +64,7 @@ public partial class PaintHud : MonoBehaviour
private const string SliderOcclusionThreshold = "Slider_OcclusionThreshold";
private const string SliderNormalIntensity = "Slider_NormalIntensity";
private const string SliderParallaxIntensity = "Slider_ParallaxIntensity";
private const string SliderFurAlpha = "Slider_FurAlpha";
private const string SliderFurOpacity = "Slider_FurOpacity";
private const string SliderFurLength = "Slider_FurLength";
private const string MaskSelector = "MaskSelector";
private const string MaskSwatchPrefix = "MaskSwatch_";
@@ -263,12 +261,10 @@ public partial class PaintHud : MonoBehaviour
WireSlider(panel, SliderNormalIntensity, painter ? painter.HeightNormalIntensity : 1.4f, v => { if (painter) painter.HeightNormalIntensity = v; });
WireSlider(panel, SliderParallaxIntensity, painter ? painter.ParallaxIntensity : 1f, v => { if (painter) painter.ParallaxIntensity = v; });
WirePicker(panel, PickerFur, painter ? painter.furColor : Color.blue,
c => { if (painter) painter.furColor = WithRgb(painter.furColor, c); });
WireSlider(panel, SliderFurAlpha, painter ? painter.furColor.a : .6f,
v => { if (painter) painter.furColor = WithAlpha(painter.furColor, v); });
WireSlider(panel, SliderFurOpacity, painter ? painter.furOpacity : 1f,
v => { if (painter) painter.furOpacity = v; });
// Fur has its own Toggle_Fur gate (wired above); the colour comes from the albedo map and the deposit
// weight from the brush alpha, so the only extra fur control is the target length.
WireSlider(panel, SliderFurLength, painter ? painter.furLength : 0.5f,
v => { if (painter) painter.furLength = v; });
foreach (var name in DraggablePanels)
MakeDraggable(panel, name);
@@ -295,11 +291,9 @@ public partial class PaintHud : MonoBehaviour
SetPicker(panel, PickerAlbedo, painter.brushColor);
SetPicker(panel, PickerEmission, painter.emissionColor);
SetPicker(panel, PickerFur, painter.furColor);
SetSlider(panel, SliderAlbedoAlpha, painter.brushColor.a);
SetSlider(panel, SliderEmissionAlpha, painter.emissionColor.a);
SetSlider(panel, SliderFurAlpha, painter.furColor.a);
SetSlider(panel, SliderFurOpacity, painter.furOpacity);
SetSlider(panel, SliderFurLength, painter.furLength);
SetSlider(panel, SliderMetallic, painter.metallic);
SetSlider(panel, SliderSmoothness, painter.smoothness);