@luma.gl/shadertools 9.2.6 → 9.3.0-alpha.10

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 (174) hide show
  1. package/dist/dist.dev.js +4798 -6439
  2. package/dist/dist.min.js +2047 -311
  3. package/dist/index.cjs +3033 -507
  4. package/dist/index.cjs.map +4 -4
  5. package/dist/index.d.ts +12 -2
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +5 -2
  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 +35 -8
  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 +20 -3
  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 +214 -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 +7 -4
  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 +91 -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 +209 -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 +12 -6
  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/assert.d.ts.map +1 -1
  37. package/dist/lib/utils/assert.js +3 -1
  38. package/dist/lib/utils/assert.js.map +1 -1
  39. package/dist/lib/utils/uniform-types.d.ts +11 -7
  40. package/dist/lib/utils/uniform-types.d.ts.map +1 -1
  41. package/dist/modules/engine/picking/picking.d.ts +5 -2
  42. package/dist/modules/engine/picking/picking.d.ts.map +1 -1
  43. package/dist/modules/engine/picking/picking.js +5 -2
  44. package/dist/modules/engine/picking/picking.js.map +1 -1
  45. package/dist/modules/engine/project/project.d.ts +1 -1
  46. package/dist/modules/engine/project/project.js +1 -1
  47. package/dist/modules/engine/skin/skin.d.ts +30 -0
  48. package/dist/modules/engine/skin/skin.d.ts.map +1 -0
  49. package/dist/modules/engine/skin/skin.js +86 -0
  50. package/dist/modules/engine/skin/skin.js.map +1 -0
  51. package/dist/modules/lighting/gouraud-material/gouraud-material.d.ts +1 -0
  52. package/dist/modules/lighting/gouraud-material/gouraud-material.d.ts.map +1 -1
  53. package/dist/modules/lighting/gouraud-material/gouraud-material.js +3 -0
  54. package/dist/modules/lighting/gouraud-material/gouraud-material.js.map +1 -1
  55. package/dist/modules/lighting/ibl/ibl.d.ts +26 -0
  56. package/dist/modules/lighting/ibl/ibl.d.ts.map +1 -0
  57. package/dist/modules/lighting/ibl/ibl.js +33 -0
  58. package/dist/modules/lighting/ibl/ibl.js.map +1 -0
  59. package/dist/modules/lighting/lambert-material/lambert-material.d.ts +10 -0
  60. package/dist/modules/lighting/lambert-material/lambert-material.d.ts.map +1 -0
  61. package/dist/modules/lighting/lambert-material/lambert-material.js +33 -0
  62. package/dist/modules/lighting/lambert-material/lambert-material.js.map +1 -0
  63. package/dist/modules/lighting/lambert-material/lambert-shaders-glsl.d.ts +3 -0
  64. package/dist/modules/lighting/lambert-material/lambert-shaders-glsl.d.ts.map +1 -0
  65. package/dist/modules/lighting/lambert-material/lambert-shaders-glsl.js +60 -0
  66. package/dist/modules/lighting/lambert-material/lambert-shaders-glsl.js.map +1 -0
  67. package/dist/modules/lighting/lambert-material/lambert-shaders-wgsl.d.ts +2 -0
  68. package/dist/modules/lighting/lambert-material/lambert-shaders-wgsl.d.ts.map +1 -0
  69. package/dist/modules/lighting/lambert-material/lambert-shaders-wgsl.js +73 -0
  70. package/dist/modules/lighting/lambert-material/lambert-shaders-wgsl.js.map +1 -0
  71. package/dist/modules/lighting/lights/lighting-glsl.d.ts +1 -1
  72. package/dist/modules/lighting/lights/lighting-glsl.d.ts.map +1 -1
  73. package/dist/modules/lighting/lights/lighting-glsl.js +44 -38
  74. package/dist/modules/lighting/lights/lighting-glsl.js.map +1 -1
  75. package/dist/modules/lighting/lights/lighting-wgsl.d.ts +1 -1
  76. package/dist/modules/lighting/lights/lighting-wgsl.d.ts.map +1 -1
  77. package/dist/modules/lighting/lights/lighting-wgsl.js +46 -18
  78. package/dist/modules/lighting/lights/lighting-wgsl.js.map +1 -1
  79. package/dist/modules/lighting/lights/lighting.d.ts +104 -62
  80. package/dist/modules/lighting/lights/lighting.d.ts.map +1 -1
  81. package/dist/modules/lighting/lights/lighting.js +107 -68
  82. package/dist/modules/lighting/lights/lighting.js.map +1 -1
  83. package/dist/modules/lighting/no-material/dirlight.d.ts +8 -3
  84. package/dist/modules/lighting/no-material/dirlight.d.ts.map +1 -1
  85. package/dist/modules/lighting/no-material/dirlight.js +4 -2
  86. package/dist/modules/lighting/no-material/dirlight.js.map +1 -1
  87. package/dist/modules/lighting/pbr-material/pbr-material-glsl.d.ts +1 -1
  88. package/dist/modules/lighting/pbr-material/pbr-material-glsl.d.ts.map +1 -1
  89. package/dist/modules/lighting/pbr-material/pbr-material-glsl.js +581 -28
  90. package/dist/modules/lighting/pbr-material/pbr-material-glsl.js.map +1 -1
  91. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.d.ts +2 -2
  92. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.d.ts.map +1 -1
  93. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.js +850 -107
  94. package/dist/modules/lighting/pbr-material/pbr-material-wgsl.js.map +1 -1
  95. package/dist/modules/lighting/pbr-material/pbr-material.d.ts +172 -41
  96. package/dist/modules/lighting/pbr-material/pbr-material.d.ts.map +1 -1
  97. package/dist/modules/lighting/pbr-material/pbr-material.js +109 -1
  98. package/dist/modules/lighting/pbr-material/pbr-material.js.map +1 -1
  99. package/dist/modules/lighting/pbr-material/pbr-projection.d.ts.map +1 -1
  100. package/dist/modules/lighting/pbr-material/pbr-projection.js +14 -2
  101. package/dist/modules/lighting/pbr-material/pbr-projection.js.map +1 -1
  102. package/dist/modules/lighting/pbr-material/pbr-scene.d.ts +40 -0
  103. package/dist/modules/lighting/pbr-material/pbr-scene.d.ts.map +1 -0
  104. package/dist/modules/lighting/pbr-material/pbr-scene.js +67 -0
  105. package/dist/modules/lighting/pbr-material/pbr-scene.js.map +1 -0
  106. package/dist/modules/lighting/phong-material/phong-material.d.ts +1 -0
  107. package/dist/modules/lighting/phong-material/phong-material.d.ts.map +1 -1
  108. package/dist/modules/lighting/phong-material/phong-material.js +4 -0
  109. package/dist/modules/lighting/phong-material/phong-material.js.map +1 -1
  110. package/dist/modules/lighting/phong-material/phong-shaders-glsl.d.ts +2 -2
  111. package/dist/modules/lighting/phong-material/phong-shaders-glsl.d.ts.map +1 -1
  112. package/dist/modules/lighting/phong-material/phong-shaders-glsl.js +17 -6
  113. package/dist/modules/lighting/phong-material/phong-shaders-glsl.js.map +1 -1
  114. package/dist/modules/lighting/phong-material/phong-shaders-wgsl.d.ts +1 -40
  115. package/dist/modules/lighting/phong-material/phong-shaders-wgsl.d.ts.map +1 -1
  116. package/dist/modules/lighting/phong-material/phong-shaders-wgsl.js +71 -76
  117. package/dist/modules/lighting/phong-material/phong-shaders-wgsl.js.map +1 -1
  118. package/dist/modules/math/fp64/fp64-arithmetic-glsl.d.ts +1 -1
  119. package/dist/modules/math/fp64/fp64-arithmetic-glsl.d.ts.map +1 -1
  120. package/dist/modules/math/fp64/fp64-arithmetic-glsl.js +42 -11
  121. package/dist/modules/math/fp64/fp64-arithmetic-glsl.js.map +1 -1
  122. package/dist/modules/math/fp64/fp64-arithmetic-wgsl.d.ts +2 -0
  123. package/dist/modules/math/fp64/fp64-arithmetic-wgsl.d.ts.map +1 -0
  124. package/dist/modules/math/fp64/fp64-arithmetic-wgsl.js +212 -0
  125. package/dist/modules/math/fp64/fp64-arithmetic-wgsl.js.map +1 -0
  126. package/dist/modules/math/fp64/fp64.d.ts +1 -0
  127. package/dist/modules/math/fp64/fp64.d.ts.map +1 -1
  128. package/dist/modules/math/fp64/fp64.js +8 -2
  129. package/dist/modules/math/fp64/fp64.js.map +1 -1
  130. package/dist/modules/math/random/random.d.ts +1 -1
  131. package/dist/modules/math/random/random.d.ts.map +1 -1
  132. package/dist/modules/math/random/random.js +2 -3
  133. package/dist/modules/math/random/random.js.map +1 -1
  134. package/package.json +4 -5
  135. package/src/index.ts +37 -6
  136. package/src/lib/preprocessor/preprocessor.ts +44 -8
  137. package/src/lib/shader-assembler.ts +25 -3
  138. package/src/lib/shader-assembly/assemble-shaders.ts +384 -12
  139. package/src/lib/shader-assembly/wgsl-binding-debug.ts +216 -0
  140. package/src/lib/shader-generator/glsl/generate-glsl.ts +11 -5
  141. package/src/lib/shader-generator/wgsl/generate-wgsl.ts +6 -0
  142. package/src/lib/shader-module/shader-module-uniform-layout.ts +346 -0
  143. package/src/lib/shader-module/shader-module.ts +17 -7
  144. package/src/lib/utils/assert.ts +3 -1
  145. package/src/lib/utils/uniform-types.ts +24 -9
  146. package/src/modules/engine/picking/picking.ts +5 -2
  147. package/src/modules/engine/project/project.ts +1 -1
  148. package/src/modules/engine/skin/skin.ts +114 -0
  149. package/src/modules/lighting/gouraud-material/gouraud-material.ts +4 -0
  150. package/src/modules/lighting/ibl/ibl.ts +44 -0
  151. package/src/modules/lighting/lambert-material/lambert-material.ts +42 -0
  152. package/src/modules/lighting/lambert-material/lambert-shaders-glsl.ts +61 -0
  153. package/src/modules/lighting/lambert-material/lambert-shaders-wgsl.ts +73 -0
  154. package/src/modules/lighting/lights/lighting-glsl.ts +44 -38
  155. package/src/modules/lighting/lights/lighting-wgsl.ts +46 -18
  156. package/src/modules/lighting/lights/lighting.ts +198 -99
  157. package/src/modules/lighting/no-material/dirlight.ts +4 -2
  158. package/src/modules/lighting/pbr-material/pbr-material-glsl.ts +581 -28
  159. package/src/modules/lighting/pbr-material/pbr-material-wgsl.ts +850 -107
  160. package/src/modules/lighting/pbr-material/pbr-material.ts +185 -5
  161. package/src/modules/lighting/pbr-material/pbr-projection.ts +15 -2
  162. package/src/modules/lighting/pbr-material/pbr-scene.ts +91 -0
  163. package/src/modules/lighting/phong-material/phong-material.ts +5 -0
  164. package/src/modules/lighting/phong-material/phong-shaders-glsl.ts +17 -6
  165. package/src/modules/lighting/phong-material/phong-shaders-wgsl.ts +71 -77
  166. package/src/modules/math/fp64/fp64-arithmetic-glsl.ts +42 -11
  167. package/src/modules/math/fp64/fp64-arithmetic-wgsl.ts +212 -0
  168. package/src/modules/math/fp64/fp64.ts +9 -3
  169. package/src/modules/math/random/random.ts +2 -3
  170. package/dist/lib/wgsl/get-shader-layout-wgsl.d.ts +0 -8
  171. package/dist/lib/wgsl/get-shader-layout-wgsl.d.ts.map +0 -1
  172. package/dist/lib/wgsl/get-shader-layout-wgsl.js +0 -95
  173. package/dist/lib/wgsl/get-shader-layout-wgsl.js.map +0 -1
  174. package/src/lib/wgsl/get-shader-layout-wgsl.ts +0 -105
@@ -48,7 +48,7 @@ void pbr_setPositionNormalTangentUV(vec4 position, vec4 normal, vec4 tangent, ve
48
48
  export const fs = /* glsl */ `\
49
49
  precision highp float;
50
50
 
51
- uniform pbrMaterialUniforms {
51
+ layout(std140) uniform pbrMaterialUniforms {
52
52
  // Material is unlit
53
53
  bool unlit;
54
54
 
@@ -70,6 +70,42 @@ uniform pbrMaterialUniforms {
70
70
 
71
71
  bool alphaCutoffEnabled;
72
72
  float alphaCutoff; // #ifdef ALPHA_CUTOFF
73
+
74
+ vec3 specularColorFactor;
75
+ float specularIntensityFactor;
76
+ bool specularColorMapEnabled;
77
+ bool specularIntensityMapEnabled;
78
+
79
+ float ior;
80
+
81
+ float transmissionFactor;
82
+ bool transmissionMapEnabled;
83
+
84
+ float thicknessFactor;
85
+ float attenuationDistance;
86
+ vec3 attenuationColor;
87
+
88
+ float clearcoatFactor;
89
+ float clearcoatRoughnessFactor;
90
+ bool clearcoatMapEnabled;
91
+ bool clearcoatRoughnessMapEnabled;
92
+
93
+ vec3 sheenColorFactor;
94
+ float sheenRoughnessFactor;
95
+ bool sheenColorMapEnabled;
96
+ bool sheenRoughnessMapEnabled;
97
+
98
+ float iridescenceFactor;
99
+ float iridescenceIor;
100
+ vec2 iridescenceThicknessRange;
101
+ bool iridescenceMapEnabled;
102
+
103
+ float anisotropyStrength;
104
+ float anisotropyRotation;
105
+ vec2 anisotropyDirection;
106
+ bool anisotropyMapEnabled;
107
+
108
+ float emissiveStrength;
73
109
 
74
110
  // IBL
75
111
  bool IBLenabled;
@@ -98,12 +134,42 @@ uniform sampler2D pbr_metallicRoughnessSampler;
98
134
  #ifdef HAS_OCCLUSIONMAP
99
135
  uniform sampler2D pbr_occlusionSampler;
100
136
  #endif
101
- #ifdef USE_IBL
102
- uniform samplerCube pbr_diffuseEnvSampler;
103
- uniform samplerCube pbr_specularEnvSampler;
104
- uniform sampler2D pbr_brdfLUT;
137
+ #ifdef HAS_SPECULARCOLORMAP
138
+ uniform sampler2D pbr_specularColorSampler;
139
+ #endif
140
+ #ifdef HAS_SPECULARINTENSITYMAP
141
+ uniform sampler2D pbr_specularIntensitySampler;
142
+ #endif
143
+ #ifdef HAS_TRANSMISSIONMAP
144
+ uniform sampler2D pbr_transmissionSampler;
145
+ #endif
146
+ #ifdef HAS_THICKNESSMAP
147
+ uniform sampler2D pbr_thicknessSampler;
148
+ #endif
149
+ #ifdef HAS_CLEARCOATMAP
150
+ uniform sampler2D pbr_clearcoatSampler;
151
+ #endif
152
+ #ifdef HAS_CLEARCOATROUGHNESSMAP
153
+ uniform sampler2D pbr_clearcoatRoughnessSampler;
154
+ #endif
155
+ #ifdef HAS_CLEARCOATNORMALMAP
156
+ uniform sampler2D pbr_clearcoatNormalSampler;
157
+ #endif
158
+ #ifdef HAS_SHEENCOLORMAP
159
+ uniform sampler2D pbr_sheenColorSampler;
160
+ #endif
161
+ #ifdef HAS_SHEENROUGHNESSMAP
162
+ uniform sampler2D pbr_sheenRoughnessSampler;
163
+ #endif
164
+ #ifdef HAS_IRIDESCENCEMAP
165
+ uniform sampler2D pbr_iridescenceSampler;
166
+ #endif
167
+ #ifdef HAS_IRIDESCENCETHICKNESSMAP
168
+ uniform sampler2D pbr_iridescenceThicknessSampler;
169
+ #endif
170
+ #ifdef HAS_ANISOTROPYMAP
171
+ uniform sampler2D pbr_anisotropySampler;
105
172
  #endif
106
-
107
173
  // Inputs from vertex shader
108
174
 
109
175
  in vec3 pbr_vPosition;
@@ -140,6 +206,8 @@ struct PBRInfo {
140
206
  const float M_PI = 3.141592653589793;
141
207
  const float c_MinRoughness = 0.04;
142
208
 
209
+ vec3 calculateFinalColor(PBRInfo pbrInfo, vec3 lightColor);
210
+
143
211
  vec4 SRGBtoLINEAR(vec4 srgbIn)
144
212
  {
145
213
  #ifdef MANUAL_SRGB
@@ -155,11 +223,9 @@ vec4 SRGBtoLINEAR(vec4 srgbIn)
155
223
  #endif //MANUAL_SRGB
156
224
  }
157
225
 
158
- // Find the normal for this fragment, pulling either from a predefined normal map
159
- // or from the interpolated mesh normal and tangent attributes.
160
- vec3 getNormal()
226
+ // Build the tangent basis from interpolated attributes or screen-space derivatives.
227
+ mat3 getTBN()
161
228
  {
162
- // Retrieve the tangent space matrix
163
229
  #ifndef HAS_TANGENTS
164
230
  vec3 pos_dx = dFdx(pbr_vPosition);
165
231
  vec3 pos_dy = dFdy(pbr_vPosition);
@@ -180,9 +246,21 @@ vec3 getNormal()
180
246
  mat3 tbn = pbr_vTBN;
181
247
  #endif
182
248
 
249
+ return tbn;
250
+ }
251
+
252
+ // Find the normal for this fragment, pulling either from a predefined normal map
253
+ // or from the interpolated mesh normal and tangent attributes.
254
+ vec3 getMappedNormal(sampler2D normalSampler, mat3 tbn, float normalScale)
255
+ {
256
+ vec3 n = texture(normalSampler, pbr_vUV).rgb;
257
+ return normalize(tbn * ((2.0 * n - 1.0) * vec3(normalScale, normalScale, 1.0)));
258
+ }
259
+
260
+ vec3 getNormal(mat3 tbn)
261
+ {
183
262
  #ifdef HAS_NORMALMAP
184
- vec3 n = texture(pbr_normalSampler, pbr_vUV).rgb;
185
- n = normalize(tbn * ((2.0 * n - 1.0) * vec3(pbrMaterial.normalScale, pbrMaterial.normalScale, 1.0)));
263
+ vec3 n = getMappedNormal(pbr_normalSampler, tbn, pbrMaterial.normalScale);
186
264
  #else
187
265
  // The tbn matrix is linearly interpolated, so we need to re-normalize
188
266
  vec3 n = normalize(tbn[2].xyz);
@@ -191,6 +269,15 @@ vec3 getNormal()
191
269
  return n;
192
270
  }
193
271
 
272
+ vec3 getClearcoatNormal(mat3 tbn, vec3 baseNormal)
273
+ {
274
+ #ifdef HAS_CLEARCOATNORMALMAP
275
+ return getMappedNormal(pbr_clearcoatNormalSampler, tbn, 1.0);
276
+ #else
277
+ return baseNormal;
278
+ #endif
279
+ }
280
+
194
281
  // Calculation of the lighting contribution from an optional Image Based Light source.
195
282
  // Precomputed Environment Maps are required uniform inputs and are computed as outlined in [1].
196
283
  // See our README.md on Environment Maps [3] for additional discussion.
@@ -266,6 +353,169 @@ float microfacetDistribution(PBRInfo pbrInfo)
266
353
  return roughnessSq / (M_PI * f * f);
267
354
  }
268
355
 
356
+ float maxComponent(vec3 value)
357
+ {
358
+ return max(max(value.r, value.g), value.b);
359
+ }
360
+
361
+ float getDielectricF0(float ior)
362
+ {
363
+ float clampedIor = max(ior, 1.0);
364
+ float ratio = (clampedIor - 1.0) / (clampedIor + 1.0);
365
+ return ratio * ratio;
366
+ }
367
+
368
+ vec2 normalizeDirection(vec2 direction)
369
+ {
370
+ float directionLength = length(direction);
371
+ return directionLength > 0.0001 ? direction / directionLength : vec2(1.0, 0.0);
372
+ }
373
+
374
+ vec2 rotateDirection(vec2 direction, float rotation)
375
+ {
376
+ float s = sin(rotation);
377
+ float c = cos(rotation);
378
+ return vec2(direction.x * c - direction.y * s, direction.x * s + direction.y * c);
379
+ }
380
+
381
+ vec3 getIridescenceTint(float iridescence, float thickness, float NdotV)
382
+ {
383
+ if (iridescence <= 0.0) {
384
+ return vec3(1.0);
385
+ }
386
+
387
+ float phase = 0.015 * thickness * pbrMaterial.iridescenceIor + (1.0 - NdotV) * 6.0;
388
+ vec3 thinFilmTint =
389
+ 0.5 + 0.5 * cos(vec3(phase, phase + 2.0943951, phase + 4.1887902));
390
+ return mix(vec3(1.0), thinFilmTint, iridescence);
391
+ }
392
+
393
+ vec3 getVolumeAttenuation(float thickness)
394
+ {
395
+ if (thickness <= 0.0) {
396
+ return vec3(1.0);
397
+ }
398
+
399
+ vec3 attenuationCoefficient =
400
+ -log(max(pbrMaterial.attenuationColor, vec3(0.0001))) /
401
+ max(pbrMaterial.attenuationDistance, 0.0001);
402
+ return exp(-attenuationCoefficient * thickness);
403
+ }
404
+
405
+ PBRInfo createClearcoatPBRInfo(PBRInfo basePBRInfo, vec3 clearcoatNormal, float clearcoatRoughness)
406
+ {
407
+ float perceptualRoughness = clamp(clearcoatRoughness, c_MinRoughness, 1.0);
408
+ float alphaRoughness = perceptualRoughness * perceptualRoughness;
409
+ float NdotV = clamp(abs(dot(clearcoatNormal, basePBRInfo.v)), 0.001, 1.0);
410
+
411
+ return PBRInfo(
412
+ basePBRInfo.NdotL,
413
+ NdotV,
414
+ basePBRInfo.NdotH,
415
+ basePBRInfo.LdotH,
416
+ basePBRInfo.VdotH,
417
+ perceptualRoughness,
418
+ 0.0,
419
+ vec3(0.04),
420
+ vec3(1.0),
421
+ alphaRoughness,
422
+ vec3(0.0),
423
+ vec3(0.04),
424
+ clearcoatNormal,
425
+ basePBRInfo.v
426
+ );
427
+ }
428
+
429
+ vec3 calculateClearcoatContribution(
430
+ PBRInfo pbrInfo,
431
+ vec3 lightColor,
432
+ vec3 clearcoatNormal,
433
+ float clearcoatFactor,
434
+ float clearcoatRoughness
435
+ ) {
436
+ if (clearcoatFactor <= 0.0) {
437
+ return vec3(0.0);
438
+ }
439
+
440
+ PBRInfo clearcoatPBRInfo = createClearcoatPBRInfo(pbrInfo, clearcoatNormal, clearcoatRoughness);
441
+ return calculateFinalColor(clearcoatPBRInfo, lightColor) * clearcoatFactor;
442
+ }
443
+
444
+ #ifdef USE_IBL
445
+ vec3 calculateClearcoatIBLContribution(
446
+ PBRInfo pbrInfo,
447
+ vec3 clearcoatNormal,
448
+ vec3 reflection,
449
+ float clearcoatFactor,
450
+ float clearcoatRoughness
451
+ ) {
452
+ if (clearcoatFactor <= 0.0) {
453
+ return vec3(0.0);
454
+ }
455
+
456
+ PBRInfo clearcoatPBRInfo = createClearcoatPBRInfo(pbrInfo, clearcoatNormal, clearcoatRoughness);
457
+ return getIBLContribution(clearcoatPBRInfo, clearcoatNormal, reflection) * clearcoatFactor;
458
+ }
459
+ #endif
460
+
461
+ vec3 calculateSheenContribution(
462
+ PBRInfo pbrInfo,
463
+ vec3 lightColor,
464
+ vec3 sheenColor,
465
+ float sheenRoughness
466
+ ) {
467
+ if (maxComponent(sheenColor) <= 0.0) {
468
+ return vec3(0.0);
469
+ }
470
+
471
+ float sheenFresnel = pow(clamp(1.0 - pbrInfo.VdotH, 0.0, 1.0), 5.0);
472
+ float sheenVisibility = mix(1.0, pbrInfo.NdotL * pbrInfo.NdotV, sheenRoughness);
473
+ return pbrInfo.NdotL *
474
+ lightColor *
475
+ sheenColor *
476
+ (0.25 + 0.75 * sheenFresnel) *
477
+ sheenVisibility *
478
+ (1.0 - pbrInfo.metalness);
479
+ }
480
+
481
+ float calculateAnisotropyBoost(
482
+ PBRInfo pbrInfo,
483
+ vec3 anisotropyTangent,
484
+ float anisotropyStrength
485
+ ) {
486
+ if (anisotropyStrength <= 0.0) {
487
+ return 1.0;
488
+ }
489
+
490
+ vec3 anisotropyBitangent = normalize(cross(pbrInfo.n, anisotropyTangent));
491
+ float bitangentViewAlignment = abs(dot(pbrInfo.v, anisotropyBitangent));
492
+ return mix(1.0, 0.65 + 0.7 * bitangentViewAlignment, anisotropyStrength);
493
+ }
494
+
495
+ vec3 calculateMaterialLightColor(
496
+ PBRInfo pbrInfo,
497
+ vec3 lightColor,
498
+ vec3 clearcoatNormal,
499
+ float clearcoatFactor,
500
+ float clearcoatRoughness,
501
+ vec3 sheenColor,
502
+ float sheenRoughness,
503
+ vec3 anisotropyTangent,
504
+ float anisotropyStrength
505
+ ) {
506
+ float anisotropyBoost = calculateAnisotropyBoost(pbrInfo, anisotropyTangent, anisotropyStrength);
507
+ vec3 color = calculateFinalColor(pbrInfo, lightColor) * anisotropyBoost;
508
+ color += calculateClearcoatContribution(
509
+ pbrInfo,
510
+ lightColor,
511
+ clearcoatNormal,
512
+ clearcoatFactor,
513
+ clearcoatRoughness
514
+ );
515
+ color += calculateSheenContribution(pbrInfo, lightColor, sheenColor, sheenRoughness);
516
+ return color;
517
+ }
518
+
269
519
  void PBRInfo_setAmbientLight(inout PBRInfo pbrInfo) {
270
520
  pbrInfo.NdotL = 1.0;
271
521
  pbrInfo.NdotH = 0.0;
@@ -290,6 +540,11 @@ void PBRInfo_setPointLight(inout PBRInfo pbrInfo, PointLight pointLight) {
290
540
  PBRInfo_setDirectionalLight(pbrInfo, light_direction);
291
541
  }
292
542
 
543
+ void PBRInfo_setSpotLight(inout PBRInfo pbrInfo, SpotLight spotLight) {
544
+ vec3 light_direction = normalize(spotLight.position - pbr_vPosition);
545
+ PBRInfo_setDirectionalLight(pbrInfo, light_direction);
546
+ }
547
+
293
548
  vec3 calculateFinalColor(PBRInfo pbrInfo, vec3 lightColor) {
294
549
  // Calculate the shading terms for the microfacet specular shading model
295
550
  vec3 F = specularReflection(pbrInfo);
@@ -320,6 +575,8 @@ vec4 pbr_filterColor(vec4 colorUnused)
320
575
 
321
576
  vec3 color = vec3(0, 0, 0);
322
577
 
578
+ float transmission = 0.0;
579
+
323
580
  if(pbrMaterial.unlit){
324
581
  color.rgb = baseColor.rgb;
325
582
  }
@@ -338,14 +595,252 @@ vec4 pbr_filterColor(vec4 colorUnused)
338
595
  #endif
339
596
  perceptualRoughness = clamp(perceptualRoughness, c_MinRoughness, 1.0);
340
597
  metallic = clamp(metallic, 0.0, 1.0);
598
+ mat3 tbn = getTBN();
599
+ vec3 n = getNormal(tbn); // normal at surface point
600
+ vec3 v = normalize(pbrProjection.camera - pbr_vPosition); // Vector from surface point to camera
601
+ float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
602
+ #ifdef USE_MATERIAL_EXTENSIONS
603
+ bool useExtendedPBR =
604
+ pbrMaterial.specularColorMapEnabled ||
605
+ pbrMaterial.specularIntensityMapEnabled ||
606
+ abs(pbrMaterial.specularIntensityFactor - 1.0) > 0.0001 ||
607
+ maxComponent(abs(pbrMaterial.specularColorFactor - vec3(1.0))) > 0.0001 ||
608
+ abs(pbrMaterial.ior - 1.5) > 0.0001 ||
609
+ pbrMaterial.transmissionMapEnabled ||
610
+ pbrMaterial.transmissionFactor > 0.0001 ||
611
+ pbrMaterial.clearcoatMapEnabled ||
612
+ pbrMaterial.clearcoatRoughnessMapEnabled ||
613
+ pbrMaterial.clearcoatFactor > 0.0001 ||
614
+ pbrMaterial.clearcoatRoughnessFactor > 0.0001 ||
615
+ pbrMaterial.sheenColorMapEnabled ||
616
+ pbrMaterial.sheenRoughnessMapEnabled ||
617
+ maxComponent(pbrMaterial.sheenColorFactor) > 0.0001 ||
618
+ pbrMaterial.sheenRoughnessFactor > 0.0001 ||
619
+ pbrMaterial.iridescenceMapEnabled ||
620
+ pbrMaterial.iridescenceFactor > 0.0001 ||
621
+ abs(pbrMaterial.iridescenceIor - 1.3) > 0.0001 ||
622
+ abs(pbrMaterial.iridescenceThicknessRange.x - 100.0) > 0.0001 ||
623
+ abs(pbrMaterial.iridescenceThicknessRange.y - 400.0) > 0.0001 ||
624
+ pbrMaterial.anisotropyMapEnabled ||
625
+ pbrMaterial.anisotropyStrength > 0.0001 ||
626
+ abs(pbrMaterial.anisotropyRotation) > 0.0001 ||
627
+ length(pbrMaterial.anisotropyDirection - vec2(1.0, 0.0)) > 0.0001;
628
+ #else
629
+ bool useExtendedPBR = false;
630
+ #endif
631
+
632
+ if (!useExtendedPBR) {
633
+ // Keep the baseline metallic-roughness implementation byte-for-byte equivalent in behavior.
634
+ float alphaRoughness = perceptualRoughness * perceptualRoughness;
635
+
636
+ vec3 f0 = vec3(0.04);
637
+ vec3 diffuseColor = baseColor.rgb * (vec3(1.0) - f0);
638
+ diffuseColor *= 1.0 - metallic;
639
+ vec3 specularColor = mix(f0, baseColor.rgb, metallic);
640
+
641
+ float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
642
+ float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
643
+ vec3 specularEnvironmentR0 = specularColor.rgb;
644
+ vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90;
645
+ vec3 reflection = -normalize(reflect(v, n));
646
+
647
+ PBRInfo pbrInfo = PBRInfo(
648
+ 0.0, // NdotL
649
+ NdotV,
650
+ 0.0, // NdotH
651
+ 0.0, // LdotH
652
+ 0.0, // VdotH
653
+ perceptualRoughness,
654
+ metallic,
655
+ specularEnvironmentR0,
656
+ specularEnvironmentR90,
657
+ alphaRoughness,
658
+ diffuseColor,
659
+ specularColor,
660
+ n,
661
+ v
662
+ );
663
+
664
+ #ifdef USE_LIGHTS
665
+ PBRInfo_setAmbientLight(pbrInfo);
666
+ color += calculateFinalColor(pbrInfo, lighting.ambientColor);
667
+
668
+ for(int i = 0; i < lighting.directionalLightCount; i++) {
669
+ if (i < lighting.directionalLightCount) {
670
+ PBRInfo_setDirectionalLight(pbrInfo, lighting_getDirectionalLight(i).direction);
671
+ color += calculateFinalColor(pbrInfo, lighting_getDirectionalLight(i).color);
672
+ }
673
+ }
674
+
675
+ for(int i = 0; i < lighting.pointLightCount; i++) {
676
+ if (i < lighting.pointLightCount) {
677
+ PBRInfo_setPointLight(pbrInfo, lighting_getPointLight(i));
678
+ float attenuation = getPointLightAttenuation(lighting_getPointLight(i), distance(lighting_getPointLight(i).position, pbr_vPosition));
679
+ color += calculateFinalColor(pbrInfo, lighting_getPointLight(i).color / attenuation);
680
+ }
681
+ }
682
+
683
+ for(int i = 0; i < lighting.spotLightCount; i++) {
684
+ if (i < lighting.spotLightCount) {
685
+ PBRInfo_setSpotLight(pbrInfo, lighting_getSpotLight(i));
686
+ float attenuation = getSpotLightAttenuation(lighting_getSpotLight(i), pbr_vPosition);
687
+ color += calculateFinalColor(pbrInfo, lighting_getSpotLight(i).color / attenuation);
688
+ }
689
+ }
690
+ #endif
691
+
692
+ #ifdef USE_IBL
693
+ if (pbrMaterial.IBLenabled) {
694
+ color += getIBLContribution(pbrInfo, n, reflection);
695
+ }
696
+ #endif
697
+
698
+ #ifdef HAS_OCCLUSIONMAP
699
+ if (pbrMaterial.occlusionMapEnabled) {
700
+ float ao = texture(pbr_occlusionSampler, pbr_vUV).r;
701
+ color = mix(color, color * ao, pbrMaterial.occlusionStrength);
702
+ }
703
+ #endif
704
+
705
+ vec3 emissive = pbrMaterial.emissiveFactor;
706
+ #ifdef HAS_EMISSIVEMAP
707
+ if (pbrMaterial.emissiveMapEnabled) {
708
+ emissive *= SRGBtoLINEAR(texture(pbr_emissiveSampler, pbr_vUV)).rgb;
709
+ }
710
+ #endif
711
+ color += emissive * pbrMaterial.emissiveStrength;
712
+
713
+ #ifdef PBR_DEBUG
714
+ color = mix(color, baseColor.rgb, pbrMaterial.scaleDiffBaseMR.y);
715
+ color = mix(color, vec3(metallic), pbrMaterial.scaleDiffBaseMR.z);
716
+ color = mix(color, vec3(perceptualRoughness), pbrMaterial.scaleDiffBaseMR.w);
717
+ #endif
718
+
719
+ return vec4(pow(color, vec3(1.0 / 2.2)), baseColor.a);
720
+ }
721
+
722
+ float specularIntensity = pbrMaterial.specularIntensityFactor;
723
+ #ifdef HAS_SPECULARINTENSITYMAP
724
+ if (pbrMaterial.specularIntensityMapEnabled) {
725
+ specularIntensity *= texture(pbr_specularIntensitySampler, pbr_vUV).a;
726
+ }
727
+ #endif
728
+
729
+ vec3 specularFactor = pbrMaterial.specularColorFactor;
730
+ #ifdef HAS_SPECULARCOLORMAP
731
+ if (pbrMaterial.specularColorMapEnabled) {
732
+ specularFactor *= SRGBtoLINEAR(texture(pbr_specularColorSampler, pbr_vUV)).rgb;
733
+ }
734
+ #endif
735
+
736
+ transmission = pbrMaterial.transmissionFactor;
737
+ #ifdef HAS_TRANSMISSIONMAP
738
+ if (pbrMaterial.transmissionMapEnabled) {
739
+ transmission *= texture(pbr_transmissionSampler, pbr_vUV).r;
740
+ }
741
+ #endif
742
+ transmission = clamp(transmission * (1.0 - metallic), 0.0, 1.0);
743
+ float thickness = max(pbrMaterial.thicknessFactor, 0.0);
744
+ #ifdef HAS_THICKNESSMAP
745
+ thickness *= texture(pbr_thicknessSampler, pbr_vUV).g;
746
+ #endif
747
+
748
+ float clearcoatFactor = pbrMaterial.clearcoatFactor;
749
+ float clearcoatRoughness = pbrMaterial.clearcoatRoughnessFactor;
750
+ #ifdef HAS_CLEARCOATMAP
751
+ if (pbrMaterial.clearcoatMapEnabled) {
752
+ clearcoatFactor *= texture(pbr_clearcoatSampler, pbr_vUV).r;
753
+ }
754
+ #endif
755
+ #ifdef HAS_CLEARCOATROUGHNESSMAP
756
+ if (pbrMaterial.clearcoatRoughnessMapEnabled) {
757
+ clearcoatRoughness *= texture(pbr_clearcoatRoughnessSampler, pbr_vUV).g;
758
+ }
759
+ #endif
760
+ clearcoatFactor = clamp(clearcoatFactor, 0.0, 1.0);
761
+ clearcoatRoughness = clamp(clearcoatRoughness, c_MinRoughness, 1.0);
762
+ vec3 clearcoatNormal = getClearcoatNormal(tbn, n);
763
+
764
+ vec3 sheenColor = pbrMaterial.sheenColorFactor;
765
+ float sheenRoughness = pbrMaterial.sheenRoughnessFactor;
766
+ #ifdef HAS_SHEENCOLORMAP
767
+ if (pbrMaterial.sheenColorMapEnabled) {
768
+ sheenColor *= SRGBtoLINEAR(texture(pbr_sheenColorSampler, pbr_vUV)).rgb;
769
+ }
770
+ #endif
771
+ #ifdef HAS_SHEENROUGHNESSMAP
772
+ if (pbrMaterial.sheenRoughnessMapEnabled) {
773
+ sheenRoughness *= texture(pbr_sheenRoughnessSampler, pbr_vUV).a;
774
+ }
775
+ #endif
776
+ sheenRoughness = clamp(sheenRoughness, c_MinRoughness, 1.0);
777
+
778
+ float iridescence = pbrMaterial.iridescenceFactor;
779
+ #ifdef HAS_IRIDESCENCEMAP
780
+ if (pbrMaterial.iridescenceMapEnabled) {
781
+ iridescence *= texture(pbr_iridescenceSampler, pbr_vUV).r;
782
+ }
783
+ #endif
784
+ iridescence = clamp(iridescence, 0.0, 1.0);
785
+ float iridescenceThickness = mix(
786
+ pbrMaterial.iridescenceThicknessRange.x,
787
+ pbrMaterial.iridescenceThicknessRange.y,
788
+ 0.5
789
+ );
790
+ #ifdef HAS_IRIDESCENCETHICKNESSMAP
791
+ iridescenceThickness = mix(
792
+ pbrMaterial.iridescenceThicknessRange.x,
793
+ pbrMaterial.iridescenceThicknessRange.y,
794
+ texture(pbr_iridescenceThicknessSampler, pbr_vUV).g
795
+ );
796
+ #endif
797
+
798
+ float anisotropyStrength = clamp(pbrMaterial.anisotropyStrength, 0.0, 1.0);
799
+ vec2 anisotropyDirection = normalizeDirection(pbrMaterial.anisotropyDirection);
800
+ #ifdef HAS_ANISOTROPYMAP
801
+ if (pbrMaterial.anisotropyMapEnabled) {
802
+ vec3 anisotropySample = texture(pbr_anisotropySampler, pbr_vUV).rgb;
803
+ anisotropyStrength *= anisotropySample.b;
804
+ vec2 mappedDirection = anisotropySample.rg * 2.0 - 1.0;
805
+ if (length(mappedDirection) > 0.0001) {
806
+ anisotropyDirection = normalize(mappedDirection);
807
+ }
808
+ }
809
+ #endif
810
+ anisotropyDirection = rotateDirection(anisotropyDirection, pbrMaterial.anisotropyRotation);
811
+ vec3 anisotropyTangent = normalize(tbn[0] * anisotropyDirection.x + tbn[1] * anisotropyDirection.y);
812
+ if (length(anisotropyTangent) < 0.0001) {
813
+ anisotropyTangent = normalize(tbn[0]);
814
+ }
815
+ float anisotropyViewAlignment = abs(dot(v, anisotropyTangent));
816
+ perceptualRoughness = mix(
817
+ perceptualRoughness,
818
+ clamp(perceptualRoughness * (1.0 - 0.6 * anisotropyViewAlignment), c_MinRoughness, 1.0),
819
+ anisotropyStrength
820
+ );
821
+
341
822
  // Roughness is authored as perceptual roughness; as is convention,
342
823
  // convert to material roughness by squaring the perceptual roughness [2].
343
824
  float alphaRoughness = perceptualRoughness * perceptualRoughness;
344
825
 
345
- vec3 f0 = vec3(0.04);
346
- vec3 diffuseColor = baseColor.rgb * (vec3(1.0) - f0);
347
- diffuseColor *= 1.0 - metallic;
348
- vec3 specularColor = mix(f0, baseColor.rgb, metallic);
826
+ float dielectricF0 = getDielectricF0(pbrMaterial.ior);
827
+ vec3 dielectricSpecularF0 = min(
828
+ vec3(dielectricF0) * specularFactor * specularIntensity,
829
+ vec3(1.0)
830
+ );
831
+ vec3 iridescenceTint = getIridescenceTint(iridescence, iridescenceThickness, NdotV);
832
+ dielectricSpecularF0 = mix(
833
+ dielectricSpecularF0,
834
+ dielectricSpecularF0 * iridescenceTint,
835
+ iridescence
836
+ );
837
+ vec3 diffuseColor = baseColor.rgb * (vec3(1.0) - dielectricSpecularF0);
838
+ diffuseColor *= (1.0 - metallic) * (1.0 - transmission);
839
+ vec3 specularColor = mix(dielectricSpecularF0, baseColor.rgb, metallic);
840
+
841
+ float baseLayerEnergy = 1.0 - clearcoatFactor * 0.25;
842
+ diffuseColor *= baseLayerEnergy;
843
+ specularColor *= baseLayerEnergy;
349
844
 
350
845
  // Compute reflectance.
351
846
  float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
@@ -357,11 +852,6 @@ vec4 pbr_filterColor(vec4 colorUnused)
357
852
  float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
358
853
  vec3 specularEnvironmentR0 = specularColor.rgb;
359
854
  vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90;
360
-
361
- vec3 n = getNormal(); // normal at surface point
362
- vec3 v = normalize(pbrProjection.camera - pbr_vPosition); // Vector from surface point to camera
363
-
364
- float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
365
855
  vec3 reflection = -normalize(reflect(v, n));
366
856
 
367
857
  PBRInfo pbrInfo = PBRInfo(
@@ -385,13 +875,33 @@ vec4 pbr_filterColor(vec4 colorUnused)
385
875
  #ifdef USE_LIGHTS
386
876
  // Apply ambient light
387
877
  PBRInfo_setAmbientLight(pbrInfo);
388
- color += calculateFinalColor(pbrInfo, lighting.ambientColor);
878
+ color += calculateMaterialLightColor(
879
+ pbrInfo,
880
+ lighting.ambientColor,
881
+ clearcoatNormal,
882
+ clearcoatFactor,
883
+ clearcoatRoughness,
884
+ sheenColor,
885
+ sheenRoughness,
886
+ anisotropyTangent,
887
+ anisotropyStrength
888
+ );
389
889
 
390
890
  // Apply directional light
391
891
  for(int i = 0; i < lighting.directionalLightCount; i++) {
392
892
  if (i < lighting.directionalLightCount) {
393
893
  PBRInfo_setDirectionalLight(pbrInfo, lighting_getDirectionalLight(i).direction);
394
- color += calculateFinalColor(pbrInfo, lighting_getDirectionalLight(i).color);
894
+ color += calculateMaterialLightColor(
895
+ pbrInfo,
896
+ lighting_getDirectionalLight(i).color,
897
+ clearcoatNormal,
898
+ clearcoatFactor,
899
+ clearcoatRoughness,
900
+ sheenColor,
901
+ sheenRoughness,
902
+ anisotropyTangent,
903
+ anisotropyStrength
904
+ );
395
905
  }
396
906
  }
397
907
 
@@ -400,7 +910,35 @@ vec4 pbr_filterColor(vec4 colorUnused)
400
910
  if (i < lighting.pointLightCount) {
401
911
  PBRInfo_setPointLight(pbrInfo, lighting_getPointLight(i));
402
912
  float attenuation = getPointLightAttenuation(lighting_getPointLight(i), distance(lighting_getPointLight(i).position, pbr_vPosition));
403
- color += calculateFinalColor(pbrInfo, lighting_getPointLight(i).color / attenuation);
913
+ color += calculateMaterialLightColor(
914
+ pbrInfo,
915
+ lighting_getPointLight(i).color / attenuation,
916
+ clearcoatNormal,
917
+ clearcoatFactor,
918
+ clearcoatRoughness,
919
+ sheenColor,
920
+ sheenRoughness,
921
+ anisotropyTangent,
922
+ anisotropyStrength
923
+ );
924
+ }
925
+ }
926
+
927
+ for(int i = 0; i < lighting.spotLightCount; i++) {
928
+ if (i < lighting.spotLightCount) {
929
+ PBRInfo_setSpotLight(pbrInfo, lighting_getSpotLight(i));
930
+ float attenuation = getSpotLightAttenuation(lighting_getSpotLight(i), pbr_vPosition);
931
+ color += calculateMaterialLightColor(
932
+ pbrInfo,
933
+ lighting_getSpotLight(i).color / attenuation,
934
+ clearcoatNormal,
935
+ clearcoatFactor,
936
+ clearcoatRoughness,
937
+ sheenColor,
938
+ sheenRoughness,
939
+ anisotropyTangent,
940
+ anisotropyStrength
941
+ );
404
942
  }
405
943
  }
406
944
  #endif
@@ -408,7 +946,16 @@ vec4 pbr_filterColor(vec4 colorUnused)
408
946
  // Calculate lighting contribution from image based lighting source (IBL)
409
947
  #ifdef USE_IBL
410
948
  if (pbrMaterial.IBLenabled) {
411
- color += getIBLContribution(pbrInfo, n, reflection);
949
+ color += getIBLContribution(pbrInfo, n, reflection) *
950
+ calculateAnisotropyBoost(pbrInfo, anisotropyTangent, anisotropyStrength);
951
+ color += calculateClearcoatIBLContribution(
952
+ pbrInfo,
953
+ clearcoatNormal,
954
+ -normalize(reflect(v, clearcoatNormal)),
955
+ clearcoatFactor,
956
+ clearcoatRoughness
957
+ );
958
+ color += sheenColor * pbrMaterial.scaleIBLAmbient.x * (1.0 - sheenRoughness) * 0.25;
412
959
  }
413
960
  #endif
414
961
 
@@ -420,12 +967,17 @@ vec4 pbr_filterColor(vec4 colorUnused)
420
967
  }
421
968
  #endif
422
969
 
970
+ vec3 emissive = pbrMaterial.emissiveFactor;
423
971
  #ifdef HAS_EMISSIVEMAP
424
972
  if (pbrMaterial.emissiveMapEnabled) {
425
- vec3 emissive = SRGBtoLINEAR(texture(pbr_emissiveSampler, pbr_vUV)).rgb * pbrMaterial.emissiveFactor;
426
- color += emissive;
973
+ emissive *= SRGBtoLINEAR(texture(pbr_emissiveSampler, pbr_vUV)).rgb;
427
974
  }
428
975
  #endif
976
+ color += emissive * pbrMaterial.emissiveStrength;
977
+
978
+ if (transmission > 0.0) {
979
+ color = mix(color, color * getVolumeAttenuation(thickness), transmission);
980
+ }
429
981
 
430
982
  // This section uses mix to override final color for reference app visualization
431
983
  // of various parameters in the lighting equation.
@@ -445,6 +997,7 @@ vec4 pbr_filterColor(vec4 colorUnused)
445
997
 
446
998
  }
447
999
 
448
- return vec4(pow(color,vec3(1.0/2.2)), baseColor.a);
1000
+ float alpha = clamp(baseColor.a * (1.0 - transmission), 0.0, 1.0);
1001
+ return vec4(pow(color,vec3(1.0/2.2)), alpha);
449
1002
  }
450
1003
  `;