@luma.gl/shadertools 9.3.0-alpha.6 → 9.3.0-alpha.8

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 (152) hide show
  1. package/dist/dist.dev.js +2550 -330
  2. package/dist/dist.min.js +1803 -283
  3. package/dist/index.cjs +2495 -358
  4. package/dist/index.cjs.map +4 -4
  5. package/dist/index.d.ts +9 -2
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +3 -0
  8. package/dist/index.js.map +1 -1
  9. package/dist/lib/preprocessor/preprocessor.d.ts.map +1 -1
  10. package/dist/lib/preprocessor/preprocessor.js +4 -3
  11. package/dist/lib/preprocessor/preprocessor.js.map +1 -1
  12. package/dist/lib/shader-assembler.d.ts +10 -0
  13. package/dist/lib/shader-assembler.d.ts.map +1 -1
  14. package/dist/lib/shader-assembler.js +12 -2
  15. package/dist/lib/shader-assembler.js.map +1 -1
  16. package/dist/lib/shader-assembly/assemble-shaders.d.ts +23 -2
  17. package/dist/lib/shader-assembly/assemble-shaders.d.ts.map +1 -1
  18. package/dist/lib/shader-assembly/assemble-shaders.js +211 -11
  19. package/dist/lib/shader-assembly/assemble-shaders.js.map +1 -1
  20. package/dist/lib/shader-assembly/wgsl-binding-debug.d.ts +37 -0
  21. package/dist/lib/shader-assembly/wgsl-binding-debug.d.ts.map +1 -0
  22. package/dist/lib/shader-assembly/wgsl-binding-debug.js +140 -0
  23. package/dist/lib/shader-assembly/wgsl-binding-debug.js.map +1 -0
  24. package/dist/lib/shader-generator/glsl/generate-glsl.js +3 -0
  25. package/dist/lib/shader-generator/glsl/generate-glsl.js.map +1 -1
  26. package/dist/lib/shader-generator/wgsl/generate-wgsl.d.ts.map +1 -1
  27. package/dist/lib/shader-generator/wgsl/generate-wgsl.js +3 -0
  28. package/dist/lib/shader-generator/wgsl/generate-wgsl.js.map +1 -1
  29. package/dist/lib/shader-module/shader-module-uniform-layout.d.ts +22 -0
  30. package/dist/lib/shader-module/shader-module-uniform-layout.d.ts.map +1 -0
  31. package/dist/lib/shader-module/shader-module-uniform-layout.js +112 -0
  32. package/dist/lib/shader-module/shader-module-uniform-layout.js.map +1 -0
  33. package/dist/lib/shader-module/shader-module.d.ts +11 -5
  34. package/dist/lib/shader-module/shader-module.d.ts.map +1 -1
  35. package/dist/lib/shader-module/shader-module.js.map +1 -1
  36. package/dist/lib/utils/uniform-types.d.ts +11 -7
  37. package/dist/lib/utils/uniform-types.d.ts.map +1 -1
  38. package/dist/modules/engine/picking/picking.d.ts +3 -0
  39. package/dist/modules/engine/picking/picking.d.ts.map +1 -1
  40. package/dist/modules/engine/picking/picking.js +3 -0
  41. package/dist/modules/engine/picking/picking.js.map +1 -1
  42. package/dist/modules/engine/skin/skin.d.ts +7 -6
  43. package/dist/modules/engine/skin/skin.d.ts.map +1 -1
  44. package/dist/modules/engine/skin/skin.js +3 -5
  45. package/dist/modules/engine/skin/skin.js.map +1 -1
  46. package/dist/modules/lighting/gouraud-material/gouraud-material.d.ts +1 -0
  47. package/dist/modules/lighting/gouraud-material/gouraud-material.d.ts.map +1 -1
  48. package/dist/modules/lighting/gouraud-material/gouraud-material.js +3 -0
  49. package/dist/modules/lighting/gouraud-material/gouraud-material.js.map +1 -1
  50. package/dist/modules/lighting/ibl/ibl.d.ts +26 -0
  51. package/dist/modules/lighting/ibl/ibl.d.ts.map +1 -0
  52. package/dist/modules/lighting/ibl/ibl.js +33 -0
  53. package/dist/modules/lighting/ibl/ibl.js.map +1 -0
  54. package/dist/modules/lighting/lambert-material/lambert-material.d.ts +10 -0
  55. package/dist/modules/lighting/lambert-material/lambert-material.d.ts.map +1 -0
  56. package/dist/modules/lighting/lambert-material/lambert-material.js +33 -0
  57. package/dist/modules/lighting/lambert-material/lambert-material.js.map +1 -0
  58. package/dist/modules/lighting/lambert-material/lambert-shaders-glsl.d.ts +3 -0
  59. package/dist/modules/lighting/lambert-material/lambert-shaders-glsl.d.ts.map +1 -0
  60. package/dist/modules/lighting/lambert-material/lambert-shaders-glsl.js +60 -0
  61. package/dist/modules/lighting/lambert-material/lambert-shaders-glsl.js.map +1 -0
  62. package/dist/modules/lighting/lambert-material/lambert-shaders-wgsl.d.ts +2 -0
  63. package/dist/modules/lighting/lambert-material/lambert-shaders-wgsl.d.ts.map +1 -0
  64. package/dist/modules/lighting/lambert-material/lambert-shaders-wgsl.js +73 -0
  65. package/dist/modules/lighting/lambert-material/lambert-shaders-wgsl.js.map +1 -0
  66. package/dist/modules/lighting/lights/lighting-glsl.d.ts +1 -1
  67. package/dist/modules/lighting/lights/lighting-glsl.d.ts.map +1 -1
  68. package/dist/modules/lighting/lights/lighting-glsl.js +43 -55
  69. package/dist/modules/lighting/lights/lighting-glsl.js.map +1 -1
  70. package/dist/modules/lighting/lights/lighting-wgsl.d.ts +1 -1
  71. package/dist/modules/lighting/lights/lighting-wgsl.d.ts.map +1 -1
  72. package/dist/modules/lighting/lights/lighting-wgsl.js +43 -65
  73. package/dist/modules/lighting/lights/lighting-wgsl.js.map +1 -1
  74. package/dist/modules/lighting/lights/lighting.d.ts +104 -86
  75. package/dist/modules/lighting/lights/lighting.d.ts.map +1 -1
  76. package/dist/modules/lighting/lights/lighting.js +96 -83
  77. package/dist/modules/lighting/lights/lighting.js.map +1 -1
  78. package/dist/modules/lighting/no-material/dirlight.d.ts +7 -2
  79. package/dist/modules/lighting/no-material/dirlight.d.ts.map +1 -1
  80. package/dist/modules/lighting/no-material/dirlight.js +3 -1
  81. package/dist/modules/lighting/no-material/dirlight.js.map +1 -1
  82. package/dist/modules/lighting/pbr-material/pbr-material-glsl.d.ts +1 -1
  83. package/dist/modules/lighting/pbr-material/pbr-material-glsl.d.ts.map +1 -1
  84. package/dist/modules/lighting/pbr-material/pbr-material-glsl.js +524 -28
  85. package/dist/modules/lighting/pbr-material/pbr-material-glsl.js.map +1 -1
  86. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.d.ts +2 -2
  87. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.d.ts.map +1 -1
  88. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.js +706 -50
  89. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.js.map +1 -1
  90. package/dist/modules/lighting/pbr-material/pbr-material.d.ts +110 -61
  91. package/dist/modules/lighting/pbr-material/pbr-material.d.ts.map +1 -1
  92. package/dist/modules/lighting/pbr-material/pbr-material.js +85 -9
  93. package/dist/modules/lighting/pbr-material/pbr-material.js.map +1 -1
  94. package/dist/modules/lighting/pbr-material/pbr-projection.d.ts.map +1 -1
  95. package/dist/modules/lighting/pbr-material/pbr-projection.js +2 -1
  96. package/dist/modules/lighting/pbr-material/pbr-projection.js.map +1 -1
  97. package/dist/modules/lighting/phong-material/phong-material.d.ts +1 -0
  98. package/dist/modules/lighting/phong-material/phong-material.d.ts.map +1 -1
  99. package/dist/modules/lighting/phong-material/phong-material.js +4 -0
  100. package/dist/modules/lighting/phong-material/phong-material.js.map +1 -1
  101. package/dist/modules/lighting/phong-material/phong-shaders-glsl.d.ts +2 -2
  102. package/dist/modules/lighting/phong-material/phong-shaders-glsl.d.ts.map +1 -1
  103. package/dist/modules/lighting/phong-material/phong-shaders-glsl.js +15 -4
  104. package/dist/modules/lighting/phong-material/phong-shaders-glsl.js.map +1 -1
  105. package/dist/modules/lighting/phong-material/phong-shaders-wgsl.d.ts +1 -1
  106. package/dist/modules/lighting/phong-material/phong-shaders-wgsl.d.ts.map +1 -1
  107. package/dist/modules/lighting/phong-material/phong-shaders-wgsl.js +36 -5
  108. package/dist/modules/lighting/phong-material/phong-shaders-wgsl.js.map +1 -1
  109. package/dist/modules/math/fp64/fp64-arithmetic-glsl.d.ts +1 -1
  110. package/dist/modules/math/fp64/fp64-arithmetic-glsl.d.ts.map +1 -1
  111. package/dist/modules/math/fp64/fp64-arithmetic-glsl.js +41 -10
  112. package/dist/modules/math/fp64/fp64-arithmetic-glsl.js.map +1 -1
  113. package/dist/modules/math/fp64/fp64-arithmetic-wgsl.d.ts +2 -0
  114. package/dist/modules/math/fp64/fp64-arithmetic-wgsl.d.ts.map +1 -0
  115. package/dist/modules/math/fp64/fp64-arithmetic-wgsl.js +212 -0
  116. package/dist/modules/math/fp64/fp64-arithmetic-wgsl.js.map +1 -0
  117. package/dist/modules/math/fp64/fp64.d.ts +1 -0
  118. package/dist/modules/math/fp64/fp64.d.ts.map +1 -1
  119. package/dist/modules/math/fp64/fp64.js +8 -2
  120. package/dist/modules/math/fp64/fp64.js.map +1 -1
  121. package/package.json +3 -3
  122. package/src/index.ts +19 -2
  123. package/src/lib/preprocessor/preprocessor.ts +6 -3
  124. package/src/lib/shader-assembler.ts +17 -2
  125. package/src/lib/shader-assembly/assemble-shaders.ts +377 -12
  126. package/src/lib/shader-assembly/wgsl-binding-debug.ts +216 -0
  127. package/src/lib/shader-generator/glsl/generate-glsl.ts +7 -1
  128. package/src/lib/shader-generator/wgsl/generate-wgsl.ts +6 -0
  129. package/src/lib/shader-module/shader-module-uniform-layout.ts +194 -0
  130. package/src/lib/shader-module/shader-module.ts +16 -6
  131. package/src/lib/utils/uniform-types.ts +24 -9
  132. package/src/modules/engine/picking/picking.ts +3 -0
  133. package/src/modules/engine/skin/skin.ts +3 -5
  134. package/src/modules/lighting/gouraud-material/gouraud-material.ts +4 -0
  135. package/src/modules/lighting/ibl/ibl.ts +44 -0
  136. package/src/modules/lighting/lambert-material/lambert-material.ts +42 -0
  137. package/src/modules/lighting/lambert-material/lambert-shaders-glsl.ts +61 -0
  138. package/src/modules/lighting/lambert-material/lambert-shaders-wgsl.ts +73 -0
  139. package/src/modules/lighting/lights/lighting-glsl.ts +43 -55
  140. package/src/modules/lighting/lights/lighting-wgsl.ts +43 -65
  141. package/src/modules/lighting/lights/lighting.ts +186 -123
  142. package/src/modules/lighting/no-material/dirlight.ts +3 -1
  143. package/src/modules/lighting/pbr-material/pbr-material-glsl.ts +524 -28
  144. package/src/modules/lighting/pbr-material/pbr-material-wgsl.ts +706 -50
  145. package/src/modules/lighting/pbr-material/pbr-material.ts +111 -18
  146. package/src/modules/lighting/pbr-material/pbr-projection.ts +2 -1
  147. package/src/modules/lighting/phong-material/phong-material.ts +5 -0
  148. package/src/modules/lighting/phong-material/phong-shaders-glsl.ts +15 -4
  149. package/src/modules/lighting/phong-material/phong-shaders-wgsl.ts +36 -5
  150. package/src/modules/math/fp64/fp64-arithmetic-glsl.ts +41 -10
  151. package/src/modules/math/fp64/fp64-arithmetic-wgsl.ts +212 -0
  152. package/src/modules/math/fp64/fp64.ts +9 -3
@@ -16,6 +16,7 @@ import type {
16
16
 
17
17
  import {ShaderModule} from '../../../lib/shader-module/shader-module';
18
18
  import {lighting} from '../lights/lighting';
19
+ import {ibl} from '../ibl/ibl';
19
20
 
20
21
  import {vs, fs} from './pbr-material-glsl';
21
22
  import {source} from './pbr-material-wgsl';
@@ -33,18 +34,16 @@ export type PBRMaterialBindings = {
33
34
  pbr_specularColorSampler?: Texture | null; // #ifdef HAS_SPECULARCOLORMAP
34
35
  pbr_specularIntensitySampler?: Texture | null; // #ifdef HAS_SPECULARINTENSITYMAP
35
36
  pbr_transmissionSampler?: Texture | null; // #ifdef HAS_TRANSMISSIONMAP
37
+ pbr_thicknessSampler?: Texture | null; // #ifdef HAS_THICKNESSMAP
36
38
 
37
39
  pbr_clearcoatSampler?: Texture | null; // #ifdef HAS_CLEARCOATMAP
38
- pbr_clearcoatRoughnessSampler?: Texture | null; // #ifdef HAS_CLEARCOATMAP
40
+ pbr_clearcoatRoughnessSampler?: Texture | null; // #ifdef HAS_CLEARCOATROUGHNESSMAP
41
+ pbr_clearcoatNormalSampler?: Texture | null; // #ifdef HAS_CLEARCOATNORMALMAP
39
42
  pbr_sheenColorSampler?: Texture | null; // #ifdef HAS_SHEENCOLORMAP
40
- pbr_sheenRoughnessSampler?: Texture | null; // #ifdef HAS_SHEENCOLORMAP
43
+ pbr_sheenRoughnessSampler?: Texture | null; // #ifdef HAS_SHEENROUGHNESSMAP
41
44
  pbr_iridescenceSampler?: Texture | null; // #ifdef HAS_IRIDESCENCEMAP
45
+ pbr_iridescenceThicknessSampler?: Texture | null; // #ifdef HAS_IRIDESCENCETHICKNESSMAP
42
46
  pbr_anisotropySampler?: Texture | null; // #ifdef HAS_ANISOTROPYMAP
43
-
44
- // IBL Samplers
45
- pbr_diffuseEnvSampler?: Texture | null; // #ifdef USE_IBL (samplerCube)
46
- pbr_specularEnvSampler?: Texture | null; // #ifdef USE_IBL (samplerCube)
47
- pbr_BrdfLUT?: Texture | null; // #ifdef USE_IBL
48
47
  };
49
48
 
50
49
  export type PBRMaterialUniforms = {
@@ -96,10 +95,12 @@ export type PBRMaterialUniforms = {
96
95
  clearcoatFactor?: number;
97
96
  clearcoatRoughnessFactor?: number;
98
97
  clearcoatMapEnabled?: boolean;
98
+ clearcoatRoughnessMapEnabled?: boolean;
99
99
 
100
100
  sheenColorFactor?: Readonly<Vector3 | NumberArray3>;
101
101
  sheenRoughnessFactor?: number;
102
102
  sheenColorMapEnabled?: boolean;
103
+ sheenRoughnessMapEnabled?: boolean;
103
104
 
104
105
  iridescenceFactor?: number;
105
106
  iridescenceIor?: number;
@@ -123,9 +124,93 @@ export type PBRMaterialProps = PBRMaterialBindings & PBRMaterialUniforms;
123
124
  export const pbrMaterial = {
124
125
  props: {} as PBRMaterialProps,
125
126
  uniforms: {} as PBRMaterialUniforms,
127
+ defaultUniforms: {
128
+ unlit: false,
129
+
130
+ baseColorMapEnabled: false,
131
+ baseColorFactor: [1, 1, 1, 1],
132
+
133
+ normalMapEnabled: false,
134
+ normalScale: 1,
135
+
136
+ emissiveMapEnabled: false,
137
+ emissiveFactor: [0, 0, 0],
138
+
139
+ metallicRoughnessValues: [1, 1],
140
+ metallicRoughnessMapEnabled: false,
141
+
142
+ occlusionMapEnabled: false,
143
+ occlusionStrength: 1,
144
+
145
+ alphaCutoffEnabled: false,
146
+ alphaCutoff: 0.5,
147
+
148
+ IBLenabled: false,
149
+ scaleIBLAmbient: [1, 1],
150
+
151
+ scaleDiffBaseMR: [0, 0, 0, 0],
152
+ scaleFGDSpec: [0, 0, 0, 0],
153
+
154
+ specularColorFactor: [1, 1, 1],
155
+ specularIntensityFactor: 1,
156
+ specularColorMapEnabled: false,
157
+ specularIntensityMapEnabled: false,
158
+
159
+ ior: 1.5,
160
+
161
+ transmissionFactor: 0,
162
+ transmissionMapEnabled: false,
163
+
164
+ thicknessFactor: 0,
165
+ attenuationDistance: 1e9,
166
+ attenuationColor: [1, 1, 1],
167
+
168
+ clearcoatFactor: 0,
169
+ clearcoatRoughnessFactor: 0,
170
+ clearcoatMapEnabled: false,
171
+ clearcoatRoughnessMapEnabled: false,
172
+
173
+ sheenColorFactor: [0, 0, 0],
174
+ sheenRoughnessFactor: 0,
175
+ sheenColorMapEnabled: false,
176
+ sheenRoughnessMapEnabled: false,
177
+
178
+ iridescenceFactor: 0,
179
+ iridescenceIor: 1.3,
180
+ iridescenceThicknessRange: [100, 400],
181
+ iridescenceMapEnabled: false,
182
+
183
+ anisotropyStrength: 0,
184
+ anisotropyRotation: 0,
185
+ anisotropyDirection: [1, 0],
186
+ anisotropyMapEnabled: false,
187
+
188
+ emissiveStrength: 1
189
+ } as Required<PBRMaterialUniforms>,
126
190
 
127
191
  name: 'pbrMaterial',
128
- dependencies: [lighting, pbrProjection],
192
+ firstBindingSlot: 0,
193
+ bindingLayout: [
194
+ {name: 'pbrMaterial', group: 3},
195
+ {name: 'pbr_baseColorSampler', group: 3},
196
+ {name: 'pbr_normalSampler', group: 3},
197
+ {name: 'pbr_emissiveSampler', group: 3},
198
+ {name: 'pbr_metallicRoughnessSampler', group: 3},
199
+ {name: 'pbr_occlusionSampler', group: 3},
200
+ {name: 'pbr_specularColorSampler', group: 3},
201
+ {name: 'pbr_specularIntensitySampler', group: 3},
202
+ {name: 'pbr_transmissionSampler', group: 3},
203
+ {name: 'pbr_thicknessSampler', group: 3},
204
+ {name: 'pbr_clearcoatSampler', group: 3},
205
+ {name: 'pbr_clearcoatRoughnessSampler', group: 3},
206
+ {name: 'pbr_clearcoatNormalSampler', group: 3},
207
+ {name: 'pbr_sheenColorSampler', group: 3},
208
+ {name: 'pbr_sheenRoughnessSampler', group: 3},
209
+ {name: 'pbr_iridescenceSampler', group: 3},
210
+ {name: 'pbr_iridescenceThicknessSampler', group: 3},
211
+ {name: 'pbr_anisotropySampler', group: 3}
212
+ ],
213
+ dependencies: [lighting, ibl, pbrProjection],
129
214
  source,
130
215
  vs,
131
216
  fs,
@@ -140,10 +225,16 @@ export const pbrMaterial = {
140
225
  HAS_SPECULARCOLORMAP: false,
141
226
  HAS_SPECULARINTENSITYMAP: false,
142
227
  HAS_TRANSMISSIONMAP: false,
228
+ HAS_THICKNESSMAP: false,
143
229
  HAS_CLEARCOATMAP: false,
230
+ HAS_CLEARCOATROUGHNESSMAP: false,
231
+ HAS_CLEARCOATNORMALMAP: false,
144
232
  HAS_SHEENCOLORMAP: false,
233
+ HAS_SHEENROUGHNESSMAP: false,
145
234
  HAS_IRIDESCENCEMAP: false,
235
+ HAS_IRIDESCENCETHICKNESSMAP: false,
146
236
  HAS_ANISOTROPYMAP: false,
237
+ USE_MATERIAL_EXTENSIONS: false,
147
238
  ALPHA_CUTOFF: false,
148
239
  USE_IBL: false,
149
240
  PBR_DEBUG: false
@@ -172,15 +263,6 @@ export const pbrMaterial = {
172
263
  alphaCutoffEnabled: 'i32',
173
264
  alphaCutoff: 'f32', // #ifdef ALPHA_CUTOFF
174
265
 
175
- // IBL
176
- IBLenabled: 'i32',
177
- scaleIBLAmbient: 'vec2<f32>', // #ifdef USE_IBL
178
-
179
- // debugging flags used for shader output of intermediate PBR variables
180
- // #ifdef PBR_DEBUG
181
- scaleDiffBaseMR: 'vec4<f32>',
182
- scaleFGDSpec: 'vec4<f32>',
183
-
184
266
  specularColorFactor: 'vec3<f32>',
185
267
  specularIntensityFactor: 'f32',
186
268
  specularColorMapEnabled: 'i32',
@@ -198,10 +280,12 @@ export const pbrMaterial = {
198
280
  clearcoatFactor: 'f32',
199
281
  clearcoatRoughnessFactor: 'f32',
200
282
  clearcoatMapEnabled: 'i32',
283
+ clearcoatRoughnessMapEnabled: 'i32',
201
284
 
202
285
  sheenColorFactor: 'vec3<f32>',
203
286
  sheenRoughnessFactor: 'f32',
204
287
  sheenColorMapEnabled: 'i32',
288
+ sheenRoughnessMapEnabled: 'i32',
205
289
 
206
290
  iridescenceFactor: 'f32',
207
291
  iridescenceIor: 'f32',
@@ -213,6 +297,15 @@ export const pbrMaterial = {
213
297
  anisotropyDirection: 'vec2<f32>',
214
298
  anisotropyMapEnabled: 'i32',
215
299
 
216
- emissiveStrength: 'f32'
300
+ emissiveStrength: 'f32',
301
+
302
+ // IBL
303
+ IBLenabled: 'i32',
304
+ scaleIBLAmbient: 'vec2<f32>', // #ifdef USE_IBL
305
+
306
+ // debugging flags used for shader output of intermediate PBR variables
307
+ // #ifdef PBR_DEBUG
308
+ scaleDiffBaseMR: 'vec4<f32>',
309
+ scaleFGDSpec: 'vec4<f32>'
217
310
  }
218
311
  } as const satisfies ShaderModule<PBRMaterialProps, PBRMaterialUniforms, PBRMaterialBindings>;
@@ -23,7 +23,7 @@ struct pbrProjectionUniforms {
23
23
  camera: vec3<f32>
24
24
  };
25
25
 
26
- @binding(0) @group(0) var<uniform> pbrProjection: pbrProjectionUniforms;
26
+ @group(0) @binding(auto) var<uniform> pbrProjection: pbrProjectionUniforms;
27
27
  `;
28
28
 
29
29
  export type PBRProjectionProps = {
@@ -35,6 +35,7 @@ export type PBRProjectionProps = {
35
35
 
36
36
  export const pbrProjection: ShaderModule<PBRProjectionProps> = {
37
37
  name: 'pbrProjection',
38
+ bindingLayout: [{name: 'pbrProjection', group: 0}],
38
39
  source: wgslUniformBlock,
39
40
  vs: uniformBlock,
40
41
  fs: uniformBlock,
@@ -9,6 +9,7 @@ import {PHONG_WGSL} from './phong-shaders-wgsl';
9
9
  import {PHONG_VS, PHONG_FS} from './phong-shaders-glsl';
10
10
 
11
11
  export type PhongMaterialProps = {
12
+ unlit?: boolean;
12
13
  ambient?: number;
13
14
  diffuse?: number;
14
15
  /** Specularity exponent */
@@ -19,6 +20,8 @@ export type PhongMaterialProps = {
19
20
  /** In Phong shading, the normal vector is linearly interpolated across the surface of the polygon from the polygon's vertex normals. */
20
21
  export const phongMaterial: ShaderModule<PhongMaterialProps> = {
21
22
  name: 'phongMaterial',
23
+ firstBindingSlot: 0,
24
+ bindingLayout: [{name: 'phongMaterial', group: 3}],
22
25
  dependencies: [lighting],
23
26
  // Note these are switched between phong and gouraud
24
27
  source: PHONG_WGSL,
@@ -28,12 +31,14 @@ export const phongMaterial: ShaderModule<PhongMaterialProps> = {
28
31
  LIGHTING_FRAGMENT: true
29
32
  },
30
33
  uniformTypes: {
34
+ unlit: 'i32',
31
35
  ambient: 'f32',
32
36
  diffuse: 'f32',
33
37
  shininess: 'f32',
34
38
  specularColor: 'vec3<f32>'
35
39
  },
36
40
  defaultUniforms: {
41
+ unlit: false,
37
42
  ambient: 0.35,
38
43
  diffuse: 0.6,
39
44
  shininess: 32,
@@ -4,6 +4,7 @@
4
4
 
5
5
  export const PHONG_VS = /* glsl */ `\
6
6
  uniform phongMaterialUniforms {
7
+ uniform bool unlit;
7
8
  uniform float ambient;
8
9
  uniform float diffuse;
9
10
  uniform float shininess;
@@ -12,9 +13,8 @@ uniform phongMaterialUniforms {
12
13
  `;
13
14
 
14
15
  export const PHONG_FS = /* glsl */ `\
15
- #define MAX_LIGHTS 3
16
-
17
16
  uniform phongMaterialUniforms {
17
+ uniform bool unlit;
18
18
  uniform float ambient;
19
19
  uniform float diffuse;
20
20
  uniform float shininess;
@@ -36,6 +36,10 @@ vec3 lighting_getLightColor(vec3 surfaceColor, vec3 light_direction, vec3 view_d
36
36
  vec3 lighting_getLightColor(vec3 surfaceColor, vec3 cameraPosition, vec3 position_worldspace, vec3 normal_worldspace) {
37
37
  vec3 lightColor = surfaceColor;
38
38
 
39
+ if (material.unlit) {
40
+ return surfaceColor;
41
+ }
42
+
39
43
  if (lighting.enabled == 0) {
40
44
  return lightColor;
41
45
  }
@@ -51,8 +55,15 @@ vec3 lighting_getLightColor(vec3 surfaceColor, vec3 cameraPosition, vec3 positio
51
55
  lightColor += lighting_getLightColor(surfaceColor, light_direction, view_direction, normal_worldspace, pointLight.color / light_attenuation);
52
56
  }
53
57
 
54
- int totalLights = min(MAX_LIGHTS, lighting.pointLightCount + lighting.directionalLightCount);
55
- for (int i = lighting.pointLightCount; i < totalLights; i++) {
58
+ for (int i = 0; i < lighting.spotLightCount; i++) {
59
+ SpotLight spotLight = lighting_getSpotLight(i);
60
+ vec3 light_position_worldspace = spotLight.position;
61
+ vec3 light_direction = normalize(light_position_worldspace - position_worldspace);
62
+ float light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace);
63
+ lightColor += lighting_getLightColor(surfaceColor, light_direction, view_direction, normal_worldspace, spotLight.color / light_attenuation);
64
+ }
65
+
66
+ for (int i = 0; i < lighting.directionalLightCount; i++) {
56
67
  DirectionalLight directionalLight = lighting_getDirectionalLight(i);
57
68
  lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, view_direction, normal_worldspace, directionalLight.color);
58
69
  }
@@ -4,13 +4,14 @@
4
4
 
5
5
  export const PHONG_WGSL = /* wgsl */ `\
6
6
  struct phongMaterialUniforms {
7
+ unlit: u32,
7
8
  ambient: f32,
8
9
  diffuse: f32,
9
10
  shininess: f32,
10
11
  specularColor: vec3<f32>,
11
12
  };
12
13
 
13
- @binding(2) @group(0) var<uniform> phongMaterial : phongMaterialUniforms;
14
+ @group(3) @binding(auto) var<uniform> phongMaterial : phongMaterialUniforms;
14
15
 
15
16
  fn lighting_getLightColor(surfaceColor: vec3<f32>, light_direction: vec3<f32>, view_direction: vec3<f32>, normal_worldspace: vec3<f32>, color: vec3<f32>) -> vec3<f32> {
16
17
  let halfway_direction: vec3<f32> = normalize(light_direction + view_direction);
@@ -27,6 +28,10 @@ fn lighting_getLightColor(surfaceColor: vec3<f32>, light_direction: vec3<f32>, v
27
28
  fn lighting_getLightColor2(surfaceColor: vec3<f32>, cameraPosition: vec3<f32>, position_worldspace: vec3<f32>, normal_worldspace: vec3<f32>) -> vec3<f32> {
28
29
  var lightColor: vec3<f32> = surfaceColor;
29
30
 
31
+ if (phongMaterial.unlit != 0u) {
32
+ return surfaceColor;
33
+ }
34
+
30
35
  if (lighting.enabled == 0) {
31
36
  return lightColor;
32
37
  }
@@ -51,8 +56,21 @@ fn lighting_getLightColor2(surfaceColor: vec3<f32>, cameraPosition: vec3<f32>, p
51
56
  );
52
57
  }
53
58
 
54
- let totalLights = min(MAX_LIGHTS, lighting.pointLightCount + lighting.directionalLightCount);
55
- for (var i: i32 = lighting.pointLightCount; i < totalLights; i++) {
59
+ for (var i: i32 = 0; i < lighting.spotLightCount; i++) {
60
+ let spotLight: SpotLight = lighting_getSpotLight(i);
61
+ let light_position_worldspace: vec3<f32> = spotLight.position;
62
+ let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);
63
+ let light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace);
64
+ lightColor += lighting_getLightColor(
65
+ surfaceColor,
66
+ light_direction,
67
+ view_direction,
68
+ normal_worldspace,
69
+ spotLight.color / light_attenuation
70
+ );
71
+ }
72
+
73
+ for (var i: i32 = 0; i < lighting.directionalLightCount; i++) {
56
74
  let directionalLight: DirectionalLight = lighting_getDirectionalLight(i);
57
75
  lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, view_direction, normal_worldspace, directionalLight.color);
58
76
  }
@@ -84,8 +102,21 @@ fn lighting_getSpecularLightColor(cameraPosition: vec3<f32>, position_worldspace
84
102
  );
85
103
  }
86
104
 
87
- let totalLights = min(MAX_LIGHTS, lighting.pointLightCount + lighting.directionalLightCount);
88
- for (var i: i32 = lighting.pointLightCount; i < totalLights; i++) {
105
+ for (var i: i32 = 0; i < lighting.spotLightCount; i++) {
106
+ let spotLight: SpotLight = lighting_getSpotLight(i);
107
+ let light_position_worldspace: vec3<f32> = spotLight.position;
108
+ let light_direction: vec3<f32> = normalize(light_position_worldspace - position_worldspace);
109
+ let light_attenuation = getSpotLightAttenuation(spotLight, position_worldspace);
110
+ lightColor += lighting_getLightColor(
111
+ surfaceColor,
112
+ light_direction,
113
+ view_direction,
114
+ normal_worldspace,
115
+ spotLight.color / light_attenuation
116
+ );
117
+ }
118
+
119
+ for (var i: i32 = 0; i < lighting.directionalLightCount; i++) {
89
120
  let directionalLight: DirectionalLight = lighting_getDirectionalLight(i);
90
121
  lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, view_direction, normal_worldspace, directionalLight.color);
91
122
  }
@@ -6,6 +6,7 @@ export const fp64arithmeticShader = /* glsl */ `\
6
6
 
7
7
  uniform fp64arithmeticUniforms {
8
8
  uniform float ONE;
9
+ uniform float SPLIT;
9
10
  } fp64;
10
11
 
11
12
  /*
@@ -15,6 +16,12 @@ The purpose of this workaround is to prevent shader compilers from
15
16
  optimizing away necessary arithmetic operations by swapping their sequences
16
17
  or transform the equation to some 'equivalent' form.
17
18
 
19
+ These helpers implement Dekker/Veltkamp-style error tracking. If the compiler
20
+ folds constants or reassociates the arithmetic, the high/low split can stop
21
+ tracking the rounding error correctly. That failure mode tends to look fine in
22
+ simple coordinate setup, but then breaks down inside iterative arithmetic such
23
+ as fp64 Mandelbrot loops.
24
+
18
25
  The method is to multiply an artifical variable, ONE, which will be known to
19
26
  the compiler to be 1 only at runtime. The whole expression is then represented
20
27
  as a polynomial with respective to ONE. In the coefficients of all terms, only one a
@@ -23,17 +30,23 @@ and one b should appear
23
30
  err = (a + b) * ONE^6 - a * ONE^5 - (a + b) * ONE^4 + a * ONE^3 - b - (a + b) * ONE^2 + a * ONE
24
31
  */
25
32
 
26
- // Divide float number to high and low floats to extend fraction bits
27
- vec2 split(float a) {
28
- const float SPLIT = 4097.0;
29
- float t = a * SPLIT;
33
+ float prevent_fp64_optimization(float value) {
30
34
  #if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND)
31
- float a_hi = t * fp64.ONE - (t - a);
32
- float a_lo = a * fp64.ONE - a_hi;
35
+ return value + fp64.ONE * 0.0;
33
36
  #else
34
- float a_hi = t - (t - a);
35
- float a_lo = a - a_hi;
37
+ return value;
36
38
  #endif
39
+ }
40
+
41
+ // Divide float number to high and low floats to extend fraction bits
42
+ vec2 split(float a) {
43
+ // Keep SPLIT as a runtime uniform so the compiler cannot fold the Dekker
44
+ // split into a constant expression and reassociate the recovery steps.
45
+ float split = prevent_fp64_optimization(fp64.SPLIT);
46
+ float t = prevent_fp64_optimization(a * split);
47
+ float temp = t - a;
48
+ float a_hi = t - temp;
49
+ float a_lo = a - a_hi;
37
50
  return vec2(a_hi, a_lo);
38
51
  }
39
52
 
@@ -97,8 +110,26 @@ vec2 twoProd(float a, float b) {
97
110
  float prod = a * b;
98
111
  vec2 a_fp64 = split(a);
99
112
  vec2 b_fp64 = split(b);
100
- float err = ((a_fp64.x * b_fp64.x - prod) + a_fp64.x * b_fp64.y +
101
- a_fp64.y * b_fp64.x) + a_fp64.y * b_fp64.y;
113
+ // twoProd is especially sensitive because mul_fp64 and div_fp64 both depend
114
+ // on the split terms and cross terms staying in the original evaluation
115
+ // order. If the compiler folds or reassociates them, the low part tends to
116
+ // collapse to zero or NaN on some drivers.
117
+ float highProduct = prevent_fp64_optimization(a_fp64.x * b_fp64.x);
118
+ float crossProduct1 = prevent_fp64_optimization(a_fp64.x * b_fp64.y);
119
+ float crossProduct2 = prevent_fp64_optimization(a_fp64.y * b_fp64.x);
120
+ float lowProduct = prevent_fp64_optimization(a_fp64.y * b_fp64.y);
121
+ #if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND)
122
+ float err1 = (highProduct - prod) * fp64.ONE;
123
+ float err2 = crossProduct1 * fp64.ONE * fp64.ONE;
124
+ float err3 = crossProduct2 * fp64.ONE * fp64.ONE * fp64.ONE;
125
+ float err4 = lowProduct * fp64.ONE * fp64.ONE * fp64.ONE * fp64.ONE;
126
+ #else
127
+ float err1 = highProduct - prod;
128
+ float err2 = crossProduct1;
129
+ float err3 = crossProduct2;
130
+ float err4 = lowProduct;
131
+ #endif
132
+ float err = ((err1 + err2) + err3) + err4;
102
133
  return vec2(prod, err);
103
134
  }
104
135
 
@@ -0,0 +1,212 @@
1
+ // luma.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ export const fp64arithmeticWGSL = /* wgsl */ `\
6
+ struct Fp64ArithmeticUniforms {
7
+ ONE: f32,
8
+ SPLIT: f32,
9
+ };
10
+
11
+ @group(0) @binding(auto) var<uniform> fp64arithmetic : Fp64ArithmeticUniforms;
12
+
13
+ fn fp64_nan(seed: f32) -> f32 {
14
+ let nanBits = 0x7fc00000u | select(0u, 1u, seed < 0.0);
15
+ return bitcast<f32>(nanBits);
16
+ }
17
+
18
+ fn fp64_runtime_zero() -> f32 {
19
+ return fp64arithmetic.ONE * 0.0;
20
+ }
21
+
22
+ fn prevent_fp64_optimization(value: f32) -> f32 {
23
+ #ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND
24
+ return value + fp64_runtime_zero();
25
+ #else
26
+ return value;
27
+ #endif
28
+ }
29
+
30
+ fn split(a: f32) -> vec2f {
31
+ let splitValue = prevent_fp64_optimization(fp64arithmetic.SPLIT + fp64_runtime_zero());
32
+ let t = prevent_fp64_optimization(a * splitValue);
33
+ let temp = prevent_fp64_optimization(t - a);
34
+ let aHi = prevent_fp64_optimization(t - temp);
35
+ let aLo = prevent_fp64_optimization(a - aHi);
36
+ return vec2f(aHi, aLo);
37
+ }
38
+
39
+ fn split2(a: vec2f) -> vec2f {
40
+ var b = split(a.x);
41
+ b.y = b.y + a.y;
42
+ return b;
43
+ }
44
+
45
+ fn quickTwoSum(a: f32, b: f32) -> vec2f {
46
+ #ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND
47
+ let sum = prevent_fp64_optimization((a + b) * fp64arithmetic.ONE);
48
+ let err = prevent_fp64_optimization(b - (sum - a) * fp64arithmetic.ONE);
49
+ #else
50
+ let sum = prevent_fp64_optimization(a + b);
51
+ let err = prevent_fp64_optimization(b - (sum - a));
52
+ #endif
53
+ return vec2f(sum, err);
54
+ }
55
+
56
+ fn twoSum(a: f32, b: f32) -> vec2f {
57
+ let s = prevent_fp64_optimization(a + b);
58
+ #ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND
59
+ let v = prevent_fp64_optimization((s * fp64arithmetic.ONE - a) * fp64arithmetic.ONE);
60
+ let err =
61
+ prevent_fp64_optimization((a - (s - v) * fp64arithmetic.ONE) *
62
+ fp64arithmetic.ONE *
63
+ fp64arithmetic.ONE *
64
+ fp64arithmetic.ONE) +
65
+ prevent_fp64_optimization(b - v);
66
+ #else
67
+ let v = prevent_fp64_optimization(s - a);
68
+ let err = prevent_fp64_optimization(a - (s - v)) + prevent_fp64_optimization(b - v);
69
+ #endif
70
+ return vec2f(s, err);
71
+ }
72
+
73
+ fn twoSub(a: f32, b: f32) -> vec2f {
74
+ let s = prevent_fp64_optimization(a - b);
75
+ #ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND
76
+ let v = prevent_fp64_optimization((s * fp64arithmetic.ONE - a) * fp64arithmetic.ONE);
77
+ let err =
78
+ prevent_fp64_optimization((a - (s - v) * fp64arithmetic.ONE) *
79
+ fp64arithmetic.ONE *
80
+ fp64arithmetic.ONE *
81
+ fp64arithmetic.ONE) -
82
+ prevent_fp64_optimization(b + v);
83
+ #else
84
+ let v = prevent_fp64_optimization(s - a);
85
+ let err = prevent_fp64_optimization(a - (s - v)) - prevent_fp64_optimization(b + v);
86
+ #endif
87
+ return vec2f(s, err);
88
+ }
89
+
90
+ fn twoSqr(a: f32) -> vec2f {
91
+ let prod = prevent_fp64_optimization(a * a);
92
+ let aFp64 = split(a);
93
+ let highProduct = prevent_fp64_optimization(aFp64.x * aFp64.x);
94
+ let crossProduct = prevent_fp64_optimization(2.0 * aFp64.x * aFp64.y);
95
+ let lowProduct = prevent_fp64_optimization(aFp64.y * aFp64.y);
96
+ #ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND
97
+ let err =
98
+ (prevent_fp64_optimization(highProduct - prod) * fp64arithmetic.ONE +
99
+ crossProduct * fp64arithmetic.ONE * fp64arithmetic.ONE) +
100
+ lowProduct * fp64arithmetic.ONE * fp64arithmetic.ONE * fp64arithmetic.ONE;
101
+ #else
102
+ let err = ((prevent_fp64_optimization(highProduct - prod) + crossProduct) + lowProduct);
103
+ #endif
104
+ return vec2f(prod, err);
105
+ }
106
+
107
+ fn twoProd(a: f32, b: f32) -> vec2f {
108
+ let prod = prevent_fp64_optimization(a * b);
109
+ let aFp64 = split(a);
110
+ let bFp64 = split(b);
111
+ let highProduct = prevent_fp64_optimization(aFp64.x * bFp64.x);
112
+ let crossProduct1 = prevent_fp64_optimization(aFp64.x * bFp64.y);
113
+ let crossProduct2 = prevent_fp64_optimization(aFp64.y * bFp64.x);
114
+ let lowProduct = prevent_fp64_optimization(aFp64.y * bFp64.y);
115
+ #ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND
116
+ let err1 = (highProduct - prod) * fp64arithmetic.ONE;
117
+ let err2 = crossProduct1 * fp64arithmetic.ONE * fp64arithmetic.ONE;
118
+ let err3 = crossProduct2 * fp64arithmetic.ONE * fp64arithmetic.ONE * fp64arithmetic.ONE;
119
+ let err4 =
120
+ lowProduct *
121
+ fp64arithmetic.ONE *
122
+ fp64arithmetic.ONE *
123
+ fp64arithmetic.ONE *
124
+ fp64arithmetic.ONE;
125
+ #else
126
+ let err1 = highProduct - prod;
127
+ let err2 = crossProduct1;
128
+ let err3 = crossProduct2;
129
+ let err4 = lowProduct;
130
+ #endif
131
+ let err12InputA = prevent_fp64_optimization(err1);
132
+ let err12InputB = prevent_fp64_optimization(err2);
133
+ let err12 = prevent_fp64_optimization(err12InputA + err12InputB);
134
+ let err123InputA = prevent_fp64_optimization(err12);
135
+ let err123InputB = prevent_fp64_optimization(err3);
136
+ let err123 = prevent_fp64_optimization(err123InputA + err123InputB);
137
+ let err1234InputA = prevent_fp64_optimization(err123);
138
+ let err1234InputB = prevent_fp64_optimization(err4);
139
+ let err = prevent_fp64_optimization(err1234InputA + err1234InputB);
140
+ return vec2f(prod, err);
141
+ }
142
+
143
+ fn sum_fp64(a: vec2f, b: vec2f) -> vec2f {
144
+ var s = twoSum(a.x, b.x);
145
+ let t = twoSum(a.y, b.y);
146
+ s.y = prevent_fp64_optimization(s.y + t.x);
147
+ s = quickTwoSum(s.x, s.y);
148
+ s.y = prevent_fp64_optimization(s.y + t.y);
149
+ s = quickTwoSum(s.x, s.y);
150
+ return s;
151
+ }
152
+
153
+ fn sub_fp64(a: vec2f, b: vec2f) -> vec2f {
154
+ var s = twoSub(a.x, b.x);
155
+ let t = twoSub(a.y, b.y);
156
+ s.y = prevent_fp64_optimization(s.y + t.x);
157
+ s = quickTwoSum(s.x, s.y);
158
+ s.y = prevent_fp64_optimization(s.y + t.y);
159
+ s = quickTwoSum(s.x, s.y);
160
+ return s;
161
+ }
162
+
163
+ fn mul_fp64(a: vec2f, b: vec2f) -> vec2f {
164
+ var prod = twoProd(a.x, b.x);
165
+ let crossProduct1 = prevent_fp64_optimization(a.x * b.y);
166
+ prod.y = prevent_fp64_optimization(prod.y + crossProduct1);
167
+ #ifdef LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND
168
+ prod = split2(prod);
169
+ #endif
170
+ prod = quickTwoSum(prod.x, prod.y);
171
+ let crossProduct2 = prevent_fp64_optimization(a.y * b.x);
172
+ prod.y = prevent_fp64_optimization(prod.y + crossProduct2);
173
+ #ifdef LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND
174
+ prod = split2(prod);
175
+ #endif
176
+ prod = quickTwoSum(prod.x, prod.y);
177
+ return prod;
178
+ }
179
+
180
+ fn div_fp64(a: vec2f, b: vec2f) -> vec2f {
181
+ let xn = prevent_fp64_optimization(1.0 / b.x);
182
+ let yn = mul_fp64(a, vec2f(xn, fp64_runtime_zero()));
183
+ let diff = prevent_fp64_optimization(sub_fp64(a, mul_fp64(b, yn)).x);
184
+ let prod = twoProd(xn, diff);
185
+ return sum_fp64(yn, prod);
186
+ }
187
+
188
+ fn sqrt_fp64(a: vec2f) -> vec2f {
189
+ if (a.x == 0.0 && a.y == 0.0) {
190
+ return vec2f(0.0, 0.0);
191
+ }
192
+ if (a.x < 0.0) {
193
+ let nanValue = fp64_nan(a.x);
194
+ return vec2f(nanValue, nanValue);
195
+ }
196
+
197
+ let x = prevent_fp64_optimization(1.0 / sqrt(a.x));
198
+ let yn = prevent_fp64_optimization(a.x * x);
199
+ #ifdef LUMA_FP64_CODE_ELIMINATION_WORKAROUND
200
+ let ynSqr = twoSqr(yn) * fp64arithmetic.ONE;
201
+ #else
202
+ let ynSqr = twoSqr(yn);
203
+ #endif
204
+ let diff = prevent_fp64_optimization(sub_fp64(a, ynSqr).x);
205
+ let prod = twoProd(prevent_fp64_optimization(x * 0.5), diff);
206
+ #ifdef LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND
207
+ return sum_fp64(split(yn), prod);
208
+ #else
209
+ return sum_fp64(vec2f(yn, 0.0), prod);
210
+ #endif
211
+ }
212
+ `;