SenseWeave is a Unity + OneJS hybrid for real-time particle-based drawing. This README captures the current architecture so we can reason about the system without spelunking through scripts every time.
- OneJS (React/TypeScript) UI boots the Unity scene, instantiates the key managers, and mirrors Unity state through signals.
- LayerManager owns every renderable layer (
IRenderLayer) and orchestrates rendering, grouping, ordering, and undo history. - BrushCanvas + BrushLayer collect drawing input and generate particle output textures for brush content.
- EffectLayer instances apply shader effects (per-layer or global) through the modular shader pipeline.
- ParticleRenderFeature (URP) composites layer outputs, invokes global effects, and writes the final frame.
OneJS UI ──> LayerManager ──> LayerGroups ──> Brush/Effect Layers ──> Shader pipeline ──> URP Render
IRenderLayerdefines the shared API (bypass, opacity, blend mode, render target).LayerManagerkeeps a flat stack and a hierarchicalLayerGrouptree so we can reorder and nest layers while keeping rendering straightforward.LayerGroupcomposites child outputs into its ownRenderTexture; groups can be nested and moved across the tree.BrushLayerimplementsIRenderLayerand renders brush strokes into a dedicatedRenderTextureviaCustomParticleRenderer.EffectLayerimplementsIRenderLayer, consumes an input texture, and emits a processed output using the shader pipeline.
ShaderEffectis now a polymorphic hierarchy (PixelateShaderEffect,MeltShaderEffect, etc.) rather than a field soup. Each subclass knows how to serialize/deserialize its parameters and how to push them to a material (ApplyToMaterial).ShaderEffectsubclasses expose their own parameter definitions; effect layers use these directly to apply shaders, andlayerStoremirrors Unity’s ordered layer stack (brush + FX) for the UI.EffectLayercaches per-effect materials, sets the_EffectTypeshader keyword, and callsApplyToMaterialbefore blitting.ParticleRenderFeaturefinds the cached effect manager, then applies enabled global effects with command buffers during URP’s render loop.
BrushCanvasmanages input, per-brush undo history, and serialization of stroke particle data.BrushLayerholds stroke collections, owns the per-layer render target/camera, and routes requests toCustomParticleRenderer.CustomParticleRenderer(not documented here in detail) batches particles, feeds GPU buffers, and renders into the layer render target.BrushProperties.Shape/Image/Colormodules expose geometry, texture, and color state independently so future brushes can mix sources (image-only, masked image, color-only shapes) without rewriting the renderer.
App/components/DrawingSystem.tsxcreates Unity GameObjects forLayerManager,BrushManager,ShapePackManager, and the main camera.App/stores/projectStore.tsmirrors Unity state. As of the bypass refactor, UI models trackbypassflags rather thanisVisibleto stay aligned with Unity semantics.- Types live in
App/types/SceneTypes.ts; regenerateapp.d.tswhenever C# signatures change.
Assets/– Unity scripts, shaders, materials (seeAssets/README.mdfor asset-specific notes).App/– OneJS (TypeScript + React) UI and integration logic.ARCHITECTURE_REDESIGN.md– Working roadmap/planning doc. Use it for sprint details and experiments.ShaderEffect.cs– Polymorphic effect definitions + serialization utilities.LayerManager.cs/LayerGroup.cs– Layer orchestration.ParticleRenderFeature.cs– URP render feature that pulls everything together.
- Serialization:
ShaderEffectSerializercan read both the new format and the legacy flat model. Hook it into any persistence path that saves effect stacks. - Typing: Always regenerate
app.d.tsafter C# changes so TypeScript stays correct. - Debug Logging: Several components still emit verbose
Debug.LogWarningcalls (especially the new effect pipeline). Trim or gate them once the pipeline stabilizes.
- Layer blend modes & opacity are still TODO in the runtime; document the blending strategy once implemented.
- When new layer types (image/video/audio) come online, extend this README with their lifecycle and render integration.
- If we formalize save/load flows, add a persistence section covering canvas data, effect stacks, and UI state syncing.