using DatReaderWriter.Enums; namespace AcDream.Core.Meshing; /// /// Categorizes how a sub-mesh should be composited into the frame. Determined /// from the Surface.Type flags on the AC dat surface that owns the sub-mesh. /// public enum TranslucencyKind { /// Standard opaque. Depth write + test, no blend. Opaque = 0, /// /// Alpha-keyed (clip-map). Treated as opaque for sorting; the fragment /// shader discards low-alpha fragments. Matches the current rendering of /// doors, windows, and vegetation. /// ClipMap = 1, /// /// Standard alpha blend: src*a + dst*(1-a). /// Depth-write off, depth-test on. Used for semi-transparent glass, /// water decals, and flame alpha surfaces. /// AlphaBlend = 2, /// /// Additive blend: src*a + dst. Depth-write off, depth-test on. /// Used for portal swirls, magical glows, and particle effects. /// Additive = 3, /// /// Inverted alpha blend: src*(1-a) + dst*a. Rare but present in /// the AC dat files. /// InvAlpha = 4, } public static class TranslucencyKindExtensions { // Priority order (highest wins): // 1. Additive — SurfaceType.Additive (0x10000) // 2. InvAlpha — SurfaceType.InvAlpha (0x200) // 3. AlphaBlend — SurfaceType.Alpha (0x100) OR SurfaceType.Translucent (0x10) // 4. ClipMap — SurfaceType.Base1ClipMap (0x04) // 5. Opaque — everything else // // Note: ACViewer groups Base1ClipMap with the alpha-draw bucket (AlphaSurfaceTypes), // but acdream keeps its existing alpha-discard approach for clip-map surfaces // (they render opaque with per-fragment discard) and introduces a separate // translucent pass only for the genuinely blended surface types. /// /// Maps a flags value to the correct /// for the two-pass render split. /// public static TranslucencyKind FromSurfaceType(SurfaceType type) { if ((type & SurfaceType.Additive) != 0) return TranslucencyKind.Additive; if ((type & SurfaceType.InvAlpha) != 0) return TranslucencyKind.InvAlpha; if ((type & (SurfaceType.Alpha | SurfaceType.Translucent)) != 0) return TranslucencyKind.AlphaBlend; if ((type & SurfaceType.Base1ClipMap) != 0) return TranslucencyKind.ClipMap; return TranslucencyKind.Opaque; } }