kmcom-nuxt-layers 1.6.4 → 1.6.7

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 (167) hide show
  1. package/layers/core/app/.DS_Store +0 -0
  2. package/layers/core/app/assets/.DS_Store +0 -0
  3. package/layers/core/app/assets/css/main.css +2 -0
  4. package/layers/core/app/components/ErrorBoundary.vue +1 -1
  5. package/layers/core/nuxt.config.ts +0 -8
  6. package/layers/motion/app/plugins/locomotive-scroll.client.ts +14 -11
  7. package/layers/motion/app.config.ts +6 -0
  8. package/layers/shader/app/components/Pipeline/ACESTonemap.client.vue +14 -0
  9. package/layers/shader/app/components/Pipeline/AddBlend.client.vue +24 -0
  10. package/layers/shader/app/components/Pipeline/AgedFilm.client.vue +62 -0
  11. package/layers/shader/app/components/Pipeline/Aurora.client.vue +81 -0
  12. package/layers/shader/app/components/Pipeline/BilinearGradient.client.vue +46 -0
  13. package/layers/shader/app/components/Pipeline/BillowNoise.client.vue +42 -0
  14. package/layers/shader/app/components/Pipeline/BrightnessContrast.client.vue +25 -0
  15. package/layers/shader/app/components/Pipeline/CellularNoise.client.vue +41 -0
  16. package/layers/shader/app/components/Pipeline/ChannelMixer.client.vue +44 -0
  17. package/layers/shader/app/components/Pipeline/ChebyshevNoiseField.client.vue +60 -0
  18. package/layers/shader/app/components/Pipeline/Checkerboard.client.vue +41 -0
  19. package/layers/shader/app/components/Pipeline/ChromaticAberration.client.vue +52 -0
  20. package/layers/shader/app/components/Pipeline/ChromaticScreenWaves.client.vue +49 -0
  21. package/layers/shader/app/components/Pipeline/Circle.client.vue +41 -0
  22. package/layers/shader/app/components/Pipeline/Clouds.client.vue +60 -0
  23. package/layers/shader/app/components/Pipeline/ColorBurnBlend.client.vue +24 -0
  24. package/layers/shader/app/components/Pipeline/ColorDodgeBlend.client.vue +24 -0
  25. package/layers/shader/app/components/Pipeline/ColourRamp.client.vue +57 -0
  26. package/layers/shader/app/components/Pipeline/ComplexPlaneField.client.vue +77 -0
  27. package/layers/shader/app/components/Pipeline/ConicGradient.client.vue +40 -0
  28. package/layers/shader/app/components/Pipeline/CosinePalette.client.vue +71 -0
  29. package/layers/shader/app/components/Pipeline/CoverageAlpha.client.vue +18 -0
  30. package/layers/shader/app/components/Pipeline/Cross.client.vue +51 -0
  31. package/layers/shader/app/components/Pipeline/CurlNoise.client.vue +48 -0
  32. package/layers/shader/app/components/Pipeline/DarkenBlend.client.vue +24 -0
  33. package/layers/shader/app/components/Pipeline/DayNightCycle.client.vue +48 -0
  34. package/layers/shader/app/components/Pipeline/Desaturate.client.vue +21 -0
  35. package/layers/shader/app/components/Pipeline/DiagonalGradient.client.vue +38 -0
  36. package/layers/shader/app/components/Pipeline/DiamondGradient.client.vue +40 -0
  37. package/layers/shader/app/components/Pipeline/DifferenceBlend.client.vue +24 -0
  38. package/layers/shader/app/components/Pipeline/DivideBlend.client.vue +26 -0
  39. package/layers/shader/app/components/Pipeline/DomainWarpedNoise.client.vue +48 -0
  40. package/layers/shader/app/components/Pipeline/Dots.client.vue +44 -0
  41. package/layers/shader/app/components/Pipeline/DuoTone.client.vue +34 -0
  42. package/layers/shader/app/components/Pipeline/ExclusionBlend.client.vue +24 -0
  43. package/layers/shader/app/components/Pipeline/ExponentialFog.client.vue +46 -0
  44. package/layers/shader/app/components/Pipeline/Exposure.client.vue +23 -0
  45. package/layers/shader/app/components/Pipeline/FBMNoise.client.vue +50 -0
  46. package/layers/shader/app/components/Pipeline/FilmBurn.client.vue +49 -0
  47. package/layers/shader/app/components/Pipeline/FilmGrain.client.vue +69 -0
  48. package/layers/shader/app/components/Pipeline/FisheyeRay.client.vue +35 -0
  49. package/layers/shader/app/components/Pipeline/Flame.client.vue +51 -0
  50. package/layers/shader/app/components/Pipeline/FocalGradient.client.vue +43 -0
  51. package/layers/shader/app/components/Pipeline/Gamma.client.vue +23 -0
  52. package/layers/shader/app/components/Pipeline/GodRays.client.vue +64 -0
  53. package/layers/shader/app/components/Pipeline/GradientNoise.client.vue +42 -0
  54. package/layers/shader/app/components/Pipeline/Grain.client.vue +81 -0
  55. package/layers/shader/app/components/Pipeline/Grid.client.vue +43 -0
  56. package/layers/shader/app/components/Pipeline/Halation.client.vue +43 -0
  57. package/layers/shader/app/components/Pipeline/Halftone.client.vue +33 -0
  58. package/layers/shader/app/components/Pipeline/HardLightBlend.client.vue +24 -0
  59. package/layers/shader/app/components/Pipeline/Haze.client.vue +50 -0
  60. package/layers/shader/app/components/Pipeline/Hexagon.client.vue +42 -0
  61. package/layers/shader/app/components/Pipeline/Hue.client.vue +21 -0
  62. package/layers/shader/app/components/Pipeline/Invert.client.vue +14 -0
  63. package/layers/shader/app/components/Pipeline/LensFlare.client.vue +67 -0
  64. package/layers/shader/app/components/Pipeline/LightenBlend.client.vue +24 -0
  65. package/layers/shader/app/components/Pipeline/LinearGradient.client.vue +36 -0
  66. package/layers/shader/app/components/Pipeline/LinearGradient4.client.vue +67 -0
  67. package/layers/shader/app/components/Pipeline/LinearToSRGB.client.vue +25 -0
  68. package/layers/shader/app/components/Pipeline/Marble.client.vue +69 -0
  69. package/layers/shader/app/components/Pipeline/MixBlend.client.vue +45 -0
  70. package/layers/shader/app/components/Pipeline/MonochromeTint.client.vue +31 -0
  71. package/layers/shader/app/components/Pipeline/MultiplyBlend.client.vue +24 -0
  72. package/layers/shader/app/components/Pipeline/NoisyGradient.client.vue +54 -0
  73. package/layers/shader/app/components/Pipeline/NoisyGradientBlend.client.vue +116 -0
  74. package/layers/shader/app/components/Pipeline/OverlayBlend.client.vue +24 -0
  75. package/layers/shader/app/components/Pipeline/PaperTexture.client.vue +41 -0
  76. package/layers/shader/app/components/Pipeline/Polygon.client.vue +47 -0
  77. package/layers/shader/app/components/Pipeline/Posterise.client.vue +23 -0
  78. package/layers/shader/app/components/Pipeline/RadialGradient.client.vue +39 -0
  79. package/layers/shader/app/components/Pipeline/RayAutoOrbit.client.vue +37 -0
  80. package/layers/shader/app/components/Pipeline/RayMouseOrbit.client.vue +49 -0
  81. package/layers/shader/app/components/Pipeline/RayRotateX.client.vue +25 -0
  82. package/layers/shader/app/components/Pipeline/RayRotateY.client.vue +25 -0
  83. package/layers/shader/app/components/Pipeline/RayRotateZ.client.vue +25 -0
  84. package/layers/shader/app/components/Pipeline/RayTiltBasis.client.vue +41 -0
  85. package/layers/shader/app/components/Pipeline/RaymarchTunnel.client.vue +101 -0
  86. package/layers/shader/app/components/Pipeline/Rectangle.client.vue +47 -0
  87. package/layers/shader/app/components/Pipeline/ReinhardTonemap.client.vue +18 -0
  88. package/layers/shader/app/components/Pipeline/RidgedNoise.client.vue +41 -0
  89. package/layers/shader/app/components/Pipeline/Ring.client.vue +44 -0
  90. package/layers/shader/app/components/Pipeline/RingField.client.vue +69 -0
  91. package/layers/shader/app/components/Pipeline/RisographGrain.client.vue +74 -0
  92. package/layers/shader/app/components/Pipeline/RotatedGradientBlend.client.vue +61 -0
  93. package/layers/shader/app/components/Pipeline/SDFColourMask.client.vue +33 -0
  94. package/layers/shader/app/components/Pipeline/SDFRadialMask.client.vue +31 -0
  95. package/layers/shader/app/components/Pipeline/SRGBToLinear.client.vue +25 -0
  96. package/layers/shader/app/components/Pipeline/Saturation.client.vue +21 -0
  97. package/layers/shader/app/components/Pipeline/Scanlines.client.vue +36 -0
  98. package/layers/shader/app/components/Pipeline/ScreenBlend.client.vue +24 -0
  99. package/layers/shader/app/components/Pipeline/ShaderDebugger.client.vue +74 -0
  100. package/layers/shader/app/components/Pipeline/SimplexNoise.client.vue +49 -0
  101. package/layers/shader/app/components/Pipeline/SkyAtmosphere.client.vue +75 -0
  102. package/layers/shader/app/components/Pipeline/SoftLightBlend.client.vue +24 -0
  103. package/layers/shader/app/components/Pipeline/SolidColour.client.vue +21 -0
  104. package/layers/shader/app/components/Pipeline/SplitTone.client.vue +47 -0
  105. package/layers/shader/app/components/Pipeline/Star.client.vue +47 -0
  106. package/layers/shader/app/components/Pipeline/Starfield.client.vue +65 -0
  107. package/layers/shader/app/components/Pipeline/Stripes.client.vue +46 -0
  108. package/layers/shader/app/components/Pipeline/SubtractBlend.client.vue +24 -0
  109. package/layers/shader/app/components/Pipeline/TanhTonemap.client.vue +24 -0
  110. package/layers/shader/app/components/Pipeline/Threshold.client.vue +25 -0
  111. package/layers/shader/app/components/Pipeline/Tint.client.vue +33 -0
  112. package/layers/shader/app/components/Pipeline/Triangle.client.vue +42 -0
  113. package/layers/shader/app/components/Pipeline/UVAspectCorrect.client.vue +14 -0
  114. package/layers/shader/app/components/Pipeline/UVBreath.client.vue +36 -0
  115. package/layers/shader/app/components/Pipeline/UVBulge.client.vue +26 -0
  116. package/layers/shader/app/components/Pipeline/UVClamp.client.vue +18 -0
  117. package/layers/shader/app/components/Pipeline/UVColumnOffset.client.vue +28 -0
  118. package/layers/shader/app/components/Pipeline/UVFlipX.client.vue +14 -0
  119. package/layers/shader/app/components/Pipeline/UVFlipXY.client.vue +14 -0
  120. package/layers/shader/app/components/Pipeline/UVFlipY.client.vue +14 -0
  121. package/layers/shader/app/components/Pipeline/UVFractBand.client.vue +31 -0
  122. package/layers/shader/app/components/Pipeline/UVMousePull.client.vue +39 -0
  123. package/layers/shader/app/components/Pipeline/UVNoiseRotate.client.vue +54 -0
  124. package/layers/shader/app/components/Pipeline/UVNoiseWarp.client.vue +35 -0
  125. package/layers/shader/app/components/Pipeline/UVOrbit.client.vue +34 -0
  126. package/layers/shader/app/components/Pipeline/UVParallax.client.vue +39 -0
  127. package/layers/shader/app/components/Pipeline/UVPixelate.client.vue +21 -0
  128. package/layers/shader/app/components/Pipeline/UVPulse.client.vue +33 -0
  129. package/layers/shader/app/components/Pipeline/UVRipple.client.vue +34 -0
  130. package/layers/shader/app/components/Pipeline/UVRotate.client.vue +37 -0
  131. package/layers/shader/app/components/Pipeline/UVScale.client.vue +30 -0
  132. package/layers/shader/app/components/Pipeline/UVScroll.client.vue +27 -0
  133. package/layers/shader/app/components/Pipeline/UVScrollX.client.vue +21 -0
  134. package/layers/shader/app/components/Pipeline/UVScrollY.client.vue +21 -0
  135. package/layers/shader/app/components/Pipeline/UVShear.client.vue +25 -0
  136. package/layers/shader/app/components/Pipeline/UVSineWarpXY.client.vue +46 -0
  137. package/layers/shader/app/components/Pipeline/UVSwapAxes.client.vue +14 -0
  138. package/layers/shader/app/components/Pipeline/UVTile.client.vue +27 -0
  139. package/layers/shader/app/components/Pipeline/UVTwirl.client.vue +26 -0
  140. package/layers/shader/app/components/Pipeline/UVWarp.client.vue +30 -0
  141. package/layers/shader/app/components/Pipeline/VHSBleed.client.vue +58 -0
  142. package/layers/shader/app/components/Pipeline/ValueNoise.client.vue +41 -0
  143. package/layers/shader/app/components/Pipeline/Vibrance.client.vue +24 -0
  144. package/layers/shader/app/components/Pipeline/Vignette.client.vue +32 -0
  145. package/layers/shader/app/components/Pipeline/VoronoiEdges.client.vue +50 -0
  146. package/layers/shader/app/components/Pipeline/Water.client.vue +53 -0
  147. package/layers/shader/app/components/Pipeline/WaveBendLayer.client.vue +61 -0
  148. package/layers/shader/app/components/Pipeline/WaveColourLayer.client.vue +56 -0
  149. package/layers/shader/app/components/Pipeline/WhiteBalance.client.vue +40 -0
  150. package/layers/shader/app/components/Pipeline/Wood.client.vue +63 -0
  151. package/layers/shader/app/components/Shader/Canvas.vue +24 -0
  152. package/layers/shader/app/components/Shader/Pipeline.client.vue +56 -0
  153. package/layers/shader/app/components/Shader/PipelineContext.vue +18 -0
  154. package/layers/shader/app/composables/useCSSColourUniform.ts +41 -0
  155. package/layers/shader/app/composables/useCSSFloatUniform.ts +34 -0
  156. package/layers/shader/app/composables/useShaderPerf.ts +73 -0
  157. package/layers/shader/app/composables/useShaderPipeline.ts +99 -0
  158. package/layers/shader/app/composables/useSunDirectionUniform.ts +54 -0
  159. package/layers/shader/app/composables/useTSLNodes.ts +0 -1
  160. package/layers/shader/app/shaders/common/complex.ts +29 -0
  161. package/layers/shader/app/shaders/common/shapes.ts +4 -4
  162. package/layers/shader/app/shaders/common/uv.ts +2 -2
  163. package/layers/shader/app/utils/tsl/patterns.ts +1 -1
  164. package/layers/shader/app/utils/tsl/uv.ts +3 -3
  165. package/layers/ui/app/app.config.ts +2 -16
  166. package/layers/ui/app/types/app-config.d.ts +17 -0
  167. package/package.json +9 -7
@@ -0,0 +1,25 @@
1
+ <script setup lang="ts">
2
+ // @ts-nocheck
3
+ import { uniform, vec4, pow, float } from 'three/tsl'
4
+
5
+ /**
6
+ * Gamma-encodes linear light to sRGB for display.
7
+ * Use as the last step in HDR pipelines before output.
8
+ * Approximate form: pow(col, 1/2.2).
9
+ */
10
+ const props = withDefaults(defineProps<{
11
+ /** Gamma exponent — 2.2 matches sRGB standard */
12
+ gamma?: number
13
+ order?: number
14
+ }>(), { gamma: 2.2, order: 0 })
15
+
16
+ const gammaNode = uniform(props.gamma)
17
+ watch(() => props.gamma, v => { gammaNode.value = v })
18
+
19
+ useShaderStage(
20
+ (prev) => vec4(pow(prev.xyz.max(float(0)), float(1).div(gammaNode)), prev.w),
21
+ props.order,
22
+ )
23
+ </script>
24
+
25
+ <template><!-- --></template>
@@ -0,0 +1,69 @@
1
+ <script setup lang="ts">
2
+ // @ts-nocheck
3
+ import { Color, Vector3 } from 'three'
4
+ import { uniform, time, vec4, mix, sin, float } from 'three/tsl'
5
+ import { fbm2D } from '../../shaders/common/noise'
6
+
7
+ const props = withDefaults(defineProps<{
8
+ /** Base (vein background) colour */
9
+ colorA?: string
10
+ /** Vein colour */
11
+ colorB?: string
12
+ /** Marble vein frequency */
13
+ frequency?: number
14
+ /** FBM noise scale for vein turbulence */
15
+ noiseScale?: number
16
+ /** Noise strength applied to sine input */
17
+ noiseStrength?: number
18
+ /** Vein sharpness — higher = thinner veins */
19
+ sharpness?: number
20
+ /** Animation speed */
21
+ speed?: number
22
+ order?: number
23
+ }>(), {
24
+ colorA: '#f5f0e8',
25
+ colorB: '#6a5a4a',
26
+ frequency: 5,
27
+ noiseScale: 3,
28
+ noiseStrength: 8,
29
+ sharpness: 4,
30
+ speed: 0,
31
+ order: 0,
32
+ })
33
+
34
+ function toVec3Node(hex: string) {
35
+ const c = new Color(hex)
36
+ return uniform(new Vector3(c.r, c.g, c.b))
37
+ }
38
+
39
+ const colorANode = toVec3Node(props.colorA)
40
+ const colorBNode = toVec3Node(props.colorB)
41
+ const freqNode = uniform(props.frequency)
42
+ const noiseScaleNode = uniform(props.noiseScale)
43
+ const noiseStrNode = uniform(props.noiseStrength)
44
+ const sharpNode = uniform(props.sharpness)
45
+ const speedNode = uniform(props.speed)
46
+ watch(() => props.colorA, v => { const c = new Color(v); colorANode.value.set(c.r, c.g, c.b) })
47
+ watch(() => props.colorB, v => { const c = new Color(v); colorBNode.value.set(c.r, c.g, c.b) })
48
+ watch(() => props.frequency, v => { freqNode.value = v })
49
+ watch(() => props.noiseScale, v => { noiseScaleNode.value = v })
50
+ watch(() => props.noiseStrength, v => { noiseStrNode.value = v })
51
+ watch(() => props.sharpness, v => { sharpNode.value = v })
52
+ watch(() => props.speed, v => { speedNode.value = v })
53
+
54
+ const pipeline = useShaderPipelineContext()
55
+
56
+ useShaderStage(
57
+ () => {
58
+ const uv = pipeline.uvNode.value
59
+ const t = time.mul(speedNode)
60
+ const n = fbm2D(uv.mul(noiseScaleNode).add(t))
61
+ // Sine + noise offset creates the vein pattern
62
+ const vein = sin(uv.x.mul(freqNode).add(n.mul(noiseStrNode))).abs().pow(sharpNode)
63
+ return vec4(mix(colorANode, colorBNode, vein), float(1))
64
+ },
65
+ props.order,
66
+ )
67
+ </script>
68
+
69
+ <template><!-- --></template>
@@ -0,0 +1,45 @@
1
+ <script setup lang="ts">
2
+ // @ts-nocheck
3
+ import { smoothstep, uniform, vec4 } from 'three/tsl'
4
+
5
+ /**
6
+ * Fades the accumulated pipeline colour toward transparent/black based on
7
+ * a UV axis threshold. Useful as a final Y/X-axis gradient mask.
8
+ *
9
+ * Example (Grainient final step):
10
+ * <MixBlend axis="y" :edge0="0.45" :edge1="0.55" />
11
+ */
12
+ const props = withDefaults(defineProps<{
13
+ axis?: 'x' | 'y'
14
+ edge0?: number
15
+ edge1?: number
16
+ /** 0 = fade to transparent, 1 = fade to opaque (keep prev) */
17
+ invert?: boolean
18
+ order?: number
19
+ }>(), {
20
+ axis: 'y',
21
+ edge0: 0.45,
22
+ edge1: 0.55,
23
+ invert: false,
24
+ order: 0,
25
+ })
26
+
27
+ const edge0Node = uniform(props.edge0)
28
+ const edge1Node = uniform(props.edge1)
29
+ watch(() => props.edge0, v => { edge0Node.value = v })
30
+ watch(() => props.edge1, v => { edge1Node.value = v })
31
+
32
+ const { uvNode } = useShaderPipelineContext()
33
+
34
+ useShaderStage(
35
+ (prev) => {
36
+ const coord = props.axis === 'x' ? uvNode.value.x : uvNode.value.y
37
+ const mask = smoothstep(edge0Node, edge1Node, coord)
38
+ const alpha = props.invert ? mask.oneMinus() : mask
39
+ return vec4(prev.xyz, prev.w.mul(alpha))
40
+ },
41
+ props.order,
42
+ )
43
+ </script>
44
+
45
+ <template><!-- --></template>
@@ -0,0 +1,31 @@
1
+ <script setup lang="ts">
2
+ // @ts-nocheck
3
+ import { Color, Vector3 } from 'three'
4
+ import { uniform, vec4 } from 'three/tsl'
5
+ import { desaturate } from '../../shaders/common/blend'
6
+
7
+ const props = withDefaults(defineProps<{
8
+ /** Tint colour applied after desaturation */
9
+ color?: string
10
+ /** How much to desaturate before tinting: 1 = full greyscale */
11
+ desaturation?: number
12
+ order?: number
13
+ }>(), { color: '#4466aa', desaturation: 1, order: 0 })
14
+
15
+ function toVec3Node(hex: string) {
16
+ const c = new Color(hex)
17
+ return uniform(new Vector3(c.r, c.g, c.b))
18
+ }
19
+
20
+ const colorNode = toVec3Node(props.color)
21
+ const desatNode = uniform(props.desaturation)
22
+ watch(() => props.color, v => { const c = new Color(v); colorNode.value.set(c.r, c.g, c.b) })
23
+ watch(() => props.desaturation, v => { desatNode.value = v })
24
+
25
+ useShaderStage(
26
+ (prev) => vec4(desaturate(prev.xyz, desatNode).mul(colorNode), prev.w),
27
+ props.order,
28
+ )
29
+ </script>
30
+
31
+ <template><!-- --></template>
@@ -0,0 +1,24 @@
1
+ <script setup lang="ts">
2
+ // @ts-nocheck
3
+ import { Color } from 'three'
4
+ import { mix, uniform, vec4 } from 'three/tsl'
5
+ import { blendMultiply } from '../../shaders/common/blend'
6
+
7
+ const props = withDefaults(defineProps<{
8
+ color?: string
9
+ opacity?: number
10
+ order?: number
11
+ }>(), { color: '#808080', opacity: 1, order: 0 })
12
+
13
+ const colorNode = uniform(new Color(props.color))
14
+ const opacityNode = uniform(props.opacity)
15
+ watch(() => props.color, v => { colorNode.value.set(v) })
16
+ watch(() => props.opacity, v => { opacityNode.value = v })
17
+
18
+ useShaderStage(
19
+ (prev) => vec4(mix(prev.xyz, blendMultiply(prev.xyz, colorNode), opacityNode), prev.w),
20
+ props.order,
21
+ )
22
+ </script>
23
+
24
+ <template><!-- --></template>
@@ -0,0 +1,54 @@
1
+ <script setup lang="ts">
2
+ // @ts-nocheck
3
+ import { Color, Vector3 } from 'three'
4
+ import { uniform, time, vec4, mix, float } from 'three/tsl'
5
+ import { fbm2D } from '../../shaders/common/noise'
6
+
7
+ /** Linear gradient with per-pixel FBM noise offset — living, organic gradient. */
8
+ const props = withDefaults(defineProps<{
9
+ colorA?: string
10
+ colorB?: string
11
+ /** Gradient axis angle in degrees */
12
+ angle?: number
13
+ /** Noise displacement strength */
14
+ noiseStrength?: number
15
+ /** Noise input scale */
16
+ noiseScale?: number
17
+ /** Animation speed */
18
+ speed?: number
19
+ order?: number
20
+ }>(), { colorA: '#1a0a5a', colorB: '#ff8866', angle: 0, noiseStrength: 0.3, noiseScale: 2, speed: 0.15, order: 0 })
21
+
22
+ function toVec3Node(hex: string) {
23
+ const c = new Color(hex)
24
+ return uniform(new Vector3(c.r, c.g, c.b))
25
+ }
26
+
27
+ const colorANode = toVec3Node(props.colorA)
28
+ const colorBNode = toVec3Node(props.colorB)
29
+ const angleNode = uniform(props.angle * Math.PI / 180)
30
+ const noiseStrNode = uniform(props.noiseStrength)
31
+ const noiseScaleNode = uniform(props.noiseScale)
32
+ const speedNode = uniform(props.speed)
33
+ watch(() => props.colorA, v => { const c = new Color(v); colorANode.value.set(c.r, c.g, c.b) })
34
+ watch(() => props.colorB, v => { const c = new Color(v); colorBNode.value.set(c.r, c.g, c.b) })
35
+ watch(() => props.angle, v => { angleNode.value = v * Math.PI / 180 })
36
+ watch(() => props.noiseStrength, v => { noiseStrNode.value = v })
37
+ watch(() => props.noiseScale, v => { noiseScaleNode.value = v })
38
+ watch(() => props.speed, v => { speedNode.value = v })
39
+
40
+ const pipeline = useShaderPipelineContext()
41
+
42
+ useShaderStage(
43
+ () => {
44
+ const uv = pipeline.uvNode.value
45
+ const n = fbm2D(uv.mul(noiseScaleNode).add(time.mul(speedNode)))
46
+ const base = uv.x.mul(angleNode.cos()).add(uv.y.mul(angleNode.sin()))
47
+ const t = base.add(n.mul(noiseStrNode)).clamp(float(0), float(1))
48
+ return vec4(mix(colorANode, colorBNode, t), float(1))
49
+ },
50
+ props.order,
51
+ )
52
+ </script>
53
+
54
+ <template><!-- --></template>
@@ -0,0 +1,116 @@
1
+ <script setup lang="ts">
2
+ // @ts-nocheck
3
+ import { Color, Vector3 } from 'three'
4
+ import { uniform, time, vec2, vec4, mix, smoothstep, cos, sin, float } from 'three/tsl'
5
+ import { simplexNoise2D } from '../../shaders/common/noise'
6
+
7
+ /**
8
+ * Self-contained Grainient/Shadertoy gradient pattern.
9
+ * Combines: GradientNoise → noise-driven UV rotation → asymmetric sine warp
10
+ * → rotated two-colour blend.
11
+ * Equivalent to: UVNoiseRotate + UVSineWarpXY + RotatedGradientBlend in one component.
12
+ * Exposes all params individually so the pipeline can still intercept at any stage,
13
+ * but provides a convenient self-contained starting point.
14
+ */
15
+ const props = withDefaults(defineProps<{
16
+ colorA?: string
17
+ colorB?: string
18
+ /** Noise input scale */
19
+ noiseScale?: number
20
+ /** Max rotation amount driven by noise (degrees) */
21
+ rotationAmount?: number
22
+ /** Sine warp frequency */
23
+ warpFrequency?: number
24
+ /** Sine warp amplitude (higher = subtler) */
25
+ warpAmplitude?: number
26
+ /** Gradient blend angle (degrees) */
27
+ blendAngle?: number
28
+ /** Smoothstep lower edge */
29
+ edge0?: number
30
+ /** Smoothstep upper edge */
31
+ edge1?: number
32
+ /** Animation speed */
33
+ speed?: number
34
+ order?: number
35
+ }>(), {
36
+ colorA: '#1a0a5a',
37
+ colorB: '#ff6688',
38
+ noiseScale: 1,
39
+ rotationAmount: 720,
40
+ warpFrequency: 3,
41
+ warpAmplitude: 3,
42
+ blendAngle: 45,
43
+ edge0: 0.2,
44
+ edge1: 0.8,
45
+ speed: 0.3,
46
+ order: 0,
47
+ })
48
+
49
+ const DEG2RAD = Math.PI / 180
50
+
51
+ function toVec3Node(hex: string) {
52
+ const c = new Color(hex)
53
+ return uniform(new Vector3(c.r, c.g, c.b))
54
+ }
55
+
56
+ const colorANode = toVec3Node(props.colorA)
57
+ const colorBNode = toVec3Node(props.colorB)
58
+ const noiseScaleNode = uniform(props.noiseScale)
59
+ const rotAmountNode = uniform(props.rotationAmount * DEG2RAD)
60
+ const warpFreqNode = uniform(props.warpFrequency)
61
+ const warpAmpNode = uniform(props.warpAmplitude)
62
+ const blendAngleNode = uniform(props.blendAngle * DEG2RAD)
63
+ const edge0Node = uniform(props.edge0)
64
+ const edge1Node = uniform(props.edge1)
65
+ const speedNode = uniform(props.speed)
66
+
67
+ watch(() => props.colorA, v => { const c = new Color(v); colorANode.value.set(c.r, c.g, c.b) })
68
+ watch(() => props.colorB, v => { const c = new Color(v); colorBNode.value.set(c.r, c.g, c.b) })
69
+ watch(() => props.noiseScale, v => { noiseScaleNode.value = v })
70
+ watch(() => props.rotationAmount, v => { rotAmountNode.value = v * DEG2RAD })
71
+ watch(() => props.warpFrequency, v => { warpFreqNode.value = v })
72
+ watch(() => props.warpAmplitude, v => { warpAmpNode.value = v })
73
+ watch(() => props.blendAngle, v => { blendAngleNode.value = v * DEG2RAD })
74
+ watch(() => props.edge0, v => { edge0Node.value = v })
75
+ watch(() => props.edge1, v => { edge1Node.value = v })
76
+ watch(() => props.speed, v => { speedNode.value = v })
77
+
78
+ const pipeline = useShaderPipelineContext()
79
+
80
+ useShaderStage(
81
+ () => {
82
+ const uvCurrent = pipeline.uvNode.value
83
+ if (!uvCurrent) return vec4(0, 0, 0, 1)
84
+
85
+ const t = time.mul(speedNode)
86
+
87
+ // 1. Noise-driven UV rotation
88
+ const n = simplexNoise2D(uvCurrent.mul(noiseScaleNode).add(t))
89
+ const angle = n.mul(0.5).add(0.5).mul(rotAmountNode).add(float(Math.PI)).sub(rotAmountNode.mul(0.5))
90
+ const c1 = cos(angle)
91
+ const s1 = sin(angle)
92
+ const centered = uvCurrent.sub(0.5)
93
+ const rotated = vec2(
94
+ centered.x.mul(c1).sub(centered.y.mul(s1)),
95
+ centered.x.mul(s1).add(centered.y.mul(c1)),
96
+ ).add(0.5)
97
+
98
+ // 2. Asymmetric sine warp — pure functional (no toVar/addAssign needed)
99
+ // warpedY uses warpedX to replicate the sequential addAssign behaviour
100
+ const warpedX = rotated.x.add(sin(rotated.y.mul(warpFreqNode).add(t)).div(warpAmpNode))
101
+ const warpedY = rotated.y.add(sin(warpedX.mul(warpFreqNode.mul(1.5)).add(t)).div(warpAmpNode.mul(0.5)))
102
+ const tuv = vec2(warpedX, warpedY)
103
+
104
+ // 3. Rotated gradient blend
105
+ const cb = cos(blendAngleNode)
106
+ const sb = sin(blendAngleNode)
107
+ const rotX = tuv.sub(0.5).x.mul(cb).sub(tuv.sub(0.5).y.mul(sb)).add(0.5)
108
+ const blend = smoothstep(edge0Node, edge1Node, rotX)
109
+
110
+ return vec4(mix(colorANode, colorBNode, blend), float(1))
111
+ },
112
+ props.order,
113
+ )
114
+ </script>
115
+
116
+ <template><!-- --></template>
@@ -0,0 +1,24 @@
1
+ <script setup lang="ts">
2
+ // @ts-nocheck
3
+ import { Color } from 'three'
4
+ import { mix, uniform, vec4 } from 'three/tsl'
5
+ import { blendOverlay } from '../../shaders/common/blend'
6
+
7
+ const props = withDefaults(defineProps<{
8
+ color?: string
9
+ opacity?: number
10
+ order?: number
11
+ }>(), { color: '#808080', opacity: 1, order: 0 })
12
+
13
+ const colorNode = uniform(new Color(props.color))
14
+ const opacityNode = uniform(props.opacity)
15
+ watch(() => props.color, v => { colorNode.value.set(v) })
16
+ watch(() => props.opacity, v => { opacityNode.value = v })
17
+
18
+ useShaderStage(
19
+ (prev) => vec4(mix(prev.xyz, blendOverlay(prev.xyz, colorNode), opacityNode), prev.w),
20
+ props.order,
21
+ )
22
+ </script>
23
+
24
+ <template><!-- --></template>
@@ -0,0 +1,41 @@
1
+ <script setup lang="ts">
2
+ // @ts-nocheck
3
+ import { uniform, time, vec4, floor, float } from 'three/tsl'
4
+ import { paperTexture } from '../../shaders/common/grain'
5
+
6
+ /**
7
+ * Paper texture overlay — multi-octave grain that reads like coarse paper or canvas.
8
+ * Adds tactile analogue feel to any underlying image.
9
+ */
10
+ const props = withDefaults(defineProps<{
11
+ /** Texture scale — higher = finer grain pattern */
12
+ scale?: number
13
+ /** Overlay intensity */
14
+ intensity?: number
15
+ /** Animate slowly for a living-paper effect (0 = static) */
16
+ speed?: number
17
+ order?: number
18
+ }>(), { scale: 12, intensity: 0.08, speed: 0, order: 0 })
19
+
20
+ const scaleNode = uniform(props.scale)
21
+ const intensityNode = uniform(props.intensity)
22
+ const speedNode = uniform(props.speed)
23
+ watch(() => props.scale, v => { scaleNode.value = v })
24
+ watch(() => props.intensity, v => { intensityNode.value = v })
25
+ watch(() => props.speed, v => { speedNode.value = v })
26
+
27
+ const pipeline = useShaderPipelineContext()
28
+
29
+ useShaderStage(
30
+ (prev) => {
31
+ const uv = pipeline.uvNode.value
32
+ const seed = floor(time.mul(speedNode).mul(6))
33
+
34
+ const tex = paperTexture(uv, scaleNode, intensityNode, seed)
35
+ return vec4(prev.xyz.add(tex), prev.w)
36
+ },
37
+ props.order,
38
+ )
39
+ </script>
40
+
41
+ <template><!-- --></template>
@@ -0,0 +1,47 @@
1
+ <script setup lang="ts">
2
+ // @ts-nocheck
3
+ import { Color, Vector3 } from 'three'
4
+ import { uniform, vec4, mix, smoothstep, float } from 'three/tsl'
5
+ import { polygon } from '../../shaders/common/shapes'
6
+
7
+ const props = withDefaults(defineProps<{
8
+ colorA?: string
9
+ colorB?: string
10
+ /** Number of sides */
11
+ sides?: number
12
+ radius?: number
13
+ softness?: number
14
+ /** Rotation offset in degrees */
15
+ rotation?: number
16
+ order?: number
17
+ }>(), { colorA: '#000000', colorB: '#ffffff', sides: 6, radius: 0.35, softness: 0.01, rotation: 0, order: 0 })
18
+
19
+ function toVec3Node(hex: string) {
20
+ const c = new Color(hex)
21
+ return uniform(new Vector3(c.r, c.g, c.b))
22
+ }
23
+
24
+ const colorANode = toVec3Node(props.colorA)
25
+ const colorBNode = toVec3Node(props.colorB)
26
+ const radiusNode = uniform(props.radius)
27
+ const softnessNode = uniform(props.softness)
28
+ const rotationNode = uniform(props.rotation * Math.PI / 180)
29
+ watch(() => props.colorA, v => { const c = new Color(v); colorANode.value.set(c.r, c.g, c.b) })
30
+ watch(() => props.colorB, v => { const c = new Color(v); colorBNode.value.set(c.r, c.g, c.b) })
31
+ watch(() => props.radius, v => { radiusNode.value = v })
32
+ watch(() => props.softness, v => { softnessNode.value = v })
33
+ watch(() => props.rotation, v => { rotationNode.value = v * Math.PI / 180 })
34
+
35
+ const pipeline = useShaderPipelineContext()
36
+
37
+ useShaderStage(
38
+ () => {
39
+ const uv = pipeline.uvNode.value
40
+ const mask = polygon(uv, [0.5, 0.5], radiusNode, props.sides, softnessNode)
41
+ return vec4(mix(colorANode, colorBNode, mask), float(1))
42
+ },
43
+ props.order,
44
+ )
45
+ </script>
46
+
47
+ <template><!-- --></template>
@@ -0,0 +1,23 @@
1
+ <script setup lang="ts">
2
+ // @ts-nocheck
3
+ import { uniform, vec4, floor, float } from 'three/tsl'
4
+
5
+ const props = withDefaults(defineProps<{
6
+ /** Number of colour steps per channel */
7
+ steps?: number
8
+ order?: number
9
+ }>(), { steps: 6, order: 0 })
10
+
11
+ const stepsNode = uniform(props.steps)
12
+ watch(() => props.steps, v => { stepsNode.value = v })
13
+
14
+ useShaderStage(
15
+ (prev) => {
16
+ const posterised = floor(prev.xyz.mul(stepsNode)).div(stepsNode.sub(float(1)))
17
+ return vec4(posterised, prev.w)
18
+ },
19
+ props.order,
20
+ )
21
+ </script>
22
+
23
+ <template><!-- --></template>
@@ -0,0 +1,39 @@
1
+ <script setup lang="ts">
2
+ // @ts-nocheck
3
+ import { Color } from 'three'
4
+ import { clamp, mix, uniform, vec4 } from 'three/tsl'
5
+
6
+ const props = withDefaults(defineProps<{
7
+ colorCenter?: string
8
+ colorEdge?: string
9
+ radius?: number
10
+ order?: number
11
+ }>(), {
12
+ colorCenter: '#ffffff',
13
+ colorEdge: '#000000',
14
+ radius: 0.7,
15
+ order: 0,
16
+ })
17
+
18
+ const colorCenterVal = new Color(props.colorCenter)
19
+ const colorEdgeVal = new Color(props.colorEdge)
20
+ const colorCenterNode = uniform(colorCenterVal)
21
+ const colorEdgeNode = uniform(colorEdgeVal)
22
+ const radiusNode = uniform(props.radius)
23
+
24
+ watch(() => props.colorCenter, v => { colorCenterNode.value.set(v) })
25
+ watch(() => props.colorEdge, v => { colorEdgeNode.value.set(v) })
26
+ watch(() => props.radius, v => { radiusNode.value = v })
27
+
28
+ const { uvNode } = useShaderPipelineContext()
29
+
30
+ useShaderStage(
31
+ (_prev) => {
32
+ const t = clamp(uvNode.value.sub(0.5).length().div(radiusNode), 0, 1)
33
+ return vec4(mix(colorCenterNode, colorEdgeNode, t), 1.0)
34
+ },
35
+ props.order,
36
+ )
37
+ </script>
38
+
39
+ <template><!-- --></template>
@@ -0,0 +1,37 @@
1
+ <script setup lang="ts">
2
+ // @ts-nocheck
3
+ import { uniform, time, cos, sin, vec3 } from 'three/tsl'
4
+
5
+ const props = withDefaults(defineProps<{
6
+ /** Orbit speed in radians per second (Y axis) */
7
+ speed?: number
8
+ /** Additional fixed pitch in radians (X axis) */
9
+ pitch?: number
10
+ order?: number
11
+ }>(), { speed: 0.5, pitch: 0, order: 0 })
12
+
13
+ const speedNode = uniform(props.speed)
14
+ const pitchNode = uniform(props.pitch)
15
+ watch(() => props.speed, v => { speedNode.value = v })
16
+ watch(() => props.pitch, v => { pitchNode.value = v })
17
+
18
+ useShaderStage(
19
+ (ray) => {
20
+ const yaw = time.mul(speedNode)
21
+
22
+ // Y-axis rotation (orbit)
23
+ const cy = cos(yaw)
24
+ const sy = sin(yaw)
25
+ const rayY = vec3(ray.x.mul(cy).add(ray.z.mul(sy)), ray.y, ray.z.mul(cy).sub(ray.x.mul(sy)))
26
+
27
+ // X-axis pitch
28
+ const cp = cos(pitchNode)
29
+ const sp = sin(pitchNode)
30
+ return vec3(rayY.x, rayY.y.mul(cp).sub(rayY.z.mul(sp)), rayY.y.mul(sp).add(rayY.z.mul(cp)))
31
+ },
32
+ props.order,
33
+ 'ray',
34
+ )
35
+ </script>
36
+
37
+ <template><!-- --></template>
@@ -0,0 +1,49 @@
1
+ <script setup lang="ts">
2
+ // @ts-nocheck
3
+ import { Vector2 } from 'three'
4
+ import { uniform, cos, sin, vec3 } from 'three/tsl'
5
+
6
+ const props = withDefaults(defineProps<{
7
+ /** Multiplier for horizontal mouse sweep → yaw range (radians) */
8
+ yawRange?: number
9
+ /** Multiplier for vertical mouse sweep → pitch range (radians) */
10
+ pitchRange?: number
11
+ order?: number
12
+ }>(), { yawRange: Math.PI, pitchRange: Math.PI / 3, order: 0 })
13
+
14
+ const mouse = uniform(new Vector2(0.5, 0.5))
15
+
16
+ onMounted(() => {
17
+ const onMove = (e: MouseEvent) => {
18
+ mouse.value.set(e.clientX / window.innerWidth, 1 - e.clientY / window.innerHeight)
19
+ }
20
+ window.addEventListener('mousemove', onMove)
21
+ onUnmounted(() => window.removeEventListener('mousemove', onMove))
22
+ })
23
+
24
+ const yawRangeNode = uniform(props.yawRange)
25
+ const pitchRangeNode = uniform(props.pitchRange)
26
+ watch(() => props.yawRange, v => { yawRangeNode.value = v })
27
+ watch(() => props.pitchRange, v => { pitchRangeNode.value = v })
28
+
29
+ useShaderStage(
30
+ (ray) => {
31
+ const yaw = mouse.x.sub(0.5).mul(yawRangeNode)
32
+ const pitch = mouse.y.sub(0.5).mul(pitchRangeNode)
33
+
34
+ // Yaw (Y-axis)
35
+ const cy = cos(yaw)
36
+ const sy = sin(yaw)
37
+ const rayY = vec3(ray.x.mul(cy).add(ray.z.mul(sy)), ray.y, ray.z.mul(cy).sub(ray.x.mul(sy)))
38
+
39
+ // Pitch (X-axis)
40
+ const cp = cos(pitch)
41
+ const sp = sin(pitch)
42
+ return vec3(rayY.x, rayY.y.mul(cp).sub(rayY.z.mul(sp)), rayY.y.mul(sp).add(rayY.z.mul(cp)))
43
+ },
44
+ props.order,
45
+ 'ray',
46
+ )
47
+ </script>
48
+
49
+ <template><!-- --></template>
@@ -0,0 +1,25 @@
1
+ <script setup lang="ts">
2
+ // @ts-nocheck
3
+ import { uniform, cos, sin, vec3 } from 'three/tsl'
4
+
5
+ const props = withDefaults(defineProps<{
6
+ /** Rotation angle in radians */
7
+ angle?: number
8
+ order?: number
9
+ }>(), { angle: 0, order: 0 })
10
+
11
+ const angleNode = uniform(props.angle)
12
+ watch(() => props.angle, v => { angleNode.value = v })
13
+
14
+ useShaderStage(
15
+ (ray) => {
16
+ const c = cos(angleNode)
17
+ const s = sin(angleNode)
18
+ return vec3(ray.x, ray.y.mul(c).sub(ray.z.mul(s)), ray.y.mul(s).add(ray.z.mul(c)))
19
+ },
20
+ props.order,
21
+ 'ray',
22
+ )
23
+ </script>
24
+
25
+ <template><!-- --></template>