Урна: дух - светящаяся дымка (сложение One/One) вместо Fade с пятнами; necrogenie glow/tint
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
3ba6572bef
commit
49c7afe273
+121
-20
@@ -14,8 +14,8 @@ namespace NecromancerTome
|
||||
/// (TEFeatureCinerarium.HasSkull) и пропадает без него. Сдвиги Origin и выгрузку чанка переживает с моделью урны.
|
||||
///
|
||||
/// Модель - бандл necrotechnologist (NecroTechnologistSetup.cs): своя сетка на своём скелете NT_rig в позе покоя,
|
||||
/// глаза - отдельные рендереры (в имени «eye»). Тело - полупрозрачное, как у торговцев-призраков (alpha 0.3, Standard
|
||||
/// в режиме Fade, как у крысы при проходе); текстура уже серая (сделана под обесцвечивание). Глаза - свой
|
||||
/// глаза - отдельные рендереры (в имени «eye»). Тело - светящаяся дымка (16.10: Fade давал пятна; сложение One/One,
|
||||
/// холодный оттенок Tint, своё слабое свечение Glow); текстура уже серая (сделана под обесцвечивание). Глаза - свой
|
||||
/// непрозрачный светящийся материал из бандла, очередь отрисовки 3100 - после тела.
|
||||
/// </summary>
|
||||
public static class CinerariumGenie
|
||||
@@ -105,27 +105,55 @@ namespace NecromancerTome
|
||||
{
|
||||
m.shader = std;
|
||||
}
|
||||
// 16.10: Fade (SrcAlpha/OneMinusSrcAlpha) давал «прозрачный, но какими-то пятнами» и «не выглядит бесплотным
|
||||
// духом»: без записи глубины треугольники одной сетки ложатся в случайном порядке. Свечение (One/One) от порядка
|
||||
// не зависит: дух только добавляет свет к тому, что за ним, - дымка. Альфа здесь не нужна, яркость - цветом.
|
||||
m.SetFloat("_Mode", 2f);
|
||||
m.SetOverrideTag("RenderType", "Transparent");
|
||||
m.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
|
||||
m.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
|
||||
m.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
|
||||
m.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One);
|
||||
m.SetInt("_ZWrite", 0);
|
||||
m.DisableKeyword("_ALPHATEST_ON");
|
||||
m.EnableKeyword("_ALPHABLEND_ON");
|
||||
m.DisableKeyword("_ALPHABLEND_ON");
|
||||
m.DisableKeyword("_ALPHAPREMULTIPLY_ON");
|
||||
if (m.HasProperty("_Glossiness"))
|
||||
{
|
||||
m.SetFloat("_Glossiness", 0f); // без бликов: блик при сложении - белое пятно
|
||||
}
|
||||
if (m.HasProperty("_Metallic"))
|
||||
{
|
||||
m.SetFloat("_Metallic", 0f);
|
||||
}
|
||||
if (m.HasProperty("_EmissionMap") && m.HasProperty("_MainTex"))
|
||||
{
|
||||
m.SetTexture("_EmissionMap", m.GetTexture("_MainTex")); // своё свечение - чтобы ночью не пропадал
|
||||
m.EnableKeyword("_EMISSION");
|
||||
m.globalIlluminationFlags = MaterialGlobalIlluminationFlags.None;
|
||||
}
|
||||
m.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
|
||||
SetAlpha(m, Alpha);
|
||||
SetLook(m);
|
||||
_ghostMats[_src] = m;
|
||||
return m;
|
||||
}
|
||||
|
||||
static void SetAlpha(Material _m, float _a)
|
||||
/// <summary>Холодный бледный оттенок духа (умножается на серую текстуру).</summary>
|
||||
public static Color Tint = new Color(0.55f, 0.75f, 1f, 1f);
|
||||
/// <summary>Своё свечение тела, доля от Tint.</summary>
|
||||
public static float Glow = 0.35f;
|
||||
|
||||
static void SetLook(Material _m)
|
||||
{
|
||||
if (_m != null && _m.HasProperty("_Color"))
|
||||
if (_m == null)
|
||||
{
|
||||
Color c = _m.color;
|
||||
c.a = _a;
|
||||
_m.color = c;
|
||||
return;
|
||||
}
|
||||
if (_m.HasProperty("_Color"))
|
||||
{
|
||||
_m.color = new Color(Tint.r * Alpha, Tint.g * Alpha, Tint.b * Alpha, 1f);
|
||||
}
|
||||
if (_m.HasProperty("_EmissionColor"))
|
||||
{
|
||||
_m.SetColor("_EmissionColor", new Color(Tint.r * Glow, Tint.g * Glow, Tint.b * Glow, 1f));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,9 +161,58 @@ namespace NecromancerTome
|
||||
{
|
||||
foreach (Material m in _ghostMats.Values)
|
||||
{
|
||||
SetAlpha(m, Alpha);
|
||||
SetLook(m);
|
||||
}
|
||||
}
|
||||
|
||||
static readonly Dictionary<Material, Material> _stuckMats = new Dictionary<Material, Material>();
|
||||
|
||||
/// <summary>Почерневший дух (класть некуда): свечением чёрное не нарисовать, поэтому обычная Fade-копия, тёмная.</summary>
|
||||
public static Material Stuck(Material _src)
|
||||
{
|
||||
if (_src == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (_stuckMats.TryGetValue(_src, out Material m) && m != null)
|
||||
{
|
||||
return m;
|
||||
}
|
||||
m = new Material(_src) { name = _src.name + "_stuck" };
|
||||
Shader std = Shader.Find("Standard");
|
||||
if (std != null && m.shader != std)
|
||||
{
|
||||
m.shader = std;
|
||||
}
|
||||
m.SetFloat("_Mode", 2f);
|
||||
m.SetOverrideTag("RenderType", "Transparent");
|
||||
m.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
|
||||
m.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
|
||||
m.SetInt("_ZWrite", 1); // с глубиной: пятен нет, тёмный и почти плотный
|
||||
m.DisableKeyword("_ALPHATEST_ON");
|
||||
m.EnableKeyword("_ALPHABLEND_ON");
|
||||
m.DisableKeyword("_ALPHAPREMULTIPLY_ON");
|
||||
m.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
|
||||
if (m.HasProperty("_Color"))
|
||||
{
|
||||
m.color = new Color(0.04f, 0.035f, 0.045f, 0.8f);
|
||||
}
|
||||
_stuckMats[_src] = m;
|
||||
return m;
|
||||
}
|
||||
|
||||
/// <summary>Исходный материал тела по его светящейся копии.</summary>
|
||||
public static Material Source(Material _ghost)
|
||||
{
|
||||
foreach (KeyValuePair<Material, Material> p in _ghostMats)
|
||||
{
|
||||
if (p.Value == _ghost)
|
||||
{
|
||||
return p.Key;
|
||||
}
|
||||
}
|
||||
return _ghost;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Покачивание и поворот джинна над урной. Только вид - никакой логики.</summary>
|
||||
@@ -150,8 +227,8 @@ namespace NecromancerTome
|
||||
public const float VisitSeconds = 2.2f;
|
||||
/// <summary>Почернел и замер (готовое класть некуда, решение 06.10).</summary>
|
||||
bool _stuck;
|
||||
static readonly MaterialPropertyBlock _mpb = new MaterialPropertyBlock();
|
||||
static readonly int ColorId = Shader.PropertyToID("_Color");
|
||||
/// <summary>Светящиеся материалы рендереров - вернуть после почернения.</summary>
|
||||
readonly Dictionary<Renderer, Material[]> _glowing = new Dictionary<Renderer, Material[]>();
|
||||
|
||||
/// <summary>_worldUnity - точка в координатах сцены (без Origin): низ блока, где дух работал.</summary>
|
||||
public void Visit(Vector3 _worldUnity)
|
||||
@@ -177,15 +254,23 @@ namespace NecromancerTome
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!_glowing.ContainsKey(r))
|
||||
{
|
||||
_glowing[r] = r.sharedMaterials;
|
||||
}
|
||||
Material[] glow = _glowing[r];
|
||||
if (_on)
|
||||
{
|
||||
r.GetPropertyBlock(_mpb);
|
||||
_mpb.SetColor(ColorId, new Color(0.04f, 0.035f, 0.045f, Mathf.Max(CinerariumGenie.Alpha, 0.6f)));
|
||||
r.SetPropertyBlock(_mpb);
|
||||
Material[] dark = new Material[glow.Length];
|
||||
for (int i = 0; i < glow.Length; i++)
|
||||
{
|
||||
dark[i] = CinerariumGenie.Stuck(CinerariumGenie.Source(glow[i]));
|
||||
}
|
||||
r.sharedMaterials = dark;
|
||||
}
|
||||
else
|
||||
{
|
||||
r.SetPropertyBlock(null);
|
||||
r.sharedMaterials = glow;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -261,7 +346,9 @@ namespace NecromancerTome
|
||||
"necrogenie fwd <m> - shift along the spirit's own forward (keeps the curled tail inside the neck)\n" +
|
||||
"necrogenie turn <deg/s> - idle turning speed\n" +
|
||||
"necrogenie bob <m> <s> - bobbing height and period\n" +
|
||||
"necrogenie alpha <0-1> - body opacity";
|
||||
"necrogenie alpha <0-1> - body brightness (the body adds light, it is not alpha-blended)\n" +
|
||||
"necrogenie glow <0-1> - body's own glow (visible at night)\n" +
|
||||
"necrogenie tint <r> <g> <b> - body colour";
|
||||
}
|
||||
|
||||
public override void Execute(List<string> _params, CommandSenderInfo _senderInfo)
|
||||
@@ -291,6 +378,19 @@ namespace NecromancerTome
|
||||
CinerariumGenie.Alpha = Mathf.Clamp01(v);
|
||||
CinerariumGenie.ApplyAlpha();
|
||||
break;
|
||||
case "glow":
|
||||
CinerariumGenie.Glow = Mathf.Clamp01(v);
|
||||
CinerariumGenie.ApplyAlpha();
|
||||
break;
|
||||
case "tint":
|
||||
if (_params.Count >= 4 &&
|
||||
float.TryParse(_params[2], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out float g) &&
|
||||
float.TryParse(_params[3], System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out float b))
|
||||
{
|
||||
CinerariumGenie.Tint = new Color(v, g, b, 1f);
|
||||
CinerariumGenie.ApplyAlpha();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
con.Output("necrogenie: unknown '" + _params[0] + "' - see 'help necrogenie'");
|
||||
return;
|
||||
@@ -298,7 +398,8 @@ namespace NecromancerTome
|
||||
}
|
||||
con.Output("necrogenie: y " + CinerariumGenie.OffsetY.ToString("F2") + ", fwd " + CinerariumGenie.Forward.ToString("F2") + ", turn " + CinerariumGenie.TurnSpeed.ToString("F1") +
|
||||
", bob " + CinerariumGenie.BobHeight.ToString("F2") + " / " + CinerariumGenie.BobPeriod.ToString("F1") + " s, alpha " +
|
||||
CinerariumGenie.Alpha.ToString("F2") + "; spirits on screen: " + CinerariumGenie.Live.Count);
|
||||
CinerariumGenie.Alpha.ToString("F2") + ", glow " + CinerariumGenie.Glow.ToString("F2") + ", tint " +
|
||||
CinerariumGenie.Tint.r.ToString("F2") + " " + CinerariumGenie.Tint.g.ToString("F2") + " " + CinerariumGenie.Tint.b.ToString("F2") + "; spirits on screen: " + CinerariumGenie.Live.Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user