Commit Graph
43 Commits
Author SHA1 Message Date
Cursor Agentand西风逍遥游 d80df444aa refactor(scene): register link kinds instead of hard-coding them
A scene link keeps an external object in step with the node it hangs off. The
kinds were a closed enum with a switch in TransformSystem, so scene had to
include graphics, physics and audio to do the casts, and no other module could
ever attach to the tree without editing SceneHost.h -- particles, voxel,
spritestack, avatar and weather all had to stay outside it.

Kinds are registered now (scene/SceneLink.h). The module owning the target type
supplies pushWorld / pullWorld / alive, keeps the casts on its own side where
the type is complete, and scene never learns what a Renderable3D is. Dispatch is
a function-pointer table rather than virtual calls, since link sync runs for
every dirty node every frame.

The six typed helpers (linkRenderable2D and friends) stay as conveniences and
now resolve their kind by name, so they return false rather than crash when the
module that registers it was trimmed out. The script API already named kinds
with strings, which is exactly the registry key, so it is unchanged.

Direction is now the right way round: graphics, physics and audio depend on
scene rather than scene on them, and scene drops from L5 to L1. What remains is
scene -> graphics from pickScreenAt / collectFrustumIdsAt, which take a Camera3D
and read its projection; that is recorded in the back-edge whitelist as the next
thing to move.

Each provider lives in a SceneLinks.cpp, sharing the basename so the three come
out of the build together when scene is disabled.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-08-18 13:46:25 +00:00
Cursor Agentand西风逍遥游 f7aacbc4a9 refactor(event): let modules translate their own platform events
The SDL pump did the translation itself, so it had to know about keyboard,
joystick, touch, window, graphics, audio and ui: eight upward dependencies from
one of the engine's lowest modules, and the source of every remaining
dependency cycle.

Each module now registers an IPlatformEventSink for the events it owns and the
pump only dispatches. Key and text events move to keyboard/sdl, joystick and
game-controller events (including the hotplug device table) to joystick/sdl,
finger events to touch/sdl, resize and the mobile background/foreground surface
watch to window/sdl, the ImGui observer to ui, and Audio::pump to an
end-of-pump hook in audio. The pump keeps only quit and window-close, which are
about the event loop rather than any one module.

Sinks run in priority order -- observer, then surface, then input -- so ImGui
still sees events first and the window is resized before anything reads its
size. The mobile surface teardown keeps using SDL_AddEventWatch rather than the
poll path, since by the time SDL_PollEvent returns the native surface is gone;
the watch is now installed by the window module on its first pump.

Also removes exceptionIfInRenderPass, whose body has been commented out since
it was written and whose only remaining effect was a graphics include.

The engine dependency graph now has zero cycles, down from 26, and the back-edge
whitelist is down to 2 (window -> graphics, window -> image). Layering is also
right way up: event sits at L0 with the input modules above it at L1/L2.

Verified: unit tests for event/input/ui/audio/thread pass, and the example
smoke suite gives the same 19 pass / 9 fail as the pre-change baseline (those 9
fail on main too, from script API drift in the examples themselves).

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-08-18 13:46:04 +00:00
Cursor Agentand西风逍遥游 164e8c1b4c refactor(filesystem): dispatch hot reload instead of hard-coding asset kinds
HotReload knew what lived at every watched path: it included graphics to
refresh textures, particles to reload emitter configs and map to reload tile
layers. That made the engine's lowest-level module depend on three of its
highest, and it was the only reason filesystem sat in a dependency cycle.

Each module now registers an eve::caps::IAssetReloader for the assets it owns
and HotReload only routes paths. Behaviour is unchanged: automatic dispatch
still matches by extension, an explicit bind() still targets one kind and
ignores the extension, and the texture reloader runs at kTexture priority so
the GPU upload happens before emitters and tile layers re-bind to it.

The reloadable set now follows the linked module set, so a build without
particles simply has no particle reloader rather than a dangling reference.
Reload kinds also become extensible: a module or plugin can add one without
touching filesystem.

Back-edge whitelist 14 -> 11; the dependency graph is now acyclic apart from
the event pump.

(map.render.tilesContributeDepthY fails when run after the hotreload cases both
before and after this change -- pre-existing test-order state, not from here.)

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-08-18 13:46:04 +00:00
Cursor Agentand西风逍遥游 08679654e0 feat(common): add the capability registry, use it for GPU info and main-thread posts
Introduces eve::cap in common/Capability.h: a name-keyed registry where the
consumer owns the interface, the provider registers an implementation, and
neither includes the other. It generalises what common/RenderTrace.h already
does for the render tracer, and supports both a single provider (provide/query)
and many ordered ones (addListener/forEach), keyed by string so a provider
compiled into a plugin lands in the same slot as the host.

Two upward dependencies go away:

  system -> graphics   IGpuInfo. The Vulkan physical-device fields move into
                       graphics/vulkan/GpuInfoProvider.cpp, with a WebGPU
                       counterpart, so System.cpp loses both the graphics
                       include and its EVENGINE_WEBGPU branches.

  thread -> event      IMainThreadPost. postMain and submitPost now enqueue
                       through the capability. The interface makes explicit
                       what was previously only a comment in submitPost: the
                       submitting thread calls prepare() so the worker never
                       reaches the module registry.

Both now report an error when no provider is linked, rather than lazily
creating a module the build may not contain.

Step S3 of docs/dev/模块编排与裁剪架构.md; back-edge whitelist 16 -> 14.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-08-18 13:46:04 +00:00
Cursor Agentand西风逍遥游 c4fd641115 docs: add module orchestration and trimming architecture analysis
Analyse how the 53 modules currently collaborate and why none of them can be
trimmed outside the hardcoded WASM axis, then lay out a target architecture and
a six-step route to per-module build options.

Adds scripts/module_depgraph.py, which produces the dependency graph, the
7-layer topological ordering and the cycle list the document cites. Its --check
mode fails on any back-edge outside the 16 known ones, so it doubles as the CI
guardrail for step S1.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-08-18 13:46:04 +00:00
西风逍遥游 cff9bb4d0c tensor: AITemplate-style compile pipeline, gpgpu Sequence, mini-LLM demo and weight-only quantization
Refactor the tensor module around AITemplate-style static compilation:

- Optimizer: DCE, constant folding, elementwise chain fusion, matmul/conv
  bias+activation epilogue fusion, liveness-based static memory planning,
  topological group execution order.
- KernelGen: shape-baked GLSL per fused group; two-pass softmax/layernorm;
  shared-memory SDPA; naive + 16x16 tiled matmul templates.
- GpuBackend: arena buffer allocation per memory plan, matmul autotuning,
  single command-buffer submission via the new gpgpu::Sequence (uploads,
  dispatches and downloads recorded once per run, Kompute-style).
- shaderc in-process GLSL->SPIR-V on Windows (no glslc.exe dependency),
  with glslc spawn fallback.
- CPU reference kernels shared by eager and the compiled interpreter;
  no-Vulkan fallback keeps compiled graphs runnable headless.

Neural-network coverage: softmax/logsoftmax, layernorm/rmsnorm (with
weight/bias), gelu/silu, conv1d/conv2d, pool, embedding, concat/slice,
axis reduces, argmax, cast, fused SDPA (+masked), resize2d, batched
matmul, seeded random.

Weight-only quantization (activations stay fp32):
- fp16 (IEEE half), fp8 (e4m3), fp4 (e2m1), int8, int4 with per-group
  block scales (MXFP-style: scale = maxAbs / format max magnitude).
- Quantized weights capture into graph Const nodes; CPU interpreter
  dequantizes at materialization; GPU matmul/embedding kernels dequantize
  inline from packed uint buffers (naive matmul variant).
- TF::quantizeWeight API + script binding.

Mini-LLM validation (TinyStories-gpt2-3M, 8 layers d=64):
- test/tensor_llm.cpp builds the full GPT-2 graph from engine ops and
  matches numpy reference: probs within 3e-7, greedy generation 24/24
  identical (~100 ms/token CPU), compiled path exact.
- tensor.llm.quantizedDtypes: fp16/int8/fp8/int4 all keep 16/16 greedy
  top-1 (fp4 16/16 with proper block scaling), weights 27.6 MB -> 3.3-13 MB.
- scripts/export_tiny_gpt2.py converts a PyTorch .bin checkpoint (no torch
  dependency) plus GPT-2 tokenizer into engine assets + numpy reference.

Tests: gpgpu 8/8, tensor 31/31 (original suite) + tensor.llm.* + tensor.quant.*
Assets in test/assets/mini_llm are gitignored (regenerate via the script).
2026-08-18 17:42:38 +08:00
sunxfancy 788adcbb53 Merge remote-tracking branch 'origin/main' into feature/virtual-geometry-nanite
# Conflicts:
#	CMakeLists.txt
#	src/engine/CMakeLists.txt
#	src/modules/graphics/Graphics.cpp
#	src/modules/graphics/Graphics.h
2026-08-17 17:14:42 +08:00
西风逍遥游 fe7b68deb4 feat(spritestack): sprite-stacking pseudo-3D rendering 2026-08-17 13:58:03 +08:00
sunxfancy fed7c3ff11 Merge remote-tracking branch 'origin/main' into feature/virtual-geometry-nanite 2026-08-16 21:49:45 +08:00
sunxfancy 2f13169b68 feat(virtualgeometry): add Nanite-style virtualized geometry rendering
Add a virtualgeometry module implementing a Nanite-inspired virtualized
geometry pipeline on the Vulkan backend:

- Cluster DAG preprocess (CPU): greedy meshletization + QEM edge-collapse
  hierarchical LOD, with per-cluster bounding spheres and geometric error.
- GPU-driven culling (compute): frustum + screen-space-error LOD selection
  that emits exactly one cluster per DAG branch (no gaps/overlaps).
- Software cluster rasterizer (compute): fills a visibility buffer
  (packed depth<<16 | clusterId) via atomicMin.
- Visibility-buffer resolve (CPU readback + resolve shader reference).
- Module facade (VirtualGeometry / VirtualGeometryRenderer) reusing the
  gpgpu compute backend; LodSelection CPU reference for tests.
- 14 unit tests (CPU preprocess + LOD-transition sweep + GPU end-to-end),
  shader compile script, example, and design doc.
2026-08-16 21:49:40 +08:00
西风逍遥游 095556319e Merge branch 'main' into feature/waterfall-shader 2026-08-16 21:29:04 +08:00
sunxfancy 28458bd104 fix(graphics): precompile water shader to SPIR-V for cross-platform support
Water used newMeshShader (runtime glslc compile), which is unsupported on
Windows (compileGlslWithGlslc throws there), failing graphics.water.* tests in
the Windows CI job. Extract the water fragment to shaders/water.frag, compile
it to water_frag_spv.inc, and create the shader via newMeshShaderFromSpv so it
works on every platform. Add compile_graphics_water_shaders.py.
2026-08-16 20:20:48 +08:00
sunxfancy 9d860e2d66 Merge remote-tracking branch 'origin/main' into feature/water-shader
# Conflicts:
#	src/modules/graphics/Graphics.cpp
2026-08-16 19:47:03 +08:00
sunxfancy 23ce82dba4 Merge remote-tracking branch 'origin/main' into feature/waterfall-shader 2026-08-16 16:24:52 +08:00
sunxfancy d8bf6820b6 Merge remote-tracking branch 'origin/main' into feature/waterfall-shader 2026-08-16 15:57:31 +08:00
西风逍遥游 0dfc18c08f deps: own libraries in external/, third-party deps in third-party/
Move the user-maintained VKBuilder from the third-party aggregate into external/ (git submodule), and relocate the third-party DungeonTemplateLibrary and Box3D from external/ into the third-party aggregate (previously pushed to EVEngine/third-party). Update .gitmodules, include paths, DTL/box3d build wiring, and docs.
2026-08-16 13:34:12 +08:00
西风逍遥游 7e3b73db83 Merge branch 'main' of https://github.com/EVEngine/EVEngine 2026-08-16 13:06:34 +08:00
西风逍遥游 26704c646e feat(procgen): update rendering functions and background color settings across various generators
- Renamed rendering functions to follow a consistent naming convention (e.g., `update` to `eve_update`, `draw` to `eve_render`).
- Set background colors for bush, tree, skyscraper, and other procedural generators to enhance visual consistency.
- Adjusted parameters in `gfx.drawSolidRect` and `gfx.drawTexturedRect` to use floating-point values for improved precision.
2026-08-16 13:06:28 +08:00
sunxfancy badb0d945d feat(graphics): screen-space reflection pass + Water SSR integration
Add a screen-space reflection (SSR) fullscreen pass and hook it into the Water
shader as an optional, off-by-default reflection overlay.

- ScreenSpaceReflection: ray-marches the reflected ray over the lit scene color
  + hardware depth, reconstructing the world normal from depth (mirrors the
  SSGI pass). Outputs reflected color with A = hit validity into a canvas.
  Graphics::newScreenSpaceReflection() + script binding; quality knobs
  (strength/steps/stepLen/thickness/distance) and enabled toggle.
- Water::setScreenSpaceReflection(enabled, strength) + setViewport: the water
  shader samples the reflection texture (bound via the height slot, binding 6)
  at screen UV and blends it over the env-cubemap reflection. Off by default.
- New ssr.frag + compile script; vulkan SPIR-V regenerated.

Note: SSR reflects only geometry that is on-screen. For a horizontal water plane
viewed from above the reflected geometry sits in the void below the plane (no
depth there), so SSR finds no hits there; it works for on-screen-reflective
surfaces (glossy floors/walls, grazing water). Env-cubemap reflection remains
the default; SSR is additive when enabled.
2026-08-16 12:59:59 +08:00
sunxfancy 3592c05438 Merge remote-tracking branch 'origin/main' into feature/waterfall-shader
# Conflicts:
#	src/modules/graphics/Graphics.cpp
#	src/modules/graphics/Graphics.h
2026-08-16 12:56:54 +08:00
西风逍遥游 09c4c9b662 Merge pull request #82 from EVEngine/codex/occluded-characters-shader 2026-08-16 12:33:14 +08:00
西风逍遥游 5771b193b7 feat(graphics): x-ray occluded-character shader (vulkan + webgpu)
Show only the part of a marked character that is hidden behind a building,
as a filled highlight silhouette (Overwatch-style). Visible parts render
normally.

- Shader: xray_mesh.frag samples G-buffer hardware depth (binding 7) and
  compares it against its own fragment depth: occluded (behind) pixels emit
  the highlight, visible pixels discard. Drawn as a second pass over the
  scene with depth test/write off + alpha blend.
- RenderSystem3D: MeshRenderer gains xrayShader + xrayHighlight. X-ray
  targets are skipped in the G-buffer (their pixels record occluder depth),
  then redrawn with the X-ray shader; scene depth is bound via
  Graphics::setMesh3DSceneDepth.
- Graphics: new setMesh3DSceneDepth + Shader::setXray. Vulkan adds binding 7
  to the mesh3d set layout and a dedicated X-ray pipeline variant.
- WebGPU: new newMeshShaderFromWgsl (WGSL custom mesh shaders), scene-depth
  binding 9, X-ray pipeline variant, xray params packed into the Frame UBO,
  and the G-buffer hardware depth is exposed/sampleable (getHwDepthTexture).
  AO (SPIR-V) is skipped on WebGPU via supportsGBufferPost.
- stylize: 'xray' style registered (createMeshShader dispatches SPIR-V on
  Vulkan / WGSL on WebGPU) with push-constant params.
- Tests: test/Xray.cpp (shader/flags + occluded-silhouette render smoke).
2026-08-16 04:08:55 +08:00
西风逍遥游 0049d8fa84 graphics: add screen-space model outline from GBuffer depth + normal
Add a t3ssel8r-style screen-space outline computed from the G-buffer
hardware depth and world-normal buffers. For each pixel the shader
samples an 8-neighbourhood at a configurable width and flags depth
(silhouette/occlusion) and normal (crease) discontinuities, emitting
vec4(outlineColor, edgeMask) that is SrcAlpha-blended over the scene.

- new graphics::Outline class (mirrors AmbientOcclusion) with color,
  width, depth/normal thresholds, softness and clip knobs
- new outline_post.frag + compiled SPIR-V include + compile script
- RenderControl "outline" feature (implies gbuffer, default off) applied
  by RenderSystem3D after the forward/hair passes
- Graphics.newOutline + Squirrel binding + test/Outline.cpp (params,
  feature toggle, and an interactive cube preview)
2026-08-16 00:39:44 +08:00
西风逍遥游 7afb248a3e Merge branch 'main' into cursor/stylized-grass-shader-3c1e 2026-08-15 16:51:39 +08:00
Cursor Agentand西风逍遥游 f29752dbb1 feat(graphics): add t3ssel8r-style stylized grass
Sample terrain meshes with Poisson-disk or Halton blue noise, expand
root-pivoted billboard quads, and shade them with a 4-frame sway atlas.
Instance ids desync the animation, the CSM shadow map picks between
light and dark green, and a second sparse pass adds always-dark tufts.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-08-15 06:15:15 +00:00
西风逍遥游 8dd21d3ea3 feat(webgpu): integrate WebGPU backend support and enhance build configuration
- Added support for the WebGPU backend in the CMake configuration, enabling builds for Emscripten and native Dawn.
- Implemented conditional compilation for WebGPU-specific features, including shader management and file system handling.
- Updated the build process to exclude unnecessary modules and dependencies for WebGPU, optimizing the engine for browser environments.
- Enhanced the installation script to include WebGPU-related files and directories in the output.
- Refactored existing modules to accommodate WebGPU, ensuring compatibility and performance improvements across the engine.
- Introduced new compile options and configurations tailored for WebGPU builds, including handling of third-party libraries and assets.
2026-08-15 10:46:26 +08:00
西风逍遥游 a8a71c7476 feat(ecs): enhance C++ and script integration for entity management
- Introduced a new mechanism for registering C++ entity view functions, allowing Squirrel scripts to access and manipulate C++ entities directly.
- Implemented a `cppCollect` function to traverse class hierarchies and collect C++ entities based on registered views, enhancing script interaction with C++ components.
- Updated the ECS API to expose new functions for registering C++ entity views and collecting entities in scripts.
- Enhanced existing tests to validate the new functionality and ensure proper integration between C++ and Squirrel scripts.
2026-08-14 15:07:39 +08:00
西风逍遥游 f27f6b1f09 feat(graphics): add toon shader and improve normal matrix calculations
- Introduced a new toon shader for enhanced visual effects in 3D rendering.
- Updated vertex shaders across multiple files to use the inverse-transpose of the model matrix for normal calculations, ensuring correct normal transformations for non-uniform scaling.
- Added the mesh3d_toon.vert shader to the shader compilation script.
- Updated SPIR-V binaries for affected shaders to reflect the changes in normal matrix calculations.
- Enhanced test cases to validate the new toon shader functionality and its integration with existing graphics features.
2026-08-14 12:03:25 +08:00
西风逍遥游 2e32afd71b feat(graphics): enhance rendering capabilities with 3D pipeline and ambient occlusion
- Added a new 3D rendering pipeline section in the documentation, detailing initialization, VKBuilder, and asynchronous frame handling.
- Updated the Ambient Occlusion module to support depth-based sampling, allowing for improved visual fidelity in 3D scenes.
- Introduced new shader functionalities for ambient occlusion and global illumination, enhancing the overall rendering quality.
- Updated GBuffer to include hardware depth texture for more accurate depth sampling in 3D rendering.
- Enhanced the RenderControl to manage new features for ambient occlusion and global illumination, ensuring they are enabled by default.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-08-13 10:01:04 +08:00
Cursor Agentand西风逍遥游 515c27f356 test(graphics): expand classic and procedural render scenes
Add more Khronos glTF orbit fixtures (WaterBottle, Lantern, AntiqueCamera,
CesiumMilkTruck, BarramundiFish, Corset), broaden procedural RenderScenes
coverage (depth, scale, checker, camera move, receiveShadow), fix DamagedHelmet
lighting expectations for metal-heavy assets, and soft-skip transient
swapchain/surface losses when chaining large downloaded scenes.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
2026-08-12 14:18:07 +00:00
西风逍遥游andCursor Agent 544779079f Add Material, RenderControl, and sampleable G-buffer for post effects (#43)
Introduce a compilable render feature control (shadow/gbuffer/forward/hair),
package shading into Material+ModelPart attachable to Renderable3D, and fill
sampleable linear-depth/normal (optional albedo) G-buffer targets while
keeping forward HW z-testing and CSM shadows.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-08-12 20:25:41 +08:00
西风逍遥游andCursor Agent 2aabe03720 Add hair/fur card rendering with Kajiya-Kay anisotropic shader (#42)
Introduce mesh3d_hair GLSL shaders with alpha-blended Vulkan pipeline
(no back-face cull, depth write disabled). Expose gfx.newHairShader(),
Renderable3D.setHair() for a back-to-front transparent pass in
RenderSystem3D, plus HairShader helpers and unit tests.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-08-12 18:35:47 +08:00
西风逍遥游andCursor Agent 4aeab04099 feat(image): ImageData 2D 像素旋转(逆映射 nearest/linear) (#39)
* feat(image): ImageData::rotate with inverse-map nearest/linear

Add CPU pixel rotation on ImageData using destination-to-source inverse
mapping (Geometric Tools / standard image processing). Supports nearest
and bilinear filters, optional canvas expand to fit the rotated AABB,
and matches Math::rotate2* angle convention. Includes unit tests, Font
script binding, and docs.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

* test(image): assert exact 90° rotate pixel positions

Pin nearest+expand 90° mapping of corner markers to (1,2) and (0,0).

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

* feat(image): implement RotSprite pixel-art rotation filter

Add Xenowhirl RotSprite as ImageData::rotate filter "rotsprite":
Scale2x×3 with color similarity, best 8×8 sampling offset search,
nearest-neighbor rotate+downscale, and single-pixel detail restore.
Quarter turns use an exact remapping fast path. Tests cover 90°
palette preservation and 45° no-new-colors.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

* fix(ci): M_PI on MSVC and GitHub API 403 for asset downloads

Windows unit tests failed because test/image.cpp used M_PI without the
MSVC fallback used by other test files. macOS build failed when
download_skinned_character.sh hit GitHub API 403 during PRE_BUILD; add
User-Agent + optional GITHUB_TOKEN auth to asset fetch scripts and pass
GITHUB_TOKEN in CI build steps.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-08-12 18:34:28 +08:00
西风逍遥游andCursor Agent 5d1e9f8c3d feat(building): extensible building placement system for strategy/ETS (#37)
* Add extensible building placement module for strategy/ETS games

Introduce eve.Building with data-driven definitions, grid occupancy worlds,
ghost previews, and pluggable validate/snap/change hooks. Includes design docs,
user module guide, unit tests, and a gitignore fix so build*/ no longer ignores
src/modules/building/.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

* fix(building): preserve free-snap world pose on placeAtWorld

placeAtWorld now keeps the snap rule's worldX/worldY on the placed
instance instead of always rewriting to the cell origin, so free and
custom snap modes stay accurate for ETS-style soft placement.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

* Add examples/building town placement sandbox demo

Interactive demo covering grid snap ghost preview, terrain (dock on water),
road adjacency (stall), L-mask barn, rotate/remove, and resource costs.
Also adds make building shortcut, docs links, and a unit test locking the
demo building definitions.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

* fix(ci): vendor CesiumMan test assets to avoid flaky Linux SSL download

Linux CI failed linking unit_test when PRE_BUILD curl hit a self-signed
certificate fetching CesiumMan from api.github.com. Commit the ~464 KiB
glTF fixture, skip download when files are present, and add curl retries
with explicit CA bundle for refresh runs.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-08-12 18:32:36 +08:00
西风逍遥游andCursor Agent 59b2865b85 feat(animation): CPU 蒙皮与 CesiumMan 骨骼动画测试 (#32)
* feat(animation): CPU skinning + CesiumMan download test

Add AnimSkin linear-blend skinning, ModelData bone/weight APIs, and a
network download script for Khronos CesiumMan used by animation.skinned
integration tests during unit_test builds.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

* fix(test): mount CesiumMan via physfs for skinned animation tests

Model3D loads through the VFS; use allowMountingForPath + mount like
ClassicScenes so CesiumMan.gltf resolves with its .bin sidecar.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-08-11 20:41:31 +08:00
西风逍遥游andCursor Agent f00ca29713 feat(graphics): 屏幕空间环境光遮蔽 SSAO / HBAO / GTAO (#29)
* feat(graphics): add screen-space ambient occlusion (SSAO/HBAO/GTAO)

Implement AmbientOcclusion with quality presets, bilateral blur, and
darkening overlay, following the Volumetric post-process pattern.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

* test(ao): avoid REQUIRE on unique_ptr (zeroerr print)

Match Volumetric tests: assert the raw pointer before wrapping.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-08-11 18:59:33 +08:00
西风逍遥游andCursor Agent 1fe6934c0a feat(graphics): texture cell bombing 消除平铺重复纹理 (#30)
* feat(graphics): texture cell bombing to break tiling

Add UV-space cell bombing on the default mesh3d / clustered PBR paths:
per-cell random offset and rotation blended across a 2x2 neighborhood
(with textureGrad for stable mips). Opt-in via Renderable3D::setTexCellBomb
(strength 0 keeps prior behavior). Includes GLSL helper, SPIR-V embeds,
CPU reference header, docs, and smoke tests.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

* fix(graphics): rotate UVs in cell bombing; harden GPU test

Rotate UVs about each cell center (not just translate) so periodic
textures actually break tiling. Use the known-good UV cube + repeating
motif in the pixel smoke test.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-08-11 17:01:48 +08:00
西风逍遥游andCursor Agent 3543a7343d feat(graphics): classic anti-aliasing (FXAA / SMAA / SSAA / NFAA) (#28)
* feat(graphics): add classic image-space anti-aliasing

Implement AntiAliasing (FXAA, SMAA-lite, SSAA resolve, NFAA) as a
Volumetric-style post API with quality presets, embedded SPIR-V shaders,
Squirrel bindings, tests, and docs.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

* test(aa): fix zeroerr REQUIRE(a && b) ambiguity

Split combined pointer checks so Expression decomposition does not
conflict with built-in operator&&.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-08-11 17:00:25 +08:00
西风逍遥游andCursor Agent a95d6c98ae feat(voxel): 32³ chunk greedy meshing with packed instanced faces (#26)
Add a voxel module that remeshes 32³ chunks into six face-direction
buffers of 32-bit packed rectangles (xyz+wh+tex), culls by frustum,
view range, and camera-facing normals, then draws via a new Vulkan
instanced unit-quad path (Graphics::drawVoxelFaceInstances).

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-08-11 14:48:51 +08:00
西风逍遥游andCursor Agent 922ad44b3c feat(tests): classic render scenes with camera flythrough config switching (#22)
* feat(tests): classic scene flythroughs with render config switching

Add Cornell Box (committed), procedural metal/roughness chart, and
downloadable Sponza/DamagedHelmet tests that fly the camera while
cycling ambient, directional, shadows, point lights, and IBL.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

* fix(tests): bake Assimp node transforms and light classic scenes

Apply scene-graph world matrices when spawning meshes, fix Cornell face
winding for inward normals, keep Sponza dielectric under missing MR
texture sampling, and link sndio when OpenAL builds that backend.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

* docs(tests): note ClassicScenes coverage

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-08-11 14:48:17 +08:00
西风逍遥游andCursor Agent 8aa8e35d34 feat(graphics): 体积光 + Ray March + 体积雾 (#19)
* feat(graphics): 屏幕空间体积光(尘雾 God Rays)

在 graphics 模块增加 Volumetric API:径向模糊光柱 + 尘/雾,
质量档 low/medium/high;Drawable.castOcclusion 对齐阴影语义的遮挡绘制。

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

* feat(graphics): 体积光 Ray March 二期 + 扩展测试

合并 main;新增 raymarch 模式(线性深度积分 + 屏空间遮挡近似 CSM),
补充 mode/质量/drawOccluders2D/ray march 等测试(11 用例)。

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

* feat(graphics): 体积雾(高度/距离 Beer-Lambert)

新增 setMode("fog") / applyFog:线性深度上积分高度指数雾与距离 ramp,
输出非预乘 RGB+alpha 以适配 SrcAlpha 混合。合并 main(gpgpu ECS)后补齐
cmake 源扫描,并扩展 volumetric 单测(15/15)。

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

* fix(test): GraphicsSmoke missing-texture 不再竞态 setupWriteDirectory

Mac CI 并行跑 clearAndPresentWindow 时共用 Filesystem identity,
ThrowsOnMissing 里多余的 bootstrap 会失败。缺文件抛错只需 PhysFS open,
并给写目录 bootstrap 使用独立 identity。

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-08-10 23:15:51 +08:00
西风逍遥游andCursor Agent 709fbd7686 feat(stylize): 风格化渲染模组(卡通 / 水彩 / 水墨 / 像素) (#8)
* feat(stylize): add NPR stylized rendering module

Add eve.Stylize with cartoon, watercolor, ink, and pixel post-process
shaders, mesh variants for cartoon/ink, CPU processImage helpers, and
StylePass integration over graphics Shader/Canvas.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

* fix(stylize): fix unit test Color/unique_ptr assertions

Use global Color typedef and compare unique_ptr via get() so zeroerr
decomposition does not try to copy unique_ptr.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

* feat(stylize): cylinder style gallery PNGs for docs

Add Graphics::newMeshCylinder and a gallery test that renders a lit
cylinder in cartoon/ink/watercolor/pixel styles, writing PNGs into
docs/images/stylize for the design doc. Fix pixel toon banding so dark
bands are not crushed to black.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

* fix(stylize): close gap vs research NPR looks in gallery

Stabilize lighting (no blown whites), use silhouette-only outlines so
stripe albedo no longer blacks out the form, composite watercolor/ink
onto paper, and retune cel/wash/pixel passes toward UTS / Bousseau /
Sumi-e / pixel-pipeline cues. Refresh cylinder gallery PNGs.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

* feat(stylize): stabilize extension APIs for future NPR work

Add StyleChain, newPassFromShader, applyTo, supports()/param
introspection, and document reserved gbuffer/multi-pass hooks.
Effects stay as first-pass approximations; the public surface is
what subsequent depth-outline and separable passes should plug into.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-08-09 23:09:10 +08:00
西风逍遥游andCursor Agent 6f290b2a1d feat(procgen): 程序化生成模块 Phase A/B(地图 + 贴图) (#5)
* docs(procgen): add procedural generation module design

Capture confirmed product direction (runtime map-first, textures
second, pixel/low-poly RPG) plus API sketch, algorithm registry,
configurable outputs, and Phase A checklist.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

* docs(procgen): list procgen in module summary table

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

* feat(procgen): Phase A runtime map generation with DTL

Add eve.Procgen module: semantic Grid2D, algorithm registry, palettes,
and TileLayer/JSON outputs. Built-ins use Dungeon Template Library
(BSP, cellular cave, maze, perlin terrain) plus local drunkard walk.
Includes tests and examples/procgen demo.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

* feat(procgen): Phase B runtime pixel texture recipes

Add seamless value-noise texture generation with banded color ramps
for soil/stone/marble/water/sky_cloud, ImageData/Texture/normal outputs,
and script bindings for gfx.newTexture / drawTexturedRect.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

* fix(test): qualify eve::image::ImageData in procgen tests

Bare image:: failed to resolve under `using namespace eve::procgen`,
breaking unit_test builds on Linux/Windows/macOS CI.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

* fix(procgen): link EVProcgen in tests and fix Apple Clang DTL build

unit_test was missing EVProcgen, causing undefined references on Linux/Windows.
Avoid the DTL umbrella header (broken Voronoi CRTP on Apple Clang) and provide
DrawJagged* compat shims that define the missing drawOperatorArray.
Verified locally: linux-debug build, unit_test link, and all 13 procgen ctests.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-08-09 08:47:27 +08:00