summaryrefslogtreecommitdiff
path: root/doc/SHADER_REUSE_INVESTIGATION.md
blob: 4f83f1dbd8273a7a51e49b206bec1dc7604550c2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# Shader Code Reuse Investigation

## Current State

### Duplication Analysis
- **36 duplicate shader files** between main and test workspaces
- Common files include: math utilities, render helpers, compute shaders, uniforms
- Files are byte-identical duplicates (verified)

### Current System Architecture
1. **ShaderComposer**: Runtime shader composition via `#include` directives
2. **Asset System**: Shaders loaded from workspace `assets.txt`
3. **Registration**: `InitShaderComposer()` registers snippets with paths like:
   - `common_uniforms`
   - `math/sdf_shapes`, `math/noise`, `math/common_utils`
   - `render/shadows`, `render/scene_query_bvh`, `render/lighting_utils`

### Duplicate Common Shaders
```
Common across both workspaces:
- common_uniforms.wgsl
- math/{common_utils, noise, sdf_shapes, sdf_utils}.wgsl
- render/{lighting_utils, scene_query_bvh, scene_query_linear, shadows}.wgsl
- compute/{gen_blend, gen_grid, gen_mask, gen_noise, gen_perlin}.wgsl
- Various effect shaders (passthrough, lighting, ray_box, etc.)
```

---

## Proposed Approaches

### Option 1: Shared Common Directory (Original Design)
**Structure:**
```
/common/
  /shaders/
    /math/          # Shared math utilities
    /render/        # Shared rendering helpers
    /compute/       # Shared compute shaders
    common_uniforms.wgsl

/workspaces/
  /main/
    /shaders/       # Workspace-specific only
    /music/
    /weights/
    /obj/
```

**Pros:**
- Single source of truth for common code
- No duplication
- Clear separation: common vs workspace-specific
- Matches original design doc intent

**Cons:**
- Breaks workspace isolation (workspaces depend on external directory)
- Harder to version control per-workspace
- Need to update asset packer to handle cross-workspace references
- Complicates workspace portability

---

### Option 2: Symbolic Links
**Structure:**
```
/workspaces/
  /main/
    /shaders/
      /common@ -> ../../common/shaders/  # Symlink
      custom_effect.wgsl
```

**Pros:**
- Maintains single source
- Works with existing asset system
- Simple filesystem solution

**Cons:**
- Windows symlink issues (requires admin or dev mode)
- Git symlink handling varies
- Still breaks workspace isolation
- Can confuse developers

---

### Option 3: Build-Time Copy/Sync
**Structure:**
Workspaces keep duplicates, but sync from canonical source at build time.

```
/common/shaders/     # Canonical source
/workspaces/*/shaders/  # Build-synced copies
```

**Implementation:**
- CMake script copies common/ → workspaces/ before asset packing
- Or: Pre-commit hook validates consistency

**Pros:**
- Workspaces remain self-contained
- No runtime dependencies
- Works across all platforms
- Git shows actual files

**Cons:**
- Easy to forget sync
- Merge conflicts if edited in workspace
- Need tooling to maintain consistency

---

### Option 4: Asset System Extension
**Enhance asset packer to support cross-workspace includes:**

`workspaces/main/assets.txt`:
```
SHADER_COMMON_UTILS, NONE, @common/shaders/math/common_utils.wgsl
SHADER_CUSTOM, NONE, shaders/custom_effect.wgsl
```

**Pros:**
- Clean at asset definition level
- ShaderComposer unchanged
- Explicit common vs local

**Cons:**
- Asset packer modification needed
- New syntax to learn
- Breaks workspace portability

---

### Option 5: Status Quo + Documentation
**Keep duplicates, document as intentional.**

Add `common/shaders/` as reference templates that workspaces copy.

**Pros:**
- Workspaces fully independent
- Can diverge per-workspace if needed
- No build system changes
- Simple mental model

**Cons:**
- Ongoing duplication
- Manual sync required
- Disk space (minimal impact)
- Bug fixes need multi-workspace updates

---

## Recommendation Matrix

| Criteria | Opt 1 | Opt 2 | Opt 3 | Opt 4 | Opt 5 |
|----------|-------|-------|-------|-------|-------|
| No duplication | ✓ | ✓ | ✗ | ✓ | ✗ |
| Workspace isolation | ✗ | ✗ | ✓ | ✗ | ✓ |
| Cross-platform | ✓ | ✗ | ✓ | ✓ | ✓ |
| Low complexity | ✗ | ✓ | ✗ | ✗ | ✓ |
| Easy maintenance | ✓ | ✓ | ✗ | ✓ | ✗ |

---

## Current Implementation Details

### How Shaders Are Currently Included

**In WGSL files:**
```wgsl
#include "common_uniforms"
#include "math/sdf_shapes"
#include "render/shadows"
```

**In C++ (shaders.cc):**
```cpp
void InitShaderComposer() {
  auto& sc = ShaderComposer::Get();
  sc.RegisterSnippet("common_uniforms", ...);
  sc.RegisterSnippet("math/sdf_shapes", ...);
  sc.RegisterSnippet("render/shadows", ...);
}
```

**Asset Registration (assets.txt):**
```
SHADER_MATH_SDF_SHAPES, NONE, shaders/math/sdf_shapes.wgsl
SHADER_RENDER_SHADOWS, NONE, shaders/render/shadows.wgsl
```

### ShaderComposer Flow
1. Assets loaded from workspace `assets.txt`
2. Snippets registered in `InitShaderComposer()`
3. Effects call `Compose()` with dependencies
4. `#include` directives recursively resolved
5. Final shader string assembled

---

## Next Steps

1. **Decide on approach** based on project priorities:
   - Simplicity → Option 5
   - True reuse → Option 1 or 4
   - Compatibility → Option 3

2. **If Option 1 chosen:**
   - Create `/common/shaders/` with canonical sources
   - Update `workspace.cfg` to reference common
   - Update asset packer to resolve `../common/` paths
   - Update docs

3. **If Option 3 chosen:**
   - Create sync script in `scripts/`
   - Add to build process
   - Document workflow

4. **If Option 5 chosen:**
   - Create `/common/shaders/` as templates
   - Add `doc/SHADER_COMMON.md` explaining pattern
   - Accept duplication as intentional