kmcom-nuxt-layers 1.6.4 → 1.6.6

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 (165) 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/package.json +9 -7
@@ -0,0 +1,41 @@
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
+
6
+ const props = withDefaults(defineProps<{
7
+ colorA?: string
8
+ colorB?: string
9
+ radius?: number
10
+ softness?: number
11
+ order?: number
12
+ }>(), { colorA: '#000000', colorB: '#ffffff', radius: 0.35, softness: 0.01, order: 0 })
13
+
14
+ function toVec3Node(hex: string) {
15
+ const c = new Color(hex)
16
+ return uniform(new Vector3(c.r, c.g, c.b))
17
+ }
18
+
19
+ const colorANode = toVec3Node(props.colorA)
20
+ const colorBNode = toVec3Node(props.colorB)
21
+ const radiusNode = uniform(props.radius)
22
+ const softnessNode = uniform(props.softness)
23
+ watch(() => props.colorA, v => { const c = new Color(v); colorANode.value.set(c.r, c.g, c.b) })
24
+ watch(() => props.colorB, v => { const c = new Color(v); colorBNode.value.set(c.r, c.g, c.b) })
25
+ watch(() => props.radius, v => { radiusNode.value = v })
26
+ watch(() => props.softness, v => { softnessNode.value = v })
27
+
28
+ const pipeline = useShaderPipelineContext()
29
+
30
+ useShaderStage(
31
+ () => {
32
+ const uv = pipeline.uvNode.value
33
+ const d = uv.sub(0.5).length()
34
+ const mask = smoothstep(radiusNode.add(softnessNode), radiusNode.sub(softnessNode), d)
35
+ return vec4(mix(colorANode, colorBNode, mask), float(1))
36
+ },
37
+ props.order,
38
+ )
39
+ </script>
40
+
41
+ <template><!-- --></template>
@@ -0,0 +1,60 @@
1
+ <script setup lang="ts">
2
+ // @ts-nocheck
3
+ import { Color, Vector3 } from 'three'
4
+ import { uniform, time, vec4, mix, smoothstep, float } from 'three/tsl'
5
+ import { fbm2D } from '../../shaders/common/noise'
6
+
7
+ const props = withDefaults(defineProps<{
8
+ /** Sky colour */
9
+ colorSky?: string
10
+ /** Cloud colour */
11
+ colorCloud?: string
12
+ /** FBM noise input scale */
13
+ scale?: number
14
+ /** Cloud coverage: lower = fewer clouds, higher = overcast */
15
+ coverage?: number
16
+ /** Cloud softness */
17
+ softness?: number
18
+ /** Wind speed */
19
+ speed?: number
20
+ order?: number
21
+ }>(), { colorSky: '#5588cc', colorCloud: '#ffffff', scale: 2, coverage: 0.5, softness: 0.15, speed: 0.05, order: 0 })
22
+
23
+ function toVec3Node(hex: string) {
24
+ const c = new Color(hex)
25
+ return uniform(new Vector3(c.r, c.g, c.b))
26
+ }
27
+
28
+ const colorSkyNode = toVec3Node(props.colorSky)
29
+ const colorCloudNode = toVec3Node(props.colorCloud)
30
+ const scaleNode = uniform(props.scale)
31
+ const coverageNode = uniform(props.coverage)
32
+ const softnessNode = uniform(props.softness)
33
+ const speedNode = uniform(props.speed)
34
+ watch(() => props.colorSky, v => { const c = new Color(v); colorSkyNode.value.set(c.r, c.g, c.b) })
35
+ watch(() => props.colorCloud, v => { const c = new Color(v); colorCloudNode.value.set(c.r, c.g, c.b) })
36
+ watch(() => props.scale, v => { scaleNode.value = v })
37
+ watch(() => props.coverage, v => { coverageNode.value = v })
38
+ watch(() => props.softness, v => { softnessNode.value = v })
39
+ watch(() => props.speed, v => { speedNode.value = v })
40
+
41
+ const pipeline = useShaderPipelineContext()
42
+
43
+ useShaderStage(
44
+ () => {
45
+ const uv = pipeline.uvNode.value
46
+ const wind = time.mul(speedNode)
47
+ const n = fbm2D(uv.mul(scaleNode).add(wind)).mul(0.5).add(0.5)
48
+ // Remap to cloud mask using coverage + softness
49
+ const cloud = smoothstep(
50
+ coverageNode.sub(softnessNode),
51
+ coverageNode.add(softnessNode),
52
+ n,
53
+ )
54
+ return vec4(mix(colorSkyNode, colorCloudNode, cloud), float(1))
55
+ },
56
+ props.order,
57
+ )
58
+ </script>
59
+
60
+ <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 { blendColorBurn } 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, blendColorBurn(prev.xyz, colorNode), opacityNode), prev.w),
20
+ props.order,
21
+ )
22
+ </script>
23
+
24
+ <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 { blendColorDodge } 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, blendColorDodge(prev.xyz, colorNode), opacityNode), prev.w),
20
+ props.order,
21
+ )
22
+ </script>
23
+
24
+ <template><!-- --></template>
@@ -0,0 +1,57 @@
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 { luminance } from '../../shaders/common/blend'
6
+
7
+ /**
8
+ * Maps input luminance to a three-stop colour ramp: shadow → midtone → highlight.
9
+ * For a simple two-stop ramp use DuoTone instead.
10
+ */
11
+ const props = withDefaults(defineProps<{
12
+ shadowColor?: string
13
+ midtoneColor?: string
14
+ highlightColor?: string
15
+ /** Luminance threshold between shadow and midtone */
16
+ shadowPoint?: number
17
+ /** Luminance threshold between midtone and highlight */
18
+ highlightPoint?: number
19
+ order?: number
20
+ }>(), {
21
+ shadowColor: '#000033',
22
+ midtoneColor: '#660066',
23
+ highlightColor: '#ffcc88',
24
+ shadowPoint: 0.33,
25
+ highlightPoint: 0.67,
26
+ order: 0,
27
+ })
28
+
29
+ function toVec3Node(hex: string) {
30
+ const c = new Color(hex)
31
+ return uniform(new Vector3(c.r, c.g, c.b))
32
+ }
33
+
34
+ const shadowNode = toVec3Node(props.shadowColor)
35
+ const midNode = toVec3Node(props.midtoneColor)
36
+ const highlightNode = toVec3Node(props.highlightColor)
37
+ const shadowPtNode = uniform(props.shadowPoint)
38
+ const highlightPtNode = uniform(props.highlightPoint)
39
+ watch(() => props.shadowColor, v => { const c = new Color(v); shadowNode.value.set(c.r, c.g, c.b) })
40
+ watch(() => props.midtoneColor, v => { const c = new Color(v); midNode.value.set(c.r, c.g, c.b) })
41
+ watch(() => props.highlightColor, v => { const c = new Color(v); highlightNode.value.set(c.r, c.g, c.b) })
42
+ watch(() => props.shadowPoint, v => { shadowPtNode.value = v })
43
+ watch(() => props.highlightPoint, v => { highlightPtNode.value = v })
44
+
45
+ useShaderStage(
46
+ (prev) => {
47
+ const lum = luminance(prev.xyz)
48
+ const t1 = smoothstep(float(0), shadowPtNode, lum)
49
+ const t2 = smoothstep(shadowPtNode, highlightPtNode, lum)
50
+ const colour = mix(mix(shadowNode, midNode, t1), mix(midNode, highlightNode, t2), t2)
51
+ return vec4(colour, prev.w)
52
+ },
53
+ props.order,
54
+ )
55
+ </script>
56
+
57
+ <template><!-- --></template>
@@ -0,0 +1,77 @@
1
+ <script setup lang="ts">
2
+ // @ts-nocheck
3
+ import { uniform, time, vec2, vec4, float, cos, sin } from 'three/tsl'
4
+ import { complexDiv, complexLog } from '../../shaders/common/complex'
5
+
6
+ /**
7
+ * Complex number plane visualisation — the imaginary2 pattern.
8
+ * Places two poles p, q derived from poleAngle/poleDistance,
9
+ * computes the Möbius transformation (z-p)/(z-q), takes the complex log,
10
+ * and extracts the imaginary component (winding angle) as a scalar float.
11
+ * Outputs grayscale for CosinePalette (scalarSource: 'prev').
12
+ */
13
+ const props = withDefaults(defineProps<{
14
+ /** Angle between the two poles in radians */
15
+ poleAngle?: number
16
+ /** Distance of poles from origin */
17
+ poleDistance?: number
18
+ /** Weight of the imaginary (winding) component */
19
+ imaginaryWeight?: number
20
+ /** Weight of the radial (exp) component */
21
+ radialWeight?: number
22
+ /** Animation speed */
23
+ speed?: number
24
+ order?: number
25
+ }>(), {
26
+ poleAngle: Math.PI / 3,
27
+ poleDistance: 0.4,
28
+ imaginaryWeight: 0.6,
29
+ radialWeight: 0.4,
30
+ speed: 0.05,
31
+ order: 0,
32
+ })
33
+
34
+ const poleAngleNode = uniform(props.poleAngle)
35
+ const poleDistNode = uniform(props.poleDistance)
36
+ const imagWeightNode = uniform(props.imaginaryWeight)
37
+ const radWeightNode = uniform(props.radialWeight)
38
+ const speedNode = uniform(props.speed)
39
+ watch(() => props.poleAngle, v => { poleAngleNode.value = v })
40
+ watch(() => props.poleDistance, v => { poleDistNode.value = v })
41
+ watch(() => props.imaginaryWeight, v => { imagWeightNode.value = v })
42
+ watch(() => props.radialWeight, v => { radWeightNode.value = v })
43
+ watch(() => props.speed, v => { speedNode.value = v })
44
+
45
+ const pipeline = useShaderPipelineContext()
46
+
47
+ useShaderStage(
48
+ () => {
49
+ const uvCurrent = pipeline.uvNode.value
50
+ const t = time.mul(speedNode)
51
+
52
+ // UV centred
53
+ const z = uvCurrent.sub(0.5)
54
+
55
+ // Pole position (complex number)
56
+ const angle = poleAngleNode.add(t)
57
+ const p = vec2(cos(angle).mul(poleDistNode), sin(angle).mul(poleDistNode))
58
+ const q = vec2(p.x, p.y.negate()) // conjugate
59
+
60
+ // Möbius: (z - p) / (z - q)
61
+ const w = complexDiv(z.sub(p), z.sub(q))
62
+
63
+ // Complex log: (ln|w|, arg(w))
64
+ const logW = complexLog(w)
65
+
66
+ // Combine imaginary (winding angle) and radial (exp magnitude) components
67
+ const imagPart = logW.y.mul(imagWeightNode)
68
+ const radPart = z.x.exp().div(z.y.abs().add(float(0.001))).mul(radWeightNode)
69
+ const scalar = imagPart.add(radPart).mul(0.5).add(0.5)
70
+
71
+ return vec4(scalar, scalar, scalar, float(1))
72
+ },
73
+ props.order,
74
+ )
75
+ </script>
76
+
77
+ <template><!-- --></template>
@@ -0,0 +1,40 @@
1
+ <script setup lang="ts">
2
+ // @ts-nocheck
3
+ import { Color, Vector3 } from 'three'
4
+ import { uniform, vec4, mix, float } from 'three/tsl'
5
+
6
+ const props = withDefaults(defineProps<{
7
+ colorA?: string
8
+ colorB?: string
9
+ /** Rotation offset in degrees */
10
+ rotation?: number
11
+ order?: number
12
+ }>(), { colorA: '#000000', colorB: '#ffffff', rotation: 0, order: 0 })
13
+
14
+ function toVec3Node(hex: string) {
15
+ const c = new Color(hex)
16
+ return uniform(new Vector3(c.r, c.g, c.b))
17
+ }
18
+
19
+ const colorANode = toVec3Node(props.colorA)
20
+ const colorBNode = toVec3Node(props.colorB)
21
+ const rotationNode = uniform(props.rotation * Math.PI / 180)
22
+ watch(() => props.colorA, v => { const c = new Color(v); colorANode.value.set(c.r, c.g, c.b) })
23
+ watch(() => props.colorB, v => { const c = new Color(v); colorBNode.value.set(c.r, c.g, c.b) })
24
+ watch(() => props.rotation, v => { rotationNode.value = v * Math.PI / 180 })
25
+
26
+ const pipeline = useShaderPipelineContext()
27
+
28
+ useShaderStage(
29
+ () => {
30
+ const uv = pipeline.uvNode.value
31
+ const centered = uv.sub(0.5)
32
+ const angle = centered.y.atan(centered.x).add(rotationNode)
33
+ const t = angle.div(Math.PI * 2).fract()
34
+ return vec4(mix(colorANode, colorBNode, t), float(1))
35
+ },
36
+ props.order,
37
+ )
38
+ </script>
39
+
40
+ <template><!-- --></template>
@@ -0,0 +1,71 @@
1
+ <script setup lang="ts">
2
+ // @ts-nocheck
3
+ import { Vector3 } from 'three'
4
+ import { time, uniform, vec4 } from 'three/tsl'
5
+ import { cosinePalette } from '../../shaders/common/palette'
6
+ import { luminance } from '../../shaders/common/blend'
7
+
8
+ /**
9
+ * IQ's cosine palette — the backbone of phobon/aurora-style shaders.
10
+ * Formula: a + b * cos(2π * (c*t + d))
11
+ * Scalar input t comes from uvNode via scalarSource.
12
+ */
13
+ const props = withDefaults(defineProps<{
14
+ /** Colour offset (brightness centre) */
15
+ a?: [number, number, number]
16
+ /** Colour amplitude (contrast) */
17
+ b?: [number, number, number]
18
+ /** Frequency per channel */
19
+ c?: [number, number, number]
20
+ /** Phase offset per channel (colour shift) */
21
+ d?: [number, number, number]
22
+ /** How fast the palette cycles over time */
23
+ timeScale?: number
24
+ /**
25
+ * What value to feed as the scalar input `t`.
26
+ * `'prev'` reads luminance of the previous pipeline stage — use after RingField,
27
+ * ChebyshevNoiseField, or any block that outputs a grayscale scalar as its colour.
28
+ */
29
+ scalarSource?: 'uv.y' | 'uv.x' | 'length' | 'time' | 'prev'
30
+ order?: number
31
+ }>(), {
32
+ a: () => [0.5, 0.5, 0.5],
33
+ b: () => [0.5, 0.5, 0.5],
34
+ c: () => [1.0, 1.0, 1.0],
35
+ d: () => [0.0, 0.33, 0.67],
36
+ timeScale: 0.1,
37
+ scalarSource: 'uv.y',
38
+ order: 0,
39
+ })
40
+
41
+ const aNode = uniform(new Vector3(...props.a))
42
+ const bNode = uniform(new Vector3(...props.b))
43
+ const cNode = uniform(new Vector3(...props.c))
44
+ const dNode = uniform(new Vector3(...props.d))
45
+ const timeScaleNode = uniform(props.timeScale)
46
+
47
+ watch(() => props.a, v => { aNode.value.set(...v) })
48
+ watch(() => props.b, v => { bNode.value.set(...v) })
49
+ watch(() => props.c, v => { cNode.value.set(...v) })
50
+ watch(() => props.d, v => { dNode.value.set(...v) })
51
+ watch(() => props.timeScale, v => { timeScaleNode.value = v })
52
+
53
+ const { uvNode } = useShaderPipelineContext()
54
+
55
+ useShaderStage(
56
+ (prev) => {
57
+ let scalar
58
+ if (props.scalarSource === 'uv.x') scalar = uvNode.value.x
59
+ else if (props.scalarSource === 'length') scalar = uvNode.value.sub(0.5).length()
60
+ else if (props.scalarSource === 'time') scalar = time
61
+ else if (props.scalarSource === 'prev') scalar = luminance(prev.xyz)
62
+ else scalar = uvNode.value.y
63
+
64
+ const t = scalar.add(time.mul(timeScaleNode))
65
+ return vec4(cosinePalette(t, aNode, bNode, cNode, dNode), 1.0)
66
+ },
67
+ props.order,
68
+ )
69
+ </script>
70
+
71
+ <template><!-- --></template>
@@ -0,0 +1,18 @@
1
+ <script setup lang="ts">
2
+ // @ts-nocheck
3
+ import { vec4 } from 'three/tsl'
4
+
5
+ /**
6
+ * Sets alpha to max(r, g, b) — the ColorBends transparent mode pattern.
7
+ * Shaders that generate shape from colour intensity (bright = opaque, dark = transparent)
8
+ * should use this instead of a fixed alpha = 1.
9
+ */
10
+ const { order = 0 } = defineProps<{ order?: number }>()
11
+
12
+ useShaderStage(
13
+ (prev) => vec4(prev.xyz, prev.x.max(prev.y).max(prev.z)),
14
+ order,
15
+ )
16
+ </script>
17
+
18
+ <template><!-- --></template>
@@ -0,0 +1,51 @@
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 { sdBox2d } from '../../shaders/common/sdf'
6
+
7
+ const props = withDefaults(defineProps<{
8
+ colorA?: string
9
+ colorB?: string
10
+ /** Length of each arm */
11
+ size?: number
12
+ /** Width of each arm */
13
+ thickness?: number
14
+ softness?: number
15
+ order?: number
16
+ }>(), { colorA: '#000000', colorB: '#ffffff', size: 0.4, thickness: 0.1, softness: 0.01, order: 0 })
17
+
18
+ function toVec3Node(hex: string) {
19
+ const c = new Color(hex)
20
+ return uniform(new Vector3(c.r, c.g, c.b))
21
+ }
22
+
23
+ const colorANode = toVec3Node(props.colorA)
24
+ const colorBNode = toVec3Node(props.colorB)
25
+ const sizeNode = uniform(props.size)
26
+ const thickNode = uniform(props.thickness)
27
+ const softnessNode = uniform(props.softness)
28
+ watch(() => props.colorA, v => { const c = new Color(v); colorANode.value.set(c.r, c.g, c.b) })
29
+ watch(() => props.colorB, v => { const c = new Color(v); colorBNode.value.set(c.r, c.g, c.b) })
30
+ watch(() => props.size, v => { sizeNode.value = v })
31
+ watch(() => props.thickness, v => { thickNode.value = v })
32
+ watch(() => props.softness, v => { softnessNode.value = v })
33
+
34
+ const pipeline = useShaderPipelineContext()
35
+
36
+ useShaderStage(
37
+ () => {
38
+ const uv = pipeline.uvNode.value
39
+ const p = uv.sub(0.5)
40
+ // Horizontal arm and vertical arm — union = min
41
+ const dH = sdBox2d(p, thickNode.div(2)) // approx — sdBox2d expects a scalar half-size
42
+ const dV = sdBox2d(p.yx, thickNode.div(2))
43
+ const d = dH.min(dV)
44
+ const mask = smoothstep(softnessNode, softnessNode.negate(), d)
45
+ return vec4(mix(colorANode, colorBNode, mask), float(1))
46
+ },
47
+ props.order,
48
+ )
49
+ </script>
50
+
51
+ <template><!-- --></template>
@@ -0,0 +1,48 @@
1
+ <script setup lang="ts">
2
+ // @ts-nocheck
3
+ import { Color, Vector3 } from 'three'
4
+ import { uniform, time, vec3, vec4, mix } from 'three/tsl'
5
+ import { curlNoise3d } from '../../shaders/common/noise'
6
+
7
+ const props = withDefaults(defineProps<{
8
+ /** Colour to mix in at curl peak */
9
+ color?: string
10
+ /** Blend opacity */
11
+ opacity?: number
12
+ /** Input scale for the curl noise */
13
+ scale?: number
14
+ /** Animation speed */
15
+ speed?: number
16
+ order?: number
17
+ }>(), { color: '#ffffff', opacity: 1, scale: 1.5, speed: 0.2, 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 colorNode = toVec3Node(props.color)
25
+ const opacityNode = uniform(props.opacity)
26
+ const scaleNode = uniform(props.scale)
27
+ const speedNode = uniform(props.speed)
28
+ watch(() => props.color, v => { const c = new Color(v); colorNode.value.set(c.r, c.g, c.b) })
29
+ watch(() => props.opacity, v => { opacityNode.value = v })
30
+ watch(() => props.scale, v => { scaleNode.value = v })
31
+ watch(() => props.speed, v => { speedNode.value = v })
32
+
33
+ const pipeline = useShaderPipelineContext()
34
+
35
+ useShaderStage(
36
+ (prev) => {
37
+ const uvCurrent = pipeline.uvNode.value
38
+ const t = time.mul(speedNode)
39
+ const p = vec3(uvCurrent.mul(scaleNode), t)
40
+ const curl = curlNoise3d(p).x.mul(0.5).add(0.5)
41
+ const blended = mix(prev.xyz, colorNode, curl.mul(opacityNode))
42
+ return vec4(blended, prev.w)
43
+ },
44
+ props.order,
45
+ )
46
+ </script>
47
+
48
+ <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 { blendDarken } 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, blendDarken(prev.xyz, colorNode), opacityNode), prev.w),
20
+ props.order,
21
+ )
22
+ </script>
23
+
24
+ <template><!-- --></template>
@@ -0,0 +1,48 @@
1
+ <script setup lang="ts">
2
+ // @ts-nocheck
3
+ import { Color, Vector3 } from 'three'
4
+ import { uniform, time, mix, pow, abs, sign, float, vec4 } from 'three/tsl'
5
+
6
+ /**
7
+ * Sinusoidal interpolation between a light and dark colour over time.
8
+ * The phobon easing: t = (sign(cycle) * pow(abs(cycle), 0.6) + 1) / 2
9
+ * where cycle = sin(time * speed).
10
+ */
11
+ const props = withDefaults(defineProps<{
12
+ /** Colour during the light phase */
13
+ colorLight?: string
14
+ /** Colour during the dark phase */
15
+ colorDark?: string
16
+ /** Cycle speed in radians per second */
17
+ speed?: number
18
+ /** Mix opacity over prev colour */
19
+ opacity?: number
20
+ order?: number
21
+ }>(), { colorLight: '#ffffff', colorDark: '#000033', speed: 0.3, opacity: 1, order: 0 })
22
+
23
+ function toVec3Node(hex: string) {
24
+ const c = new Color(hex)
25
+ return uniform(new Vector3(c.r, c.g, c.b))
26
+ }
27
+
28
+ const lightNode = toVec3Node(props.colorLight)
29
+ const darkNode = toVec3Node(props.colorDark)
30
+ const speedNode = uniform(props.speed)
31
+ const opacityNode = uniform(props.opacity)
32
+ watch(() => props.colorLight, v => { const c = new Color(v); lightNode.value.set(c.r, c.g, c.b) })
33
+ watch(() => props.colorDark, v => { const c = new Color(v); darkNode.value.set(c.r, c.g, c.b) })
34
+ watch(() => props.speed, v => { speedNode.value = v })
35
+ watch(() => props.opacity, v => { opacityNode.value = v })
36
+
37
+ useShaderStage(
38
+ (prev) => {
39
+ const cycle = time.mul(speedNode).sin()
40
+ const t = sign(cycle).mul(pow(abs(cycle), float(0.6))).add(1).div(2)
41
+ const colour = mix(darkNode, lightNode, t)
42
+ return vec4(mix(prev.xyz, colour, opacityNode), prev.w)
43
+ },
44
+ props.order,
45
+ )
46
+ </script>
47
+
48
+ <template><!-- --></template>
@@ -0,0 +1,21 @@
1
+ <script setup lang="ts">
2
+ // @ts-nocheck
3
+ import { uniform, vec4 } from 'three/tsl'
4
+ import { desaturate } from '../../shaders/common/blend'
5
+
6
+ const props = withDefaults(defineProps<{
7
+ /** 0 = original colour, 1 = full greyscale */
8
+ amount?: number
9
+ order?: number
10
+ }>(), { amount: 1, order: 0 })
11
+
12
+ const amountNode = uniform(props.amount)
13
+ watch(() => props.amount, v => { amountNode.value = v })
14
+
15
+ useShaderStage(
16
+ (prev) => vec4(desaturate(prev.xyz, amountNode), prev.w),
17
+ props.order,
18
+ )
19
+ </script>
20
+
21
+ <template><!-- --></template>
@@ -0,0 +1,38 @@
1
+ <script setup lang="ts">
2
+ // @ts-nocheck
3
+ import { Color, Vector3 } from 'three'
4
+ import { uniform, vec4, mix, cos, sin, float } from 'three/tsl'
5
+
6
+ const props = withDefaults(defineProps<{
7
+ colorA?: string
8
+ colorB?: string
9
+ /** Gradient angle in degrees (0 = left→right, 90 = bottom→top) */
10
+ angle?: number
11
+ order?: number
12
+ }>(), { colorA: '#000000', colorB: '#ffffff', angle: 45, order: 0 })
13
+
14
+ function toVec3Node(hex: string) {
15
+ const c = new Color(hex)
16
+ return uniform(new Vector3(c.r, c.g, c.b))
17
+ }
18
+
19
+ const colorANode = toVec3Node(props.colorA)
20
+ const colorBNode = toVec3Node(props.colorB)
21
+ const angleNode = uniform(props.angle * Math.PI / 180)
22
+ watch(() => props.colorA, v => { const c = new Color(v); colorANode.value.set(c.r, c.g, c.b) })
23
+ watch(() => props.colorB, v => { const c = new Color(v); colorBNode.value.set(c.r, c.g, c.b) })
24
+ watch(() => props.angle, v => { angleNode.value = v * Math.PI / 180 })
25
+
26
+ const pipeline = useShaderPipelineContext()
27
+
28
+ useShaderStage(
29
+ () => {
30
+ const uv = pipeline.uvNode.value
31
+ const t = uv.x.mul(cos(angleNode)).add(uv.y.mul(sin(angleNode))).clamp(float(0), float(1))
32
+ return vec4(mix(colorANode, colorBNode, t), float(1))
33
+ },
34
+ props.order,
35
+ )
36
+ </script>
37
+
38
+ <template><!-- --></template>