@driftengine/core 4.4.2 → 4.6.0

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 (339) hide show
  1. package/CHANGELOG.json +97 -0
  2. package/README.md +1 -1
  3. package/dist/geometry/boxCsg.d.ts +28 -0
  4. package/dist/geometry/boxCsg.js +139 -0
  5. package/dist/geometry/csg.d.ts +36 -0
  6. package/dist/geometry/csg.js +329 -0
  7. package/dist/geometry/meshBuilder.js +13 -0
  8. package/dist/geometry/meshConcat.js +1 -0
  9. package/dist/geometry/pixelFont.js +2 -0
  10. package/dist/geometry/solid.d.ts +61 -0
  11. package/dist/geometry/solid.js +152 -0
  12. package/dist/geometry/solidFlat.d.ts +35 -0
  13. package/dist/geometry/solidFlat.js +428 -0
  14. package/dist/geometry/solidHarness.d.ts +19 -0
  15. package/dist/geometry/solidHarness.js +66 -0
  16. package/dist/geometry/solidNormals.d.ts +17 -0
  17. package/dist/geometry/solidNormals.js +86 -0
  18. package/dist/geometry/solidRound.d.ts +41 -0
  19. package/dist/geometry/solidRound.js +323 -0
  20. package/dist/geometry/solidWriter.d.ts +16 -0
  21. package/dist/geometry/solidWriter.js +42 -0
  22. package/dist/index.d.ts +28 -3
  23. package/dist/index.js +20 -1
  24. package/dist/render/backend/api.d.ts +34 -14
  25. package/dist/render/backend/drawFog.d.ts +26 -0
  26. package/dist/render/backend/drawFog.js +30 -0
  27. package/dist/render/backend/materialChanges.d.ts +2 -1
  28. package/dist/render/backend/materialChanges.js +6 -1
  29. package/dist/render/backend/webgl2/glassTintPrograms.d.ts +13 -0
  30. package/dist/render/backend/webgl2/glassTintPrograms.js +38 -0
  31. package/dist/render/backend/webgl2/instanced.d.ts +24 -5
  32. package/dist/render/backend/webgl2/instanced.js +72 -15
  33. package/dist/render/backend/webgl2/renderer.d.ts +201 -16
  34. package/dist/render/backend/webgl2/renderer.js +596 -224
  35. package/dist/render/backend/webgpu/buffers.d.ts +29 -1
  36. package/dist/render/backend/webgpu/buffers.js +61 -4
  37. package/dist/render/backend/webgpu/depthPass.d.ts +1 -1
  38. package/dist/render/backend/webgpu/depthPass.js +7 -2
  39. package/dist/render/backend/webgpu/drawCommand.d.ts +5 -0
  40. package/dist/render/backend/webgpu/drawCommand.js +1 -0
  41. package/dist/render/backend/webgpu/flatPass.d.ts +6 -1
  42. package/dist/render/backend/webgpu/flatPass.js +57 -9
  43. package/dist/render/backend/webgpu/glassTintPass.d.ts +28 -0
  44. package/dist/render/backend/webgpu/glassTintPass.js +206 -0
  45. package/dist/render/backend/webgpu/gpuDrivenPass.d.ts +60 -1
  46. package/dist/render/backend/webgpu/gpuDrivenPass.js +305 -5
  47. package/dist/render/backend/webgpu/instanceCullPass.d.ts +34 -0
  48. package/dist/render/backend/webgpu/instanceCullPass.js +144 -0
  49. package/dist/render/backend/webgpu/instanced.d.ts +23 -2
  50. package/dist/render/backend/webgpu/instanced.js +41 -4
  51. package/dist/render/backend/webgpu/latePass.d.ts +30 -0
  52. package/dist/render/backend/webgpu/latePass.js +140 -0
  53. package/dist/render/backend/webgpu/lightVolumePass.js +5 -1
  54. package/dist/render/backend/webgpu/motionPass.d.ts +95 -0
  55. package/dist/render/backend/webgpu/motionPass.js +491 -0
  56. package/dist/render/backend/webgpu/pipelineCache.d.ts +10 -1
  57. package/dist/render/backend/webgpu/pipelineCache.js +11 -1
  58. package/dist/render/backend/webgpu/pointGlassTintPass.d.ts +32 -0
  59. package/dist/render/backend/webgpu/pointGlassTintPass.js +193 -0
  60. package/dist/render/backend/webgpu/pointShadowPass.d.ts +35 -6
  61. package/dist/render/backend/webgpu/pointShadowPass.js +105 -20
  62. package/dist/render/backend/webgpu/postPass.d.ts +3 -13
  63. package/dist/render/backend/webgpu/renderer.d.ts +271 -64
  64. package/dist/render/backend/webgpu/renderer.js +1395 -580
  65. package/dist/render/backend/webgpu/scatterPass.js +2 -1
  66. package/dist/render/backend/webgpu/sdfTextPass.js +6 -1
  67. package/dist/render/backend/webgpu/shaders/instanceCull.wgsl.d.ts +18 -0
  68. package/dist/render/backend/webgpu/shaders/instanceCull.wgsl.js +59 -0
  69. package/dist/render/backend/webgpu/skinPaletteRing.d.ts +4 -0
  70. package/dist/render/backend/webgpu/skinPaletteRing.js +4 -0
  71. package/dist/render/backend/webgpu/snapshotMips.d.ts +29 -0
  72. package/dist/render/backend/webgpu/snapshotMips.js +52 -0
  73. package/dist/render/backend/webgpu/surfaceTexturePass.d.ts +22 -3
  74. package/dist/render/backend/webgpu/surfaceTexturePass.js +78 -39
  75. package/dist/render/driftLight/bake.d.ts +7 -0
  76. package/dist/render/driftLight/bake.js +61 -56
  77. package/dist/render/driftLight/denseField.d.ts +46 -0
  78. package/dist/render/driftLight/denseField.js +109 -0
  79. package/dist/render/driftLight/lightField.d.ts +10 -5
  80. package/dist/render/driftLight/lightField.js +25 -19
  81. package/dist/render/driftLight/presence.d.ts +50 -0
  82. package/dist/render/driftLight/presence.js +43 -0
  83. package/dist/render/driftLight/uniforms.d.ts +3 -3
  84. package/dist/render/driftLight/uniforms.js +5 -6
  85. package/dist/render/driftLight/worldLightField.d.ts +41 -0
  86. package/dist/render/driftLight/worldLightField.js +66 -0
  87. package/dist/render/fixtureAtlas.d.ts +20 -0
  88. package/dist/render/fixtureAtlas.js +49 -0
  89. package/dist/render/glass.d.ts +45 -0
  90. package/dist/render/glass.js +39 -0
  91. package/dist/render/glassCasters.d.ts +40 -0
  92. package/dist/render/glassCasters.js +84 -0
  93. package/dist/render/glassShadow.d.ts +78 -0
  94. package/dist/render/glassShadow.js +125 -0
  95. package/dist/render/globalMediumPass.d.ts +2 -3
  96. package/dist/render/globalMediumPass.js +2 -8
  97. package/dist/render/gpudriven/lit.d.ts +12 -0
  98. package/dist/render/gpudriven/lit.js +23 -0
  99. package/dist/render/gpudriven/materialTable.d.ts +15 -5
  100. package/dist/render/gpudriven/materialTable.js +26 -6
  101. package/dist/render/gpudriven/pipeline.d.ts +1 -1
  102. package/dist/render/gpudriven/pipeline.js +4 -3
  103. package/dist/render/gpudriven/sunGlass.d.ts +35 -0
  104. package/dist/render/gpudriven/sunGlass.js +89 -0
  105. package/dist/render/instanceCull.d.ts +63 -0
  106. package/dist/render/instanceCull.js +160 -0
  107. package/dist/render/instances.d.ts +15 -0
  108. package/dist/render/lightBudget.d.ts +36 -35
  109. package/dist/render/lightBudget.js +38 -37
  110. package/dist/render/lightGrid.d.ts +42 -0
  111. package/dist/render/lightGrid.js +87 -0
  112. package/dist/render/mesh.d.ts +18 -24
  113. package/dist/render/mesh.js +51 -68
  114. package/dist/render/occlusion.d.ts +10 -0
  115. package/dist/render/occlusion.js +36 -7
  116. package/dist/render/pointGlassTint.d.ts +59 -0
  117. package/dist/render/pointGlassTint.js +198 -0
  118. package/dist/render/pointLightSelection.d.ts +7 -0
  119. package/dist/render/pointLightSelection.js +29 -4
  120. package/dist/render/pointShadowArray.d.ts +56 -3
  121. package/dist/render/pointShadowArray.js +127 -16
  122. package/dist/render/pointShadowMap.d.ts +23 -1
  123. package/dist/render/pointShadowMap.js +27 -1
  124. package/dist/render/rainField.d.ts +13 -0
  125. package/dist/render/rainField.js +27 -5
  126. package/dist/render/recon/changeFrames.d.ts +15 -0
  127. package/dist/render/recon/changeFrames.js +21 -0
  128. package/dist/render/recon/lateDepth.d.ts +11 -0
  129. package/dist/render/recon/lateDepth.js +70 -0
  130. package/dist/render/recon/lateRouting.d.ts +14 -0
  131. package/dist/render/recon/lateRouting.js +18 -0
  132. package/dist/render/recon/mover.d.ts +57 -0
  133. package/dist/render/recon/mover.js +86 -0
  134. package/dist/render/recon/resolve.d.ts +34 -4
  135. package/dist/render/recon/resolve.js +161 -20
  136. package/dist/render/renderQuality.d.ts +35 -0
  137. package/dist/render/renderQuality.js +7 -0
  138. package/dist/render/rendererHarness.js +16 -0
  139. package/dist/render/sceneTarget.d.ts +9 -1
  140. package/dist/render/sceneTarget.js +60 -12
  141. package/dist/render/shaders/depth.d.ts +16 -1
  142. package/dist/render/shaders/depth.js +94 -15
  143. package/dist/render/shaders/flat/directionalShadow.js +91 -6
  144. package/dist/render/shaders/flat/driftLight.d.ts +1 -1
  145. package/dist/render/shaders/flat/driftLight.js +32 -7
  146. package/dist/render/shaders/flat/glassTint.d.ts +6 -0
  147. package/dist/render/shaders/flat/glassTint.js +25 -0
  148. package/dist/render/shaders/flat/index.d.ts +13 -0
  149. package/dist/render/shaders/flat/index.js +9 -3
  150. package/dist/render/shaders/flat/lampGlass.d.ts +1 -0
  151. package/dist/render/shaders/flat/lampGlass.js +183 -0
  152. package/dist/render/shaders/flat/main.d.ts +1 -1
  153. package/dist/render/shaders/flat/main.js +190 -38
  154. package/dist/render/shaders/flat/pointShadow.d.ts +1 -1
  155. package/dist/render/shaders/flat/pointShadow.js +2 -0
  156. package/dist/render/shaders/flat/preamble.js +96 -26
  157. package/dist/render/shaders/flat/surfaceEffects.d.ts +29 -0
  158. package/dist/render/shaders/flat/surfaceEffects.js +152 -0
  159. package/dist/render/shaders/generated/depth.wgsl.d.ts +230 -7
  160. package/dist/render/shaders/generated/depth.wgsl.js +230 -7
  161. package/dist/render/shaders/generated/flat.wgsl.d.ts +1644 -1596
  162. package/dist/render/shaders/generated/flat.wgsl.js +1683 -1621
  163. package/dist/render/shaders/generated/globalMedium.wgsl.d.ts +3 -13
  164. package/dist/render/shaders/generated/globalMedium.wgsl.js +3 -13
  165. package/dist/render/shaders/generated/lightVolume.wgsl.d.ts +3 -13
  166. package/dist/render/shaders/generated/lightVolume.wgsl.js +21 -17
  167. package/dist/render/shaders/generated/octahedralResolve.wgsl.d.ts +29 -0
  168. package/dist/render/shaders/generated/octahedralResolve.wgsl.js +29 -0
  169. package/dist/render/shaders/generated/rush.wgsl.d.ts +21 -16
  170. package/dist/render/shaders/generated/rush.wgsl.js +21 -16
  171. package/dist/render/shaders/generated/sdfText.wgsl.d.ts +2 -2
  172. package/dist/render/shaders/generated/sdfText.wgsl.js +2 -2
  173. package/dist/render/shaders/generated/text.wgsl.d.ts +1 -1
  174. package/dist/render/shaders/generated/text.wgsl.js +1 -1
  175. package/dist/render/shaders/gi/driftLight.wgsl.d.ts +1 -1
  176. package/dist/render/shaders/gi/driftLight.wgsl.js +27 -4
  177. package/dist/render/shaders/globalMedium.js +6 -6
  178. package/dist/render/shaders/gpudriven/blendRaster.wgsl.d.ts +7 -0
  179. package/dist/render/shaders/gpudriven/blendRaster.wgsl.js +86 -1
  180. package/dist/render/shaders/gpudriven/cull.wgsl.d.ts +1 -1
  181. package/dist/render/shaders/gpudriven/cull.wgsl.js +11 -2
  182. package/dist/render/shaders/gpudriven/materialTable.wgsl.d.ts +1 -1
  183. package/dist/render/shaders/gpudriven/materialTable.wgsl.js +3 -1
  184. package/dist/render/shaders/gpudriven/shade.wgsl.js +50 -1
  185. package/dist/render/shaders/gpudriven/sunGlass.wgsl.d.ts +9 -0
  186. package/dist/render/shaders/gpudriven/sunGlass.wgsl.js +133 -0
  187. package/dist/render/shaders/lightVolume.js +6 -6
  188. package/dist/render/shaders/octahedralResolve.d.ts +8 -0
  189. package/dist/render/shaders/octahedralResolve.js +48 -17
  190. package/dist/render/shaders/recon/lateDepth.wgsl.d.ts +1 -0
  191. package/dist/render/shaders/recon/lateDepth.wgsl.js +69 -0
  192. package/dist/render/shaders/recon/motion.wgsl.d.ts +1 -1
  193. package/dist/render/shaders/recon/motion.wgsl.js +84 -0
  194. package/dist/render/shaders/recon/resolve.wgsl.d.ts +8 -7
  195. package/dist/render/shaders/recon/resolve.wgsl.js +161 -27
  196. package/dist/render/shaders/rush.js +11 -1
  197. package/dist/render/shaders/sdfText.d.ts +1 -1
  198. package/dist/render/shaders/sdfText.js +3 -2
  199. package/dist/render/shaders/text.d.ts +1 -1
  200. package/dist/render/shaders/text.js +18 -9
  201. package/dist/render/shadowCasters.d.ts +20 -1
  202. package/dist/render/shadowCasters.js +15 -1
  203. package/dist/render/shadowMap.d.ts +54 -5
  204. package/dist/render/shadowMap.js +190 -36
  205. package/dist/render/sunGlassTint.d.ts +25 -0
  206. package/dist/render/sunGlassTint.js +79 -0
  207. package/dist/render/surfaceEffects.d.ts +83 -0
  208. package/dist/render/surfaceEffects.js +75 -0
  209. package/dist/render/surfaceScene.d.ts +8 -0
  210. package/dist/render/surfaceScene.js +8 -0
  211. package/dist/render/surfaceTexture.d.ts +18 -2
  212. package/dist/render/surfaceTexture.js +68 -15
  213. package/dist/render/temporalAa.d.ts +25 -6
  214. package/dist/render/temporalAa.js +45 -15
  215. package/dist/render/textureSource.d.ts +30 -0
  216. package/dist/render/textureSource.js +53 -0
  217. package/dist/render/translucentQueue.d.ts +6 -0
  218. package/dist/render/translucentQueue.js +15 -1
  219. package/dist/render/vertexDefaults.js +2 -0
  220. package/dist/world/hlod.d.ts +104 -0
  221. package/dist/world/hlod.js +214 -0
  222. package/package.json +6 -6
  223. package/src/geometry/boxCsg.ts +186 -0
  224. package/src/geometry/csg.ts +384 -0
  225. package/src/geometry/meshBuilder.ts +15 -0
  226. package/src/geometry/meshConcat.ts +1 -0
  227. package/src/geometry/pixelFont.ts +2 -0
  228. package/src/geometry/solid.ts +189 -0
  229. package/src/geometry/solidFlat.ts +522 -0
  230. package/src/geometry/solidHarness.ts +83 -0
  231. package/src/geometry/solidNormals.ts +103 -0
  232. package/src/geometry/solidRound.ts +443 -0
  233. package/src/geometry/solidWriter.ts +58 -0
  234. package/src/index.ts +61 -1
  235. package/src/render/backend/api.ts +36 -11
  236. package/src/render/backend/drawFog.ts +31 -0
  237. package/src/render/backend/materialChanges.ts +9 -2
  238. package/src/render/backend/webgl2/glassTintPrograms.ts +58 -0
  239. package/src/render/backend/webgl2/instanced.ts +80 -14
  240. package/src/render/backend/webgl2/renderer.ts +700 -250
  241. package/src/render/backend/webgpu/buffers.ts +92 -5
  242. package/src/render/backend/webgpu/depthPass.ts +7 -2
  243. package/src/render/backend/webgpu/drawCommand.ts +6 -0
  244. package/src/render/backend/webgpu/flatPass.ts +62 -11
  245. package/src/render/backend/webgpu/glassTintPass.ts +245 -0
  246. package/src/render/backend/webgpu/gpuDrivenPass.ts +349 -5
  247. package/src/render/backend/webgpu/instanceCullPass.ts +165 -0
  248. package/src/render/backend/webgpu/instanced.ts +42 -4
  249. package/src/render/backend/webgpu/latePass.ts +161 -0
  250. package/src/render/backend/webgpu/lightVolumePass.ts +5 -1
  251. package/src/render/backend/webgpu/motionPass.ts +535 -0
  252. package/src/render/backend/webgpu/pipelineCache.ts +12 -1
  253. package/src/render/backend/webgpu/pointGlassTintPass.ts +233 -0
  254. package/src/render/backend/webgpu/pointShadowPass.ts +158 -26
  255. package/src/render/backend/webgpu/renderer.ts +1671 -670
  256. package/src/render/backend/webgpu/scatterPass.ts +2 -1
  257. package/src/render/backend/webgpu/sdfTextPass.ts +6 -1
  258. package/src/render/backend/webgpu/shaders/instanceCull.wgsl.ts +61 -0
  259. package/src/render/backend/webgpu/skinPaletteRing.ts +4 -0
  260. package/src/render/backend/webgpu/snapshotMips.ts +80 -0
  261. package/src/render/backend/webgpu/surfaceTexturePass.ts +91 -51
  262. package/src/render/driftLight/bake.ts +85 -62
  263. package/src/render/driftLight/denseField.ts +149 -0
  264. package/src/render/driftLight/lightField.ts +33 -18
  265. package/src/render/driftLight/presence.ts +69 -0
  266. package/src/render/driftLight/uniforms.ts +8 -9
  267. package/src/render/driftLight/worldLightField.ts +83 -0
  268. package/src/render/fixtureAtlas.ts +63 -0
  269. package/src/render/glass.ts +74 -0
  270. package/src/render/glassCasters.ts +164 -0
  271. package/src/render/glassShadow.ts +153 -0
  272. package/src/render/globalMediumPass.ts +4 -11
  273. package/src/render/gpudriven/lit.ts +31 -0
  274. package/src/render/gpudriven/materialTable.ts +28 -6
  275. package/src/render/gpudriven/pipeline.ts +4 -3
  276. package/src/render/gpudriven/sunGlass.ts +117 -0
  277. package/src/render/instanceCull.ts +205 -0
  278. package/src/render/instances.ts +16 -0
  279. package/src/render/lightBudget.ts +41 -38
  280. package/src/render/lightGrid.ts +130 -0
  281. package/src/render/mesh.ts +59 -72
  282. package/src/render/occlusion.ts +51 -7
  283. package/src/render/pointGlassTint.ts +250 -0
  284. package/src/render/pointLightSelection.ts +72 -4
  285. package/src/render/pointShadowArray.ts +188 -22
  286. package/src/render/pointShadowMap.ts +41 -0
  287. package/src/render/rainField.ts +39 -5
  288. package/src/render/recon/changeFrames.ts +24 -0
  289. package/src/render/recon/lateDepth.ts +83 -0
  290. package/src/render/recon/lateRouting.ts +29 -0
  291. package/src/render/recon/mover.ts +118 -0
  292. package/src/render/recon/resolve.ts +206 -20
  293. package/src/render/renderQuality.ts +47 -0
  294. package/src/render/rendererHarness.ts +16 -0
  295. package/src/render/sceneTarget.ts +62 -11
  296. package/src/render/shaders/depth.ts +118 -15
  297. package/src/render/shaders/flat/directionalShadow.ts +97 -6
  298. package/src/render/shaders/flat/driftLight.ts +32 -7
  299. package/src/render/shaders/flat/glassTint.ts +25 -0
  300. package/src/render/shaders/flat/index.ts +22 -3
  301. package/src/render/shaders/flat/lampGlass.ts +185 -0
  302. package/src/render/shaders/flat/main.ts +190 -38
  303. package/src/render/shaders/flat/pointShadow.ts +2 -0
  304. package/src/render/shaders/flat/preamble.ts +96 -26
  305. package/src/render/shaders/flat/surfaceEffects.ts +152 -0
  306. package/src/render/shaders/generated/depth.wgsl.ts +237 -7
  307. package/src/render/shaders/generated/flat.wgsl.ts +1685 -1621
  308. package/src/render/shaders/generated/globalMedium.wgsl.ts +3 -13
  309. package/src/render/shaders/generated/lightVolume.wgsl.ts +23 -17
  310. package/src/render/shaders/generated/octahedralResolve.wgsl.ts +30 -0
  311. package/src/render/shaders/generated/rush.wgsl.ts +21 -16
  312. package/src/render/shaders/generated/sdfText.wgsl.ts +2 -2
  313. package/src/render/shaders/generated/text.wgsl.ts +1 -1
  314. package/src/render/shaders/gi/driftLight.wgsl.ts +27 -4
  315. package/src/render/shaders/globalMedium.ts +6 -6
  316. package/src/render/shaders/gpudriven/blendRaster.wgsl.ts +88 -1
  317. package/src/render/shaders/gpudriven/cull.wgsl.ts +11 -2
  318. package/src/render/shaders/gpudriven/materialTable.wgsl.ts +3 -1
  319. package/src/render/shaders/gpudriven/shade.wgsl.ts +50 -1
  320. package/src/render/shaders/gpudriven/sunGlass.wgsl.ts +139 -0
  321. package/src/render/shaders/lightVolume.ts +6 -6
  322. package/src/render/shaders/octahedralResolve.ts +50 -17
  323. package/src/render/shaders/recon/lateDepth.wgsl.ts +72 -0
  324. package/src/render/shaders/recon/motion.wgsl.ts +84 -0
  325. package/src/render/shaders/recon/resolve.wgsl.ts +161 -27
  326. package/src/render/shaders/rush.ts +11 -1
  327. package/src/render/shaders/sdfText.ts +3 -2
  328. package/src/render/shaders/text.ts +18 -9
  329. package/src/render/shadowCasters.ts +28 -1
  330. package/src/render/shadowMap.ts +231 -37
  331. package/src/render/sunGlassTint.ts +86 -0
  332. package/src/render/surfaceEffects.ts +132 -0
  333. package/src/render/surfaceScene.ts +16 -0
  334. package/src/render/surfaceTexture.ts +110 -19
  335. package/src/render/temporalAa.ts +78 -14
  336. package/src/render/textureSource.ts +72 -0
  337. package/src/render/translucentQueue.ts +20 -1
  338. package/src/render/vertexDefaults.ts +2 -0
  339. package/src/world/hlod.ts +290 -0
@@ -1,5 +1,6 @@
1
1
  /** Version, inputs, uniforms and the defines the rest of the fragment shader is written against. */
2
2
  import { COOKIE_TILE } from '../../lightBudget.ts';
3
+ import { IES_ATLAS_WIDTH } from '../../iesProfile.ts';
3
4
  import {
4
5
  CLUSTER_TEXELS,
5
6
  CLUSTER_X,
@@ -51,7 +52,7 @@ in vec3 vWorldPos;
51
52
  in float vEmissive;
52
53
  in float vSpecular;
53
54
  in vec4 vLightPos;
54
- in vec2 vUv;
55
+ in vec3 vUv;
55
56
  in vec3 vEmissiveColor;
56
57
  in float vRoughness;
57
58
  /*
@@ -108,13 +109,20 @@ in float vThickness;
108
109
  * paid by every consumer whether or not they refract, against 19.8 KB for a branch -- which is the
109
110
  * price table Track D's three shipped rows measured.
110
111
  *
111
- * uRefractStrength at 0 is every draw that shipped before this existed, and it is the default, so
112
+ * uSeeThrough.x, the strength, at 0 is every draw that shipped before this existed, and it is the default, so
112
113
  * the sampler is bound to an empty texture and read nowhere on a frame that refracts nothing.
113
114
  */
114
115
  uniform sampler2D uRefractScene;
115
- uniform float uRefractStrength;
116
+ /*
117
+ * **Four numbers in one vector: refraction's strength and path thickness, glass's transmission and
118
+ * frost** (x, y, z, w). One vector rather than four, and that is the whole reason: on a device at the
119
+ * WebGL2 floor of 256 fragment uniform vectors, every loose float is a vector the light budget
120
+ * gives up, and four separate floats cost half the shadowed lights such a device can have. The tints
121
+ * stay colours of their own. Zero transmission is not glass — see glass.ts.
122
+ */
123
+ uniform vec4 uSeeThrough;
116
124
  uniform vec3 uRefractTint;
117
- uniform float uRefractThickness;
125
+ uniform vec3 uGlassTint;
118
126
  flat in int vHasTangents;
119
127
 
120
128
  /**
@@ -129,7 +137,7 @@ flat in int vHasTangents;
129
137
  * biome recolours a whole world without a second texture, and a mesh whose texture is
130
138
  * white shades identically to one with no texture at all.
131
139
  */
132
- uniform sampler2D uAlbedo;
140
+ uniform mediump sampler2DArray uAlbedo;
133
141
  /** 0 leaves every textured path unevaluated, for the majority of geometry with no image. */
134
142
  uniform int uAlbedoEnabled;
135
143
  /**
@@ -145,6 +153,12 @@ uniform int uAlbedoEnabled;
145
153
  * else changes.
146
154
  */
147
155
  uniform float uAlbedoCutout;
156
+ /**
157
+ * The albedo array's per-layer effects table: six texels a layer, read with \`texelFetch\` at the
158
+ * layer a vertex carries. A 1×1 stand-in where the array has none, which the size test below reads
159
+ * as no effects at all. See \`surfaceEffects.ts\` for the layout.
160
+ */
161
+ uniform mediump sampler2D uSurfaceEffects;
148
162
 
149
163
  /**
150
164
  * 1 for a surface seen from both faces: glTF's doubleSided, a curtain or a leaf card. Its draw culls
@@ -162,7 +176,7 @@ uniform int uDoubleSided;
162
176
  * display values bends every normal toward the surface and reads as a green tint over everything.
163
177
  * SurfaceTextureOptions.colorSpace already defaults to linear and says why.
164
178
  */
165
- uniform highp sampler2D uNormalMap;
179
+ uniform highp sampler2DArray uNormalMap;
166
180
  /**
167
181
  * How hard the map turns the shading normal. 0 is no map at all, and gates the whole block.
168
182
  *
@@ -184,7 +198,7 @@ uniform float uNormalStrength;
184
198
  * Sampled linear and never sRGB. These three numbers *are* the data, not a picture of it, and
185
199
  * decoding them as display values would bend every one of them toward its floor.
186
200
  */
187
- uniform highp sampler2D uOrmMap;
201
+ uniform highp sampler2DArray uOrmMap;
188
202
  /**
189
203
  * 1 when a map is bound. Gates the whole block, following uAlbedoEnabled.
190
204
  *
@@ -230,7 +244,7 @@ uniform float uEnvironmentPrefiltered;
230
244
  * above, and now with a number behind them: a fifth flag was built and measured at 49% of the
231
245
  * bundle. See \`ARCHITECTURE.md\` §1.
232
246
  */
233
- uniform highp sampler2D uEmissiveMap;
247
+ uniform highp sampler2DArray uEmissiveMap;
234
248
  /** 1 when a map is bound. Gates the sample, following uOrmEnabled. */
235
249
  uniform int uEmissiveMapEnabled;
236
250
  /**
@@ -268,9 +282,13 @@ uniform vec3 uEmissiveScale;
268
282
  * half of the file, because a test asserts that a profile without a probe mentions them
269
283
  * nowhere — a comment is source too, and it failed that test first.
270
284
  */
271
- uniform highp sampler2D uStaticShadowMap; // wgsl:share shadow
272
- uniform highp sampler2D uPeeledShadowMap; // wgsl:share shadow
273
- uniform highp sampler2D uDynamicShadowMap; // wgsl:share shadow
285
+ /* The sun's static, moving and peeled maps, as layers of one array: see shadowMap.ts. Where glass
286
+ has cast, the last two layers are the nearest pane's depth, static then moving. */
287
+ uniform highp sampler2DArray uSunShadows; // wgsl:share shadow
288
+ /* What the sun keeps through glass, static then moving: colour times colour, and clarity (see
289
+ glassShadow.ts). A one-texel stand-in where no glass has cast, which the lookup reads as none.
290
+ Mipmapped and filtered, unlike the depths: frost reads the level its spread asks for. */
291
+ uniform highp sampler2DArray uSunGlassTints; // wgsl:share tint
274
292
  /** 0 disables directional shadows when their source is not emitting. */
275
293
  uniform float uShadowStrength;
276
294
  uniform float uShadowMapSize;
@@ -302,9 +320,21 @@ uniform vec3 uAmbient;
302
320
  uniform vec3 uAmbientGround;
303
321
  ${FOG_GLSL}
304
322
  uniform vec3 uCameraPos;
305
- /** Optional world plane; reflection passes retain only the viewer's side. */
323
+ /**
324
+ * Optional world plane; reflection passes retain only the viewer's side.
325
+ *
326
+ * **Zero is off, and there is no flag beside it.** A zero plane gives \`dot(p, 0) = 0\`, which is
327
+ * never below zero, so it discards nothing — the \`uClipEnabled\` int that stood here said nothing
328
+ * the plane could not, and a scalar is a whole uniform row on WebGL2. Its row paid for
329
+ * \`uSurfaceScene\`. Other programs keep their own flags; this is the lit stage's alone.
330
+ */
306
331
  uniform vec4 uClipPlane;
307
- uniform int uClipEnabled;
332
+ /**
333
+ * The scene's surface clock and weather, from the environment: x seconds on the caller's clock, y
334
+ * how wet the world is, z the share of facade windows lit, w the share that stays lit however late.
335
+ * One row for all four, paid for by the flag the clip plane no longer needs.
336
+ */
337
+ uniform vec4 uSurfaceScene;
308
338
  uniform float uEmissiveGain;
309
339
  uniform float uNightFactor;
310
340
  #if NIGHT_EMISSIVE
@@ -334,22 +364,47 @@ uniform float uNightEmissive;
334
364
  uniform float uOpacity;
335
365
 
336
366
  /**
337
- * Whether this draw is accumulating into the order-independent transparency buffers, and
338
- * therefore weights its own output. 0 is every draw that is not, which is every draw on every
367
+ * Two per-draw switches on how a fragment is *written* rather than what colour it is, sharing one
368
+ * row: on WebGL2 every scalar uniform takes a row of its own, and the eight-light rung stands at 255
369
+ * of the 256 an Adreno 740 offers (\`uniformVectorBudget.test.ts\`), so a second scalar would have
370
+ * spent the last row and the next uniform anybody added would drop that part to four lights.
371
+ *
372
+ * **\`.x\` — whether this draw is accumulating into the order-independent transparency buffers**,
373
+ * and therefore weights its own output. 0 is every draw that is not, which is every draw on every
339
374
  * published scene.
340
375
  *
341
- * **A uniform rather than a permutation, and the cost is why.** Writing the accumulation and the
376
+ * A uniform rather than a permutation, and the cost is why. Writing the accumulation and the
342
377
  * revealage from one pass needs a second fragment output, which is another \`flatFrag\` axis —
343
378
  * measured in \`scripts/wgsl.ts\` at about 247 KB gzipped, doubling the sixteen fragment variants,
344
379
  * and paid by every consumer whether or not they ever switch this on. A branch on a uniform costs
345
380
  * a compare, and the geometry is submitted twice instead. See \`orderIndependent.ts\`.
346
381
  *
347
- * **The revealage pass does not read this.** It draws with this at 0 and a blend of
382
+ * The revealage pass does not read it. It draws with it at 0 and a blend of
348
383
  * \`(ZERO, ONE_MINUS_SRC_ALPHA)\`, so the colour it computes is multiplied away and only its alpha
349
384
  * reaches the target — which is exactly the point: both passes run the same code to decide what
350
385
  * alpha this fragment has, so they cannot disagree about it.
386
+ *
387
+ * **\`.y\` — how much of this draw survives a screen-door dither**, for a crossfade between two
388
+ * levels of detail of one thing. 0 is off, and every draw that never asked for it. Positive keeps
389
+ * that share of an 8×8 Bayer pattern's cells; negative keeps the complement — the cells a draw at
390
+ * the positive amount leaves out — so two draws at \`t\` and \`-t\` cover every pixel exactly once,
391
+ * whatever \`t\` is. Keyed on the framebuffer's own pixel, whose y runs the other way on WebGPU, so
392
+ * the grain is mirrored between backends and nothing else about it differs. What it gives up: a
393
+ * crossfade reads as grain for as long as it lasts, which is why it should be short; and a blended
394
+ * draw that asks for it is dithered too, since the test is a discard.
351
395
  */
352
- uniform float uOitWeighted;
396
+ uniform vec2 uWriteMode;
397
+
398
+ /** Whether this fragment is one \`uWriteMode.y\` keeps. Integer arithmetic, per the device rule. */
399
+ bool ditherKeeps(float amount) {
400
+ uvec2 p = uvec2(gl_FragCoord.xy) & 7u;
401
+ uint a = p.x ^ p.y;
402
+ uint b = p.y;
403
+ uint cell = ((a & 1u) << 5) | ((b & 1u) << 4) | ((a & 2u) << 2) | ((b & 2u) << 1) |
404
+ ((a & 4u) >> 1) | ((b & 4u) >> 2);
405
+ float threshold = (float(cell) + 0.5) / 64.0;
406
+ return amount > 0.0 ? threshold < amount : threshold >= -amount;
407
+ }
353
408
 
354
409
  /**
355
410
  * Whether the fragment stage runs any lighting: ambient, the sun, point lights, specular,
@@ -373,10 +428,11 @@ uniform float uOitWeighted;
373
428
  */
374
429
  uniform int uLightingEnabled;
375
430
  /**
376
- * Whether this draw recedes into the medium: the atmospheric haze and the underwater tint
377
- * both, folded together because both are the *camera's* medium rather than a property of the
378
- * surface — see \`mediumFog\`/\`mediumColor\` in \`fog.ts\`. 1 keeps both, matching every draw
379
- * before this existed.
431
+ * How this draw meets the medium: the atmospheric haze and the underwater tint both, folded
432
+ * together because both are the *camera's* medium rather than a property of the surface — see
433
+ * \`mediumFog\`/\`mediumColor\` in \`fog.ts\`. 1 recedes into it, matching every draw before this
434
+ * existed; 2 fades in it without taking its colour, which is what an additive draw is given; 0
435
+ * keeps out of it. The rule is \`fogModeOf\` in \`backend/drawFog.ts\`.
380
436
  *
381
437
  * **Independent of \`uLightingEnabled\`, and that is the point of it being a second uniform
382
438
  * rather than the same one.** "Unlit but still fading into the haze" is a real thing to
@@ -726,15 +782,15 @@ uniform vec3 uLightIesAxis[MAX_LIGHTS];
726
782
  */
727
783
  uniform float uLightCookie[MAX_LIGHTS];
728
784
  /**
729
- * Photometric profiles: one row per fixture, a fixture's intensity by vertical angle across it.
785
+ * Photometric profiles: one row per fixture, a fixture's intensity by vertical angle across it, in
786
+ * the bottom band of the fixture atlas below.
730
787
  *
731
788
  * **Every row spans the same 0 to 180 degree arc**, whatever the file measured, which is what lets
732
789
  * a light carry only a row index — see \`iesProfile.ts\`. With no profile loaded this holds a
733
790
  * single row of ones, the multiplicative identity, because a declared sampler needs a complete
734
791
  * texture whether or not the branch reads it and a row of zeros would switch off every light.
735
792
  */
736
- uniform sampler2D uIesAtlas;
737
- /** Rows in the atlas, so a row index becomes a coordinate. At least 1. */
793
+ /** Rows of profile in the fixture atlas, below its cookies. At least 1. */
738
794
  uniform float uIesAtlasRows;
739
795
  /**
740
796
  * Horizontal planes each profile occupies, so a row is \`profile * planes + plane\`.
@@ -754,8 +810,14 @@ uniform float uIesPlaneCount;
754
810
  * identity, because a declared sampler needs a complete texture whether or not the branch reads it
755
811
  * and a black stand-in would switch off every light that reached it.
756
812
  */
757
- uniform sampler2D uCookieAtlas;
758
813
  uniform float uCookieTiles;
814
+ /**
815
+ * Both tables in one texture: the cookies' row of tiles in the top band, the profiles' rows below.
816
+ * One sampler for the two since 2026-09-30, because the lit stage bound fifteen of the sixteen
817
+ * WebGL2 guarantees; see \`fixtureAtlas.ts\`. The bands are found from \`textureSize\` and
818
+ * \`uIesAtlasRows\`, so the fold cost no uniform.
819
+ */
820
+ uniform sampler2D uFixtureAtlas;
759
821
  /**
760
822
  * Half a texel of a tile, so a cookie's edge cannot reach its neighbour in the atlas.
761
823
  *
@@ -764,6 +826,10 @@ uniform float uCookieTiles;
764
826
  * cookie. Derived from \`COOKIE_TILE\` rather than written twice.
765
827
  */
766
828
  #define COOKIE_INSET (0.5 / ${COOKIE_TILE}.0)
829
+ /** Texels across a profile's row, where a vertical angle of 0 to 180 degrees is laid. */
830
+ #define IES_WIDTH ${IES_ATLAS_WIDTH}.0
831
+ /** Texels a cookie's tile spans, on both axes. */
832
+ #define COOKIE_SPAN ${COOKIE_TILE}.0
767
833
  /**
768
834
  * Rectangular area lights, and how many of them are live.
769
835
  *
@@ -866,6 +932,10 @@ uniform float uPointShadowWeight[MAX_LIGHTS];
866
932
  * it exists.
867
933
  */
868
934
  uniform highp sampler2DArray uPointShadows; // wgsl:share shadow
935
+ /* What each light keeps through glass: one layer a light, colour times colour and clarity, beside
936
+ the array above — whose light L then keeps its depth at 2L and its nearest pane at 2L + 1 (see
937
+ pointShadowArray.ts). A one-texel stand-in where no lamp has met glass, read as none. */
938
+ uniform highp sampler2DArray uPointGlassTints; // wgsl:share tint
869
939
 
870
940
  /**
871
941
  * Moving casters are separate from persistent world maps. Two live maps exist
@@ -0,0 +1,152 @@
1
+ /**
2
+ * Surface effects in the lit shader: what a layer does beyond its picture, read from the albedo
3
+ * array's effects table at the layer a vertex carries (`surfaceEffects.ts` has the layout).
4
+ *
5
+ * **Nothing here changes a surface that asks for nothing.** With no table the fetch never runs and
6
+ * every value is zero; each effect is then `mix(x, y, 0)` or a multiply by exactly 1, so a scene
7
+ * that never names an effect draws bit for bit what it drew before. Rain is the one effect that
8
+ * needs no table — it is the scene's (`Environment.wetness`) — and at zero it is the same no-op.
9
+ *
10
+ * **Windows and rooms.** A layer's windows are a grid of cells over one repeat. Each window lights
11
+ * by a hash of its cell against the scene's lit share, quantised to tenths, so a rising share lights
12
+ * more windows rather than brightening the lit ones; a share of them stays lit in the small hours.
13
+ * A room behind a window is **interior mapping from one image**: a one-point perspective picture of
14
+ * a room, back wall in its centre half, is sampled where the view ray meets the room's box. A point
15
+ * on any wall at depth s maps into that picture at `0.5 + (xy - 0.5) / (1 + s)` — the back wall at
16
+ * s = 1 lands in the centre square, and a side wall runs from the picture's edge in to it — so one
17
+ * formula serves every wall and the picture carries its own shading.
18
+ *
19
+ * **Wear** is procedural: dust settling on what faces up, grime rising from the ground and in
20
+ * blotches, streaks running down walls, all fading out with distance where a table says to.
21
+ *
22
+ * Every sample inside these branches is `textureGrad` with gradients taken outside them, or
23
+ * `texelFetch` (the 2026-08-07 rule). Hashes are integer arithmetic (the 2026-09-20 rule).
24
+ *
25
+ * What it gives up: the room picture is one per layer, so every room of a facade is the same room
26
+ * lit or dark; and a room's box assumes a window as wide as it is tall, so a very tall cell
27
+ * stretches its room.
28
+ */
29
+ export const SURFACE_EFFECTS_GLSL = /* glsl */ `
30
+ /*
31
+ * The layer's six rows, and what every effect reads beside them, filled once at the top of main.
32
+ * Globals rather than arguments, because naga passes every argument through a pointer and a copy,
33
+ * and in sixteen permutations that traffic was most of what the effects cost in bytes.
34
+ */
35
+ vec4 fx0;
36
+ vec4 fx1;
37
+ vec4 fx2;
38
+ vec4 fx3;
39
+ vec4 fx4;
40
+ vec4 fx5;
41
+ vec3 fxNormal;
42
+ float fxDistance;
43
+
44
+ /** Fill the rows for this layer, or leave them zero where the array carries no table. */
45
+ void fxLoad(int layer) {
46
+ fx0 = vec4(0.0);
47
+ fx1 = vec4(0.0);
48
+ fx2 = vec4(0.0);
49
+ fx3 = vec4(0.0);
50
+ fx4 = vec4(0.0);
51
+ fx5 = vec4(0.0);
52
+ ivec2 size = textureSize(uSurfaceEffects, 0);
53
+ if (size.x < 6 || layer < 0 || layer >= size.y) return;
54
+ fx0 = texelFetch(uSurfaceEffects, ivec2(0, layer), 0);
55
+ fx1 = texelFetch(uSurfaceEffects, ivec2(1, layer), 0);
56
+ fx2 = texelFetch(uSurfaceEffects, ivec2(2, layer), 0);
57
+ fx3 = texelFetch(uSurfaceEffects, ivec2(3, layer), 0);
58
+ fx4 = texelFetch(uSurfaceEffects, ivec2(4, layer), 0);
59
+ fx5 = texelFetch(uSurfaceEffects, ivec2(5, layer), 0);
60
+ }
61
+
62
+ /** A cell and a seed to 0..1, the same on every device. */
63
+ float fxHash(vec2 cell, float seed) {
64
+ uvec2 q = uvec2(ivec2(cell)) + uvec2(uint(seed) * 7919u, uint(seed) * 104729u);
65
+ uint h = (q.x * 1597334677u) ^ (q.y * 3812015801u);
66
+ h = (h ^ (h >> 16)) * 2246822519u;
67
+ h ^= h >> 13;
68
+ return float(h & 16777215u) / 16777216.0;
69
+ }
70
+
71
+ float fxNoise(vec2 p) {
72
+ vec2 i = floor(p);
73
+ vec2 u = smoothstep(0.0, 1.0, fract(p));
74
+ return mix(
75
+ mix(fxHash(i, 0.0), fxHash(i + vec2(1.0, 0.0), 0.0), u.x),
76
+ mix(fxHash(i + vec2(0.0, 1.0), 0.0), fxHash(i + vec2(1.0, 1.0), 0.0), u.x),
77
+ u.y);
78
+ }
79
+
80
+ /** Scroll and flipbook, on the caller's clock. \`fract\` keeps a long clock from eating precision. */
81
+ vec3 fxAnimate(vec3 at) {
82
+ float time = uSurfaceScene.x;
83
+ at.xy += fract(fx4.xy * time);
84
+ if (fx5.y > 0.0) at.z += mod(floor(time * fx5.z), fx5.y);
85
+ return at;
86
+ }
87
+
88
+ /** Pulse, flicker and fade with distance, as a factor on the emission. */
89
+ float fxEmission(float layer) {
90
+ float time = uSurfaceScene.x;
91
+ float e = 1.0 - fx4.w * (0.5 + 0.5 * sin(6.2831853 * fract(fx4.z * time)));
92
+ e *= 1.0 - fx5.x * step(0.7, fxHash(vec2(floor(time * 14.0), layer), 3.0));
93
+ if (fx5.w > 0.0) e *= 1.0 - smoothstep(fx5.w * 0.7, fx5.w, fxDistance);
94
+ return e;
95
+ }
96
+
97
+ /** Dust, grime and streaks, then the scene's rain: the colour in xyz, the roughness in w. */
98
+ vec4 fxWeather(vec3 world, vec3 albedo, float roughness) {
99
+ float fade = fx3.w > 0.0 ? 1.0 - smoothstep(fx3.w * 0.5, fx3.w, fxDistance) : 1.0;
100
+ if (fx3.x + fx3.y + fx3.z > 0.0) {
101
+ float blotch = fxNoise(world.xz * 0.35 + world.y * 0.2);
102
+ float dust = fx3.x * smoothstep(0.35, 0.9, fxNormal.y) * (0.5 + 0.5 * blotch) * fade;
103
+ float grime = fx3.y * (0.55 - 0.55 * smoothstep(0.0, 2.5, world.y) + 0.45 * blotch) * fade;
104
+ float streak = fx3.z * (1.0 - abs(fxNormal.y))
105
+ * fxNoise(vec2((world.x + world.z) * 2.5, world.y * 0.15)) * fade;
106
+ albedo = mix(albedo, vec3(0.56, 0.53, 0.48), dust * 0.6) * (1.0 - 0.5 * grime - 0.35 * streak);
107
+ roughness = mix(roughness, 1.0, clamp(0.5 * (dust + grime), 0.0, 1.0));
108
+ }
109
+ float wet = uSurfaceScene.y * (1.0 - fx2.w) * mix(0.35, 1.0, smoothstep(0.2, 0.8, fxNormal.y));
110
+ return vec4(albedo * (1.0 - 0.45 * wet), mix(roughness, 0.08, wet));
111
+ }
112
+
113
+ /**
114
+ * Windows and the rooms behind them: the glow a lit window adds to the emission in xyz, and in w
115
+ * how much of the surface is glass, which the caller mixes toward the room's dim colour. The room
116
+ * itself is returned through \`fxRoom\`. \`mask\` is the albedo's alpha, and a window is a hole in the
117
+ * wall's picture: glass where it is 0. The other way round would lose the wall's colour, which does
118
+ * not survive an upload at alpha 0.
119
+ *
120
+ * **A building's own light, where its vertices name one.** The table is per layer, and every
121
+ * facade of one style shares a layer, so a light that differs from building to building — its
122
+ * colour and its strength — cannot live there. A window layer's vertex emissive is otherwise unused
123
+ * (its windows glow here, not through the emissive term), so the vertex's emissive colour, strength
124
+ * folded in, is that light: the window's colour where there is no room, a tint on the room where
125
+ * there is. An absent colour reads negative and leaves both exactly as the table says.
126
+ */
127
+ vec3 fxRoom;
128
+ vec4 fxWindows(vec3 at, vec2 dx, vec2 dy, float mask) {
129
+ float glass = fx0.z > 0.0 ? 1.0 - mask : 1.0;
130
+ vec2 g = at.xy * fx0.xy;
131
+ vec2 local = fract(g);
132
+ float share = floor(max(uSurfaceScene.z, uSurfaceScene.w) * 10.0 + 0.5) / 10.0;
133
+ float lit = fxHash(floor(g), fx0.w) < share * (fx1.x > 0.0 ? fx1.z : 1.0) ? 1.0 : 0.0;
134
+ fxRoom = fx2.rgb;
135
+ bool own = vEmissiveColor.r >= 0.0;
136
+ vec3 glow = own ? vEmissiveColor : fx2.rgb;
137
+ float tangentLength = length(vTangent.xyz);
138
+ if (fx1.x > 0.0 && tangentLength > 1e-4) {
139
+ vec3 t = vTangent.xyz / tangentLength;
140
+ vec3 v = normalize(vWorldPos - uCameraPos);
141
+ vec3 d = vec3(dot(v, t), dot(v, cross(fxNormal, t)) * sign(vTangent.w + 0.5),
142
+ min(dot(v, fxNormal), -1e-3) / max(fx1.y, 0.05));
143
+ vec2 across = (step(0.0, d.xy) - local) / (sign(d.xy + 1e-9) * max(abs(d.xy), 1e-5));
144
+ float travel = min(min(across.x, across.y), -1.0 / d.z);
145
+ float depth = min(-d.z * travel, 1.0);
146
+ vec2 picture = 0.5 + (local + d.xy * travel - 0.5) / (1.0 + depth);
147
+ fxRoom = textureGrad(uAlbedo, vec3(picture, fx1.x - 1.0), dx * fx0.xy * 0.5, dy * fx0.xy * 0.5).rgb;
148
+ glow = own ? fxRoom * vEmissiveColor : fxRoom;
149
+ }
150
+ return vec4(glow * (lit * fx1.w * glass), glass);
151
+ }
152
+ `;