diff --git a/src/AcDream.App/Rendering/Wb/WbDrawDispatcher.cs b/src/AcDream.App/Rendering/Wb/WbDrawDispatcher.cs index 3fe6f13..05b9919 100644 --- a/src/AcDream.App/Rendering/Wb/WbDrawDispatcher.cs +++ b/src/AcDream.App/Rendering/Wb/WbDrawDispatcher.cs @@ -643,6 +643,13 @@ public sealed unsafe class WbDrawDispatcher : IDisposable return new IndirectLayoutResult(opaqueCount, transparentCount, opaqueCount * DrawCommandStride); } + /// + /// Public test shim for . Locks in the N.5 Decision 2 + /// translucency partition: Opaque + ClipMap → opaque indirect; AlphaBlend + + /// Additive + InvAlpha → transparent indirect. + /// + public static bool IsOpaquePublic(TranslucencyKind t) => IsOpaque(t); + private static bool IsOpaque(TranslucencyKind t) => t == TranslucencyKind.Opaque || t == TranslucencyKind.ClipMap; diff --git a/tests/AcDream.Core.Tests/Rendering/Wb/WbDrawDispatcherTranslucencyTests.cs b/tests/AcDream.Core.Tests/Rendering/Wb/WbDrawDispatcherTranslucencyTests.cs new file mode 100644 index 0000000..f79fb09 --- /dev/null +++ b/tests/AcDream.Core.Tests/Rendering/Wb/WbDrawDispatcherTranslucencyTests.cs @@ -0,0 +1,25 @@ +using AcDream.App.Rendering.Wb; +using AcDream.Core.Meshing; +using Xunit; + +namespace AcDream.Core.Tests.Rendering.Wb; + +/// +/// Locks in the N.5 translucency partition contract (spec Decision 2). +/// If the partition drifts, the dispatcher's opaque + transparent indirect +/// passes will silently render the wrong groups in the wrong pass — visible +/// regression that's hard to spot in code review. +/// +public sealed class WbDrawDispatcherTranslucencyTests +{ + [Theory] + [InlineData(TranslucencyKind.Opaque, true)] + [InlineData(TranslucencyKind.ClipMap, true)] + [InlineData(TranslucencyKind.AlphaBlend, false)] + [InlineData(TranslucencyKind.Additive, false)] + [InlineData(TranslucencyKind.InvAlpha, false)] + public void IsOpaque_PartitionsByKind(TranslucencyKind kind, bool expected) + { + Assert.Equal(expected, WbDrawDispatcher.IsOpaquePublic(kind)); + } +}