fix(rendering): carry retail SetSurface state to detail draws
Resolve exact SetSurface blend, alpha-test, and fog state once during extraction and preserve it through recipe-10 prepared payloads, Wb/EnvCell command data, Vulkan pipelines, push constants, and both ordinary/atmospheric one-pass shaders. Preserve AP-240 Wb pure-Clip immediate opaque/A2C while EnvCell uses retail premultiplied Clip; detail-off routing remains unchanged. Correct AP-232 and register the remaining detail-off state divergence. Mutation first failures (all restored): - raw Add->SRCALPHA/ONE: WalkStaticStreamPopulatorTests.ImmediateBuildingDetail_UsesExactResolvedSetSurfaceState line 1278, expected wb-mesh-raw-additive-1x. - inverse-add->alpha-add: same test line 1278, expected wb-mesh-inverse-additive-1x. - remove Env inverse: EnvCellAlphaDrawSourceTests.DetailOn_EveryEnvCellFamilyDrawsOnceInPlaceWithAuthoredOpacity line 132, expected envcell-inverse. - raw IsAdditive precedence: same test line 132, Translucent|Clip|Additive expected envcell-alpha. - Wb paletted ParamB=0: OrderPreservingSubmitterTests line 333, expected 0.392156869. - Wb DDS ParamB=0.05: same test line 333, expected 0.784313738. - disable Alpha+Clip test: WalkStaticStreamPopulatorTests line 1286, expected 0.784313738. - always fog raw Add: same test line 1287, expected no-fog true. - disable fog non-Add: same test line 1287, expected no-fog false. - X=a*qA: RetailDetailTextureContractTests line 261, shared squared-alpha substring absent. - X includes base alpha: same test line 262, forbidden baseTexel.a present. - CLIP uses 0.05: EnvCellAlphaDrawSourceTests.ClipShaders_UseGreaterEqualForThePerRangeReference line 367. - second detail draw: EnvCell detail-on line 131, collection contained 2 draws. - straight-alpha substitute: Wb immediate line 1278, expected wb-mesh-additive-1x. - omit ordered detail arm: OrderPreservingSubmitterTests line 318, expected (77,3.5), got (0,0). - omit atmospheric combine: RetailDetailTextureContractTests line 260, shared include absent. - drop serialized opacity: ObjectMeshDataSerializerTests line 292, expected opacity bits, got 1.0. - stale detail arm: atmospheric adjacency line 402, expected slot 0, got 77. - per-frame surface map: EnvCell warmed allocation line 285, expected 0 B, got 204800 B.
This commit is contained in:
parent
75664805f8
commit
15ed57a1e7
44 changed files with 1154 additions and 187 deletions
|
|
@ -4,6 +4,7 @@ using System.Diagnostics.CodeAnalysis;
|
|||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using AcDream.Content;
|
||||
using AcDream.Core.Meshing;
|
||||
using Chorizite.Core.Render.Enums;
|
||||
using DatReaderWriter;
|
||||
using DatReaderWriter.DBObjs;
|
||||
|
|
@ -255,6 +256,60 @@ public sealed class MeshExtractorSolidFaceExtractionTests
|
|||
BitConverter.SingleToInt32Bits(batch.SurfaceOpacity));
|
||||
}
|
||||
|
||||
public static TheoryData<SurfaceType, bool, RetailSetSurfaceBlend,
|
||||
RetailSetSurfaceAlphaTest, bool> SetSurfaceExtractionRows() => new()
|
||||
{
|
||||
{ SurfaceType.Base1Image, false, RetailSetSurfaceBlend.Opaque, RetailSetSurfaceAlphaTest.Disabled, true },
|
||||
{ SurfaceType.Base1Image | SurfaceType.Alpha, false, RetailSetSurfaceBlend.StraightAlpha, RetailSetSurfaceAlphaTest.Disabled, true },
|
||||
{ SurfaceType.Base1Image | SurfaceType.Alpha | SurfaceType.Additive, false, RetailSetSurfaceBlend.AlphaAdditive, RetailSetSurfaceAlphaTest.Disabled, false },
|
||||
{ SurfaceType.Base1Image | SurfaceType.Additive, false, RetailSetSurfaceBlend.Additive, RetailSetSurfaceAlphaTest.Disabled, false },
|
||||
{ SurfaceType.Base1Image | SurfaceType.InvAlpha, false, RetailSetSurfaceBlend.InverseAlpha, RetailSetSurfaceAlphaTest.Disabled, true },
|
||||
{ SurfaceType.Base1Image | SurfaceType.InvAlpha | SurfaceType.Additive, false, RetailSetSurfaceBlend.InverseAdditive, RetailSetSurfaceAlphaTest.Disabled, false },
|
||||
{ SurfaceType.Base1Image | SurfaceType.Base1ClipMap, false, RetailSetSurfaceBlend.Clip, RetailSetSurfaceAlphaTest.Dds, true },
|
||||
{ SurfaceType.Base1Image | SurfaceType.Base1ClipMap, true, RetailSetSurfaceBlend.Clip, RetailSetSurfaceAlphaTest.Paletted, true },
|
||||
{ SurfaceType.Base1Image | SurfaceType.Alpha | SurfaceType.Base1ClipMap, true, RetailSetSurfaceBlend.StraightAlpha, RetailSetSurfaceAlphaTest.Paletted, true },
|
||||
{ SurfaceType.Base1Image | SurfaceType.Translucent | SurfaceType.Base1ClipMap | SurfaceType.Additive, true, RetailSetSurfaceBlend.StraightAlpha, RetailSetSurfaceAlphaTest.Disabled, false },
|
||||
};
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(SetSurfaceExtractionRows))]
|
||||
public void OrdinaryAndCellExtraction_CarryIdenticalResolvedSetSurfaceState(
|
||||
SurfaceType type,
|
||||
bool paletted,
|
||||
RetailSetSurfaceBlend expectedBlend,
|
||||
RetailSetSurfaceAlphaTest expectedAlphaTest,
|
||||
bool expectedFog)
|
||||
{
|
||||
var dats = new FakeMeshExtractorDats();
|
||||
uint paletteId = paletted ? 0x04000001u : 0u;
|
||||
RegisterTexturedQuad(
|
||||
dats,
|
||||
type,
|
||||
PixelFormat.PFID_A8R8G8B8,
|
||||
new byte[4 * 4 * 4],
|
||||
paletteId: paletteId);
|
||||
var extractor = new MeshExtractor(dats, NullLogger.Instance, sideStagedSink: null);
|
||||
|
||||
ObjectMeshData ordinary = Assert.IsType<ObjectMeshData>(
|
||||
extractor.PrepareMeshData(GfxObjId, isSetup: false));
|
||||
ObjectMeshData cell = Assert.IsType<ObjectMeshData>(
|
||||
extractor.PrepareCellStructMeshData(
|
||||
id: 1,
|
||||
BuildQuadCellStruct(RetailCullMode.Landblock),
|
||||
surfaceOverrides: [2],
|
||||
Matrix4x4.Identity,
|
||||
CancellationToken.None));
|
||||
RetailSetSurfaceMaterialState ordinaryState =
|
||||
Assert.Single(Assert.Single(ordinary.TextureBatches).Value).MaterialState;
|
||||
RetailSetSurfaceMaterialState cellState =
|
||||
Assert.Single(Assert.Single(cell.TextureBatches).Value).MaterialState;
|
||||
|
||||
Assert.Equal(ordinaryState, cellState);
|
||||
Assert.Equal(expectedBlend, ordinaryState.Blend);
|
||||
Assert.Equal(expectedAlphaTest, ordinaryState.AlphaTest);
|
||||
Assert.Equal(expectedFog, ordinaryState.FogEnabled);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// OH2/S1 chunk-2 (2026-09-02): these two winding tests used to register
|
||||
/// an UNTEXTURED (Base1Solid) surface. Under the exact contract, an
|
||||
|
|
@ -800,7 +855,8 @@ public sealed class MeshExtractorSolidFaceExtractionTests
|
|||
SurfaceType surfaceType,
|
||||
PixelFormat pixelFormat,
|
||||
byte[] sourceData,
|
||||
float translucency = 0.0f)
|
||||
float translucency = 0.0f,
|
||||
uint paletteId = 0)
|
||||
{
|
||||
dats.RegisterRootGfxObj(GfxObjId, BuildQuadGfxObj(TexturedSurfaceId, noPos: false));
|
||||
dats.Register(TexturedSurfaceId, new Surface
|
||||
|
|
@ -818,6 +874,7 @@ public sealed class MeshExtractorSolidFaceExtractionTests
|
|||
Width = 4,
|
||||
Height = 4,
|
||||
Format = pixelFormat,
|
||||
DefaultPaletteId = paletteId,
|
||||
SourceData = sourceData,
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue