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,36 @@
1
+ <script setup lang="ts">
2
+ // @ts-nocheck
3
+ import { uniform, vec4, time } from 'three/tsl'
4
+ import { scanlines } from '../../shaders/common/grain'
5
+
6
+ const props = withDefaults(defineProps<{
7
+ /** Number of scanlines across the screen */
8
+ density?: number
9
+ /** Darkness of the lines: 0 = invisible, 1 = full black */
10
+ intensity?: number
11
+ /** Animate the lines — speed in lines/second */
12
+ scrollSpeed?: number
13
+ order?: number
14
+ }>(), { density: 400, intensity: 0.25, scrollSpeed: 0, order: 0 })
15
+
16
+ const densityNode = uniform(props.density)
17
+ const intensityNode = uniform(props.intensity)
18
+ const scrollSpeedNode = uniform(props.scrollSpeed)
19
+ watch(() => props.density, v => { densityNode.value = v })
20
+ watch(() => props.intensity, v => { intensityNode.value = v })
21
+ watch(() => props.scrollSpeed, v => { scrollSpeedNode.value = v })
22
+
23
+ const pipeline = useShaderPipelineContext()
24
+
25
+ useShaderStage(
26
+ (prev) => {
27
+ const uvCurrent = pipeline.uvNode.value
28
+ const offset = time.mul(scrollSpeedNode)
29
+ const factor = scanlines(uvCurrent, densityNode, intensityNode, offset)
30
+ return vec4(prev.xyz.mul(factor), prev.w)
31
+ },
32
+ props.order,
33
+ )
34
+ </script>
35
+
36
+ <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 { blendScreen } 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, blendScreen(prev.xyz, colorNode), opacityNode), prev.w),
20
+ props.order,
21
+ )
22
+ </script>
23
+
24
+ <template><!-- --></template>
@@ -0,0 +1,74 @@
1
+ <script setup lang="ts">
2
+ // @ts-nocheck
3
+ import { uniform, vec3, vec4, float, floor, fract } from 'three/tsl'
4
+
5
+ /**
6
+ * ShaderDebugger — dev-only visualization overlay for inspecting pipeline state.
7
+ *
8
+ * Modes:
9
+ * 'uv' — displays UV coordinates as red/green channels
10
+ * 'normal' — encodes normal-space UV as blue hue sweep
11
+ * 'grid' — overlays a reference grid on the current output
12
+ * 'pass' — passes through unchanged (no-op, useful for toggling off)
13
+ *
14
+ * Drop this at any `order` value to inspect that point in the pipeline.
15
+ * Only renders in development — remove from production compositions.
16
+ */
17
+ const props = withDefaults(defineProps<{
18
+ /** Visualization mode */
19
+ mode?: 'uv' | 'normal' | 'grid' | 'pass'
20
+ /** Grid line count (grid mode) */
21
+ gridLines?: number
22
+ /** Grid line thickness */
23
+ gridThickness?: number
24
+ /** Blend with original output (0 = full debug, 1 = full original) */
25
+ blend?: number
26
+ order?: number
27
+ }>(), { mode: 'uv', gridLines: 10, gridThickness: 0.02, blend: 0, order: 0 })
28
+
29
+ const gridLinesNode = uniform(props.gridLines)
30
+ const gridThickNode = uniform(props.gridThickness)
31
+ const blendNode = uniform(props.blend)
32
+ watch(() => props.gridLines, v => { gridLinesNode.value = v })
33
+ watch(() => props.gridThickness, v => { gridThickNode.value = v })
34
+ watch(() => props.blend, v => { blendNode.value = v })
35
+
36
+ const pipeline = useShaderPipelineContext()
37
+
38
+ useShaderStage(
39
+ (prev) => {
40
+ const uv = pipeline.uvNode.value
41
+
42
+ let debugColour
43
+
44
+ if (props.mode === 'uv') {
45
+ // Red = U, Green = V, Blue = 0
46
+ debugColour = vec3(uv.x, uv.y, float(0))
47
+ }
48
+ else if (props.mode === 'normal') {
49
+ // Encodes centered UV — negative values become blue tones
50
+ const centered = uv.sub(0.5)
51
+ debugColour = vec3(centered.x.add(0.5), centered.y.add(0.5), float(0.5))
52
+ }
53
+ else if (props.mode === 'grid') {
54
+ // Grid lines via fract — line at every 1/gridLines interval
55
+ const scaled = uv.mul(gridLinesNode)
56
+ const fx = fract(scaled.x)
57
+ const fy = fract(scaled.y)
58
+ const lineX = float(1).sub(fx.smoothstep(gridThickNode, float(0)))
59
+ const lineY = float(1).sub(fy.smoothstep(gridThickNode, float(0)))
60
+ const line = lineX.max(lineY)
61
+ debugColour = prev.xyz.mul(float(1).sub(line)).add(vec3(line, line.mul(0.5), float(0)))
62
+ }
63
+ else {
64
+ // pass — no-op
65
+ debugColour = prev.xyz
66
+ }
67
+
68
+ return vec4(prev.xyz.mix(debugColour, float(1).sub(blendNode)), prev.w)
69
+ },
70
+ props.order,
71
+ )
72
+ </script>
73
+
74
+ <template><!-- --></template>
@@ -0,0 +1,49 @@
1
+ <script setup lang="ts">
2
+ // @ts-nocheck
3
+ import { Color } from 'three'
4
+ import { float, mix, time, uniform, vec2, vec4 } from 'three/tsl'
5
+ import { simplexNoise2D } from '../../shaders/common/noise'
6
+
7
+ const props = withDefaults(defineProps<{
8
+ colorA?: string
9
+ colorB?: string
10
+ scale?: number
11
+ animated?: boolean
12
+ speed?: number
13
+ order?: number
14
+ }>(), {
15
+ colorA: '#000000',
16
+ colorB: '#ffffff',
17
+ scale: 3,
18
+ animated: true,
19
+ speed: 0.3,
20
+ order: 0,
21
+ })
22
+
23
+ const colorAVal = new Color(props.colorA)
24
+ const colorBVal = new Color(props.colorB)
25
+ const colorANode = uniform(colorAVal)
26
+ const colorBNode = uniform(colorBVal)
27
+ const scaleNode = uniform(props.scale)
28
+ const speedNode = uniform(props.speed)
29
+
30
+ watch(() => props.colorA, v => { colorANode.value.set(v) })
31
+ watch(() => props.colorB, v => { colorBNode.value.set(v) })
32
+ watch(() => props.scale, v => { scaleNode.value = v })
33
+ watch(() => props.speed, v => { speedNode.value = v })
34
+
35
+ const { uvNode } = useShaderPipelineContext()
36
+
37
+ useShaderStage(
38
+ (_prev) => {
39
+ // Scroll UV over time to animate noise (cheaper than 3D noise)
40
+ const offset = props.animated ? time.mul(speedNode) : float(0)
41
+ const input = uvNode.value.mul(scaleNode).add(vec2(offset, 0))
42
+ const n = simplexNoise2D(input).mul(0.5).add(0.5)
43
+ return vec4(mix(colorANode, colorBNode, n), 1.0)
44
+ },
45
+ props.order,
46
+ )
47
+ </script>
48
+
49
+ <template><!-- --></template>
@@ -0,0 +1,75 @@
1
+ <script setup lang="ts">
2
+ // @ts-nocheck
3
+ import { Color, Vector3 } from 'three'
4
+ import { uniform, clamp, mix, pow, dot, vec3, vec4, float } from 'three/tsl'
5
+
6
+ const props = withDefaults(defineProps<{
7
+ /** Sky colour at the zenith */
8
+ zenith?: string
9
+ /** Sky colour at the horizon */
10
+ horizon?: string
11
+ /** Ground colour below horizon */
12
+ ground?: string
13
+ /** Sun direction — [x, y, z] world space (will be normalised) */
14
+ sunDirection?: [number, number, number]
15
+ /** Sun colour */
16
+ sunColor?: string
17
+ /** Sun disk sharpness (higher = smaller disk) */
18
+ sunPower?: number
19
+ order?: number
20
+ }>(), {
21
+ zenith: '#1a3a8a',
22
+ horizon: '#7ab0d8',
23
+ ground: '#5a4a3a',
24
+ sunDirection: () => [0.3, 0.8, 0.5],
25
+ sunColor: '#fff8e0',
26
+ sunPower: 512,
27
+ order: 0,
28
+ })
29
+
30
+ function toVec3Node(hex: string) {
31
+ const c = new Color(hex)
32
+ return uniform(new Vector3(c.r, c.g, c.b))
33
+ }
34
+
35
+ const zenithNode = toVec3Node(props.zenith)
36
+ const horizonNode = toVec3Node(props.horizon)
37
+ const groundNode = toVec3Node(props.ground)
38
+ const sunColorNode = toVec3Node(props.sunColor)
39
+ const sunPowerNode = uniform(props.sunPower)
40
+
41
+ const sunDir = new Vector3(...props.sunDirection).normalize()
42
+ const sunDirNode = uniform(new Vector3(sunDir.x, sunDir.y, sunDir.z))
43
+
44
+ watch(() => props.zenith, v => { const c = new Color(v); zenithNode.value.set(c.r, c.g, c.b) })
45
+ watch(() => props.horizon, v => { const c = new Color(v); horizonNode.value.set(c.r, c.g, c.b) })
46
+ watch(() => props.ground, v => { const c = new Color(v); groundNode.value.set(c.r, c.g, c.b) })
47
+ watch(() => props.sunColor, v => { const c = new Color(v); sunColorNode.value.set(c.r, c.g, c.b) })
48
+ watch(() => props.sunPower, v => { sunPowerNode.value = v })
49
+ watch(() => props.sunDirection, ([x, y, z]) => {
50
+ const d = new Vector3(x, y, z).normalize()
51
+ sunDirNode.value.set(d.x, d.y, d.z)
52
+ })
53
+
54
+ const pipeline = useShaderPipelineContext()
55
+
56
+ useShaderStage(
57
+ () => {
58
+ const ray = pipeline.rayNode.value
59
+
60
+ // Sky gradient: -1..+1 on Y → ground..zenith
61
+ const t = clamp(ray.y.mul(2.0).add(0.5), 0, 1)
62
+ const sky = mix(horizonNode, zenithNode, t)
63
+ const colour = mix(groundNode, sky, clamp(ray.y.add(0.1).mul(10.0), 0, 1))
64
+
65
+ // Sun disc
66
+ const sunDot = dot(ray, sunDirNode).max(float(0))
67
+ const sun = sunColorNode.mul(pow(sunDot, sunPowerNode))
68
+
69
+ return vec4(colour.add(sun), 1.0)
70
+ },
71
+ props.order,
72
+ )
73
+ </script>
74
+
75
+ <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 { blendSoftLight } 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, blendSoftLight(prev.xyz, colorNode), opacityNode), prev.w),
20
+ props.order,
21
+ )
22
+ </script>
23
+
24
+ <template><!-- --></template>
@@ -0,0 +1,21 @@
1
+ <script setup lang="ts">
2
+ // @ts-nocheck
3
+ import { Color } from 'three'
4
+ import { uniform, vec4 } from 'three/tsl'
5
+
6
+ const props = withDefaults(defineProps<{
7
+ color?: string
8
+ order?: number
9
+ }>(), {
10
+ color: '#ffffff',
11
+ order: 0,
12
+ })
13
+
14
+ const colorVal = new Color(props.color)
15
+ const colorNode = uniform(colorVal)
16
+ watch(() => props.color, v => { colorNode.value.set(v) })
17
+
18
+ useShaderStage((_prev) => vec4(colorNode, 1.0), props.order)
19
+ </script>
20
+
21
+ <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 { luminance } from '../../shaders/common/blend'
6
+
7
+ const props = withDefaults(defineProps<{
8
+ /** Colour pushed into shadow tones */
9
+ shadowColor?: string
10
+ /** Colour pushed into highlight tones */
11
+ highlightColor?: string
12
+ /** Balance point: 0.5 = even split, lower = shadows dominate */
13
+ balance?: number
14
+ /** Overall blend strength */
15
+ opacity?: number
16
+ order?: number
17
+ }>(), { shadowColor: '#1a2a5a', highlightColor: '#ffeecc', balance: 0.5, opacity: 0.5, 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 shadowNode = toVec3Node(props.shadowColor)
25
+ const highlightNode = toVec3Node(props.highlightColor)
26
+ const balanceNode = uniform(props.balance)
27
+ const opacityNode = uniform(props.opacity)
28
+ watch(() => props.shadowColor, v => { const c = new Color(v); shadowNode.value.set(c.r, c.g, c.b) })
29
+ watch(() => props.highlightColor, v => { const c = new Color(v); highlightNode.value.set(c.r, c.g, c.b) })
30
+ watch(() => props.balance, v => { balanceNode.value = v })
31
+ watch(() => props.opacity, v => { opacityNode.value = v })
32
+
33
+ useShaderStage(
34
+ (prev) => {
35
+ const lum = luminance(prev.xyz)
36
+ const shadowMask = smoothstep(balanceNode, float(0), lum)
37
+ const highlightMask = smoothstep(balanceNode, float(1), lum)
38
+ const toned = prev.xyz
39
+ .add(shadowNode.mul(shadowMask).mul(opacityNode))
40
+ .add(highlightNode.mul(highlightMask).mul(opacityNode))
41
+ return vec4(toned, prev.w)
42
+ },
43
+ props.order,
44
+ )
45
+ </script>
46
+
47
+ <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, float } from 'three/tsl'
5
+ import { star } from '../../shaders/common/shapes'
6
+
7
+ const props = withDefaults(defineProps<{
8
+ colorA?: string
9
+ colorB?: string
10
+ radius?: number
11
+ /** Number of points */
12
+ points?: number
13
+ /** Inner radius ratio (0–1) */
14
+ innerRatio?: number
15
+ softness?: number
16
+ order?: number
17
+ }>(), { colorA: '#000000', colorB: '#ffcc00', radius: 0.35, points: 5, innerRatio: 0.45, softness: 0.01, 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 innerNode = uniform(props.innerRatio)
28
+ const softnessNode = uniform(props.softness)
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.innerRatio, v => { innerNode.value = v })
33
+ watch(() => props.softness, v => { softnessNode.value = v })
34
+
35
+ const pipeline = useShaderPipelineContext()
36
+
37
+ useShaderStage(
38
+ () => {
39
+ const uv = pipeline.uvNode.value
40
+ const mask = star(uv, [0.5, 0.5], radiusNode, props.points, innerNode, softnessNode)
41
+ return vec4(mix(colorANode, colorBNode, mask), float(1))
42
+ },
43
+ props.order,
44
+ )
45
+ </script>
46
+
47
+ <template><!-- --></template>
@@ -0,0 +1,65 @@
1
+ <script setup lang="ts">
2
+ // @ts-nocheck
3
+ import { uniform, time, vec3, vec4, vec2, floor, fract, sin, dot, smoothstep, float } from 'three/tsl'
4
+
5
+ /**
6
+ * Hash-based procedural starfield.
7
+ * Each cell on a grid may contain a star whose brightness twinkles over time.
8
+ */
9
+ const props = withDefaults(defineProps<{
10
+ /** Grid density — higher = more stars */
11
+ density?: number
12
+ /** Star brightness */
13
+ brightness?: number
14
+ /** Twinkle animation speed */
15
+ twinkleSpeed?: number
16
+ /** Star size (sharpness) */
17
+ size?: number
18
+ order?: number
19
+ }>(), { density: 80, brightness: 1.0, twinkleSpeed: 1.0, size: 0.4, order: 0 })
20
+
21
+ const densityNode = uniform(props.density)
22
+ const brightnessNode = uniform(props.brightness)
23
+ const twinkleNode = uniform(props.twinkleSpeed)
24
+ const sizeNode = uniform(props.size)
25
+ watch(() => props.density, v => { densityNode.value = v })
26
+ watch(() => props.brightness, v => { brightnessNode.value = v })
27
+ watch(() => props.twinkleSpeed, v => { twinkleNode.value = v })
28
+ watch(() => props.size, v => { sizeNode.value = v })
29
+
30
+ const pipeline = useShaderPipelineContext()
31
+
32
+ useShaderStage(
33
+ (prev) => {
34
+ const uv = pipeline.uvNode.value
35
+ const t = time.mul(twinkleNode)
36
+
37
+ // Scale UV into grid cells
38
+ const scaled = uv.mul(densityNode)
39
+ const cell = floor(scaled)
40
+ const local = fract(scaled).sub(0.5)
41
+
42
+ // Hash per cell → star position offset and brightness
43
+ const h1 = fract(sin(dot(cell, vec2(127.1, 311.7))).mul(43758.5453))
44
+ const h2 = fract(sin(dot(cell, vec2(269.5, 183.3))).mul(43758.5453))
45
+ const h3 = fract(sin(dot(cell, vec2(419.2, 371.9))).mul(43758.5453))
46
+
47
+ // Only ~30% of cells have stars
48
+ const hasStar = smoothstep(0.7, 0.75, h3)
49
+
50
+ // Star position within cell
51
+ const starPos = vec2(h1, h2).sub(0.5).mul(0.6)
52
+ const dist = local.sub(starPos).length()
53
+
54
+ // Twinkle via time-based sine modulation
55
+ const twinkle = sin(t.add(h1.mul(6.28))).mul(0.3).add(0.7)
56
+ const star = smoothstep(sizeNode, float(0), dist.mul(10)).mul(hasStar).mul(twinkle)
57
+
58
+ const colour = vec3(star.mul(brightnessNode))
59
+ return vec4(prev.xyz.add(colour), prev.w)
60
+ },
61
+ props.order,
62
+ )
63
+ </script>
64
+
65
+ <template><!-- --></template>
@@ -0,0 +1,46 @@
1
+ <script setup lang="ts">
2
+ // @ts-nocheck
3
+ import { Color, Vector3 } from 'three'
4
+ import { uniform, vec4, mix, float } from 'three/tsl'
5
+ import { stripes } from '../../shaders/common/shapes'
6
+
7
+ const props = withDefaults(defineProps<{
8
+ colorA?: string
9
+ colorB?: string
10
+ frequency?: number
11
+ /** Fraction of each stripe that is colorB (0–1) */
12
+ thickness?: number
13
+ /** Angle in degrees */
14
+ angle?: number
15
+ order?: number
16
+ }>(), { colorA: '#000000', colorB: '#ffffff', frequency: 10, thickness: 0.5, angle: 0, 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 freqNode = uniform(props.frequency)
26
+ const thickNode = uniform(props.thickness)
27
+ const angleNode = uniform(props.angle * Math.PI / 180)
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.frequency, v => { freqNode.value = v })
31
+ watch(() => props.thickness, v => { thickNode.value = v })
32
+ watch(() => props.angle, v => { angleNode.value = v * Math.PI / 180 })
33
+
34
+ const pipeline = useShaderPipelineContext()
35
+
36
+ useShaderStage(
37
+ () => {
38
+ const uv = pipeline.uvNode.value
39
+ const mask = stripes(uv, freqNode, thickNode, angleNode)
40
+ return vec4(mix(colorANode, colorBNode, mask), float(1))
41
+ },
42
+ props.order,
43
+ )
44
+ </script>
45
+
46
+ <template><!-- --></template>
@@ -0,0 +1,24 @@
1
+ <script setup lang="ts">
2
+ // @ts-nocheck
3
+ import { Color } from 'three'
4
+ import { clamp, uniform, vec4 } from 'three/tsl'
5
+ import { blendSubtract } 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) => clamp(vec4(blendSubtract(prev.xyz, colorNode, opacityNode), prev.w), 0, 1),
20
+ props.order,
21
+ )
22
+ </script>
23
+
24
+ <template><!-- --></template>
@@ -0,0 +1,24 @@
1
+ <script setup lang="ts">
2
+ // @ts-nocheck
3
+ import { uniform, vec4 } from 'three/tsl'
4
+ import { tanhTonemap } from '../../shaders/common/tonemapping'
5
+
6
+ const props = withDefaults(defineProps<{
7
+ /** Controls how aggressively values above 1 are compressed. dawn5 uses 2.5. */
8
+ exposure?: number
9
+ order?: number
10
+ }>(), {
11
+ exposure: 1.0,
12
+ order: 0,
13
+ })
14
+
15
+ const exposureNode = uniform(props.exposure)
16
+ watch(() => props.exposure, v => { exposureNode.value = v })
17
+
18
+ useShaderStage(
19
+ (prev) => vec4(tanhTonemap(prev.xyz.mul(exposureNode)), prev.w),
20
+ props.order,
21
+ )
22
+ </script>
23
+
24
+ <template><!-- --></template>
@@ -0,0 +1,25 @@
1
+ <script setup lang="ts">
2
+ // @ts-nocheck
3
+ import { uniform, vec4, step, float } from 'three/tsl'
4
+ import { luminance } from '../../shaders/common/blend'
5
+
6
+ const props = withDefaults(defineProps<{
7
+ /** Luminance threshold 0–1: below = black, above = white */
8
+ threshold?: number
9
+ order?: number
10
+ }>(), { threshold: 0.5, order: 0 })
11
+
12
+ const thresholdNode = uniform(props.threshold)
13
+ watch(() => props.threshold, v => { thresholdNode.value = v })
14
+
15
+ useShaderStage(
16
+ (prev) => {
17
+ const lum = luminance(prev.xyz)
18
+ const t = step(thresholdNode, lum)
19
+ return vec4(float(t), float(t), float(t), prev.w)
20
+ },
21
+ props.order,
22
+ )
23
+ </script>
24
+
25
+ <template><!-- --></template>
@@ -0,0 +1,33 @@
1
+ <script setup lang="ts">
2
+ // @ts-nocheck
3
+ import { Color, Vector3 } from 'three'
4
+ import { uniform, vec4 } from 'three/tsl'
5
+
6
+ const props = withDefaults(defineProps<{
7
+ /** Tint colour — multiplied against the existing colour */
8
+ color?: string
9
+ /** Blend between original (0) and fully tinted (1) */
10
+ opacity?: number
11
+ order?: number
12
+ }>(), { color: '#ff8844', opacity: 1, 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 colorNode = toVec3Node(props.color)
20
+ const opacityNode = uniform(props.opacity)
21
+ watch(() => props.color, v => { const c = new Color(v); colorNode.value.set(c.r, c.g, c.b) })
22
+ watch(() => props.opacity, v => { opacityNode.value = v })
23
+
24
+ useShaderStage(
25
+ (prev) => {
26
+ const tinted = prev.xyz.mul(colorNode)
27
+ return vec4(prev.xyz.mix(tinted, opacityNode), prev.w)
28
+ },
29
+ props.order,
30
+ )
31
+ </script>
32
+
33
+ <template><!-- --></template>
@@ -0,0 +1,42 @@
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 { sdEquilateralTriangle } from '../../shaders/common/sdf'
6
+
7
+ const props = withDefaults(defineProps<{
8
+ colorA?: string
9
+ colorB?: string
10
+ size?: number
11
+ softness?: number
12
+ order?: number
13
+ }>(), { colorA: '#000000', colorB: '#ffffff', size: 0.35, softness: 0.01, 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 colorANode = toVec3Node(props.colorA)
21
+ const colorBNode = toVec3Node(props.colorB)
22
+ const sizeNode = uniform(props.size)
23
+ const softnessNode = uniform(props.softness)
24
+ watch(() => props.colorA, v => { const c = new Color(v); colorANode.value.set(c.r, c.g, c.b) })
25
+ watch(() => props.colorB, v => { const c = new Color(v); colorBNode.value.set(c.r, c.g, c.b) })
26
+ watch(() => props.size, v => { sizeNode.value = v })
27
+ watch(() => props.softness, v => { softnessNode.value = v })
28
+
29
+ const pipeline = useShaderPipelineContext()
30
+
31
+ useShaderStage(
32
+ () => {
33
+ const uv = pipeline.uvNode.value
34
+ const d = sdEquilateralTriangle(uv.sub(0.5), sizeNode)
35
+ const mask = smoothstep(softnessNode, softnessNode.negate(), d)
36
+ return vec4(mix(colorANode, colorBNode, mask), float(1))
37
+ },
38
+ props.order,
39
+ )
40
+ </script>
41
+
42
+ <template><!-- --></template>