@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
@@ -52,10 +52,12 @@ uniform pbrMaterialUniforms {
52
52
  float clearcoatFactor;
53
53
  float clearcoatRoughnessFactor;
54
54
  bool clearcoatMapEnabled;
55
+ bool clearcoatRoughnessMapEnabled;
55
56
 
56
57
  vec3 sheenColorFactor;
57
58
  float sheenRoughnessFactor;
58
59
  bool sheenColorMapEnabled;
60
+ bool sheenRoughnessMapEnabled;
59
61
 
60
62
  float iridescenceFactor;
61
63
  float iridescenceIor;
@@ -105,17 +107,30 @@ uniform sampler2D u_SpecularIntensitySampler;
105
107
  #ifdef HAS_TRANSMISSIONMAP
106
108
  uniform sampler2D u_TransmissionSampler;
107
109
  #endif
110
+ #ifdef HAS_THICKNESSMAP
111
+ uniform sampler2D u_ThicknessSampler;
112
+ #endif
108
113
  #ifdef HAS_CLEARCOATMAP
109
114
  uniform sampler2D u_ClearcoatSampler;
115
+ #endif
116
+ #ifdef HAS_CLEARCOATROUGHNESSMAP
110
117
  uniform sampler2D u_ClearcoatRoughnessSampler;
111
118
  #endif
119
+ #ifdef HAS_CLEARCOATNORMALMAP
120
+ uniform sampler2D u_ClearcoatNormalSampler;
121
+ #endif
112
122
  #ifdef HAS_SHEENCOLORMAP
113
123
  uniform sampler2D u_SheenColorSampler;
124
+ #endif
125
+ #ifdef HAS_SHEENROUGHNESSMAP
114
126
  uniform sampler2D u_SheenRoughnessSampler;
115
127
  #endif
116
128
  #ifdef HAS_IRIDESCENCEMAP
117
129
  uniform sampler2D u_IridescenceSampler;
118
130
  #endif
131
+ #ifdef HAS_IRIDESCENCETHICKNESSMAP
132
+ uniform sampler2D u_IridescenceThicknessSampler;
133
+ #endif
119
134
  #ifdef HAS_ANISOTROPYMAP
120
135
  uniform sampler2D u_AnisotropySampler;
121
136
  #endif
@@ -185,6 +200,42 @@ struct pbrMaterialUniforms {
185
200
 
186
201
  alphaCutoffEnabled: i32,
187
202
  alphaCutoff: f32, // #ifdef ALPHA_CUTOFF
203
+
204
+ specularColorFactor: vec3f,
205
+ specularIntensityFactor: f32,
206
+ specularColorMapEnabled: i32,
207
+ specularIntensityMapEnabled: i32,
208
+
209
+ ior: f32,
210
+
211
+ transmissionFactor: f32,
212
+ transmissionMapEnabled: i32,
213
+
214
+ thicknessFactor: f32,
215
+ attenuationDistance: f32,
216
+ attenuationColor: vec3f,
217
+
218
+ clearcoatFactor: f32,
219
+ clearcoatRoughnessFactor: f32,
220
+ clearcoatMapEnabled: i32,
221
+ clearcoatRoughnessMapEnabled: i32,
222
+
223
+ sheenColorFactor: vec3f,
224
+ sheenRoughnessFactor: f32,
225
+ sheenColorMapEnabled: i32,
226
+ sheenRoughnessMapEnabled: i32,
227
+
228
+ iridescenceFactor: f32,
229
+ iridescenceIor: f32,
230
+ iridescenceThicknessRange: vec2f,
231
+ iridescenceMapEnabled: i32,
232
+
233
+ anisotropyStrength: f32,
234
+ anisotropyRotation: f32,
235
+ anisotropyDirection: vec2f,
236
+ anisotropyMapEnabled: i32,
237
+
238
+ emissiveStrength: f32,
188
239
 
189
240
  // IBL
190
241
  IBLenabled: i32,
@@ -197,38 +248,77 @@ struct pbrMaterialUniforms {
197
248
  // #endif
198
249
  }
199
250
 
200
- @binding(2) @group(0) var<uniform> pbrMaterial : pbrMaterialUniforms;
251
+ @group(3) @binding(auto) var<uniform> pbrMaterial : pbrMaterialUniforms;
201
252
 
202
253
  // Samplers
203
254
  #ifdef HAS_BASECOLORMAP
204
- @binding(3) @group(0) var pbr_baseColorSampler: texture_2d<f32>;
205
- @binding(4) @group(0) var pbr_baseColorSamplerSampler: sampler;
255
+ @group(3) @binding(auto) var pbr_baseColorSampler: texture_2d<f32>;
256
+ @group(3) @binding(auto) var pbr_baseColorSamplerSampler: sampler;
206
257
  #endif
207
258
  #ifdef HAS_NORMALMAP
208
- @binding(5) @group(0) var pbr_normalSampler: texture_2d<f32>;
209
- @binding(6) @group(0) var pbr_normalSamplerSampler: sampler;
259
+ @group(3) @binding(auto) var pbr_normalSampler: texture_2d<f32>;
260
+ @group(3) @binding(auto) var pbr_normalSamplerSampler: sampler;
210
261
  #endif
211
262
  #ifdef HAS_EMISSIVEMAP
212
- @binding(7) @group(0) var pbr_emissiveSampler: texture_2d<f32>;
213
- @binding(8) @group(0) var pbr_emissiveSamplerSampler: sampler;
263
+ @group(3) @binding(auto) var pbr_emissiveSampler: texture_2d<f32>;
264
+ @group(3) @binding(auto) var pbr_emissiveSamplerSampler: sampler;
214
265
  #endif
215
266
  #ifdef HAS_METALROUGHNESSMAP
216
- @binding(9) @group(0) var pbr_metallicRoughnessSampler: texture_2d<f32>;
217
- @binding(10) @group(0) var pbr_metallicRoughnessSamplerSampler: sampler;
267
+ @group(3) @binding(auto) var pbr_metallicRoughnessSampler: texture_2d<f32>;
268
+ @group(3) @binding(auto) var pbr_metallicRoughnessSamplerSampler: sampler;
218
269
  #endif
219
270
  #ifdef HAS_OCCLUSIONMAP
220
- @binding(11) @group(0) var pbr_occlusionSampler: texture_2d<f32>;
221
- @binding(12) @group(0) var pbr_occlusionSamplerSampler: sampler;
271
+ @group(3) @binding(auto) var pbr_occlusionSampler: texture_2d<f32>;
272
+ @group(3) @binding(auto) var pbr_occlusionSamplerSampler: sampler;
222
273
  #endif
223
- #ifdef USE_IBL
224
- @binding(13) @group(0) var pbr_diffuseEnvSampler: texture_cube<f32>;
225
- @binding(14) @group(0) var pbr_diffuseEnvSamplerSampler: sampler;
226
- @binding(15) @group(0) var pbr_specularEnvSampler: texture_cube<f32>;
227
- @binding(16) @group(0) var pbr_specularEnvSamplerSampler: sampler;
228
- @binding(17) @group(0) var pbr_BrdfLUT: texture_2d<f32>;
229
- @binding(18) @group(0) var pbr_BrdfLUTSampler: sampler;
274
+ #ifdef HAS_SPECULARCOLORMAP
275
+ @group(3) @binding(auto) var pbr_specularColorSampler: texture_2d<f32>;
276
+ @group(3) @binding(auto) var pbr_specularColorSamplerSampler: sampler;
277
+ #endif
278
+ #ifdef HAS_SPECULARINTENSITYMAP
279
+ @group(3) @binding(auto) var pbr_specularIntensitySampler: texture_2d<f32>;
280
+ @group(3) @binding(auto) var pbr_specularIntensitySamplerSampler: sampler;
281
+ #endif
282
+ #ifdef HAS_TRANSMISSIONMAP
283
+ @group(3) @binding(auto) var pbr_transmissionSampler: texture_2d<f32>;
284
+ @group(3) @binding(auto) var pbr_transmissionSamplerSampler: sampler;
285
+ #endif
286
+ #ifdef HAS_THICKNESSMAP
287
+ @group(3) @binding(auto) var pbr_thicknessSampler: texture_2d<f32>;
288
+ @group(3) @binding(auto) var pbr_thicknessSamplerSampler: sampler;
289
+ #endif
290
+ #ifdef HAS_CLEARCOATMAP
291
+ @group(3) @binding(auto) var pbr_clearcoatSampler: texture_2d<f32>;
292
+ @group(3) @binding(auto) var pbr_clearcoatSamplerSampler: sampler;
293
+ #endif
294
+ #ifdef HAS_CLEARCOATROUGHNESSMAP
295
+ @group(3) @binding(auto) var pbr_clearcoatRoughnessSampler: texture_2d<f32>;
296
+ @group(3) @binding(auto) var pbr_clearcoatRoughnessSamplerSampler: sampler;
297
+ #endif
298
+ #ifdef HAS_CLEARCOATNORMALMAP
299
+ @group(3) @binding(auto) var pbr_clearcoatNormalSampler: texture_2d<f32>;
300
+ @group(3) @binding(auto) var pbr_clearcoatNormalSamplerSampler: sampler;
301
+ #endif
302
+ #ifdef HAS_SHEENCOLORMAP
303
+ @group(3) @binding(auto) var pbr_sheenColorSampler: texture_2d<f32>;
304
+ @group(3) @binding(auto) var pbr_sheenColorSamplerSampler: sampler;
305
+ #endif
306
+ #ifdef HAS_SHEENROUGHNESSMAP
307
+ @group(3) @binding(auto) var pbr_sheenRoughnessSampler: texture_2d<f32>;
308
+ @group(3) @binding(auto) var pbr_sheenRoughnessSamplerSampler: sampler;
309
+ #endif
310
+ #ifdef HAS_IRIDESCENCEMAP
311
+ @group(3) @binding(auto) var pbr_iridescenceSampler: texture_2d<f32>;
312
+ @group(3) @binding(auto) var pbr_iridescenceSamplerSampler: sampler;
313
+ #endif
314
+ #ifdef HAS_IRIDESCENCETHICKNESSMAP
315
+ @group(3) @binding(auto) var pbr_iridescenceThicknessSampler: texture_2d<f32>;
316
+ @group(3) @binding(auto) var pbr_iridescenceThicknessSamplerSampler: sampler;
317
+ #endif
318
+ #ifdef HAS_ANISOTROPYMAP
319
+ @group(3) @binding(auto) var pbr_anisotropySampler: texture_2d<f32>;
320
+ @group(3) @binding(auto) var pbr_anisotropySamplerSampler: sampler;
230
321
  #endif
231
-
232
322
  // Encapsulate the various inputs used by the various functions in the shading equation
233
323
  // We store values in this struct to simplify the integration of alternative implementations
234
324
  // of the shading terms, outlined in the Readme.MD Appendix.
@@ -269,11 +359,9 @@ fn SRGBtoLINEAR(srgbIn: vec4f ) -> vec4f
269
359
  return vec4f(linOut, srgbIn.w);
270
360
  }
271
361
 
272
- // Find the normal for this fragment, pulling either from a predefined normal map
273
- // or from the interpolated mesh normal and tangent attributes.
274
- fn getNormal() -> vec3f
362
+ // Build the tangent basis from interpolated attributes or screen-space derivatives.
363
+ fn getTBN() -> mat3x3f
275
364
  {
276
- // Retrieve the tangent space matrix
277
365
  let pos_dx: vec3f = dpdx(fragmentInputs.pbr_vPosition);
278
366
  let pos_dy: vec3f = dpdy(fragmentInputs.pbr_vPosition);
279
367
  let tex_dx: vec3f = dpdx(vec3f(fragmentInputs.pbr_vUV, 0.0));
@@ -291,16 +379,52 @@ fn getNormal() -> vec3f
291
379
  tbn = fragmentInputs.pbr_vTBN;
292
380
  #endif
293
381
 
382
+ return tbn;
383
+ }
384
+
385
+ // Find the normal for this fragment, pulling either from a predefined normal map
386
+ // or from the interpolated mesh normal and tangent attributes.
387
+ fn getMappedNormal(
388
+ normalSampler: texture_2d<f32>,
389
+ normalSamplerBinding: sampler,
390
+ tbn: mat3x3f,
391
+ normalScale: f32
392
+ ) -> vec3f
393
+ {
394
+ let n = textureSample(normalSampler, normalSamplerBinding, fragmentInputs.pbr_vUV).rgb;
395
+ return normalize(tbn * ((2.0 * n - 1.0) * vec3f(normalScale, normalScale, 1.0)));
396
+ }
397
+
398
+ fn getNormal(tbn: mat3x3f) -> vec3f
399
+ {
294
400
  // The tbn matrix is linearly interpolated, so we need to re-normalize
295
401
  var n: vec3f = normalize(tbn[2].xyz);
296
402
  #ifdef HAS_NORMALMAP
297
- n = textureSample(pbr_normalSampler, pbr_normalSamplerSampler, fragmentInputs.pbr_vUV).rgb;
298
- n = normalize(tbn * ((2.0 * n - 1.0) * vec3f(pbrMaterial.normalScale, pbrMaterial.normalScale, 1.0)));
403
+ n = getMappedNormal(
404
+ pbr_normalSampler,
405
+ pbr_normalSamplerSampler,
406
+ tbn,
407
+ pbrMaterial.normalScale
408
+ );
299
409
  #endif
300
410
 
301
411
  return n;
302
412
  }
303
413
 
414
+ fn getClearcoatNormal(tbn: mat3x3f, baseNormal: vec3f) -> vec3f
415
+ {
416
+ #ifdef HAS_CLEARCOATNORMALMAP
417
+ return getMappedNormal(
418
+ pbr_clearcoatNormalSampler,
419
+ pbr_clearcoatNormalSamplerSampler,
420
+ tbn,
421
+ 1.0
422
+ );
423
+ #else
424
+ return baseNormal;
425
+ #endif
426
+ }
427
+
304
428
  // Calculation of the lighting contribution from an optional Image Based Light source.
305
429
  // Precomputed Environment Maps are required uniform inputs and are computed as outlined in [1].
306
430
  // See our README.md on Environment Maps [3] for additional discussion.
@@ -311,17 +435,25 @@ fn getIBLContribution(pbrInfo: PBRInfo, n: vec3f, reflection: vec3f) -> vec3f
311
435
  let lod: f32 = pbrInfo.perceptualRoughness * mipCount;
312
436
  // retrieve a scale and bias to F0. See [1], Figure 3
313
437
  let brdf = SRGBtoLINEAR(
314
- textureSample(
315
- pbr_BrdfLUT,
316
- pbr_BrdfLUTSampler,
317
- vec2f(pbrInfo.NdotV, 1.0 - pbrInfo.perceptualRoughness)
438
+ textureSampleLevel(
439
+ pbr_brdfLUT,
440
+ pbr_brdfLUTSampler,
441
+ vec2f(pbrInfo.NdotV, 1.0 - pbrInfo.perceptualRoughness),
442
+ 0.0
318
443
  )
319
444
  ).rgb;
320
445
  let diffuseLight =
321
- SRGBtoLINEAR(textureSample(pbr_diffuseEnvSampler, pbr_diffuseEnvSamplerSampler, n)).rgb;
322
- let specularLightDefault =
323
- SRGBtoLINEAR(textureSample(pbr_specularEnvSampler, pbr_specularEnvSamplerSampler, reflection)).rgb;
324
- var specularLight = specularLightDefault;
446
+ SRGBtoLINEAR(
447
+ textureSampleLevel(pbr_diffuseEnvSampler, pbr_diffuseEnvSamplerSampler, n, 0.0)
448
+ ).rgb;
449
+ var specularLight = SRGBtoLINEAR(
450
+ textureSampleLevel(
451
+ pbr_specularEnvSampler,
452
+ pbr_specularEnvSamplerSampler,
453
+ reflection,
454
+ 0.0
455
+ )
456
+ ).rgb;
325
457
  #ifdef USE_TEX_LOD
326
458
  specularLight = SRGBtoLINEAR(
327
459
  textureSampleLevel(
@@ -382,6 +514,172 @@ fn microfacetDistribution(pbrInfo: PBRInfo) -> f32 {
382
514
  return roughnessSq / (M_PI * f * f);
383
515
  }
384
516
 
517
+ fn maxComponent(value: vec3f) -> f32 {
518
+ return max(max(value.r, value.g), value.b);
519
+ }
520
+
521
+ fn getDielectricF0(ior: f32) -> f32 {
522
+ let clampedIor = max(ior, 1.0);
523
+ let ratio = (clampedIor - 1.0) / (clampedIor + 1.0);
524
+ return ratio * ratio;
525
+ }
526
+
527
+ fn normalizeDirection(direction: vec2f) -> vec2f {
528
+ let directionLength = length(direction);
529
+ if (directionLength > 0.0001) {
530
+ return direction / directionLength;
531
+ }
532
+
533
+ return vec2f(1.0, 0.0);
534
+ }
535
+
536
+ fn rotateDirection(direction: vec2f, rotation: f32) -> vec2f {
537
+ let s = sin(rotation);
538
+ let c = cos(rotation);
539
+ return vec2f(direction.x * c - direction.y * s, direction.x * s + direction.y * c);
540
+ }
541
+
542
+ fn getIridescenceTint(iridescence: f32, thickness: f32, NdotV: f32) -> vec3f {
543
+ if (iridescence <= 0.0) {
544
+ return vec3f(1.0);
545
+ }
546
+
547
+ let phase = 0.015 * thickness * pbrMaterial.iridescenceIor + (1.0 - NdotV) * 6.0;
548
+ let thinFilmTint =
549
+ 0.5 +
550
+ 0.5 *
551
+ cos(vec3f(phase, phase + 2.0943951, phase + 4.1887902));
552
+ return mix(vec3f(1.0), thinFilmTint, iridescence);
553
+ }
554
+
555
+ fn getVolumeAttenuation(thickness: f32) -> vec3f {
556
+ if (thickness <= 0.0) {
557
+ return vec3f(1.0);
558
+ }
559
+
560
+ let attenuationCoefficient =
561
+ -log(max(pbrMaterial.attenuationColor, vec3f(0.0001))) /
562
+ max(pbrMaterial.attenuationDistance, 0.0001);
563
+ return exp(-attenuationCoefficient * thickness);
564
+ }
565
+
566
+ fn createClearcoatPBRInfo(
567
+ basePBRInfo: PBRInfo,
568
+ clearcoatNormal: vec3f,
569
+ clearcoatRoughness: f32
570
+ ) -> PBRInfo {
571
+ let perceptualRoughness = clamp(clearcoatRoughness, c_MinRoughness, 1.0);
572
+ let alphaRoughness = perceptualRoughness * perceptualRoughness;
573
+ let NdotV = clamp(abs(dot(clearcoatNormal, basePBRInfo.v)), 0.001, 1.0);
574
+
575
+ return PBRInfo(
576
+ basePBRInfo.NdotL,
577
+ NdotV,
578
+ basePBRInfo.NdotH,
579
+ basePBRInfo.LdotH,
580
+ basePBRInfo.VdotH,
581
+ perceptualRoughness,
582
+ 0.0,
583
+ vec3f(0.04),
584
+ vec3f(1.0),
585
+ alphaRoughness,
586
+ vec3f(0.0),
587
+ vec3f(0.04),
588
+ clearcoatNormal,
589
+ basePBRInfo.v
590
+ );
591
+ }
592
+
593
+ fn calculateClearcoatContribution(
594
+ pbrInfo: PBRInfo,
595
+ lightColor: vec3f,
596
+ clearcoatNormal: vec3f,
597
+ clearcoatFactor: f32,
598
+ clearcoatRoughness: f32
599
+ ) -> vec3f {
600
+ if (clearcoatFactor <= 0.0) {
601
+ return vec3f(0.0);
602
+ }
603
+
604
+ let clearcoatPBRInfo = createClearcoatPBRInfo(pbrInfo, clearcoatNormal, clearcoatRoughness);
605
+ return calculateFinalColor(clearcoatPBRInfo, lightColor) * clearcoatFactor;
606
+ }
607
+
608
+ #ifdef USE_IBL
609
+ fn calculateClearcoatIBLContribution(
610
+ pbrInfo: PBRInfo,
611
+ clearcoatNormal: vec3f,
612
+ reflection: vec3f,
613
+ clearcoatFactor: f32,
614
+ clearcoatRoughness: f32
615
+ ) -> vec3f {
616
+ if (clearcoatFactor <= 0.0) {
617
+ return vec3f(0.0);
618
+ }
619
+
620
+ let clearcoatPBRInfo = createClearcoatPBRInfo(pbrInfo, clearcoatNormal, clearcoatRoughness);
621
+ return getIBLContribution(clearcoatPBRInfo, clearcoatNormal, reflection) * clearcoatFactor;
622
+ }
623
+ #endif
624
+
625
+ fn calculateSheenContribution(
626
+ pbrInfo: PBRInfo,
627
+ lightColor: vec3f,
628
+ sheenColor: vec3f,
629
+ sheenRoughness: f32
630
+ ) -> vec3f {
631
+ if (maxComponent(sheenColor) <= 0.0) {
632
+ return vec3f(0.0);
633
+ }
634
+
635
+ let sheenFresnel = pow(clamp(1.0 - pbrInfo.VdotH, 0.0, 1.0), 5.0);
636
+ let sheenVisibility = mix(1.0, pbrInfo.NdotL * pbrInfo.NdotV, sheenRoughness);
637
+ return pbrInfo.NdotL *
638
+ lightColor *
639
+ sheenColor *
640
+ (0.25 + 0.75 * sheenFresnel) *
641
+ sheenVisibility *
642
+ (1.0 - pbrInfo.metalness);
643
+ }
644
+
645
+ fn calculateAnisotropyBoost(
646
+ pbrInfo: PBRInfo,
647
+ anisotropyTangent: vec3f,
648
+ anisotropyStrength: f32
649
+ ) -> f32 {
650
+ if (anisotropyStrength <= 0.0) {
651
+ return 1.0;
652
+ }
653
+
654
+ let anisotropyBitangent = normalize(cross(pbrInfo.n, anisotropyTangent));
655
+ let bitangentViewAlignment = abs(dot(pbrInfo.v, anisotropyBitangent));
656
+ return mix(1.0, 0.65 + 0.7 * bitangentViewAlignment, anisotropyStrength);
657
+ }
658
+
659
+ fn calculateMaterialLightColor(
660
+ pbrInfo: PBRInfo,
661
+ lightColor: vec3f,
662
+ clearcoatNormal: vec3f,
663
+ clearcoatFactor: f32,
664
+ clearcoatRoughness: f32,
665
+ sheenColor: vec3f,
666
+ sheenRoughness: f32,
667
+ anisotropyTangent: vec3f,
668
+ anisotropyStrength: f32
669
+ ) -> vec3f {
670
+ let anisotropyBoost = calculateAnisotropyBoost(pbrInfo, anisotropyTangent, anisotropyStrength);
671
+ var color = calculateFinalColor(pbrInfo, lightColor) * anisotropyBoost;
672
+ color += calculateClearcoatContribution(
673
+ pbrInfo,
674
+ lightColor,
675
+ clearcoatNormal,
676
+ clearcoatFactor,
677
+ clearcoatRoughness
678
+ );
679
+ color += calculateSheenContribution(pbrInfo, lightColor, sheenColor, sheenRoughness);
680
+ return color;
681
+ }
682
+
385
683
  fn PBRInfo_setAmbientLight(pbrInfo: ptr<function, PBRInfo>) {
386
684
  (*pbrInfo).NdotL = 1.0;
387
685
  (*pbrInfo).NdotH = 0.0;
@@ -406,6 +704,11 @@ fn PBRInfo_setPointLight(pbrInfo: ptr<function, PBRInfo>, pointLight: PointLight
406
704
  PBRInfo_setDirectionalLight(pbrInfo, light_direction);
407
705
  }
408
706
 
707
+ fn PBRInfo_setSpotLight(pbrInfo: ptr<function, PBRInfo>, spotLight: SpotLight) {
708
+ let light_direction = normalize(spotLight.position - fragmentInputs.pbr_vPosition);
709
+ PBRInfo_setDirectionalLight(pbrInfo, light_direction);
710
+ }
711
+
409
712
  fn calculateFinalColor(pbrInfo: PBRInfo, lightColor: vec3<f32>) -> vec3<f32> {
410
713
  // Calculate the shading terms for the microfacet specular shading model
411
714
  let F = specularReflection(pbrInfo);
@@ -435,6 +738,7 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
435
738
  #endif
436
739
 
437
740
  var color = vec3<f32>(0.0, 0.0, 0.0);
741
+ var transmission = 0.0;
438
742
 
439
743
  if (pbrMaterial.unlit != 0u) {
440
744
  color = baseColor.rgb;
@@ -457,14 +761,308 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
457
761
  #endif
458
762
  perceptualRoughness = clamp(perceptualRoughness, c_MinRoughness, 1.0);
459
763
  metallic = clamp(metallic, 0.0, 1.0);
764
+ let tbn = getTBN();
765
+ let n = getNormal(tbn); // normal at surface point
766
+ let v = normalize(pbrProjection.camera - fragmentInputs.pbr_vPosition); // Vector from surface point to camera
767
+ let NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
768
+ var useExtendedPBR = false;
769
+ #ifdef USE_MATERIAL_EXTENSIONS
770
+ useExtendedPBR =
771
+ pbrMaterial.specularColorMapEnabled != 0 ||
772
+ pbrMaterial.specularIntensityMapEnabled != 0 ||
773
+ abs(pbrMaterial.specularIntensityFactor - 1.0) > 0.0001 ||
774
+ maxComponent(abs(pbrMaterial.specularColorFactor - vec3f(1.0))) > 0.0001 ||
775
+ abs(pbrMaterial.ior - 1.5) > 0.0001 ||
776
+ pbrMaterial.transmissionMapEnabled != 0 ||
777
+ pbrMaterial.transmissionFactor > 0.0001 ||
778
+ pbrMaterial.clearcoatMapEnabled != 0 ||
779
+ pbrMaterial.clearcoatRoughnessMapEnabled != 0 ||
780
+ pbrMaterial.clearcoatFactor > 0.0001 ||
781
+ pbrMaterial.clearcoatRoughnessFactor > 0.0001 ||
782
+ pbrMaterial.sheenColorMapEnabled != 0 ||
783
+ pbrMaterial.sheenRoughnessMapEnabled != 0 ||
784
+ maxComponent(pbrMaterial.sheenColorFactor) > 0.0001 ||
785
+ pbrMaterial.sheenRoughnessFactor > 0.0001 ||
786
+ pbrMaterial.iridescenceMapEnabled != 0 ||
787
+ pbrMaterial.iridescenceFactor > 0.0001 ||
788
+ abs(pbrMaterial.iridescenceIor - 1.3) > 0.0001 ||
789
+ abs(pbrMaterial.iridescenceThicknessRange.x - 100.0) > 0.0001 ||
790
+ abs(pbrMaterial.iridescenceThicknessRange.y - 400.0) > 0.0001 ||
791
+ pbrMaterial.anisotropyMapEnabled != 0 ||
792
+ pbrMaterial.anisotropyStrength > 0.0001 ||
793
+ abs(pbrMaterial.anisotropyRotation) > 0.0001 ||
794
+ length(pbrMaterial.anisotropyDirection - vec2f(1.0, 0.0)) > 0.0001;
795
+ #endif
796
+
797
+ if (!useExtendedPBR) {
798
+ let alphaRoughness = perceptualRoughness * perceptualRoughness;
799
+
800
+ let f0 = vec3<f32>(0.04);
801
+ var diffuseColor = baseColor.rgb * (vec3<f32>(1.0) - f0);
802
+ diffuseColor *= 1.0 - metallic;
803
+ let specularColor = mix(f0, baseColor.rgb, metallic);
804
+
805
+ let reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
806
+ let reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
807
+ let specularEnvironmentR0 = specularColor;
808
+ let specularEnvironmentR90 = vec3<f32>(1.0, 1.0, 1.0) * reflectance90;
809
+ let reflection = -normalize(reflect(v, n));
810
+
811
+ var pbrInfo = PBRInfo(
812
+ 0.0, // NdotL
813
+ NdotV,
814
+ 0.0, // NdotH
815
+ 0.0, // LdotH
816
+ 0.0, // VdotH
817
+ perceptualRoughness,
818
+ metallic,
819
+ specularEnvironmentR0,
820
+ specularEnvironmentR90,
821
+ alphaRoughness,
822
+ diffuseColor,
823
+ specularColor,
824
+ n,
825
+ v
826
+ );
827
+
828
+ #ifdef USE_LIGHTS
829
+ PBRInfo_setAmbientLight(&pbrInfo);
830
+ color += calculateFinalColor(pbrInfo, lighting.ambientColor);
831
+
832
+ for (var i = 0; i < lighting.directionalLightCount; i++) {
833
+ if (i < lighting.directionalLightCount) {
834
+ PBRInfo_setDirectionalLight(&pbrInfo, lighting_getDirectionalLight(i).direction);
835
+ color += calculateFinalColor(pbrInfo, lighting_getDirectionalLight(i).color);
836
+ }
837
+ }
838
+
839
+ for (var i = 0; i < lighting.pointLightCount; i++) {
840
+ if (i < lighting.pointLightCount) {
841
+ PBRInfo_setPointLight(&pbrInfo, lighting_getPointLight(i));
842
+ let attenuation = getPointLightAttenuation(
843
+ lighting_getPointLight(i),
844
+ distance(lighting_getPointLight(i).position, fragmentInputs.pbr_vPosition)
845
+ );
846
+ color += calculateFinalColor(pbrInfo, lighting_getPointLight(i).color / attenuation);
847
+ }
848
+ }
849
+
850
+ for (var i = 0; i < lighting.spotLightCount; i++) {
851
+ if (i < lighting.spotLightCount) {
852
+ PBRInfo_setSpotLight(&pbrInfo, lighting_getSpotLight(i));
853
+ let attenuation = getSpotLightAttenuation(
854
+ lighting_getSpotLight(i),
855
+ fragmentInputs.pbr_vPosition
856
+ );
857
+ color += calculateFinalColor(pbrInfo, lighting_getSpotLight(i).color / attenuation);
858
+ }
859
+ }
860
+ #endif
861
+
862
+ #ifdef USE_IBL
863
+ if (pbrMaterial.IBLenabled != 0) {
864
+ color += getIBLContribution(pbrInfo, n, reflection);
865
+ }
866
+ #endif
867
+
868
+ #ifdef HAS_OCCLUSIONMAP
869
+ if (pbrMaterial.occlusionMapEnabled != 0) {
870
+ let ao =
871
+ textureSample(pbr_occlusionSampler, pbr_occlusionSamplerSampler, fragmentInputs.pbr_vUV).r;
872
+ color = mix(color, color * ao, pbrMaterial.occlusionStrength);
873
+ }
874
+ #endif
875
+
876
+ var emissive = pbrMaterial.emissiveFactor;
877
+ #ifdef HAS_EMISSIVEMAP
878
+ if (pbrMaterial.emissiveMapEnabled != 0u) {
879
+ emissive *= SRGBtoLINEAR(
880
+ textureSample(pbr_emissiveSampler, pbr_emissiveSamplerSampler, fragmentInputs.pbr_vUV)
881
+ ).rgb;
882
+ }
883
+ #endif
884
+ color += emissive * pbrMaterial.emissiveStrength;
885
+
886
+ #ifdef PBR_DEBUG
887
+ color = mix(color, baseColor.rgb, pbrMaterial.scaleDiffBaseMR.y);
888
+ color = mix(color, vec3<f32>(metallic), pbrMaterial.scaleDiffBaseMR.z);
889
+ color = mix(color, vec3<f32>(perceptualRoughness), pbrMaterial.scaleDiffBaseMR.w);
890
+ #endif
891
+
892
+ return vec4<f32>(pow(color, vec3<f32>(1.0 / 2.2)), baseColor.a);
893
+ }
894
+
895
+ var specularIntensity = pbrMaterial.specularIntensityFactor;
896
+ #ifdef HAS_SPECULARINTENSITYMAP
897
+ if (pbrMaterial.specularIntensityMapEnabled != 0) {
898
+ specularIntensity *= textureSample(
899
+ pbr_specularIntensitySampler,
900
+ pbr_specularIntensitySamplerSampler,
901
+ fragmentInputs.pbr_vUV
902
+ ).a;
903
+ }
904
+ #endif
905
+
906
+ var specularFactor = pbrMaterial.specularColorFactor;
907
+ #ifdef HAS_SPECULARCOLORMAP
908
+ if (pbrMaterial.specularColorMapEnabled != 0) {
909
+ specularFactor *= SRGBtoLINEAR(
910
+ textureSample(
911
+ pbr_specularColorSampler,
912
+ pbr_specularColorSamplerSampler,
913
+ fragmentInputs.pbr_vUV
914
+ )
915
+ ).rgb;
916
+ }
917
+ #endif
918
+
919
+ transmission = pbrMaterial.transmissionFactor;
920
+ #ifdef HAS_TRANSMISSIONMAP
921
+ if (pbrMaterial.transmissionMapEnabled != 0) {
922
+ transmission *= textureSample(
923
+ pbr_transmissionSampler,
924
+ pbr_transmissionSamplerSampler,
925
+ fragmentInputs.pbr_vUV
926
+ ).r;
927
+ }
928
+ #endif
929
+ transmission = clamp(transmission * (1.0 - metallic), 0.0, 1.0);
930
+ var thickness = max(pbrMaterial.thicknessFactor, 0.0);
931
+ #ifdef HAS_THICKNESSMAP
932
+ thickness *= textureSample(
933
+ pbr_thicknessSampler,
934
+ pbr_thicknessSamplerSampler,
935
+ fragmentInputs.pbr_vUV
936
+ ).g;
937
+ #endif
938
+
939
+ var clearcoatFactor = pbrMaterial.clearcoatFactor;
940
+ var clearcoatRoughness = pbrMaterial.clearcoatRoughnessFactor;
941
+ #ifdef HAS_CLEARCOATMAP
942
+ if (pbrMaterial.clearcoatMapEnabled != 0) {
943
+ clearcoatFactor *= textureSample(
944
+ pbr_clearcoatSampler,
945
+ pbr_clearcoatSamplerSampler,
946
+ fragmentInputs.pbr_vUV
947
+ ).r;
948
+ }
949
+ #endif
950
+ #ifdef HAS_CLEARCOATROUGHNESSMAP
951
+ if (pbrMaterial.clearcoatRoughnessMapEnabled != 0) {
952
+ clearcoatRoughness *= textureSample(
953
+ pbr_clearcoatRoughnessSampler,
954
+ pbr_clearcoatRoughnessSamplerSampler,
955
+ fragmentInputs.pbr_vUV
956
+ ).g;
957
+ }
958
+ #endif
959
+ clearcoatFactor = clamp(clearcoatFactor, 0.0, 1.0);
960
+ clearcoatRoughness = clamp(clearcoatRoughness, c_MinRoughness, 1.0);
961
+ let clearcoatNormal = getClearcoatNormal(tbn, n);
962
+
963
+ var sheenColor = pbrMaterial.sheenColorFactor;
964
+ var sheenRoughness = pbrMaterial.sheenRoughnessFactor;
965
+ #ifdef HAS_SHEENCOLORMAP
966
+ if (pbrMaterial.sheenColorMapEnabled != 0) {
967
+ sheenColor *= SRGBtoLINEAR(
968
+ textureSample(
969
+ pbr_sheenColorSampler,
970
+ pbr_sheenColorSamplerSampler,
971
+ fragmentInputs.pbr_vUV
972
+ )
973
+ ).rgb;
974
+ }
975
+ #endif
976
+ #ifdef HAS_SHEENROUGHNESSMAP
977
+ if (pbrMaterial.sheenRoughnessMapEnabled != 0) {
978
+ sheenRoughness *= textureSample(
979
+ pbr_sheenRoughnessSampler,
980
+ pbr_sheenRoughnessSamplerSampler,
981
+ fragmentInputs.pbr_vUV
982
+ ).a;
983
+ }
984
+ #endif
985
+ sheenRoughness = clamp(sheenRoughness, c_MinRoughness, 1.0);
986
+
987
+ var iridescence = pbrMaterial.iridescenceFactor;
988
+ #ifdef HAS_IRIDESCENCEMAP
989
+ if (pbrMaterial.iridescenceMapEnabled != 0) {
990
+ iridescence *= textureSample(
991
+ pbr_iridescenceSampler,
992
+ pbr_iridescenceSamplerSampler,
993
+ fragmentInputs.pbr_vUV
994
+ ).r;
995
+ }
996
+ #endif
997
+ iridescence = clamp(iridescence, 0.0, 1.0);
998
+ var iridescenceThickness = mix(
999
+ pbrMaterial.iridescenceThicknessRange.x,
1000
+ pbrMaterial.iridescenceThicknessRange.y,
1001
+ 0.5
1002
+ );
1003
+ #ifdef HAS_IRIDESCENCETHICKNESSMAP
1004
+ iridescenceThickness = mix(
1005
+ pbrMaterial.iridescenceThicknessRange.x,
1006
+ pbrMaterial.iridescenceThicknessRange.y,
1007
+ textureSample(
1008
+ pbr_iridescenceThicknessSampler,
1009
+ pbr_iridescenceThicknessSamplerSampler,
1010
+ fragmentInputs.pbr_vUV
1011
+ ).g
1012
+ );
1013
+ #endif
1014
+
1015
+ var anisotropyStrength = clamp(pbrMaterial.anisotropyStrength, 0.0, 1.0);
1016
+ var anisotropyDirection = normalizeDirection(pbrMaterial.anisotropyDirection);
1017
+ #ifdef HAS_ANISOTROPYMAP
1018
+ if (pbrMaterial.anisotropyMapEnabled != 0) {
1019
+ let anisotropySample = textureSample(
1020
+ pbr_anisotropySampler,
1021
+ pbr_anisotropySamplerSampler,
1022
+ fragmentInputs.pbr_vUV
1023
+ ).rgb;
1024
+ anisotropyStrength *= anisotropySample.b;
1025
+ let mappedDirection = anisotropySample.rg * 2.0 - 1.0;
1026
+ if (length(mappedDirection) > 0.0001) {
1027
+ anisotropyDirection = normalize(mappedDirection);
1028
+ }
1029
+ }
1030
+ #endif
1031
+ anisotropyDirection = rotateDirection(anisotropyDirection, pbrMaterial.anisotropyRotation);
1032
+ var anisotropyTangent =
1033
+ normalize(tbn[0] * anisotropyDirection.x + tbn[1] * anisotropyDirection.y);
1034
+ if (length(anisotropyTangent) < 0.0001) {
1035
+ anisotropyTangent = normalize(tbn[0]);
1036
+ }
1037
+ let anisotropyViewAlignment = abs(dot(v, anisotropyTangent));
1038
+ perceptualRoughness = mix(
1039
+ perceptualRoughness,
1040
+ clamp(perceptualRoughness * (1.0 - 0.6 * anisotropyViewAlignment), c_MinRoughness, 1.0),
1041
+ anisotropyStrength
1042
+ );
1043
+
460
1044
  // Roughness is authored as perceptual roughness; as is convention,
461
1045
  // convert to material roughness by squaring the perceptual roughness [2].
462
1046
  let alphaRoughness = perceptualRoughness * perceptualRoughness;
463
1047
 
464
- let f0 = vec3<f32>(0.04);
465
- var diffuseColor = baseColor.rgb * (vec3<f32>(1.0) - f0);
466
- diffuseColor *= 1.0 - metallic;
467
- let specularColor = mix(f0, baseColor.rgb, metallic);
1048
+ let dielectricF0 = getDielectricF0(pbrMaterial.ior);
1049
+ var dielectricSpecularF0 = min(
1050
+ vec3f(dielectricF0) * specularFactor * specularIntensity,
1051
+ vec3f(1.0)
1052
+ );
1053
+ let iridescenceTint = getIridescenceTint(iridescence, iridescenceThickness, NdotV);
1054
+ dielectricSpecularF0 = mix(
1055
+ dielectricSpecularF0,
1056
+ dielectricSpecularF0 * iridescenceTint,
1057
+ iridescence
1058
+ );
1059
+ var diffuseColor = baseColor.rgb * (vec3f(1.0) - dielectricSpecularF0);
1060
+ diffuseColor *= (1.0 - metallic) * (1.0 - transmission);
1061
+ var specularColor = mix(dielectricSpecularF0, baseColor.rgb, metallic);
1062
+
1063
+ let baseLayerEnergy = 1.0 - clearcoatFactor * 0.25;
1064
+ diffuseColor *= baseLayerEnergy;
1065
+ specularColor *= baseLayerEnergy;
468
1066
 
469
1067
  // Compute reflectance.
470
1068
  let reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
@@ -476,11 +1074,6 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
476
1074
  let reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
477
1075
  let specularEnvironmentR0 = specularColor;
478
1076
  let specularEnvironmentR90 = vec3<f32>(1.0, 1.0, 1.0) * reflectance90;
479
-
480
- let n = getNormal(); // normal at surface point
481
- let v = normalize(pbrProjection.camera - fragmentInputs.pbr_vPosition); // Vector from surface point to camera
482
-
483
- let NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
484
1077
  let reflection = -normalize(reflect(v, n));
485
1078
 
486
1079
  var pbrInfo = PBRInfo(
@@ -503,13 +1096,33 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
503
1096
  #ifdef USE_LIGHTS
504
1097
  // Apply ambient light
505
1098
  PBRInfo_setAmbientLight(&pbrInfo);
506
- color += calculateFinalColor(pbrInfo, lighting.ambientColor);
1099
+ color += calculateMaterialLightColor(
1100
+ pbrInfo,
1101
+ lighting.ambientColor,
1102
+ clearcoatNormal,
1103
+ clearcoatFactor,
1104
+ clearcoatRoughness,
1105
+ sheenColor,
1106
+ sheenRoughness,
1107
+ anisotropyTangent,
1108
+ anisotropyStrength
1109
+ );
507
1110
 
508
1111
  // Apply directional light
509
1112
  for (var i = 0; i < lighting.directionalLightCount; i++) {
510
1113
  if (i < lighting.directionalLightCount) {
511
1114
  PBRInfo_setDirectionalLight(&pbrInfo, lighting_getDirectionalLight(i).direction);
512
- color += calculateFinalColor(pbrInfo, lighting_getDirectionalLight(i).color);
1115
+ color += calculateMaterialLightColor(
1116
+ pbrInfo,
1117
+ lighting_getDirectionalLight(i).color,
1118
+ clearcoatNormal,
1119
+ clearcoatFactor,
1120
+ clearcoatRoughness,
1121
+ sheenColor,
1122
+ sheenRoughness,
1123
+ anisotropyTangent,
1124
+ anisotropyStrength
1125
+ );
513
1126
  }
514
1127
  }
515
1128
 
@@ -521,7 +1134,35 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
521
1134
  lighting_getPointLight(i),
522
1135
  distance(lighting_getPointLight(i).position, fragmentInputs.pbr_vPosition)
523
1136
  );
524
- color += calculateFinalColor(pbrInfo, lighting_getPointLight(i).color / attenuation);
1137
+ color += calculateMaterialLightColor(
1138
+ pbrInfo,
1139
+ lighting_getPointLight(i).color / attenuation,
1140
+ clearcoatNormal,
1141
+ clearcoatFactor,
1142
+ clearcoatRoughness,
1143
+ sheenColor,
1144
+ sheenRoughness,
1145
+ anisotropyTangent,
1146
+ anisotropyStrength
1147
+ );
1148
+ }
1149
+ }
1150
+
1151
+ for (var i = 0; i < lighting.spotLightCount; i++) {
1152
+ if (i < lighting.spotLightCount) {
1153
+ PBRInfo_setSpotLight(&pbrInfo, lighting_getSpotLight(i));
1154
+ let attenuation = getSpotLightAttenuation(lighting_getSpotLight(i), fragmentInputs.pbr_vPosition);
1155
+ color += calculateMaterialLightColor(
1156
+ pbrInfo,
1157
+ lighting_getSpotLight(i).color / attenuation,
1158
+ clearcoatNormal,
1159
+ clearcoatFactor,
1160
+ clearcoatRoughness,
1161
+ sheenColor,
1162
+ sheenRoughness,
1163
+ anisotropyTangent,
1164
+ anisotropyStrength
1165
+ );
525
1166
  }
526
1167
  }
527
1168
  #endif
@@ -529,7 +1170,16 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
529
1170
  // Calculate lighting contribution from image based lighting source (IBL)
530
1171
  #ifdef USE_IBL
531
1172
  if (pbrMaterial.IBLenabled != 0) {
532
- color += getIBLContribution(pbrInfo, n, reflection);
1173
+ color += getIBLContribution(pbrInfo, n, reflection) *
1174
+ calculateAnisotropyBoost(pbrInfo, anisotropyTangent, anisotropyStrength);
1175
+ color += calculateClearcoatIBLContribution(
1176
+ pbrInfo,
1177
+ clearcoatNormal,
1178
+ -normalize(reflect(v, clearcoatNormal)),
1179
+ clearcoatFactor,
1180
+ clearcoatRoughness
1181
+ );
1182
+ color += sheenColor * pbrMaterial.scaleIBLAmbient.x * (1.0 - sheenRoughness) * 0.25;
533
1183
  }
534
1184
  #endif
535
1185
 
@@ -542,14 +1192,19 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
542
1192
  }
543
1193
  #endif
544
1194
 
1195
+ var emissive = pbrMaterial.emissiveFactor;
545
1196
  #ifdef HAS_EMISSIVEMAP
546
1197
  if (pbrMaterial.emissiveMapEnabled != 0u) {
547
- let emissive = SRGBtoLINEAR(
1198
+ emissive *= SRGBtoLINEAR(
548
1199
  textureSample(pbr_emissiveSampler, pbr_emissiveSamplerSampler, fragmentInputs.pbr_vUV)
549
- ).rgb * pbrMaterial.emissiveFactor;
550
- color += emissive;
1200
+ ).rgb;
551
1201
  }
552
1202
  #endif
1203
+ color += emissive * pbrMaterial.emissiveStrength;
1204
+
1205
+ if (transmission > 0.0) {
1206
+ color = mix(color, color * getVolumeAttenuation(thickness), transmission);
1207
+ }
553
1208
 
554
1209
  // This section uses mix to override final color for reference app visualization
555
1210
  // of various parameters in the lighting equation.
@@ -568,7 +1223,8 @@ fn pbr_filterColor(colorUnused: vec4<f32>) -> vec4<f32> {
568
1223
  #endif
569
1224
  }
570
1225
 
571
- return vec4<f32>(pow(color, vec3<f32>(1.0 / 2.2)), baseColor.a);
1226
+ let alpha = clamp(baseColor.a * (1.0 - transmission), 0.0, 1.0);
1227
+ return vec4<f32>(pow(color, vec3<f32>(1.0 / 2.2)), alpha);
572
1228
  }
573
1229
  `;
574
1230
  //# sourceMappingURL=pbr-material-wgsl.js.map