@zephyr3d/scene 0.9.25 → 0.9.26

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 (262) hide show
  1. package/dist/animation/hair/gpu_hair_simulation.js +1090 -0
  2. package/dist/animation/hair/gpu_hair_simulation.js.map +1 -0
  3. package/dist/animation/joint_dynamics/controller.js +7 -5
  4. package/dist/animation/joint_dynamics/controller.js.map +1 -1
  5. package/dist/animation/joint_dynamics/joint_dynamics_system.js +81 -5
  6. package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
  7. package/dist/animation/morphtrack.js +3 -4
  8. package/dist/animation/morphtrack.js.map +1 -1
  9. package/dist/animation/skeleton.js +58 -24
  10. package/dist/animation/skeleton.js.map +1 -1
  11. package/dist/animation/spring/multi_chain_spring_system.js +577 -179
  12. package/dist/animation/spring/multi_chain_spring_system.js.map +1 -1
  13. package/dist/animation/spring/spring_collider.js +4 -3
  14. package/dist/animation/spring/spring_collider.js.map +1 -1
  15. package/dist/animation/spring/spring_node_pose_tracker.js +40 -0
  16. package/dist/animation/spring/spring_node_pose_tracker.js.map +1 -0
  17. package/dist/animation/spring/spring_particle.js +2 -0
  18. package/dist/animation/spring/spring_particle.js.map +1 -1
  19. package/dist/animation/spring/spring_system.js +11 -3
  20. package/dist/animation/spring/spring_system.js.map +1 -1
  21. package/dist/animation/spring_modifier.js +10 -0
  22. package/dist/animation/spring_modifier.js.map +1 -1
  23. package/dist/app/engine.js +53 -43
  24. package/dist/app/engine.js.map +1 -1
  25. package/dist/app/scriptingsystem.js +119 -6
  26. package/dist/app/scriptingsystem.js.map +1 -1
  27. package/dist/app/scriptregistry.js +3 -2
  28. package/dist/app/scriptregistry.js.map +1 -1
  29. package/dist/asset/assetmanager.js +284 -67
  30. package/dist/asset/assetmanager.js.map +1 -1
  31. package/dist/asset/loaders/zhair/zhair_format.js +288 -0
  32. package/dist/asset/loaders/zhair/zhair_format.js.map +1 -0
  33. package/dist/asset/loaders/zhair/zhair_loader.js +221 -0
  34. package/dist/asset/loaders/zhair/zhair_loader.js.map +1 -0
  35. package/dist/asset/model.js +178 -67
  36. package/dist/asset/model.js.map +1 -1
  37. package/dist/camera/camera.js +193 -21
  38. package/dist/camera/camera.js.map +1 -1
  39. package/dist/camera/perspectivecamera.js +3 -1
  40. package/dist/camera/perspectivecamera.js.map +1 -1
  41. package/dist/index.d.ts +4019 -1278
  42. package/dist/index.js +15 -5
  43. package/dist/index.js.map +1 -1
  44. package/dist/material/eye.js +932 -0
  45. package/dist/material/eye.js.map +1 -0
  46. package/dist/material/hair.js +917 -0
  47. package/dist/material/hair.js.map +1 -0
  48. package/dist/material/hairstrand.js +842 -0
  49. package/dist/material/hairstrand.js.map +1 -0
  50. package/dist/material/hairstrand_data.js +162 -0
  51. package/dist/material/hairstrand_data.js.map +1 -0
  52. package/dist/material/lambert.js +5 -2
  53. package/dist/material/lambert.js.map +1 -1
  54. package/dist/material/material.js +338 -300
  55. package/dist/material/material.js.map +1 -1
  56. package/dist/material/meshmaterial.js +120 -19
  57. package/dist/material/meshmaterial.js.map +1 -1
  58. package/dist/material/mixins/albedocolor.js +1 -1
  59. package/dist/material/mixins/albedocolor.js.map +1 -1
  60. package/dist/material/mixins/lightmodel/blinnphong.js +5 -3
  61. package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
  62. package/dist/material/mixins/lightmodel/lambert.js +5 -4
  63. package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
  64. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +3 -3
  65. package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
  66. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +5 -5
  67. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
  68. package/dist/material/mixins/lightmodel/pbrspecularglossness.js +3 -3
  69. package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
  70. package/dist/material/mixins/lit.js +73 -18
  71. package/dist/material/mixins/lit.js.map +1 -1
  72. package/dist/material/mixins/pbr/common.js +4 -4
  73. package/dist/material/mixins/pbr/common.js.map +1 -1
  74. package/dist/material/mixins/texture.js +48 -11
  75. package/dist/material/mixins/texture.js.map +1 -1
  76. package/dist/material/mtoon.js +6 -5
  77. package/dist/material/mtoon.js.map +1 -1
  78. package/dist/material/pbrblueprint.js +146 -28
  79. package/dist/material/pbrblueprint.js.map +1 -1
  80. package/dist/material/pbrblueprint_instance.js +501 -0
  81. package/dist/material/pbrblueprint_instance.js.map +1 -0
  82. package/dist/material/pbrmr.js +15 -16
  83. package/dist/material/pbrmr.js.map +1 -1
  84. package/dist/material/shader/helper.js +330 -20
  85. package/dist/material/shader/helper.js.map +1 -1
  86. package/dist/material/shader/terrain_blend.js +55 -0
  87. package/dist/material/shader/terrain_blend.js.map +1 -0
  88. package/dist/material/skin.js +192 -32
  89. package/dist/material/skin.js.map +1 -1
  90. package/dist/material/spriteblueprint.js +16 -1
  91. package/dist/material/spriteblueprint.js.map +1 -1
  92. package/dist/material/subsurfaceprofile.js +86 -23
  93. package/dist/material/subsurfaceprofile.js.map +1 -1
  94. package/dist/material/water.js +3 -1
  95. package/dist/material/water.js.map +1 -1
  96. package/dist/posteffect/bloom.js +167 -7
  97. package/dist/posteffect/bloom.js.map +1 -1
  98. package/dist/posteffect/coloradjust.js +2 -1
  99. package/dist/posteffect/coloradjust.js.map +1 -1
  100. package/dist/posteffect/compositor.js.map +1 -1
  101. package/dist/posteffect/fxaa.js +2 -1
  102. package/dist/posteffect/fxaa.js.map +1 -1
  103. package/dist/posteffect/grayscale.js +3 -1
  104. package/dist/posteffect/grayscale.js.map +1 -1
  105. package/dist/posteffect/motionblur.js +4 -1
  106. package/dist/posteffect/motionblur.js.map +1 -1
  107. package/dist/posteffect/posteffect.js.map +1 -1
  108. package/dist/posteffect/skinsss.js +368 -69
  109. package/dist/posteffect/skinsss.js.map +1 -1
  110. package/dist/posteffect/ssgi.js +16 -9
  111. package/dist/posteffect/ssgi.js.map +1 -1
  112. package/dist/posteffect/ssr.js +3 -0
  113. package/dist/posteffect/ssr.js.map +1 -1
  114. package/dist/posteffect/sss.js +91 -34
  115. package/dist/posteffect/sss.js.map +1 -1
  116. package/dist/posteffect/taa.js.map +1 -1
  117. package/dist/posteffect/tonemap.js +44 -1
  118. package/dist/posteffect/tonemap.js.map +1 -1
  119. package/dist/render/abuffer_oit.js +45 -39
  120. package/dist/render/abuffer_oit.js.map +1 -1
  121. package/dist/render/cull_visitor.js +19 -0
  122. package/dist/render/cull_visitor.js.map +1 -1
  123. package/dist/render/depthpass.js +36 -2
  124. package/dist/render/depthpass.js.map +1 -1
  125. package/dist/render/drawable_mixin.js +26 -1
  126. package/dist/render/drawable_mixin.js.map +1 -1
  127. package/dist/render/dualdepthpeeling_oit.js +52 -51
  128. package/dist/render/dualdepthpeeling_oit.js.map +1 -1
  129. package/dist/render/envlight.js +1 -1
  130. package/dist/render/envlight.js.map +1 -1
  131. package/dist/render/fbm_wavegenerator.js +3 -0
  132. package/dist/render/fbm_wavegenerator.js.map +1 -1
  133. package/dist/render/gerstner_wavegenerator.js +3 -0
  134. package/dist/render/gerstner_wavegenerator.js.map +1 -1
  135. package/dist/render/globalbindgroup_allocator.js +3 -0
  136. package/dist/render/globalbindgroup_allocator.js.map +1 -1
  137. package/dist/render/oit.js +29 -0
  138. package/dist/render/oit.js.map +1 -0
  139. package/dist/render/render_queue.js +3 -0
  140. package/dist/render/render_queue.js.map +1 -1
  141. package/dist/render/rendergraph/device_pool_allocator.js.map +1 -1
  142. package/dist/render/rendergraph/executor.js +2 -0
  143. package/dist/render/rendergraph/executor.js.map +1 -1
  144. package/dist/render/rendergraph/forward_plus_builder.js +61 -1
  145. package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
  146. package/dist/render/rendergraph/rendergraph.js.map +1 -1
  147. package/dist/render/rendergraph/texture_affinity_cache.js +1 -1
  148. package/dist/render/rendergraph/texture_affinity_cache.js.map +1 -1
  149. package/dist/render/rendergraph/types.js.map +1 -1
  150. package/dist/render/shadow_mask_pass.js +73 -8
  151. package/dist/render/shadow_mask_pass.js.map +1 -1
  152. package/dist/render/sky.js +166 -126
  153. package/dist/render/sky.js.map +1 -1
  154. package/dist/render/weightedblended_oit.js +36 -35
  155. package/dist/render/weightedblended_oit.js.map +1 -1
  156. package/dist/scene/basesprite.js +8 -0
  157. package/dist/scene/basesprite.js.map +1 -1
  158. package/dist/scene/batchgroup.js +3 -0
  159. package/dist/scene/batchgroup.js.map +1 -1
  160. package/dist/scene/environment.js +4 -1
  161. package/dist/scene/environment.js.map +1 -1
  162. package/dist/scene/hair.js +963 -0
  163. package/dist/scene/hair.js.map +1 -0
  164. package/dist/scene/light.js +5 -1
  165. package/dist/scene/light.js.map +1 -1
  166. package/dist/scene/mesh.js +481 -47
  167. package/dist/scene/mesh.js.map +1 -1
  168. package/dist/scene/meshdrawable.js +6 -0
  169. package/dist/scene/meshdrawable.js.map +1 -1
  170. package/dist/scene/msdftext.js +3 -0
  171. package/dist/scene/msdftext.js.map +1 -1
  172. package/dist/scene/msdftextsprite.js +3 -0
  173. package/dist/scene/msdftextsprite.js.map +1 -1
  174. package/dist/scene/particlesys.js +6 -0
  175. package/dist/scene/particlesys.js.map +1 -1
  176. package/dist/scene/scene.js +3 -0
  177. package/dist/scene/scene.js.map +1 -1
  178. package/dist/scene/scene_node.js +6 -1
  179. package/dist/scene/scene_node.js.map +1 -1
  180. package/dist/scene/terrain-cm/grass.js +3 -0
  181. package/dist/scene/terrain-cm/grass.js.map +1 -1
  182. package/dist/scene/terrain-cm/grassmaterial.js +3 -0
  183. package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
  184. package/dist/scene/terrain-cm/terrain-cm.js +6 -0
  185. package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
  186. package/dist/scene/terrain-cm/texture_cache.js +309 -0
  187. package/dist/scene/terrain-cm/texture_cache.js.map +1 -0
  188. package/dist/scene/water.js +6 -0
  189. package/dist/scene/water.js.map +1 -1
  190. package/dist/shaders/atmosphere.js.map +1 -1
  191. package/dist/shaders/diffusion.js +54 -0
  192. package/dist/shaders/diffusion.js.map +1 -0
  193. package/dist/shaders/shadow.js +33 -21
  194. package/dist/shaders/shadow.js.map +1 -1
  195. package/dist/shaders/temporal.js +71 -33
  196. package/dist/shaders/temporal.js.map +1 -1
  197. package/dist/shadow/dom.js +546 -0
  198. package/dist/shadow/dom.js.map +1 -0
  199. package/dist/shadow/pcf_opt.js +3 -5
  200. package/dist/shadow/pcf_opt.js.map +1 -1
  201. package/dist/shadow/pcf_pd.js +1 -1
  202. package/dist/shadow/pcf_pd.js.map +1 -1
  203. package/dist/shadow/receiver_bias.js +41 -0
  204. package/dist/shadow/receiver_bias.js.map +1 -0
  205. package/dist/shadow/shader.js +20 -60
  206. package/dist/shadow/shader.js.map +1 -1
  207. package/dist/shadow/shadow_impl.js +89 -0
  208. package/dist/shadow/shadow_impl.js.map +1 -1
  209. package/dist/shadow/shadow_region.js +50 -50
  210. package/dist/shadow/shadow_region.js.map +1 -1
  211. package/dist/shadow/shadowmapper.js +150 -37
  212. package/dist/shadow/shadowmapper.js.map +1 -1
  213. package/dist/shapes/shape.js +11 -2
  214. package/dist/shapes/shape.js.map +1 -1
  215. package/dist/shapes/sphere.js +50 -9
  216. package/dist/shapes/sphere.js.map +1 -1
  217. package/dist/utility/blueprint/common/constants.js +112 -2
  218. package/dist/utility/blueprint/common/constants.js.map +1 -1
  219. package/dist/utility/blueprint/material/func.js +142 -49
  220. package/dist/utility/blueprint/material/func.js.map +1 -1
  221. package/dist/utility/blueprint/material/ir.js +490 -25
  222. package/dist/utility/blueprint/material/ir.js.map +1 -1
  223. package/dist/utility/blueprint/material/texture.js +898 -4
  224. package/dist/utility/blueprint/material/texture.js.map +1 -1
  225. package/dist/utility/serialization/manager.js +431 -100
  226. package/dist/utility/serialization/manager.js.map +1 -1
  227. package/dist/utility/serialization/scene/animation.js +370 -3
  228. package/dist/utility/serialization/scene/animation.js.map +1 -1
  229. package/dist/utility/serialization/scene/batch.js +4 -0
  230. package/dist/utility/serialization/scene/batch.js.map +1 -1
  231. package/dist/utility/serialization/scene/camera.js +133 -1
  232. package/dist/utility/serialization/scene/camera.js.map +1 -1
  233. package/dist/utility/serialization/scene/common.js +26 -5
  234. package/dist/utility/serialization/scene/common.js.map +1 -1
  235. package/dist/utility/serialization/scene/hair.js +1141 -0
  236. package/dist/utility/serialization/scene/hair.js.map +1 -0
  237. package/dist/utility/serialization/scene/light.js +84 -4
  238. package/dist/utility/serialization/scene/light.js.map +1 -1
  239. package/dist/utility/serialization/scene/material.js +1867 -166
  240. package/dist/utility/serialization/scene/material.js.map +1 -1
  241. package/dist/utility/serialization/scene/mesh.js +231 -14
  242. package/dist/utility/serialization/scene/mesh.js.map +1 -1
  243. package/dist/utility/serialization/scene/node.js +141 -7
  244. package/dist/utility/serialization/scene/node.js.map +1 -1
  245. package/dist/utility/serialization/scene/particle.js +4 -0
  246. package/dist/utility/serialization/scene/particle.js.map +1 -1
  247. package/dist/utility/serialization/scene/primitive.js +18 -0
  248. package/dist/utility/serialization/scene/primitive.js.map +1 -1
  249. package/dist/utility/serialization/scene/sprite.js +4 -0
  250. package/dist/utility/serialization/scene/sprite.js.map +1 -1
  251. package/dist/utility/serialization/scene/terrain.js +4 -0
  252. package/dist/utility/serialization/scene/terrain.js.map +1 -1
  253. package/dist/utility/serialization/scene/text.js +4 -0
  254. package/dist/utility/serialization/scene/text.js.map +1 -1
  255. package/dist/utility/serialization/scene/water.js +4 -0
  256. package/dist/utility/serialization/scene/water.js.map +1 -1
  257. package/dist/utility/serialization/types.js.map +1 -1
  258. package/dist/utility/shprojector.js +96 -95
  259. package/dist/utility/shprojector.js.map +1 -1
  260. package/dist/values.js +49 -2
  261. package/dist/values.js.map +1 -1
  262. package/package.json +3 -3
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Samples every splat mask layer once in the given scope.
3
+ *
4
+ * Shared by the live terrain shading path and the texture cache bake pass so
5
+ * both interpret splat weights identically.
6
+ *
7
+ * @param scope - Scope to sample in
8
+ * @param splatMap - Splat map texture expression (2d array, or plain 2d on WebGL1)
9
+ * @param uv - Normalized terrain uv
10
+ * @param numLayers - Number of detail layers
11
+ * @param isWebGL1 - Whether targeting WebGL1 (splat map is a plain 2d texture)
12
+ * @param namePrefix - Local variable name prefix for the sampled masks
13
+ * @returns One vec4 expression per splat layer, 4 detail weights packed per layer
14
+ *
15
+ * @internal
16
+ */ function sampleTerrainSplatMasks(scope, splatMap, uv, numLayers, isWebGL1, namePrefix = 'splatMask') {
17
+ const pb = scope.$builder;
18
+ const masks = [];
19
+ for(let i = 0; i < numLayers + 3 >> 2; i++){
20
+ scope.$l[`${namePrefix}${i}`] = isWebGL1 ? pb.textureSample(splatMap, uv) : pb.textureArraySample(splatMap, uv, i);
21
+ masks.push(scope[`${namePrefix}${i}`]);
22
+ }
23
+ return masks;
24
+ }
25
+ /**
26
+ * Accumulates per-layer samples weighted by splat masks:
27
+ * `result = init + sum(sampleLayer(i, uv * uvScale(i)) * maskWeight(i))`
28
+ *
29
+ * This is the single definition of terrain detail blending. The live shading
30
+ * path and the texture cache bake pass must both go through it so the cached
31
+ * result can never diverge from the realtime result.
32
+ *
33
+ * @param scope - Scope to evaluate in
34
+ * @param resultName - Local variable name for the accumulator
35
+ * @param init - Initial accumulator value (also determines the value type)
36
+ * @param numLayers - Number of detail layers
37
+ * @param uv - Normalized terrain uv
38
+ * @param masks - Splat masks returned by {@link sampleTerrainSplatMasks}
39
+ * @param getUVScale - Per-layer uv scale accessor, or null when uv is unused by sampleLayer
40
+ * @param sampleLayer - Per-layer value accessor, must return the same type as init
41
+ * @returns The accumulated expression
42
+ *
43
+ * @internal
44
+ */ function accumulateTerrainLayers(scope, resultName, init, numLayers, uv, masks, getUVScale, sampleLayer) {
45
+ const pb = scope.$builder;
46
+ scope.$l[resultName] = init;
47
+ for(let i = 0; i < numLayers; i++){
48
+ const layerUV = getUVScale ? pb.mul(uv, getUVScale(i)) : uv;
49
+ scope[resultName] = pb.add(scope[resultName], pb.mul(sampleLayer(scope, i, layerUV), masks[i >> 2][i & 3]));
50
+ }
51
+ return scope[resultName];
52
+ }
53
+
54
+ export { accumulateTerrainLayers, sampleTerrainSplatMasks };
55
+ //# sourceMappingURL=terrain_blend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terrain_blend.js","sources":["../../../src/material/shader/terrain_blend.ts"],"sourcesContent":["import type { PBInsideFunctionScope, PBShaderExp } from '@zephyr3d/device';\r\n\r\n/**\r\n * Samples every splat mask layer once in the given scope.\r\n *\r\n * Shared by the live terrain shading path and the texture cache bake pass so\r\n * both interpret splat weights identically.\r\n *\r\n * @param scope - Scope to sample in\r\n * @param splatMap - Splat map texture expression (2d array, or plain 2d on WebGL1)\r\n * @param uv - Normalized terrain uv\r\n * @param numLayers - Number of detail layers\r\n * @param isWebGL1 - Whether targeting WebGL1 (splat map is a plain 2d texture)\r\n * @param namePrefix - Local variable name prefix for the sampled masks\r\n * @returns One vec4 expression per splat layer, 4 detail weights packed per layer\r\n *\r\n * @internal\r\n */\r\nexport function sampleTerrainSplatMasks(\r\n scope: PBInsideFunctionScope,\r\n splatMap: PBShaderExp,\r\n uv: PBShaderExp,\r\n numLayers: number,\r\n isWebGL1: boolean,\r\n namePrefix = 'splatMask'\r\n): PBShaderExp[] {\r\n const pb = scope.$builder;\r\n const masks: PBShaderExp[] = [];\r\n for (let i = 0; i < (numLayers + 3) >> 2; i++) {\r\n scope.$l[`${namePrefix}${i}`] = isWebGL1\r\n ? pb.textureSample(splatMap, uv)\r\n : pb.textureArraySample(splatMap, uv, i);\r\n masks.push(scope[`${namePrefix}${i}`]);\r\n }\r\n return masks;\r\n}\r\n\r\n/**\r\n * Accumulates per-layer samples weighted by splat masks:\r\n * `result = init + sum(sampleLayer(i, uv * uvScale(i)) * maskWeight(i))`\r\n *\r\n * This is the single definition of terrain detail blending. The live shading\r\n * path and the texture cache bake pass must both go through it so the cached\r\n * result can never diverge from the realtime result.\r\n *\r\n * @param scope - Scope to evaluate in\r\n * @param resultName - Local variable name for the accumulator\r\n * @param init - Initial accumulator value (also determines the value type)\r\n * @param numLayers - Number of detail layers\r\n * @param uv - Normalized terrain uv\r\n * @param masks - Splat masks returned by {@link sampleTerrainSplatMasks}\r\n * @param getUVScale - Per-layer uv scale accessor, or null when uv is unused by sampleLayer\r\n * @param sampleLayer - Per-layer value accessor, must return the same type as init\r\n * @returns The accumulated expression\r\n *\r\n * @internal\r\n */\r\nexport function accumulateTerrainLayers(\r\n scope: PBInsideFunctionScope,\r\n resultName: string,\r\n init: PBShaderExp,\r\n numLayers: number,\r\n uv: PBShaderExp,\r\n masks: PBShaderExp[],\r\n getUVScale: ((index: number) => PBShaderExp) | null,\r\n sampleLayer: (scope: PBInsideFunctionScope, index: number, uv: PBShaderExp) => PBShaderExp\r\n): PBShaderExp {\r\n const pb = scope.$builder;\r\n scope.$l[resultName] = init;\r\n for (let i = 0; i < numLayers; i++) {\r\n const layerUV = getUVScale ? pb.mul(uv, getUVScale(i)) : uv;\r\n scope[resultName] = pb.add(\r\n scope[resultName],\r\n pb.mul(sampleLayer(scope, i, layerUV), masks[i >> 2][i & 3])\r\n );\r\n }\r\n return scope[resultName];\r\n}\r\n"],"names":["sampleTerrainSplatMasks","scope","splatMap","uv","numLayers","isWebGL1","namePrefix","pb","$builder","masks","i","$l","textureSample","textureArraySample","push","accumulateTerrainLayers","resultName","init","getUVScale","sampleLayer","layerUV","mul","add"],"mappings":"AAEA;;;;;;;;;;;;;;;AAeC,IACM,SAASA,uBACdC,CAAAA,KAA4B,EAC5BC,QAAqB,EACrBC,EAAe,EACfC,SAAiB,EACjBC,QAAiB,EACjBC,aAAa,WAAW,EAAA;IAExB,MAAMC,EAAAA,GAAKN,MAAMO,QAAQ;AACzB,IAAA,MAAMC,QAAuB,EAAE;IAC/B,IAAK,IAAIC,IAAI,CAAGA,EAAAA,CAAAA,GAAI,SAAa,GAAA,CAAA,IAAM,GAAGA,CAAK,EAAA,CAAA;AAC7CT,QAAAA,KAAAA,CAAMU,EAAE,CAAC,CAAA,EAAGL,UAAaI,CAAAA,EAAAA,CAAAA,CAAAA,CAAG,CAAC,GAAGL,QAAAA,GAC5BE,EAAGK,CAAAA,aAAa,CAACV,QAAUC,EAAAA,EAAAA,CAAAA,GAC3BI,GAAGM,kBAAkB,CAACX,UAAUC,EAAIO,EAAAA,CAAAA,CAAAA;AACxCD,QAAAA,KAAAA,CAAMK,IAAI,CAACb,KAAK,CAAC,CAAGK,EAAAA,UAAAA,CAAAA,EAAaI,GAAG,CAAC,CAAA;AACvC;IACA,OAAOD,KAAAA;AACT;AAEA;;;;;;;;;;;;;;;;;;;AAmBC,IACM,SAASM,uBAAAA,CACdd,KAA4B,EAC5Be,UAAkB,EAClBC,IAAiB,EACjBb,SAAiB,EACjBD,EAAe,EACfM,KAAoB,EACpBS,UAAmD,EACnDC,WAA0F,EAAA;IAE1F,MAAMZ,EAAAA,GAAKN,MAAMO,QAAQ;IACzBP,KAAMU,CAAAA,EAAE,CAACK,UAAAA,CAAW,GAAGC,IAAAA;AACvB,IAAA,IAAK,IAAIP,CAAAA,GAAI,CAAGA,EAAAA,CAAAA,GAAIN,WAAWM,CAAK,EAAA,CAAA;AAClC,QAAA,MAAMU,UAAUF,UAAaX,GAAAA,EAAAA,CAAGc,GAAG,CAAClB,EAAAA,EAAIe,WAAWR,CAAMP,CAAAA,CAAAA,GAAAA,EAAAA;QACzDF,KAAK,CAACe,WAAW,GAAGT,EAAAA,CAAGe,GAAG,CACxBrB,KAAK,CAACe,UAAAA,CAAW,EACjBT,EAAAA,CAAGc,GAAG,CAACF,WAAAA,CAAYlB,KAAOS,EAAAA,CAAAA,EAAGU,OAAUX,CAAAA,EAAAA,KAAK,CAACC,CAAK,IAAA,CAAA,CAAE,CAACA,CAAAA,GAAI,CAAE,CAAA,CAAA,CAAA;AAE/D;IACA,OAAOT,KAAK,CAACe,UAAW,CAAA;AAC1B;;;;"}
@@ -6,16 +6,34 @@ import { mixinTextureProps } from './mixins/texture.js';
6
6
  import { ShaderHelper } from './shader/helper.js';
7
7
  import { RENDER_PASS_TYPE_LIGHT, LIGHT_TYPE_POINT, MaterialVaryingFlags } from '../values.js';
8
8
 
9
+ /**
10
+ * HDR range packed into the SkinSSS side buffer when the render graph falls
11
+ * back to an 8-bit format. The material divides the scatter irradiance by this
12
+ * factor on write and {@link SkinSSS} multiplies it back after the blur.
13
+ * @public
14
+ */ const SKIN_SSS_LDR_ENCODE_RANGE = 4;
9
15
  /**
10
16
  * Stylized realtime skin material.
11
17
  *
12
18
  * @remarks
13
- * This material is designed for the {@link SkinSSS} post effect. It renders a regular lit color,
14
- * and when `camera.skinSSS` is enabled it also writes a skin lighting multiplier into the
15
- * `SkinSSSTexture` MRT. The post effect blurs that side buffer in screen space to create a soft
16
- * character-skin look similar to simple game/anime skin renderers.
19
+ * This material is designed for the {@link SkinSSS} post effect. It renders a regular lit color
20
+ * and, when `camera.skinSSS` is enabled, writes the *diffusible* part of that color - the stylized
21
+ * diffuse ramp plus back-lit transmission, without specular - into the `SkinSSSTexture` MRT.
22
+ *
23
+ * The side buffer holds exactly the same term that is already in the lit color, untinted and
24
+ * unscaled. {@link SkinSSS} subtracts it and adds back a channel-dependent diffused version, so
25
+ * the redistribution is energy conserving by construction and disabling the effect leaves the
26
+ * image unchanged. Scatter tint, strength and radius therefore live on the post effect, not here.
27
+ *
28
+ * Stylization is split from diffusion on purpose. {@link SkinMaterial.diffuseWrap},
29
+ * {@link SkinMaterial.diffuseSoftness}, {@link SkinMaterial.shadowTint} and
30
+ * {@link SkinMaterial.brightening} shape the direct lighting ramp; the post effect then diffuses
31
+ * whatever ramp they produced. A stylized ramp stays stylized after scattering rather than being
32
+ * averaged away.
17
33
  *
18
- * The optional `subsurfaceTexture` uses R as skin mask and G as local softness.
34
+ * The optional `subsurfaceTexture` uses R as skin mask, G as local softness and B as thickness
35
+ * for the back-lit transmission term (thin regions such as ears and nostrils glow when lit from
36
+ * behind; enable it by setting {@link SkinMaterial.transmissionStrength}).
19
37
  *
20
38
  * @public
21
39
  */ class SkinMaterial extends applyMaterialMixins(MeshMaterial, mixinLight, mixinVertexColor, mixinTextureProps('subsurface')) {
@@ -28,15 +46,23 @@ import { RENDER_PASS_TYPE_LIGHT, LIGHT_TYPE_POINT, MaterialVaryingFlags } from '
28
46
  _scatterWrap;
29
47
  _scatterStrength;
30
48
  _scatterColor;
49
+ _transmissionStrength;
50
+ _transmissionPower;
51
+ _shadowTint;
52
+ _brightening;
31
53
  constructor(){
32
54
  super();
33
55
  this._shininess = 72;
34
- this._specularStrength = 0.22;
56
+ this._specularStrength = 1;
35
57
  this._diffuseWrap = 0.28;
36
58
  this._diffuseSoftness = 0.45;
37
59
  this._scatterWrap = 0.65;
38
- this._scatterStrength = 0.7;
60
+ this._scatterStrength = 1.5;
39
61
  this._scatterColor = new Vector4(1, 0.42, 0.28, 1);
62
+ this._transmissionStrength = 0;
63
+ this._transmissionPower = 4;
64
+ this._shadowTint = new Vector4(0, 0, 0, 1);
65
+ this._brightening = 0;
40
66
  this.useFeature(SkinMaterial.FEATURE_VERTEX_NORMAL, true);
41
67
  }
42
68
  /** Marker used by the forward render graph to allocate the SkinSSS MRT. */ get skinSSS() {
@@ -58,6 +84,10 @@ import { RENDER_PASS_TYPE_LIGHT, LIGHT_TYPE_POINT, MaterialVaryingFlags } from '
58
84
  this.scatterWrap = other.scatterWrap;
59
85
  this.scatterStrength = other.scatterStrength;
60
86
  this.scatterColor = other.scatterColor;
87
+ this.transmissionStrength = other.transmissionStrength;
88
+ this.transmissionPower = other.transmissionPower;
89
+ this.shadowTint = other.shadowTint;
90
+ this.brightening = other.brightening;
61
91
  }
62
92
  /** true if vertex normal attribute presents */ get vertexNormal() {
63
93
  return this.featureUsed(SkinMaterial.FEATURE_VERTEX_NORMAL);
@@ -111,7 +141,15 @@ import { RENDER_PASS_TYPE_LIGHT, LIGHT_TYPE_POINT, MaterialVaryingFlags } from '
111
141
  this.uniformChanged();
112
142
  }
113
143
  }
114
- /** Wider wrap used only for the post-process scattering source. */ get scatterWrap() {
144
+ /**
145
+ * Wider wrap that used to shape the post-process scattering source.
146
+ *
147
+ * @deprecated No longer has any effect. The side buffer now carries the real
148
+ * diffuse term rather than a hand-built difference that was nonzero only near
149
+ * the terminator, so there is nothing for a second wrap to shape. Use
150
+ * {@link SkinSSS.scatterRadius} and the profile's channel radii to control how
151
+ * far light travels, and {@link SkinMaterial.diffuseWrap} to shape the ramp.
152
+ */ get scatterWrap() {
115
153
  return this._scatterWrap;
116
154
  }
117
155
  set scatterWrap(val) {
@@ -121,7 +159,15 @@ import { RENDER_PASS_TYPE_LIGHT, LIGHT_TYPE_POINT, MaterialVaryingFlags } from '
121
159
  this.uniformChanged();
122
160
  }
123
161
  }
124
- /** Strength of the multiplier written into the SkinSSS side buffer. */ get scatterStrength() {
162
+ /**
163
+ * Strength of the multiplier written into the SkinSSS side buffer.
164
+ *
165
+ * @deprecated No longer has any effect. Scaling the side buffer would break
166
+ * the identity that makes the diffusion energy conserving - it must equal the
167
+ * diffusible term already present in the lit color. Use
168
+ * {@link SkinSSS.strength} for the overall amount and {@link SkinSSS.glow} for
169
+ * an additive, non-conserving bleed on top.
170
+ */ get scatterStrength() {
125
171
  return this._scatterStrength;
126
172
  }
127
173
  set scatterStrength(val) {
@@ -131,7 +177,38 @@ import { RENDER_PASS_TYPE_LIGHT, LIGHT_TYPE_POINT, MaterialVaryingFlags } from '
131
177
  this.uniformChanged();
132
178
  }
133
179
  }
134
- /** Warm tint for the blurred skin lighting contribution. */ get scatterColor() {
180
+ /**
181
+ * Strength of the back-lit transmission term. Requires a `subsurfaceTexture`
182
+ * with thickness in the B channel; 0 (the default) disables transmission.
183
+ */ get transmissionStrength() {
184
+ return this._transmissionStrength;
185
+ }
186
+ set transmissionStrength(val) {
187
+ const next = Math.max(0, val ?? 0);
188
+ if (next !== this._transmissionStrength) {
189
+ this._transmissionStrength = next;
190
+ this.uniformChanged();
191
+ }
192
+ }
193
+ /** Exponent of the back-lit transmission falloff. Higher values tighten the glow. */ get transmissionPower() {
194
+ return this._transmissionPower;
195
+ }
196
+ set transmissionPower(val) {
197
+ const next = Math.max(1, val ?? 1);
198
+ if (next !== this._transmissionPower) {
199
+ this._transmissionPower = next;
200
+ this.uniformChanged();
201
+ }
202
+ }
203
+ /**
204
+ * Warm tint for the blurred skin lighting contribution.
205
+ *
206
+ * @deprecated No longer has any effect; moved to {@link SkinSSS.scatterTint}.
207
+ * Tinting here would tint the diffuse in the lit color too, which is what made
208
+ * the old look read as a red haze over the whole face. On the post effect the
209
+ * tint applies only to the light that actually moved, and per-channel scatter
210
+ * radii from the profile already produce the red bleed on their own.
211
+ */ get scatterColor() {
135
212
  return this._scatterColor;
136
213
  }
137
214
  set scatterColor(val) {
@@ -140,6 +217,29 @@ import { RENDER_PASS_TYPE_LIGHT, LIGHT_TYPE_POINT, MaterialVaryingFlags } from '
140
217
  this.uniformChanged();
141
218
  }
142
219
  }
220
+ /**
221
+ * NPR-style shadow tint: the dark end of the diffuse ramp lifts toward this
222
+ * color instead of black (black, the default, reproduces plain wrapped
223
+ * lambert). A rosy/lavender tint gives the stylized beauty-shot shadow look.
224
+ */ get shadowTint() {
225
+ return this._shadowTint;
226
+ }
227
+ set shadowTint(val) {
228
+ if (!val.equalsTo(this._shadowTint)) {
229
+ this._shadowTint.set(val);
230
+ this.uniformChanged();
231
+ }
232
+ }
233
+ /** Whitening gain applied to the whole diffuse response. 0 (the default) is neutral. */ get brightening() {
234
+ return this._brightening;
235
+ }
236
+ set brightening(val) {
237
+ const next = Math.max(0, val ?? 0);
238
+ if (next !== this._brightening) {
239
+ this._brightening = next;
240
+ this.uniformChanged();
241
+ }
242
+ }
143
243
  vertexShader(scope) {
144
244
  super.vertexShader(scope);
145
245
  const pb = scope.$builder;
@@ -166,9 +266,15 @@ import { RENDER_PASS_TYPE_LIGHT, LIGHT_TYPE_POINT, MaterialVaryingFlags } from '
166
266
  scope.zSkinSpecularStrength = pb.float().uniform(2);
167
267
  scope.zSkinDiffuseWrap = pb.float().uniform(2);
168
268
  scope.zSkinDiffuseSoftness = pb.float().uniform(2);
169
- scope.zSkinScatterWrap = pb.float().uniform(2);
170
- scope.zSkinScatterStrength = pb.float().uniform(2);
171
- scope.zSkinScatterColor = pb.vec4().uniform(2);
269
+ scope.zSkinShadowTint = pb.vec4().uniform(2);
270
+ scope.zSkinBrightening = pb.float().uniform(2);
271
+ // Encodes HDR scatter irradiance into the SkinSSS buffer range when the
272
+ // render graph falls back to rgba8unorm (see getSSSLightingTextureFormat).
273
+ scope.zSkinScatterEncodeScale = pb.float().uniform(2);
274
+ if (this.subsurfaceTexture) {
275
+ scope.zSkinTransmissionStrength = pb.float().uniform(2);
276
+ scope.zSkinTransmissionPower = pb.float().uniform(2);
277
+ }
172
278
  }
173
279
  scope.$l.albedo = this.calculateAlbedoColor(scope);
174
280
  if (this.vertexColor) {
@@ -176,25 +282,32 @@ import { RENDER_PASS_TYPE_LIGHT, LIGHT_TYPE_POINT, MaterialVaryingFlags } from '
176
282
  }
177
283
  if (this.drawContext.renderPass.type === RENDER_PASS_TYPE_LIGHT) {
178
284
  const baseLightPass = !this.drawContext.lightBlending;
179
- scope.$l.normal = this.calculateNormal(scope, scope.$inputs.worldPos, scope.$inputs.wNorm, scope.$inputs.wTangent, scope.$inputs.wBinormal);
285
+ // TBN[2] is the pre-normal-map geometric normal, needed for shadow
286
+ // normal offset bias. Feeding the normal mapped shading normal instead
287
+ // would displace the shadow lookup along pore detail.
288
+ scope.$l.normalInfo = this.calculateNormalAndTBN(scope, scope.$inputs.worldPos, scope.$inputs.wNorm, scope.$inputs.wTangent, scope.$inputs.wBinormal);
289
+ scope.$l.normal = scope.normalInfo.normal;
180
290
  scope.$l.viewVec = this.calculateViewVector(scope, scope.$inputs.worldPos);
181
291
  scope.$l.roughness = pb.sqrt(pb.div(2, pb.add(scope.zSkinShininess, 2)));
182
292
  scope.$l.skinMask = pb.float(1);
183
293
  scope.$l.skinSoftness = pb.float(0);
294
+ scope.$l.skinThickness = pb.float(0);
184
295
  if (this.subsurfaceTexture) {
185
296
  scope.$l.subsurfaceTexel = this.sampleSubsurfaceTexture(scope);
186
297
  scope.skinMask = pb.clamp(scope.subsurfaceTexel.r, 0, 1);
187
298
  scope.skinSoftness = pb.clamp(scope.subsurfaceTexel.g, 0, 1);
299
+ scope.skinThickness = pb.clamp(scope.subsurfaceTexel.b, 0, 1);
188
300
  }
189
301
  scope.$l.diffuseLighting = pb.vec3(0);
190
- scope.$l.scatterLighting = pb.vec3(0);
302
+ scope.$l.transmissionLighting = pb.vec3(0);
191
303
  scope.$l.specularLighting = pb.vec3(0);
304
+ scope.$l.NoV = pb.clamp(pb.dot(scope.normal, scope.viewVec), 0, 1);
192
305
  if (this.needCalculateEnvLight() && baseLightPass) {
193
306
  scope.$l.envDiffuse = this.getEnvLightIrradiance(scope, scope.normal);
194
307
  scope.diffuseLighting = pb.add(scope.diffuseLighting, scope.envDiffuse);
195
- scope.scatterLighting = pb.add(scope.scatterLighting, pb.mul(scope.envDiffuse, pb.add(0.7, pb.mul(scope.skinSoftness, 0.45))));
196
308
  scope.$l.reflectVec = this.calculateReflectionVector(scope, scope.normal, scope.viewVec);
197
- scope.specularLighting = pb.add(scope.specularLighting, pb.mul(this.getEnvLightRadiance(scope, scope.reflectVec, scope.roughness), scope.zSkinSpecularStrength));
309
+ scope.$l.envFresnel = pb.add(0.028, pb.mul(0.972, pb.pow(pb.sub(1, scope.NoV), 5)));
310
+ scope.specularLighting = pb.add(scope.specularLighting, pb.mul(this.getEnvLightRadiance(scope, scope.reflectVec, scope.roughness), scope.envFresnel, scope.zSkinSpecularStrength));
198
311
  }
199
312
  this.forEachLight(scope, function(type, posRange, dirCutoff, colorIntensity, extra, shadow) {
200
313
  this.$l.diffuseScale = pb.float(1);
@@ -210,26 +323,68 @@ import { RENDER_PASS_TYPE_LIGHT, LIGHT_TYPE_POINT, MaterialVaryingFlags } from '
210
323
  this.$l.rawNoL = pb.dot(this.normal, this.lightDir);
211
324
  this.$l.NoL = pb.clamp(this.rawNoL, 0, 1);
212
325
  this.$l.NoLWrap = pb.clamp(pb.div(pb.add(this.rawNoL, this.zSkinDiffuseWrap), pb.add(1, this.zSkinDiffuseWrap)), 0, 1);
213
- this.$l.NoLScatter = pb.clamp(pb.div(pb.add(this.rawNoL, this.zSkinScatterWrap), pb.add(1, this.zSkinScatterWrap)), 0, 1);
214
326
  // calculateShadow() samples with implicit derivatives (dpdx); WGSL
215
327
  // requires the call to stay in uniform control flow, so never wrap
216
328
  // it in a dynamic branch such as NoLWrap > 0.
217
- this.$l.shadowTerm = shadow ? that.calculateShadow(this, this.$inputs.worldPos, pb.max(this.NoL, 1e-5)) : pb.float(1);
218
- this.$l.lightColor = pb.mul(colorIntensity.rgb, colorIntensity.a, this.lightAtten, this.shadowTerm);
329
+ //
330
+ // Diffuse and specular share this term unmodified. An earlier version
331
+ // faded it toward 1 around the terminator to hide shadow map acne
332
+ // there, but that released the shadow in the wrong band (only ~9% at
333
+ // NdotL = 0, by which point the acne is at its worst) and made cast
334
+ // shadows dissolve wherever a surface turned away from the light.
335
+ // Normal offset bias removes the acne at the source instead.
336
+ this.$l.shadowTerm = shadow ? that.calculateShadow(this, this.$inputs.worldPos, scope.normalInfo.TBN[2], pb.max(this.NoL, 1e-5)) : pb.float(1);
337
+ this.$l.lightColor = pb.mul(colorIntensity.rgb, colorIntensity.a, this.lightAtten);
338
+ this.$l.diffuseLightColor = pb.mul(this.lightColor, this.shadowTerm);
219
339
  this.$l.halfVec = pb.normalize(pb.add(this.viewVec, this.lightDir));
220
340
  this.$l.NoH = pb.clamp(pb.dot(this.normal, this.halfVec), 0, 1);
341
+ this.$l.LoH = pb.clamp(pb.dot(this.lightDir, this.halfVec), 0, 1);
221
342
  this.$l.pointShininess = pb.max(pb.div(this.zSkinShininess, pb.add(1, pb.mul(this.sourceRadiusFactor, 32))), 1);
222
- this.$l.hardDiffuse = pb.mul(this.lightColor, this.NoL, this.diffuseScale, 1 / Math.PI);
223
- this.$l.softDiffuse = pb.mul(this.lightColor, this.NoLWrap, this.diffuseScale, 1 / Math.PI);
224
343
  this.$l.softness = pb.clamp(pb.add(this.zSkinDiffuseSoftness, pb.mul(this.skinSoftness, 0.35)), 0, 1);
225
- this.diffuseLighting = pb.add(this.diffuseLighting, pb.mix(this.hardDiffuse, this.softDiffuse, this.softness));
226
- this.scatterLighting = pb.add(this.scatterLighting, pb.mul(this.lightColor, this.NoLScatter, pb.add(0.7, pb.mul(this.skinSoftness, 0.55)), this.diffuseScale, 1 / Math.PI));
227
- this.$l.specular = pb.mul(this.lightColor, pb.pow(this.NoH, this.pointShininess), this.zSkinSpecularStrength, this.specularScale, this.NoLWrap);
344
+ this.$l.NoLVis = pb.mix(this.NoL, this.NoLWrap, this.softness);
345
+ // NPR-style diffuse ramp: the dark end lifts toward the shadow tint
346
+ // instead of black. A black tint reproduces plain wrapped lambert.
347
+ this.$l.diffuseRamp = pb.mix(this.zSkinShadowTint.rgb, pb.vec3(1), this.NoLVis);
348
+ this.diffuseLighting = pb.add(this.diffuseLighting, pb.mul(this.diffuseLightColor, this.diffuseRamp, this.diffuseScale, 1 / Math.PI));
349
+ if (that.subsurfaceTexture) {
350
+ // Back-lit transmission: thin regions (B channel of the subsurface
351
+ // texture) glow when the light faces the camera through the
352
+ // surface.
353
+ //
354
+ // This deliberately uses the unshadowed lightColor. A back-lit
355
+ // fragment is self-shadowed by definition - its own front face is
356
+ // the occluder - so multiplying by the shadow term would cancel
357
+ // exactly the case the term exists to model. The cost is that an
358
+ // external caster does not block the glow, which a shadow map
359
+ // cannot distinguish from self occlusion anyway.
360
+ this.$l.transmission = pb.mul(pb.pow(pb.clamp(pb.dot(pb.neg(this.lightDir), this.viewVec), 0, 1), this.zSkinTransmissionPower), this.skinThickness, this.zSkinTransmissionStrength);
361
+ this.transmissionLighting = pb.add(this.transmissionLighting, pb.mul(this.lightColor, this.transmission, this.diffuseScale, 1 / Math.PI));
362
+ }
363
+ // Normalized Blinn with Schlick Fresnel (skin F0 = 0.028). Specular
364
+ // keeps the unfaded shadow term and hard NoL masking.
365
+ this.$l.specNormalization = pb.div(pb.add(this.pointShininess, 8), 8 * Math.PI);
366
+ this.$l.specFresnel = pb.add(0.028, pb.mul(0.972, pb.pow(pb.sub(1, this.LoH), 5)));
367
+ this.$l.specular = pb.mul(this.lightColor, this.shadowTerm, pb.pow(this.NoH, this.pointShininess), this.specNormalization, this.specFresnel, this.zSkinSpecularStrength, this.specularScale, this.NoL);
228
368
  this.specularLighting = pb.add(this.specularLighting, this.specular);
229
369
  });
230
- scope.$l.litColor = pb.add(pb.mul(scope.albedo.rgb, scope.diffuseLighting), scope.specularLighting);
231
- scope.$l.scatterMultiplier = pb.add(baseLightPass ? pb.vec3(1) : pb.vec3(0), pb.mul(scope.albedo.rgb, scope.scatterLighting, scope.zSkinScatterColor.rgb, scope.zSkinScatterStrength, pb.add(0.75, pb.mul(scope.skinSoftness, 0.45))));
232
- scope.$l.skinSSS = pb.vec4(scope.scatterMultiplier, scope.skinMask);
370
+ // Whitening: lift the whole diffuse response (direct and ambient).
371
+ scope.diffuseLighting = pb.mul(scope.diffuseLighting, pb.add(1, scope.zSkinBrightening));
372
+ // Everything that scatters through the surface: the stylized diffuse
373
+ // ramp plus back-lit transmission. Specular stays out - it reflects off
374
+ // the oil layer and never enters the skin.
375
+ scope.$l.diffusible = pb.mul(scope.albedo.rgb, pb.add(scope.diffuseLighting, scope.transmissionLighting));
376
+ scope.$l.litColor = pb.add(scope.diffusible, scope.specularLighting);
377
+ // The SkinSSS side buffer carries exactly the diffusible term that is
378
+ // also in litColor - untinted and unscaled. That identity is what lets
379
+ // the post effect subtract it and add back a diffused version, which is
380
+ // energy conserving by construction and leaves the image untouched when
381
+ // the effect is disabled. Tinting or scaling here would break it; those
382
+ // controls live on SkinSSS instead.
383
+ //
384
+ // Base and additive light passes both write their own contribution; the
385
+ // additive blend (RGB one/one, alpha zero/one) accumulates RGB and keeps
386
+ // the mask written by the base pass in alpha.
387
+ scope.$l.skinSSS = pb.vec4(pb.mul(scope.diffusible, scope.zSkinScatterEncodeScale), scope.skinMask);
233
388
  if (this.drawContext.materialFlags & (MaterialVaryingFlags.SCENE_STORE_ROUGHNESS | MaterialVaryingFlags.SCENE_STORE_NORMAL)) {
234
389
  scope.$l.outRoughness = pb.vec4(pb.mul(scope.albedo.rgb, pb.sub(1, scope.roughness), scope.zSkinSpecularStrength), pb.mul(scope.roughness, ShaderHelper.getCameraRoughnessFactor(scope)));
235
390
  this.outputFragmentColor(scope, scope.$inputs.worldPos, pb.vec4(scope.litColor, scope.albedo.a), scope.outRoughness, pb.vec4(pb.add(pb.mul(scope.normal, 0.5), pb.vec3(0.5)), 1), undefined, undefined, undefined, undefined, false, scope.skinSSS);
@@ -250,12 +405,17 @@ import { RENDER_PASS_TYPE_LIGHT, LIGHT_TYPE_POINT, MaterialVaryingFlags } from '
250
405
  bindGroup.setValue('zSkinSpecularStrength', this._specularStrength);
251
406
  bindGroup.setValue('zSkinDiffuseWrap', this._diffuseWrap);
252
407
  bindGroup.setValue('zSkinDiffuseSoftness', this._diffuseSoftness);
253
- bindGroup.setValue('zSkinScatterWrap', this._scatterWrap);
254
- bindGroup.setValue('zSkinScatterStrength', this._scatterStrength);
255
- bindGroup.setValue('zSkinScatterColor', this._scatterColor);
408
+ bindGroup.setValue('zSkinShadowTint', this._shadowTint);
409
+ bindGroup.setValue('zSkinBrightening', this._brightening);
410
+ const ldrSkinSSS = ctx.SkinSSSTexture && ctx.SkinSSSTexture.format === 'rgba8unorm';
411
+ bindGroup.setValue('zSkinScatterEncodeScale', ldrSkinSSS ? 1 / SKIN_SSS_LDR_ENCODE_RANGE : 1);
412
+ if (this.subsurfaceTexture) {
413
+ bindGroup.setValue('zSkinTransmissionStrength', this._transmissionStrength);
414
+ bindGroup.setValue('zSkinTransmissionPower', this._transmissionPower);
415
+ }
256
416
  }
257
417
  }
258
418
  }
259
419
 
260
- export { SkinMaterial };
420
+ export { SKIN_SSS_LDR_ENCODE_RANGE, SkinMaterial };
261
421
  //# sourceMappingURL=skin.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"skin.js","sources":["../../src/material/skin.ts"],"sourcesContent":["import type { BindGroup, PBFunctionScope } from '@zephyr3d/device';\r\nimport type { Clonable, Immutable } from '@zephyr3d/base';\r\nimport { Vector4 } from '@zephyr3d/base';\r\nimport { MeshMaterial, applyMaterialMixins } from './meshmaterial';\r\nimport { mixinLight } from './mixins/lit';\r\nimport { mixinVertexColor } from './mixins/vertexcolor';\r\nimport { mixinTextureProps } from './mixins/texture';\r\nimport { ShaderHelper } from './shader/helper';\r\nimport type { DrawContext } from '../render';\r\nimport { LIGHT_TYPE_POINT, MaterialVaryingFlags, RENDER_PASS_TYPE_LIGHT } from '../values';\r\n\r\n/**\r\n * Stylized realtime skin material.\r\n *\r\n * @remarks\r\n * This material is designed for the {@link SkinSSS} post effect. It renders a regular lit color,\r\n * and when `camera.skinSSS` is enabled it also writes a skin lighting multiplier into the\r\n * `SkinSSSTexture` MRT. The post effect blurs that side buffer in screen space to create a soft\r\n * character-skin look similar to simple game/anime skin renderers.\r\n *\r\n * The optional `subsurfaceTexture` uses R as skin mask and G as local softness.\r\n *\r\n * @public\r\n */\r\nexport class SkinMaterial\r\n extends applyMaterialMixins(MeshMaterial, mixinLight, mixinVertexColor, mixinTextureProps('subsurface'))\r\n implements Clonable<SkinMaterial>\r\n{\r\n private static readonly FEATURE_VERTEX_NORMAL = this.defineFeature();\r\n private static readonly FEATURE_VERTEX_TANGENT = this.defineFeature();\r\n private _shininess: number;\r\n private _specularStrength: number;\r\n private _diffuseWrap: number;\r\n private _diffuseSoftness: number;\r\n private _scatterWrap: number;\r\n private _scatterStrength: number;\r\n private readonly _scatterColor: Vector4;\r\n\r\n constructor() {\r\n super();\r\n this._shininess = 72;\r\n this._specularStrength = 0.22;\r\n this._diffuseWrap = 0.28;\r\n this._diffuseSoftness = 0.45;\r\n this._scatterWrap = 0.65;\r\n this._scatterStrength = 0.7;\r\n this._scatterColor = new Vector4(1, 0.42, 0.28, 1);\r\n this.useFeature(SkinMaterial.FEATURE_VERTEX_NORMAL, true);\r\n }\r\n\r\n /** Marker used by the forward render graph to allocate the SkinSSS MRT. */\r\n get skinSSS() {\r\n return true;\r\n }\r\n\r\n clone() {\r\n const other = new SkinMaterial();\r\n other.copyFrom(this);\r\n return other;\r\n }\r\n\r\n copyFrom(other: this) {\r\n super.copyFrom(other);\r\n this.vertexNormal = other.vertexNormal;\r\n this.vertexTangent = other.vertexTangent;\r\n this.shininess = other.shininess;\r\n this.specularStrength = other.specularStrength;\r\n this.diffuseWrap = other.diffuseWrap;\r\n this.diffuseSoftness = other.diffuseSoftness;\r\n this.scatterWrap = other.scatterWrap;\r\n this.scatterStrength = other.scatterStrength;\r\n this.scatterColor = other.scatterColor;\r\n }\r\n\r\n /** true if vertex normal attribute presents */\r\n get vertexNormal() {\r\n return this.featureUsed<boolean>(SkinMaterial.FEATURE_VERTEX_NORMAL);\r\n }\r\n set vertexNormal(val) {\r\n this.useFeature(SkinMaterial.FEATURE_VERTEX_NORMAL, !!val);\r\n }\r\n\r\n /** true if vertex tangent attribute presents */\r\n get vertexTangent() {\r\n return this.featureUsed<boolean>(SkinMaterial.FEATURE_VERTEX_TANGENT);\r\n }\r\n set vertexTangent(val) {\r\n this.useFeature(SkinMaterial.FEATURE_VERTEX_TANGENT, !!val);\r\n }\r\n\r\n /** Blinn specular exponent. Higher values produce smaller highlights. */\r\n get shininess() {\r\n return this._shininess;\r\n }\r\n set shininess(val) {\r\n const next = Math.max(1, val ?? 1);\r\n if (next !== this._shininess) {\r\n this._shininess = next;\r\n this.uniformChanged();\r\n }\r\n }\r\n\r\n /** Direct specular strength. Keep this restrained for soft skin. */\r\n get specularStrength() {\r\n return this._specularStrength;\r\n }\r\n set specularStrength(val) {\r\n const next = Math.max(0, val ?? 0);\r\n if (next !== this._specularStrength) {\r\n this._specularStrength = next;\r\n this.uniformChanged();\r\n }\r\n }\r\n\r\n /** Wrap amount for visible diffuse lighting. */\r\n get diffuseWrap() {\r\n return this._diffuseWrap;\r\n }\r\n set diffuseWrap(val) {\r\n const next = Math.max(0, val ?? 0);\r\n if (next !== this._diffuseWrap) {\r\n this._diffuseWrap = next;\r\n this.uniformChanged();\r\n }\r\n }\r\n\r\n /** Blend from hard Lambert lighting to wrapped diffuse lighting. */\r\n get diffuseSoftness() {\r\n return this._diffuseSoftness;\r\n }\r\n set diffuseSoftness(val) {\r\n const next = Math.max(0, Math.min(1, val ?? 0));\r\n if (next !== this._diffuseSoftness) {\r\n this._diffuseSoftness = next;\r\n this.uniformChanged();\r\n }\r\n }\r\n\r\n /** Wider wrap used only for the post-process scattering source. */\r\n get scatterWrap() {\r\n return this._scatterWrap;\r\n }\r\n set scatterWrap(val) {\r\n const next = Math.max(0, val ?? 0);\r\n if (next !== this._scatterWrap) {\r\n this._scatterWrap = next;\r\n this.uniformChanged();\r\n }\r\n }\r\n\r\n /** Strength of the multiplier written into the SkinSSS side buffer. */\r\n get scatterStrength() {\r\n return this._scatterStrength;\r\n }\r\n set scatterStrength(val) {\r\n const next = Math.max(0, val ?? 0);\r\n if (next !== this._scatterStrength) {\r\n this._scatterStrength = next;\r\n this.uniformChanged();\r\n }\r\n }\r\n\r\n /** Warm tint for the blurred skin lighting contribution. */\r\n get scatterColor(): Immutable<Vector4> {\r\n return this._scatterColor;\r\n }\r\n set scatterColor(val: Immutable<Vector4>) {\r\n if (!val.equalsTo(this._scatterColor)) {\r\n this._scatterColor.set(val);\r\n this.uniformChanged();\r\n }\r\n }\r\n\r\n vertexShader(scope: PBFunctionScope) {\r\n super.vertexShader(scope);\r\n const pb = scope.$builder;\r\n scope.$l.oPos = ShaderHelper.resolveVertexPosition(scope);\r\n scope.$outputs.worldPos = pb.mul(ShaderHelper.getWorldMatrix(scope), pb.vec4(scope.oPos, 1)).xyz;\r\n ShaderHelper.setClipSpacePosition(\r\n scope,\r\n pb.mul(ShaderHelper.getViewProjectionMatrix(scope), pb.vec4(scope.$outputs.worldPos, 1))\r\n );\r\n if (this.vertexNormal) {\r\n scope.$l.oNorm = ShaderHelper.resolveVertexNormal(scope);\r\n scope.$outputs.wNorm = pb.mul(ShaderHelper.getNormalMatrix(scope), pb.vec4(scope.oNorm, 0)).xyz;\r\n if (this.vertexTangent) {\r\n scope.$l.oTangent = ShaderHelper.resolveVertexTangent(scope);\r\n scope.$outputs.wTangent = pb.mul(\r\n ShaderHelper.getNormalMatrix(scope),\r\n pb.vec4(scope.oTangent.xyz, 0)\r\n ).xyz;\r\n scope.$outputs.wBinormal = pb.mul(\r\n pb.cross(scope.$outputs.wNorm, scope.$outputs.wTangent),\r\n scope.oTangent.w\r\n );\r\n }\r\n }\r\n }\r\n\r\n fragmentShader(scope: PBFunctionScope) {\r\n super.fragmentShader(scope);\r\n const pb = scope.$builder;\r\n const that = this;\r\n if (this.needFragmentColorInput()) {\r\n if (this.drawContext.renderPass!.type === RENDER_PASS_TYPE_LIGHT) {\r\n scope.zSkinShininess = pb.float().uniform(2);\r\n scope.zSkinSpecularStrength = pb.float().uniform(2);\r\n scope.zSkinDiffuseWrap = pb.float().uniform(2);\r\n scope.zSkinDiffuseSoftness = pb.float().uniform(2);\r\n scope.zSkinScatterWrap = pb.float().uniform(2);\r\n scope.zSkinScatterStrength = pb.float().uniform(2);\r\n scope.zSkinScatterColor = pb.vec4().uniform(2);\r\n }\r\n scope.$l.albedo = this.calculateAlbedoColor(scope);\r\n if (this.vertexColor) {\r\n scope.albedo = pb.mul(scope.albedo, this.getVertexColor(scope));\r\n }\r\n if (this.drawContext.renderPass!.type === RENDER_PASS_TYPE_LIGHT) {\r\n const baseLightPass = !this.drawContext.lightBlending;\r\n scope.$l.normal = this.calculateNormal(\r\n scope,\r\n scope.$inputs.worldPos,\r\n scope.$inputs.wNorm,\r\n scope.$inputs.wTangent,\r\n scope.$inputs.wBinormal\r\n );\r\n scope.$l.viewVec = this.calculateViewVector(scope, scope.$inputs.worldPos);\r\n scope.$l.roughness = pb.sqrt(pb.div(2, pb.add(scope.zSkinShininess, 2)));\r\n scope.$l.skinMask = pb.float(1);\r\n scope.$l.skinSoftness = pb.float(0);\r\n if (this.subsurfaceTexture) {\r\n scope.$l.subsurfaceTexel = this.sampleSubsurfaceTexture(scope);\r\n scope.skinMask = pb.clamp(scope.subsurfaceTexel.r, 0, 1);\r\n scope.skinSoftness = pb.clamp(scope.subsurfaceTexel.g, 0, 1);\r\n }\r\n scope.$l.diffuseLighting = pb.vec3(0);\r\n scope.$l.scatterLighting = pb.vec3(0);\r\n scope.$l.specularLighting = pb.vec3(0);\r\n if (this.needCalculateEnvLight() && baseLightPass) {\r\n scope.$l.envDiffuse = this.getEnvLightIrradiance(scope, scope.normal);\r\n scope.diffuseLighting = pb.add(scope.diffuseLighting, scope.envDiffuse);\r\n scope.scatterLighting = pb.add(\r\n scope.scatterLighting,\r\n pb.mul(scope.envDiffuse, pb.add(0.7, pb.mul(scope.skinSoftness, 0.45)))\r\n );\r\n scope.$l.reflectVec = this.calculateReflectionVector(scope, scope.normal, scope.viewVec);\r\n scope.specularLighting = pb.add(\r\n scope.specularLighting,\r\n pb.mul(\r\n this.getEnvLightRadiance(scope, scope.reflectVec, scope.roughness),\r\n scope.zSkinSpecularStrength\r\n )\r\n );\r\n }\r\n this.forEachLight(scope, function (type, posRange, dirCutoff, colorIntensity, extra, shadow) {\r\n this.$l.diffuseScale = pb.float(1);\r\n this.$l.specularScale = pb.float(1);\r\n this.$l.sourceRadiusFactor = pb.float(0);\r\n this.$if(pb.equal(type, LIGHT_TYPE_POINT), function () {\r\n this.diffuseScale = extra.x;\r\n this.specularScale = extra.y;\r\n this.sourceRadiusFactor = pb.div(\r\n extra.z,\r\n pb.max(pb.distance(posRange.xyz, this.$inputs.worldPos), 0.0001)\r\n );\r\n });\r\n this.$l.lightAtten = that.calculateLightAttenuation(\r\n this,\r\n type,\r\n this.$inputs.worldPos,\r\n posRange,\r\n dirCutoff,\r\n extra\r\n );\r\n this.$l.lightDir = that.calculateLightDirection(\r\n this,\r\n type,\r\n this.$inputs.worldPos,\r\n posRange,\r\n dirCutoff\r\n );\r\n this.$l.rawNoL = pb.dot(this.normal, this.lightDir);\r\n this.$l.NoL = pb.clamp(this.rawNoL, 0, 1);\r\n this.$l.NoLWrap = pb.clamp(\r\n pb.div(pb.add(this.rawNoL, this.zSkinDiffuseWrap), pb.add(1, this.zSkinDiffuseWrap)),\r\n 0,\r\n 1\r\n );\r\n this.$l.NoLScatter = pb.clamp(\r\n pb.div(pb.add(this.rawNoL, this.zSkinScatterWrap), pb.add(1, this.zSkinScatterWrap)),\r\n 0,\r\n 1\r\n );\r\n // calculateShadow() samples with implicit derivatives (dpdx); WGSL\r\n // requires the call to stay in uniform control flow, so never wrap\r\n // it in a dynamic branch such as NoLWrap > 0.\r\n this.$l.shadowTerm = shadow\r\n ? that.calculateShadow(this, this.$inputs.worldPos, pb.max(this.NoL, 1e-5))\r\n : pb.float(1);\r\n this.$l.lightColor = pb.mul(colorIntensity.rgb, colorIntensity.a, this.lightAtten, this.shadowTerm);\r\n this.$l.halfVec = pb.normalize(pb.add(this.viewVec, this.lightDir));\r\n this.$l.NoH = pb.clamp(pb.dot(this.normal, this.halfVec), 0, 1);\r\n this.$l.pointShininess = pb.max(\r\n pb.div(this.zSkinShininess, pb.add(1, pb.mul(this.sourceRadiusFactor, 32))),\r\n 1\r\n );\r\n this.$l.hardDiffuse = pb.mul(this.lightColor, this.NoL, this.diffuseScale, 1 / Math.PI);\r\n this.$l.softDiffuse = pb.mul(this.lightColor, this.NoLWrap, this.diffuseScale, 1 / Math.PI);\r\n this.$l.softness = pb.clamp(\r\n pb.add(this.zSkinDiffuseSoftness, pb.mul(this.skinSoftness, 0.35)),\r\n 0,\r\n 1\r\n );\r\n this.diffuseLighting = pb.add(\r\n this.diffuseLighting,\r\n pb.mix(this.hardDiffuse, this.softDiffuse, this.softness)\r\n );\r\n this.scatterLighting = pb.add(\r\n this.scatterLighting,\r\n pb.mul(\r\n this.lightColor,\r\n this.NoLScatter,\r\n pb.add(0.7, pb.mul(this.skinSoftness, 0.55)),\r\n this.diffuseScale,\r\n 1 / Math.PI\r\n )\r\n );\r\n this.$l.specular = pb.mul(\r\n this.lightColor,\r\n pb.pow(this.NoH, this.pointShininess),\r\n this.zSkinSpecularStrength,\r\n this.specularScale,\r\n this.NoLWrap\r\n );\r\n this.specularLighting = pb.add(this.specularLighting, this.specular);\r\n });\r\n scope.$l.litColor = pb.add(pb.mul(scope.albedo.rgb, scope.diffuseLighting), scope.specularLighting);\r\n scope.$l.scatterMultiplier = pb.add(\r\n baseLightPass ? pb.vec3(1) : pb.vec3(0),\r\n pb.mul(\r\n scope.albedo.rgb,\r\n scope.scatterLighting,\r\n scope.zSkinScatterColor.rgb,\r\n scope.zSkinScatterStrength,\r\n pb.add(0.75, pb.mul(scope.skinSoftness, 0.45))\r\n )\r\n );\r\n scope.$l.skinSSS = pb.vec4(scope.scatterMultiplier, scope.skinMask);\r\n if (\r\n this.drawContext.materialFlags &\r\n (MaterialVaryingFlags.SCENE_STORE_ROUGHNESS | MaterialVaryingFlags.SCENE_STORE_NORMAL)\r\n ) {\r\n scope.$l.outRoughness = pb.vec4(\r\n pb.mul(scope.albedo.rgb, pb.sub(1, scope.roughness), scope.zSkinSpecularStrength),\r\n pb.mul(scope.roughness, ShaderHelper.getCameraRoughnessFactor(scope))\r\n );\r\n this.outputFragmentColor(\r\n scope,\r\n scope.$inputs.worldPos,\r\n pb.vec4(scope.litColor, scope.albedo.a),\r\n scope.outRoughness,\r\n pb.vec4(pb.add(pb.mul(scope.normal, 0.5), pb.vec3(0.5)), 1),\r\n undefined,\r\n undefined,\r\n undefined,\r\n undefined,\r\n false,\r\n scope.skinSSS\r\n );\r\n } else {\r\n this.outputFragmentColor(\r\n scope,\r\n scope.$inputs.worldPos,\r\n pb.vec4(scope.litColor, scope.albedo.a),\r\n undefined,\r\n undefined,\r\n undefined,\r\n undefined,\r\n undefined,\r\n undefined,\r\n false,\r\n scope.skinSSS\r\n );\r\n }\r\n } else {\r\n this.outputFragmentColor(scope, scope.$inputs.worldPos, scope.albedo);\r\n }\r\n } else {\r\n this.outputFragmentColor(scope, scope.$inputs.worldPos, null);\r\n }\r\n }\r\n\r\n applyUniformValues(bindGroup: BindGroup, ctx: DrawContext, pass: number) {\r\n super.applyUniformValues(bindGroup, ctx, pass);\r\n if (this.needFragmentColor(ctx) && ctx.renderPass!.type === RENDER_PASS_TYPE_LIGHT) {\r\n bindGroup.setValue('zSkinShininess', this._shininess);\r\n bindGroup.setValue('zSkinSpecularStrength', this._specularStrength);\r\n bindGroup.setValue('zSkinDiffuseWrap', this._diffuseWrap);\r\n bindGroup.setValue('zSkinDiffuseSoftness', this._diffuseSoftness);\r\n bindGroup.setValue('zSkinScatterWrap', this._scatterWrap);\r\n bindGroup.setValue('zSkinScatterStrength', this._scatterStrength);\r\n bindGroup.setValue('zSkinScatterColor', this._scatterColor);\r\n }\r\n }\r\n}\r\n"],"names":["SkinMaterial","applyMaterialMixins","MeshMaterial","mixinLight","mixinVertexColor","mixinTextureProps","FEATURE_VERTEX_NORMAL","defineFeature","FEATURE_VERTEX_TANGENT","_shininess","_specularStrength","_diffuseWrap","_diffuseSoftness","_scatterWrap","_scatterStrength","_scatterColor","Vector4","useFeature","skinSSS","clone","other","copyFrom","vertexNormal","vertexTangent","shininess","specularStrength","diffuseWrap","diffuseSoftness","scatterWrap","scatterStrength","scatterColor","featureUsed","val","next","Math","max","uniformChanged","min","equalsTo","set","vertexShader","scope","pb","$builder","$l","oPos","ShaderHelper","resolveVertexPosition","$outputs","worldPos","mul","getWorldMatrix","vec4","xyz","setClipSpacePosition","getViewProjectionMatrix","oNorm","resolveVertexNormal","wNorm","getNormalMatrix","oTangent","resolveVertexTangent","wTangent","wBinormal","cross","w","fragmentShader","that","needFragmentColorInput","drawContext","renderPass","type","RENDER_PASS_TYPE_LIGHT","zSkinShininess","float","uniform","zSkinSpecularStrength","zSkinDiffuseWrap","zSkinDiffuseSoftness","zSkinScatterWrap","zSkinScatterStrength","zSkinScatterColor","albedo","calculateAlbedoColor","vertexColor","getVertexColor","baseLightPass","lightBlending","normal","calculateNormal","$inputs","viewVec","calculateViewVector","roughness","sqrt","div","add","skinMask","skinSoftness","subsurfaceTexture","subsurfaceTexel","sampleSubsurfaceTexture","clamp","r","g","diffuseLighting","vec3","scatterLighting","specularLighting","needCalculateEnvLight","envDiffuse","getEnvLightIrradiance","reflectVec","calculateReflectionVector","getEnvLightRadiance","forEachLight","posRange","dirCutoff","colorIntensity","extra","shadow","diffuseScale","specularScale","sourceRadiusFactor","$if","equal","LIGHT_TYPE_POINT","x","y","z","distance","lightAtten","calculateLightAttenuation","lightDir","calculateLightDirection","rawNoL","dot","NoL","NoLWrap","NoLScatter","shadowTerm","calculateShadow","lightColor","rgb","a","halfVec","normalize","NoH","pointShininess","hardDiffuse","PI","softDiffuse","softness","mix","specular","pow","litColor","scatterMultiplier","materialFlags","MaterialVaryingFlags","SCENE_STORE_ROUGHNESS","SCENE_STORE_NORMAL","outRoughness","sub","getCameraRoughnessFactor","outputFragmentColor","undefined","applyUniformValues","bindGroup","ctx","pass","needFragmentColor","setValue"],"mappings":"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"}
1
+ {"version":3,"file":"skin.js","sources":["../../src/material/skin.ts"],"sourcesContent":["import type { BindGroup, PBFunctionScope } from '@zephyr3d/device';\r\nimport type { Clonable, Immutable } from '@zephyr3d/base';\r\nimport { Vector4 } from '@zephyr3d/base';\r\nimport { MeshMaterial, applyMaterialMixins } from './meshmaterial';\r\nimport { mixinLight } from './mixins/lit';\r\nimport { mixinVertexColor } from './mixins/vertexcolor';\r\nimport { mixinTextureProps } from './mixins/texture';\r\nimport { ShaderHelper } from './shader/helper';\r\nimport type { DrawContext } from '../render';\r\nimport { LIGHT_TYPE_POINT, MaterialVaryingFlags, RENDER_PASS_TYPE_LIGHT } from '../values';\r\n\r\n/**\r\n * HDR range packed into the SkinSSS side buffer when the render graph falls\r\n * back to an 8-bit format. The material divides the scatter irradiance by this\r\n * factor on write and {@link SkinSSS} multiplies it back after the blur.\r\n * @public\r\n */\r\nexport const SKIN_SSS_LDR_ENCODE_RANGE = 4;\r\n\r\n/**\r\n * Stylized realtime skin material.\r\n *\r\n * @remarks\r\n * This material is designed for the {@link SkinSSS} post effect. It renders a regular lit color\r\n * and, when `camera.skinSSS` is enabled, writes the *diffusible* part of that color - the stylized\r\n * diffuse ramp plus back-lit transmission, without specular - into the `SkinSSSTexture` MRT.\r\n *\r\n * The side buffer holds exactly the same term that is already in the lit color, untinted and\r\n * unscaled. {@link SkinSSS} subtracts it and adds back a channel-dependent diffused version, so\r\n * the redistribution is energy conserving by construction and disabling the effect leaves the\r\n * image unchanged. Scatter tint, strength and radius therefore live on the post effect, not here.\r\n *\r\n * Stylization is split from diffusion on purpose. {@link SkinMaterial.diffuseWrap},\r\n * {@link SkinMaterial.diffuseSoftness}, {@link SkinMaterial.shadowTint} and\r\n * {@link SkinMaterial.brightening} shape the direct lighting ramp; the post effect then diffuses\r\n * whatever ramp they produced. A stylized ramp stays stylized after scattering rather than being\r\n * averaged away.\r\n *\r\n * The optional `subsurfaceTexture` uses R as skin mask, G as local softness and B as thickness\r\n * for the back-lit transmission term (thin regions such as ears and nostrils glow when lit from\r\n * behind; enable it by setting {@link SkinMaterial.transmissionStrength}).\r\n *\r\n * @public\r\n */\r\nexport class SkinMaterial\r\n extends applyMaterialMixins(MeshMaterial, mixinLight, mixinVertexColor, mixinTextureProps('subsurface'))\r\n implements Clonable<SkinMaterial>\r\n{\r\n private static readonly FEATURE_VERTEX_NORMAL = this.defineFeature();\r\n private static readonly FEATURE_VERTEX_TANGENT = this.defineFeature();\r\n private _shininess: number;\r\n private _specularStrength: number;\r\n private _diffuseWrap: number;\r\n private _diffuseSoftness: number;\r\n private _scatterWrap: number;\r\n private _scatterStrength: number;\r\n private readonly _scatterColor: Vector4;\r\n private _transmissionStrength: number;\r\n private _transmissionPower: number;\r\n private readonly _shadowTint: Vector4;\r\n private _brightening: number;\r\n\r\n constructor() {\r\n super();\r\n this._shininess = 72;\r\n this._specularStrength = 1;\r\n this._diffuseWrap = 0.28;\r\n this._diffuseSoftness = 0.45;\r\n this._scatterWrap = 0.65;\r\n this._scatterStrength = 1.5;\r\n this._scatterColor = new Vector4(1, 0.42, 0.28, 1);\r\n this._transmissionStrength = 0;\r\n this._transmissionPower = 4;\r\n this._shadowTint = new Vector4(0, 0, 0, 1);\r\n this._brightening = 0;\r\n this.useFeature(SkinMaterial.FEATURE_VERTEX_NORMAL, true);\r\n }\r\n\r\n /** Marker used by the forward render graph to allocate the SkinSSS MRT. */\r\n get skinSSS() {\r\n return true;\r\n }\r\n\r\n clone() {\r\n const other = new SkinMaterial();\r\n other.copyFrom(this);\r\n return other;\r\n }\r\n\r\n copyFrom(other: this) {\r\n super.copyFrom(other);\r\n this.vertexNormal = other.vertexNormal;\r\n this.vertexTangent = other.vertexTangent;\r\n this.shininess = other.shininess;\r\n this.specularStrength = other.specularStrength;\r\n this.diffuseWrap = other.diffuseWrap;\r\n this.diffuseSoftness = other.diffuseSoftness;\r\n this.scatterWrap = other.scatterWrap;\r\n this.scatterStrength = other.scatterStrength;\r\n this.scatterColor = other.scatterColor;\r\n this.transmissionStrength = other.transmissionStrength;\r\n this.transmissionPower = other.transmissionPower;\r\n this.shadowTint = other.shadowTint;\r\n this.brightening = other.brightening;\r\n }\r\n\r\n /** true if vertex normal attribute presents */\r\n get vertexNormal() {\r\n return this.featureUsed<boolean>(SkinMaterial.FEATURE_VERTEX_NORMAL);\r\n }\r\n set vertexNormal(val) {\r\n this.useFeature(SkinMaterial.FEATURE_VERTEX_NORMAL, !!val);\r\n }\r\n\r\n /** true if vertex tangent attribute presents */\r\n get vertexTangent() {\r\n return this.featureUsed<boolean>(SkinMaterial.FEATURE_VERTEX_TANGENT);\r\n }\r\n set vertexTangent(val) {\r\n this.useFeature(SkinMaterial.FEATURE_VERTEX_TANGENT, !!val);\r\n }\r\n\r\n /** Blinn specular exponent. Higher values produce smaller highlights. */\r\n get shininess() {\r\n return this._shininess;\r\n }\r\n set shininess(val) {\r\n const next = Math.max(1, val ?? 1);\r\n if (next !== this._shininess) {\r\n this._shininess = next;\r\n this.uniformChanged();\r\n }\r\n }\r\n\r\n /** Direct specular strength. Keep this restrained for soft skin. */\r\n get specularStrength() {\r\n return this._specularStrength;\r\n }\r\n set specularStrength(val) {\r\n const next = Math.max(0, val ?? 0);\r\n if (next !== this._specularStrength) {\r\n this._specularStrength = next;\r\n this.uniformChanged();\r\n }\r\n }\r\n\r\n /** Wrap amount for visible diffuse lighting. */\r\n get diffuseWrap() {\r\n return this._diffuseWrap;\r\n }\r\n set diffuseWrap(val) {\r\n const next = Math.max(0, val ?? 0);\r\n if (next !== this._diffuseWrap) {\r\n this._diffuseWrap = next;\r\n this.uniformChanged();\r\n }\r\n }\r\n\r\n /** Blend from hard Lambert lighting to wrapped diffuse lighting. */\r\n get diffuseSoftness() {\r\n return this._diffuseSoftness;\r\n }\r\n set diffuseSoftness(val) {\r\n const next = Math.max(0, Math.min(1, val ?? 0));\r\n if (next !== this._diffuseSoftness) {\r\n this._diffuseSoftness = next;\r\n this.uniformChanged();\r\n }\r\n }\r\n\r\n /**\r\n * Wider wrap that used to shape the post-process scattering source.\r\n *\r\n * @deprecated No longer has any effect. The side buffer now carries the real\r\n * diffuse term rather than a hand-built difference that was nonzero only near\r\n * the terminator, so there is nothing for a second wrap to shape. Use\r\n * {@link SkinSSS.scatterRadius} and the profile's channel radii to control how\r\n * far light travels, and {@link SkinMaterial.diffuseWrap} to shape the ramp.\r\n */\r\n get scatterWrap() {\r\n return this._scatterWrap;\r\n }\r\n set scatterWrap(val) {\r\n const next = Math.max(0, val ?? 0);\r\n if (next !== this._scatterWrap) {\r\n this._scatterWrap = next;\r\n this.uniformChanged();\r\n }\r\n }\r\n\r\n /**\r\n * Strength of the multiplier written into the SkinSSS side buffer.\r\n *\r\n * @deprecated No longer has any effect. Scaling the side buffer would break\r\n * the identity that makes the diffusion energy conserving - it must equal the\r\n * diffusible term already present in the lit color. Use\r\n * {@link SkinSSS.strength} for the overall amount and {@link SkinSSS.glow} for\r\n * an additive, non-conserving bleed on top.\r\n */\r\n get scatterStrength() {\r\n return this._scatterStrength;\r\n }\r\n set scatterStrength(val) {\r\n const next = Math.max(0, val ?? 0);\r\n if (next !== this._scatterStrength) {\r\n this._scatterStrength = next;\r\n this.uniformChanged();\r\n }\r\n }\r\n\r\n /**\r\n * Strength of the back-lit transmission term. Requires a `subsurfaceTexture`\r\n * with thickness in the B channel; 0 (the default) disables transmission.\r\n */\r\n get transmissionStrength() {\r\n return this._transmissionStrength;\r\n }\r\n set transmissionStrength(val) {\r\n const next = Math.max(0, val ?? 0);\r\n if (next !== this._transmissionStrength) {\r\n this._transmissionStrength = next;\r\n this.uniformChanged();\r\n }\r\n }\r\n\r\n /** Exponent of the back-lit transmission falloff. Higher values tighten the glow. */\r\n get transmissionPower() {\r\n return this._transmissionPower;\r\n }\r\n set transmissionPower(val) {\r\n const next = Math.max(1, val ?? 1);\r\n if (next !== this._transmissionPower) {\r\n this._transmissionPower = next;\r\n this.uniformChanged();\r\n }\r\n }\r\n\r\n /**\r\n * Warm tint for the blurred skin lighting contribution.\r\n *\r\n * @deprecated No longer has any effect; moved to {@link SkinSSS.scatterTint}.\r\n * Tinting here would tint the diffuse in the lit color too, which is what made\r\n * the old look read as a red haze over the whole face. On the post effect the\r\n * tint applies only to the light that actually moved, and per-channel scatter\r\n * radii from the profile already produce the red bleed on their own.\r\n */\r\n get scatterColor(): Immutable<Vector4> {\r\n return this._scatterColor;\r\n }\r\n set scatterColor(val: Immutable<Vector4>) {\r\n if (!val.equalsTo(this._scatterColor)) {\r\n this._scatterColor.set(val);\r\n this.uniformChanged();\r\n }\r\n }\r\n\r\n /**\r\n * NPR-style shadow tint: the dark end of the diffuse ramp lifts toward this\r\n * color instead of black (black, the default, reproduces plain wrapped\r\n * lambert). A rosy/lavender tint gives the stylized beauty-shot shadow look.\r\n */\r\n get shadowTint(): Immutable<Vector4> {\r\n return this._shadowTint;\r\n }\r\n set shadowTint(val: Immutable<Vector4>) {\r\n if (!val.equalsTo(this._shadowTint)) {\r\n this._shadowTint.set(val);\r\n this.uniformChanged();\r\n }\r\n }\r\n\r\n /** Whitening gain applied to the whole diffuse response. 0 (the default) is neutral. */\r\n get brightening() {\r\n return this._brightening;\r\n }\r\n set brightening(val) {\r\n const next = Math.max(0, val ?? 0);\r\n if (next !== this._brightening) {\r\n this._brightening = next;\r\n this.uniformChanged();\r\n }\r\n }\r\n\r\n vertexShader(scope: PBFunctionScope) {\r\n super.vertexShader(scope);\r\n const pb = scope.$builder;\r\n scope.$l.oPos = ShaderHelper.resolveVertexPosition(scope);\r\n scope.$outputs.worldPos = pb.mul(ShaderHelper.getWorldMatrix(scope), pb.vec4(scope.oPos, 1)).xyz;\r\n ShaderHelper.setClipSpacePosition(\r\n scope,\r\n pb.mul(ShaderHelper.getViewProjectionMatrix(scope), pb.vec4(scope.$outputs.worldPos, 1))\r\n );\r\n if (this.vertexNormal) {\r\n scope.$l.oNorm = ShaderHelper.resolveVertexNormal(scope);\r\n scope.$outputs.wNorm = pb.mul(ShaderHelper.getNormalMatrix(scope), pb.vec4(scope.oNorm, 0)).xyz;\r\n if (this.vertexTangent) {\r\n scope.$l.oTangent = ShaderHelper.resolveVertexTangent(scope);\r\n scope.$outputs.wTangent = pb.mul(\r\n ShaderHelper.getNormalMatrix(scope),\r\n pb.vec4(scope.oTangent.xyz, 0)\r\n ).xyz;\r\n scope.$outputs.wBinormal = pb.mul(\r\n pb.cross(scope.$outputs.wNorm, scope.$outputs.wTangent),\r\n scope.oTangent.w\r\n );\r\n }\r\n }\r\n }\r\n\r\n fragmentShader(scope: PBFunctionScope) {\r\n super.fragmentShader(scope);\r\n const pb = scope.$builder;\r\n const that = this;\r\n if (this.needFragmentColorInput()) {\r\n if (this.drawContext.renderPass!.type === RENDER_PASS_TYPE_LIGHT) {\r\n scope.zSkinShininess = pb.float().uniform(2);\r\n scope.zSkinSpecularStrength = pb.float().uniform(2);\r\n scope.zSkinDiffuseWrap = pb.float().uniform(2);\r\n scope.zSkinDiffuseSoftness = pb.float().uniform(2);\r\n scope.zSkinShadowTint = pb.vec4().uniform(2);\r\n scope.zSkinBrightening = pb.float().uniform(2);\r\n // Encodes HDR scatter irradiance into the SkinSSS buffer range when the\r\n // render graph falls back to rgba8unorm (see getSSSLightingTextureFormat).\r\n scope.zSkinScatterEncodeScale = pb.float().uniform(2);\r\n if (this.subsurfaceTexture) {\r\n scope.zSkinTransmissionStrength = pb.float().uniform(2);\r\n scope.zSkinTransmissionPower = pb.float().uniform(2);\r\n }\r\n }\r\n scope.$l.albedo = this.calculateAlbedoColor(scope);\r\n if (this.vertexColor) {\r\n scope.albedo = pb.mul(scope.albedo, this.getVertexColor(scope));\r\n }\r\n if (this.drawContext.renderPass!.type === RENDER_PASS_TYPE_LIGHT) {\r\n const baseLightPass = !this.drawContext.lightBlending;\r\n // TBN[2] is the pre-normal-map geometric normal, needed for shadow\r\n // normal offset bias. Feeding the normal mapped shading normal instead\r\n // would displace the shadow lookup along pore detail.\r\n scope.$l.normalInfo = this.calculateNormalAndTBN(\r\n scope,\r\n scope.$inputs.worldPos,\r\n scope.$inputs.wNorm,\r\n scope.$inputs.wTangent,\r\n scope.$inputs.wBinormal\r\n );\r\n scope.$l.normal = scope.normalInfo.normal;\r\n scope.$l.viewVec = this.calculateViewVector(scope, scope.$inputs.worldPos);\r\n scope.$l.roughness = pb.sqrt(pb.div(2, pb.add(scope.zSkinShininess, 2)));\r\n scope.$l.skinMask = pb.float(1);\r\n scope.$l.skinSoftness = pb.float(0);\r\n scope.$l.skinThickness = pb.float(0);\r\n if (this.subsurfaceTexture) {\r\n scope.$l.subsurfaceTexel = this.sampleSubsurfaceTexture(scope);\r\n scope.skinMask = pb.clamp(scope.subsurfaceTexel.r, 0, 1);\r\n scope.skinSoftness = pb.clamp(scope.subsurfaceTexel.g, 0, 1);\r\n scope.skinThickness = pb.clamp(scope.subsurfaceTexel.b, 0, 1);\r\n }\r\n scope.$l.diffuseLighting = pb.vec3(0);\r\n scope.$l.transmissionLighting = pb.vec3(0);\r\n scope.$l.specularLighting = pb.vec3(0);\r\n scope.$l.NoV = pb.clamp(pb.dot(scope.normal, scope.viewVec), 0, 1);\r\n if (this.needCalculateEnvLight() && baseLightPass) {\r\n scope.$l.envDiffuse = this.getEnvLightIrradiance(scope, scope.normal);\r\n scope.diffuseLighting = pb.add(scope.diffuseLighting, scope.envDiffuse);\r\n scope.$l.reflectVec = this.calculateReflectionVector(scope, scope.normal, scope.viewVec);\r\n scope.$l.envFresnel = pb.add(0.028, pb.mul(0.972, pb.pow(pb.sub(1, scope.NoV), 5)));\r\n scope.specularLighting = pb.add(\r\n scope.specularLighting,\r\n pb.mul(\r\n this.getEnvLightRadiance(scope, scope.reflectVec, scope.roughness),\r\n scope.envFresnel,\r\n scope.zSkinSpecularStrength\r\n )\r\n );\r\n }\r\n this.forEachLight(scope, function (type, posRange, dirCutoff, colorIntensity, extra, shadow) {\r\n this.$l.diffuseScale = pb.float(1);\r\n this.$l.specularScale = pb.float(1);\r\n this.$l.sourceRadiusFactor = pb.float(0);\r\n this.$if(pb.equal(type, LIGHT_TYPE_POINT), function () {\r\n this.diffuseScale = extra.x;\r\n this.specularScale = extra.y;\r\n this.sourceRadiusFactor = pb.div(\r\n extra.z,\r\n pb.max(pb.distance(posRange.xyz, this.$inputs.worldPos), 0.0001)\r\n );\r\n });\r\n this.$l.lightAtten = that.calculateLightAttenuation(\r\n this,\r\n type,\r\n this.$inputs.worldPos,\r\n posRange,\r\n dirCutoff,\r\n extra\r\n );\r\n this.$l.lightDir = that.calculateLightDirection(\r\n this,\r\n type,\r\n this.$inputs.worldPos,\r\n posRange,\r\n dirCutoff\r\n );\r\n this.$l.rawNoL = pb.dot(this.normal, this.lightDir);\r\n this.$l.NoL = pb.clamp(this.rawNoL, 0, 1);\r\n this.$l.NoLWrap = pb.clamp(\r\n pb.div(pb.add(this.rawNoL, this.zSkinDiffuseWrap), pb.add(1, this.zSkinDiffuseWrap)),\r\n 0,\r\n 1\r\n );\r\n // calculateShadow() samples with implicit derivatives (dpdx); WGSL\r\n // requires the call to stay in uniform control flow, so never wrap\r\n // it in a dynamic branch such as NoLWrap > 0.\r\n //\r\n // Diffuse and specular share this term unmodified. An earlier version\r\n // faded it toward 1 around the terminator to hide shadow map acne\r\n // there, but that released the shadow in the wrong band (only ~9% at\r\n // NdotL = 0, by which point the acne is at its worst) and made cast\r\n // shadows dissolve wherever a surface turned away from the light.\r\n // Normal offset bias removes the acne at the source instead.\r\n this.$l.shadowTerm = shadow\r\n ? that.calculateShadow(\r\n this,\r\n this.$inputs.worldPos,\r\n scope.normalInfo.TBN[2],\r\n pb.max(this.NoL, 1e-5)\r\n )\r\n : pb.float(1);\r\n this.$l.lightColor = pb.mul(colorIntensity.rgb, colorIntensity.a, this.lightAtten);\r\n this.$l.diffuseLightColor = pb.mul(this.lightColor, this.shadowTerm);\r\n this.$l.halfVec = pb.normalize(pb.add(this.viewVec, this.lightDir));\r\n this.$l.NoH = pb.clamp(pb.dot(this.normal, this.halfVec), 0, 1);\r\n this.$l.LoH = pb.clamp(pb.dot(this.lightDir, this.halfVec), 0, 1);\r\n this.$l.pointShininess = pb.max(\r\n pb.div(this.zSkinShininess, pb.add(1, pb.mul(this.sourceRadiusFactor, 32))),\r\n 1\r\n );\r\n this.$l.softness = pb.clamp(\r\n pb.add(this.zSkinDiffuseSoftness, pb.mul(this.skinSoftness, 0.35)),\r\n 0,\r\n 1\r\n );\r\n this.$l.NoLVis = pb.mix(this.NoL, this.NoLWrap, this.softness);\r\n // NPR-style diffuse ramp: the dark end lifts toward the shadow tint\r\n // instead of black. A black tint reproduces plain wrapped lambert.\r\n this.$l.diffuseRamp = pb.mix(this.zSkinShadowTint.rgb, pb.vec3(1), this.NoLVis);\r\n this.diffuseLighting = pb.add(\r\n this.diffuseLighting,\r\n pb.mul(this.diffuseLightColor, this.diffuseRamp, this.diffuseScale, 1 / Math.PI)\r\n );\r\n if (that.subsurfaceTexture) {\r\n // Back-lit transmission: thin regions (B channel of the subsurface\r\n // texture) glow when the light faces the camera through the\r\n // surface.\r\n //\r\n // This deliberately uses the unshadowed lightColor. A back-lit\r\n // fragment is self-shadowed by definition - its own front face is\r\n // the occluder - so multiplying by the shadow term would cancel\r\n // exactly the case the term exists to model. The cost is that an\r\n // external caster does not block the glow, which a shadow map\r\n // cannot distinguish from self occlusion anyway.\r\n this.$l.transmission = pb.mul(\r\n pb.pow(\r\n pb.clamp(pb.dot(pb.neg(this.lightDir), this.viewVec), 0, 1),\r\n this.zSkinTransmissionPower\r\n ),\r\n this.skinThickness,\r\n this.zSkinTransmissionStrength\r\n );\r\n this.transmissionLighting = pb.add(\r\n this.transmissionLighting,\r\n pb.mul(this.lightColor, this.transmission, this.diffuseScale, 1 / Math.PI)\r\n );\r\n }\r\n // Normalized Blinn with Schlick Fresnel (skin F0 = 0.028). Specular\r\n // keeps the unfaded shadow term and hard NoL masking.\r\n this.$l.specNormalization = pb.div(pb.add(this.pointShininess, 8), 8 * Math.PI);\r\n this.$l.specFresnel = pb.add(0.028, pb.mul(0.972, pb.pow(pb.sub(1, this.LoH), 5)));\r\n this.$l.specular = pb.mul(\r\n this.lightColor,\r\n this.shadowTerm,\r\n pb.pow(this.NoH, this.pointShininess),\r\n this.specNormalization,\r\n this.specFresnel,\r\n this.zSkinSpecularStrength,\r\n this.specularScale,\r\n this.NoL\r\n );\r\n this.specularLighting = pb.add(this.specularLighting, this.specular);\r\n });\r\n // Whitening: lift the whole diffuse response (direct and ambient).\r\n scope.diffuseLighting = pb.mul(scope.diffuseLighting, pb.add(1, scope.zSkinBrightening));\r\n // Everything that scatters through the surface: the stylized diffuse\r\n // ramp plus back-lit transmission. Specular stays out - it reflects off\r\n // the oil layer and never enters the skin.\r\n scope.$l.diffusible = pb.mul(\r\n scope.albedo.rgb,\r\n pb.add(scope.diffuseLighting, scope.transmissionLighting)\r\n );\r\n scope.$l.litColor = pb.add(scope.diffusible, scope.specularLighting);\r\n // The SkinSSS side buffer carries exactly the diffusible term that is\r\n // also in litColor - untinted and unscaled. That identity is what lets\r\n // the post effect subtract it and add back a diffused version, which is\r\n // energy conserving by construction and leaves the image untouched when\r\n // the effect is disabled. Tinting or scaling here would break it; those\r\n // controls live on SkinSSS instead.\r\n //\r\n // Base and additive light passes both write their own contribution; the\r\n // additive blend (RGB one/one, alpha zero/one) accumulates RGB and keeps\r\n // the mask written by the base pass in alpha.\r\n scope.$l.skinSSS = pb.vec4(pb.mul(scope.diffusible, scope.zSkinScatterEncodeScale), scope.skinMask);\r\n if (\r\n this.drawContext.materialFlags &\r\n (MaterialVaryingFlags.SCENE_STORE_ROUGHNESS | MaterialVaryingFlags.SCENE_STORE_NORMAL)\r\n ) {\r\n scope.$l.outRoughness = pb.vec4(\r\n pb.mul(scope.albedo.rgb, pb.sub(1, scope.roughness), scope.zSkinSpecularStrength),\r\n pb.mul(scope.roughness, ShaderHelper.getCameraRoughnessFactor(scope))\r\n );\r\n this.outputFragmentColor(\r\n scope,\r\n scope.$inputs.worldPos,\r\n pb.vec4(scope.litColor, scope.albedo.a),\r\n scope.outRoughness,\r\n pb.vec4(pb.add(pb.mul(scope.normal, 0.5), pb.vec3(0.5)), 1),\r\n undefined,\r\n undefined,\r\n undefined,\r\n undefined,\r\n false,\r\n scope.skinSSS\r\n );\r\n } else {\r\n this.outputFragmentColor(\r\n scope,\r\n scope.$inputs.worldPos,\r\n pb.vec4(scope.litColor, scope.albedo.a),\r\n undefined,\r\n undefined,\r\n undefined,\r\n undefined,\r\n undefined,\r\n undefined,\r\n false,\r\n scope.skinSSS\r\n );\r\n }\r\n } else {\r\n this.outputFragmentColor(scope, scope.$inputs.worldPos, scope.albedo);\r\n }\r\n } else {\r\n this.outputFragmentColor(scope, scope.$inputs.worldPos, null);\r\n }\r\n }\r\n\r\n applyUniformValues(bindGroup: BindGroup, ctx: DrawContext, pass: number) {\r\n super.applyUniformValues(bindGroup, ctx, pass);\r\n if (this.needFragmentColor(ctx) && ctx.renderPass!.type === RENDER_PASS_TYPE_LIGHT) {\r\n bindGroup.setValue('zSkinShininess', this._shininess);\r\n bindGroup.setValue('zSkinSpecularStrength', this._specularStrength);\r\n bindGroup.setValue('zSkinDiffuseWrap', this._diffuseWrap);\r\n bindGroup.setValue('zSkinDiffuseSoftness', this._diffuseSoftness);\r\n bindGroup.setValue('zSkinShadowTint', this._shadowTint);\r\n bindGroup.setValue('zSkinBrightening', this._brightening);\r\n const ldrSkinSSS = ctx.SkinSSSTexture && ctx.SkinSSSTexture.format === 'rgba8unorm';\r\n bindGroup.setValue('zSkinScatterEncodeScale', ldrSkinSSS ? 1 / SKIN_SSS_LDR_ENCODE_RANGE : 1);\r\n if (this.subsurfaceTexture) {\r\n bindGroup.setValue('zSkinTransmissionStrength', this._transmissionStrength);\r\n bindGroup.setValue('zSkinTransmissionPower', this._transmissionPower);\r\n }\r\n }\r\n }\r\n}\r\n"],"names":["SKIN_SSS_LDR_ENCODE_RANGE","SkinMaterial","applyMaterialMixins","MeshMaterial","mixinLight","mixinVertexColor","mixinTextureProps","FEATURE_VERTEX_NORMAL","defineFeature","FEATURE_VERTEX_TANGENT","_shininess","_specularStrength","_diffuseWrap","_diffuseSoftness","_scatterWrap","_scatterStrength","_scatterColor","_transmissionStrength","_transmissionPower","_shadowTint","_brightening","Vector4","useFeature","skinSSS","clone","other","copyFrom","vertexNormal","vertexTangent","shininess","specularStrength","diffuseWrap","diffuseSoftness","scatterWrap","scatterStrength","scatterColor","transmissionStrength","transmissionPower","shadowTint","brightening","featureUsed","val","next","Math","max","uniformChanged","min","equalsTo","set","vertexShader","scope","pb","$builder","$l","oPos","ShaderHelper","resolveVertexPosition","$outputs","worldPos","mul","getWorldMatrix","vec4","xyz","setClipSpacePosition","getViewProjectionMatrix","oNorm","resolveVertexNormal","wNorm","getNormalMatrix","oTangent","resolveVertexTangent","wTangent","wBinormal","cross","w","fragmentShader","that","needFragmentColorInput","drawContext","renderPass","type","RENDER_PASS_TYPE_LIGHT","zSkinShininess","float","uniform","zSkinSpecularStrength","zSkinDiffuseWrap","zSkinDiffuseSoftness","zSkinShadowTint","zSkinBrightening","zSkinScatterEncodeScale","subsurfaceTexture","zSkinTransmissionStrength","zSkinTransmissionPower","albedo","calculateAlbedoColor","vertexColor","getVertexColor","baseLightPass","lightBlending","normalInfo","calculateNormalAndTBN","$inputs","normal","viewVec","calculateViewVector","roughness","sqrt","div","add","skinMask","skinSoftness","skinThickness","subsurfaceTexel","sampleSubsurfaceTexture","clamp","r","g","b","diffuseLighting","vec3","transmissionLighting","specularLighting","NoV","dot","needCalculateEnvLight","envDiffuse","getEnvLightIrradiance","reflectVec","calculateReflectionVector","envFresnel","pow","sub","getEnvLightRadiance","forEachLight","posRange","dirCutoff","colorIntensity","extra","shadow","diffuseScale","specularScale","sourceRadiusFactor","$if","equal","LIGHT_TYPE_POINT","x","y","z","distance","lightAtten","calculateLightAttenuation","lightDir","calculateLightDirection","rawNoL","NoL","NoLWrap","shadowTerm","calculateShadow","TBN","lightColor","rgb","a","diffuseLightColor","halfVec","normalize","NoH","LoH","pointShininess","softness","NoLVis","mix","diffuseRamp","PI","transmission","neg","specNormalization","specFresnel","specular","diffusible","litColor","materialFlags","MaterialVaryingFlags","SCENE_STORE_ROUGHNESS","SCENE_STORE_NORMAL","outRoughness","getCameraRoughnessFactor","outputFragmentColor","undefined","applyUniformValues","bindGroup","ctx","pass","needFragmentColor","setValue","ldrSkinSSS","SkinSSSTexture","format"],"mappings":"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"}