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
|
# Shader Composability Improvement
## Created: `math/common_utils.wgsl`
Common utility functions to reduce duplication:
- `transform_normal()` - Normal matrix transform (was in 2 shaders)
- `spherical_uv()` - Spherical UV mapping (was in 7+ places)
- `spherical_uv_from_dir()` - For skybox/direction vectors
- `calc_sdf_normal_bumped()` - Bump-mapped normal (36 lines → 1 call)
- Constants: `PI`, `TAU`
## Usage in Shaders
### Bump Mapping Note:
`calc_sdf_normal_bumped()` was removed from common_utils - too specialized, depends on `get_dist()` from scene_query snippets. Keep bump mapping inline in shaders that use it.
### Transform Normal (appears in renderer_3d.wgsl:174, mesh_render.wgsl:38):
```wgsl
// Before
let normal_matrix = mat3x3<f32>(obj.inv_model[0].xyz, obj.inv_model[1].xyz, obj.inv_model[2].xyz);
normal = normalize(normal_matrix * n_local);
// After (if common_utils included)
normal = transform_normal(obj.inv_model, n_local);
```
### Spherical UV (appears 6x in renderer_3d.wgsl):
```wgsl
// Before
let uv = vec2<f32>(atan2(q.x, q.z) / 6.28 + 0.5,
acos(clamp(q.y / length(q), -1.0, 1.0)) / 3.14);
// After
let uv = spherical_uv(q);
```
### Skybox (skybox.wgsl:41-42):
```wgsl
// Before
let u = atan2(ray_dir.z, ray_dir.x) / 6.28318 + 0.5;
let v = asin(clamp(ray_dir.y, -1.0, 1.0)) / 3.14159 + 0.5;
// After
let uv = spherical_uv_from_dir(ray_dir);
```
## Integration with ShaderComposer
ShaderComposer already supports `#include` directives. To use:
```cpp
// In gpu/effects initialization
ShaderComposer::Get().RegisterSnippet(
"math/common_utils",
GetAssetString(AssetId::SHADER_MATH_COMMON_UTILS)
);
// In shader composition
composer.Compose(
{"common_uniforms", "math/common_utils"},
main_shader_code
);
```
## Size Impact
**Estimated binary size change:**
- Add common_utils.wgsl: +800 bytes
- Remove duplication: -1500 bytes (6 spherical_uv + bump mapping)
- **Net savings: ~700 bytes**
Plus improved maintainability and consistency.
## Next Steps
1. Refactor `renderer_3d.wgsl` to use new utilities
2. Refactor `skybox.wgsl` to use `spherical_uv_from_dir()`
3. Refactor `mesh_render.wgsl` to use `transform_normal()`
4. Consider extracting more patterns:
- Grid pattern (appears 2x)
- Light direction constant
- Ray-box intersection variants
|