@lampdotdev/lamp 0.0.0-stage → 0.36.2-nightly.16

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 (470) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +397 -2
  3. package/Resources/Devices/roku.json +410 -0
  4. package/Resources/Devices/xbox-one.json +367 -0
  5. package/Resources/GameKit/NOTICE.md +63 -0
  6. package/Resources/GameKit/apple/LampPage.swift +1813 -0
  7. package/Resources/GameKit/apple/LampPlayer.swift +46 -0
  8. package/Resources/GameKit/apple/LampWebApp.swift +63 -0
  9. package/Resources/GameKit/apple/LampWebGame.swift +87 -0
  10. package/Resources/GameKit/apple/Native.swift +12 -0
  11. package/Resources/GameKit/build.sh +55 -0
  12. package/Resources/GameKit/lamp_game.h +116 -0
  13. package/Resources/GameKit/lamp_host.h +19 -0
  14. package/Resources/GameKit/lamp_kit.cpp +61 -0
  15. package/Resources/GameKit/lamp_sound.cpp +455 -0
  16. package/Resources/GameKit/lamp_xbox.cpp +374 -0
  17. package/Resources/GameKit/libraries/HandmadeMath.h +3940 -0
  18. package/Resources/GameKit/libraries/cgltf.h +7240 -0
  19. package/Resources/GameKit/libraries/dr_mp3.h +5430 -0
  20. package/Resources/GameKit/libraries/dr_wav.h +9209 -0
  21. package/Resources/GameKit/libraries/sokol_debugtext.h +4754 -0
  22. package/Resources/GameKit/libraries/sokol_gfx.h +29558 -0
  23. package/Resources/GameKit/libraries/sokol_gl.h +4538 -0
  24. package/Resources/GameKit/libraries/sokol_log.h +335 -0
  25. package/Resources/GameKit/libraries/sokol_shape.h +1531 -0
  26. package/Resources/GameKit/libraries/stb_image.h +7988 -0
  27. package/Resources/GameKit/libraries/stb_vorbis.c +5584 -0
  28. package/Resources/GameKit/page/lamp-live.js +672 -0
  29. package/Resources/GameKit/scaffold/Game/game.cpp +142 -0
  30. package/Resources/GameKit/scaffold/Game/scene.glsl +49 -0
  31. package/Resources/GameKit/scaffold-web/Web/game.js +31 -0
  32. package/Resources/GameKit/scaffold-web/Web/index.html +13 -0
  33. package/Resources/GameKit/scaffold-web/Web/making.js +33 -0
  34. package/Resources/GameKit/scaffold-web/Web/world.js +33 -0
  35. package/Resources/GameKit/web/lamp-game.js +3042 -0
  36. package/Resources/GameKit/web/lamp-phaser.js +128 -0
  37. package/Resources/WebHost/App.exe +0 -0
  38. package/Resources/WebHost/Microsoft.Web.WebView2.Core.dll +0 -0
  39. package/Resources/WebHost/WebView2-LICENSE.txt +27 -0
  40. package/Resources/WebHost/lamp_controllers.h +1506 -0
  41. package/Resources/WebHost/lamp_web_host.cpp +1173 -0
  42. package/Resources/WebLibraries/earlier.txt +318 -0
  43. package/Resources/WebLibraries/phaser/LICENSE.md +20 -0
  44. package/Resources/WebLibraries/phaser/NOTICE.md +2 -0
  45. package/Resources/WebLibraries/phaser/phaser.esm.min.js +1 -0
  46. package/Resources/WebLibraries/qrcode/LICENSE +21 -0
  47. package/Resources/WebLibraries/qrcode/NOTICE.md +4 -0
  48. package/Resources/WebLibraries/qrcode/qrcode.js +2297 -0
  49. package/Resources/WebLibraries/rapier/LICENSE +201 -0
  50. package/Resources/WebLibraries/rapier/NOTICE.md +3 -0
  51. package/Resources/WebLibraries/rapier/rapier.js +2 -0
  52. package/Resources/WebLibraries/three/LICENSE +21 -0
  53. package/Resources/WebLibraries/three/NOTICE.md +4 -0
  54. package/Resources/WebLibraries/three/addons/animation/AnimationClipCreator.js +168 -0
  55. package/Resources/WebLibraries/three/addons/animation/CCDIKSolver.js +607 -0
  56. package/Resources/WebLibraries/three/addons/controls/ArcballControls.js +3543 -0
  57. package/Resources/WebLibraries/three/addons/controls/DragControls.js +452 -0
  58. package/Resources/WebLibraries/three/addons/controls/FirstPersonControls.js +512 -0
  59. package/Resources/WebLibraries/three/addons/controls/FlyControls.js +384 -0
  60. package/Resources/WebLibraries/three/addons/controls/MapControls.js +116 -0
  61. package/Resources/WebLibraries/three/addons/controls/OrbitControls.js +1985 -0
  62. package/Resources/WebLibraries/three/addons/controls/PointerLockControls.js +264 -0
  63. package/Resources/WebLibraries/three/addons/controls/TrackballControls.js +1106 -0
  64. package/Resources/WebLibraries/three/addons/controls/TransformControls.js +2003 -0
  65. package/Resources/WebLibraries/three/addons/curves/CurveExtras.js +694 -0
  66. package/Resources/WebLibraries/three/addons/curves/NURBSCurve.js +169 -0
  67. package/Resources/WebLibraries/three/addons/curves/NURBSSurface.js +98 -0
  68. package/Resources/WebLibraries/three/addons/curves/NURBSUtils.js +532 -0
  69. package/Resources/WebLibraries/three/addons/curves/NURBSVolume.js +82 -0
  70. package/Resources/WebLibraries/three/addons/effects/AnaglyphEffect.js +274 -0
  71. package/Resources/WebLibraries/three/addons/effects/AsciiEffect.js +323 -0
  72. package/Resources/WebLibraries/three/addons/effects/OutlineEffect.js +489 -0
  73. package/Resources/WebLibraries/three/addons/effects/ParallaxBarrierEffect.js +155 -0
  74. package/Resources/WebLibraries/three/addons/effects/StereoEffect.js +91 -0
  75. package/Resources/WebLibraries/three/addons/environments/ColorEnvironment.js +59 -0
  76. package/Resources/WebLibraries/three/addons/environments/DebugEnvironment.js +102 -0
  77. package/Resources/WebLibraries/three/addons/environments/RoomEnvironment.js +185 -0
  78. package/Resources/WebLibraries/three/addons/geometries/BoxLineGeometry.js +92 -0
  79. package/Resources/WebLibraries/three/addons/geometries/ConvexGeometry.js +72 -0
  80. package/Resources/WebLibraries/three/addons/geometries/DecalGeometry.js +420 -0
  81. package/Resources/WebLibraries/three/addons/geometries/LoftGeometry.js +355 -0
  82. package/Resources/WebLibraries/three/addons/geometries/ParametricFunctions.js +100 -0
  83. package/Resources/WebLibraries/three/addons/geometries/ParametricGeometry.js +172 -0
  84. package/Resources/WebLibraries/three/addons/geometries/RoundedBoxGeometry.js +216 -0
  85. package/Resources/WebLibraries/three/addons/geometries/TeapotGeometry.js +689 -0
  86. package/Resources/WebLibraries/three/addons/geometries/TextGeometry.js +102 -0
  87. package/Resources/WebLibraries/three/addons/helpers/AnimationPathHelper.js +302 -0
  88. package/Resources/WebLibraries/three/addons/helpers/LightProbeGridHelper.js +166 -0
  89. package/Resources/WebLibraries/three/addons/helpers/LightProbeGridHelperWebGL.js +221 -0
  90. package/Resources/WebLibraries/three/addons/helpers/LightProbeHelper.js +166 -0
  91. package/Resources/WebLibraries/three/addons/helpers/LightProbeHelperGPU.js +102 -0
  92. package/Resources/WebLibraries/three/addons/helpers/OctreeHelper.js +109 -0
  93. package/Resources/WebLibraries/three/addons/helpers/PositionalAudioHelper.js +169 -0
  94. package/Resources/WebLibraries/three/addons/helpers/RapierHelper.js +59 -0
  95. package/Resources/WebLibraries/three/addons/helpers/RectAreaLightHelper.js +118 -0
  96. package/Resources/WebLibraries/three/addons/helpers/TextureHelper.js +265 -0
  97. package/Resources/WebLibraries/three/addons/helpers/TextureHelperGPU.js +214 -0
  98. package/Resources/WebLibraries/three/addons/helpers/VertexNormalsHelper.js +155 -0
  99. package/Resources/WebLibraries/three/addons/helpers/VertexTangentsHelper.js +133 -0
  100. package/Resources/WebLibraries/three/addons/helpers/ViewHelper.js +529 -0
  101. package/Resources/WebLibraries/three/addons/interactive/HTMLMesh.js +617 -0
  102. package/Resources/WebLibraries/three/addons/interactive/InteractiveGroup.js +224 -0
  103. package/Resources/WebLibraries/three/addons/interactive/SelectionBox.js +324 -0
  104. package/Resources/WebLibraries/three/addons/interactive/SelectionHelper.js +150 -0
  105. package/Resources/WebLibraries/three/addons/libs/fflate.module.js +2699 -0
  106. package/Resources/WebLibraries/three/addons/libs/lil-gui.module.min.js +8 -0
  107. package/Resources/WebLibraries/three/addons/libs/meshopt_decoder.module.js +196 -0
  108. package/Resources/WebLibraries/three/addons/libs/potpack.module.js +125 -0
  109. package/Resources/WebLibraries/three/addons/libs/stats.module.js +167 -0
  110. package/Resources/WebLibraries/three/addons/libs/tween.module.js +876 -0
  111. package/Resources/WebLibraries/three/addons/lighting/ClusteredLighting.js +153 -0
  112. package/Resources/WebLibraries/three/addons/lighting/DynamicLighting.js +82 -0
  113. package/Resources/WebLibraries/three/addons/lighting/LightMapper.js +295 -0
  114. package/Resources/WebLibraries/three/addons/lighting/LightProbeGrid.js +923 -0
  115. package/Resources/WebLibraries/three/addons/lighting/LightProbeGridUtils.js +107 -0
  116. package/Resources/WebLibraries/three/addons/lighting/LightProbeGridWebGL.js +846 -0
  117. package/Resources/WebLibraries/three/addons/lighting/vxgi/VXGIConeTracer.js +243 -0
  118. package/Resources/WebLibraries/three/addons/lighting/vxgi/VXGIIrradiance.js +43 -0
  119. package/Resources/WebLibraries/three/addons/lighting/vxgi/VXGINode.js +617 -0
  120. package/Resources/WebLibraries/three/addons/lighting/vxgi/VXGISceneCollector.js +793 -0
  121. package/Resources/WebLibraries/three/addons/lighting/vxgi/VXGIVolume.js +1440 -0
  122. package/Resources/WebLibraries/three/addons/lights/LightProbeGenerator.js +337 -0
  123. package/Resources/WebLibraries/three/addons/lights/RectAreaLightTexturesLib.js +127 -0
  124. package/Resources/WebLibraries/three/addons/lights/RectAreaLightUniformsLib.js +40 -0
  125. package/Resources/WebLibraries/three/addons/lights/SunLight.js +100 -0
  126. package/Resources/WebLibraries/three/addons/lights/SunLightNode.js +56 -0
  127. package/Resources/WebLibraries/three/addons/lights/SunLightShadow.js +319 -0
  128. package/Resources/WebLibraries/three/addons/lights/SunShadowNode.js +312 -0
  129. package/Resources/WebLibraries/three/addons/lines/Line2.js +56 -0
  130. package/Resources/WebLibraries/three/addons/lines/LineGeometry.js +157 -0
  131. package/Resources/WebLibraries/three/addons/lines/LineMaterial.js +742 -0
  132. package/Resources/WebLibraries/three/addons/lines/LineSegments2.js +434 -0
  133. package/Resources/WebLibraries/three/addons/lines/LineSegmentsGeometry.js +298 -0
  134. package/Resources/WebLibraries/three/addons/lines/Wireframe.js +108 -0
  135. package/Resources/WebLibraries/three/addons/lines/WireframeGeometry2.js +49 -0
  136. package/Resources/WebLibraries/three/addons/lines/webgpu/Line2.js +46 -0
  137. package/Resources/WebLibraries/three/addons/lines/webgpu/LineSegments2.js +419 -0
  138. package/Resources/WebLibraries/three/addons/lines/webgpu/Wireframe.js +86 -0
  139. package/Resources/WebLibraries/three/addons/loaders/EXRLoader.js +3411 -0
  140. package/Resources/WebLibraries/three/addons/loaders/FBXLoader.js +4660 -0
  141. package/Resources/WebLibraries/three/addons/loaders/FontLoader.js +262 -0
  142. package/Resources/WebLibraries/three/addons/loaders/GLTFLoader.js +5006 -0
  143. package/Resources/WebLibraries/three/addons/loaders/HDRLoader.js +463 -0
  144. package/Resources/WebLibraries/three/addons/loaders/MTLLoader.js +601 -0
  145. package/Resources/WebLibraries/three/addons/loaders/OBJLoader.js +961 -0
  146. package/Resources/WebLibraries/three/addons/loaders/PLYLoader.js +992 -0
  147. package/Resources/WebLibraries/three/addons/loaders/RGBELoader.js +18 -0
  148. package/Resources/WebLibraries/three/addons/loaders/STLLoader.js +423 -0
  149. package/Resources/WebLibraries/three/addons/loaders/SVGLoader.js +3297 -0
  150. package/Resources/WebLibraries/three/addons/loaders/TGALoader.js +539 -0
  151. package/Resources/WebLibraries/three/addons/loaders/UltraHDRLoader.js +757 -0
  152. package/Resources/WebLibraries/three/addons/math/Capsule.js +159 -0
  153. package/Resources/WebLibraries/three/addons/math/ColorConverter.js +62 -0
  154. package/Resources/WebLibraries/three/addons/math/ColorSpaces.js +147 -0
  155. package/Resources/WebLibraries/three/addons/math/ConvexHull.js +1695 -0
  156. package/Resources/WebLibraries/three/addons/math/ImprovedNoise.js +88 -0
  157. package/Resources/WebLibraries/three/addons/math/Lut.js +317 -0
  158. package/Resources/WebLibraries/three/addons/math/MeshSurfaceSampler.js +315 -0
  159. package/Resources/WebLibraries/three/addons/math/OBB.js +535 -0
  160. package/Resources/WebLibraries/three/addons/math/Octree.js +825 -0
  161. package/Resources/WebLibraries/three/addons/math/SimplexNoise.js +470 -0
  162. package/Resources/WebLibraries/three/addons/misc/ConvexObjectBreaker.js +539 -0
  163. package/Resources/WebLibraries/three/addons/misc/GPUComputationRenderer.js +508 -0
  164. package/Resources/WebLibraries/three/addons/misc/Gyroscope.js +78 -0
  165. package/Resources/WebLibraries/three/addons/misc/MorphAnimMesh.js +119 -0
  166. package/Resources/WebLibraries/three/addons/misc/MorphBlendMesh.js +425 -0
  167. package/Resources/WebLibraries/three/addons/misc/ProgressiveLightMap.js +370 -0
  168. package/Resources/WebLibraries/three/addons/misc/ProgressiveLightMapGPU.js +322 -0
  169. package/Resources/WebLibraries/three/addons/misc/RollerCoaster.js +661 -0
  170. package/Resources/WebLibraries/three/addons/misc/Sculptor.js +1679 -0
  171. package/Resources/WebLibraries/three/addons/misc/SculptorMesh.js +1504 -0
  172. package/Resources/WebLibraries/three/addons/misc/SculptorTools.js +1180 -0
  173. package/Resources/WebLibraries/three/addons/misc/SculptorUtils.js +345 -0
  174. package/Resources/WebLibraries/three/addons/misc/TileCreasedNormalsPlugin.js +270 -0
  175. package/Resources/WebLibraries/three/addons/misc/TubePainter.js +611 -0
  176. package/Resources/WebLibraries/three/addons/misc/Volume.js +520 -0
  177. package/Resources/WebLibraries/three/addons/misc/VolumeSlice.js +275 -0
  178. package/Resources/WebLibraries/three/addons/modifiers/CurveModifier.js +374 -0
  179. package/Resources/WebLibraries/three/addons/modifiers/CurveModifierGPU.js +256 -0
  180. package/Resources/WebLibraries/three/addons/modifiers/EdgeSplitModifier.js +299 -0
  181. package/Resources/WebLibraries/three/addons/modifiers/TessellateModifier.js +340 -0
  182. package/Resources/WebLibraries/three/addons/objects/GroundedSkybox.js +69 -0
  183. package/Resources/WebLibraries/three/addons/objects/Lensflare.js +489 -0
  184. package/Resources/WebLibraries/three/addons/objects/LensflareMesh.js +376 -0
  185. package/Resources/WebLibraries/three/addons/objects/MarchingCubes.js +1261 -0
  186. package/Resources/WebLibraries/three/addons/objects/Reflector.js +390 -0
  187. package/Resources/WebLibraries/three/addons/objects/ReflectorForSSRPass.js +393 -0
  188. package/Resources/WebLibraries/three/addons/objects/Refractor.js +389 -0
  189. package/Resources/WebLibraries/three/addons/objects/ShadowMesh.js +130 -0
  190. package/Resources/WebLibraries/three/addons/objects/Sky.js +342 -0
  191. package/Resources/WebLibraries/three/addons/objects/SkyMesh.js +403 -0
  192. package/Resources/WebLibraries/three/addons/objects/Water.js +374 -0
  193. package/Resources/WebLibraries/three/addons/objects/Water2.js +403 -0
  194. package/Resources/WebLibraries/three/addons/objects/Water2Mesh.js +199 -0
  195. package/Resources/WebLibraries/three/addons/objects/WaterMesh.js +194 -0
  196. package/Resources/WebLibraries/three/addons/postprocessing/AfterimagePass.js +187 -0
  197. package/Resources/WebLibraries/three/addons/postprocessing/BloomPass.js +274 -0
  198. package/Resources/WebLibraries/three/addons/postprocessing/BokehPass.js +218 -0
  199. package/Resources/WebLibraries/three/addons/postprocessing/ClearPass.js +97 -0
  200. package/Resources/WebLibraries/three/addons/postprocessing/CubeTexturePass.js +146 -0
  201. package/Resources/WebLibraries/three/addons/postprocessing/DotScreenPass.js +114 -0
  202. package/Resources/WebLibraries/three/addons/postprocessing/EffectComposer.js +365 -0
  203. package/Resources/WebLibraries/three/addons/postprocessing/FXAAPass.js +40 -0
  204. package/Resources/WebLibraries/three/addons/postprocessing/FilmPass.js +113 -0
  205. package/Resources/WebLibraries/three/addons/postprocessing/GTAOPass.js +735 -0
  206. package/Resources/WebLibraries/three/addons/postprocessing/GlitchPass.js +177 -0
  207. package/Resources/WebLibraries/three/addons/postprocessing/HalftonePass.js +134 -0
  208. package/Resources/WebLibraries/three/addons/postprocessing/LUTPass.js +138 -0
  209. package/Resources/WebLibraries/three/addons/postprocessing/MaskPass.js +195 -0
  210. package/Resources/WebLibraries/three/addons/postprocessing/OutlinePass.js +776 -0
  211. package/Resources/WebLibraries/three/addons/postprocessing/OutputPass.js +148 -0
  212. package/Resources/WebLibraries/three/addons/postprocessing/Pass.js +191 -0
  213. package/Resources/WebLibraries/three/addons/postprocessing/RenderPass.js +193 -0
  214. package/Resources/WebLibraries/three/addons/postprocessing/RenderPixelatedPass.js +314 -0
  215. package/Resources/WebLibraries/three/addons/postprocessing/RenderTransitionPass.js +267 -0
  216. package/Resources/WebLibraries/three/addons/postprocessing/SAOPass.js +407 -0
  217. package/Resources/WebLibraries/three/addons/postprocessing/SMAAPass.js +230 -0
  218. package/Resources/WebLibraries/three/addons/postprocessing/SSAARenderPass.js +313 -0
  219. package/Resources/WebLibraries/three/addons/postprocessing/SSAOPass.js +527 -0
  220. package/Resources/WebLibraries/three/addons/postprocessing/SSRPass.js +858 -0
  221. package/Resources/WebLibraries/three/addons/postprocessing/SavePass.js +132 -0
  222. package/Resources/WebLibraries/three/addons/postprocessing/ShaderPass.js +135 -0
  223. package/Resources/WebLibraries/three/addons/postprocessing/TAARenderPass.js +243 -0
  224. package/Resources/WebLibraries/three/addons/postprocessing/TexturePass.js +131 -0
  225. package/Resources/WebLibraries/three/addons/postprocessing/UnrealBloomPass.js +541 -0
  226. package/Resources/WebLibraries/three/addons/shaders/ACESFilmicToneMappingShader.js +96 -0
  227. package/Resources/WebLibraries/three/addons/shaders/AfterimageShader.js +63 -0
  228. package/Resources/WebLibraries/three/addons/shaders/BasicShader.js +36 -0
  229. package/Resources/WebLibraries/three/addons/shaders/BleachBypassShader.js +68 -0
  230. package/Resources/WebLibraries/three/addons/shaders/BlendShader.js +56 -0
  231. package/Resources/WebLibraries/three/addons/shaders/BokehShader.js +151 -0
  232. package/Resources/WebLibraries/three/addons/shaders/BokehShader2.js +404 -0
  233. package/Resources/WebLibraries/three/addons/shaders/BrightnessContrastShader.js +62 -0
  234. package/Resources/WebLibraries/three/addons/shaders/ColorCorrectionShader.js +59 -0
  235. package/Resources/WebLibraries/three/addons/shaders/ColorifyShader.js +57 -0
  236. package/Resources/WebLibraries/three/addons/shaders/ConvolutionShader.js +74 -0
  237. package/Resources/WebLibraries/three/addons/shaders/CopyShader.js +52 -0
  238. package/Resources/WebLibraries/three/addons/shaders/DOFMipMapShader.js +63 -0
  239. package/Resources/WebLibraries/three/addons/shaders/DepthLimitedBlurShader.js +183 -0
  240. package/Resources/WebLibraries/three/addons/shaders/DigitalGlitch.js +104 -0
  241. package/Resources/WebLibraries/three/addons/shaders/DotScreenShader.js +75 -0
  242. package/Resources/WebLibraries/three/addons/shaders/ExposureShader.js +51 -0
  243. package/Resources/WebLibraries/three/addons/shaders/FXAAShader.js +298 -0
  244. package/Resources/WebLibraries/three/addons/shaders/FilmShader.js +73 -0
  245. package/Resources/WebLibraries/three/addons/shaders/FocusShader.js +94 -0
  246. package/Resources/WebLibraries/three/addons/shaders/FreiChenShader.js +103 -0
  247. package/Resources/WebLibraries/three/addons/shaders/GTAOShader.js +437 -0
  248. package/Resources/WebLibraries/three/addons/shaders/GammaCorrectionShader.js +52 -0
  249. package/Resources/WebLibraries/three/addons/shaders/HalftoneShader.js +332 -0
  250. package/Resources/WebLibraries/three/addons/shaders/HorizontalBlurShader.js +68 -0
  251. package/Resources/WebLibraries/three/addons/shaders/HorizontalTiltShiftShader.js +70 -0
  252. package/Resources/WebLibraries/three/addons/shaders/HueSaturationShader.js +74 -0
  253. package/Resources/WebLibraries/three/addons/shaders/KaleidoShader.js +65 -0
  254. package/Resources/WebLibraries/three/addons/shaders/LuminosityHighPassShader.js +68 -0
  255. package/Resources/WebLibraries/three/addons/shaders/LuminosityShader.js +54 -0
  256. package/Resources/WebLibraries/three/addons/shaders/MirrorShader.js +62 -0
  257. package/Resources/WebLibraries/three/addons/shaders/NormalMapShader.js +60 -0
  258. package/Resources/WebLibraries/three/addons/shaders/OutputShader.js +103 -0
  259. package/Resources/WebLibraries/three/addons/shaders/PoissonDenoiseShader.js +230 -0
  260. package/Resources/WebLibraries/three/addons/shaders/RGBShiftShader.js +61 -0
  261. package/Resources/WebLibraries/three/addons/shaders/SAOShader.js +201 -0
  262. package/Resources/WebLibraries/three/addons/shaders/SMAAShader.js +489 -0
  263. package/Resources/WebLibraries/three/addons/shaders/SSAOShader.js +331 -0
  264. package/Resources/WebLibraries/three/addons/shaders/SSRShader.js +396 -0
  265. package/Resources/WebLibraries/three/addons/shaders/SepiaShader.js +57 -0
  266. package/Resources/WebLibraries/three/addons/shaders/SobelOperatorShader.js +98 -0
  267. package/Resources/WebLibraries/three/addons/shaders/SubsurfaceScatteringShader.js +95 -0
  268. package/Resources/WebLibraries/three/addons/shaders/TechnicolorShader.js +51 -0
  269. package/Resources/WebLibraries/three/addons/shaders/ToonShader.js +349 -0
  270. package/Resources/WebLibraries/three/addons/shaders/TriangleBlurShader.js +79 -0
  271. package/Resources/WebLibraries/three/addons/shaders/UnpackDepthRGBAShader.js +60 -0
  272. package/Resources/WebLibraries/three/addons/shaders/VelocityShader.js +137 -0
  273. package/Resources/WebLibraries/three/addons/shaders/VerticalBlurShader.js +66 -0
  274. package/Resources/WebLibraries/three/addons/shaders/VerticalTiltShiftShader.js +70 -0
  275. package/Resources/WebLibraries/three/addons/shaders/VignetteShader.js +56 -0
  276. package/Resources/WebLibraries/three/addons/shaders/VolumeShader.js +285 -0
  277. package/Resources/WebLibraries/three/addons/shaders/WaterRefractionShader.js +106 -0
  278. package/Resources/WebLibraries/three/addons/textures/FlakesTexture.js +54 -0
  279. package/Resources/WebLibraries/three/addons/tsl/WebGLNodesHandler.js +607 -0
  280. package/Resources/WebLibraries/three/addons/tsl/display/AfterImageNode.js +256 -0
  281. package/Resources/WebLibraries/three/addons/tsl/display/AnaglyphPassNode.js +550 -0
  282. package/Resources/WebLibraries/three/addons/tsl/display/BilateralBlurNode.js +377 -0
  283. package/Resources/WebLibraries/three/addons/tsl/display/BleachBypass.js +33 -0
  284. package/Resources/WebLibraries/three/addons/tsl/display/BloomNode.js +599 -0
  285. package/Resources/WebLibraries/three/addons/tsl/display/CRT.js +150 -0
  286. package/Resources/WebLibraries/three/addons/tsl/display/ChromaticAberrationNode.js +163 -0
  287. package/Resources/WebLibraries/three/addons/tsl/display/DenoiseNode.js +354 -0
  288. package/Resources/WebLibraries/three/addons/tsl/display/DepthOfFieldNode.js +572 -0
  289. package/Resources/WebLibraries/three/addons/tsl/display/DotScreenNode.js +104 -0
  290. package/Resources/WebLibraries/three/addons/tsl/display/FSR1Node.js +481 -0
  291. package/Resources/WebLibraries/three/addons/tsl/display/FXAANode.js +357 -0
  292. package/Resources/WebLibraries/three/addons/tsl/display/FilmNode.js +101 -0
  293. package/Resources/WebLibraries/three/addons/tsl/display/GTAONode.js +727 -0
  294. package/Resources/WebLibraries/three/addons/tsl/display/GaussianBlurNode.js +412 -0
  295. package/Resources/WebLibraries/three/addons/tsl/display/GodraysNode.js +604 -0
  296. package/Resources/WebLibraries/three/addons/tsl/display/ImportanceSampledEnvironment.js +564 -0
  297. package/Resources/WebLibraries/three/addons/tsl/display/LensflareNode.js +282 -0
  298. package/Resources/WebLibraries/three/addons/tsl/display/Lut3DNode.js +109 -0
  299. package/Resources/WebLibraries/three/addons/tsl/display/MotionBlur.js +33 -0
  300. package/Resources/WebLibraries/three/addons/tsl/display/OITPassNode.js +341 -0
  301. package/Resources/WebLibraries/three/addons/tsl/display/OutlineNode.js +916 -0
  302. package/Resources/WebLibraries/three/addons/tsl/display/ParallaxBarrierPassNode.js +90 -0
  303. package/Resources/WebLibraries/three/addons/tsl/display/PixelationPassNode.js +227 -0
  304. package/Resources/WebLibraries/three/addons/tsl/display/RGBShiftNode.js +96 -0
  305. package/Resources/WebLibraries/three/addons/tsl/display/RecurrentDenoiseNode.js +812 -0
  306. package/Resources/WebLibraries/three/addons/tsl/display/RetroPassNode.js +263 -0
  307. package/Resources/WebLibraries/three/addons/tsl/display/SMAANode.js +729 -0
  308. package/Resources/WebLibraries/three/addons/tsl/display/SSAAPassNode.js +344 -0
  309. package/Resources/WebLibraries/three/addons/tsl/display/SSAONode.js +422 -0
  310. package/Resources/WebLibraries/three/addons/tsl/display/SSGINode.js +698 -0
  311. package/Resources/WebLibraries/three/addons/tsl/display/SSRNode.js +1430 -0
  312. package/Resources/WebLibraries/three/addons/tsl/display/SSSNode.js +479 -0
  313. package/Resources/WebLibraries/three/addons/tsl/display/Sepia.js +24 -0
  314. package/Resources/WebLibraries/three/addons/tsl/display/Shape.js +29 -0
  315. package/Resources/WebLibraries/three/addons/tsl/display/SharpenNode.js +284 -0
  316. package/Resources/WebLibraries/three/addons/tsl/display/SobelOperatorNode.js +168 -0
  317. package/Resources/WebLibraries/three/addons/tsl/display/StereoCompositePassNode.js +190 -0
  318. package/Resources/WebLibraries/three/addons/tsl/display/StereoPassNode.js +117 -0
  319. package/Resources/WebLibraries/three/addons/tsl/display/TAAUNode.js +700 -0
  320. package/Resources/WebLibraries/three/addons/tsl/display/TRAANode.js +609 -0
  321. package/Resources/WebLibraries/three/addons/tsl/display/TemporalReprojectNode.js +1024 -0
  322. package/Resources/WebLibraries/three/addons/tsl/display/TransitionNode.js +141 -0
  323. package/Resources/WebLibraries/three/addons/tsl/display/boxBlur.js +65 -0
  324. package/Resources/WebLibraries/three/addons/tsl/display/depthAwareBlend.js +80 -0
  325. package/Resources/WebLibraries/three/addons/tsl/display/depthAwareBlur.js +63 -0
  326. package/Resources/WebLibraries/three/addons/tsl/display/hashBlur.js +55 -0
  327. package/Resources/WebLibraries/three/addons/tsl/display/lensDirt.js +30 -0
  328. package/Resources/WebLibraries/three/addons/tsl/display/radialBlur.js +68 -0
  329. package/Resources/WebLibraries/three/addons/tsl/lighting/ClusteredLightsNode.js +994 -0
  330. package/Resources/WebLibraries/three/addons/tsl/lighting/DynamicLightsNode.js +201 -0
  331. package/Resources/WebLibraries/three/addons/tsl/lighting/LightProbeGridNode.js +183 -0
  332. package/Resources/WebLibraries/three/addons/tsl/lighting/data/AmbientLightDataNode.js +67 -0
  333. package/Resources/WebLibraries/three/addons/tsl/lighting/data/DirectionalLightDataNode.js +117 -0
  334. package/Resources/WebLibraries/three/addons/tsl/lighting/data/HemisphereLightDataNode.js +105 -0
  335. package/Resources/WebLibraries/three/addons/tsl/lighting/data/PointLightDataNode.js +140 -0
  336. package/Resources/WebLibraries/three/addons/tsl/lighting/data/SpotLightDataNode.js +167 -0
  337. package/Resources/WebLibraries/three/addons/tsl/math/Bayer.js +84 -0
  338. package/Resources/WebLibraries/three/addons/tsl/math/curlNoise.js +107 -0
  339. package/Resources/WebLibraries/three/addons/tsl/math/voronoiNoise.js +112 -0
  340. package/Resources/WebLibraries/three/addons/tsl/shadows/TileShadowNode.js +542 -0
  341. package/Resources/WebLibraries/three/addons/tsl/shadows/TileShadowNodeHelper.js +212 -0
  342. package/Resources/WebLibraries/three/addons/tsl/utils/GroundedSkybox.js +62 -0
  343. package/Resources/WebLibraries/three/addons/tsl/utils/RNoise.js +51 -0
  344. package/Resources/WebLibraries/three/addons/tsl/utils/Raymarching.js +70 -0
  345. package/Resources/WebLibraries/three/addons/tsl/utils/SoftParticles.js +53 -0
  346. package/Resources/WebLibraries/three/addons/tsl/utils/SpecularHelpers.js +302 -0
  347. package/Resources/WebLibraries/three/addons/tsl/utils/TAAUtils.js +184 -0
  348. package/Resources/WebLibraries/three/addons/utils/BufferGeometryUtils.js +1523 -0
  349. package/Resources/WebLibraries/three/addons/utils/CameraUtils.js +82 -0
  350. package/Resources/WebLibraries/three/addons/utils/ColorUtils.js +76 -0
  351. package/Resources/WebLibraries/three/addons/utils/GaussianSplatUtils.js +229 -0
  352. package/Resources/WebLibraries/three/addons/utils/GeometryCompressionUtils.js +547 -0
  353. package/Resources/WebLibraries/three/addons/utils/GeometryUtils.js +226 -0
  354. package/Resources/WebLibraries/three/addons/utils/LDrawUtils.js +211 -0
  355. package/Resources/WebLibraries/three/addons/utils/SceneOptimizer.js +459 -0
  356. package/Resources/WebLibraries/three/addons/utils/SceneUtils.js +363 -0
  357. package/Resources/WebLibraries/three/addons/utils/ShadowMapViewer.js +244 -0
  358. package/Resources/WebLibraries/three/addons/utils/ShadowMapViewerGPU.js +233 -0
  359. package/Resources/WebLibraries/three/addons/utils/SkeletonUtils.js +496 -0
  360. package/Resources/WebLibraries/three/addons/utils/SortUtils.js +175 -0
  361. package/Resources/WebLibraries/three/addons/utils/UVsDebug.js +173 -0
  362. package/Resources/WebLibraries/three/addons/utils/WebGLTextureUtils.js +115 -0
  363. package/Resources/WebLibraries/three/addons/utils/WebGPUTextureUtils.js +81 -0
  364. package/Resources/WebLibraries/three/addons/utils/WorkerPool.js +167 -0
  365. package/Resources/WebLibraries/three/addons/utils/unwrapUVs.js +865 -0
  366. package/Resources/WebLibraries/three/three.core.js +61162 -0
  367. package/Resources/WebLibraries/three/three.module.js +19537 -0
  368. package/Resources/WebLibraries/three/three.tsl.js +41903 -0
  369. package/Resources/WebLibraries/three/three.webgpu.js +53714 -0
  370. package/Resources/share-rules.json +64 -0
  371. package/Resources/skills/2d-game/SKILL.md +305 -0
  372. package/Resources/skills/3d-game/SKILL.md +274 -0
  373. package/Resources/skills/accounts/SKILL.md +41 -0
  374. package/Resources/skills/android-design/SKILL.md +159 -0
  375. package/Resources/skills/app-ai/SKILL.md +154 -0
  376. package/Resources/skills/app-intents/SKILL.md +31 -0
  377. package/Resources/skills/app-kinds/SKILL.md +122 -0
  378. package/Resources/skills/apple-watch/SKILL.md +43 -0
  379. package/Resources/skills/assets/SKILL.md +183 -0
  380. package/Resources/skills/building-blocks/SKILL.md +97 -0
  381. package/Resources/skills/device-control/SKILL.md +56 -0
  382. package/Resources/skills/device-integrations/SKILL.md +278 -0
  383. package/Resources/skills/finder-files/SKILL.md +19 -0
  384. package/Resources/skills/game/SKILL.md +416 -0
  385. package/Resources/skills/game-3d/SKILL.md +12 -0
  386. package/Resources/skills/game-art/SKILL.md +11 -0
  387. package/Resources/skills/game-feel/SKILL.md +13 -0
  388. package/Resources/skills/game-levels/SKILL.md +12 -0
  389. package/Resources/skills/game-live/SKILL.md +12 -0
  390. package/Resources/skills/game-physics/SKILL.md +13 -0
  391. package/Resources/skills/game-playtest/SKILL.md +26 -0
  392. package/Resources/skills/game-ui/SKILL.md +278 -0
  393. package/Resources/skills/github-projects/SKILL.md +62 -0
  394. package/Resources/skills/icloud-sync/SKILL.md +30 -0
  395. package/Resources/skills/iphone-hardware/SKILL.md +57 -0
  396. package/Resources/skills/iphone-widgets/SKILL.md +53 -0
  397. package/Resources/skills/lg-developer-mode/SKILL.md +152 -0
  398. package/Resources/skills/mac-widgets/SKILL.md +60 -0
  399. package/Resources/skills/maps/SKILL.md +8 -0
  400. package/Resources/skills/menu-bar/SKILL.md +36 -0
  401. package/Resources/skills/more-apps/SKILL.md +53 -0
  402. package/Resources/skills/phone-controllers/SKILL.md +79 -0
  403. package/Resources/skills/phone-pages/SKILL.md +173 -0
  404. package/Resources/skills/roku-developer-mode/SKILL.md +106 -0
  405. package/Resources/skills/scene-3d/SKILL.md +27 -0
  406. package/Resources/skills/scripting/SKILL.md +17 -0
  407. package/Resources/skills/share-extension/SKILL.md +22 -0
  408. package/Resources/skills/tv-design/SKILL.md +72 -0
  409. package/Resources/skills/web-app/SKILL.md +170 -0
  410. package/Resources/skills/web-game/SKILL.md +95 -0
  411. package/Resources/skills/web-or-native/SKILL.md +108 -0
  412. package/Resources/skills/wish-links/SKILL.md +156 -0
  413. package/THIRD_PARTY_NOTICES.md +170 -0
  414. package/cli/ai.mjs +237 -0
  415. package/cli/android.mjs +941 -0
  416. package/cli/app-ai.mjs +473 -0
  417. package/cli/browser.mjs +284 -0
  418. package/cli/calls.mjs +594 -0
  419. package/cli/dev.mjs +820 -0
  420. package/cli/devices.mjs +984 -0
  421. package/cli/lamp.mjs +1326 -0
  422. package/cli/lampapp.mjs +332 -0
  423. package/cli/lamps/android-host/LampPageGateway.kt +345 -0
  424. package/cli/lamps/android-host/app/build.gradle.kts +40 -0
  425. package/cli/lamps/android-host/build.gradle.kts +4 -0
  426. package/cli/lamps/android-host/game/AndroidManifest.xml +33 -0
  427. package/cli/lamps/android-host/game/MainActivity.kt +173 -0
  428. package/cli/lamps/android-host/gradle/libs.versions.toml +39 -0
  429. package/cli/lamps/android-host/gradle.properties +8 -0
  430. package/cli/lamps/android-host/page/AndroidManifest.xml +35 -0
  431. package/cli/lamps/android-host/page/MainActivity.kt +193 -0
  432. package/cli/lamps/android-host/settings.gradle.kts +30 -0
  433. package/cli/lamps/android-host/tools.json +43 -0
  434. package/cli/lamps/lamp-controllers.js +2 -0
  435. package/cli/lamps/lamp-for-games.js +6922 -0
  436. package/cli/lamps/lamp.js +7082 -0
  437. package/cli/lamps/mac-starter/.lamp/meta.json +1 -0
  438. package/cli/lamps/mac-starter/APP.md +12 -0
  439. package/cli/lamps/mac-starter/Package.swift +8 -0
  440. package/cli/lamps/mac-starter/Sources/App.swift +11 -0
  441. package/cli/lamps/mac-starter/Sources/ContentView.swift +17 -0
  442. package/cli/lamps/mac-starter/Sources/LampSupport.swift +18215 -0
  443. package/cli/lamps/mac-starter/build.sh +336 -0
  444. package/cli/lamps/mac-starter/gitignore +3 -0
  445. package/cli/lamps/mac-starter/lamp-starter.json +6 -0
  446. package/cli/lamps/web-starter/APP.md +8 -0
  447. package/cli/lamps/web-starter/app.js +1 -0
  448. package/cli/lamps/web-starter/index.html +17 -0
  449. package/cli/lamps/web-starter/lamp-starter.json +5 -0
  450. package/cli/lamps/web-starter/lamp.js +7082 -0
  451. package/cli/lamps/web-starter/style.css +25 -0
  452. package/cli/link.mjs +202 -0
  453. package/cli/local-ai.mjs +193 -0
  454. package/cli/mac.mjs +621 -0
  455. package/cli/mdns.mjs +205 -0
  456. package/cli/msix.mjs +413 -0
  457. package/cli/network.mjs +209 -0
  458. package/cli/openrouter.mjs +133 -0
  459. package/cli/outside.mjs +203 -0
  460. package/cli/page.js +317 -0
  461. package/cli/place.mjs +298 -0
  462. package/cli/png.mjs +184 -0
  463. package/cli/share.mjs +270 -0
  464. package/cli/skill/SKILL.md +280 -0
  465. package/cli/skills.mjs +71 -0
  466. package/cli/state.mjs +176 -0
  467. package/cli/update.mjs +162 -0
  468. package/package.json +20 -4
  469. package/site/lib/quota.js +59 -0
  470. package/site/lib/shared-wishes.js +1727 -0
@@ -0,0 +1,1430 @@
1
+ import { Break, Continue, Fn, If, Loop, abs, bool, cross, distance, div, dot, float, getScreenPosition, getViewPosition, int, luminance, max, min, mix, mul, nodeObject, normalize, orthographicDepthToViewZ, passTexture, perspectiveDepthToViewZ, reference, reflect, sub, texture, textureSize, trunc, uniform, uv, vec2, vec3, vec4, context, isBackgroundDepth, projectionDepth } from 'three/tsl';
2
+ import { HalfFloatType, LinearFilter, LinearMipmapLinearFilter, Matrix4, NodeMaterial, NodeUpdateType, QuadMesh, RenderTarget, RendererUtils, Node, Vector2, Vector3 } from 'three/webgpu';
3
+ import { bindAnalyticNoise } from '../utils/RNoise.js';
4
+ import { ENV_RAY_LENGTH, getSpecularDominantFactor, ggxReflectionSample } from '../utils/SpecularHelpers.js';
5
+ import { boxBlur } from './boxBlur.js';
6
+ import ImportanceSampledEnvironment from './ImportanceSampledEnvironment.js';
7
+
8
+ const _quadMesh = /*@__PURE__*/ new QuadMesh();
9
+ const _size = /*@__PURE__*/ new Vector2();
10
+ let _rendererState;
11
+
12
+ // Maximum ray-march step count; `quality` (0..1) scales it to a fixed per-ray count.
13
+ const MAX_STEPS = 64;
14
+
15
+ /**
16
+ * @typedef {Object} SSRNodeOptions
17
+ * @property {boolean} [stochastic=false] - When `false`, traces a single mirror reflection and softens roughness with a blur pass (first-generation SSR). When `true`, varies the reflection direction per pixel with stochastic GGX rays (second-generation SSR); higher quality on rough/glossy surfaces but noisier, so it expects a temporal/spatial denoiser downstream.
18
+ * @property {Node<float>} [metalnessNode=null] - Per-pixel metalness. Drives GGX reflection sampling and, with `reflectNonMetals=false`, the non-metal early-out.
19
+ * @property {Node<vec3>} [specularNode=null] - Stochastic mode only: material normal-incidence reflectance (F0), typically an MRT `specularColorBlended` attachment (it already includes IOR, specular intensity and metalness; raw `material.specularColor` reflects too brightly). Defaults to the metalness/base-color approximation.
20
+ * @property {Node<float>} [specularF90Node=null] - Stochastic mode only: material grazing reflectance, typically an MRT `specularF90` attachment. Defaults to one.
21
+ * @property {Node<float>} [roughnessNode=null] - Per-pixel roughness. Drives GGX sampling and the blur mip selection.
22
+ * @property {boolean} [reflectNonMetals=false] - Only used when `stochastic=false`. When `false`, non-metallic surfaces are discarded for a noticeable performance gain; set `true` to also reflect dielectrics (e.g. marble, polished wood, plastic).
23
+ * @property {Texture} [environmentNode=null] - Equirectangular HDR environment map with CPU-side `image.data` (e.g. from RGBELoader). Not compatible with PMREM / `scene.environment` cubemaps.
24
+ * @property {boolean} [envImportanceSampling=false] - When `true`, precomputes env-luminance CDF tables and uses MIS for environment misses. Build-time only.
25
+ * @property {Node} [diffuseNode=null] - Scene diffuse / base color. Defaults to `vec3(1)` in the shader when omitted.
26
+ * @property {boolean} [binaryRefine=false] - Sub-step binary-search refinement of detected hits. Compile-time constant (baked into the shader at construction).
27
+ * @property {Camera} [camera=null] - Camera the scene is rendered with. Inferred from the color pass when omitted.
28
+ */
29
+
30
+ /**
31
+ * Post processing node for computing screen space reflections (SSR).
32
+ *
33
+ * Reference: {@link https://lettier.github.io/3d-game-shaders-for-beginners/screen-space-reflection.html}
34
+ *
35
+ * @augments Node
36
+ * @three_import import { ssr } from 'three/addons/tsl/display/SSRNode.js';
37
+ */
38
+ class SSRNode extends Node {
39
+
40
+ static get type() {
41
+
42
+ return 'SSRNode';
43
+
44
+ }
45
+
46
+ /**
47
+ * Constructs a new SSR node.
48
+ *
49
+ * @param {Node<vec4>} colorNode - The node that represents the beauty pass.
50
+ * @param {Node<float>} depthNode - A node that represents the beauty pass's depth.
51
+ * @param {Node<vec3>} normalNode - A node that represents the beauty pass's normals.
52
+ * @param {SSRNodeOptions} [options] - Optional inputs for material and environment data.
53
+ */
54
+ constructor( colorNode, depthNode, normalNode, options = {} ) {
55
+
56
+ super( 'vec4' );
57
+
58
+ const {
59
+ stochastic = false,
60
+ metalnessNode = null,
61
+ specularNode = null,
62
+ specularF90Node = null,
63
+ roughnessNode = null,
64
+ reflectNonMetals = false,
65
+ environmentNode = null,
66
+ envImportanceSampling = false,
67
+ diffuseNode = null,
68
+ binaryRefine = false
69
+ } = options;
70
+
71
+ let camera = options.camera ?? null;
72
+
73
+ /**
74
+ * When `true`, the reflection direction is varied per pixel with stochastic GGX rays
75
+ * (second-generation SSR). When `false`, a single mirror reflection is traced and
76
+ * roughness is softened with a blur pass (first-generation SSR).
77
+ *
78
+ * @type {boolean}
79
+ */
80
+ this.stochastic = stochastic;
81
+
82
+ /**
83
+ * When `true`, env-luminance CDF tables are built and MIS is used for environment misses.
84
+ * Fixed at construction time.
85
+ *
86
+ * @type {boolean}
87
+ */
88
+ this.envImportanceSampling = envImportanceSampling;
89
+
90
+ /**
91
+ * The node that represents the beauty pass.
92
+ *
93
+ * @type {Node<vec4>}
94
+ */
95
+ this.colorNode = colorNode;
96
+
97
+ /**
98
+ * A node that represents the scene's diffuse color (typically the MRT `diffuseColor` attachment).
99
+ * When `null`, the shader uses `vec3(1)`.
100
+ *
101
+ * @type {?Node<vec4>}
102
+ */
103
+ this.diffuseNode = diffuseNode !== null ? nodeObject( diffuseNode ) : null;
104
+
105
+ /**
106
+ * A node that represents the beauty pass's depth.
107
+ *
108
+ * @type {Node<float>}
109
+ */
110
+ this.depthNode = depthNode;
111
+
112
+ /**
113
+ * A node that represents the beauty pass's normals.
114
+ *
115
+ * @type {Node<vec3>}
116
+ */
117
+ this.normalNode = normalNode;
118
+
119
+ /**
120
+ * Per-pixel metalness, used to drive the GGX reflection sampling and the non-metal
121
+ * early-out. When `null`, the shader treats surfaces as non-metallic.
122
+ *
123
+ * @type {?Node<float>}
124
+ */
125
+ this.metalnessNode = metalnessNode;
126
+
127
+ /**
128
+ * Stochastic mode only: per-pixel normal-incidence reflectance (F0), typically an MRT
129
+ * `specularColorBlended` attachment, which already includes IOR, specular intensity and
130
+ * metalness (raw `material.specularColor` reflects too brightly). When `null`, F0 is
131
+ * derived from metalness and the diffuse color.
132
+ *
133
+ * @type {?Node<vec3>}
134
+ * @default null
135
+ */
136
+ this.specularNode = specularNode;
137
+
138
+ /**
139
+ * Stochastic mode only: per-pixel grazing reflectance (F90), typically an MRT
140
+ * `specularF90` attachment. When `null`, the shader uses `1`.
141
+ *
142
+ * @type {?Node<float>}
143
+ * @default null
144
+ */
145
+ this.specularF90Node = specularF90Node;
146
+
147
+ /**
148
+ * Per-pixel roughness, used to drive the GGX reflection sampling and the blur mip
149
+ * selection. When `null`, the shader treats surfaces as fully smooth.
150
+ *
151
+ * @type {?Node<float>}
152
+ */
153
+ this.roughnessNode = roughnessNode;
154
+
155
+ /**
156
+ * Only used when {@link SSRNode#stochastic} is `false`. When `false`, non-metallic
157
+ * surfaces are discarded for a noticeable performance gain; set `true` to also
158
+ * reflect dielectrics. Baked into the shader as a compile-time constant; assigning a
159
+ * new value recompiles the SSR material.
160
+ *
161
+ * @type {boolean}
162
+ * @default false
163
+ */
164
+ this._reflectNonMetals = reflectNonMetals;
165
+
166
+ /**
167
+ * The resolution scale. Valid values are in the range
168
+ * `[0,1]`. `1` means best quality but also results in
169
+ * more computational overhead. Setting to `0.5` means
170
+ * the effect is computed in half-resolution.
171
+ *
172
+ * @type {number}
173
+ * @default 1
174
+ */
175
+ this.resolutionScale = 1;
176
+
177
+ /**
178
+ * The `updateBeforeType` is set to `NodeUpdateType.FRAME` since the node renders
179
+ * its effect once per frame in `updateBefore()`.
180
+ *
181
+ * @type {string}
182
+ * @default 'frame'
183
+ */
184
+ this.updateBeforeType = NodeUpdateType.FRAME;
185
+
186
+ /**
187
+ * Controls how far a fragment can reflect. Increasing this value result in more
188
+ * computational overhead but also increases the reflection distance.
189
+ *
190
+ * @type {UniformNode<float>}
191
+ */
192
+ this.maxDistance = uniform( 1 );
193
+
194
+ /**
195
+ * Controls the cutoff between what counts as a possible reflection hit and what does not.
196
+ *
197
+ * @type {UniformNode<float>}
198
+ */
199
+ this.thickness = uniform( 0.1 );
200
+
201
+ /**
202
+ * A multiplier for the overall reflection intensity. `1` leaves the
203
+ * reflections unchanged, lower values dim them and higher values boost them.
204
+ *
205
+ * @type {UniformNode<float>}
206
+ * @default 1
207
+ */
208
+ this.intensity = uniform( 1 );
209
+
210
+ /**
211
+ * Screen-edge fade width, in UV units. As a screen-space hit approaches a screen
212
+ * border, the reflection is faded over this distance — either toward the environment
213
+ * reflection ({@link SSRNode#screenEdgeFadeBlack} `false`) or to zero intensity
214
+ * (`true`). `0` disables it.
215
+ *
216
+ * @type {UniformNode<float>}
217
+ * @default 0.2
218
+ */
219
+ this.screenEdgeFade = uniform( 0.2 );
220
+
221
+ /**
222
+ * When `true`, SSR fades to zero near screen borders instead of blending toward
223
+ * the environment map. Hits are faded by the reflection sample UV; misses are
224
+ * faded by the surface pixel UV.
225
+ *
226
+ * Baked into the shader as a compile-time constant so the unused fade branch is
227
+ * eliminated; assigning a new value recompiles the SSR material.
228
+ *
229
+ * @type {boolean}
230
+ * @default false
231
+ */
232
+ this._screenEdgeFadeBlack = false;
233
+
234
+ /**
235
+ * Absolute env luminance cap. HDR env samples above this are scaled down (hue preserved).
236
+ *
237
+ * @type {UniformNode<float>}
238
+ * @default 10
239
+ */
240
+ this.maxLuminance = uniform( 10 );
241
+
242
+ /**
243
+ * This parameter controls how detailed the raymarching process works.
244
+ * The value ranges is `[0,1]` where `1` means best quality (the maximum number
245
+ * of raymarching iterations/samples) and `0` means no samples at all.
246
+ *
247
+ * A quality of `0.5` is usually sufficient for most use cases. Try to keep
248
+ * this parameter as low as possible. Larger values result in noticeable more
249
+ * overhead.
250
+ *
251
+ * @type {UniformNode<float>}
252
+ */
253
+ this.quality = uniform( 0.5 );
254
+
255
+ /**
256
+ * Mirror bias for the stochastic GGX sampling. Concentrates the reflected rays toward
257
+ * the lobe's narrow (near-mirror) core, trading sampling bias for less noise.
258
+ * `0` samples the full VNDF lobe; values toward `1` tighten the cone. Range `[0,1]`.
259
+ *
260
+ * @type {UniformNode<float>}
261
+ * @default 0
262
+ */
263
+ this.mirrorBias = uniform( 0 );
264
+
265
+ /**
266
+ * The quality of the blur. Must be an integer in the range `[1,3]`.
267
+ *
268
+ * Baked into the blur shader as a compile-time constant so the `(size*2+1)²`
269
+ * sample loop unrolls; assigning a new value recompiles the blur material.
270
+ *
271
+ * @type {number}
272
+ * @default 2
273
+ */
274
+ this._blurQuality = 2;
275
+
276
+ /**
277
+ * Enables sub-step binary-search refinement of a detected hit. When on, a coarse
278
+ * crossing is bisected toward the exact intersection (sharper hits, less step
279
+ * aliasing) at the cost of extra depth samples. Baked into the shader as a
280
+ * compile-time constant; assigning a new value rebuilds the SSR material.
281
+ *
282
+ * @type {boolean}
283
+ * @default false
284
+ */
285
+ this._binaryRefine = binaryRefine;
286
+
287
+ /**
288
+ * Non-linear step distribution exponent. `1` = uniform steps; `> 1` concentrates
289
+ * samples near the ray origin — where most short-range reflections are missed — and
290
+ * spaces them out toward maxDistance, as `s = (i / steps) ^ stepExponent`.
291
+ *
292
+ * Baked into the shader as a compile-time constant so `pow()` folds to a few
293
+ * multiplies; assigning a new value recompiles the SSR material. Only used by the
294
+ * stochastic reflection path.
295
+ *
296
+ * @type {number}
297
+ * @default 2
298
+ */
299
+ this._stepExponent = 2;
300
+
301
+ /**
302
+ * HDR environment map for screen-space misses.
303
+ *
304
+ * @type {?Texture}
305
+ */
306
+ this.environmentNode = environmentNode;
307
+
308
+ /**
309
+ * A node that represents the history texture for multi-bounce reflections.
310
+ *
311
+ * @type {?Texture}
312
+ */
313
+ this.historyTexture = null;
314
+
315
+ /**
316
+ * A node that represents the velocity texture for reprojection.
317
+ *
318
+ * @type {?Node<vec2>}
319
+ */
320
+ this.velocityTexture = null;
321
+
322
+ //
323
+
324
+ if ( camera === null ) {
325
+
326
+ if ( this.colorNode.passNode && this.colorNode.passNode.isPassNode === true ) {
327
+
328
+ camera = this.colorNode.passNode.camera;
329
+
330
+ } else {
331
+
332
+ throw new Error( 'THREE.SSRNode: No camera found. ssr() requires a camera.' );
333
+
334
+ }
335
+
336
+ }
337
+
338
+ /**
339
+ * The camera the scene is rendered with.
340
+ *
341
+ * @type {Camera}
342
+ */
343
+ this.camera = camera;
344
+
345
+ /**
346
+ * The spread of the blur. Automatically set when generating mips.
347
+ *
348
+ * @private
349
+ * @type {UniformNode<int>}
350
+ */
351
+ this._blurSpread = uniform( 1 );
352
+
353
+ /**
354
+ * Represents the projection matrix of the scene's camera.
355
+ *
356
+ * @private
357
+ * @type {UniformNode<mat4>}
358
+ */
359
+ this._cameraProjectionMatrix = uniform( camera.projectionMatrix );
360
+
361
+ /**
362
+ * Represents the inverse projection matrix of the scene's camera.
363
+ *
364
+ * @private
365
+ * @type {UniformNode<mat4>}
366
+ */
367
+ this._cameraProjectionMatrixInverse = uniform( camera.projectionMatrixInverse );
368
+
369
+ /**
370
+ * Represents the near value of the scene's camera.
371
+ *
372
+ * @private
373
+ * @type {ReferenceNode<float>}
374
+ */
375
+ this._cameraNear = reference( 'near', 'float', camera );
376
+
377
+ /**
378
+ * Represents the far value of the scene's camera.
379
+ *
380
+ * @private
381
+ * @type {ReferenceNode<float>}
382
+ */
383
+ this._cameraFar = reference( 'far', 'float', camera );
384
+
385
+ this._cameraWorldMatrix = uniform( new Matrix4().copy( camera.matrixWorld ) );
386
+ this._cameraWorldPosition = uniform( new Vector3().copy( camera.position ) );
387
+
388
+ this._cameraViewMatrix = uniform( new Matrix4().copy( camera.matrixWorld ) );
389
+ this._cameraViewMatrixInverse = uniform( new Matrix4().copy( camera.matrixWorldInverse ) );
390
+
391
+ /**
392
+ * The resolution of the pass.
393
+ *
394
+ * @private
395
+ * @type {UniformNode<vec2>}
396
+ */
397
+ this._resolution = uniform( new Vector2() );
398
+
399
+ this._noiseIndex = uniform( 0 );
400
+
401
+ /**
402
+ * CDF-backed environment sampler. Created when {@link setEnvMap} is called.
403
+ *
404
+ * @private
405
+ * @type {?ImportanceSampledEnvironment}
406
+ */
407
+ this._importanceEnvironment = null;
408
+
409
+ /**
410
+ * Intensity multiplier applied to environment-map reflections on screen-space
411
+ * misses and at screen edges. Defaults to π to match the former hardcoded multiplier.
412
+ *
413
+ * @type {UniformNode<float>}
414
+ * @default Math.PI
415
+ */
416
+ this.environmentIntensity = uniform( Math.PI );
417
+
418
+ /**
419
+ * The render target the SSR is rendered into.
420
+ *
421
+ * @private
422
+ * @type {RenderTarget}
423
+ */
424
+ this._ssrRenderTarget = new RenderTarget( 1, 1, { depthBuffer: false, type: HalfFloatType } );
425
+ this._ssrRenderTarget.texture.name = 'SSRNode.SSR';
426
+
427
+ /**
428
+ * The render target for the blurred SSR reflections.
429
+ *
430
+ * @private
431
+ * @type {RenderTarget}
432
+ */
433
+ this._blurRenderTarget = new RenderTarget( 1, 1, { depthBuffer: false, type: HalfFloatType, minFilter: LinearMipmapLinearFilter, magFilter: LinearFilter } );
434
+ this._blurRenderTarget.texture.name = 'SSRNode.Blur';
435
+ this._blurRenderTarget.texture.mipmaps.push( {}, {}, {}, {}, {} );
436
+
437
+ /**
438
+ * The material that is used to render the effect.
439
+ *
440
+ * @private
441
+ * @type {NodeMaterial}
442
+ */
443
+ this._ssrMaterial = new NodeMaterial();
444
+ this._ssrMaterial.name = 'SSRNode.SSR';
445
+
446
+ /**
447
+ * The SSR fragment `Fn` and its shared context, captured in {@link SSRNode#setup}.
448
+ * Re-invoking the `Fn` produces a fresh node graph, which is how the baked
449
+ * compile-time constants are re-applied when they change (see {@link SSRNode#_buildSSRMaterial}).
450
+ *
451
+ * @private
452
+ */
453
+ this._ssrFn = null;
454
+ this._sharedContext = null;
455
+
456
+ /**
457
+ * The blur material.
458
+ *
459
+ * @private
460
+ * @type {NodeMaterial}
461
+ */
462
+ this._blurMaterial = new NodeMaterial();
463
+ this._blurMaterial.name = 'SSRNode.Blur';
464
+
465
+ /**
466
+ * The copy material.
467
+ *
468
+ * @private
469
+ * @type {NodeMaterial}
470
+ */
471
+ this._copyMaterial = new NodeMaterial();
472
+ this._copyMaterial.name = 'SSRNode.Copy';
473
+
474
+ /**
475
+ * The result of the effect is represented as a separate texture node.
476
+ *
477
+ * @private
478
+ * @type {PassTextureNode}
479
+ */
480
+ this._textureNode = passTexture( this, this._ssrRenderTarget.texture );
481
+
482
+ let blurredTextureNode = null;
483
+
484
+ if ( this.stochastic === false && this.roughnessNode !== null ) {
485
+
486
+ const mips = this._blurRenderTarget.texture.mipmaps.length - 1;
487
+ const r = this.roughnessNode;
488
+ const lod = r.mul( r ).mul( mips ).clamp( 0, mips );
489
+
490
+ blurredTextureNode = passTexture( this, this._blurRenderTarget.texture ).level( lod );
491
+
492
+ }
493
+
494
+ /**
495
+ * Holds the blurred SSR reflections.
496
+ *
497
+ * @private
498
+ * @type {?PassTextureNode}
499
+ */
500
+ this._blurredTextureNode = blurredTextureNode;
501
+
502
+ if ( environmentNode !== null && environmentNode.isTexture === true ) {
503
+
504
+ this.setEnvMap( environmentNode );
505
+
506
+ }
507
+
508
+ }
509
+
510
+ /**
511
+ * Non-linear step distribution exponent (compile-time constant). See the backing
512
+ * field for details. Assigning a new value recompiles the SSR material.
513
+ *
514
+ * @type {number}
515
+ */
516
+ get stepExponent() {
517
+
518
+ return this._stepExponent;
519
+
520
+ }
521
+
522
+ set stepExponent( value ) {
523
+
524
+ if ( value !== this._stepExponent ) {
525
+
526
+ this._stepExponent = value;
527
+ this._buildSSRMaterial();
528
+
529
+ }
530
+
531
+ }
532
+
533
+ /**
534
+ * Blur kernel size (compile-time constant). Assigning a new value recompiles the
535
+ * blur material.
536
+ *
537
+ * @type {number}
538
+ */
539
+ get blurQuality() {
540
+
541
+ return this._blurQuality;
542
+
543
+ }
544
+
545
+ set blurQuality( value ) {
546
+
547
+ if ( value !== this._blurQuality ) {
548
+
549
+ this._blurQuality = value;
550
+
551
+ // The size is baked into the boxBlur node tree, so rebuild it (recompiles the material).
552
+ if ( this.stochastic === false ) this._buildBlurMaterial();
553
+
554
+ }
555
+
556
+ }
557
+
558
+ /**
559
+ * Builds (or rebuilds) the blur material's node graph, baking the current
560
+ * {@link SSRNode#blurQuality} as the kernel size so the sample loop unrolls.
561
+ *
562
+ * @private
563
+ */
564
+ _buildBlurMaterial() {
565
+
566
+ this._blurMaterial.fragmentNode = boxBlur( texture( this._ssrRenderTarget.texture ), { size: this._blurQuality, separation: this._blurSpread } );
567
+ this._blurMaterial.needsUpdate = true;
568
+
569
+ }
570
+
571
+ /**
572
+ * Whether SSR fades to black near screen borders (compile-time constant). Assigning
573
+ * a new value recompiles the SSR material.
574
+ *
575
+ * @type {boolean}
576
+ */
577
+ get screenEdgeFadeBlack() {
578
+
579
+ return this._screenEdgeFadeBlack;
580
+
581
+ }
582
+
583
+ set screenEdgeFadeBlack( value ) {
584
+
585
+ if ( value !== this._screenEdgeFadeBlack ) {
586
+
587
+ this._screenEdgeFadeBlack = value;
588
+ this._buildSSRMaterial();
589
+
590
+ }
591
+
592
+ }
593
+
594
+ /**
595
+ * Whether sub-step binary-search hit refinement is enabled (compile-time constant).
596
+ * Assigning a new value rebuilds the SSR material.
597
+ *
598
+ * @type {boolean}
599
+ */
600
+ get binaryRefine() {
601
+
602
+ return this._binaryRefine;
603
+
604
+ }
605
+
606
+ set binaryRefine( value ) {
607
+
608
+ if ( value !== this._binaryRefine ) {
609
+
610
+ this._binaryRefine = value;
611
+ this._buildSSRMaterial();
612
+
613
+ }
614
+
615
+ }
616
+
617
+ /**
618
+ * Whether dielectrics are reflected in the non-stochastic path (compile-time constant).
619
+ * Assigning a new value rebuilds the SSR material.
620
+ *
621
+ * @type {boolean}
622
+ */
623
+ get reflectNonMetals() {
624
+
625
+ return this._reflectNonMetals;
626
+
627
+ }
628
+
629
+ set reflectNonMetals( value ) {
630
+
631
+ if ( value !== this._reflectNonMetals ) {
632
+
633
+ this._reflectNonMetals = value;
634
+ this._buildSSRMaterial();
635
+
636
+ }
637
+
638
+ }
639
+
640
+ /**
641
+ * Rebuilds the SSR material's node graph by re-invoking the fragment `Fn`, which
642
+ * re-bakes the compile-time constants ({@link SSRNode#binaryRefine},
643
+ * {@link SSRNode#stepExponent}, {@link SSRNode#screenEdgeFadeBlack}) at their current
644
+ * values. A no-op until {@link SSRNode#setup} has captured the `Fn`.
645
+ *
646
+ * @private
647
+ */
648
+ _buildSSRMaterial() {
649
+
650
+ if ( this._ssrFn === null ) return;
651
+
652
+ this._ssrMaterial.contextNode = context( this._sharedContext );
653
+ this._ssrMaterial.fragmentNode = this._ssrFn();
654
+ this._ssrMaterial.needsUpdate = true;
655
+
656
+ }
657
+
658
+ /**
659
+ * Returns the result of the effect as a texture node.
660
+ *
661
+ * @return {PassTextureNode} A texture node that represents the result of the effect.
662
+ */
663
+ getTextureNode() {
664
+
665
+ return ( this.stochastic === false && this.roughnessNode !== null ) ? this._blurredTextureNode : this._textureNode;
666
+
667
+ }
668
+
669
+ /**
670
+ * Sets the size of the effect.
671
+ *
672
+ * @param {number} width - The width of the effect.
673
+ * @param {number} height - The height of the effect.
674
+ */
675
+ setSize( width, height ) {
676
+
677
+ width = Math.round( this.resolutionScale * width );
678
+ height = Math.round( this.resolutionScale * height );
679
+
680
+ this._resolution.value.set( width, height );
681
+ this._ssrRenderTarget.setSize( width, height );
682
+ this._blurRenderTarget.setSize( width, height );
683
+
684
+ }
685
+
686
+ /**
687
+ * Wires the feedback inputs for multi-bounce reflections: the previous frame's
688
+ * denoised result (`history`) and the velocity buffer used to reproject it
689
+ * (`velocity`). `history` accepts the producing node (e.g. a
690
+ * {@link RecurrentDenoiseNode}) — its output render target is used — or a raw
691
+ * texture. Pass `null` for both to disable multi-bounce.
692
+ *
693
+ * @param {Texture} history
694
+ * @param {Node<vec2>} velocity
695
+ */
696
+ setHistory( history, velocity ) {
697
+
698
+ this.historyTexture = ( history && typeof history.getRenderTarget === 'function' )
699
+ ? history.getRenderTarget().texture
700
+ : history;
701
+ this.velocityTexture = velocity;
702
+
703
+ }
704
+
705
+ /**
706
+ * Sets the environment map for importance-sampled env lighting when
707
+ * screen-space rays miss. Call this whenever the scene's env map changes.
708
+ *
709
+ * Uses {@link ImportanceSampledEnvironment} (CDF + MIS adapted from
710
+ * [three-gpu-pathtracer](https://github.com/gkjohnson/three-gpu-pathtracer)).
711
+ *
712
+ * @param {Texture|null} hdr - The equirectangular HDR environment map, or null to disable.
713
+ * @see {@link https://github.com/gkjohnson/three-gpu-pathtracer}
714
+ */
715
+ setEnvMap( hdr ) {
716
+
717
+ if ( hdr === null ) {
718
+
719
+ if ( this._importanceEnvironment !== null ) {
720
+
721
+ this._importanceEnvironment.clear();
722
+ this._importanceEnvironment = null;
723
+
724
+ }
725
+
726
+ this._buildSSRMaterial();
727
+ return;
728
+
729
+ }
730
+
731
+ if ( hdr.image === undefined || hdr.image.data === undefined ) {
732
+
733
+ console.warn( 'SSRNode: `environmentNode` / `setEnvMap()` expects an equirectangular HDR texture with CPU-side image data (e.g. RGBELoader). PMREM cubemaps and `scene.environment` are not supported.' );
734
+ return;
735
+
736
+ }
737
+
738
+ if ( this._importanceEnvironment === null ) {
739
+
740
+ this._importanceEnvironment = new ImportanceSampledEnvironment( this.envImportanceSampling );
741
+
742
+ }
743
+
744
+ this._importanceEnvironment.updateFrom( hdr );
745
+ this._buildSSRMaterial();
746
+
747
+ }
748
+
749
+ /**
750
+ * Intensity multiplier for the importance-sampled env contribution.
751
+ * Only available after {@link setEnvMap} has been called.
752
+ *
753
+ * @type {?UniformNode<float>}
754
+ */
755
+ get envMapIntensity() {
756
+
757
+ return this._importanceEnvironment !== null ? this._importanceEnvironment.intensity : null;
758
+
759
+ }
760
+
761
+ /**
762
+ * This method is used to render the effect once per frame.
763
+ *
764
+ * @param {NodeFrame} frame - The current node frame.
765
+ */
766
+ updateBefore( frame ) {
767
+
768
+ const { renderer } = frame;
769
+
770
+ this._cameraWorldMatrix.value.copy( this.camera.matrixWorld );
771
+ this._cameraWorldPosition.value.copy( this.camera.position );
772
+
773
+ _rendererState = RendererUtils.resetRendererState( renderer, _rendererState );
774
+
775
+ const ssrRenderTarget = this._ssrRenderTarget;
776
+ const blurRenderTarget = this._blurRenderTarget;
777
+
778
+ const size = renderer.getDrawingBufferSize( _size );
779
+
780
+ _quadMesh.material = this._ssrMaterial;
781
+
782
+ this.setSize( size.width, size.height );
783
+
784
+ // Advance the noise index once per frame (matches SSGI / Denoise).
785
+ this._noiseIndex.value = ( this._noiseIndex.value + 1 ) % 0x7fffffff;
786
+
787
+ // clear
788
+
789
+ renderer.setMRT( null );
790
+ renderer.setClearColor( 0x000000, 0 );
791
+
792
+ // ssr
793
+
794
+ renderer.setRenderTarget( ssrRenderTarget );
795
+ _quadMesh.name = 'SSR [ Reflections ]';
796
+ _quadMesh.render( renderer );
797
+
798
+ // blur (optional)
799
+
800
+ if ( this.stochastic === false && this.roughnessNode !== null ) {
801
+
802
+ // blur mips but leave the base mip unblurred
803
+
804
+ for ( let i = 0; i < blurRenderTarget.texture.mipmaps.length; i ++ ) {
805
+
806
+ _quadMesh.material = ( i === 0 ) ? this._copyMaterial : this._blurMaterial;
807
+
808
+ this._blurSpread.value = i;
809
+ renderer.setRenderTarget( blurRenderTarget, 0, i );
810
+ _quadMesh.name = 'SSR [ Blur Level ' + i + ' ]';
811
+ _quadMesh.render( renderer );
812
+
813
+ }
814
+
815
+ }
816
+
817
+ // restore
818
+
819
+ RendererUtils.restoreRendererState( renderer, _rendererState );
820
+
821
+ }
822
+
823
+ /**
824
+ * This method is used to setup the effect's TSL code.
825
+ *
826
+ * @param {NodeBuilder} builder - The current node builder.
827
+ * @return {PassTextureNode}
828
+ */
829
+ setup( builder ) {
830
+
831
+ const uvNode = uv();
832
+
833
+ const pointToLineDistance = Fn( ( [ point, linePointA, linePointB ] ) => {
834
+
835
+ // https://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html
836
+
837
+ return cross( point.sub( linePointA ), point.sub( linePointB ) ).length().div( linePointB.sub( linePointA ).length() );
838
+
839
+ }, { point: 'vec3', linePointA: 'vec3', linePointB: 'vec3', return: 'float' } );
840
+
841
+ const pointPlaneDistance = Fn( ( [ point, planePoint, planeNormal ] ) => {
842
+
843
+ // https://mathworld.wolfram.com/Point-PlaneDistance.html
844
+ // https://en.wikipedia.org/wiki/Plane_(geometry)
845
+ // http://paulbourke.net/geometry/pointlineplane/
846
+
847
+ // planeNormal is already normalized, so the denominator is 1.
848
+ const d = mul( planeNormal.x, planePoint.x ).add( mul( planeNormal.y, planePoint.y ) ).add( mul( planeNormal.z, planePoint.z ) ).negate().toVar();
849
+ const distance = mul( planeNormal.x, point.x ).add( mul( planeNormal.y, point.y ) ).add( mul( planeNormal.z, point.z ) ).add( d );
850
+ return distance;
851
+
852
+ }, { point: 'vec3', planePoint: 'vec3', planeNormal: 'vec3', return: 'float' } );
853
+
854
+ const getViewZ = Fn( ( [ depth ] ) => {
855
+
856
+ let viewZNode;
857
+
858
+ if ( this.camera.isPerspectiveCamera ) {
859
+
860
+ viewZNode = perspectiveDepthToViewZ( depth, this._cameraNear, this._cameraFar );
861
+
862
+ } else {
863
+
864
+ viewZNode = orthographicDepthToViewZ( depth, this._cameraNear, this._cameraFar );
865
+
866
+ }
867
+
868
+ return viewZNode;
869
+
870
+ } );
871
+
872
+ const sampleDepth = ( uv ) => projectionDepth( this.depthNode.sample( uv ).r, this._cameraNear, this._cameraFar );
873
+
874
+ const sampleMarchNoise = this.stochastic === true ? bindAnalyticNoise( this._resolution, 47 ) : null;
875
+
876
+ const computeScreenBorderFactor = Fn( ( [ uvCoord, borderWidth ] ) => {
877
+
878
+ const border = borderWidth.max( 1e-4 );
879
+
880
+ // Distance to the nearest screen edge — uniform falloff at corners.
881
+ const edgeDist = min(
882
+ min( uvCoord.x, float( 1 ).sub( uvCoord.x ) ),
883
+ min( uvCoord.y, float( 1 ).sub( uvCoord.y ) )
884
+ );
885
+
886
+ // Two smoothsteps for a softer ease-in-out than a single ramp.
887
+ const t = edgeDist.smoothstep( 0, border );
888
+
889
+ return t.smoothstep( 0, 1 ).pow( 0.125 );
890
+
891
+ }, { uvCoord: 'vec2', borderWidth: 'float', return: 'float' } );
892
+
893
+ const ssr = Fn( () => {
894
+
895
+ const noise = this.stochastic === true ? sampleMarchNoise( uvNode, this._noiseIndex ) : null;
896
+ // reconstruct at the depth texel center
897
+
898
+ const depthSize = vec2( textureSize( this.depthNode ) ).toConst();
899
+ const uvPos = uvNode.mul( depthSize ).floor().add( 0.5 ).div( depthSize ).toVar();
900
+
901
+ const depth = sampleDepth( uvPos ).toVar();
902
+
903
+ // Skip background pixels (cleared far-plane depth); the target is cleared each frame.
904
+ isBackgroundDepth( depth ).discard();
905
+
906
+ const viewPosition = getViewPosition( uvPos, depth, this._cameraProjectionMatrixInverse ).toVar();
907
+ const worldPosition = this._cameraWorldMatrix.mul( vec4( viewPosition, 1.0 ) ).xyz.toVar();
908
+ const viewNormal = this.normalNode.rgb.normalize().toVar();
909
+
910
+ const viewIncidentDir = ( ( this.camera.isPerspectiveCamera ) ? normalize( viewPosition ) : vec3( 0, 0, - 1 ) ).toVar();
911
+
912
+ // The node system samples the metalness/roughness textures at the current uv,
913
+ // so no explicit sample() is needed here.
914
+ const metalness = float( this.metalnessNode );
915
+
916
+ if ( this.stochastic === false && this._reflectNonMetals === false ) {
917
+
918
+ metalness.lessThanEqual( 0.0 ).discard();
919
+
920
+ }
921
+
922
+ const roughness = float( this.roughnessNode );
923
+ const glossiness = min( roughness.div( 0.25 ), 1 ).oneMinus();
924
+ // Only the fade-to-black miss path reads this, and that path is baked out otherwise.
925
+ const surfaceBorderFactor = this.screenEdgeFadeBlack ? computeScreenBorderFactor( uvPos, this.screenEdgeFade ) : null;
926
+ const hitBorderWidth = this.screenEdgeFade.mul( glossiness );
927
+
928
+ const V = viewIncidentDir.negate().normalize().toVar();
929
+
930
+ let viewReflectDir, finalSampleWeight, specDominantFactor;
931
+ let sampleEnvReflection = null;
932
+
933
+ if ( this.stochastic === false ) {
934
+
935
+ viewReflectDir = reflect( viewIncidentDir, viewNormal ).normalize().toVar();
936
+ finalSampleWeight = vec3( metalness );
937
+ specDominantFactor = float( 1 );
938
+
939
+ } else {
940
+
941
+ const Xi = noise.toVar();
942
+ // mirror bias trades the unbiased GGX lobe for lower variance
943
+ Xi.y.assign( mix( Xi.y, 0.0, this.mirrorBias.mul( Xi.w.sqrt() ) ) );
944
+
945
+ // The base color only feeds the metalness F0 fallback.
946
+ const albedo = ( this.specularNode === null && this.diffuseNode !== null ? this.diffuseNode.sample( uvPos ).rgb : vec3( 1 ) ).toVar();
947
+ const ggxSample = ggxReflectionSample( viewNormal, V, roughness, metalness, albedo, Xi, this.specularNode, this.specularF90Node ?? 1 ).toVar();
948
+
949
+ // Sometimes the GGX sample is facing away from the surface, so we need to re-sample.
950
+ If( ggxSample.get( 'reflectDir' ).dot( viewNormal ).lessThan( 0 ), () => {
951
+
952
+ ggxSample.assign( ggxReflectionSample( viewNormal, V, roughness, metalness, albedo, Xi.add( Xi.mul( 7 ) ).fract(), this.specularNode, this.specularF90Node ?? 1 ) );
953
+
954
+ } );
955
+
956
+ viewReflectDir = ggxSample.get( 'reflectDir' ).toVar();
957
+ finalSampleWeight = ggxSample.get( 'sampleWeight' ).toVar();
958
+ specDominantFactor = getSpecularDominantFactor( ggxSample.get( 'NdotV' ), roughness ).toVar();
959
+
960
+ sampleEnvReflection = () => {
961
+
962
+ if ( this._importanceEnvironment === null ) return vec3( 0 );
963
+
964
+ const envColor = vec3( 0 ).toVar();
965
+
966
+ if ( this.envImportanceSampling ) {
967
+
968
+ const Xi2 = bindAnalyticNoise( this._resolution, 59 )( uvPos, this._noiseIndex );
969
+
970
+ envColor.assign( this._importanceEnvironment.sampleEnvironmentMIS( {
971
+ cameraWorldMatrix: this._cameraWorldMatrix,
972
+ viewReflectDir,
973
+ N: viewNormal,
974
+ V,
975
+ alpha: ggxSample.get( 'alpha' ),
976
+ f0: ggxSample.get( 'f0' ),
977
+ f90: ggxSample.get( 'f90' ),
978
+ Xi2
979
+ } ) );
980
+
981
+ } else {
982
+
983
+ envColor.assign( this._importanceEnvironment.sampleEnvironmentBRDF( {
984
+ cameraWorldMatrix: this._cameraWorldMatrix,
985
+ viewReflectDir,
986
+ N: viewNormal,
987
+ V,
988
+ alpha: ggxSample.get( 'alpha' ),
989
+ f0: ggxSample.get( 'f0' ),
990
+ f90: ggxSample.get( 'f90' )
991
+ } ) );
992
+
993
+ }
994
+
995
+ return envColor;
996
+
997
+ };
998
+
999
+ }
1000
+
1001
+ // Multi-bounce: fold in the previous frame's reflection at the hit point, reprojected by its
1002
+ // own motion. The (1 - history.a) decay damps the feedback. No-op until both textures are set.
1003
+ const reprojectHitPointHistory = ( uvHit, color ) => {
1004
+
1005
+ if ( ! ( this.historyTexture && this.velocityTexture ) ) return color;
1006
+
1007
+ const velocity = this.velocityTexture.sample( uvHit ).xy;
1008
+ const historyUV = uvHit.sub( velocity );
1009
+ const historyBounce = texture( this.historyTexture, historyUV ).toVar();
1010
+ const sampleDecay = historyBounce.a.oneMinus();
1011
+
1012
+ return color.add( historyBounce.rgb.mul( sampleDecay ) );
1013
+
1014
+ };
1015
+
1016
+ // Fades a screen-space hit near the screen borders, using the hit sample UV (where the
1017
+ // screen-space data was read). `screenEdgeFadeBlack` is baked, so the two modes branch in
1018
+ // JS: fade the reflection to black, or blend it toward the environment reflection.
1019
+ const applyHitEdgeFade = ( reflectColor, uvS, hitBorderWidth ) => {
1020
+
1021
+ if ( this.screenEdgeFadeBlack ) {
1022
+
1023
+ const hitBorderFactor = computeScreenBorderFactor( uvS, this.screenEdgeFade );
1024
+ reflectColor.rgb.mulAssign( hitBorderFactor );
1025
+
1026
+ } else {
1027
+
1028
+ const hitBorderFactor = computeScreenBorderFactor( uvS, hitBorderWidth );
1029
+
1030
+ If( hitBorderFactor.lessThan( 1 ), () => {
1031
+
1032
+ reflectColor.rgb.assign( mix( sampleEnvReflection().mul( this.environmentIntensity ), reflectColor.rgb, hitBorderFactor ) );
1033
+
1034
+ } );
1035
+
1036
+ }
1037
+
1038
+ };
1039
+
1040
+ const maxReflectRayLen = this.maxDistance.div( dot( viewIncidentDir.negate(), viewNormal ).max( 1e-4 ) ).toVar();
1041
+
1042
+ const d1viewPosition = viewPosition.add( viewReflectDir.mul( maxReflectRayLen ) ).toVar();
1043
+
1044
+ // Camera type is fixed at build time, so guard the near-plane clamp with a JS branch
1045
+ // rather than a runtime uniform (the orthographic case compiles it out entirely).
1046
+ if ( this.camera.isPerspectiveCamera ) {
1047
+
1048
+ If( d1viewPosition.z.greaterThan( this._cameraNear.negate() ), () => {
1049
+
1050
+ const t = sub( this._cameraNear.negate(), viewPosition.z ).div( viewReflectDir.z );
1051
+ d1viewPosition.assign( viewPosition.add( viewReflectDir.mul( t ) ) );
1052
+
1053
+ } );
1054
+
1055
+ }
1056
+
1057
+ const d0 = uvPos.mul( this._resolution ).xy.toVar();
1058
+ const d1 = getScreenPosition( d1viewPosition, this._cameraProjectionMatrix ).mul( this._resolution ).toVar();
1059
+
1060
+ // clip the ray to the screen so all steps land on visible texels
1061
+
1062
+ const extent = d1.sub( d0 ).toVar();
1063
+ const exitT = vec2(
1064
+ extent.x.greaterThanEqual( 0 ).select( this._resolution.x.sub( d0.x ), d0.x ),
1065
+ extent.y.greaterThanEqual( 0 ).select( this._resolution.y.sub( d0.y ), d0.y )
1066
+ ).div( extent.abs().max( 1e-6 ) );
1067
+ const clipT = min( exitT.x, exitT.y ).min( 1 ).toConst();
1068
+
1069
+ If( clipT.lessThan( 1 ), () => {
1070
+
1071
+ d1.assign( d0.add( extent.mul( clipT ) ) );
1072
+ d1viewPosition.assign( this.camera.isPerspectiveCamera
1073
+ ? mix( viewPosition.div( viewPosition.z ), d1viewPosition.div( d1viewPosition.z ), clipT ).div( mix( viewPosition.z.reciprocal(), d1viewPosition.z.reciprocal(), clipT ) )
1074
+ : mix( viewPosition, d1viewPosition, clipT ) );
1075
+
1076
+ } );
1077
+
1078
+ const xLen = d1.x.sub( d0.x ).toVar();
1079
+ const yLen = d1.y.sub( d0.y ).toVar();
1080
+
1081
+ // dominant-axis ray length in texels (used for the per-step floor below)
1082
+ const rayLen = max( xLen.abs(), yLen.abs() ).max( 1 ).toVar();
1083
+
1084
+ // Blur traces a single mirror ray, so spend steps in proportion to the ray's screen-space
1085
+ // length (cheap for the short rays that dominate). Scatter needs a fixed, bounded count for
1086
+ // coherent stochastic sampling; each step then spans the whole ray as rayVec / totalStep.
1087
+ const totalStep = int( this.stochastic === false
1088
+ ? trunc( max( abs( xLen ), abs( yLen ) ).mul( this.quality.clamp() ) ).max( int( 1 ) ).toConst()
1089
+ : this.quality.clamp().mul( MAX_STEPS ).max( float( 1 ) ) ).toConst();
1090
+
1091
+ const xSpan = xLen.div( totalStep ).toVar();
1092
+ const ySpan = yLen.div( totalStep ).toVar();
1093
+
1094
+ const stepVec = vec2( xSpan, ySpan ).toVar();
1095
+ const invResolution = vec2( float( 1 ), float( 1 ) ).div( this._resolution ).toVar();
1096
+ const uvPixelStepX = vec2( invResolution.x, float( 0 ) ).toVar();
1097
+
1098
+ const output = vec4( 0 ).toVar();
1099
+ const hit = float( 0 ).toVar();
1100
+
1101
+ // Reflected-ray view-space Z at ray parameter s ∈ [0,1] (linear in 1/z for perspective),
1102
+ // hoisted so the march and refinement evaluate it identically.
1103
+ const recipVPZ = float( 1 ).div( viewPosition.z ).toConst();
1104
+ const recipD1VPZ = float( 1 ).div( d1viewPosition.z ).toConst();
1105
+
1106
+ // Camera type is known at build time, so branch at compile time rather than via a runtime select.
1107
+ const reflectRayZAt = this.camera.isPerspectiveCamera
1108
+ ? ( sVal ) => float( 1 ).div( recipVPZ.add( sVal.mul( recipD1VPZ.sub( recipVPZ ) ) ) )
1109
+ : ( sVal ) => viewPosition.z.add( sVal.mul( d1viewPosition.z.sub( viewPosition.z ) ) );
1110
+
1111
+ // view-space point on the reflected ray at s
1112
+
1113
+ const rayPointAt = this.camera.isPerspectiveCamera
1114
+ ? ( sVal ) => mix( viewPosition.div( viewPosition.z ), d1viewPosition.div( d1viewPosition.z ), sVal ).mul( reflectRayZAt( sVal ) )
1115
+ : ( sVal ) => mix( viewPosition, d1viewPosition, sVal );
1116
+
1117
+ // Screen-space position along the ray for a given s ∈ [0,1].
1118
+ const screenPosAt = ( sVal ) => d0.add( stepVec.mul( sVal.mul( totalStep ) ) );
1119
+
1120
+ // Ray parameter s ∈ [0,1] for step `idx`. Blur marches uniformly (matching the original loop:
1121
+ // one ~texel step per iteration). Scatter uses an exponential remap `(idx/steps)^stepExponent`
1122
+ // that concentrates samples near the origin, floored to ≥1 texel/step; `jitter` dissolves banding.
1123
+ const sampleFraction = this.stochastic === false
1124
+ ? ( idx ) => idx.div( totalStep )
1125
+ : ( idx ) => max(
1126
+ idx.add( noise.z.sub( 0.5 ) ).div( totalStep ).pow( this.stepExponent ),
1127
+ idx.div( rayLen )
1128
+ );
1129
+
1130
+ // Carry the hit out of the loop so refinement runs after the march, not nested inside it (a
1131
+ // loop-inside-a-loop tripped shader-compiler bugs on some drivers). hitSLo/hitSHi bracket s.
1132
+ const foundHit = bool( false ).toVar();
1133
+ const hitSLo = float( 0 ).toVar();
1134
+ const hitSHi = float( 0 ).toVar();
1135
+ // Carry the coarse hit's UV/depth to skip a redundant fetch when refinement is off.
1136
+ const hitUvS = vec2( 0 ).toVar();
1137
+ const hitD = float( 0 ).toVar();
1138
+ const previousS = float( 0 ).toVar();
1139
+ const previousInFront = bool( true ).toVar();
1140
+ const canRefine = bool( false ).toVar();
1141
+
1142
+ // March from d0 toward d1, looking for an intersection with the depth buffer.
1143
+ Loop( { start: int( 1 ), end: totalStep }, ( { i } ) => {
1144
+
1145
+ // Exponentially-distributed ray parameter, shared by the sample position and ray depth.
1146
+ const s = sampleFraction( float( i ) ).toVar();
1147
+
1148
+ If( s.greaterThan( 1 ), () => {
1149
+
1150
+ Break();
1151
+
1152
+ } );
1153
+
1154
+ const xy = screenPosAt( s ).toVar();
1155
+
1156
+ If( xy.x.lessThan( 0 ).or( xy.x.greaterThan( this._resolution.x ) ).or( xy.y.lessThan( 0 ) ).or( xy.y.greaterThan( this._resolution.y ) ), () => {
1157
+
1158
+ Break();
1159
+
1160
+ } );
1161
+
1162
+ const uvS = xy.mul( invResolution ).toVar();
1163
+ const d = sampleDepth( uvS ).toVar();
1164
+ const vZ = getViewZ( d ).toVar();
1165
+
1166
+ const viewReflectRayZ = reflectRayZAt( s ).toVar();
1167
+
1168
+ // Advance the previous sample before any Continue() so rejected samples still bound the next bracket.
1169
+ const lastS = previousS.toVar();
1170
+ const lastInFront = previousInFront.toVar();
1171
+ previousS.assign( s );
1172
+ previousInFront.assign( viewReflectRayZ.greaterThan( vZ ) );
1173
+
1174
+ If( isBackgroundDepth( d ).not().and( viewReflectRayZ.lessThanEqual( vZ ) ), () => {
1175
+
1176
+ // Depth crossing: ray went behind the depth buffer. Gate by thickness before stopping
1177
+ // so an occluder gap doesn't end the march prematurely.
1178
+ const vP = getViewPosition( uvS, d, this._cameraProjectionMatrixInverse ).toVar();
1179
+ const away = pointToLineDistance( vP, viewPosition, d1viewPosition ).toVar();
1180
+
1181
+ const uvNeighbor = uvS.add( uvPixelStepX ).toVar();
1182
+ const vPNeighbor = getViewPosition( uvNeighbor, d, this._cameraProjectionMatrixInverse ).toVar();
1183
+ const minThickness = vPNeighbor.x.sub( vP.x ).mul( 3 ).toVar();
1184
+ // Only refinement may use a wider coarse tolerance.
1185
+
1186
+ const stepLength = distance( rayPointAt( lastS ), rayPointAt( s ) );
1187
+ const tk = ( this.binaryRefine ? max( max( minThickness, this.thickness ), stepLength ) : max( minThickness, this.thickness ) ).toVar();
1188
+
1189
+ If( away.lessThanEqual( tk ), () => {
1190
+
1191
+ const vN = this.normalNode.sample( uvS ).rgb.normalize().toVar();
1192
+
1193
+ // the reflected ray is pointing towards the same side as the fragment's normal (current ray position),
1194
+ // which means it wouldn't reflect off the surface. The loop continues to the next step for the next ray sample.
1195
+ If( dot( viewReflectDir, vN ).greaterThanEqual( 0 ), () => {
1196
+
1197
+ Continue();
1198
+
1199
+ } );
1200
+
1201
+ if ( this.stochastic === false ) {
1202
+
1203
+ // this distance represents the depth of the intersection point between the reflected ray and the scene.
1204
+ const distance = pointPlaneDistance( vP, viewPosition, viewNormal ).toVar();
1205
+
1206
+ // Distance exceeding limit: The reflection is potentially too far away and
1207
+ // might not contribute significantly to the final color
1208
+ If( distance.greaterThan( this.maxDistance ), () => {
1209
+
1210
+ Break();
1211
+
1212
+ } );
1213
+
1214
+ }
1215
+
1216
+ foundHit.assign( true );
1217
+ hitUvS.assign( uvS );
1218
+ hitD.assign( d );
1219
+
1220
+ if ( this.binaryRefine ) {
1221
+
1222
+ // refine only front-to-back crossings
1223
+
1224
+ canRefine.assign( lastInFront );
1225
+ hitSLo.assign( lastS );
1226
+ hitSHi.assign( s );
1227
+
1228
+ }
1229
+
1230
+ Break();
1231
+
1232
+
1233
+ } );
1234
+
1235
+ } );
1236
+
1237
+ } );
1238
+
1239
+ If( foundHit, () => {
1240
+
1241
+ // Bisect the bracketed crossing toward the exact intersection. Run after the march, not
1242
+ // nested (a loop-inside-a-loop tripped shader-compiler bugs on some drivers).
1243
+ if ( this.binaryRefine ) {
1244
+
1245
+ If( canRefine, () => {
1246
+
1247
+ Loop( { start: int( 0 ), end: int( 8 ), type: 'int', condition: '<' }, () => {
1248
+
1249
+ const sMid = hitSLo.add( hitSHi ).mul( 0.5 ).toVar();
1250
+ const uvMid = screenPosAt( sMid ).mul( invResolution ).toConst();
1251
+ const sceneZMid = getViewZ( sampleDepth( uvMid ) );
1252
+ const frontFacing = dot( viewReflectDir, this.normalNode.sample( uvMid ).rgb.normalize() ).lessThan( 0 );
1253
+
1254
+ If( reflectRayZAt( sMid ).lessThanEqual( sceneZMid ).and( frontFacing ), () => {
1255
+
1256
+ hitSHi.assign( sMid );
1257
+
1258
+ } ).Else( () => {
1259
+
1260
+ hitSLo.assign( sMid );
1261
+
1262
+ } );
1263
+
1264
+ } );
1265
+
1266
+ // re-fetch UV/depth at the refined `s`
1267
+
1268
+ hitUvS.assign( screenPosAt( hitSHi ).mul( invResolution ) );
1269
+ hitD.assign( sampleDepth( hitUvS ) );
1270
+
1271
+ } );
1272
+
1273
+ }
1274
+
1275
+ // Shade the hit, reusing the depth fetched during the march (or refinement).
1276
+ const uvS = hitUvS;
1277
+ const vP = getViewPosition( uvS, hitD, this._cameraProjectionMatrixInverse ).toVar();
1278
+
1279
+ // In blur mode the ratio² falloff re-grows past maxDistance, so over-range hits fall back
1280
+ // to env. The scatter path bounds reach via ray length, so every hit shades.
1281
+ const distancePointPlane = this.stochastic === false ? pointPlaneDistance( vP, viewPosition, viewNormal ).toVar() : float( 0 );
1282
+ const withinRange = distancePointPlane.lessThanEqual( this.maxDistance ).toVar();
1283
+
1284
+ if ( this.binaryRefine ) {
1285
+
1286
+ // bisection can land on a depth discontinuity, so validate the refined hit
1287
+
1288
+ const neighbor = getViewPosition( uvS.add( uvPixelStepX ), hitD, this._cameraProjectionMatrixInverse );
1289
+ const tk = max( neighbor.x.sub( vP.x ).mul( 3 ), this.thickness );
1290
+ withinRange.assign( withinRange.and( isBackgroundDepth( hitD ).not() )
1291
+ .and( pointToLineDistance( vP, viewPosition, d1viewPosition ).lessThanEqual( tk ) ) );
1292
+
1293
+ withinRange.assign( withinRange.and( dot( viewReflectDir, this.normalNode.sample( uvS ).rgb.normalize() ).lessThan( 0 ) ) );
1294
+
1295
+ }
1296
+
1297
+ If( withinRange, () => {
1298
+
1299
+ const hitWorldPosition = this._cameraWorldMatrix.mul( vec4( vP, 1.0 ) ).xyz.toVar();
1300
+ const worldDistance = distance( worldPosition, hitWorldPosition ).mul( specDominantFactor ).toVar();
1301
+
1302
+ const reflectColor = this.colorNode.sample( uvS ).toVar();
1303
+
1304
+ // Multi-bounce: add the reprojected previous-frame reflection at the hit point.
1305
+ reflectColor.rgb.assign( reprojectHitPointHistory( uvS, reflectColor.rgb ) );
1306
+
1307
+ if ( this.stochastic === true ) applyHitEdgeFade( reflectColor, uvS, hitBorderWidth );
1308
+
1309
+ // The scatter (GGX) path bakes distance/grazing response into finalSampleWeight.
1310
+ // The mirror/blur path is a plain reflection, so reapply upstream's squared
1311
+ // distance attenuation and grazing Fresnel here to match its falloff.
1312
+ let weightedColor = reflectColor.rgb.mul( finalSampleWeight );
1313
+
1314
+ if ( this.stochastic === false ) {
1315
+
1316
+ const ratio = float( 1 ).sub( distancePointPlane.div( this.maxDistance ) ).toVar();
1317
+ const attenuation = ratio.mul( ratio ).toVar();
1318
+ const fresnelCoe = div( dot( viewIncidentDir, viewReflectDir ).add( 1 ), 2 ).toVar();
1319
+ weightedColor = weightedColor.mul( attenuation.mul( fresnelCoe ) );
1320
+
1321
+ }
1322
+
1323
+ hit.assign( 1 );
1324
+ output.assign( vec4( weightedColor, worldDistance ) );
1325
+
1326
+ } );
1327
+
1328
+ } );
1329
+
1330
+ // Screen-space ray missed: environment fallback (MIS when CDF env is set up).
1331
+ If( hit.equal( 0 ), () => {
1332
+
1333
+ if ( this.stochastic === true ) {
1334
+
1335
+ output.assign( vec4( sampleEnvReflection().mul( this.environmentIntensity ), float( ENV_RAY_LENGTH ) ) );
1336
+
1337
+ // Misses fade by the surface pixel UV (where the reflection is being shaded).
1338
+ if ( this.screenEdgeFadeBlack ) {
1339
+
1340
+ output.rgb.mulAssign( surfaceBorderFactor );
1341
+
1342
+ }
1343
+
1344
+ }
1345
+
1346
+ } );
1347
+
1348
+ const lum = luminance( output.rgb ).max( 1e-4 ).toVar();
1349
+ output.rgb.mulAssign( this.maxLuminance.div( lum ).min( 1 ) );
1350
+
1351
+ // scale the reflection color by the user-controlled intensity
1352
+ output.rgb.mulAssign( this.intensity );
1353
+
1354
+ return output.max( 0 );
1355
+
1356
+ } );
1357
+
1358
+
1359
+ this._ssrFn = ssr;
1360
+ this._sharedContext = builder.getSharedContext();
1361
+ this._buildSSRMaterial();
1362
+
1363
+ const reflectionBuffer = texture( this._ssrRenderTarget.texture );
1364
+
1365
+ if ( this.stochastic === false ) {
1366
+
1367
+ this._buildBlurMaterial();
1368
+
1369
+ }
1370
+
1371
+ this._copyMaterial.fragmentNode = reflectionBuffer;
1372
+ this._copyMaterial.needsUpdate = true;
1373
+
1374
+ //
1375
+
1376
+ return this.getTextureNode();
1377
+
1378
+ }
1379
+
1380
+ getRenderTarget() {
1381
+
1382
+ return this._ssrRenderTarget;
1383
+
1384
+ }
1385
+
1386
+ /**
1387
+ * Frees internal resources. This method should be called
1388
+ * when the effect is no longer required.
1389
+ */
1390
+ dispose() {
1391
+
1392
+ super.dispose();
1393
+
1394
+ this._ssrRenderTarget.dispose();
1395
+ this._blurRenderTarget.dispose();
1396
+
1397
+ this._ssrMaterial.dispose();
1398
+ this._blurMaterial.dispose();
1399
+ this._copyMaterial.dispose();
1400
+
1401
+ if ( this._importanceEnvironment !== null ) {
1402
+
1403
+ this._importanceEnvironment.dispose();
1404
+ this._importanceEnvironment = null;
1405
+
1406
+ }
1407
+
1408
+ }
1409
+
1410
+ }
1411
+
1412
+ export default SSRNode;
1413
+
1414
+ /**
1415
+ * TSL function for creating screen space reflections (SSR).
1416
+ *
1417
+ * @tsl
1418
+ * @function
1419
+ * @param {Node<vec4>} colorNode - The node that represents the beauty pass.
1420
+ * @param {Node<float>} depthNode - A node that represents the beauty pass's depth.
1421
+ * @param {Node<vec3>} normalNode - A node that represents the beauty pass's normals.
1422
+ * @param {SSRNodeOptions} [options] - Optional inputs for material and environment data.
1423
+ * @returns {SSRNode}
1424
+ */
1425
+ export const ssr = ( colorNode, depthNode, normalNode, options = {} ) => new SSRNode(
1426
+ nodeObject( colorNode ),
1427
+ nodeObject( depthNode ),
1428
+ nodeObject( normalNode ),
1429
+ options
1430
+ );