@forgeax/engine-shader 0.1.23 → 0.1.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +13 -4
  2. package/dist/ShaderRegistry.d.ts.map +1 -1
  3. package/dist/index.d.ts +1 -1
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.mjs +28 -52
  6. package/dist/index.mjs.map +1 -1
  7. package/dist/material-schemas.d.ts +31 -0
  8. package/dist/material-schemas.d.ts.map +1 -1
  9. package/package.json +4 -4
  10. package/src/ShaderRegistry.ts +0 -17
  11. package/src/__tests__/default-standard-pbr-alpha.unit.test.ts +9 -3
  12. package/src/__tests__/default-standard-pbr-transmission.unit.test.ts +48 -166
  13. package/src/__tests__/deferred-lighting-ssao.test.ts +3 -3
  14. package/src/__tests__/ibl-irradiance.unit.test.ts +9 -0
  15. package/src/__tests__/lighting-directional.unit.test.ts +36 -0
  16. package/src/__tests__/lighting-punctual.unit.test.ts +12 -4
  17. package/src/__tests__/material-builtins.unit.test.ts +21 -3
  18. package/src/__tests__/material-contract.unit.test.ts +131 -17
  19. package/src/__tests__/physical-clearcoat.unit.test.ts +65 -0
  20. package/src/__tests__/probe-lighting-composition.unit.test.ts +3 -2
  21. package/src/__tests__/shader-manifest-transmission.unit.test.ts +8 -10
  22. package/src/__tests__/shader.unit.test.ts +52 -87
  23. package/src/__tests__/spot-cookie-composition.unit.test.ts +2 -1
  24. package/src/__tests__/standard-webgl2-varying-budget.unit.test.ts +17 -0
  25. package/src/__tests__/surface-v1-negative.unit.test.ts +37 -0
  26. package/src/__tests__/surface-v1.unit.test.ts +83 -0
  27. package/src/__tests__/transmission-thickness-scale.unit.test.ts +2 -6
  28. package/src/__tests__/vertex-color-variant.unit.test.ts +16 -5
  29. package/src/default-standard-pbr-skin.wgsl +678 -192
  30. package/src/default-standard-pbr.wgsl +563 -279
  31. package/src/default_standard_surface.wgsl +88 -0
  32. package/src/hdrp-cluster-forward.wgsl +225 -0
  33. package/src/ibl-irradiance.wgsl +43 -8
  34. package/src/ibl-prefilter.wgsl +13 -3
  35. package/src/ibl-shared.wgsl +9 -2
  36. package/src/index.ts +6 -0
  37. package/src/lighting-directional.wgsl +3 -1
  38. package/src/lighting-spot-modifiers.wgsl +8 -1
  39. package/src/lighting-spot-projector.wgsl +31 -0
  40. package/src/material/artifact-types.ts +2 -2
  41. package/src/material/physical/anisotropy.wgsl +26 -0
  42. package/src/material/physical/clearcoat.wgsl +24 -0
  43. package/src/material/physical/iridescence.wgsl +23 -0
  44. package/src/material/physical/sheen.wgsl +17 -0
  45. package/src/material-schemas.ts +65 -30
  46. package/src/register-default-standard-pbr-skin.ts +2 -2
  47. package/src/standard-cluster.wgsl +1 -36
  48. package/src/surface_v1.wgsl +26 -0
@@ -1,4 +1,8 @@
1
1
  import type { ParamSchemaEntry } from '@forgeax/engine-types';
2
+ import {
3
+ STANDARD_MATERIAL_PARAM_SCHEMA,
4
+ STANDARD_PHYSICAL_PARAMETER_NAMES,
5
+ } from '@forgeax/engine-types';
2
6
  import {
3
7
  createStandardPbrArtifactReceipt,
4
8
  type MaterialShaderArtifactReceipt,
@@ -7,36 +11,67 @@ import {
7
11
  export const STANDARD_PBR_ALPHA_CUTOFF_DEFAULT = 0;
8
12
 
9
13
  /** Shared material contract for the standard PBR and skinned PBR shaders. */
10
- export const DEFAULT_STANDARD_PBR_PARAM_SCHEMA: readonly ParamSchemaEntry[] = [
11
- { name: 'baseColor', type: 'color', default: [1, 1, 1, 1] },
12
- { name: 'metallic', type: 'f32', default: 0 },
13
- { name: 'roughness', type: 'f32', default: 0.5 },
14
- { name: 'metallicChannel', type: 'f32', default: 2 },
15
- { name: 'roughnessChannel', type: 'f32', default: 1 },
16
- { name: 'aoChannel', type: 'f32', default: 0 },
17
- { name: 'extraChannel', type: 'f32', default: 0 },
18
- { name: 'emissive', type: 'vec3', colorSpace: 'srgb', default: [0, 0, 0] },
19
- { name: 'emissiveIntensity', type: 'f32', default: 0 },
20
- { name: 'occlusionStrength', type: 'f32', default: 1 },
21
- { name: 'alphaCutoff', type: 'f32', default: STANDARD_PBR_ALPHA_CUTOFF_DEFAULT },
22
- { name: 'clearcoat', type: 'f32', default: 0 },
23
- { name: 'clearcoatRoughness', type: 'f32', default: 0.5 },
24
- { name: 'specularTint', type: 'vec3', colorSpace: 'srgb', default: [1, 1, 1] },
25
- { name: 'normalScale', type: 'f32', default: 1 },
26
- { name: 'transmission', type: 'f32', default: 0 },
27
- { name: 'ior', type: 'f32', default: 1.5 },
28
- { name: 'thickness', type: 'f32', default: 0 },
29
- { name: 'attenuationColor', type: 'vec3', colorSpace: 'linear', default: [1, 1, 1] },
30
- { name: 'attenuationDistance', type: 'f32' },
31
- { name: 'baseColorTexture', type: 'texture2d' },
32
- { name: 'metallicRoughnessTexture', type: 'texture2d' },
33
- { name: 'normalTexture', type: 'texture2d' },
34
- { name: 'specularTintTexture', type: 'texture2d' },
35
- { name: 'emissiveTexture', type: 'texture2d' },
36
- { name: 'occlusionTexture', type: 'texture2d' },
37
- { name: 'transmissionTexture', type: 'texture2d' },
38
- { name: 'thicknessTexture', type: 'texture2d' },
39
- ];
14
+ export const DEFAULT_STANDARD_PBR_PARAM_SCHEMA = STANDARD_MATERIAL_PARAM_SCHEMA;
15
+
16
+ export type { StandardPhysicalTextureField } from '@forgeax/engine-types';
17
+ /**
18
+ * Backward-compatible export name for callers that need the physical
19
+ * projection. Every entry is selected from the Standard root schema above;
20
+ * no independent defaults or binding inventory can drift from it.
21
+ */
22
+ /**
23
+ * Stable physical texture injection order. The order is part of the
24
+ * Standard template's resource ABI and is derived from the root schema by
25
+ * `standardPhysicalTextureFields`; render/cook must not maintain another
26
+ * field inventory.
27
+ */
28
+ export {
29
+ STANDARD_PHYSICAL_TEXTURE_FIELDS,
30
+ standardPhysicalTextureFields,
31
+ } from '@forgeax/engine-types';
32
+
33
+ export const STANDARD_PHYSICAL_LAYER_PARAM_SCHEMA: readonly ParamSchemaEntry[] =
34
+ DEFAULT_STANDARD_PBR_PARAM_SCHEMA.filter((entry) =>
35
+ STANDARD_PHYSICAL_PARAMETER_NAMES.has(entry.name),
36
+ );
37
+
38
+ /**
39
+ * Canonical static Standard entry. It deliberately contains only the base
40
+ * contract (including the specular extension) so a base-only material keeps
41
+ * its Deferred path and carries no second-stage physical resources.
42
+ */
43
+ export const STANDARD_BASE_PARAM_SCHEMA: readonly ParamSchemaEntry[] =
44
+ DEFAULT_STANDARD_PBR_PARAM_SCHEMA.filter(
45
+ (entry) =>
46
+ !STANDARD_PHYSICAL_PARAMETER_NAMES.has(entry.name) &&
47
+ ![
48
+ 'transmission',
49
+ 'thickness',
50
+ 'attenuationColor',
51
+ 'attenuationDistance',
52
+ 'transmissionTexture',
53
+ 'thicknessTexture',
54
+ ].includes(entry.name),
55
+ );
56
+
57
+ /**
58
+ * Canonical boot-time user region for the shared Standard material BGL.
59
+ *
60
+ * It is still a projection of the root schema, but unlike the author-facing
61
+ * base-only projection it retains the pre-existing transmission texture pair.
62
+ * The template reserves those two pairs before the IBL/backdrop injection so
63
+ * a base-only shader and a transmissive shader can share one boot layout;
64
+ * physical texture pairs are never included here and are appended only for a
65
+ * root contract that declares them.
66
+ */
67
+ export const STANDARD_PIPELINE_PARAM_SCHEMA: readonly ParamSchemaEntry[] =
68
+ DEFAULT_STANDARD_PBR_PARAM_SCHEMA.filter(
69
+ // The canonical Standard UBO keeps every numeric root coordinate,
70
+ // including the physical-layer tail. Physical map pairs are engine-owned
71
+ // resources and are injected after the stable user region.
72
+ (entry) =>
73
+ !(STANDARD_PHYSICAL_PARAMETER_NAMES.has(entry.name) && entry.type.startsWith('texture')),
74
+ );
40
75
 
41
76
  /** The single producer receipt shared by direct and scene-index Standard PBR. */
42
77
  export const STANDARD_PBR_ARTIFACT_RECEIPT: MaterialShaderArtifactReceipt =
@@ -13,7 +13,7 @@
13
13
  // - R-10: paramSchema reuses default-standard-pbr schema (same params)
14
14
 
15
15
  import type { ShaderRegistry } from './index.js';
16
- import { DEFAULT_STANDARD_PBR_PARAM_SCHEMA } from './material-schemas.js';
16
+ import { STANDARD_PIPELINE_PARAM_SCHEMA } from './material-schemas.js';
17
17
 
18
18
  /**
19
19
  * paramSchema for forgeax::pbr-skin — mirrors default-standard-pbr 8 fields.
@@ -69,6 +69,6 @@ export function registerDefaultStandardPbrSkin(
69
69
  void caps;
70
70
  registry.installMaterialArtifact(RESERVED_ID, {
71
71
  source: composedWgsl,
72
- paramSchema: DEFAULT_STANDARD_PBR_PARAM_SCHEMA,
72
+ paramSchema: STANDARD_PIPELINE_PARAM_SCHEMA,
73
73
  });
74
74
  }
@@ -9,18 +9,11 @@
9
9
  #define_import_path forgeax_standard::cluster
10
10
 
11
11
  #import forgeax_pbr::lighting_punctual::{evalPoint, evalPointFlat, evalSpot, evalSpotFlat, evalSpotShadowed}
12
- #import forgeax_pbr::lighting_attenuation::{projectSpotUv}
13
12
  #import forgeax_pbr::lighting_spot_modifiers::{spotModifierFactors}
14
13
  #import forgeax_pbr::lighting_rect_area::{evalRectAreaLtcGgx}
15
14
  #import forgeax_view::common::{view}
16
15
  #ifdef PROJECTOR_AVAILABLE
17
- #ifdef EXTENDED_LIGHTING_AVAILABLE
18
- #import forgeax_view::common::{spotModifierSampler, cookieTexture}
19
- #else
20
- #ifndef EXTENDED_LIGHTING_AVAILABLE
21
- #import forgeax_view::common::{projectorTexture, projectorSampler}
22
- #endif
23
- #endif
16
+ #import forgeax_pbr::lighting_spot_projector::{sampleStandardSpotProjector}
24
17
  #endif
25
18
  #ifdef POINT_SHADOW_AVAILABLE
26
19
  #import forgeax_pbr::lighting_punctual::{evalPointShadowed}
@@ -95,34 +88,6 @@ fn ndc_position_to_cluster(
95
88
  return vec3(cx, cy, cz);
96
89
  }
97
90
 
98
- // Surface SpotLight projector sampling is owned by the same clustered light
99
- // evaluator as the analytic cone/range contribution. The host marks the
100
- // selected projector in the DirectLightSlot flag and writes its matrix to the
101
- // corresponding View lane (lane 0 for projector-only); no second
102
- // material-local sampling loop or resource owner is allowed.
103
- fn sampleStandardSpotProjector(
104
- lightViewProj : mat4x4<f32>,
105
- world_pos : vec3<f32>,
106
- metadata : vec4<u32>,
107
- ) -> vec3<f32> {
108
- #ifdef PROJECTOR_AVAILABLE
109
- let uv = projectSpotUv(lightViewProj, world_pos);
110
- if (!(uv.x >= 0.0 && uv.x <= 1.0 && uv.y >= 0.0 && uv.y <= 1.0)) {
111
- return vec3<f32>(1.0);
112
- }
113
- #ifdef EXTENDED_LIGHTING_AVAILABLE
114
- if (metadata.w == 0xffffffffu) {
115
- return vec3<f32>(1.0);
116
- }
117
- return textureSampleLevel(cookieTexture, spotModifierSampler, uv, metadata.w, 0.0).rgb;
118
- #else
119
- return textureSampleLevel(projectorTexture, projectorSampler, uv, 0.0).rgb;
120
- #endif
121
- #else
122
- return vec3<f32>(1.0);
123
- #endif
124
- }
125
-
126
91
  // Decode one kind first, then delegate the complete evaluation to the shared
127
92
  // punctual owner. Unknown kinds are explicitly zero contribution.
128
93
  fn evaluate_cluster_light(
@@ -0,0 +1,26 @@
1
+ #define_import_path forgeax_material::surface_v1
2
+
3
+ // Engine-owned input ABI for authored Standard material surfaces.
4
+ struct SurfaceInput {
5
+ positionOS : vec3<f32>,
6
+ positionWS : vec3<f32>,
7
+ geometricNormalWS : vec3<f32>,
8
+ tangentWS : vec4<f32>,
9
+ viewDirectionWS : vec3<f32>,
10
+ uv0 : vec2<f32>,
11
+ uv1 : vec2<f32>,
12
+ vertexColor : vec4<f32>,
13
+ frontFacing : bool,
14
+ };
15
+
16
+ // Surface output is consumed by the Standard BRDF and pass family.
17
+ struct SurfaceData {
18
+ baseColor : vec3<f32>,
19
+ normalWS : vec3<f32>,
20
+ metallic : f32,
21
+ roughness : f32,
22
+ emissive : vec3<f32>,
23
+ occlusion : f32,
24
+ opacity : f32,
25
+ alphaClipThreshold : f32,
26
+ };