super-three 0.157.1 → 0.160.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 (303) hide show
  1. package/README.md +6 -4
  2. package/build/three.cjs +3100 -1537
  3. package/build/three.js +3100 -1537
  4. package/build/three.min.js +1 -1
  5. package/build/three.module.js +3093 -1538
  6. package/build/three.module.min.js +1 -1
  7. package/examples/jsm/Addons.js +291 -0
  8. package/examples/jsm/controls/FlyControls.js +26 -0
  9. package/examples/jsm/controls/OrbitControls.js +62 -41
  10. package/examples/jsm/controls/TransformControls.js +27 -11
  11. package/examples/jsm/csm/CSMShader.js +53 -48
  12. package/examples/jsm/exporters/GLTFExporter.js +151 -3
  13. package/examples/jsm/exporters/USDZExporter.js +27 -19
  14. package/examples/jsm/geometries/InstancedPointsGeometry.js +174 -0
  15. package/examples/jsm/geometries/SDFGeometryGenerator.js +144 -0
  16. package/examples/jsm/helpers/TextureHelper.js +237 -0
  17. package/examples/jsm/interactive/HTMLMesh.js +9 -2
  18. package/examples/jsm/libs/lottie_canvas.module.js +6 -1
  19. package/examples/jsm/libs/opentype.module.js +13 -75
  20. package/examples/jsm/libs/surfaceNet.js +201 -0
  21. package/examples/jsm/lines/LineMaterial.js +16 -33
  22. package/examples/jsm/loaders/ColladaLoader.js +0 -6
  23. package/examples/jsm/loaders/DRACOLoader.js +4 -3
  24. package/examples/jsm/loaders/FBXLoader.js +294 -124
  25. package/examples/jsm/loaders/GLTFLoader.js +83 -6
  26. package/examples/jsm/loaders/LUTImageLoader.js +162 -0
  27. package/examples/jsm/loaders/MaterialXLoader.js +73 -54
  28. package/examples/jsm/loaders/NRRDLoader.js +0 -13
  29. package/examples/jsm/loaders/SVGLoader.js +4 -4
  30. package/examples/jsm/loaders/USDZLoader.js +3 -17
  31. package/examples/jsm/loaders/lwo/IFFParser.js +89 -93
  32. package/examples/jsm/materials/MeshGouraudMaterial.js +2 -0
  33. package/examples/jsm/math/Capsule.js +0 -55
  34. package/examples/jsm/math/Octree.js +85 -7
  35. package/examples/jsm/misc/Timer.js +119 -0
  36. package/examples/jsm/misc/TubePainter.js +3 -6
  37. package/examples/jsm/modifiers/CurveModifier.js +20 -2
  38. package/examples/jsm/modifiers/SimplifyModifier.js +103 -11
  39. package/examples/jsm/modifiers/TessellateModifier.js +3 -3
  40. package/examples/jsm/nodes/Nodes.js +16 -12
  41. package/examples/jsm/nodes/accessors/CameraNode.js +18 -2
  42. package/examples/jsm/nodes/accessors/CubeTextureNode.js +5 -73
  43. package/examples/jsm/nodes/accessors/InstanceNode.js +3 -3
  44. package/examples/jsm/nodes/accessors/InstancedPointsMaterialNode.js +21 -0
  45. package/examples/jsm/nodes/accessors/MaterialNode.js +68 -31
  46. package/examples/jsm/nodes/accessors/MaterialReferenceNode.js +11 -2
  47. package/examples/jsm/nodes/accessors/ModelNode.js +1 -2
  48. package/examples/jsm/nodes/accessors/ModelViewProjectionNode.js +12 -3
  49. package/examples/jsm/nodes/accessors/MorphNode.js +191 -16
  50. package/examples/jsm/nodes/accessors/NormalNode.js +1 -1
  51. package/examples/jsm/nodes/accessors/PositionNode.js +1 -1
  52. package/examples/jsm/nodes/accessors/ReferenceNode.js +25 -1
  53. package/examples/jsm/nodes/accessors/SkinningNode.js +13 -3
  54. package/examples/jsm/nodes/accessors/TextureNode.js +123 -37
  55. package/examples/jsm/nodes/code/CodeNode.js +3 -3
  56. package/examples/jsm/nodes/code/FunctionNode.js +1 -1
  57. package/examples/jsm/nodes/core/AssignNode.js +72 -0
  58. package/examples/jsm/nodes/core/AttributeNode.js +7 -1
  59. package/examples/jsm/nodes/core/CacheNode.js +4 -1
  60. package/examples/jsm/nodes/core/ConstNode.js +1 -1
  61. package/examples/jsm/nodes/core/LightingModel.js +3 -1
  62. package/examples/jsm/nodes/core/Node.js +13 -15
  63. package/examples/jsm/nodes/core/NodeBuilder.js +209 -42
  64. package/examples/jsm/nodes/core/NodeFrame.js +10 -8
  65. package/examples/jsm/nodes/core/NodeUniform.js +12 -0
  66. package/examples/jsm/nodes/core/NodeUtils.js +7 -9
  67. package/examples/jsm/nodes/core/OutputStructNode.js +4 -4
  68. package/examples/jsm/nodes/core/ParameterNode.js +33 -0
  69. package/examples/jsm/nodes/core/PropertyNode.js +15 -6
  70. package/examples/jsm/nodes/core/StackNode.js +7 -17
  71. package/examples/jsm/nodes/core/StructTypeNode.js +4 -4
  72. package/examples/jsm/nodes/core/TempNode.js +1 -1
  73. package/examples/jsm/nodes/core/UniformGroup.js +13 -0
  74. package/examples/jsm/nodes/core/UniformGroupNode.js +36 -0
  75. package/examples/jsm/nodes/core/UniformNode.js +17 -0
  76. package/examples/jsm/nodes/core/VarNode.js +7 -34
  77. package/examples/jsm/nodes/core/VaryingNode.js +3 -7
  78. package/examples/jsm/nodes/display/BumpMapNode.js +35 -13
  79. package/examples/jsm/nodes/display/ColorAdjustmentNode.js +6 -10
  80. package/examples/jsm/nodes/display/GaussianBlurNode.js +170 -0
  81. package/examples/jsm/nodes/display/NormalMapNode.js +3 -1
  82. package/examples/jsm/nodes/display/PassNode.js +182 -0
  83. package/examples/jsm/nodes/display/ViewportDepthNode.js +31 -3
  84. package/examples/jsm/nodes/display/ViewportDepthTextureNode.js +2 -2
  85. package/examples/jsm/nodes/display/ViewportNode.js +17 -10
  86. package/examples/jsm/nodes/functions/BSDF/BRDF_Sheen.js +20 -6
  87. package/examples/jsm/nodes/functions/BSDF/DFGApprox.js +8 -7
  88. package/examples/jsm/nodes/functions/BSDF/D_GGX.js +8 -3
  89. package/examples/jsm/nodes/functions/BSDF/Schlick_to_F0.js +8 -0
  90. package/examples/jsm/nodes/functions/BSDF/V_GGX_SmithCorrelated.js +8 -0
  91. package/examples/jsm/nodes/functions/PhysicalLightingModel.js +93 -43
  92. package/examples/jsm/nodes/gpgpu/ComputeNode.js +2 -2
  93. package/examples/jsm/nodes/lighting/AmbientLightNode.js +1 -1
  94. package/examples/jsm/nodes/lighting/AnalyticLightNode.js +55 -6
  95. package/examples/jsm/nodes/lighting/DirectionalLightNode.js +1 -1
  96. package/examples/jsm/nodes/lighting/EnvironmentNode.js +8 -18
  97. package/examples/jsm/nodes/lighting/LightingContextNode.js +21 -57
  98. package/examples/jsm/nodes/lighting/LightsNode.js +80 -20
  99. package/examples/jsm/nodes/lighting/PointLightNode.js +1 -1
  100. package/examples/jsm/nodes/lighting/SpotLightNode.js +1 -1
  101. package/examples/jsm/nodes/materials/InstancedPointsNodeMaterial.js +162 -0
  102. package/examples/jsm/nodes/materials/Line2NodeMaterial.js +76 -77
  103. package/examples/jsm/nodes/materials/LineDashedNodeMaterial.js +5 -5
  104. package/examples/jsm/nodes/materials/Materials.js +1 -0
  105. package/examples/jsm/nodes/materials/MeshBasicNodeMaterial.js +1 -0
  106. package/examples/jsm/nodes/materials/MeshNormalNodeMaterial.js +3 -3
  107. package/examples/jsm/nodes/materials/MeshPhongNodeMaterial.js +3 -3
  108. package/examples/jsm/nodes/materials/MeshPhysicalNodeMaterial.js +47 -20
  109. package/examples/jsm/nodes/materials/MeshStandardNodeMaterial.js +6 -6
  110. package/examples/jsm/nodes/materials/NodeMaterial.js +82 -60
  111. package/examples/jsm/nodes/materials/PointsNodeMaterial.js +0 -10
  112. package/examples/jsm/nodes/materials/SpriteNodeMaterial.js +0 -7
  113. package/examples/jsm/nodes/materialx/MaterialXNodes.js +10 -10
  114. package/examples/jsm/nodes/materialx/lib/mx_hsv.js +128 -54
  115. package/examples/jsm/nodes/materialx/lib/mx_noise.js +1430 -618
  116. package/examples/jsm/nodes/materialx/lib/mx_transform_color.js +24 -14
  117. package/examples/jsm/nodes/math/MathNode.js +2 -0
  118. package/examples/jsm/nodes/math/OperatorNode.js +24 -27
  119. package/examples/jsm/nodes/shadernode/ShaderNode.js +158 -10
  120. package/examples/jsm/nodes/utils/ArrayElementNode.js +2 -0
  121. package/examples/jsm/nodes/utils/DiscardNode.js +3 -2
  122. package/examples/jsm/nodes/utils/FunctionOverloadingNode.js +95 -0
  123. package/examples/jsm/nodes/utils/JoinNode.js +11 -1
  124. package/examples/jsm/nodes/utils/LoopNode.js +36 -24
  125. package/examples/jsm/nodes/utils/RemapNode.js +2 -2
  126. package/examples/jsm/nodes/utils/SplitNode.js +10 -2
  127. package/examples/jsm/nodes/utils/TriplanarTexturesNode.js +3 -3
  128. package/examples/jsm/objects/InstancedPoints.js +21 -0
  129. package/examples/jsm/objects/Lensflare.js +20 -0
  130. package/examples/jsm/objects/QuadMesh.js +60 -0
  131. package/examples/jsm/objects/ReflectorForSSRPass.js +3 -0
  132. package/examples/jsm/objects/Refractor.js +3 -0
  133. package/examples/jsm/objects/Sky.js +5 -3
  134. package/examples/jsm/objects/Water.js +5 -2
  135. package/examples/jsm/objects/Water2.js +3 -0
  136. package/examples/jsm/physics/AmmoPhysics.js +21 -0
  137. package/examples/jsm/physics/RapierPhysics.js +21 -0
  138. package/examples/jsm/postprocessing/BokehPass.js +3 -2
  139. package/examples/jsm/postprocessing/GTAOPass.js +572 -0
  140. package/examples/jsm/postprocessing/LUTPass.js +2 -1
  141. package/examples/jsm/postprocessing/OutputPass.js +3 -0
  142. package/examples/jsm/postprocessing/Pass.js +14 -3
  143. package/examples/jsm/postprocessing/SAOPass.js +0 -1
  144. package/examples/jsm/postprocessing/SMAAPass.js +0 -2
  145. package/examples/jsm/postprocessing/TAARenderPass.js +1 -2
  146. package/examples/jsm/renderers/CSS3DRenderer.js +3 -9
  147. package/examples/jsm/renderers/SVGRenderer.js +9 -6
  148. package/examples/jsm/renderers/common/Animation.js +10 -21
  149. package/examples/jsm/renderers/common/Backend.js +19 -3
  150. package/examples/jsm/renderers/common/Background.js +20 -22
  151. package/examples/jsm/renderers/common/Bindings.js +31 -22
  152. package/examples/jsm/renderers/common/ChainMap.js +3 -3
  153. package/examples/jsm/renderers/common/Color4.js +37 -0
  154. package/examples/jsm/renderers/common/Geometries.js +4 -4
  155. package/examples/jsm/renderers/common/Info.js +12 -2
  156. package/examples/jsm/renderers/common/Pipelines.js +3 -51
  157. package/examples/jsm/renderers/common/PostProcessing.js +25 -0
  158. package/examples/jsm/renderers/common/RenderContext.js +1 -1
  159. package/examples/jsm/renderers/common/RenderContexts.js +1 -1
  160. package/examples/jsm/renderers/common/RenderObject.js +21 -2
  161. package/examples/jsm/renderers/common/RenderObjects.js +5 -3
  162. package/examples/jsm/renderers/common/Renderer.js +137 -37
  163. package/examples/jsm/renderers/common/StorageTexture.js +1 -0
  164. package/examples/jsm/renderers/common/Textures.js +8 -37
  165. package/examples/jsm/renderers/common/nodes/NodeBuilderState.js +10 -2
  166. package/examples/jsm/renderers/common/nodes/NodeUniformsGroup.js +44 -0
  167. package/examples/jsm/renderers/common/nodes/Nodes.js +121 -19
  168. package/examples/jsm/renderers/webgl/WebGLBackend.js +366 -67
  169. package/examples/jsm/renderers/webgl/nodes/GLSLNodeBuilder.js +183 -38
  170. package/examples/jsm/renderers/webgl/utils/WebGLAttributeUtils.js +92 -5
  171. package/examples/jsm/renderers/webgl/utils/WebGLCapabilities.js +36 -0
  172. package/examples/jsm/renderers/webgl/utils/WebGLExtensions.js +11 -1
  173. package/examples/jsm/renderers/webgl/utils/WebGLState.js +14 -2
  174. package/examples/jsm/renderers/webgl/utils/WebGLTextureUtils.js +71 -2
  175. package/examples/jsm/renderers/webgl/utils/WebGLUtils.js +42 -0
  176. package/examples/jsm/renderers/webgl-legacy/nodes/SlotNode.js +1 -1
  177. package/examples/jsm/renderers/webgl-legacy/nodes/WebGLNodeBuilder.js +33 -3
  178. package/examples/jsm/renderers/webgl-legacy/nodes/WebGLNodes.js +4 -14
  179. package/examples/jsm/renderers/webgpu/WebGPUBackend.js +188 -137
  180. package/examples/jsm/renderers/webgpu/WebGPURenderer.js +1 -1
  181. package/examples/jsm/renderers/webgpu/nodes/WGSLNodeBuilder.js +241 -90
  182. package/examples/jsm/renderers/webgpu/utils/WebGPUAttributeUtils.js +15 -10
  183. package/examples/jsm/renderers/webgpu/utils/WebGPUBindingUtils.js +11 -3
  184. package/examples/jsm/renderers/webgpu/utils/WebGPUPipelineUtils.js +2 -3
  185. package/examples/jsm/renderers/webgpu/utils/WebGPUTextureUtils.js +88 -6
  186. package/examples/jsm/shaders/ACESFilmicToneMappingShader.js +2 -0
  187. package/examples/jsm/shaders/AfterimageShader.js +2 -0
  188. package/examples/jsm/shaders/BasicShader.js +2 -0
  189. package/examples/jsm/shaders/BlendShader.js +2 -0
  190. package/examples/jsm/shaders/BokehShader.js +2 -0
  191. package/examples/jsm/shaders/BokehShader2.js +4 -0
  192. package/examples/jsm/shaders/BrightnessContrastShader.js +2 -0
  193. package/examples/jsm/shaders/ColorCorrectionShader.js +2 -0
  194. package/examples/jsm/shaders/DOFMipMapShader.js +2 -0
  195. package/examples/jsm/shaders/DepthLimitedBlurShader.js +5 -0
  196. package/examples/jsm/shaders/FXAAShader.js +135 -133
  197. package/examples/jsm/shaders/FilmShader.js +1 -1
  198. package/examples/jsm/shaders/FocusShader.js +2 -0
  199. package/examples/jsm/shaders/FreiChenShader.js +2 -0
  200. package/examples/jsm/shaders/GTAOShader.js +424 -0
  201. package/examples/jsm/shaders/GodRaysShader.js +8 -0
  202. package/examples/jsm/shaders/HalftoneShader.js +2 -0
  203. package/examples/jsm/shaders/HorizontalTiltShiftShader.js +2 -0
  204. package/examples/jsm/shaders/HueSaturationShader.js +2 -0
  205. package/examples/jsm/shaders/KaleidoShader.js +2 -0
  206. package/examples/jsm/shaders/LuminosityHighPassShader.js +2 -0
  207. package/examples/jsm/shaders/LuminosityShader.js +2 -0
  208. package/examples/jsm/shaders/MMDToonShader.js +2 -0
  209. package/examples/jsm/shaders/MirrorShader.js +2 -0
  210. package/examples/jsm/shaders/NormalMapShader.js +2 -0
  211. package/examples/jsm/shaders/OutputShader.js +8 -5
  212. package/examples/jsm/shaders/PoissonDenoiseShader.js +226 -0
  213. package/examples/jsm/shaders/SAOShader.js +7 -3
  214. package/examples/jsm/shaders/SMAAShader.js +6 -0
  215. package/examples/jsm/shaders/SSAOShader.js +8 -3
  216. package/examples/jsm/shaders/SSRShader.js +6 -0
  217. package/examples/jsm/shaders/SobelOperatorShader.js +2 -0
  218. package/examples/jsm/shaders/SubsurfaceScatteringShader.js +2 -0
  219. package/examples/jsm/shaders/TechnicolorShader.js +2 -0
  220. package/examples/jsm/shaders/TriangleBlurShader.js +2 -0
  221. package/examples/jsm/shaders/UnpackDepthRGBAShader.js +2 -0
  222. package/examples/jsm/shaders/VelocityShader.js +2 -0
  223. package/examples/jsm/shaders/VerticalTiltShiftShader.js +2 -0
  224. package/examples/jsm/shaders/WaterRefractionShader.js +2 -0
  225. package/examples/jsm/transpiler/AST.js +270 -0
  226. package/examples/jsm/transpiler/GLSLDecoder.js +941 -0
  227. package/examples/jsm/transpiler/ShaderToyDecoder.js +49 -0
  228. package/examples/jsm/transpiler/TSLEncoder.js +715 -0
  229. package/examples/jsm/transpiler/Transpiler.js +18 -0
  230. package/examples/jsm/utils/SortUtils.js +158 -0
  231. package/examples/jsm/utils/TextureUtils.js +33 -21
  232. package/examples/jsm/webxr/ARButton.js +14 -0
  233. package/examples/jsm/webxr/VRButton.js +24 -9
  234. package/examples/jsm/webxr/XRButton.js +27 -11
  235. package/examples/jsm/webxr/XREstimatedLight.js +1 -1
  236. package/package.json +8 -6
  237. package/src/Three.js +1 -0
  238. package/src/constants.js +8 -1
  239. package/src/core/BufferAttribute.js +21 -2
  240. package/src/core/InterleavedBuffer.js +21 -1
  241. package/src/core/Object3D.js +60 -12
  242. package/src/core/UniformsGroup.js +7 -1
  243. package/src/extras/PMREMGenerator.js +7 -1
  244. package/src/extras/curves/LineCurve3.js +4 -0
  245. package/src/loaders/AudioLoader.js +1 -1
  246. package/src/loaders/BufferGeometryLoader.js +0 -7
  247. package/src/loaders/ImageBitmapLoader.js +25 -1
  248. package/src/loaders/MaterialLoader.js +10 -2
  249. package/src/loaders/ObjectLoader.js +49 -0
  250. package/src/materials/Material.js +27 -13
  251. package/src/materials/ShaderMaterial.js +2 -1
  252. package/src/math/Box3.js +35 -18
  253. package/src/math/ColorManagement.js +0 -16
  254. package/src/math/Quaternion.js +5 -4
  255. package/src/math/Sphere.js +2 -0
  256. package/src/math/Triangle.js +17 -5
  257. package/src/math/Vector3.js +11 -12
  258. package/src/objects/BatchedMesh.js +1020 -0
  259. package/src/objects/Skeleton.js +1 -3
  260. package/src/objects/SkinnedMesh.js +6 -7
  261. package/src/renderers/WebGL3DRenderTarget.js +2 -2
  262. package/src/renderers/WebGLArrayRenderTarget.js +2 -2
  263. package/src/renderers/WebGLRenderer.js +165 -43
  264. package/src/renderers/shaders/ShaderChunk/aomap_fragment.glsl.js +8 -0
  265. package/src/renderers/shaders/ShaderChunk/batching_pars_vertex.glsl.js +19 -0
  266. package/src/renderers/shaders/ShaderChunk/batching_vertex.glsl.js +5 -0
  267. package/src/renderers/shaders/ShaderChunk/bumpmap_pars_fragment.glsl.js +3 -2
  268. package/src/renderers/shaders/ShaderChunk/cube_uv_reflection_fragment.glsl.js +0 -5
  269. package/src/renderers/shaders/ShaderChunk/defaultnormal_vertex.glsl.js +31 -4
  270. package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +1 -1
  271. package/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl.js +9 -4
  272. package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +8 -6
  273. package/src/renderers/shaders/ShaderChunk/project_vertex.glsl.js +6 -0
  274. package/src/renderers/shaders/ShaderChunk/skinning_pars_vertex.glsl.js +9 -17
  275. package/src/renderers/shaders/ShaderChunk/tonemapping_pars_fragment.glsl.js +84 -0
  276. package/src/renderers/shaders/ShaderChunk/worldpos_vertex.glsl.js +6 -0
  277. package/src/renderers/shaders/ShaderChunk.js +4 -0
  278. package/src/renderers/shaders/ShaderLib/depth.glsl.js +2 -0
  279. package/src/renderers/shaders/ShaderLib/distanceRGBA.glsl.js +2 -0
  280. package/src/renderers/shaders/ShaderLib/meshbasic.glsl.js +2 -0
  281. package/src/renderers/shaders/ShaderLib/meshlambert.glsl.js +2 -0
  282. package/src/renderers/shaders/ShaderLib/meshmatcap.glsl.js +3 -0
  283. package/src/renderers/shaders/ShaderLib/meshnormal.glsl.js +2 -0
  284. package/src/renderers/shaders/ShaderLib/meshphong.glsl.js +2 -0
  285. package/src/renderers/shaders/ShaderLib/meshphysical.glsl.js +4 -2
  286. package/src/renderers/shaders/ShaderLib/meshtoon.glsl.js +2 -0
  287. package/src/renderers/shaders/ShaderLib/shadow.glsl.js +3 -0
  288. package/src/renderers/webgl/WebGLAttributes.js +39 -5
  289. package/src/renderers/webgl/WebGLBufferRenderer.js +31 -0
  290. package/src/renderers/webgl/WebGLCubeMaps.js +1 -1
  291. package/src/renderers/webgl/WebGLExtensions.js +1 -0
  292. package/src/renderers/webgl/WebGLIndexedBufferRenderer.js +31 -0
  293. package/src/renderers/webgl/WebGLLights.js +11 -2
  294. package/src/renderers/webgl/WebGLProgram.js +100 -51
  295. package/src/renderers/webgl/WebGLPrograms.js +8 -0
  296. package/src/renderers/webgl/WebGLShadowMap.js +35 -0
  297. package/src/renderers/webgl/WebGLState.js +25 -4
  298. package/src/renderers/webgl/WebGLTextures.js +7 -11
  299. package/src/renderers/webgl/WebGLUniforms.js +11 -1
  300. package/src/renderers/webgl/WebGLUniformsGroups.js +72 -93
  301. package/src/renderers/webxr/WebXRManager.js +16 -0
  302. package/examples/jsm/nodes/accessors/ExtendedMaterialNode.js +0 -76
  303. package/examples/jsm/nodes/accessors/LineMaterialNode.js +0 -29
@@ -5,6 +5,7 @@ import {
5
5
  Matrix3,
6
6
  Matrix4,
7
7
  Object3D,
8
+ SRGBColorSpace,
8
9
  Vector3
9
10
  } from 'three';
10
11
  import { Projector } from '../renderers/Projector.js';
@@ -75,6 +76,8 @@ class SVGRenderer {
75
76
 
76
77
  this.overdraw = 0.5;
77
78
 
79
+ this.outputColorSpace = SRGBColorSpace;
80
+
78
81
  this.info = {
79
82
 
80
83
  render: {
@@ -155,7 +158,7 @@ class SVGRenderer {
155
158
  this.clear = function () {
156
159
 
157
160
  removeChildNodes();
158
- _svg.style.backgroundColor = _clearColor.getStyle();
161
+ _svg.style.backgroundColor = _clearColor.getStyle( _this.outputColorSpace );
159
162
 
160
163
  };
161
164
 
@@ -173,7 +176,7 @@ class SVGRenderer {
173
176
  if ( background && background.isColor ) {
174
177
 
175
178
  removeChildNodes();
176
- _svg.style.backgroundColor = background.getStyle();
179
+ _svg.style.backgroundColor = background.getStyle( _this.outputColorSpace );
177
180
 
178
181
  } else if ( this.autoClear === true ) {
179
182
 
@@ -389,7 +392,7 @@ class SVGRenderer {
389
392
 
390
393
  if ( material.isSpriteMaterial || material.isPointsMaterial ) {
391
394
 
392
- style = 'fill:' + material.color.getStyle() + ';fill-opacity:' + material.opacity;
395
+ style = 'fill:' + material.color.getStyle( _this.outputColorSpace ) + ';fill-opacity:' + material.opacity;
393
396
 
394
397
  }
395
398
 
@@ -403,7 +406,7 @@ class SVGRenderer {
403
406
 
404
407
  if ( material.isLineBasicMaterial ) {
405
408
 
406
- let style = 'fill:none;stroke:' + material.color.getStyle() + ';stroke-opacity:' + material.opacity + ';stroke-width:' + material.linewidth + ';stroke-linecap:' + material.linecap;
409
+ let style = 'fill:none;stroke:' + material.color.getStyle( _this.outputColorSpace ) + ';stroke-opacity:' + material.opacity + ';stroke-width:' + material.linewidth + ';stroke-linecap:' + material.linecap;
407
410
 
408
411
  if ( material.isLineDashedMaterial ) {
409
412
 
@@ -463,11 +466,11 @@ class SVGRenderer {
463
466
 
464
467
  if ( material.wireframe ) {
465
468
 
466
- style = 'fill:none;stroke:' + _color.getStyle() + ';stroke-opacity:' + material.opacity + ';stroke-width:' + material.wireframeLinewidth + ';stroke-linecap:' + material.wireframeLinecap + ';stroke-linejoin:' + material.wireframeLinejoin;
469
+ style = 'fill:none;stroke:' + _color.getStyle( _this.outputColorSpace ) + ';stroke-opacity:' + material.opacity + ';stroke-width:' + material.wireframeLinewidth + ';stroke-linecap:' + material.wireframeLinecap + ';stroke-linejoin:' + material.wireframeLinejoin;
467
470
 
468
471
  } else {
469
472
 
470
- style = 'fill:' + _color.getStyle() + ';fill-opacity:' + material.opacity;
473
+ style = 'fill:' + _color.getStyle( _this.outputColorSpace ) + ';fill-opacity:' + material.opacity;
471
474
 
472
475
  }
473
476
 
@@ -1,23 +1,18 @@
1
1
  class Animation {
2
2
 
3
- constructor() {
3
+ constructor( nodes, info ) {
4
4
 
5
- this.nodes = null;
5
+ this.nodes = nodes;
6
+ this.info = info;
6
7
 
7
8
  this.animationLoop = null;
8
9
  this.requestId = null;
9
10
 
10
- this.isAnimating = false;
11
-
12
- this.context = self;
11
+ this._init();
13
12
 
14
13
  }
15
14
 
16
- start() {
17
-
18
- if ( this.isAnimating === true || this.animationLoop === null || this.nodes === null ) return;
19
-
20
- this.isAnimating = true;
15
+ _init() {
21
16
 
22
17
  const update = ( time, frame ) => {
23
18
 
@@ -25,20 +20,20 @@ class Animation {
25
20
 
26
21
  this.nodes.nodeFrame.update();
27
22
 
28
- this.animationLoop( time, frame );
23
+ this.info.frame = this.nodes.nodeFrame.frameId;
24
+
25
+ if ( this.animationLoop !== null ) this.animationLoop( time, frame );
29
26
 
30
27
  };
31
28
 
32
- this.requestId = self.requestAnimationFrame( update );
29
+ update();
33
30
 
34
31
  }
35
32
 
36
- stop() {
33
+ dispose() {
37
34
 
38
35
  self.cancelAnimationFrame( this.requestId );
39
36
 
40
- this.isAnimating = false;
41
-
42
37
  }
43
38
 
44
39
  setAnimationLoop( callback ) {
@@ -47,12 +42,6 @@ class Animation {
47
42
 
48
43
  }
49
44
 
50
- setNodes( nodes ) {
51
-
52
- this.nodes = nodes;
53
-
54
- }
55
-
56
45
  }
57
46
 
58
47
  export default Animation;
@@ -1,6 +1,8 @@
1
1
  let vector2 = null;
2
2
  let vector4 = null;
3
+ let color4 = null;
3
4
 
5
+ import Color4 from './Color4.js';
4
6
  import { Vector2, Vector4, REVISION, createCanvasElement } from 'three';
5
7
 
6
8
  class Backend {
@@ -52,9 +54,9 @@ class Backend {
52
54
 
53
55
  // cache key
54
56
 
55
- needsUpdate( renderObject ) { } // return Boolean ( fast test )
57
+ needsRenderUpdate( renderObject ) { } // return Boolean ( fast test )
56
58
 
57
- getCacheKey( renderObject ) { } // return String
59
+ getRenderCacheKey( renderObject ) { } // return String
58
60
 
59
61
  // node builder
60
62
 
@@ -112,6 +114,20 @@ class Backend {
112
114
 
113
115
  }
114
116
 
117
+ getClearColor() {
118
+
119
+ const renderer = this.renderer;
120
+
121
+ color4 = color4 || new Color4();
122
+
123
+ renderer.getClearColor( color4 );
124
+
125
+ color4.getRGB( color4, this.renderer.currentColorSpace );
126
+
127
+ return color4;
128
+
129
+ }
130
+
115
131
  getDomElement() {
116
132
 
117
133
  let domElement = this.domElement;
@@ -121,7 +137,7 @@ class Backend {
121
137
  domElement = ( this.parameters.canvas !== undefined ) ? this.parameters.canvas : createCanvasElement();
122
138
 
123
139
  // OffscreenCanvas does not have setAttribute, see #22811
124
- if ( 'setAttribute' in domElement ) domElement.setAttribute( 'data-engine', `three.js r${REVISION}` );
140
+ if ( 'setAttribute' in domElement ) domElement.setAttribute( 'data-engine', `three.js r${REVISION} webgpu` );
125
141
 
126
142
  this.domElement = domElement;
127
143
 
@@ -1,9 +1,9 @@
1
1
  import DataMap from './DataMap.js';
2
- import { Color, Mesh, SphereGeometry, BackSide } from 'three';
3
- import { context, normalWorld, backgroundBlurriness, backgroundIntensity, NodeMaterial, modelViewProjection } from '../../nodes/Nodes.js';
2
+ import Color4 from './Color4.js';
3
+ import { Mesh, SphereGeometry, BackSide } from 'three';
4
+ import { vec4, context, normalWorld, backgroundBlurriness, backgroundIntensity, NodeMaterial, modelViewProjection } from '../../nodes/Nodes.js';
4
5
 
5
- let _clearAlpha;
6
- const _clearColor = new Color();
6
+ const _clearColor = new Color4();
7
7
 
8
8
  class Background extends DataMap {
9
9
 
@@ -14,9 +14,6 @@ class Background extends DataMap {
14
14
  this.renderer = renderer;
15
15
  this.nodes = nodes;
16
16
 
17
- this.backgroundMesh = null;
18
- this.backgroundMeshNode = null;
19
-
20
17
  }
21
18
 
22
19
  update( scene, renderList, renderContext ) {
@@ -30,15 +27,16 @@ class Background extends DataMap {
30
27
 
31
28
  // no background settings, use clear color configuration from the renderer
32
29
 
33
- _clearColor.copyLinearToSRGB( renderer._clearColor );
34
- _clearAlpha = renderer._clearAlpha;
30
+ renderer._clearColor.getRGB( _clearColor, this.renderer.currentColorSpace );
31
+ _clearColor.a = renderer._clearColor.a;
35
32
 
36
33
  } else if ( background.isColor === true ) {
37
34
 
38
35
  // background is an opaque color
39
36
 
40
- _clearColor.copyLinearToSRGB( background );
41
- _clearAlpha = 1;
37
+ background.getRGB( _clearColor, this.renderer.currentColorSpace );
38
+ _clearColor.a = 1;
39
+
42
40
  forceClear = true;
43
41
 
44
42
  } else if ( background.isNode === true ) {
@@ -47,30 +45,30 @@ class Background extends DataMap {
47
45
  const backgroundNode = background;
48
46
 
49
47
  _clearColor.copy( renderer._clearColor );
50
- _clearAlpha = renderer._clearAlpha;
51
48
 
52
- let backgroundMesh = this.backgroundMesh;
49
+ let backgroundMesh = sceneData.backgroundMesh;
53
50
 
54
- if ( backgroundMesh === null ) {
51
+ if ( backgroundMesh === undefined ) {
55
52
 
56
- this.backgroundMeshNode = context( backgroundNode, {
53
+ const backgroundMeshNode = context( vec4( backgroundNode ), {
57
54
  // @TODO: Add Texture2D support using node context
58
- getUVNode: () => normalWorld,
59
- getSamplerLevelNode: () => backgroundBlurriness
55
+ getUV: () => normalWorld,
56
+ getTextureLevel: () => backgroundBlurriness
60
57
  } ).mul( backgroundIntensity );
61
58
 
62
59
  let viewProj = modelViewProjection();
63
60
  viewProj = viewProj.setZ( viewProj.w );
64
61
 
65
62
  const nodeMaterial = new NodeMaterial();
66
- nodeMaterial.outputNode = this.backgroundMeshNode;
67
63
  nodeMaterial.side = BackSide;
68
64
  nodeMaterial.depthTest = false;
69
65
  nodeMaterial.depthWrite = false;
70
66
  nodeMaterial.fog = false;
71
67
  nodeMaterial.vertexNode = viewProj;
68
+ nodeMaterial.fragmentNode = backgroundMeshNode;
72
69
 
73
- this.backgroundMesh = backgroundMesh = new Mesh( new SphereGeometry( 1, 32, 32 ), nodeMaterial );
70
+ sceneData.backgroundMeshNode = backgroundMeshNode;
71
+ sceneData.backgroundMesh = backgroundMesh = new Mesh( new SphereGeometry( 1, 32, 32 ), nodeMaterial );
74
72
  backgroundMesh.frustumCulled = false;
75
73
 
76
74
  backgroundMesh.onBeforeRender = function ( renderer, scene, camera ) {
@@ -85,7 +83,7 @@ class Background extends DataMap {
85
83
 
86
84
  if ( sceneData.backgroundCacheKey !== backgroundCacheKey ) {
87
85
 
88
- this.backgroundMeshNode.node = backgroundNode;
86
+ sceneData.backgroundMeshNode.node = vec4( backgroundNode );
89
87
 
90
88
  backgroundMesh.material.needsUpdate = true;
91
89
 
@@ -105,14 +103,14 @@ class Background extends DataMap {
105
103
 
106
104
  if ( renderer.autoClear === true || forceClear === true ) {
107
105
 
108
- _clearColor.multiplyScalar( _clearAlpha );
106
+ _clearColor.multiplyScalar( _clearColor.a );
109
107
 
110
108
  const clearColorValue = renderContext.clearColorValue;
111
109
 
112
110
  clearColorValue.r = _clearColor.r;
113
111
  clearColorValue.g = _clearColor.g;
114
112
  clearColorValue.b = _clearColor.b;
115
- clearColorValue.a = _clearAlpha;
113
+ clearColorValue.a = _clearColor.a;
116
114
 
117
115
  renderContext.depthClearValue = renderer._clearDepth;
118
116
  renderContext.stencilClearValue = renderer._clearStencil;
@@ -16,8 +16,6 @@ class Bindings extends DataMap {
16
16
 
17
17
  this.pipelines.bindings = this; // assign bindings to pipelines
18
18
 
19
- this.updateMap = new WeakMap();
20
-
21
19
  }
22
20
 
23
21
  getForRender( renderObject ) {
@@ -50,7 +48,7 @@ class Bindings extends DataMap {
50
48
 
51
49
  const nodeBuilderState = this.nodes.getForCompute( computeNode );
52
50
 
53
- const bindings = nodeBuilderState.bindings;
51
+ const bindings = nodeBuilderState.bindings.compute;
54
52
 
55
53
  data.bindings = bindings;
56
54
 
@@ -100,24 +98,25 @@ class Bindings extends DataMap {
100
98
 
101
99
  const { backend } = this;
102
100
 
103
- const updateMap = this.updateMap;
104
- const frame = this.info.render.frame;
105
-
106
101
  let needsBindingsUpdate = false;
107
102
 
108
103
  // iterate over all bindings and check if buffer updates or a new binding group is required
109
104
 
110
105
  for ( const binding of bindings ) {
111
106
 
112
- const isUpdated = updateMap.get( binding ) === frame;
107
+ if ( binding.isNodeUniformsGroup ) {
108
+
109
+ const updated = this.nodes.updateGroup( binding );
113
110
 
114
- if ( isUpdated ) continue;
111
+ if ( ! updated ) continue;
112
+
113
+ }
115
114
 
116
115
  if ( binding.isUniformBuffer ) {
117
116
 
118
- const needsUpdate = binding.update();
117
+ const updated = binding.update();
119
118
 
120
- if ( needsUpdate ) {
119
+ if ( updated ) {
121
120
 
122
121
  backend.updateBinding( binding );
123
122
 
@@ -125,37 +124,47 @@ class Bindings extends DataMap {
125
124
 
126
125
  } else if ( binding.isSampledTexture ) {
127
126
 
127
+ const texture = binding.texture;
128
+
128
129
  if ( binding.needsBindingsUpdate ) needsBindingsUpdate = true;
129
130
 
130
- const needsUpdate = binding.update();
131
+ const updated = binding.update();
131
132
 
132
- if ( needsUpdate ) {
133
+ if ( updated ) {
133
134
 
134
135
  this.textures.updateTexture( binding.texture );
135
136
 
136
137
  }
137
138
 
138
- }
139
+ if ( texture.isStorageTexture === true ) {
139
140
 
140
- updateMap.set( binding, frame );
141
+ const textureData = this.get( texture );
141
142
 
142
- }
143
+ if ( binding.store === true ) {
143
144
 
144
- if ( needsBindingsUpdate === true ) {
145
+ textureData.needsMipmap = true;
145
146
 
146
- const pipeline = this.pipelines.getForRender( object );
147
+ } else if ( texture.generateMipmaps === true && this.textures.needsMipmaps( texture ) && textureData.needsMipmap === true ) {
147
148
 
148
- this.backend.updateBindings( bindings, pipeline );
149
+ this.backend.generateMipmaps( texture );
150
+
151
+ textureData.needsMipmap = false;
152
+
153
+ }
154
+
155
+ }
156
+
157
+ }
149
158
 
150
159
  }
151
160
 
152
- }
161
+ if ( needsBindingsUpdate === true ) {
153
162
 
154
- dispose() {
163
+ const pipeline = this.pipelines.getForRender( object );
155
164
 
156
- super.dispose();
165
+ this.backend.updateBindings( bindings, pipeline );
157
166
 
158
- this.updateMap = new WeakMap();
167
+ }
159
168
 
160
169
  }
161
170
 
@@ -12,7 +12,7 @@ export default class ChainMap {
12
12
 
13
13
  let map = this.weakMap;
14
14
 
15
- for ( let i = 0; i < keys.length - 1; i ++ ) {
15
+ for ( let i = 0; i < keys.length; i ++ ) {
16
16
 
17
17
  map = map.get( keys[ i ] );
18
18
 
@@ -36,7 +36,7 @@ export default class ChainMap {
36
36
 
37
37
  let map = this.weakMap;
38
38
 
39
- for ( let i = 0; i < keys.length - 1; i ++ ) {
39
+ for ( let i = 0; i < keys.length; i ++ ) {
40
40
 
41
41
  const key = keys[ i ];
42
42
 
@@ -62,7 +62,7 @@ export default class ChainMap {
62
62
 
63
63
  let map = this.weakMap;
64
64
 
65
- for ( let i = 0; i < keys.length - 1; i ++ ) {
65
+ for ( let i = 0; i < keys.length; i ++ ) {
66
66
 
67
67
  map = map.get( keys[ i ] );
68
68
 
@@ -0,0 +1,37 @@
1
+ import { Color } from 'three';
2
+
3
+ class Color4 extends Color {
4
+
5
+ constructor( r, g, b, a = 1 ) {
6
+
7
+ super( r, g, b );
8
+
9
+ this.a = a;
10
+
11
+ }
12
+
13
+ set( r, g, b, a = 1 ) {
14
+
15
+ this.a = a;
16
+
17
+ return super.set( r, g, b );
18
+
19
+ }
20
+
21
+ copy( color ) {
22
+
23
+ if ( color.a !== undefined ) this.a = color.a;
24
+
25
+ return super.copy( color );
26
+
27
+ }
28
+
29
+ clone() {
30
+
31
+ return new this.constructor( this.r, this.g, this.b, this.a );
32
+
33
+ }
34
+
35
+ }
36
+
37
+ export default Color4;
@@ -76,7 +76,7 @@ class Geometries extends DataMap {
76
76
  this.info = info;
77
77
 
78
78
  this.wireframes = new WeakMap();
79
- this.attributeFrame = new WeakMap();
79
+ this.attributeCall = new WeakMap();
80
80
 
81
81
  }
82
82
 
@@ -162,13 +162,13 @@ class Geometries extends DataMap {
162
162
 
163
163
  updateAttribute( attribute, type ) {
164
164
 
165
- const frame = this.info.render.frame;
165
+ const callId = this.info.render.calls;
166
166
 
167
- if ( this.attributeFrame.get( attribute ) !== frame ) {
167
+ if ( this.attributeCall.get( attribute ) !== callId ) {
168
168
 
169
169
  this.attributes.update( attribute, type );
170
170
 
171
- this.attributeFrame.set( attribute, frame );
171
+ this.attributeCall.set( attribute, callId );
172
172
 
173
173
  }
174
174
 
@@ -4,14 +4,21 @@ class Info {
4
4
 
5
5
  this.autoReset = true;
6
6
 
7
+ this.frame = 0;
8
+ this.calls = 0;
9
+
7
10
  this.render = {
8
- frame: 0,
11
+ calls: 0,
9
12
  drawCalls: 0,
10
13
  triangles: 0,
11
14
  points: 0,
12
15
  lines: 0
13
16
  };
14
17
 
18
+ this.compute = {
19
+ calls: 0
20
+ };
21
+
15
22
  this.memory = {
16
23
  geometries: 0,
17
24
  textures: 0
@@ -60,7 +67,10 @@ class Info {
60
67
 
61
68
  this.reset();
62
69
 
63
- this.render.frame = 0;
70
+ this.calls = 0;
71
+
72
+ this.render.calls = 0;
73
+ this.compute.calls = 0;
64
74
 
65
75
  this.memory.geometries = 0;
66
76
  this.memory.textures = 0;
@@ -276,29 +276,13 @@ class Pipelines extends DataMap {
276
276
 
277
277
  _getComputeCacheKey( computeNode, stageCompute ) {
278
278
 
279
- return 'compute' + computeNode.id + stageCompute.id;
279
+ return computeNode.id + ',' + stageCompute.id;
280
280
 
281
281
  }
282
282
 
283
283
  _getRenderCacheKey( renderObject, stageVertex, stageFragment ) {
284
284
 
285
- const { material } = renderObject;
286
-
287
- const parameters = [
288
- stageVertex.id, stageFragment.id,
289
- material.transparent, material.blending, material.premultipliedAlpha,
290
- material.blendSrc, material.blendDst, material.blendEquation,
291
- material.blendSrcAlpha, material.blendDstAlpha, material.blendEquationAlpha,
292
- material.colorWrite,
293
- material.depthWrite, material.depthTest, material.depthFunc,
294
- material.stencilWrite, material.stencilFunc,
295
- material.stencilFail, material.stencilZFail, material.stencilZPass,
296
- material.stencilFuncMask, material.stencilWriteMask,
297
- material.side,
298
- this.backend.getCacheKey( renderObject )
299
- ];
300
-
301
- return parameters.join();
285
+ return stageVertex.id + ',' + stageFragment.id + ',' + this.backend.getRenderCacheKey( renderObject );
302
286
 
303
287
  }
304
288
 
@@ -328,40 +312,8 @@ class Pipelines extends DataMap {
328
312
  _needsRenderUpdate( renderObject ) {
329
313
 
330
314
  const data = this.get( renderObject );
331
- const material = renderObject.material;
332
-
333
- let needsUpdate = this.backend.needsUpdate( renderObject );
334
-
335
- // check material state
336
-
337
- if ( data.material !== material || data.materialVersion !== material.version ||
338
- data.transparent !== material.transparent || data.blending !== material.blending || data.premultipliedAlpha !== material.premultipliedAlpha ||
339
- data.blendSrc !== material.blendSrc || data.blendDst !== material.blendDst || data.blendEquation !== material.blendEquation ||
340
- data.blendSrcAlpha !== material.blendSrcAlpha || data.blendDstAlpha !== material.blendDstAlpha || data.blendEquationAlpha !== material.blendEquationAlpha ||
341
- data.colorWrite !== material.colorWrite ||
342
- data.depthWrite !== material.depthWrite || data.depthTest !== material.depthTest || data.depthFunc !== material.depthFunc ||
343
- data.stencilWrite !== material.stencilWrite || data.stencilFunc !== material.stencilFunc ||
344
- data.stencilFail !== material.stencilFail || data.stencilZFail !== material.stencilZFail || data.stencilZPass !== material.stencilZPass ||
345
- data.stencilFuncMask !== material.stencilFuncMask || data.stencilWriteMask !== material.stencilWriteMask ||
346
- data.side !== material.side || data.alphaToCoverage !== material.alphaToCoverage
347
- ) {
348
-
349
- data.material = material; data.materialVersion = material.version;
350
- data.transparent = material.transparent; data.blending = material.blending; data.premultipliedAlpha = material.premultipliedAlpha;
351
- data.blendSrc = material.blendSrc; data.blendDst = material.blendDst; data.blendEquation = material.blendEquation;
352
- data.blendSrcAlpha = material.blendSrcAlpha; data.blendDstAlpha = material.blendDstAlpha; data.blendEquationAlpha = material.blendEquationAlpha;
353
- data.colorWrite = material.colorWrite;
354
- data.depthWrite = material.depthWrite; data.depthTest = material.depthTest; data.depthFunc = material.depthFunc;
355
- data.stencilWrite = material.stencilWrite; data.stencilFunc = material.stencilFunc;
356
- data.stencilFail = material.stencilFail; data.stencilZFail = material.stencilZFail; data.stencilZPass = material.stencilZPass;
357
- data.stencilFuncMask = material.stencilFuncMask; data.stencilWriteMask = material.stencilWriteMask;
358
- data.side = material.side; data.alphaToCoverage = material.alphaToCoverage;
359
-
360
- needsUpdate = true;
361
-
362
- }
363
315
 
364
- return needsUpdate || data.pipeline === undefined;
316
+ return data.pipeline === undefined || this.backend.needsRenderUpdate( renderObject );
365
317
 
366
318
  }
367
319
 
@@ -0,0 +1,25 @@
1
+ import { vec4, MeshBasicNodeMaterial } from '../../nodes/Nodes.js';
2
+ import QuadMesh from '../../objects/QuadMesh.js';
3
+
4
+ const quadMesh = new QuadMesh( new MeshBasicNodeMaterial() );
5
+
6
+ class PostProcessing {
7
+
8
+ constructor( renderer, outputNode = vec4( 0, 0, 1, 1 ) ) {
9
+
10
+ this.renderer = renderer;
11
+ this.outputNode = outputNode;
12
+
13
+ }
14
+
15
+ render() {
16
+
17
+ quadMesh.material.fragmentNode = this.outputNode;
18
+
19
+ quadMesh.render( this.renderer );
20
+
21
+ }
22
+
23
+ }
24
+
25
+ export default PostProcessing;
@@ -26,7 +26,7 @@ class RenderContext {
26
26
  this.scissor = false;
27
27
  this.scissorValue = new Vector4();
28
28
 
29
- this.texture = null;
29
+ this.textures = null;
30
30
  this.depthTexture = null;
31
31
  this.activeCubeFace = 0;
32
32
  this.sampleCount = 1;
@@ -35,7 +35,7 @@ class RenderContexts {
35
35
 
36
36
  }
37
37
 
38
- attachmentState = `${count}:${format}:${renderTarget.samples}:${renderTarget.depthBuffer}:${renderTarget.stencilBuffer}`;
38
+ attachmentState = `${ count }:${ format }:${ renderTarget.samples }:${ renderTarget.depthBuffer }:${ renderTarget.stencilBuffer }`;
39
39
 
40
40
  }
41
41