# 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(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(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