feat(render): Vulkan campaign V11 step 3 — drop the GL packages and shaders
Commit 2 deleted the GL rendering backend's implementations; this step removes the package references and shader vocabulary they leave behind, so nothing in the App project still spells Silk.NET.OpenGL. Silk.NET.OpenGL and Silk.NET.OpenGL.Extensions.ARB are dropped from AcDream.App.csproj. Chorizite.Core stays — the audit is NOT clean: its Render.Enums (TextureFormat, BufferUsage) and Lib.BoundingBox types are used directly and extensively across the Wb texture/mesh pipeline, independent of the deleted GL IUniformBuffer implementers the package comment used to cite. The stale comment is corrected in place. IMeshPipelineDevice.Gl is removed along with the GL? gl parameter threaded through WbMeshAdapter's four constructors, WorldRenderComposition's CreateMeshAdapter, and VulkanMeshPipelineDevice's Gl => null implementation — nothing read any of them once the legacy per-mesh upload bodies were gone (confirmed by grep: the sole non-doc-comment hit was a test assertion). While in WbMeshAdapter.Dispose(), found and fixed a real bug along the way: its teardown still pattern-matched the deleted GL GpuFrameFlightController to decide whether to wait for submitted work, which VulkanFrameFlightController replaced at slice V6a without this site being updated — so the wait had been silently dead on every Vulkan run since then. Retargeted to VulkanFrameFlightController, which carries the same WaitForSubmittedWork(). The GL pixel-format vocabulary (Silk.NET.OpenGL.PixelFormat/PixelType) that WorldTextureArray/TextureFormatExtensions/TextureAtlasManager used for upload validation is replaced by AcDream.Content's existing Silk.NET-free UploadPixelFormat/UploadPixelType enums (added at MP1a to keep the bake tool GL-free); two new members (Rgb, Red, Float) extend that enum with their GL ABI constants to cover the full vocabulary WorldTextureArray needs, since MP1a's original set only covered what the extractor itself emits. ObjectMeshManager's App-boundary cast `(Silk.NET.OpenGL.PixelFormat?)batch.UploadPixelFormat` becomes a direct pass-through now that both sides share the type. GpuBindingModel.StorageTextureTable (the GL-only binding=9 emulation of the Vulkan texture table) is deleted and StorageBindingCount drops from 10 to 9; the descriptor-set-layout code that builds from that count (VulkanPipelineLayouts, VulkanFrameBindings) is untouched and just allocates one fewer always-dummy-seeded, always-unused binding. Several fully dead GL-only classes came along for the ride, confirmed by zero construction sites: SilkFramebufferViewportTarget (NullFramebufferViewportTarget is the sole production IFramebufferViewportTarget), SilkRenderGlStateReader (NullRenderGlStateReader.Instance is the sole IRenderGlStateReader), RuntimeRenderFrameClearPhase (VulkanRenderFrameClearPhase is the sole IRenderFrameClearPhase, expressing the same atmosphere-clear logic as a pass load-op instead), and GpuFrameTimer plus FrameProfiler's GL-owning FrameBoundary(GL) overload and BeginGpuFrame/EndGpuFrame bracket (RecordGpuSample is the only GPU-timing path any backend uses now — the ACDREAM_WB_DIAG nested-query exclusion these existed for no longer applies, since WbDrawDispatcher's own diagnostic GPU sampling already moved to the device's Vulkan timer pool). GpuFrameFlightController itself stays (never constructed with a real fence API in production, but its retirement-ledger/serial-ring logic is backend-neutral and still covered by its own unit tests) — only its GL-specific parts (the public GL constructor overload, SilkGpuFenceApi) are deleted, since removing the whole class would mean restructuring the frozen Slice-8 composition shape's GpuFrameFlightController? threading, which is out of this commit's scope. TextureParameters.cs and BufferUsageExtensions.cs (zero callers each) are deleted outright. common.glsl is deleted: nothing in the actual Vulkan .spv build reads it. tools/ShaderCompiler/Program.cs compiles each .vert/.frag pair directly and tools/ShaderCompiler/VulkanGlslPreamble.cs injects its own complete self-contained preamble per file; common.glsl's textual concatenation was exclusively Shader.cs's GL-only mechanism, deleted at Commit 2. The five shader files that named it in comments (mesh_modern.vert, particle.vert, particle.frag, sky.frag, terrain_modern.frag) are corrected to point at VulkanGlslPreamble.cs instead. mesh.vert/mesh.frag — the pre-N.5 legacy shader pair the mandatory modern path already made unreachable, with zero C# consumers and no compiled .spv — are deleted too. Regenerated via tools/compile-shaders.ps1: 9/9 remaining shader pairs compile (previously 9/10, with mesh the sole failure — the VulkanShaderManifestTests doc comment's "nine of ten are not Vulkan-expressible" was already stale before this commit). Test fallout: dead-subject test methods/files are deleted rather than patched (TextRendererFailureSafetyTests.cs, ClipFrameUploadTests.cs, GpuResourceRetirementTransactionTests.cs's GL queue tests, one WorldRenderDiagnosticsTests source-order test, one RenderFrameResourceControllerTests clear-phase-order test); tests whose subject moved or was renamed are updated in place rather than deleted (GpuContractTests, VulkanCapabilityGateTests, MeshPipelineDeviceSeamTests' pinned seven-member surface now reads six, ParticleBindlessInstanceTests' cross-dialect check now covers the one surviving dialect, WbMeshAdapterTests' misleadingly-named null-gl test — gpuDevice was always the parameter that actually threw). Build: `dotnet build AcDream.slnx -c Release` — 0 warnings, 0 errors, with the Silk.NET.OpenGL/.Extensions.ARB package references physically removed from the csproj (not just unreferenced in code). Tests: full-solution `dotnet test` green across every project. Zero remaining `using Silk.NET.OpenGL` anywhere in src/ or tests/. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
8a7a0837e1
commit
7a0227c12e
44 changed files with 300 additions and 977 deletions
|
|
@ -1,84 +0,0 @@
|
|||
// Campaign V slice V2 shared preamble (docs/plans/2026-07-27-vulkan-campaign.md
|
||||
// §3.4, §5.2). GL has no #include, so AcDream.App.Rendering.Shader
|
||||
// concatenates this file's text into every shader source that opts in
|
||||
// (Shader(gl, vertPath, fragPath, includeCommonPreamble: true)), inserted
|
||||
// right after the leading #version / #extension block so it can declare new
|
||||
// layout bindings and macros before the rest of the shader body runs.
|
||||
//
|
||||
// --- set 1 (uniform buffers) ------------------------------------------------
|
||||
// GL keeps the SSBO and UBO binding-number namespaces separate, so today's
|
||||
// SceneLighting UBO (binding=1) never collides with BatchBuffer's SSBO
|
||||
// (also binding=1). Vulkan has ONE binding namespace per set, so the Vulkan
|
||||
// backend (from V6 on) moves every uniform buffer to its own set (1) to keep
|
||||
// both binding numbers. ACDREAM_UBO_SET is a no-op under GL today and is
|
||||
// redefined to `set = 1,` when the same source is compiled for Vulkan, so
|
||||
// applying it to every UBO layout now costs nothing and needs no source edit
|
||||
// at the call sites later.
|
||||
#define ACDREAM_UBO_SET
|
||||
|
||||
// --- set 0 binding 9 / set 2 (the global texture table) --------------------
|
||||
// GL emulates Vulkan's set 2 variable-count sampled-texture descriptor array
|
||||
// (GpuBindingModel.TextureTableSet) with a plain storage buffer of packed
|
||||
// GL_ARB_bindless_texture handles at set 0 binding 9
|
||||
// (GpuBindingModel.StorageTextureTable). A batch/pass no longer carries a
|
||||
// 64-bit bindless handle directly into its GPU-visible struct; it carries a
|
||||
// small integer slot index into this table instead, which is what makes the
|
||||
// CPU-side data model backend-neutral (Campaign V slice V2). The table itself
|
||||
// — and every per-renderer GL-side handle-slot allocator that fills it
|
||||
// (WbDrawDispatcher, EnvCellRenderer, TerrainModernRenderer, ParticleRenderer)
|
||||
// — is deleted once each renderer moves onto IGpuDevice's own retirement-gated
|
||||
// table at V4c/V4d/V4e; see the campaign doc's §5.2 for why V2 cannot reach
|
||||
// that table yet.
|
||||
layout(std430, binding = 9) readonly buffer TextureTableBuf {
|
||||
uvec2 gTextureTable[];
|
||||
};
|
||||
|
||||
// Looks up the packed bindless handle for table slot `idx`. Callers still
|
||||
// wrap the result in `sampler2DArray(...)` themselves at the use site (kept
|
||||
// explicit rather than folded into one sampler-returning macro) because every
|
||||
// existing call site already follows that exact pattern and a function cannot
|
||||
// return an opaque sampler type built from a runtime value in GLSL.
|
||||
//
|
||||
// Campaign V slice V6e: this macro is GL-shaped — under Vulkan it degenerates
|
||||
// to the index itself, because there is no handle to look up. Every NEW call
|
||||
// site should use ACDREAM_SAMPLE_ARRAY / ACDREAM_SAMPLE_2D below, which ask the
|
||||
// dialect-neutral question ("sample table slot N") instead of the GL-only one
|
||||
// ("what handle does slot N hold"). The remaining direct users are the shaders
|
||||
// whose port slice has not run yet.
|
||||
#define ACDREAM_TEXTURE_HANDLE(idx) gTextureTable[idx]
|
||||
|
||||
// Campaign V slice V6e: samples a table slot that holds a 2-D ARRAY texture —
|
||||
// the world/particle/terrain case, as opposed to the retained UI's plain 2-D
|
||||
// entries that ACDREAM_SAMPLE_2D below covers.
|
||||
//
|
||||
// Expressed as a SAMPLING macro rather than a sampler-returning one on purpose.
|
||||
// Under Vulkan the expansion carries a `nonuniformEXT` qualifier, and that
|
||||
// qualifier belongs on the indexing expression at the point of use; binding the
|
||||
// result to a local `sampler2DArray` variable first is where a driver is free to
|
||||
// lose it. Both dialects therefore read the texture in one expression.
|
||||
#define ACDREAM_SAMPLE_ARRAY(idx, uvw) texture(sampler2DArray(gTextureTable[idx]), uvw)
|
||||
|
||||
// Campaign V slice V6e: the reserved "this draw has no texture" slot index.
|
||||
//
|
||||
// GL could ask the question directly — an unregistered slot holds the handle 0,
|
||||
// so `gTextureTable[idx] == uvec2(0)` answered it. Vulkan cannot: set 2 is an
|
||||
// opaque descriptor array with nothing to compare, and reading an unwritten
|
||||
// element of a partially-bound array is undefined rather than zero. So the
|
||||
// answer moves to the index itself, which both dialects can test identically,
|
||||
// and the CPU writes this value instead of registering a null handle.
|
||||
#define ACDREAM_TEXTURE_NONE 0xFFFFFFFFu
|
||||
|
||||
// Campaign V slice V6d: samples a table slot that holds a plain 2-D texture.
|
||||
//
|
||||
// The two backends disagree about what a 2-D table entry IS, and this macro is
|
||||
// the one place that difference lives. Under GL a bindless handle carries its
|
||||
// own texture type, so a GL_TEXTURE_2D entry is reconstructed as a sampler2D
|
||||
// and read with a 2-component UV. Under Vulkan the table is one descriptor
|
||||
// array whose element type is fixed at sampler2DArray, so the same entry is a
|
||||
// one-layer array read at layer 0 (see tools/ShaderCompiler/VulkanGlslPreamble.cs).
|
||||
//
|
||||
// That asymmetry is deliberate and is what keeps the retained UI's textures
|
||||
// exactly as they are on GL — including the paperdoll/appraisal FBO colour
|
||||
// texture, which is an externally-owned GL_TEXTURE_2D registered by the §7.1
|
||||
// transitional seam and cannot be made an array before V4g moves its renderer.
|
||||
#define ACDREAM_SAMPLE_2D(idx, uv) texture(sampler2D(gTextureTable[idx]), uv)
|
||||
|
|
@ -1,132 +0,0 @@
|
|||
#version 430 core
|
||||
in vec2 vTex;
|
||||
in vec3 vWorldNormal;
|
||||
in vec3 vWorldPos;
|
||||
out vec4 fragColor;
|
||||
|
||||
uniform sampler2D uDiffuse;
|
||||
|
||||
// Phase 9.1: translucency kind — matches TranslucencyKind C# enum.
|
||||
// 0 = Opaque — depth write+test, no blend; shader never discards
|
||||
// 1 = ClipMap — alpha-key discard (doors, windows, vegetation)
|
||||
// 2 = AlphaBlend — GL blending handles compositing; do NOT discard
|
||||
// 3 = Additive — GL additive blending; do NOT discard
|
||||
// 4 = InvAlpha — GL inverted-alpha blending; do NOT discard
|
||||
uniform int uTranslucencyKind;
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// Phase G.1+G.2: shared scene-lighting UBO (binding = 1).
|
||||
//
|
||||
// Layout mirrors SceneLightingUbo in C#:
|
||||
// struct Light {
|
||||
// vec4 posAndKind; xyz = world pos, w = kind (0=dir,1=point,2=spot)
|
||||
// vec4 dirAndRange; xyz = forward, w = range (metres, hard cutoff)
|
||||
// vec4 colorAndIntensity; xyz = RGB linear, w = intensity
|
||||
// vec4 coneAngleEtc; x = cone (rad), yzw = reserved
|
||||
// };
|
||||
// layout(std140, binding = 1) uniform SceneLighting {
|
||||
// Light uLights[8];
|
||||
// vec4 uCellAmbient; xyz = ambient RGB, w = active count
|
||||
// vec4 uFogParams; x = start, y = end, z = flash, w = mode
|
||||
// vec4 uFogColor; xyz = color
|
||||
// vec4 uCameraAndTime; xyz = camera pos, w = day fraction
|
||||
// };
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
struct Light {
|
||||
vec4 posAndKind;
|
||||
vec4 dirAndRange;
|
||||
vec4 colorAndIntensity;
|
||||
vec4 coneAngleEtc;
|
||||
};
|
||||
layout(std140, binding = 1) uniform SceneLighting {
|
||||
Light uLights[8];
|
||||
vec4 uCellAmbient;
|
||||
vec4 uFogParams;
|
||||
vec4 uFogColor;
|
||||
vec4 uCameraAndTime;
|
||||
};
|
||||
|
||||
// Retail per-vertex point-light ramp (calc_point_light 0x0059c8b0): the
|
||||
// contribution scales by (1 - dist/falloff_eff) — a LINEAR fade to exactly
|
||||
// 0 at the edge, NOT a hard-cutoff bubble. (The prior "no attenuation inside
|
||||
// Range / crisp boundaries" note was a misread; it is the literal cause of
|
||||
// the #133 "spotlight" look. falloff_eff = Falloff * static_light_factor 1.3
|
||||
// is folded into Range by LightInfoLoader.) Spots add a binary cos-cone test.
|
||||
vec3 accumulateLights(vec3 N, vec3 worldPos) {
|
||||
vec3 lit = uCellAmbient.xyz;
|
||||
int activeLights = int(uCellAmbient.w);
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
if (i >= activeLights) break;
|
||||
|
||||
int kind = int(uLights[i].posAndKind.w);
|
||||
vec3 Lcol = uLights[i].colorAndIntensity.xyz * uLights[i].colorAndIntensity.w;
|
||||
|
||||
if (kind == 0) {
|
||||
// Directional: "forward" is the light's direction vector
|
||||
// pointing INTO the scene. N·(-forward) = light-facing.
|
||||
vec3 Ldir = -uLights[i].dirAndRange.xyz;
|
||||
float ndl = max(0.0, dot(N, Ldir));
|
||||
lit += Lcol * ndl;
|
||||
} else {
|
||||
// Point / spot: falloff is a HARD bubble at Range.
|
||||
vec3 toL = uLights[i].posAndKind.xyz - worldPos;
|
||||
float d = length(toL);
|
||||
float range = uLights[i].dirAndRange.w;
|
||||
if (d < range && range > 1e-3) {
|
||||
vec3 Ldir = toL / max(d, 1e-4);
|
||||
float ndl = max(0.0, dot(N, Ldir));
|
||||
// calc_point_light (1 - dist/falloff_eff) linear ramp; Range already
|
||||
// carries falloff_eff (Falloff * 1.3), so it fades to 0 at the cutoff.
|
||||
float atten = clamp(1.0 - d / max(range, 1e-3), 0.0, 1.0);
|
||||
if (kind == 2) {
|
||||
// Spotlight: hard-edged cos-cone test.
|
||||
float cos_edge = cos(uLights[i].coneAngleEtc.x * 0.5);
|
||||
float cos_l = dot(-Ldir, uLights[i].dirAndRange.xyz);
|
||||
atten *= (cos_l > cos_edge) ? 1.0 : 0.0;
|
||||
}
|
||||
// Retail per-channel "no-blowout" cap (calc_point_light 0x0059c8b0): a single
|
||||
// point/spot light can't push a channel past its own colour, regardless of
|
||||
// intensity (~100) — kills the close-torch overblow (#93). See mesh_modern.frag.
|
||||
lit += min(Lcol * ndl * atten, uLights[i].colorAndIntensity.xyz);
|
||||
}
|
||||
}
|
||||
}
|
||||
return lit;
|
||||
}
|
||||
|
||||
// Linear fog (r12 §5.1): mode 1 = LINEAR, 0 = off, others reserved.
|
||||
vec3 applyFog(vec3 lit, vec3 worldPos) {
|
||||
int mode = int(uFogParams.w);
|
||||
if (mode == 0) return lit;
|
||||
float d = length(worldPos - uCameraAndTime.xyz);
|
||||
float fogStart = uFogParams.x;
|
||||
float fogEnd = uFogParams.y;
|
||||
float span = max(1e-3, fogEnd - fogStart);
|
||||
float fog = clamp((d - fogStart) / span, 0.0, 1.0);
|
||||
return mix(lit, uFogColor.xyz, fog);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 sampled = texture(uDiffuse, vTex);
|
||||
|
||||
// Alpha cutout only for clip-map surfaces (doors, windows, vegetation).
|
||||
if (uTranslucencyKind == 1 && sampled.a < 0.5) discard;
|
||||
|
||||
vec3 N = normalize(vWorldNormal);
|
||||
vec3 lit = accumulateLights(N, vWorldPos);
|
||||
|
||||
// Lightning flash (r12 §9) — additive cold-white pulse layered on top
|
||||
// of diffuse lighting.
|
||||
float flash = uFogParams.z;
|
||||
lit += flash * vec3(0.6, 0.6, 0.75);
|
||||
|
||||
// Clamp per-channel to 1.0 — matches retail (r13 §13.1).
|
||||
lit = min(lit, vec3(1.0));
|
||||
|
||||
vec3 rgb = sampled.rgb * lit;
|
||||
|
||||
// Atmospheric fog — applied after lighting.
|
||||
rgb = applyFog(rgb, vWorldPos);
|
||||
|
||||
fragColor = vec4(rgb, sampled.a);
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
#version 430 core
|
||||
layout(location = 0) in vec3 aPos;
|
||||
layout(location = 1) in vec3 aNormal;
|
||||
layout(location = 2) in vec2 aTex;
|
||||
|
||||
uniform mat4 uModel;
|
||||
uniform mat4 uView;
|
||||
uniform mat4 uProjection;
|
||||
|
||||
out vec2 vTex;
|
||||
out vec3 vWorldNormal;
|
||||
out vec3 vWorldPos;
|
||||
|
||||
void main() {
|
||||
vTex = aTex;
|
||||
// Transform the mesh normal into world space. For uniform-scale transforms
|
||||
// (the common case), the upper-left 3x3 of uModel is correct. Non-uniform
|
||||
// scale would require the inverse transpose; we accept that as a Phase 3+
|
||||
// concern.
|
||||
vWorldNormal = normalize(mat3(uModel) * aNormal);
|
||||
vec4 world = uModel * vec4(aPos, 1.0);
|
||||
vWorldPos = world.xyz;
|
||||
gl_Position = uProjection * uView * world;
|
||||
}
|
||||
|
|
@ -11,14 +11,14 @@ struct InstanceData {
|
|||
|
||||
// Campaign V slice V2 (2026-07-27): textureHandle (uvec2, a 64-bit
|
||||
// GL_ARB_bindless_texture handle) became textureIndex (uint) plus an explicit
|
||||
// pad word. textureIndex is a slot into the binding=9 handle table
|
||||
// (common.glsl) which main() below forwards to the fragment stage, where slice
|
||||
// V6e moved the lookup so the same source compiles for Vulkan. The pad word keeps
|
||||
// textureLayer/flags at their original std430 offsets (8/12), so the struct
|
||||
// is still 16 bytes and every existing CPU writer's layout is unchanged
|
||||
// (GpuBindingModel.GpuBatchDataStrideBytes).
|
||||
// pad word. textureIndex is a slot into the global texture table (set 2,
|
||||
// injected by tools/ShaderCompiler/VulkanGlslPreamble.cs — see
|
||||
// ACDREAM_TEXTURE_HANDLE/ACDREAM_SAMPLE_ARRAY) which main() below forwards to
|
||||
// the fragment stage. The pad word keeps textureLayer/flags at their original
|
||||
// std430 offsets (8/12), so the struct is still 16 bytes and every existing
|
||||
// CPU writer's layout is unchanged (GpuBindingModel.GpuBatchDataStrideBytes).
|
||||
struct BatchData {
|
||||
uint textureIndex; // slot into the binding=9 handle table
|
||||
uint textureIndex; // slot into the global texture table
|
||||
uint _pad; // keeps textureLayer/flags at offsets 8/12
|
||||
uint textureLayer; // layer in the shared WB or pooled composite array
|
||||
uint flags; // reserved — N.5 dispatcher owns all blend state
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ in vec4 vColor;
|
|||
// Campaign V slice V6e: the texture-table SLOT, not the bindless handle — see
|
||||
// particle.vert. ACDREAM_TEXTURE_NONE is the untextured particle, which used to
|
||||
// be spelled "the slot whose handle is zero"; a Vulkan descriptor array cannot
|
||||
// be asked that question, so the answer lives in the index (common.glsl).
|
||||
// be asked that question, so the answer lives in the index (see
|
||||
// tools/ShaderCompiler/VulkanGlslPreamble.cs).
|
||||
flat in uint vTextureIndex;
|
||||
out vec4 fragColor;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,8 +10,9 @@ layout(location = 3) in vec4 aAxisX;
|
|||
layout(location = 4) in vec4 aAxisY;
|
||||
layout(location = 5) in vec4 aColor;
|
||||
// Campaign V slice V2c (2026-07-27): was uvec2 aTextureHandle (a raw
|
||||
// ARB_bindless_texture handle); now a slot into the binding=9 handle table
|
||||
// (ACDREAM_TEXTURE_HANDLE, common.glsl).
|
||||
// ARB_bindless_texture handle); now a slot into the global texture table
|
||||
// (ACDREAM_TEXTURE_HANDLE, injected by
|
||||
// tools/ShaderCompiler/VulkanGlslPreamble.cs).
|
||||
layout(location = 6) in uint aTextureIndex;
|
||||
|
||||
uniform mat4 uViewProjection;
|
||||
|
|
|
|||
|
|
@ -7,9 +7,10 @@ in float vFogFactor; // 1 = no fog, 0 = full fog color
|
|||
out vec4 fragColor;
|
||||
|
||||
// Campaign V slice V6e: the sky's texture is now read through the shared table
|
||||
// (ACDREAM_SAMPLE_2D, common.glsl) rather than a `uniform sampler2D` bound to
|
||||
// texture unit 0. Vulkan has no default uniform block to declare a loose
|
||||
// sampler in, and set 2 is where every sampled texture lives.
|
||||
// (ACDREAM_SAMPLE_2D, injected by tools/ShaderCompiler/VulkanGlslPreamble.cs)
|
||||
// rather than a `uniform sampler2D` bound to texture unit 0. Vulkan has no
|
||||
// default uniform block to declare a loose sampler in, and set 2 is where
|
||||
// every sampled texture lives.
|
||||
//
|
||||
// The wrap mode travels WITH the slot: SkyRenderer registers a distinct table
|
||||
// entry per (texture, sampler) pair, so the per-submesh Repeat-vs-ClampToEdge
|
||||
|
|
|
|||
|
|
@ -17,31 +17,13 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "mesh",
|
||||
"vulkanReady": false,
|
||||
"stages": [
|
||||
{
|
||||
"stage": "vert",
|
||||
"sourceSha256": "c35f767ab07fa9df805f9e77f4851f517c153dd2ef2efa6d49d0c24b688e4f56",
|
||||
"compiled": false,
|
||||
"message": "mesh.vert:73: error: \u0027uModel\u0027 : undeclared identifier"
|
||||
},
|
||||
{
|
||||
"stage": "frag",
|
||||
"sourceSha256": "4d6478543a9a903a3453581fa847e096aaecf01f38ebb2921572663bad8e24ea",
|
||||
"compiled": false,
|
||||
"message": "mesh.frag:160: error: \u0027uDiffuse\u0027 : undeclared identifier"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "mesh_modern",
|
||||
"vulkanReady": true,
|
||||
"stages": [
|
||||
{
|
||||
"stage": "vert",
|
||||
"sourceSha256": "770e6300e023bd2600e8fed52768c624d8fff2ff8d6f997f076980502d3f675b",
|
||||
"sourceSha256": "2c37aa0fd1ee4af5ee1f6541b00e6a7226d4173988e748b1fb1c271b0a9b91b2",
|
||||
"compiled": true
|
||||
},
|
||||
{
|
||||
|
|
@ -57,12 +39,12 @@
|
|||
"stages": [
|
||||
{
|
||||
"stage": "vert",
|
||||
"sourceSha256": "9629271f8997853a3c78a3cb1ec7af02a13518d68bdaa5ae1378997da7e5ab62",
|
||||
"sourceSha256": "921c32617708b3931a6304b4697ee96d728077d96f489d6c09eea4c5fe225b63",
|
||||
"compiled": true
|
||||
},
|
||||
{
|
||||
"stage": "frag",
|
||||
"sourceSha256": "bc08e4fb6f57da94d6c41d52aa81d73ab287c968214303a446c40a04d0495b40",
|
||||
"sourceSha256": "6f2a5769670087bf58b0c1a7a007c1853952354dfd9106973656311bcbb855cd",
|
||||
"compiled": true
|
||||
}
|
||||
]
|
||||
|
|
@ -110,7 +92,7 @@
|
|||
},
|
||||
{
|
||||
"stage": "frag",
|
||||
"sourceSha256": "bcb21fd47fc6f74a75edd349bc3dff6120b8995115b2a08269a22f98c0bedd6c",
|
||||
"sourceSha256": "8de9a5d8f819d1abf893f134cf8ed9fa7edf937a353a74d2befab7b05a3ff700",
|
||||
"compiled": true
|
||||
}
|
||||
]
|
||||
|
|
@ -126,7 +108,7 @@
|
|||
},
|
||||
{
|
||||
"stage": "frag",
|
||||
"sourceSha256": "21f41dcca4d4973ad9ee148c5433e0dae015489414c164c51bde958963f03598",
|
||||
"sourceSha256": "a9f0ad2e679b68ee2de6c4877202f6f5e5089d0f7368fcedd6048891c6848915",
|
||||
"compiled": true
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -5,15 +5,16 @@
|
|||
// Math identical to terrain.frag (Phase 3c per-cell maskBlend3 +
|
||||
// Phase G fog + lightning flash).
|
||||
//
|
||||
// Texture reads go through ACDREAM_SAMPLE_ARRAY (common.glsl) since slice
|
||||
// V6f-3, so this source compiles for both backends. Under GL that still expands
|
||||
// to the uvec2-handle + sampler2DArray-constructor pattern this shader has
|
||||
// always used — the documented "always works" form per the ARB_bindless_texture
|
||||
// spec, and the one that avoids the GL_INVALID_OPERATION the alternative
|
||||
// (`uniform sampler2DArray` set via glProgramUniformHandleARB) produces on at
|
||||
// least one driver in practice. Under Vulkan it indexes the set-2 descriptor
|
||||
// array instead. The extension requirement above is dropped for Vulkan by the
|
||||
// compiler's preamble, where it would be an error rather than a no-op.
|
||||
// Texture reads go through ACDREAM_SAMPLE_ARRAY, which
|
||||
// tools/ShaderCompiler/VulkanGlslPreamble.cs injects to index the set-2
|
||||
// descriptor array. GL is deleted (Campaign V slice V11); before that this
|
||||
// macro expanded (via the now-deleted common.glsl) to the uvec2-handle +
|
||||
// sampler2DArray-constructor pattern this shader used on that arm — the
|
||||
// documented "always works" form per the ARB_bindless_texture spec, and the
|
||||
// one that avoided the GL_INVALID_OPERATION the alternative (`uniform
|
||||
// sampler2DArray` set via glProgramUniformHandleARB) produced on at least one
|
||||
// driver in practice. The extension requirement above is dropped for Vulkan
|
||||
// by the compiler's preamble, where it would be an error rather than a no-op.
|
||||
|
||||
in vec2 vBaseUV;
|
||||
in vec3 vWorldNormal;
|
||||
|
|
@ -30,8 +31,9 @@ out vec4 fragColor;
|
|||
|
||||
// Campaign V slice V2b (2026-07-27): uTerrainHandle/uAlphaHandle (uvec2, raw
|
||||
// ARB_bindless_texture handles) became uTextureIndexA/uTextureIndexB (slots
|
||||
// into the binding=9 handle table, ACDREAM_TEXTURE_HANDLE in common.glsl).
|
||||
// Named to match the pinned GpuPushConstants.TextureIndexA/B fields so V4d's
|
||||
// into the global texture table, ACDREAM_TEXTURE_HANDLE injected by
|
||||
// tools/ShaderCompiler/VulkanGlslPreamble.cs). Named to match the pinned
|
||||
// GpuPushConstants.TextureIndexA/B fields so V4d's
|
||||
// move to push constants is a rename, not a redesign — there is no
|
||||
// push-constant plumbing yet, so these stay plain uniforms for now.
|
||||
uniform uint uTextureIndexA;
|
||||
|
|
@ -45,8 +47,8 @@ uniform uint uTextureIndexB;
|
|||
// question both dialects can answer ("sample table slot N at these
|
||||
// coordinates") and expands to the right thing on each.
|
||||
//
|
||||
// A SAMPLING macro, not a sampler-returning one, for the reason common.glsl
|
||||
// records: under Vulkan the expansion carries `nonuniformEXT` on the indexing
|
||||
// A SAMPLING macro, not a sampler-returning one, for the reason
|
||||
// VulkanGlslPreamble.cs records: under Vulkan the expansion carries `nonuniformEXT` on the indexing
|
||||
// expression, and binding the result to a local sampler2DArray first is exactly
|
||||
// where an implementation may drop that qualifier. The old `#define uTerrain
|
||||
// sampler2DArray(...)` was that shape textually, so keeping it would have
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue