bg2e-js 2.3.1 → 2.3.3

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 (148) hide show
  1. package/dist/bg2e-js.js +350 -334
  2. package/dist/bg2e-js.js.map +1 -1
  3. package/package.json +56 -56
  4. package/src/app/AppController.ts +39 -39
  5. package/src/app/Bg2KeyboardEvent.ts +54 -54
  6. package/src/app/Bg2MouseEvent.ts +82 -82
  7. package/src/app/Bg2TouchEvent.ts +18 -18
  8. package/src/app/Canvas.ts +108 -108
  9. package/src/app/EventBase.ts +10 -10
  10. package/src/app/MainLoop.ts +273 -273
  11. package/src/app/index.ts +24 -24
  12. package/src/base/Color.ts +134 -134
  13. package/src/base/Environment.ts +183 -183
  14. package/src/base/Light.ts +192 -192
  15. package/src/base/Material.ts +620 -620
  16. package/src/base/PolyList.ts +365 -365
  17. package/src/base/Texture.ts +620 -620
  18. package/src/base/index.ts +81 -81
  19. package/src/db/Bg2LoaderPlugin.ts +143 -143
  20. package/src/db/DBPluginApi.ts +48 -48
  21. package/src/db/Loader.ts +116 -116
  22. package/src/db/LoaderPlugin.ts +34 -34
  23. package/src/db/MtlParser.ts +7 -7
  24. package/src/db/ObjLoaderPlugin.ts +54 -54
  25. package/src/db/ObjParser.ts +252 -252
  26. package/src/db/ObjWriterPlugin.ts +18 -18
  27. package/src/db/VitscnjLoaderPlugin.ts +112 -112
  28. package/src/db/Writer.ts +52 -52
  29. package/src/db/WriterPlugin.ts +22 -22
  30. package/src/db/index.ts +44 -44
  31. package/src/debug/DebugRenderer.ts +173 -173
  32. package/src/debug/WebGLTextureViewer.ts +75 -75
  33. package/src/debug/index.ts +6 -6
  34. package/src/index.html +11 -11
  35. package/src/index.ts +33 -33
  36. package/src/manipulation/SelectionBuffer.ts +82 -82
  37. package/src/manipulation/SelectionHighlight.ts +85 -85
  38. package/src/manipulation/SelectionIdAssignVisitor.ts +96 -96
  39. package/src/manipulation/SelectionManager.ts +166 -166
  40. package/src/manipulation/SelectionMode.ts +6 -6
  41. package/src/math/Mat3.ts +259 -259
  42. package/src/math/Mat4.ts +710 -710
  43. package/src/math/MatrixStrategy.ts +25 -25
  44. package/src/math/Quat.ts +65 -65
  45. package/src/math/Vec.ts +753 -753
  46. package/src/math/constants.ts +46 -46
  47. package/src/math/functions.ts +103 -103
  48. package/src/math/index.ts +74 -74
  49. package/src/phsics/joint.ts +137 -137
  50. package/src/primitives/arrow.ts +57 -57
  51. package/src/primitives/cone.ts +138 -138
  52. package/src/primitives/cube.ts +60 -60
  53. package/src/primitives/cylinder.ts +216 -216
  54. package/src/primitives/index.ts +13 -13
  55. package/src/primitives/plane.ts +31 -31
  56. package/src/primitives/sphere.ts +809 -809
  57. package/src/react/useBg2e.ts +75 -70
  58. package/src/render/BRDFIntegrationMap.ts +4 -4
  59. package/src/render/Environment.ts +135 -135
  60. package/src/render/FrameBuffer.ts +35 -35
  61. package/src/render/MaterialRenderer.ts +34 -34
  62. package/src/render/Pipeline.ts +108 -108
  63. package/src/render/PolyListRenderer.ts +47 -47
  64. package/src/render/RenderBuffer.ts +197 -197
  65. package/src/render/RenderQueue.ts +198 -198
  66. package/src/render/RenderState.ts +116 -116
  67. package/src/render/Renderer.ts +248 -248
  68. package/src/render/SceneAppController.ts +250 -247
  69. package/src/render/SceneRenderer.ts +387 -372
  70. package/src/render/Shader.ts +32 -32
  71. package/src/render/ShadowRenderer.ts +176 -176
  72. package/src/render/SkyCube.ts +105 -105
  73. package/src/render/SkySphere.ts +117 -117
  74. package/src/render/TextureMergerRenderer.ts +70 -70
  75. package/src/render/TextureRenderer.ts +34 -34
  76. package/src/render/index.ts +67 -67
  77. package/src/render/webgl/FrameBuffer.ts +9 -9
  78. package/src/render/webgl/MaterialRenderer.ts +112 -112
  79. package/src/render/webgl/Pipeline.ts +88 -88
  80. package/src/render/webgl/PolyListRenderer.ts +260 -260
  81. package/src/render/webgl/RenderBuffer.ts +226 -226
  82. package/src/render/webgl/Renderer.ts +262 -262
  83. package/src/render/webgl/SceneRenderer.ts +67 -67
  84. package/src/render/webgl/ShaderProgram.ts +424 -424
  85. package/src/render/webgl/ShadowRenderer.ts +6 -6
  86. package/src/render/webgl/SkyCube.ts +15 -15
  87. package/src/render/webgl/SkySphere.ts +15 -15
  88. package/src/render/webgl/State.ts +152 -152
  89. package/src/render/webgl/TextureRenderer.ts +167 -167
  90. package/src/render/webgl/VertexBuffer.ts +137 -137
  91. package/src/render/webgl/index.ts +35 -35
  92. package/src/scene/Camera.ts +458 -458
  93. package/src/scene/Chain.ts +44 -44
  94. package/src/scene/ChainJoint.ts +58 -58
  95. package/src/scene/Component.ts +176 -173
  96. package/src/scene/ComponentMap.ts +106 -106
  97. package/src/scene/Drawable.ts +154 -154
  98. package/src/scene/EnvironmentComponent.ts +141 -141
  99. package/src/scene/FindNodeVisitor.ts +59 -59
  100. package/src/scene/LightComponent.ts +154 -154
  101. package/src/scene/MatrixState.ts +46 -46
  102. package/src/scene/Node.ts +328 -314
  103. package/src/scene/NodeVisitor.ts +15 -15
  104. package/src/scene/OrbitCameraController.ts +450 -450
  105. package/src/scene/SmoothOrbitCameraController.ts +99 -99
  106. package/src/scene/Transform.ts +73 -73
  107. package/src/scene/index.ts +60 -60
  108. package/src/shaders/BasicDiffuseColorShader.ts +111 -111
  109. package/src/shaders/BasicPBRLightShader.ts +276 -276
  110. package/src/shaders/DebugRenderShader.ts +97 -97
  111. package/src/shaders/DepthRenderShader.ts +127 -127
  112. package/src/shaders/IrradianceMapCubeShader.ts +115 -115
  113. package/src/shaders/PBRLightIBLShader.ts +486 -486
  114. package/src/shaders/PickSelectionShader.ts +101 -101
  115. package/src/shaders/PresentDebugFramebufferShader.ts +118 -118
  116. package/src/shaders/PresentTextureShader.ts +99 -99
  117. package/src/shaders/SelectionHighlightShader.ts +127 -127
  118. package/src/shaders/ShaderFunction.ts +318 -318
  119. package/src/shaders/SkyCubeShader.ts +93 -93
  120. package/src/shaders/SkySphereShader.ts +102 -102
  121. package/src/shaders/SpecularMapCubeShader.ts +164 -164
  122. package/src/shaders/TextureMergerShader.ts +171 -171
  123. package/src/shaders/index.ts +36 -36
  124. package/src/shaders/webgl/color_correction.glsl +47 -47
  125. package/src/shaders/webgl/constants.glsl +6 -6
  126. package/src/shaders/webgl/index.ts +70 -70
  127. package/src/shaders/webgl/normal_map.glsl +9 -9
  128. package/src/shaders/webgl/pbr.glsl +173 -173
  129. package/src/shaders/webgl/uniforms.glsl +91 -91
  130. package/src/shaders/webgl_shader_lib.ts +213 -213
  131. package/src/tools/BinaryResourceProvider.ts +14 -14
  132. package/src/tools/ImageResourceProvider.ts +66 -66
  133. package/src/tools/MaterialModifier.ts +446 -446
  134. package/src/tools/Resource.ts +203 -203
  135. package/src/tools/ResourceProvider.ts +69 -69
  136. package/src/tools/TextResourceProvider.ts +24 -24
  137. package/src/tools/TextureCache.ts +51 -51
  138. package/src/tools/TextureResourceDatabase.ts +100 -100
  139. package/src/tools/UserAgent.ts +362 -362
  140. package/src/tools/VideoResourceProvider.ts +50 -50
  141. package/src/tools/WriteStrategy.ts +22 -22
  142. package/src/tools/base64.ts +11 -11
  143. package/src/tools/crypto.ts +19 -19
  144. package/src/tools/endiantess.ts +13 -13
  145. package/src/tools/image.ts +18 -18
  146. package/src/tools/index.ts +41 -41
  147. package/src/tools/processType.ts +39 -39
  148. package/src/vite-env.d.ts +12 -12
package/dist/bg2e-js.js CHANGED
@@ -5414,7 +5414,7 @@ async function uo(t) {
5414
5414
  }
5415
5415
  class fe {
5416
5416
  constructor(e = "") {
5417
- this._sceneChanged = !1, this._name = e, this._enabled = !0, this._steady = !1, this._components = new dr(this), this._parent = null, this._children = [];
5417
+ this._sceneChanged = !1, this._postRedisplayFrames = 0, this._name = e, this._enabled = !0, this._steady = !1, this._components = new dr(this), this._parent = null, this._children = [];
5418
5418
  }
5419
5419
  get name() {
5420
5420
  return this._name;
@@ -5519,6 +5519,16 @@ class fe {
5519
5519
  await this._children[r].asyncAccept(e);
5520
5520
  }
5521
5521
  }
5522
+ // Used by components to require a redraw of the scene for a certain number of frames.
5523
+ // This is needed, for example, when a component changes the material of a drawable,
5524
+ // so the change is reflected inmediately in the screen, or when a component generates
5525
+ // an animation that needs to be updated for a certain number of frames.
5526
+ get postRedisplayFrames() {
5527
+ return this._postRedisplayFrames;
5528
+ }
5529
+ set postRedisplayFrames(e) {
5530
+ this._postRedisplayFrames = e;
5531
+ }
5522
5532
  // Most usual components
5523
5533
  get transform() {
5524
5534
  return this.component("Transform");
@@ -7942,22 +7952,25 @@ class St {
7942
7952
  }
7943
7953
  class Rt extends ce {
7944
7954
  constructor(e) {
7945
- super(), this._renderQueue = e, this._delta = 0, this._modelMatrix = w.MakeIdentity(), this._matrixStack = [];
7955
+ super(), this._postRedisplayFrames = 0, this._renderQueue = e, this._delta = 0, this._modelMatrix = w.MakeIdentity(), this._matrixStack = [];
7946
7956
  }
7947
7957
  get delta() {
7948
7958
  return this._delta;
7949
7959
  }
7950
- set delta(e) {
7951
- this._delta = e;
7952
- }
7953
7960
  get modelMatrix() {
7954
7961
  return this._modelMatrix;
7955
7962
  }
7963
+ get postRedisplayFrames() {
7964
+ return this._postRedisplayFrames;
7965
+ }
7966
+ beginFrame(e) {
7967
+ this._delta = e, this._postRedisplayFrames = 0;
7968
+ }
7956
7969
  visit(e) {
7957
7970
  this._matrixStack.push(new w(this._modelMatrix)), e.frame(this._delta, this._modelMatrix, this._renderQueue);
7958
7971
  }
7959
7972
  didVisit(e) {
7960
- this._modelMatrix = this._matrixStack[this._matrixStack.length - 1] || w.MakeIdentity(), this._matrixStack.pop();
7973
+ this._modelMatrix = this._matrixStack[this._matrixStack.length - 1] || w.MakeIdentity(), this._matrixStack.pop(), this._postRedisplayFrames = Math.max(this._postRedisplayFrames, e.postRedisplayFrames), e.postRedisplayFrames = 0;
7961
7974
  }
7962
7975
  }
7963
7976
  class cn extends ce {
@@ -8011,6 +8024,9 @@ class un {
8011
8024
  get renderQueue() {
8012
8025
  return this._renderQueue;
8013
8026
  }
8027
+ get postRedisplayFrames() {
8028
+ return this._frameVisitor ? this._frameVisitor.postRedisplayFrames : 0;
8029
+ }
8014
8030
  async init({ shadowMapSize: e = new h(1024, 1024) } = {}) {
8015
8031
  typeof e == "number" && (e = new h(e, e)), this._shadowMapSize = e, this._mainDirectionalLight = null, this._opaquePipeline = this.renderer.factory.pipeline(), this._opaquePipeline?.setBlendState({ enabled: !1 }), this._opaquePipeline?.create(), this._transparentPipeline = this.renderer.factory.pipeline(), this._transparentPipeline?.setBlendState({
8016
8032
  enabled: !0,
@@ -8055,7 +8071,7 @@ class un {
8055
8071
  async frame(e, r) {
8056
8072
  if (!this._frameVisitor || !this._renderQueue || !this._initVisitor)
8057
8073
  throw new Error("SceneRenderer.frame(): SceneRenderer not initialized. Call SceneRenderer.init() first.");
8058
- e.sceneChanged && await e.asyncAccept(this._initVisitor), this._sceneRoot = e, this._renderQueue?.newFrame(), this._frameVisitor.delta = r, this._frameVisitor.modelMatrix.identity();
8074
+ e.sceneChanged && await e.asyncAccept(this._initVisitor), this._sceneRoot = e, this._renderQueue?.newFrame(), this._frameVisitor.beginFrame(r), this._frameVisitor.modelMatrix.identity();
8059
8075
  const i = j.GetMain(e);
8060
8076
  let n = this.defaultViewMatrix, s = this.defaultProjectionMatrix;
8061
8077
  i && (s = i.projectionMatrix, n = w.GetInverted(oe.GetWorldMatrix(i.node))), this._renderQueue.viewMatrix = n, this._renderQueue.projectionMatrix = s, e.accept(this._frameVisitor), this._skyCube?.updateRenderState({
@@ -9018,7 +9034,7 @@ class m0 extends en {
9018
9034
  !this.sceneRoot || !this.sceneRenderer || (this.sceneRenderer.resize(this.sceneRoot, e, r), this.selectionManager?.setViewportSize(e, r), this.selectionHighlight?.setViewportSize(e, r), this._debugRenderer?.setViewportSize(e, r));
9019
9035
  }
9020
9036
  async frame(e) {
9021
- !this.sceneRoot || !this.sceneRenderer || (this._debugRenderer?.beginFrame(), await this.sceneRenderer?.frame(this.sceneRoot, e));
9037
+ !this.sceneRoot || !this.sceneRenderer || (this._debugRenderer?.beginFrame(), await this.sceneRenderer?.frame(this.sceneRoot, e), this.sceneRenderer.postRedisplayFrames > 0 && this.mainLoop.postRedisplay({ frames: this.sceneRenderer.postRedisplayFrames }));
9022
9038
  }
9023
9039
  display() {
9024
9040
  if (!this.sceneRoot || !this.sceneRenderer)
@@ -9064,332 +9080,332 @@ class m0 extends en {
9064
9080
  this.sceneRoot && this.sceneRenderer?.touchEnd(this.sceneRoot, e), this.selectionManager?.touchEnd(e), this.updateOnInputEvents && this.mainLoop.postRedisplay({ frames: this._updateInputEventsFrameCount });
9065
9081
  }
9066
9082
  }
9067
- const bn = `#ifndef COLOR_CORRECTION_GLSL
9068
- #define COLOR_CORRECTION_GLSL
9069
-
9070
- // Convert lineal color to SRGB for shader output
9071
- vec4 lineal2SRGB(vec4 color, float gamma)
9072
- {
9073
- color = color / (color + vec4(1.0));
9074
- return vec4(pow(color.rgb, vec3(1.0 / gamma)), color.a);
9075
- }
9076
-
9077
- vec3 lineal2SRGB(vec3 color, float gamma)
9078
- {
9079
- color = color / (color + vec3(1.0));
9080
- return pow(color.rgb, vec3(1.0 / gamma));
9081
- }
9082
-
9083
- // Convert SRGB textures to lineal color
9084
- vec4 SRGB2Lineal(vec4 color, float gamma)
9085
- {
9086
- return vec4(pow(color.rgb, vec3(gamma)), color.a);
9087
- }
9088
-
9089
- vec3 SRGB2lLineal(vec3 color, float gamma)
9090
- {
9091
- return pow(color, vec3(gamma));
9092
- }
9093
-
9094
- vec4 brightnessContrast(vec4 color, float brightness, float contrast)
9095
- {
9096
- mat4 brightnessMat = mat4(
9097
- 1.0, 0.0, 0.0, 0.0,
9098
- 0.0, 1.0, 0.0, 0.0,
9099
- 0.0, 0.0, 1.0, 0.0,
9100
- brightness, brightness, brightness, 1.0
9101
- );
9102
- float t = (1.0 - contrast) / 2.0;
9103
- mat4 contrastMat = mat4(
9104
- contrast, 0.0, 0.0, 0.0,
9105
- 0.0, contrast, 0.0, 0.0,
9106
- 0.0, 0.0, contrast, 0.0,
9107
- t, t, t, 1.0
9108
- );
9109
- return contrastMat * brightnessMat * color;
9110
- }
9111
-
9112
- #endif // COLOR_CORRECTION_GLSL
9113
-
9114
- `, P0 = `
9115
- #define PI 3.14159265359
9116
- #define LIGHT_TYPE_POINT 5
9117
- #define LIGHT_TYPE_DIRECTIONAL 4
9118
- #define LIGHT_TYPE_SPOT 1
9119
- #define LIGHT_TYPE_DISABLED 10
9120
- `, En = `
9121
- mat3 TBNMatrix(mat4 model, vec3 normal, vec3 tangent)
9122
- {
9123
- vec3 T = normalize(vec3(model * vec4(tangent, 0.0)));
9124
- vec3 B = normalize(vec3(model * vec4(cross(tangent, normal), 0.0)));
9125
- vec3 N = normalize(vec3(model * vec4(normal, 0.0)));
9126
- return mat3(T, B, N);
9127
- }
9128
-
9129
- `, xn = `
9130
- #include "lib/constants.glsl"
9131
-
9132
- vec3 fresnelSchlick(float cosTheta, vec3 F0)
9133
- {
9134
- return F0 + (1.0 - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0);
9135
- }
9136
-
9137
- vec3 fresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness)
9138
- {
9139
- // Use the Schlick approximation for fresnel with roughness
9140
- return F0 + (max(vec3(1.0 - roughness), F0) - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0);
9141
- }
9142
-
9143
- float distributionGGX(vec3 normal, vec3 halfVector, float roughness)
9144
- {
9145
- float a = roughness * roughness;
9146
- float a2 = a * a;
9147
-
9148
- float NdotH = max(dot(normal, halfVector), 0.0);
9149
- float NdotH2 = NdotH * NdotH;
9150
-
9151
- float denom = NdotH2 * (a2 - 1.0) + 1.0;
9152
-
9153
- return a2 / (PI * denom * denom);
9154
- }
9155
-
9156
- float geometrySchlickGGX(float NdotV, float roughness)
9157
- {
9158
- float r = (roughness + 1.0);
9159
- float k = (r * r) / 8.0;
9160
-
9161
- float num = NdotV;
9162
- float denom = NdotV * (1.0 - k) + k;
9163
-
9164
- return num / denom;
9165
- }
9166
-
9167
- float geometrySmith(vec3 normal, vec3 viewDir, vec3 lightDir, float roughness)
9168
- {
9169
- float NdotV = max(dot(normal, viewDir), 0.0);
9170
- float NdotL = max(dot(normal, lightDir), 0.0);
9171
- float ggx2 = geometrySchlickGGX(NdotV, roughness);
9172
- float ggx1 = geometrySchlickGGX(NdotL, roughness);
9173
- return ggx1 * ggx2;
9174
- }
9175
-
9176
- float calcAttenuation(vec3 lightPosition, vec3 fragPosition)
9177
- {
9178
- float distance = length(lightPosition - fragPosition);
9179
- return 1.0 / (distance * distance);
9180
- }
9181
-
9182
- vec3 calcRadiancePoint( Light light, vec3 viewDir, vec3 fragPos, float metallic, float roughness, vec3 F0, vec3 normal, vec3 albedo, float sheenIntensity, vec3 sheenColor, float ambientOcclussion) {
9183
- // calculate per-light radiance
9184
- vec3 L = normalize(light.position - fragPos);
9185
- vec3 H = normalize(viewDir + L);
9186
- float attenuation = calcAttenuation(light.position, fragPos);
9187
- vec3 radiance = light.color.rgb * light.intensity * attenuation;
9188
-
9189
- // cook-torrance brdf
9190
- float NDF = distributionGGX(normal, H, roughness);
9191
- float G = geometrySmith(normal, viewDir, L, roughness);
9192
- vec3 F = fresnelSchlick(max(dot(H, viewDir), 0.0), F0);
9193
-
9194
- vec3 kS = F;
9195
- vec3 kD = vec3(1.0) - kS;
9196
- kD *= 1.0 - metallic;
9197
-
9198
- vec3 numerator = NDF * G * F;
9199
- float denominator = 4.0 * max(dot(normal, viewDir), 0.0) * max(dot(normal, L), 0.0) + 0.0001;
9200
- vec3 specular = numerator / denominator;
9201
-
9202
- // add to outgoing radiance Lo
9203
- float NdotL = max(dot(normal, L), 0.0);
9204
- vec3 base = (kD * albedo / PI + specular) * radiance * NdotL;
9205
- vec3 sheen = calcSheen(normal, viewDir, sheenColor, sheenIntensity) * ambientOcclussion;
9206
- return base + sheen;
9207
- }
9208
-
9209
- vec3 calcRadianceDirectional(Light light, vec3 viewDir, vec3 fragPos, float metallic, float roughness, vec3 F0, vec3 normal, vec3 albedo, float sheenIntensity, vec3 sheenColor, float ambientOcclussion)
9210
- {
9211
- vec3 L = normalize(-light.direction);
9212
- vec3 H = normalize(viewDir + L);
9213
- vec3 radiance = light.color.rgb * light.intensity;
9214
-
9215
- // cook-torrance brdf
9216
- float NDF = distributionGGX(normal, H, roughness);
9217
- float G = geometrySmith(normal, viewDir, L, roughness);
9218
- vec3 F = fresnelSchlick(max(dot(H, viewDir), 0.0), F0);
9219
-
9220
- vec3 kS = F;
9221
- vec3 kD = vec3(1.0) - kS;
9222
- kD *= 1.0 - metallic;
9223
-
9224
- vec3 numerator = NDF * G * F;
9225
- float denominator = 4.0 * max(dot(normal, viewDir), 0.0) * max(dot(normal, L), 0.0) + 0.0001;
9226
- vec3 specular = numerator / denominator;
9227
-
9228
- // add to outgoing radiance Lo
9229
- float NdotL = max(dot(normal, L), 0.0);
9230
- vec3 base = (kD * albedo / PI + specular) * radiance * NdotL;
9231
- vec3 sheen = calcSheen(normal, viewDir, sheenColor, sheenIntensity) * ambientOcclussion;
9232
- return base + sheen;
9233
- }
9234
-
9235
- vec3 calcRadiance( Light light, vec3 viewDir, vec3 fragPos, float metallic, float roughness, vec3 F0, vec3 normal, vec3 albedo, float sheenIntensity, vec3 sheenColor, float ambientOcclussion) {
9236
- if (light.type == LIGHT_TYPE_POINT)
9237
- {
9238
- return calcRadiancePoint(light, viewDir, fragPos, metallic, roughness, F0, normal, albedo, sheenIntensity, sheenColor, ambientOcclussion);
9239
- }
9240
- else if (light.type == LIGHT_TYPE_DIRECTIONAL)
9241
- {
9242
- return calcRadianceDirectional(light, viewDir, fragPos, metallic, roughness, F0, normal, albedo, sheenIntensity, sheenColor, ambientOcclussion);
9243
- }
9244
- return vec3(0.0);
9245
- }
9246
-
9247
- vec3 getPrefilteredColor(float roughness,vec3 refVec,samplerCube irrMap,samplerCube specMap,samplerCube envMap) {
9248
- vec3 specMap0 = textureCube(envMap, refVec).rgb;
9249
- vec3 specMap1 = textureCube(specMap, refVec).rgb;
9250
- vec3 specMap2 = textureCube(irrMap, refVec).rgb;
9251
-
9252
- if (roughness < 0.4) {
9253
- return mix(specMap0, specMap1, roughness / 0.4);
9254
- }
9255
- return mix(specMap1, specMap2, (roughness - 0.4) / 0.6);
9256
- }
9257
-
9258
- vec3 calcAmbientLight( vec3 viewDir, vec3 normal, vec3 F0, vec3 albedo, float metallic, float roughness, samplerCube irradianceMap, samplerCube prefilteredEnvMap, samplerCube envMap, sampler2D brdfLUT, float ambientOcclussion, float sheenIntensity, vec3 sheenColor, vec3 shadowColor, float ambientIntensity) {
9259
- vec3 R = reflect(-viewDir, normal);
9260
-
9261
- vec3 F = fresnelSchlickRoughness(max(dot(normal, viewDir), 0.0), F0, roughness) * max(shadowColor, vec3(0.8));
9262
-
9263
- vec3 Ks = F;
9264
- vec3 Kd = 1.0 - Ks;
9265
- Kd *= 1.0 - metallic;
9266
-
9267
- vec3 irradiance = textureCube(irradianceMap, normal).rgb * ambientIntensity;
9268
- vec3 diffuse = irradiance * albedo;
9269
-
9270
- vec3 prefilteredColor = getPrefilteredColor(roughness, R, irradianceMap, prefilteredEnvMap, envMap);
9271
-
9272
- vec2 brdfUV = vec2(clamp(max(dot(normal, viewDir), 0.0), 0.01, 0.99), roughness);
9273
- vec2 envBRDF = texture2D(brdfLUT, brdfUV).rg;
9274
- vec3 specular = prefilteredColor * (F * envBRDF.x + envBRDF.y);
9275
-
9276
- vec3 base = (Kd * diffuse + specular) * ambientOcclussion;
9277
- vec3 sheen = calcSheen(normal, viewDir, sheenColor, sheenIntensity) * ambientOcclussion * shadowColor;
9278
- return base + sheen;
9279
- }
9280
-
9281
- // TODO: Extract this function to a shadow map shader function
9282
- vec3 getShadowColor(vec4 positionFromLightPov, sampler2D shadowMap, float shadowBias, float shadowStrength) {
9283
- // The vertex location rendered from the light source is almost in
9284
- // normalized device coordinates (NDC), but the perspective division
9285
- // has not been performed yet. We need to divide by w to get the
9286
- // vertex location in range [-1, +1]
9287
- vec3 shadowCoord = positionFromLightPov.xyz / positionFromLightPov.w;
9288
-
9289
- // Convert from NDC to texture coordinates
9290
- shadowCoord = shadowCoord * 0.5 + 0.5;
9291
-
9292
- if (shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 &&
9293
- shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0)
9294
- {
9295
- float shadowDepth = texture2D(shadowMap, shadowCoord.xy).r;
9296
- if (shadowCoord.z > shadowDepth + shadowBias) {
9297
- return vec3(1.0 - shadowStrength);
9298
- }
9299
- }
9300
- return vec3(1.0);
9301
- }
9302
- `, Qn = `
9303
- struct PBRMaterialData
9304
- {
9305
- vec4 albedo;
9306
-
9307
- vec2 albedoScale;
9308
- vec2 normalScale;
9309
- vec2 metalnessScale;
9310
- vec2 roughnessScale;
9311
- vec2 lightEmissionScale;
9312
-
9313
- float metalness;
9314
- float roughness;
9315
- float lightEmission;
9316
-
9317
- int albedoUVSet;
9318
- int normalUVSet;
9319
- int metalnessUVSet;
9320
- int roughnessUVSet;
9321
- int lightEmissionUVSet;
9322
- int aoUVSet;
9323
-
9324
- vec4 fresnelTint;
9325
- vec4 sheenColor;
9326
- float sheenIntensity;
9327
- };
9328
-
9329
- struct Light
9330
- {
9331
- vec3 position;
9332
- float intensity;
9333
- vec4 color;
9334
- vec3 direction;
9335
- int type;
9336
- };
9337
-
9338
- vec4 sampleAlbedo(sampler2D tex, vec2 uv0, vec2 uv1, PBRMaterialData mat, float gamma)
9339
- {
9340
- vec2 uv = mat.albedoUVSet == 0 ? uv0 : uv1;
9341
- vec4 texColor = texture2D(tex, uv * mat.albedoScale);
9342
- return vec4(SRGB2Lineal(texColor, gamma).rgb * mat.albedo.rgb, texColor.a * mat.albedo.a);
9343
- }
9344
-
9345
- float sampleMetallic(sampler2D tex, vec2 uv0, vec2 uv1, PBRMaterialData mat)
9346
- {
9347
- vec2 uv = mat.metalnessUVSet == 0 ? uv0 : uv1;
9348
- return texture2D(tex, uv * mat.metalnessScale).r * mat.metalness;
9349
- }
9350
-
9351
- float sampleRoughness(sampler2D tex, vec2 uv0, vec2 uv1, PBRMaterialData mat)
9352
- {
9353
- const float minRoughness = 0.05; // Minimum roughness value: even a mirror have some roughness
9354
- const float maxRoughness = 0.98; // Maximum roughness value: avoid completely diffuse surfaces
9355
- vec2 uv = mat.roughnessUVSet == 0 ? uv0 : uv1;
9356
- return min(max(texture2D(tex, uv * mat.roughnessScale).g * mat.roughness, minRoughness), maxRoughness);
9357
- }
9358
-
9359
-
9360
- float sampleLightEmission(sampler2D tex, vec2 uv0, vec2 uv1, PBRMaterialData mat)
9361
- {
9362
- vec2 uv = mat.lightEmissionUVSet == 0 ? uv0 : uv1;
9363
- return texture2D(tex, uv * mat.lightEmissionScale).b * mat.lightEmission;
9364
- }
9365
-
9366
- vec3 sampleNormal(sampler2D tex, vec2 uv0, vec2 uv1, PBRMaterialData mat, mat3 TBN)
9367
- {
9368
- vec2 uv = mat.normalUVSet == 0 ? uv0 : uv1;
9369
- vec3 normal = texture2D(tex, uv * mat.normalScale).xyz * 2.0 - 1.0;
9370
- return normalize(TBN * normal);
9371
- }
9372
-
9373
- float sampleAmbientOcclussion(sampler2D tex, vec2 uv0, vec2 uv1, PBRMaterialData mat)
9374
- {
9375
- vec2 uv = mat.aoUVSet == 0 ? uv0 : uv1;
9376
- return texture2D(tex, uv).a;
9377
- }
9378
-
9379
- vec3 calcF0(vec3 albedo, PBRMaterialData mat)
9380
- {
9381
- return mix(vec3(0.04), albedo, mat.metalness) * mat.fresnelTint.rgb;
9382
- }
9383
-
9384
- vec3 calcSheen(vec3 normal, vec3 viewDir, vec3 sheenColor, float sheenIntensity)
9385
- {
9386
- float NdotV = max(dot(normal, viewDir), 0.0);
9387
- float facing = 1.0 - NdotV;
9388
-
9389
- // Adjustable power: controls how concentrated the brightness is
9390
- float falloff = pow(facing, 5.0);
9391
- return sheenColor * falloff * sheenIntensity;
9392
- }
9083
+ const bn = `#ifndef COLOR_CORRECTION_GLSL\r
9084
+ #define COLOR_CORRECTION_GLSL\r
9085
+ \r
9086
+ // Convert lineal color to SRGB for shader output\r
9087
+ vec4 lineal2SRGB(vec4 color, float gamma)\r
9088
+ {\r
9089
+ color = color / (color + vec4(1.0));\r
9090
+ return vec4(pow(color.rgb, vec3(1.0 / gamma)), color.a);\r
9091
+ }\r
9092
+ \r
9093
+ vec3 lineal2SRGB(vec3 color, float gamma)\r
9094
+ {\r
9095
+ color = color / (color + vec3(1.0));\r
9096
+ return pow(color.rgb, vec3(1.0 / gamma));\r
9097
+ }\r
9098
+ \r
9099
+ // Convert SRGB textures to lineal color\r
9100
+ vec4 SRGB2Lineal(vec4 color, float gamma)\r
9101
+ {\r
9102
+ return vec4(pow(color.rgb, vec3(gamma)), color.a);\r
9103
+ }\r
9104
+ \r
9105
+ vec3 SRGB2lLineal(vec3 color, float gamma)\r
9106
+ {\r
9107
+ return pow(color, vec3(gamma));\r
9108
+ }\r
9109
+ \r
9110
+ vec4 brightnessContrast(vec4 color, float brightness, float contrast)\r
9111
+ {\r
9112
+ mat4 brightnessMat = mat4(\r
9113
+ 1.0, 0.0, 0.0, 0.0,\r
9114
+ 0.0, 1.0, 0.0, 0.0,\r
9115
+ 0.0, 0.0, 1.0, 0.0,\r
9116
+ brightness, brightness, brightness, 1.0\r
9117
+ );\r
9118
+ float t = (1.0 - contrast) / 2.0;\r
9119
+ mat4 contrastMat = mat4(\r
9120
+ contrast, 0.0, 0.0, 0.0,\r
9121
+ 0.0, contrast, 0.0, 0.0,\r
9122
+ 0.0, 0.0, contrast, 0.0,\r
9123
+ t, t, t, 1.0\r
9124
+ );\r
9125
+ return contrastMat * brightnessMat * color;\r
9126
+ }\r
9127
+ \r
9128
+ #endif // COLOR_CORRECTION_GLSL\r
9129
+ \r
9130
+ `, P0 = `\r
9131
+ #define PI 3.14159265359\r
9132
+ #define LIGHT_TYPE_POINT 5\r
9133
+ #define LIGHT_TYPE_DIRECTIONAL 4\r
9134
+ #define LIGHT_TYPE_SPOT 1\r
9135
+ #define LIGHT_TYPE_DISABLED 10\r
9136
+ `, En = `\r
9137
+ mat3 TBNMatrix(mat4 model, vec3 normal, vec3 tangent)\r
9138
+ {\r
9139
+ vec3 T = normalize(vec3(model * vec4(tangent, 0.0)));\r
9140
+ vec3 B = normalize(vec3(model * vec4(cross(tangent, normal), 0.0)));\r
9141
+ vec3 N = normalize(vec3(model * vec4(normal, 0.0)));\r
9142
+ return mat3(T, B, N);\r
9143
+ }\r
9144
+ \r
9145
+ `, xn = `\r
9146
+ #include "lib/constants.glsl"\r
9147
+ \r
9148
+ vec3 fresnelSchlick(float cosTheta, vec3 F0)\r
9149
+ {\r
9150
+ return F0 + (1.0 - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0);\r
9151
+ }\r
9152
+ \r
9153
+ vec3 fresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness)\r
9154
+ {\r
9155
+ // Use the Schlick approximation for fresnel with roughness\r
9156
+ return F0 + (max(vec3(1.0 - roughness), F0) - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0);\r
9157
+ }\r
9158
+ \r
9159
+ float distributionGGX(vec3 normal, vec3 halfVector, float roughness)\r
9160
+ {\r
9161
+ float a = roughness * roughness;\r
9162
+ float a2 = a * a;\r
9163
+ \r
9164
+ float NdotH = max(dot(normal, halfVector), 0.0);\r
9165
+ float NdotH2 = NdotH * NdotH;\r
9166
+ \r
9167
+ float denom = NdotH2 * (a2 - 1.0) + 1.0;\r
9168
+ \r
9169
+ return a2 / (PI * denom * denom);\r
9170
+ }\r
9171
+ \r
9172
+ float geometrySchlickGGX(float NdotV, float roughness)\r
9173
+ {\r
9174
+ float r = (roughness + 1.0);\r
9175
+ float k = (r * r) / 8.0;\r
9176
+ \r
9177
+ float num = NdotV;\r
9178
+ float denom = NdotV * (1.0 - k) + k;\r
9179
+ \r
9180
+ return num / denom;\r
9181
+ }\r
9182
+ \r
9183
+ float geometrySmith(vec3 normal, vec3 viewDir, vec3 lightDir, float roughness)\r
9184
+ {\r
9185
+ float NdotV = max(dot(normal, viewDir), 0.0);\r
9186
+ float NdotL = max(dot(normal, lightDir), 0.0);\r
9187
+ float ggx2 = geometrySchlickGGX(NdotV, roughness);\r
9188
+ float ggx1 = geometrySchlickGGX(NdotL, roughness);\r
9189
+ return ggx1 * ggx2;\r
9190
+ }\r
9191
+ \r
9192
+ float calcAttenuation(vec3 lightPosition, vec3 fragPosition)\r
9193
+ {\r
9194
+ float distance = length(lightPosition - fragPosition);\r
9195
+ return 1.0 / (distance * distance);\r
9196
+ }\r
9197
+ \r
9198
+ vec3 calcRadiancePoint( Light light, vec3 viewDir, vec3 fragPos, float metallic, float roughness, vec3 F0, vec3 normal, vec3 albedo, float sheenIntensity, vec3 sheenColor, float ambientOcclussion) {\r
9199
+ // calculate per-light radiance\r
9200
+ vec3 L = normalize(light.position - fragPos);\r
9201
+ vec3 H = normalize(viewDir + L);\r
9202
+ float attenuation = calcAttenuation(light.position, fragPos);\r
9203
+ vec3 radiance = light.color.rgb * light.intensity * attenuation;\r
9204
+ \r
9205
+ // cook-torrance brdf\r
9206
+ float NDF = distributionGGX(normal, H, roughness);\r
9207
+ float G = geometrySmith(normal, viewDir, L, roughness);\r
9208
+ vec3 F = fresnelSchlick(max(dot(H, viewDir), 0.0), F0);\r
9209
+ \r
9210
+ vec3 kS = F;\r
9211
+ vec3 kD = vec3(1.0) - kS;\r
9212
+ kD *= 1.0 - metallic;\r
9213
+ \r
9214
+ vec3 numerator = NDF * G * F;\r
9215
+ float denominator = 4.0 * max(dot(normal, viewDir), 0.0) * max(dot(normal, L), 0.0) + 0.0001;\r
9216
+ vec3 specular = numerator / denominator;\r
9217
+ \r
9218
+ // add to outgoing radiance Lo\r
9219
+ float NdotL = max(dot(normal, L), 0.0);\r
9220
+ vec3 base = (kD * albedo / PI + specular) * radiance * NdotL;\r
9221
+ vec3 sheen = calcSheen(normal, viewDir, sheenColor, sheenIntensity) * ambientOcclussion;\r
9222
+ return base + sheen;\r
9223
+ }\r
9224
+ \r
9225
+ vec3 calcRadianceDirectional(Light light, vec3 viewDir, vec3 fragPos, float metallic, float roughness, vec3 F0, vec3 normal, vec3 albedo, float sheenIntensity, vec3 sheenColor, float ambientOcclussion)\r
9226
+ {\r
9227
+ vec3 L = normalize(-light.direction);\r
9228
+ vec3 H = normalize(viewDir + L);\r
9229
+ vec3 radiance = light.color.rgb * light.intensity;\r
9230
+ \r
9231
+ // cook-torrance brdf\r
9232
+ float NDF = distributionGGX(normal, H, roughness);\r
9233
+ float G = geometrySmith(normal, viewDir, L, roughness);\r
9234
+ vec3 F = fresnelSchlick(max(dot(H, viewDir), 0.0), F0);\r
9235
+ \r
9236
+ vec3 kS = F;\r
9237
+ vec3 kD = vec3(1.0) - kS;\r
9238
+ kD *= 1.0 - metallic;\r
9239
+ \r
9240
+ vec3 numerator = NDF * G * F;\r
9241
+ float denominator = 4.0 * max(dot(normal, viewDir), 0.0) * max(dot(normal, L), 0.0) + 0.0001;\r
9242
+ vec3 specular = numerator / denominator;\r
9243
+ \r
9244
+ // add to outgoing radiance Lo\r
9245
+ float NdotL = max(dot(normal, L), 0.0);\r
9246
+ vec3 base = (kD * albedo / PI + specular) * radiance * NdotL;\r
9247
+ vec3 sheen = calcSheen(normal, viewDir, sheenColor, sheenIntensity) * ambientOcclussion;\r
9248
+ return base + sheen;\r
9249
+ }\r
9250
+ \r
9251
+ vec3 calcRadiance( Light light, vec3 viewDir, vec3 fragPos, float metallic, float roughness, vec3 F0, vec3 normal, vec3 albedo, float sheenIntensity, vec3 sheenColor, float ambientOcclussion) {\r
9252
+ if (light.type == LIGHT_TYPE_POINT)\r
9253
+ {\r
9254
+ return calcRadiancePoint(light, viewDir, fragPos, metallic, roughness, F0, normal, albedo, sheenIntensity, sheenColor, ambientOcclussion);\r
9255
+ }\r
9256
+ else if (light.type == LIGHT_TYPE_DIRECTIONAL)\r
9257
+ {\r
9258
+ return calcRadianceDirectional(light, viewDir, fragPos, metallic, roughness, F0, normal, albedo, sheenIntensity, sheenColor, ambientOcclussion);\r
9259
+ }\r
9260
+ return vec3(0.0);\r
9261
+ }\r
9262
+ \r
9263
+ vec3 getPrefilteredColor(float roughness,vec3 refVec,samplerCube irrMap,samplerCube specMap,samplerCube envMap) {\r
9264
+ vec3 specMap0 = textureCube(envMap, refVec).rgb;\r
9265
+ vec3 specMap1 = textureCube(specMap, refVec).rgb;\r
9266
+ vec3 specMap2 = textureCube(irrMap, refVec).rgb;\r
9267
+ \r
9268
+ if (roughness < 0.4) {\r
9269
+ return mix(specMap0, specMap1, roughness / 0.4);\r
9270
+ }\r
9271
+ return mix(specMap1, specMap2, (roughness - 0.4) / 0.6);\r
9272
+ }\r
9273
+ \r
9274
+ vec3 calcAmbientLight( vec3 viewDir, vec3 normal, vec3 F0, vec3 albedo, float metallic, float roughness, samplerCube irradianceMap, samplerCube prefilteredEnvMap, samplerCube envMap, sampler2D brdfLUT, float ambientOcclussion, float sheenIntensity, vec3 sheenColor, vec3 shadowColor, float ambientIntensity) {\r
9275
+ vec3 R = reflect(-viewDir, normal);\r
9276
+ \r
9277
+ vec3 F = fresnelSchlickRoughness(max(dot(normal, viewDir), 0.0), F0, roughness) * max(shadowColor, vec3(0.8));\r
9278
+ \r
9279
+ vec3 Ks = F;\r
9280
+ vec3 Kd = 1.0 - Ks;\r
9281
+ Kd *= 1.0 - metallic;\r
9282
+ \r
9283
+ vec3 irradiance = textureCube(irradianceMap, normal).rgb * ambientIntensity;\r
9284
+ vec3 diffuse = irradiance * albedo;\r
9285
+ \r
9286
+ vec3 prefilteredColor = getPrefilteredColor(roughness, R, irradianceMap, prefilteredEnvMap, envMap);\r
9287
+ \r
9288
+ vec2 brdfUV = vec2(clamp(max(dot(normal, viewDir), 0.0), 0.01, 0.99), roughness);\r
9289
+ vec2 envBRDF = texture2D(brdfLUT, brdfUV).rg;\r
9290
+ vec3 specular = prefilteredColor * (F * envBRDF.x + envBRDF.y);\r
9291
+ \r
9292
+ vec3 base = (Kd * diffuse + specular) * ambientOcclussion;\r
9293
+ vec3 sheen = calcSheen(normal, viewDir, sheenColor, sheenIntensity) * ambientOcclussion * shadowColor;\r
9294
+ return base + sheen;\r
9295
+ }\r
9296
+ \r
9297
+ // TODO: Extract this function to a shadow map shader function\r
9298
+ vec3 getShadowColor(vec4 positionFromLightPov, sampler2D shadowMap, float shadowBias, float shadowStrength) {\r
9299
+ // The vertex location rendered from the light source is almost in\r
9300
+ // normalized device coordinates (NDC), but the perspective division\r
9301
+ // has not been performed yet. We need to divide by w to get the\r
9302
+ // vertex location in range [-1, +1]\r
9303
+ vec3 shadowCoord = positionFromLightPov.xyz / positionFromLightPov.w;\r
9304
+ \r
9305
+ // Convert from NDC to texture coordinates\r
9306
+ shadowCoord = shadowCoord * 0.5 + 0.5;\r
9307
+ \r
9308
+ if (shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 &&\r
9309
+ shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0)\r
9310
+ {\r
9311
+ float shadowDepth = texture2D(shadowMap, shadowCoord.xy).r;\r
9312
+ if (shadowCoord.z > shadowDepth + shadowBias) {\r
9313
+ return vec3(1.0 - shadowStrength);\r
9314
+ }\r
9315
+ }\r
9316
+ return vec3(1.0);\r
9317
+ }\r
9318
+ `, Qn = `\r
9319
+ struct PBRMaterialData\r
9320
+ {\r
9321
+ vec4 albedo;\r
9322
+ \r
9323
+ vec2 albedoScale;\r
9324
+ vec2 normalScale;\r
9325
+ vec2 metalnessScale;\r
9326
+ vec2 roughnessScale;\r
9327
+ vec2 lightEmissionScale;\r
9328
+ \r
9329
+ float metalness;\r
9330
+ float roughness;\r
9331
+ float lightEmission;\r
9332
+ \r
9333
+ int albedoUVSet;\r
9334
+ int normalUVSet;\r
9335
+ int metalnessUVSet;\r
9336
+ int roughnessUVSet;\r
9337
+ int lightEmissionUVSet;\r
9338
+ int aoUVSet;\r
9339
+ \r
9340
+ vec4 fresnelTint;\r
9341
+ vec4 sheenColor;\r
9342
+ float sheenIntensity;\r
9343
+ };\r
9344
+ \r
9345
+ struct Light\r
9346
+ {\r
9347
+ vec3 position;\r
9348
+ float intensity;\r
9349
+ vec4 color;\r
9350
+ vec3 direction;\r
9351
+ int type;\r
9352
+ };\r
9353
+ \r
9354
+ vec4 sampleAlbedo(sampler2D tex, vec2 uv0, vec2 uv1, PBRMaterialData mat, float gamma)\r
9355
+ {\r
9356
+ vec2 uv = mat.albedoUVSet == 0 ? uv0 : uv1;\r
9357
+ vec4 texColor = texture2D(tex, uv * mat.albedoScale);\r
9358
+ return vec4(SRGB2Lineal(texColor, gamma).rgb * mat.albedo.rgb, texColor.a * mat.albedo.a);\r
9359
+ }\r
9360
+ \r
9361
+ float sampleMetallic(sampler2D tex, vec2 uv0, vec2 uv1, PBRMaterialData mat)\r
9362
+ {\r
9363
+ vec2 uv = mat.metalnessUVSet == 0 ? uv0 : uv1;\r
9364
+ return texture2D(tex, uv * mat.metalnessScale).r * mat.metalness;\r
9365
+ }\r
9366
+ \r
9367
+ float sampleRoughness(sampler2D tex, vec2 uv0, vec2 uv1, PBRMaterialData mat)\r
9368
+ {\r
9369
+ const float minRoughness = 0.05; // Minimum roughness value: even a mirror have some roughness\r
9370
+ const float maxRoughness = 0.98; // Maximum roughness value: avoid completely diffuse surfaces\r
9371
+ vec2 uv = mat.roughnessUVSet == 0 ? uv0 : uv1;\r
9372
+ return min(max(texture2D(tex, uv * mat.roughnessScale).g * mat.roughness, minRoughness), maxRoughness);\r
9373
+ }\r
9374
+ \r
9375
+ \r
9376
+ float sampleLightEmission(sampler2D tex, vec2 uv0, vec2 uv1, PBRMaterialData mat)\r
9377
+ {\r
9378
+ vec2 uv = mat.lightEmissionUVSet == 0 ? uv0 : uv1;\r
9379
+ return texture2D(tex, uv * mat.lightEmissionScale).b * mat.lightEmission;\r
9380
+ }\r
9381
+ \r
9382
+ vec3 sampleNormal(sampler2D tex, vec2 uv0, vec2 uv1, PBRMaterialData mat, mat3 TBN)\r
9383
+ {\r
9384
+ vec2 uv = mat.normalUVSet == 0 ? uv0 : uv1;\r
9385
+ vec3 normal = texture2D(tex, uv * mat.normalScale).xyz * 2.0 - 1.0;\r
9386
+ return normalize(TBN * normal);\r
9387
+ }\r
9388
+ \r
9389
+ float sampleAmbientOcclussion(sampler2D tex, vec2 uv0, vec2 uv1, PBRMaterialData mat)\r
9390
+ {\r
9391
+ vec2 uv = mat.aoUVSet == 0 ? uv0 : uv1;\r
9392
+ return texture2D(tex, uv).a;\r
9393
+ }\r
9394
+ \r
9395
+ vec3 calcF0(vec3 albedo, PBRMaterialData mat)\r
9396
+ {\r
9397
+ return mix(vec3(0.04), albedo, mat.metalness) * mat.fresnelTint.rgb;\r
9398
+ }\r
9399
+ \r
9400
+ vec3 calcSheen(vec3 normal, vec3 viewDir, vec3 sheenColor, float sheenIntensity)\r
9401
+ {\r
9402
+ float NdotV = max(dot(normal, viewDir), 0.0);\r
9403
+ float facing = 1.0 - NdotV;\r
9404
+ \r
9405
+ // Adjustable power: controls how concentrated the brightness is\r
9406
+ float falloff = pow(facing, 5.0);\r
9407
+ return sheenColor * falloff * sheenIntensity;\r
9408
+ }\r
9393
9409
  `;
9394
9410
  let _t = null;
9395
9411
  function B0() {