aptechka 0.1.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 (115) hide show
  1. package/.prettierignore +16 -0
  2. package/.prettierrc +9 -0
  3. package/.vscode/extensions.json +4 -0
  4. package/.vscode/launch.json +11 -0
  5. package/.vscode/settings.json +18 -0
  6. package/README.md +0 -0
  7. package/index.html +32 -0
  8. package/package.json +272 -0
  9. package/public/vite.svg +1 -0
  10. package/src/packages/animation/Animated.ts +189 -0
  11. package/src/packages/animation/Damped.ts +39 -0
  12. package/src/packages/animation/Tweened.ts +51 -0
  13. package/src/packages/animation/index.ts +10 -0
  14. package/src/packages/attribute/index.ts +59 -0
  15. package/src/packages/canvas-2d/index.ts +137 -0
  16. package/src/packages/controls/Controls.ts +15 -0
  17. package/src/packages/controls/KeyboardControls.ts +63 -0
  18. package/src/packages/controls/LinearControls.ts +27 -0
  19. package/src/packages/controls/User.ts +20 -0
  20. package/src/packages/controls/WheelControls.ts +92 -0
  21. package/src/packages/controls/index.ts +5 -0
  22. package/src/packages/css-unit-parser/index.ts +32 -0
  23. package/src/packages/custom-element/index.ts +19 -0
  24. package/src/packages/device/Device.ts +113 -0
  25. package/src/packages/device/Viewport.ts +67 -0
  26. package/src/packages/device/index.ts +2 -0
  27. package/src/packages/element-constructor/ElementConstructor.ts +577 -0
  28. package/src/packages/element-constructor/htmlTags.ts +679 -0
  29. package/src/packages/element-constructor/index.ts +4 -0
  30. package/src/packages/element-constructor/specialObjects.ts +8 -0
  31. package/src/packages/element-constructor/svgTags.ts +588 -0
  32. package/src/packages/en3/attachments/En3SourceManager.ts +116 -0
  33. package/src/packages/en3/core/en3.ts +306 -0
  34. package/src/packages/en3/index.ts +52 -0
  35. package/src/packages/en3/instances/en3LazyLoader.ts +22 -0
  36. package/src/packages/en3/libs/MeshoptDecoder.js +138 -0
  37. package/src/packages/en3/loaders/en3GLTFLoader.ts +54 -0
  38. package/src/packages/en3/loaders/en3TextureLoader.ts +3 -0
  39. package/src/packages/en3/objects/En3Clip.ts +53 -0
  40. package/src/packages/en3/objects/En3ClipHelpers.ts +12 -0
  41. package/src/packages/en3/objects/En3GLTF.ts +35 -0
  42. package/src/packages/en3/objects/En3Image.ts +18 -0
  43. package/src/packages/en3/objects/En3ImageLike.ts +101 -0
  44. package/src/packages/en3/objects/En3SourceConsumer.ts +5 -0
  45. package/src/packages/en3/objects/En3Video.ts +88 -0
  46. package/src/packages/en3/test/En3HTML.ts +55 -0
  47. package/src/packages/en3/test/En3ModifiedMaterial.ts +221 -0
  48. package/src/packages/en3/test/En3Raycaster.ts +187 -0
  49. package/src/packages/en3/utils/coverTexture.ts +29 -0
  50. package/src/packages/en3/utils/dispose.ts +27 -0
  51. package/src/packages/en3/utils/traverseMaterials.ts +10 -0
  52. package/src/packages/en3/utils/traverseMeshes.ts +9 -0
  53. package/src/packages/image/index.ts +19 -0
  54. package/src/packages/intersector/index.ts +83 -0
  55. package/src/packages/ladder/index.ts +112 -0
  56. package/src/packages/layout-box/index.ts +417 -0
  57. package/src/packages/loading/index.ts +131 -0
  58. package/src/packages/measurer/CumulativeOffsetLeft.ts +8 -0
  59. package/src/packages/measurer/CumulativeOffsetTop.ts +8 -0
  60. package/src/packages/measurer/Meaurer.ts +38 -0
  61. package/src/packages/measurer/index.ts +3 -0
  62. package/src/packages/media/index.ts +38 -0
  63. package/src/packages/morph/Link.ts +32 -0
  64. package/src/packages/morph/Morph.ts +246 -0
  65. package/src/packages/morph/index.ts +10 -0
  66. package/src/packages/notifier/index.ts +41 -0
  67. package/src/packages/order/index.ts +14 -0
  68. package/src/packages/resizer/index.ts +55 -0
  69. package/src/packages/router/Link.ts +33 -0
  70. package/src/packages/router/Route.ts +152 -0
  71. package/src/packages/router/RouteElement.ts +34 -0
  72. package/src/packages/router/Router.ts +190 -0
  73. package/src/packages/router/index.ts +13 -0
  74. package/src/packages/scroll/ScrollElement.ts +618 -0
  75. package/src/packages/scroll/ScrollUserElement.ts +21 -0
  76. package/src/packages/scroll/ScrollbarElement.ts +170 -0
  77. package/src/packages/scroll/index.ts +2 -0
  78. package/src/packages/scroll-entries/index.ts +74 -0
  79. package/src/packages/source/SourceClass.ts +77 -0
  80. package/src/packages/source/SourceElement.ts +177 -0
  81. package/src/packages/source/SourceManager.ts +61 -0
  82. package/src/packages/source/SourceSet.ts +52 -0
  83. package/src/packages/source/index.ts +8 -0
  84. package/src/packages/store/Composed.ts +33 -0
  85. package/src/packages/store/Derived.ts +24 -0
  86. package/src/packages/store/DerivedArray.ts +36 -0
  87. package/src/packages/store/Resource.ts +38 -0
  88. package/src/packages/store/Store.ts +144 -0
  89. package/src/packages/store/StoreRegistry.ts +105 -0
  90. package/src/packages/store/index.ts +23 -0
  91. package/src/packages/ticker/index.ts +173 -0
  92. package/src/packages/utils/array.ts +3 -0
  93. package/src/packages/utils/attributes.ts +19 -0
  94. package/src/packages/utils/browser.ts +2 -0
  95. package/src/packages/utils/canvas.ts +46 -0
  96. package/src/packages/utils/collisions.ts +12 -0
  97. package/src/packages/utils/coordinates.ts +40 -0
  98. package/src/packages/utils/decoding.ts +11 -0
  99. package/src/packages/utils/dev.ts +5 -0
  100. package/src/packages/utils/dom.ts +48 -0
  101. package/src/packages/utils/easings.ts +69 -0
  102. package/src/packages/utils/file.ts +17 -0
  103. package/src/packages/utils/function.ts +29 -0
  104. package/src/packages/utils/index.ts +61 -0
  105. package/src/packages/utils/layout.ts +22 -0
  106. package/src/packages/utils/math.ts +74 -0
  107. package/src/packages/utils/number.ts +26 -0
  108. package/src/packages/utils/object.ts +108 -0
  109. package/src/packages/utils/string.ts +49 -0
  110. package/src/packages/utils/ts-shape.ts +25 -0
  111. package/src/packages/utils/ts-utility.ts +47 -0
  112. package/src/packages/video/index.ts +39 -0
  113. package/src/playground/index.ts +0 -0
  114. package/tsconfig.json +31 -0
  115. package/vite.config.ts +65 -0
@@ -0,0 +1,35 @@
1
+ import { Group } from 'three'
2
+ import type { GLTF } from 'three/examples/jsm/loaders/GLTFLoader.js'
3
+ import { dispose } from '../utils/dispose'
4
+ import { en3GLTFLoader } from '../loaders/en3GLTFLoader'
5
+ import { En3SourceConsumer } from './En3SourceConsumer'
6
+ import { En3SourceManager, En3SourceManagerParameters } from '../attachments/En3SourceManager'
7
+
8
+ export class En3GLTF extends Group implements En3SourceConsumer<GLTF> {
9
+ #sourceManager: En3SourceManager<GLTF>
10
+
11
+ constructor(parameters: En3SourceManagerParameters<GLTF>) {
12
+ super()
13
+
14
+ this.#sourceManager = new En3SourceManager({
15
+ loader: en3GLTFLoader,
16
+ consumer: this,
17
+ ...parameters,
18
+ })
19
+
20
+ this.#sourceManager.data.subscribe((detail) => {
21
+ if (!detail.current) {
22
+ this.children.forEach((child) => {
23
+ this.remove(child)
24
+ dispose(child)
25
+ })
26
+ } else {
27
+ this.add(...detail.current.scene.children)
28
+ }
29
+ })
30
+ }
31
+
32
+ public get sourceManager() {
33
+ return this.#sourceManager
34
+ }
35
+ }
@@ -0,0 +1,18 @@
1
+ import { Texture } from 'three'
2
+ import { En3ImageLike, En3ImageLikeMaterial, En3ImageLikeParameters } from './En3ImageLike'
3
+ import { en3TextureLoader } from '../loaders/en3TextureLoader'
4
+
5
+ export interface En3ImageParameters<TMaterial extends En3ImageLikeMaterial<Texture>>
6
+ extends Omit<En3ImageLikeParameters<Texture, TMaterial>, 'loader'> {}
7
+
8
+ export class En3Image<TMaterial extends En3ImageLikeMaterial<Texture>> extends En3ImageLike<
9
+ Texture,
10
+ TMaterial
11
+ > {
12
+ constructor(parameters: En3ImageParameters<TMaterial>) {
13
+ super({
14
+ ...parameters,
15
+ loader: en3TextureLoader,
16
+ })
17
+ }
18
+ }
@@ -0,0 +1,101 @@
1
+ import { Material, Mesh, PlaneGeometry, SRGBColorSpace, Texture } from 'three'
2
+ import { coverTexture } from '../utils/coverTexture'
3
+ import {
4
+ En3SourceManager,
5
+ En3SourceManagerLoader,
6
+ En3SourceManagerParameters,
7
+ } from '../attachments/En3SourceManager'
8
+ import { En3SourceConsumer } from './En3SourceConsumer'
9
+ import { resizer } from '$packages/resizer'
10
+
11
+ export type En3ImageLikeMaterial<TTexture extends Texture> = Material & { map: TTexture | null }
12
+
13
+ export interface En3ImageLikeParameters<
14
+ TTexture extends Texture,
15
+ TMaterial extends En3ImageLikeMaterial<TTexture>
16
+ > extends En3SourceManagerParameters<TTexture> {
17
+ width?: number
18
+ height?: number
19
+ widthSegments?: number
20
+ heightSegments?: number
21
+ material?: TMaterial
22
+ cover?: boolean
23
+ loader: En3SourceManagerLoader<TTexture>
24
+ }
25
+
26
+ export class En3ImageLike<
27
+ TTexture extends Texture,
28
+ TMaterial extends En3ImageLikeMaterial<TTexture>
29
+ >
30
+ extends Mesh<PlaneGeometry, TMaterial>
31
+ implements En3SourceConsumer<TTexture>
32
+ {
33
+ #sourceManager: En3SourceManager<TTexture>
34
+ #isCover: boolean
35
+
36
+ constructor(parameters: En3ImageLikeParameters<TTexture, TMaterial>) {
37
+ super(
38
+ new PlaneGeometry(
39
+ parameters.width,
40
+ parameters.height,
41
+ parameters.widthSegments,
42
+ parameters.heightSegments
43
+ ),
44
+ parameters.material
45
+ )
46
+
47
+ this.#sourceManager = new En3SourceManager<TTexture>({
48
+ consumer: this,
49
+ ...parameters,
50
+ })
51
+
52
+ this.#isCover = parameters.cover || false
53
+
54
+ this.addEventListener('added', () => {
55
+ resizer.subscribe(this.#resizeListener)
56
+ })
57
+
58
+ this.addEventListener('removed', () => {
59
+ resizer.unsubscribe(this.#resizeListener)
60
+ })
61
+
62
+ this.#sourceManager.data.subscribe((detail) => {
63
+ if (!detail.current && detail.previous) {
64
+ detail.previous.dispose()
65
+ } else if (detail.current) {
66
+ if (this.material) {
67
+ if (this.#isCover) {
68
+ detail.current.matrixAutoUpdate = false
69
+ }
70
+
71
+ detail.current.colorSpace = SRGBColorSpace
72
+ detail.current.center.set(0.5, 0.5)
73
+ this.material.map = detail.current
74
+ this.material.needsUpdate = true
75
+ this.#resizeListener()
76
+ }
77
+ }
78
+ })
79
+ }
80
+
81
+ public get sourceManager() {
82
+ return this.#sourceManager
83
+ }
84
+
85
+ public updateTexture() {
86
+ this.#resizeListener()
87
+ }
88
+
89
+ protected onCoverResize(texture: TTexture) {
90
+ coverTexture(texture, {
91
+ x: this.scale.x,
92
+ y: this.scale.y,
93
+ })
94
+ }
95
+
96
+ #resizeListener = () => {
97
+ if (this.#sourceManager.data.current && this.#isCover) {
98
+ this.onCoverResize(this.#sourceManager.data.current)
99
+ }
100
+ }
101
+ }
@@ -0,0 +1,5 @@
1
+ import { En3SourceManager } from '../attachments/En3SourceManager'
2
+
3
+ export interface En3SourceConsumer<T> {
4
+ get sourceManager(): En3SourceManager<T>
5
+ }
@@ -0,0 +1,88 @@
1
+ import { Loader, VideoTexture } from 'three'
2
+ import { En3ImageLike, En3ImageLikeMaterial, En3ImageLikeParameters } from './En3ImageLike'
3
+ import { coverTexture } from '../utils/coverTexture'
4
+
5
+ class En3VideoLoader<
6
+ P extends Parameters<Loader<VideoTexture>['load']> = Parameters<Loader<VideoTexture>['load']>
7
+ > {
8
+ public load(...parameters: P) {
9
+ const url = parameters[0]
10
+ const onLoad = parameters[1]
11
+ const onError = parameters[3]
12
+
13
+ const videoElement = document.createElement('video')
14
+ videoElement.src = url
15
+
16
+ videoElement.onloadeddata = () => {
17
+ onLoad(new VideoTexture(videoElement))
18
+
19
+ videoElement.onerror = null
20
+ videoElement.onloadeddata = null
21
+ }
22
+
23
+ videoElement.onerror = () => {
24
+ onError?.(url)
25
+
26
+ videoElement.onerror = null
27
+ videoElement.onloadeddata = null
28
+ }
29
+ }
30
+ }
31
+
32
+ export interface En3VideoParameters<TMaterial extends En3ImageLikeMaterial<VideoTexture>>
33
+ extends Omit<En3ImageLikeParameters<VideoTexture, TMaterial>, 'loader'> {
34
+ autoplay?: boolean
35
+ muted?: boolean
36
+ loop?: boolean
37
+ }
38
+
39
+ export class En3Video<TMaterial extends En3ImageLikeMaterial<VideoTexture>> extends En3ImageLike<
40
+ VideoTexture,
41
+ TMaterial
42
+ > {
43
+ #isAutoplay: boolean
44
+ #isMuted: boolean
45
+ #isLoop: boolean
46
+
47
+ constructor(parameters: En3VideoParameters<TMaterial>) {
48
+ super({
49
+ ...parameters,
50
+ loader: new En3VideoLoader(),
51
+ })
52
+
53
+ this.#isAutoplay = parameters.autoplay || false
54
+ this.#isMuted = parameters.muted || false
55
+ this.#isLoop = parameters.loop || false
56
+
57
+ this.sourceManager.data.subscribe((v) => {
58
+ if (v.current) {
59
+ const video = v.current.image as HTMLVideoElement
60
+
61
+ if (this.#isMuted) {
62
+ video.muted = true
63
+ }
64
+
65
+ if (this.#isLoop) {
66
+ video.loop = true
67
+ }
68
+
69
+ if (this.#isAutoplay) {
70
+ video.play()
71
+ }
72
+ }
73
+ })
74
+ }
75
+
76
+ protected override onCoverResize(texture: VideoTexture) {
77
+ const video = texture.image as HTMLVideoElement
78
+
79
+ coverTexture(
80
+ texture,
81
+ {
82
+ x: this.scale.x,
83
+ y: this.scale.y,
84
+ },
85
+ video.videoWidth / video.videoHeight
86
+ )
87
+ }
88
+ }
@@ -0,0 +1,55 @@
1
+ import { CSS3DObject, CSS3DRenderer } from 'three/examples/jsm/renderers/CSS3DRenderer.js'
2
+ import { RESIZE_ORDER, TICK_ORDER } from '$packages/order'
3
+ import { resizer } from '$packages/resizer'
4
+ import { ticker } from '$packages/ticker'
5
+ import { en3 } from '../core/en3'
6
+
7
+ export interface En3HTMLParameters {
8
+ element: HTMLElement
9
+ }
10
+
11
+ export class En3HTML extends CSS3DObject {
12
+ static #cssRenderer: CSS3DRenderer = null!
13
+
14
+ static #createRenderer() {
15
+ En3HTML.#cssRenderer = new CSS3DRenderer()
16
+ En3HTML.#cssRenderer.domElement.style.cssText = `
17
+ position: fixed;
18
+ left: 0;
19
+ top: 0;
20
+ width: 100%;
21
+ height: 100%;
22
+ z-index: 1;
23
+ pointer-events: none;
24
+ overflow: hidden;
25
+ `
26
+
27
+ en3.containerElement.prepend(En3HTML.#cssRenderer.domElement)
28
+
29
+ resizer.subscribe(this.#resizeListener, RESIZE_ORDER.EN3 + 1)
30
+ ticker.subscribe(this.#tickListener, { order: TICK_ORDER.EN3 + 1 })
31
+ }
32
+
33
+ public static destroy() {
34
+ resizer.unsubscribe(this.#resizeListener)
35
+ ticker.unsubscribe(this.#tickListener)
36
+
37
+ this.#cssRenderer = null!
38
+ }
39
+
40
+ static #tickListener = () => {
41
+ this.#cssRenderer.render(en3.scene, en3.camera)
42
+ }
43
+
44
+ static #resizeListener = () => {
45
+ this.#cssRenderer.setSize(en3.width, en3.height)
46
+ }
47
+
48
+ constructor(parameters: En3HTMLParameters) {
49
+ super(parameters.element)
50
+
51
+ if (!En3HTML.#cssRenderer) {
52
+ En3HTML.#createRenderer()
53
+ }
54
+ }
55
+ }
@@ -0,0 +1,221 @@
1
+ import { Material, WebGLProgramParametersWithUniforms } from 'three'
2
+
3
+ export type En3VertexChunk =
4
+ | 'begin_vertex'
5
+ | 'beginnormal_vertex'
6
+ | 'clipping_planes_pars_vertex'
7
+ | 'clipping_planes_vertex'
8
+ | 'color_pars_vertex'
9
+ | 'color_vertex'
10
+ | 'default_vertex'
11
+ | 'defaultnormal_vertex'
12
+ | 'displacementmap_pars_vertex'
13
+ | 'displacementmap_vertex'
14
+ | 'envmap_pars_vertex'
15
+ | 'envmap_vertex'
16
+ | 'fog_pars_vertex'
17
+ | 'fog_vertex'
18
+ | 'lights_pars_begin'
19
+ | 'logdepthbuf_pars_vertex'
20
+ | 'logdepthbuf_vertex'
21
+ | 'morphcolor_vertex'
22
+ | 'morphnormal_vertex'
23
+ | 'morphtarget_pars_vertex'
24
+ | 'morphtarget_vertex'
25
+ | 'normal_pars_vertex'
26
+ | 'normal_vertex'
27
+ | 'project_vertex'
28
+ | 'shadowmap_pars_vertex'
29
+ | 'shadowmap_vertex'
30
+ | 'skinbase_vertex'
31
+ | 'skinning_pars_vertex'
32
+ | 'skinning_vertex'
33
+ | 'skinnormal_vertex'
34
+ | 'uv_pars_vertex'
35
+ | 'uv_vertex'
36
+ | 'worldpos_vertex'
37
+
38
+ export type En3FragmentChunk =
39
+ | 'alphahash_fragment'
40
+ | 'alphahash_pars_fragment'
41
+ | 'alphamap_fragment'
42
+ | 'alphamap_pars_fragment'
43
+ | 'alphatest_fragment'
44
+ | 'alphatest_pars_fragment'
45
+ | 'aomap_fragment'
46
+ | 'aomap_pars_fragment'
47
+ | 'bumpmap_pars_fragment'
48
+ | 'clearcoat_normal_fragment_begin'
49
+ | 'clearcoat_normal_fragment_maps'
50
+ | 'clearcoat_pars_fragment'
51
+ | 'clipping_planes_fragment'
52
+ | 'clipping_planes_pars_fragment'
53
+ | 'color_fragment'
54
+ | 'color_pars_fragment'
55
+ | 'colorspace_fragment'
56
+ | 'colorspace_pars_fragment'
57
+ | 'cube_uv_reflection_fragment'
58
+ | 'default_fragment'
59
+ | 'dithering_fragment'
60
+ | 'dithering_pars_fragment'
61
+ | 'emissivemap_fragment'
62
+ | 'emissivemap_pars_fragment'
63
+ | 'envmap_common_pars_fragment'
64
+ | 'envmap_fragment'
65
+ | 'envmap_pars_fragment'
66
+ | 'envmap_physical_pars_fragment'
67
+ | 'fog_fragment'
68
+ | 'fog_pars_fragment'
69
+ | 'gradientmap_pars_fragment'
70
+ | 'iridescence_fragment'
71
+ | 'iridescence_pars_fragment'
72
+ | 'lightmap_fragment'
73
+ | 'lightmap_pars_fragment'
74
+ | 'lights_fragment_begin'
75
+ | 'lights_fragment_end'
76
+ | 'lights_fragment_maps'
77
+ | 'lights_lambert_fragment'
78
+ | 'lights_lambert_pars_fragment'
79
+ | 'lights_phong_fragment'
80
+ | 'lights_phong_pars_fragment'
81
+ | 'lights_physical_fragment'
82
+ | 'lights_physical_pars_fragment'
83
+ | 'lights_toon_fragment'
84
+ | 'lights_toon_pars_fragment'
85
+ | 'logdepthbuf_fragment'
86
+ | 'logdepthbuf_pars_fragment'
87
+ | 'map_fragment'
88
+ | 'map_pars_fragment'
89
+ | 'map_particle_fragment'
90
+ | 'map_particle_pars_fragment'
91
+ | 'metalnessmap_fragment'
92
+ | 'metalnessmap_pars_fragment'
93
+ | 'normal_fragment_begin'
94
+ | 'normal_fragment_maps'
95
+ | 'normal_pars_fragment'
96
+ | 'normalmap_pars_fragment'
97
+ | 'opaque_fragment'
98
+ | 'premultiplied_alpha_fragment'
99
+ | 'roughnessmap_fragment'
100
+ | 'roughnessmap_pars_fragment'
101
+ | 'shadowmap_pars_fragment'
102
+ | 'shadowmask_pars_fragment'
103
+ | 'specularmap_fragment'
104
+ | 'specularmap_pars_fragment'
105
+ | 'tonemapping_fragment'
106
+ | 'tonemapping_pars_fragment'
107
+ | 'transmission_fragment'
108
+ | 'transmission_pars_fragment'
109
+ | 'uv_pars_fragment'
110
+
111
+ export type En3ModifiedMaterialUniforms = { [key: string]: { value: any } }
112
+
113
+ export interface En3ModifiedMaterialParameters<
114
+ TMaterial extends Material,
115
+ Uniforms extends En3ModifiedMaterialUniforms = {}
116
+ > {
117
+ material: TMaterial
118
+ uniforms?: Uniforms
119
+ vertextDeclarations?: string
120
+ fragmentDeclarations?: string
121
+ vertexChunk?: {
122
+ update?: En3VertexChunk
123
+ replace?: En3VertexChunk
124
+ content: string
125
+ }
126
+ fragmentChunk?: {
127
+ update?: En3FragmentChunk
128
+ replace?: En3FragmentChunk
129
+ content: string
130
+ }
131
+ log?: boolean
132
+ onReady?: (modifiedMaterial: En3ModifiedMaterial<TMaterial, Uniforms>) => Function | void
133
+ }
134
+
135
+ export class En3ModifiedMaterial<
136
+ TMaterial extends Material,
137
+ Uniforms extends En3ModifiedMaterialUniforms = {}
138
+ > {
139
+ #material: TMaterial
140
+ #uniforms: Uniforms
141
+
142
+ constructor(parameters: En3ModifiedMaterialParameters<TMaterial, Uniforms>) {
143
+ this.#material = parameters.material
144
+ this.#uniforms = (parameters.uniforms || {}) as Uniforms
145
+ this.#material.userData.uniforms = this.#uniforms
146
+
147
+ let destroy: Function | void
148
+
149
+ const dispose = () => {
150
+ destroy?.()
151
+ }
152
+
153
+ this.#material.addEventListener('dispose', dispose)
154
+
155
+ this.#material.onBeforeCompile = (shader) => {
156
+ destroy?.()
157
+
158
+ for (const key in this.#uniforms) {
159
+ shader.uniforms[key] = this.#uniforms[key]
160
+ }
161
+
162
+ if (parameters.vertextDeclarations) {
163
+ shader.vertexShader = `
164
+ ${parameters.vertextDeclarations}
165
+ ${shader.vertexShader}
166
+ `
167
+ }
168
+
169
+ if (parameters.fragmentDeclarations) {
170
+ shader.fragmentShader = `
171
+ ${parameters.fragmentDeclarations}
172
+ ${shader.fragmentShader}
173
+ `
174
+ }
175
+
176
+ this.#chunk(shader, 'vertex', parameters)
177
+ this.#chunk(shader, 'fragment', parameters)
178
+
179
+ destroy = parameters.onReady?.(this)
180
+
181
+ if (parameters.log) {
182
+ console.log('VERTEX SHADER: ', shader.vertexShader)
183
+ console.log('FRAGMENT SHADER: ', shader.fragmentShader)
184
+ }
185
+ }
186
+ }
187
+
188
+ public get material() {
189
+ return this.#material
190
+ }
191
+
192
+ public get uniforms() {
193
+ return this.#uniforms
194
+ }
195
+
196
+ #chunk(
197
+ shader: WebGLProgramParametersWithUniforms,
198
+ type: 'vertex' | 'fragment',
199
+ parameters: En3ModifiedMaterialParameters<TMaterial, Uniforms>
200
+ ) {
201
+ const chunkName = type === 'vertex' ? 'vertexChunk' : 'fragmentChunk'
202
+ const shaderName = type === 'vertex' ? 'vertexShader' : 'fragmentShader'
203
+
204
+ if (parameters[chunkName]) {
205
+ if (parameters[chunkName]!.replace) {
206
+ shader[shaderName] = shader[shaderName].replace(
207
+ `#include <${parameters[chunkName]!.replace}>`,
208
+ parameters[chunkName]!.content
209
+ )
210
+ } else if (parameters[chunkName]!.update) {
211
+ shader[shaderName] = shader[shaderName].replace(
212
+ `#include <${parameters[chunkName]!.update}>`,
213
+ `
214
+ #include <${parameters[chunkName]!.update}>
215
+ ${parameters[chunkName]!.content}
216
+ `
217
+ )
218
+ }
219
+ }
220
+ }
221
+ }