@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
@@ -1 +1 @@
1
- {"version":3,"file":"skinsss.js","sources":["../../src/posteffect/skinsss.ts"],"sourcesContent":["import { DEPTH_FARTHEST, Vector2, Vector4 } from '@zephyr3d/base';\r\nimport type { BindGroup, GPUProgram, Texture2D } from '@zephyr3d/device';\r\nimport type { DrawContext } from '../render';\r\nimport { ShaderHelper } from '../material';\r\nimport { linearToGamma } from '../shaders/misc';\r\nimport { fetchSampler } from '../utility/misc';\r\nimport { AbstractPostEffect, PostEffectLayer } from './posteffect';\r\n\r\n/**\r\n * Stylized screen-space skin scattering pass.\r\n *\r\n * @remarks\r\n * This is intentionally separate from the profile-based {@link SSS} pass. It follows the simpler\r\n * depth-aware blur used by many character renderers: a skin material writes a lighting multiplier\r\n * into a side buffer, then this pass performs a fixed 9x9 depth-aware blur and composites it back\r\n * over the opaque color.\r\n *\r\n * @public\r\n */\r\nexport class SkinSSS extends AbstractPostEffect {\r\n private static _program: GPUProgram | null = null;\r\n private _bindGroup: BindGroup | null;\r\n private _strength: number;\r\n private _opacity: number;\r\n private _sampleStep: number;\r\n private _depthScale: number;\r\n private _colorBoost: number;\r\n\r\n constructor() {\r\n super();\r\n this._layer = PostEffectLayer.opaque;\r\n this._bindGroup = null;\r\n this._strength = 1;\r\n this._opacity = 0.18;\r\n this._sampleStep = 2;\r\n this._depthScale = 80;\r\n this._colorBoost = 1;\r\n }\r\n\r\n /** Final blend strength. */\r\n get strength() {\r\n return this._strength;\r\n }\r\n set strength(val) {\r\n this._strength = Math.max(0, val ?? 0);\r\n }\r\n\r\n /** Bias subtracted from the blurred skin mask before compositing. */\r\n get opacity() {\r\n return this._opacity;\r\n }\r\n set opacity(val) {\r\n this._opacity = Math.max(0, Math.min(1, val ?? 0));\r\n }\r\n\r\n /** Pixel spacing between blur taps. The reference shader uses 2. */\r\n get sampleStep() {\r\n return this._sampleStep;\r\n }\r\n set sampleStep(val) {\r\n this._sampleStep = Math.max(0.25, val ?? 0.25);\r\n }\r\n\r\n /** Depth rejection scale. The reference shader uses 80. */\r\n get depthScale() {\r\n return this._depthScale;\r\n }\r\n set depthScale(val) {\r\n this._depthScale = Math.max(0, val ?? 0);\r\n }\r\n\r\n /** Multiplier applied to the blurred skin lighting multiplier before compositing. */\r\n get colorBoost() {\r\n return this._colorBoost;\r\n }\r\n set colorBoost(val) {\r\n this._colorBoost = Math.max(0, val ?? 0);\r\n }\r\n\r\n requireLinearDepthTexture() {\r\n return true;\r\n }\r\n\r\n apply(ctx: DrawContext, inputColorTexture: Texture2D, sceneDepthTexture: Texture2D, srgbOutput: boolean) {\r\n if (!ctx.SkinSSSTexture || this._strength <= 0) {\r\n this.passThrough(ctx, inputColorTexture, srgbOutput);\r\n return;\r\n }\r\n const device = ctx.device;\r\n let program = SkinSSS._program;\r\n if (!program) {\r\n program = this.createProgram(ctx);\r\n SkinSSS._program = program;\r\n }\r\n if (!this._bindGroup) {\r\n this._bindGroup = device.createBindGroup(program.bindGroupLayouts[0]);\r\n }\r\n this._bindGroup.setTexture('colorTex', inputColorTexture, fetchSampler('clamp_linear'));\r\n this._bindGroup.setTexture('skinTex', ctx.SkinSSSTexture, fetchSampler('clamp_linear'));\r\n this._bindGroup.setTexture('depthTex', sceneDepthTexture, fetchSampler('clamp_nearest_nomip'));\r\n this._bindGroup.setValue(\r\n 'cameraNearFar',\r\n new Vector2(ctx.camera.getNearPlane(), ctx.camera.getFarPlane())\r\n );\r\n this._bindGroup.setValue(\r\n 'targetSize',\r\n new Vector4(\r\n inputColorTexture.width,\r\n inputColorTexture.height,\r\n inputColorTexture.width,\r\n inputColorTexture.height\r\n )\r\n );\r\n this._bindGroup.setValue('strength', this._strength);\r\n this._bindGroup.setValue('opacity', this._opacity);\r\n this._bindGroup.setValue('sampleStep', this._sampleStep);\r\n this._bindGroup.setValue('depthScale', this._depthScale);\r\n this._bindGroup.setValue('colorBoost', this._colorBoost);\r\n this._bindGroup.setValue('flip', this.needFlip(device) ? 1 : 0);\r\n this._bindGroup.setValue('srgbOut', srgbOutput ? 1 : 0);\r\n device.setProgram(program);\r\n device.setBindGroup(0, this._bindGroup);\r\n this.drawFullscreenQuad();\r\n }\r\n\r\n private createProgram(ctx: DrawContext) {\r\n const program = ctx.device.buildRenderProgram({\r\n vertex(pb) {\r\n this.flip = pb.int().uniform(0);\r\n this.$inputs.pos = pb.vec2().attrib('position');\r\n this.$outputs.uv = pb.vec2();\r\n pb.main(function () {\r\n this.$builtins.position = pb.vec4(this.$inputs.pos, DEPTH_FARTHEST, 1);\r\n this.$outputs.uv = pb.add(pb.mul(this.$inputs.pos.xy, 0.5), pb.vec2(0.5));\r\n this.$if(pb.notEqual(this.flip, 0), function () {\r\n this.$builtins.position.y = pb.neg(this.$builtins.position.y);\r\n });\r\n });\r\n },\r\n fragment(pb) {\r\n this.colorTex = pb.tex2D().uniform(0);\r\n this.skinTex = pb.tex2D().uniform(0);\r\n this.depthTex = pb.tex2D().sampleType('unfilterable-float').uniform(0);\r\n this.cameraNearFar = pb.vec2().uniform(0);\r\n this.targetSize = pb.vec4().uniform(0);\r\n this.strength = pb.float().uniform(0);\r\n this.opacity = pb.float().uniform(0);\r\n this.sampleStep = pb.float().uniform(0);\r\n this.depthScale = pb.float().uniform(0);\r\n this.colorBoost = pb.float().uniform(0);\r\n this.srgbOut = pb.int().uniform(0);\r\n this.$outputs.outColor = pb.vec4();\r\n pb.func('readDepth01', [pb.vec2('uv')], function () {\r\n this.$return(ShaderHelper.sampleLinearDepth(this, this.depthTex, this.uv, 0));\r\n });\r\n pb.main(function () {\r\n this.$l.uv = this.$inputs.uv;\r\n this.$l.baseColor = pb.textureSampleLevel(this.colorTex, this.uv, 0);\r\n this.$l.result = this.baseColor.rgb;\r\n this.$l.centerDepth01 = this.readDepth01(this.uv);\r\n this.$if(pb.lessThan(this.centerDepth01, 1), function () {\r\n this.$l.centerDepth = pb.max(pb.mul(this.centerDepth01, this.cameraNearFar.y), 1e-4);\r\n this.$l.sum = pb.vec4(0);\r\n this.$l.weightSum = pb.float(0);\r\n this.$for(pb.int('y'), -4, 5, function () {\r\n this.$for(pb.int('x'), -4, 5, function () {\r\n this.$l.offsetPx = pb.mul(pb.vec2(pb.float(this.x), pb.float(this.y)), this.sampleStep);\r\n this.$l.sampleUV = pb.clamp(\r\n pb.add(this.uv, pb.div(this.offsetPx, this.targetSize.xy)),\r\n pb.vec2(0),\r\n pb.vec2(1)\r\n );\r\n this.$l.skinSample = pb.textureSampleLevel(this.skinTex, this.sampleUV, 0);\r\n this.$if(pb.lessThanEqual(this.skinSample.a, 1e-4), function () {\r\n this.skinSample = pb.vec4(0, 0, 0, this.opacity);\r\n });\r\n this.$l.sampleDepth01 = this.readDepth01(this.sampleUV);\r\n this.$l.sampleDepth = pb.max(pb.mul(this.sampleDepth01, this.cameraNearFar.y), 1e-4);\r\n this.$l.depthWeight = pb.clamp(\r\n pb.sub(\r\n 1,\r\n pb.div(\r\n pb.mul(pb.abs(pb.sub(this.centerDepth, this.sampleDepth)), this.depthScale),\r\n this.centerDepth\r\n )\r\n ),\r\n 0,\r\n 1\r\n );\r\n this.depthWeight = pb.mul(\r\n this.depthWeight,\r\n this.depthWeight,\r\n pb.sub(3, pb.mul(this.depthWeight, 2))\r\n );\r\n this.sum = pb.add(this.sum, pb.mul(this.skinSample, this.depthWeight));\r\n this.weightSum = pb.add(this.weightSum, this.depthWeight);\r\n });\r\n });\r\n this.$if(pb.greaterThan(this.weightSum, 1e-4), function () {\r\n this.$l.blurredSkin = pb.div(this.sum, this.weightSum);\r\n this.$l.alphaDelta = pb.sub(this.blurredSkin.a, this.opacity);\r\n this.$l.referenceLit = pb.mul(\r\n this.baseColor.rgb,\r\n pb.add(\r\n pb.vec3(pb.sub(1, this.alphaDelta)),\r\n pb.mul(this.blurredSkin.rgb, pb.max(pb.sub(1, this.opacity), 0), this.colorBoost)\r\n )\r\n );\r\n this.result = pb.add(\r\n this.baseColor.rgb,\r\n pb.mul(pb.sub(this.referenceLit, this.baseColor.rgb), this.strength)\r\n );\r\n });\r\n });\r\n this.$if(pb.equal(this.srgbOut, 0), function () {\r\n this.$outputs.outColor = pb.vec4(this.result, this.baseColor.a);\r\n }).$else(function () {\r\n this.$outputs.outColor = pb.vec4(linearToGamma(this, this.result), this.baseColor.a);\r\n });\r\n });\r\n }\r\n })!;\r\n program.name = '@SkinSSS';\r\n return program;\r\n }\r\n}\r\n"],"names":["SkinSSS","AbstractPostEffect","_program","_bindGroup","_strength","_opacity","_sampleStep","_depthScale","_colorBoost","_layer","PostEffectLayer","opaque","strength","val","Math","max","opacity","min","sampleStep","depthScale","colorBoost","requireLinearDepthTexture","apply","ctx","inputColorTexture","sceneDepthTexture","srgbOutput","SkinSSSTexture","passThrough","device","program","createProgram","createBindGroup","bindGroupLayouts","setTexture","fetchSampler","setValue","Vector2","camera","getNearPlane","getFarPlane","Vector4","width","height","needFlip","setProgram","setBindGroup","drawFullscreenQuad","buildRenderProgram","vertex","pb","flip","int","uniform","$inputs","pos","vec2","attrib","$outputs","uv","main","$builtins","position","vec4","DEPTH_FARTHEST","add","mul","xy","$if","notEqual","y","neg","fragment","colorTex","tex2D","skinTex","depthTex","sampleType","cameraNearFar","targetSize","float","srgbOut","outColor","func","$return","ShaderHelper","sampleLinearDepth","$l","baseColor","textureSampleLevel","result","rgb","centerDepth01","readDepth01","lessThan","centerDepth","sum","weightSum","$for","offsetPx","x","sampleUV","clamp","div","skinSample","lessThanEqual","a","sampleDepth01","sampleDepth","depthWeight","sub","abs","greaterThan","blurredSkin","alphaDelta","referenceLit","vec3","equal","$else","linearToGamma","name"],"mappings":"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"}
1
+ {"version":3,"file":"skinsss.js","sources":["../../src/posteffect/skinsss.ts"],"sourcesContent":["import { DEPTH_FARTHEST, Vector2, Vector3, Vector4 } from '@zephyr3d/base';\r\nimport type { BindGroup, GPUProgram, Texture2D } from '@zephyr3d/device';\r\nimport type { DrawContext } from '../render';\r\nimport { ShaderHelper } from '../material';\r\nimport { SKIN_SSS_LDR_ENCODE_RANGE } from '../material/skin';\r\nimport { SubsurfaceProfile } from '../material/subsurfaceprofile';\r\nimport { burleyDiffusionWeight } from '../shaders/diffusion';\r\nimport { linearToGamma } from '../shaders/misc';\r\nimport { fetchSampler } from '../utility/misc';\r\nimport { AbstractPostEffect, PostEffectLayer } from './posteffect';\r\n\r\n/** Taps per side of the separable kernel. The full kernel is `2 * TAPS + 1` wide. */\r\nconst SKIN_SSS_TAPS = 8;\r\n\r\n/**\r\n * Stylized screen-space skin scattering pass.\r\n *\r\n * @remarks\r\n * {@link SkinMaterial} writes the diffusible part of its lit color - the stylized diffuse ramp\r\n * plus back-lit transmission, without specular - into a side buffer. This pass diffuses that\r\n * buffer with a channel-dependent kernel and swaps it back in:\r\n *\r\n * ```\r\n * result = base + (diffused - original) * scatterTint * strength + diffused * glow\r\n * ```\r\n *\r\n * Because the term added back replaces exactly the term subtracted, the redistribution is energy\r\n * conserving: light that appears on the dark side of the terminator is light that left the lit\r\n * side, rather than light invented on top of a finished image. With `scatterTint` white and\r\n * `glow` zero the total radiance is preserved to within the kernel's normalization error.\r\n *\r\n * Two things follow from that formulation and are worth knowing:\r\n *\r\n * - Nothing happens where the diffusion changes nothing, so a disabled or zero-radius pass is a\r\n * true no-op, and quantization from an 8-bit side buffer largely cancels between the subtracted\r\n * and added terms instead of banding across the whole face.\r\n * - `scatterTint` colors only the light that actually moved. Tinting the whole diffuse - what the\r\n * material used to do with `scatterColor` - is what made the old look read as red haze.\r\n *\r\n * Stylization survives in two places. The material owns the direct lighting ramp (wrap, softness,\r\n * shadow tint, brightening) and this pass diffuses whatever ramp it produced; and {@link profile}\r\n * selects the channel radii, so the `wax` and `jade` presets are as reachable as `skin`.\r\n *\r\n * This is intentionally separate from the profile-based {@link SSS} pass, which supports per-pixel\r\n * profiles via a profile-slot MRT. Here a single global profile lives in uniforms.\r\n *\r\n * @public\r\n */\r\nexport class SkinSSS extends AbstractPostEffect {\r\n private static _blurProgram: GPUProgram | null = null;\r\n private static _combineProgram: GPUProgram | null = null;\r\n private _blurBindGroupH: BindGroup | null;\r\n private _blurBindGroupV: BindGroup | null;\r\n private _combineBindGroup: BindGroup | null;\r\n private _profile: SubsurfaceProfile | null;\r\n private _strength: number;\r\n private _glow: number;\r\n private _opacity: number;\r\n private _sampleStep: number;\r\n private _depthScale: number;\r\n private _colorBoost: number;\r\n private _scatterRadius: number;\r\n private _smoothness: number;\r\n private readonly _scatterTint: Vector4;\r\n private readonly _channelRadius: Vector3;\r\n private readonly _channelFalloff: Vector3;\r\n private readonly _blurDirection: Vector2;\r\n private readonly _radiusParams: Vector4;\r\n private readonly _targetSize: Vector4;\r\n private readonly _cameraNearFar: Vector2;\r\n\r\n constructor() {\r\n super();\r\n this._layer = PostEffectLayer.opaque;\r\n this._blurBindGroupH = null;\r\n this._blurBindGroupV = null;\r\n this._combineBindGroup = null;\r\n this._profile = null;\r\n this._strength = 1;\r\n this._glow = 0;\r\n this._opacity = 0.18;\r\n this._sampleStep = 3;\r\n this._depthScale = 80;\r\n this._colorBoost = 1;\r\n this._scatterRadius = 0.02;\r\n this._smoothness = 0;\r\n this._scatterTint = new Vector4(1, 1, 1, 1);\r\n this._channelRadius = new Vector3(1, 1, 1);\r\n this._channelFalloff = new Vector3(1, 1, 1);\r\n this._blurDirection = new Vector2();\r\n this._radiusParams = new Vector4();\r\n this._targetSize = new Vector4();\r\n this._cameraNearFar = new Vector2();\r\n }\r\n\r\n /**\r\n * Subsurface profile supplying the per-channel scatter radii and falloff.\r\n *\r\n * @remarks\r\n * Defaults to {@link SubsurfaceProfile.getDefaultSkinProfile} when unset. Only the channel\r\n * ratios of `scatterRadius` and the `falloffColor` are read; the absolute distance comes from\r\n * {@link SkinSSS.scatterRadius}, so switching profiles changes the color of the bleed without\r\n * changing how far it reaches.\r\n *\r\n * The channel ratios are what make skin read as skin - red travels several times further than\r\n * blue, which is the red-to-orange-to-yellow gradient at the terminator. They are also the main\r\n * stylization lever: the `wax` and `jade` presets are the same code path with different ratios.\r\n */\r\n get profile(): SubsurfaceProfile | null {\r\n return this._profile;\r\n }\r\n set profile(val: SubsurfaceProfile | null) {\r\n this._profile = val ?? null;\r\n }\r\n\r\n /** Final blend strength of the conserving redistribution. 1 fully diffuses the skin diffuse. */\r\n get strength() {\r\n return this._strength;\r\n }\r\n set strength(val) {\r\n this._strength = Math.max(0, val ?? 0);\r\n }\r\n\r\n /**\r\n * Additive, deliberately non-conserving bleed layered on top of the conserving result.\r\n *\r\n * @remarks\r\n * 0 (the default) keeps the pass energy conserving. Raising it adds the diffused term a second\r\n * time without subtracting anything, which is the glow-heavy look the pass produced before it\r\n * conserved energy; around 1 approximates it. Use it when the art direction wants skin to read\r\n * as lit from within rather than as a physical surface.\r\n */\r\n get glow() {\r\n return this._glow;\r\n }\r\n set glow(val) {\r\n this._glow = Math.max(0, val ?? 0);\r\n }\r\n\r\n /**\r\n * Tint applied to the redistributed light.\r\n *\r\n * @remarks\r\n * White (the default) leaves the pass energy conserving. A warm tint pushes the classic reddish\r\n * terminator further than the profile's channel radii do on their own. Because it multiplies\r\n * only the difference between the diffused and original diffuse, it cannot wash the whole\r\n * surface - only the light that moved.\r\n */\r\n get scatterTint(): Vector4 {\r\n return this._scatterTint;\r\n }\r\n set scatterTint(val: Vector4) {\r\n this._scatterTint.set(val);\r\n }\r\n\r\n /** Skin mask coverage threshold. Scattering fades in as the blurred mask coverage exceeds this. */\r\n get opacity() {\r\n return this._opacity;\r\n }\r\n set opacity(val) {\r\n this._opacity = Math.max(0, Math.min(1, val ?? 0));\r\n }\r\n\r\n /**\r\n * Maximum pixel spacing between blur taps. Caps the projected scatter radius for close-ups.\r\n *\r\n * @remarks\r\n * With `SKIN_SSS_TAPS` taps per side the kernel reaches `sampleStep * SKIN_SSS_TAPS` pixels, so\r\n * this is the real limit on scatter width. The separable form makes taps cheap enough that the\r\n * default no longer has to be tight: the old single-pass 9x9 kernel capped out at 8 pixels, and\r\n * a face in close-up projects a 2 cm scatter radius far past that - the shot that needs the most\r\n * scattering used to get the least.\r\n */\r\n get sampleStep() {\r\n return this._sampleStep;\r\n }\r\n set sampleStep(val) {\r\n this._sampleStep = Math.max(0.25, Math.min(6, val ?? 0.25));\r\n }\r\n\r\n /** World-space scatter radius. The blur width shrinks with distance to keep this constant. */\r\n get scatterRadius() {\r\n return this._scatterRadius;\r\n }\r\n set scatterRadius(val) {\r\n this._scatterRadius = Math.max(0, val ?? 0);\r\n }\r\n\r\n /**\r\n * Skin smoothing amount (\"beauty filter\"). Blends the lit color toward a mask- and depth-weighted\r\n * blur of itself on skin pixels, removing pore and albedo detail while facial features stay sharp\r\n * wherever the skin mask excludes them (eyes, brows, lips). 0 disables smoothing.\r\n *\r\n * @remarks\r\n * This is separate from the diffusion and stacks on top of it. The diffusion blurs *lighting*\r\n * only; albedo detail such as pores and blemishes passes through it untouched, which is correct\r\n * but is not what a beauty filter is for.\r\n */\r\n get smoothness() {\r\n return this._smoothness;\r\n }\r\n set smoothness(val) {\r\n this._smoothness = Math.max(0, Math.min(1, val ?? 0));\r\n }\r\n\r\n /** Depth rejection scale. The reference shader uses 80. */\r\n get depthScale() {\r\n return this._depthScale;\r\n }\r\n set depthScale(val) {\r\n this._depthScale = Math.max(0, val ?? 0);\r\n }\r\n\r\n /** Multiplier applied to the diffused irradiance before compositing. */\r\n get colorBoost() {\r\n return this._colorBoost;\r\n }\r\n set colorBoost(val) {\r\n this._colorBoost = Math.max(0, val ?? 0);\r\n }\r\n\r\n requireLinearDepthTexture() {\r\n return true;\r\n }\r\n\r\n apply(ctx: DrawContext, inputColorTexture: Texture2D, sceneDepthTexture: Texture2D, srgbOutput: boolean) {\r\n if (!ctx.SkinSSSTexture || this._strength <= 0) {\r\n this.passThrough(ctx, inputColorTexture, srgbOutput);\r\n return;\r\n }\r\n const device = ctx.device;\r\n const outputFramebuffer = device.getFramebuffer();\r\n const skinTex = ctx.SkinSSSTexture;\r\n if (!SkinSSS._blurProgram) {\r\n SkinSSS._blurProgram = this.createBlurProgram(ctx);\r\n }\r\n if (!SkinSSS._combineProgram) {\r\n SkinSSS._combineProgram = this.createCombineProgram(ctx);\r\n }\r\n const blurProgram = SkinSSS._blurProgram;\r\n const combineProgram = SkinSSS._combineProgram;\r\n if (!this._blurBindGroupH) {\r\n // Two bind groups rather than one program per direction: the only thing\r\n // that differs is the step vector, and rewriting it between draws would\r\n // race the first draw's read of it.\r\n this._blurBindGroupH = device.createBindGroup(blurProgram.bindGroupLayouts[0]);\r\n this._blurBindGroupV = device.createBindGroup(blurProgram.bindGroupLayouts[0]);\r\n }\r\n if (!this._combineBindGroup) {\r\n this._combineBindGroup = device.createBindGroup(combineProgram.bindGroupLayouts[0]);\r\n }\r\n\r\n const profile = this._profile ?? SubsurfaceProfile.getDefaultSkinProfile();\r\n const radius = profile.scatterRadius;\r\n const maxChannel = Math.max(radius.x, radius.y, radius.z, 1e-5);\r\n this._channelRadius.setXYZ(radius.x / maxChannel, radius.y / maxChannel, radius.z / maxChannel);\r\n const falloff = profile.falloffColor;\r\n this._channelFalloff.setXYZ(falloff.x, falloff.y, falloff.z);\r\n\r\n // Pixels per world unit at unit view depth. The shader divides by view depth\r\n // so the footprint stays a constant world-space radius.\r\n const projScale = 0.5 * inputColorTexture.height * ctx.camera.getProjectionMatrix().m11;\r\n this._radiusParams.setXYZW(\r\n this._scatterRadius * projScale,\r\n ctx.camera.isPerspective() ? 1 : 0,\r\n this._sampleStep,\r\n this._depthScale\r\n );\r\n this._targetSize.setXYZW(\r\n inputColorTexture.width,\r\n inputColorTexture.height,\r\n 1 / inputColorTexture.width,\r\n 1 / inputColorTexture.height\r\n );\r\n this._cameraNearFar.setXY(ctx.camera.getNearPlane(), ctx.camera.getFarPlane());\r\n const encodeScale = skinTex.format === 'rgba8unorm' ? SKIN_SSS_LDR_ENCODE_RANGE : 1;\r\n\r\n const blurH = device.pool.fetchTemporalFramebuffer(\r\n false,\r\n skinTex.width,\r\n skinTex.height,\r\n skinTex.format,\r\n null,\r\n false\r\n );\r\n const blurV = device.pool.fetchTemporalFramebuffer(\r\n false,\r\n skinTex.width,\r\n skinTex.height,\r\n skinTex.format,\r\n null,\r\n false\r\n );\r\n\r\n device.setFramebuffer(blurH);\r\n this.blur(ctx, blurProgram, this._blurBindGroupH!, skinTex, sceneDepthTexture, true);\r\n device.setFramebuffer(blurV);\r\n this.blur(\r\n ctx,\r\n blurProgram,\r\n this._blurBindGroupV!,\r\n blurH.getColorAttachments()[0] as Texture2D,\r\n sceneDepthTexture,\r\n false\r\n );\r\n\r\n device.setFramebuffer(outputFramebuffer);\r\n this.combine(\r\n ctx,\r\n combineProgram,\r\n inputColorTexture,\r\n skinTex,\r\n blurV.getColorAttachments()[0] as Texture2D,\r\n sceneDepthTexture,\r\n encodeScale,\r\n srgbOutput\r\n );\r\n\r\n device.pool.releaseFrameBuffer(blurH);\r\n device.pool.releaseFrameBuffer(blurV);\r\n }\r\n\r\n private blur(\r\n ctx: DrawContext,\r\n program: GPUProgram,\r\n bindGroup: BindGroup,\r\n source: Texture2D,\r\n sceneDepthTexture: Texture2D,\r\n horizontal: boolean\r\n ) {\r\n const device = ctx.device;\r\n this._blurDirection.setXY(horizontal ? 1 : 0, horizontal ? 0 : 1);\r\n bindGroup.setTexture('skinTex', source, fetchSampler('clamp_linear'));\r\n bindGroup.setTexture('depthTex', sceneDepthTexture, fetchSampler('clamp_nearest_nomip'));\r\n bindGroup.setValue('cameraNearFar', this._cameraNearFar);\r\n bindGroup.setValue('targetSize', this._targetSize);\r\n bindGroup.setValue('radiusParams', this._radiusParams);\r\n bindGroup.setValue('channelRadius', this._channelRadius);\r\n bindGroup.setValue('channelFalloff', this._channelFalloff);\r\n bindGroup.setValue('blurDirection', this._blurDirection);\r\n bindGroup.setValue('flip', 0);\r\n device.setProgram(program);\r\n device.setBindGroup(0, bindGroup);\r\n this.drawFullscreenQuad();\r\n }\r\n\r\n private combine(\r\n ctx: DrawContext,\r\n program: GPUProgram,\r\n colorTexture: Texture2D,\r\n skinTexture: Texture2D,\r\n blurredTexture: Texture2D,\r\n sceneDepthTexture: Texture2D,\r\n encodeScale: number,\r\n srgbOutput: boolean\r\n ) {\r\n const device = ctx.device;\r\n const bindGroup = this._combineBindGroup!;\r\n bindGroup.setTexture('colorTex', colorTexture, fetchSampler('clamp_linear'));\r\n bindGroup.setTexture('skinTex', skinTexture, fetchSampler('clamp_linear'));\r\n bindGroup.setTexture('blurredTex', blurredTexture, fetchSampler('clamp_linear'));\r\n bindGroup.setTexture('depthTex', sceneDepthTexture, fetchSampler('clamp_nearest_nomip'));\r\n bindGroup.setValue('cameraNearFar', this._cameraNearFar);\r\n bindGroup.setValue('targetSize', this._targetSize);\r\n bindGroup.setValue('radiusParams', this._radiusParams);\r\n bindGroup.setValue('scatterTint', this._scatterTint);\r\n bindGroup.setValue('strength', this._strength);\r\n bindGroup.setValue('glow', this._glow);\r\n bindGroup.setValue('opacity', this._opacity);\r\n bindGroup.setValue('colorBoost', this._colorBoost);\r\n bindGroup.setValue('encodeScale', encodeScale);\r\n bindGroup.setValue('smoothness', this._smoothness);\r\n bindGroup.setValue('flip', this.needFlip(device) ? 1 : 0);\r\n bindGroup.setValue('srgbOut', srgbOutput ? 1 : 0);\r\n device.setProgram(program);\r\n device.setBindGroup(0, bindGroup);\r\n this.drawFullscreenQuad();\r\n }\r\n\r\n /** Shared fullscreen vertex stage for both passes. */\r\n private static fullscreenVertex(pb: any) {\r\n pb.getGlobalScope().flip = pb.int().uniform(0);\r\n pb.getGlobalScope().$inputs.pos = pb.vec2().attrib('position');\r\n pb.getGlobalScope().$outputs.uv = pb.vec2();\r\n pb.main(function (this: any) {\r\n this.$builtins.position = pb.vec4(this.$inputs.pos, DEPTH_FARTHEST, 1);\r\n this.$outputs.uv = pb.add(pb.mul(this.$inputs.pos.xy, 0.5), pb.vec2(0.5));\r\n this.$if(pb.notEqual(this.flip, 0), function (this: any) {\r\n this.$builtins.position.y = pb.neg(this.$builtins.position.y);\r\n });\r\n });\r\n }\r\n\r\n private createBlurProgram(ctx: DrawContext) {\r\n const program = ctx.device.buildRenderProgram({\r\n vertex(pb) {\r\n SkinSSS.fullscreenVertex(pb);\r\n },\r\n fragment(pb) {\r\n this.skinTex = pb.tex2D().uniform(0);\r\n this.depthTex = pb.tex2D().sampleType('unfilterable-float').uniform(0);\r\n this.cameraNearFar = pb.vec2().uniform(0);\r\n this.targetSize = pb.vec4().uniform(0);\r\n // x: world scatter radius in pixels at unit depth, y: 1 for perspective,\r\n // z: max tap spacing, w: depth rejection scale.\r\n this.radiusParams = pb.vec4().uniform(0);\r\n this.channelRadius = pb.vec3().uniform(0);\r\n this.channelFalloff = pb.vec3().uniform(0);\r\n this.blurDirection = pb.vec2().uniform(0);\r\n this.$outputs.outColor = pb.vec4();\r\n pb.func('readDepth01', [pb.vec2('uv')], function () {\r\n this.$return(ShaderHelper.sampleLinearDepth(this, this.depthTex, this.uv, 0));\r\n });\r\n pb.main(function () {\r\n this.$l.uv = this.$inputs.uv;\r\n this.$l.center = pb.textureSampleLevel(this.skinTex, this.uv, 0);\r\n this.$l.centerDepth01 = this.readDepth01(this.uv);\r\n this.$outputs.outColor = this.center;\r\n // Background, or a pixel no skin material wrote: nothing to diffuse.\r\n this.$if(\r\n pb.and(pb.lessThan(this.centerDepth01, 1), pb.greaterThan(this.center.a, 1e-4)),\r\n function () {\r\n this.$l.centerDepth = pb.max(pb.mul(this.centerDepth01, this.cameraNearFar.y), 1e-4);\r\n // Per-channel radius in pixels. Red reaches several times further\r\n // than blue, which is the whole point - a shared radius is what\r\n // makes Gaussian SSS read as a flat haze.\r\n this.$l.viewScale = pb.max(pb.mix(pb.float(1), this.centerDepth, this.radiusParams.y), 1e-4);\r\n this.$l.radiusPx = pb.div(pb.mul(this.channelRadius, this.radiusParams.x), this.viewScale);\r\n // Burley shaping distance per channel; falloff tightens or widens\r\n // the profile without changing its reach.\r\n this.$l.shape = pb.vec3(\r\n pb.mix(0.72, 1.46, pb.clamp(this.channelFalloff.x, 0.05, 1)),\r\n pb.mix(0.72, 1.46, pb.clamp(this.channelFalloff.y, 0.05, 1)),\r\n pb.mix(0.72, 1.46, pb.clamp(this.channelFalloff.z, 0.05, 1))\r\n );\r\n this.$l.shapeDist = pb.max(pb.mul(this.radiusPx, this.shape), pb.vec3(1e-3));\r\n // Tap spacing follows the widest channel so the longest tail is\r\n // resolved; the narrower channels simply weight down sooner.\r\n this.$l.maxRadiusPx = pb.max(pb.max(this.radiusPx.x, this.radiusPx.y), this.radiusPx.z);\r\n this.$l.stepPx = pb.clamp(pb.div(this.maxRadiusPx, SKIN_SSS_TAPS), 0, this.radiusParams.z);\r\n this.$l.stepUV = pb.mul(this.blurDirection, this.stepPx, this.targetSize.zw);\r\n this.$l.sum = pb.vec3(0);\r\n this.$l.weightSum = pb.vec3(0);\r\n this.$l.coverage = pb.float(0);\r\n this.$l.coverageWeight = pb.float(0);\r\n this.$for(pb.int('i'), -SKIN_SSS_TAPS, SKIN_SSS_TAPS + 1, function () {\r\n this.$l.fi = pb.float(this.i);\r\n this.$l.sampleUV = pb.clamp(\r\n pb.add(this.uv, pb.mul(this.stepUV, this.fi)),\r\n pb.vec2(0),\r\n pb.vec2(1)\r\n );\r\n this.$l.dist = pb.mul(pb.abs(this.fi), this.stepPx);\r\n this.$l.w = pb.vec3(\r\n burleyDiffusionWeight(this, this.dist, this.shapeDist.x),\r\n burleyDiffusionWeight(this, this.dist, this.shapeDist.y),\r\n burleyDiffusionWeight(this, this.dist, this.shapeDist.z)\r\n );\r\n this.$l.sampleDepth01 = this.readDepth01(this.sampleUV);\r\n this.$l.sampleDepth = pb.max(pb.mul(this.sampleDepth01, this.cameraNearFar.y), 1e-4);\r\n this.$l.depthWeight = pb.clamp(\r\n pb.sub(\r\n 1,\r\n pb.div(\r\n pb.mul(pb.abs(pb.sub(this.centerDepth, this.sampleDepth)), this.radiusParams.w),\r\n this.centerDepth\r\n )\r\n ),\r\n 0,\r\n 1\r\n );\r\n this.depthWeight = pb.mul(\r\n this.depthWeight,\r\n this.depthWeight,\r\n pb.sub(3, pb.mul(this.depthWeight, 2))\r\n );\r\n this.$l.tapWeight = pb.mul(this.w, this.depthWeight);\r\n this.$l.tapSample = pb.textureSampleLevel(this.skinTex, this.sampleUV, 0);\r\n // Non-skin taps are excluded from the numerator *and* the\r\n // denominator. Leaving them in the denominator - as this pass\r\n // used to - drags the diffuse toward zero near every silhouette,\r\n // which was a mild darkening under the old additive composite\r\n // but would eat real light now that the term is subtracted back\r\n // out of the base color.\r\n this.$l.isSkin = pb.float(pb.greaterThan(this.tapSample.a, 1e-4));\r\n this.sum = pb.add(this.sum, pb.mul(this.tapSample.rgb, this.tapWeight, this.isSkin));\r\n this.weightSum = pb.add(this.weightSum, pb.mul(this.tapWeight, this.isSkin));\r\n // Coverage keeps its own accumulator: it is the skin fraction of\r\n // the neighbourhood, so it must count every tap in the\r\n // denominator, skin or not.\r\n this.coverage = pb.add(\r\n this.coverage,\r\n pb.mul(this.tapWeight.x, this.isSkin, this.tapSample.a)\r\n );\r\n this.coverageWeight = pb.add(this.coverageWeight, this.tapWeight.x);\r\n });\r\n this.$l.diffused = pb.div(this.sum, pb.max(this.weightSum, pb.vec3(1e-6)));\r\n this.$outputs.outColor = pb.vec4(\r\n this.diffused,\r\n pb.div(this.coverage, pb.max(this.coverageWeight, 1e-6))\r\n );\r\n }\r\n );\r\n });\r\n }\r\n })!;\r\n program.name = '@SkinSSSBlur';\r\n return program;\r\n }\r\n\r\n private createCombineProgram(ctx: DrawContext) {\r\n const program = ctx.device.buildRenderProgram({\r\n vertex(pb) {\r\n SkinSSS.fullscreenVertex(pb);\r\n },\r\n fragment(pb) {\r\n this.colorTex = pb.tex2D().uniform(0);\r\n this.skinTex = pb.tex2D().uniform(0);\r\n this.blurredTex = pb.tex2D().uniform(0);\r\n this.depthTex = pb.tex2D().sampleType('unfilterable-float').uniform(0);\r\n this.cameraNearFar = pb.vec2().uniform(0);\r\n this.targetSize = pb.vec4().uniform(0);\r\n this.radiusParams = pb.vec4().uniform(0);\r\n this.scatterTint = pb.vec4().uniform(0);\r\n this.strength = pb.float().uniform(0);\r\n this.glow = pb.float().uniform(0);\r\n this.opacity = pb.float().uniform(0);\r\n this.colorBoost = pb.float().uniform(0);\r\n this.encodeScale = pb.float().uniform(0);\r\n this.smoothness = pb.float().uniform(0);\r\n this.srgbOut = pb.int().uniform(0);\r\n this.$outputs.outColor = pb.vec4();\r\n pb.func('readDepth01', [pb.vec2('uv')], function () {\r\n this.$return(ShaderHelper.sampleLinearDepth(this, this.depthTex, this.uv, 0));\r\n });\r\n pb.main(function () {\r\n this.$l.uv = this.$inputs.uv;\r\n this.$l.baseColor = pb.textureSampleLevel(this.colorTex, this.uv, 0);\r\n this.$l.result = this.baseColor.rgb;\r\n this.$l.centerSkin = pb.textureSampleLevel(this.skinTex, this.uv, 0);\r\n this.$l.centerDepth01 = this.readDepth01(this.uv);\r\n this.$if(\r\n pb.and(pb.lessThan(this.centerDepth01, 1), pb.greaterThan(this.centerSkin.a, 1e-4)),\r\n function () {\r\n this.$l.blurred = pb.textureSampleLevel(this.blurredTex, this.uv, 0);\r\n // Both buffers carry the same LDR encoding, so decode once here.\r\n this.$l.original = pb.mul(this.centerSkin.rgb, this.encodeScale);\r\n this.$l.diffused = pb.mul(this.blurred.rgb, this.encodeScale, this.colorBoost);\r\n this.$l.coverage = pb.smoothStep(this.opacity, pb.add(this.opacity, 0.35), this.blurred.a);\r\n // Energy conserving core: swap the original diffuse for the\r\n // diffused one. The added term is exactly the subtracted term, so\r\n // brightening the dark side of the terminator darkens the lit side\r\n // by the same amount rather than adding light to the frame.\r\n this.$l.redistributed = pb.mul(\r\n pb.sub(this.diffused, this.original),\r\n this.scatterTint.rgb,\r\n this.strength,\r\n this.coverage\r\n );\r\n this.result = pb.add(this.baseColor.rgb, this.redistributed);\r\n // Explicit, opt-in departure from conservation.\r\n this.$if(pb.greaterThan(this.glow, 0), function () {\r\n this.result = pb.add(\r\n this.result,\r\n pb.mul(this.diffused, this.scatterTint.rgb, this.glow, this.coverage)\r\n );\r\n });\r\n // Beauty filter. Unlike the diffusion above this blurs the shaded\r\n // color itself, so it removes albedo detail (pores, blemishes)\r\n // that scattering physically leaves alone. Uniform branch: free\r\n // when disabled.\r\n this.$if(pb.greaterThan(this.smoothness, 0), function () {\r\n this.$l.centerDepth = pb.max(pb.mul(this.centerDepth01, this.cameraNearFar.y), 1e-4);\r\n this.$l.viewScale = pb.max(pb.mix(pb.float(1), this.centerDepth, this.radiusParams.y), 1e-4);\r\n this.$l.smoothStepPx = pb.clamp(\r\n pb.div(pb.mul(this.radiusParams.x, 0.5), this.viewScale),\r\n 0,\r\n this.radiusParams.z\r\n );\r\n this.$l.colorSum = pb.vec3(0);\r\n this.$l.colorWeight = pb.float(0);\r\n this.$for(pb.int('y'), -2, 3, function () {\r\n this.$for(pb.int('x'), -2, 3, function () {\r\n this.$l.offset = pb.mul(\r\n pb.vec2(pb.float(this.x), pb.float(this.y)),\r\n this.smoothStepPx,\r\n this.targetSize.zw\r\n );\r\n this.$l.sampleUV = pb.clamp(pb.add(this.uv, this.offset), pb.vec2(0), pb.vec2(1));\r\n // The skin mask is the edge stop, so eyes, brows and lips\r\n // (mask 0) never bleed onto the surrounding skin.\r\n this.$l.maskSample = pb.textureSampleLevel(this.skinTex, this.sampleUV, 0).a;\r\n this.$l.w = pb.float(pb.greaterThan(this.maskSample, 1e-4));\r\n this.colorSum = pb.add(\r\n this.colorSum,\r\n pb.mul(pb.textureSampleLevel(this.colorTex, this.sampleUV, 0).rgb, this.w)\r\n );\r\n this.colorWeight = pb.add(this.colorWeight, this.w);\r\n });\r\n });\r\n this.$if(pb.greaterThan(this.colorWeight, 1e-4), function () {\r\n this.result = pb.mix(\r\n this.result,\r\n pb.div(this.colorSum, this.colorWeight),\r\n pb.mul(this.smoothness, this.coverage, this.centerSkin.a)\r\n );\r\n });\r\n });\r\n // Precision can push the subtraction a hair below zero.\r\n this.result = pb.max(this.result, pb.vec3(0));\r\n }\r\n );\r\n this.$if(pb.equal(this.srgbOut, 0), function () {\r\n this.$outputs.outColor = pb.vec4(this.result, this.baseColor.a);\r\n }).$else(function () {\r\n this.$outputs.outColor = pb.vec4(linearToGamma(this, this.result), this.baseColor.a);\r\n });\r\n });\r\n }\r\n })!;\r\n program.name = '@SkinSSSCombine';\r\n return program;\r\n }\r\n}\r\n"],"names":["SKIN_SSS_TAPS","SkinSSS","AbstractPostEffect","_blurProgram","_combineProgram","_blurBindGroupH","_blurBindGroupV","_combineBindGroup","_profile","_strength","_glow","_opacity","_sampleStep","_depthScale","_colorBoost","_scatterRadius","_smoothness","_scatterTint","_channelRadius","_channelFalloff","_blurDirection","_radiusParams","_targetSize","_cameraNearFar","_layer","PostEffectLayer","opaque","Vector4","Vector3","Vector2","profile","val","strength","Math","max","glow","scatterTint","set","opacity","min","sampleStep","scatterRadius","smoothness","depthScale","colorBoost","requireLinearDepthTexture","apply","ctx","inputColorTexture","sceneDepthTexture","srgbOutput","SkinSSSTexture","passThrough","device","outputFramebuffer","getFramebuffer","skinTex","createBlurProgram","createCombineProgram","blurProgram","combineProgram","createBindGroup","bindGroupLayouts","SubsurfaceProfile","getDefaultSkinProfile","radius","maxChannel","x","y","z","setXYZ","falloff","falloffColor","projScale","height","camera","getProjectionMatrix","m11","setXYZW","isPerspective","width","setXY","getNearPlane","getFarPlane","encodeScale","format","SKIN_SSS_LDR_ENCODE_RANGE","blurH","pool","fetchTemporalFramebuffer","blurV","setFramebuffer","blur","getColorAttachments","combine","releaseFrameBuffer","program","bindGroup","source","horizontal","setTexture","fetchSampler","setValue","setProgram","setBindGroup","drawFullscreenQuad","colorTexture","skinTexture","blurredTexture","needFlip","fullscreenVertex","pb","getGlobalScope","flip","int","uniform","$inputs","pos","vec2","attrib","$outputs","uv","main","$builtins","position","vec4","DEPTH_FARTHEST","add","mul","xy","$if","notEqual","neg","buildRenderProgram","vertex","fragment","tex2D","depthTex","sampleType","cameraNearFar","targetSize","radiusParams","channelRadius","vec3","channelFalloff","blurDirection","outColor","func","$return","ShaderHelper","sampleLinearDepth","$l","center","textureSampleLevel","centerDepth01","readDepth01","and","lessThan","greaterThan","a","centerDepth","viewScale","mix","float","radiusPx","div","shape","clamp","shapeDist","maxRadiusPx","stepPx","stepUV","zw","sum","weightSum","coverage","coverageWeight","$for","fi","i","sampleUV","dist","abs","w","burleyDiffusionWeight","sampleDepth01","sampleDepth","depthWeight","sub","tapWeight","tapSample","isSkin","rgb","diffused","name","colorTex","blurredTex","srgbOut","baseColor","result","centerSkin","blurred","original","smoothStep","redistributed","smoothStepPx","colorSum","colorWeight","offset","maskSample","equal","$else","linearToGamma"],"mappings":"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"}
@@ -9,9 +9,12 @@ import '../material/unlit.js';
9
9
  import '../material/particle.js';
10
10
  import '../material/subsurfaceprofile.js';
11
11
  import '../material/skin.js';
12
+ import '../material/eye.js';
12
13
  import '@zephyr3d/device';
13
14
  import '../values.js';
14
15
  import '../material/meshmaterial.js';
16
+ import '../material/hair.js';
17
+ import '../material/hairstrand.js';
15
18
  import '../material/grassmaterial.js';
16
19
  import '../material/terrain-cm.js';
17
20
  import '../material/pbrmr.js';
@@ -58,10 +61,10 @@ const MOMENT_LUMINANCE_MAX = 255;
58
61
  return !!ctx.SSGI;
59
62
  }
60
63
  /** {@inheritDoc AbstractPostEffect.requireMotionVectorTexture} */ requireMotionVectorTexture(ctx) {
61
- return !!ctx.SSGI && ctx.device.type === 'webgpu';
64
+ return !!ctx.SSGI && ctx.device.type !== 'webgl';
62
65
  }
63
66
  /** {@inheritDoc AbstractPostEffect.requireHiZTexture} */ requireHiZTexture(ctx) {
64
- return !!ctx.SSGI && ctx.device.type === 'webgpu';
67
+ return !!ctx.SSGI && ctx.device.type !== 'webgl';
65
68
  }
66
69
  /** {@inheritDoc AbstractPostEffect.requireSceneNormalTexture} */ requireSceneNormalTexture(ctx) {
67
70
  return !!ctx.SSGI;
@@ -141,7 +144,10 @@ const MOMENT_LUMINANCE_MAX = 255;
141
144
  // imported directly instead of being routed through the light pass history
142
145
  // read bindings the way irradiance and surface are.
143
146
  const previousAOHandle = history.importPreviousIfCompatible(graph, RGHistoryResources.SSGI_AO, aoTraceDesc, traceSize);
144
- const previousSceneColorHandle = ctx.device.type === 'webgpu' ? history.importPreviousIfCompatible(graph, RGHistoryResources.SSGI_SCENE_COLOR, {
147
+ // Reprojecting last frame's colour needs motion vectors, which the WebGL1
148
+ // backend does not produce. WebGL2 and WebGPU both do, so both take the
149
+ // multi-bounce path.
150
+ const previousSceneColorHandle = ctx.device.type !== 'webgl' ? history.importPreviousIfCompatible(graph, RGHistoryResources.SSGI_SCENE_COLOR, {
145
151
  format: s.colorFormat,
146
152
  sizeMode: 'absolute',
147
153
  width: s.width,
@@ -234,7 +240,7 @@ const MOMENT_LUMINANCE_MAX = 255;
234
240
  });
235
241
  return out;
236
242
  });
237
- const canTemporal = !!(ctx.device.type === 'webgpu' && ctx.camera.ssgiTemporal && motionHandle && previousIrradianceHandle && previousSurfaceHandle && previousMomentsHandle && previousAOHandle);
243
+ const canTemporal = !!(ctx.device.type !== 'webgl' && ctx.camera.ssgiTemporal && motionHandle && previousIrradianceHandle && previousSurfaceHandle && previousMomentsHandle && previousAOHandle);
238
244
  // Temporal pass always creates moments. On the first frame it simply
239
245
  // initializes them; with valid history it rejects by depth and normal,
240
246
  // neighborhood-clamps radiance, and accumulates first/second moments.
@@ -424,7 +430,7 @@ const MOMENT_LUMINANCE_MAX = 255;
424
430
  } else {
425
431
  this.passThrough(ctx, sceneColor, output.srgbOutput);
426
432
  }
427
- if (ctx.device.type === 'webgpu') {
433
+ if (ctx.device.type !== 'webgl') {
428
434
  // Commit the same fog-free color the trace sampled, so next frame's
429
435
  // reprojected history is on the same footing as this frame's fallback.
430
436
  this.commitHistory(history, RGHistoryResources.SSGI_SCENE_COLOR, rg.getTexture(sampleColorHandle));
@@ -522,8 +528,9 @@ const MOMENT_LUMINANCE_MAX = 255;
522
528
  bindGroup.setTexture('previousIrradianceTex', previousIrradiance, fetchSampler('clamp_linear_nomip'));
523
529
  bindGroup.setTexture('previousSurfaceTex', previousSurface, fetchSampler('clamp_nearest_nomip'));
524
530
  bindGroup.setTexture('previousMomentsTex', previousMoments, fetchSampler('clamp_linear_nomip'));
525
- // Linear is safe here: this branch only runs on WebGPU, where r16f is
526
- // unconditionally filterable, and the read is at a reprojected UV.
531
+ // Linear is safe here: this branch never runs on WebGL1, and both
532
+ // WebGL2 and WebGPU filter r16f unconditionally. The read is at a
533
+ // reprojected UV.
527
534
  bindGroup.setTexture('previousAOTex', previousAO, fetchSampler('clamp_linear_nomip'));
528
535
  }
529
536
  this._temporalBindGroups[hash] = bindGroup;
@@ -911,7 +918,7 @@ const MOMENT_LUMINANCE_MAX = 255;
911
918
  this.$l.variance = pb.max(0, pb.sub(this.momentXY.y, pb.mul(this.momentXY.x, this.momentXY.x)));
912
919
  this.moment = pb.vec4(this.momentXY, this.historyLength, this.variance);
913
920
  } else {
914
- // The WebGL fallback has no motion-vector temporal resolve. Seed
921
+ // The WebGL1 fallback has no motion-vector temporal resolve. Seed
915
922
  // a-trous with spatial variance so its luminance weighting can
916
923
  // still remove Monte Carlo noise instead of treating it as an edge.
917
924
  this.$l.spatialLum = pb.float(0);
@@ -1122,7 +1129,7 @@ const MOMENT_LUMINANCE_MAX = 255;
1122
1129
  this.$l.ao = pb.clamp(pb.textureSampleLevel(this.aoTex, this.$inputs.uv, 0).r, 0, 1);
1123
1130
  // mix() toward 1 rather than a plain multiply: intensity then doubles as
1124
1131
  // the fallback for noisy or unresolved texels, which matters most on the
1125
- // WebGL path where there is no temporal accumulation to converge them.
1132
+ // WebGL1 path where there is no temporal accumulation to converge them.
1126
1133
  this.$l.shapedAO = pb.pow(this.ao, this.aoParams.y);
1127
1134
  this.$l.finalAO = pb.mix(pb.float(1), this.shapedAO, this.aoParams.x);
1128
1135
  this.$l.occludedColor = pb.mul(this.color.rgb, this.finalAO);