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