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.
- package/layers/core/app/.DS_Store +0 -0
- package/layers/core/app/assets/.DS_Store +0 -0
- package/layers/core/app/assets/css/main.css +2 -0
- package/layers/core/app/components/ErrorBoundary.vue +1 -1
- package/layers/core/nuxt.config.ts +0 -8
- package/layers/motion/app/plugins/locomotive-scroll.client.ts +14 -11
- package/layers/motion/app.config.ts +6 -0
- package/layers/shader/app/components/Pipeline/ACESTonemap.client.vue +14 -0
- package/layers/shader/app/components/Pipeline/AddBlend.client.vue +24 -0
- package/layers/shader/app/components/Pipeline/AgedFilm.client.vue +62 -0
- package/layers/shader/app/components/Pipeline/Aurora.client.vue +81 -0
- package/layers/shader/app/components/Pipeline/BilinearGradient.client.vue +46 -0
- package/layers/shader/app/components/Pipeline/BillowNoise.client.vue +42 -0
- package/layers/shader/app/components/Pipeline/BrightnessContrast.client.vue +25 -0
- package/layers/shader/app/components/Pipeline/CellularNoise.client.vue +41 -0
- package/layers/shader/app/components/Pipeline/ChannelMixer.client.vue +44 -0
- package/layers/shader/app/components/Pipeline/ChebyshevNoiseField.client.vue +60 -0
- package/layers/shader/app/components/Pipeline/Checkerboard.client.vue +41 -0
- package/layers/shader/app/components/Pipeline/ChromaticAberration.client.vue +52 -0
- package/layers/shader/app/components/Pipeline/ChromaticScreenWaves.client.vue +49 -0
- package/layers/shader/app/components/Pipeline/Circle.client.vue +41 -0
- package/layers/shader/app/components/Pipeline/Clouds.client.vue +60 -0
- package/layers/shader/app/components/Pipeline/ColorBurnBlend.client.vue +24 -0
- package/layers/shader/app/components/Pipeline/ColorDodgeBlend.client.vue +24 -0
- package/layers/shader/app/components/Pipeline/ColourRamp.client.vue +57 -0
- package/layers/shader/app/components/Pipeline/ComplexPlaneField.client.vue +77 -0
- package/layers/shader/app/components/Pipeline/ConicGradient.client.vue +40 -0
- package/layers/shader/app/components/Pipeline/CosinePalette.client.vue +71 -0
- package/layers/shader/app/components/Pipeline/CoverageAlpha.client.vue +18 -0
- package/layers/shader/app/components/Pipeline/Cross.client.vue +51 -0
- package/layers/shader/app/components/Pipeline/CurlNoise.client.vue +48 -0
- package/layers/shader/app/components/Pipeline/DarkenBlend.client.vue +24 -0
- package/layers/shader/app/components/Pipeline/DayNightCycle.client.vue +48 -0
- package/layers/shader/app/components/Pipeline/Desaturate.client.vue +21 -0
- package/layers/shader/app/components/Pipeline/DiagonalGradient.client.vue +38 -0
- package/layers/shader/app/components/Pipeline/DiamondGradient.client.vue +40 -0
- package/layers/shader/app/components/Pipeline/DifferenceBlend.client.vue +24 -0
- package/layers/shader/app/components/Pipeline/DivideBlend.client.vue +26 -0
- package/layers/shader/app/components/Pipeline/DomainWarpedNoise.client.vue +48 -0
- package/layers/shader/app/components/Pipeline/Dots.client.vue +44 -0
- package/layers/shader/app/components/Pipeline/DuoTone.client.vue +34 -0
- package/layers/shader/app/components/Pipeline/ExclusionBlend.client.vue +24 -0
- package/layers/shader/app/components/Pipeline/ExponentialFog.client.vue +46 -0
- package/layers/shader/app/components/Pipeline/Exposure.client.vue +23 -0
- package/layers/shader/app/components/Pipeline/FBMNoise.client.vue +50 -0
- package/layers/shader/app/components/Pipeline/FilmBurn.client.vue +49 -0
- package/layers/shader/app/components/Pipeline/FilmGrain.client.vue +69 -0
- package/layers/shader/app/components/Pipeline/FisheyeRay.client.vue +35 -0
- package/layers/shader/app/components/Pipeline/Flame.client.vue +51 -0
- package/layers/shader/app/components/Pipeline/FocalGradient.client.vue +43 -0
- package/layers/shader/app/components/Pipeline/Gamma.client.vue +23 -0
- package/layers/shader/app/components/Pipeline/GodRays.client.vue +64 -0
- package/layers/shader/app/components/Pipeline/GradientNoise.client.vue +42 -0
- package/layers/shader/app/components/Pipeline/Grain.client.vue +81 -0
- package/layers/shader/app/components/Pipeline/Grid.client.vue +43 -0
- package/layers/shader/app/components/Pipeline/Halation.client.vue +43 -0
- package/layers/shader/app/components/Pipeline/Halftone.client.vue +33 -0
- package/layers/shader/app/components/Pipeline/HardLightBlend.client.vue +24 -0
- package/layers/shader/app/components/Pipeline/Haze.client.vue +50 -0
- package/layers/shader/app/components/Pipeline/Hexagon.client.vue +42 -0
- package/layers/shader/app/components/Pipeline/Hue.client.vue +21 -0
- package/layers/shader/app/components/Pipeline/Invert.client.vue +14 -0
- package/layers/shader/app/components/Pipeline/LensFlare.client.vue +67 -0
- package/layers/shader/app/components/Pipeline/LightenBlend.client.vue +24 -0
- package/layers/shader/app/components/Pipeline/LinearGradient.client.vue +36 -0
- package/layers/shader/app/components/Pipeline/LinearGradient4.client.vue +67 -0
- package/layers/shader/app/components/Pipeline/LinearToSRGB.client.vue +25 -0
- package/layers/shader/app/components/Pipeline/Marble.client.vue +69 -0
- package/layers/shader/app/components/Pipeline/MixBlend.client.vue +45 -0
- package/layers/shader/app/components/Pipeline/MonochromeTint.client.vue +31 -0
- package/layers/shader/app/components/Pipeline/MultiplyBlend.client.vue +24 -0
- package/layers/shader/app/components/Pipeline/NoisyGradient.client.vue +54 -0
- package/layers/shader/app/components/Pipeline/NoisyGradientBlend.client.vue +116 -0
- package/layers/shader/app/components/Pipeline/OverlayBlend.client.vue +24 -0
- package/layers/shader/app/components/Pipeline/PaperTexture.client.vue +41 -0
- package/layers/shader/app/components/Pipeline/Polygon.client.vue +47 -0
- package/layers/shader/app/components/Pipeline/Posterise.client.vue +23 -0
- package/layers/shader/app/components/Pipeline/RadialGradient.client.vue +39 -0
- package/layers/shader/app/components/Pipeline/RayAutoOrbit.client.vue +37 -0
- package/layers/shader/app/components/Pipeline/RayMouseOrbit.client.vue +49 -0
- package/layers/shader/app/components/Pipeline/RayRotateX.client.vue +25 -0
- package/layers/shader/app/components/Pipeline/RayRotateY.client.vue +25 -0
- package/layers/shader/app/components/Pipeline/RayRotateZ.client.vue +25 -0
- package/layers/shader/app/components/Pipeline/RayTiltBasis.client.vue +41 -0
- package/layers/shader/app/components/Pipeline/RaymarchTunnel.client.vue +101 -0
- package/layers/shader/app/components/Pipeline/Rectangle.client.vue +47 -0
- package/layers/shader/app/components/Pipeline/ReinhardTonemap.client.vue +18 -0
- package/layers/shader/app/components/Pipeline/RidgedNoise.client.vue +41 -0
- package/layers/shader/app/components/Pipeline/Ring.client.vue +44 -0
- package/layers/shader/app/components/Pipeline/RingField.client.vue +69 -0
- package/layers/shader/app/components/Pipeline/RisographGrain.client.vue +74 -0
- package/layers/shader/app/components/Pipeline/RotatedGradientBlend.client.vue +61 -0
- package/layers/shader/app/components/Pipeline/SDFColourMask.client.vue +33 -0
- package/layers/shader/app/components/Pipeline/SDFRadialMask.client.vue +31 -0
- package/layers/shader/app/components/Pipeline/SRGBToLinear.client.vue +25 -0
- package/layers/shader/app/components/Pipeline/Saturation.client.vue +21 -0
- package/layers/shader/app/components/Pipeline/Scanlines.client.vue +36 -0
- package/layers/shader/app/components/Pipeline/ScreenBlend.client.vue +24 -0
- package/layers/shader/app/components/Pipeline/ShaderDebugger.client.vue +74 -0
- package/layers/shader/app/components/Pipeline/SimplexNoise.client.vue +49 -0
- package/layers/shader/app/components/Pipeline/SkyAtmosphere.client.vue +75 -0
- package/layers/shader/app/components/Pipeline/SoftLightBlend.client.vue +24 -0
- package/layers/shader/app/components/Pipeline/SolidColour.client.vue +21 -0
- package/layers/shader/app/components/Pipeline/SplitTone.client.vue +47 -0
- package/layers/shader/app/components/Pipeline/Star.client.vue +47 -0
- package/layers/shader/app/components/Pipeline/Starfield.client.vue +65 -0
- package/layers/shader/app/components/Pipeline/Stripes.client.vue +46 -0
- package/layers/shader/app/components/Pipeline/SubtractBlend.client.vue +24 -0
- package/layers/shader/app/components/Pipeline/TanhTonemap.client.vue +24 -0
- package/layers/shader/app/components/Pipeline/Threshold.client.vue +25 -0
- package/layers/shader/app/components/Pipeline/Tint.client.vue +33 -0
- package/layers/shader/app/components/Pipeline/Triangle.client.vue +42 -0
- package/layers/shader/app/components/Pipeline/UVAspectCorrect.client.vue +14 -0
- package/layers/shader/app/components/Pipeline/UVBreath.client.vue +36 -0
- package/layers/shader/app/components/Pipeline/UVBulge.client.vue +26 -0
- package/layers/shader/app/components/Pipeline/UVClamp.client.vue +18 -0
- package/layers/shader/app/components/Pipeline/UVColumnOffset.client.vue +28 -0
- package/layers/shader/app/components/Pipeline/UVFlipX.client.vue +14 -0
- package/layers/shader/app/components/Pipeline/UVFlipXY.client.vue +14 -0
- package/layers/shader/app/components/Pipeline/UVFlipY.client.vue +14 -0
- package/layers/shader/app/components/Pipeline/UVFractBand.client.vue +31 -0
- package/layers/shader/app/components/Pipeline/UVMousePull.client.vue +39 -0
- package/layers/shader/app/components/Pipeline/UVNoiseRotate.client.vue +54 -0
- package/layers/shader/app/components/Pipeline/UVNoiseWarp.client.vue +35 -0
- package/layers/shader/app/components/Pipeline/UVOrbit.client.vue +34 -0
- package/layers/shader/app/components/Pipeline/UVParallax.client.vue +39 -0
- package/layers/shader/app/components/Pipeline/UVPixelate.client.vue +21 -0
- package/layers/shader/app/components/Pipeline/UVPulse.client.vue +33 -0
- package/layers/shader/app/components/Pipeline/UVRipple.client.vue +34 -0
- package/layers/shader/app/components/Pipeline/UVRotate.client.vue +37 -0
- package/layers/shader/app/components/Pipeline/UVScale.client.vue +30 -0
- package/layers/shader/app/components/Pipeline/UVScroll.client.vue +27 -0
- package/layers/shader/app/components/Pipeline/UVScrollX.client.vue +21 -0
- package/layers/shader/app/components/Pipeline/UVScrollY.client.vue +21 -0
- package/layers/shader/app/components/Pipeline/UVShear.client.vue +25 -0
- package/layers/shader/app/components/Pipeline/UVSineWarpXY.client.vue +46 -0
- package/layers/shader/app/components/Pipeline/UVSwapAxes.client.vue +14 -0
- package/layers/shader/app/components/Pipeline/UVTile.client.vue +27 -0
- package/layers/shader/app/components/Pipeline/UVTwirl.client.vue +26 -0
- package/layers/shader/app/components/Pipeline/UVWarp.client.vue +30 -0
- package/layers/shader/app/components/Pipeline/VHSBleed.client.vue +58 -0
- package/layers/shader/app/components/Pipeline/ValueNoise.client.vue +41 -0
- package/layers/shader/app/components/Pipeline/Vibrance.client.vue +24 -0
- package/layers/shader/app/components/Pipeline/Vignette.client.vue +32 -0
- package/layers/shader/app/components/Pipeline/VoronoiEdges.client.vue +50 -0
- package/layers/shader/app/components/Pipeline/Water.client.vue +53 -0
- package/layers/shader/app/components/Pipeline/WaveBendLayer.client.vue +61 -0
- package/layers/shader/app/components/Pipeline/WaveColourLayer.client.vue +56 -0
- package/layers/shader/app/components/Pipeline/WhiteBalance.client.vue +40 -0
- package/layers/shader/app/components/Pipeline/Wood.client.vue +63 -0
- package/layers/shader/app/components/Shader/Canvas.vue +24 -0
- package/layers/shader/app/components/Shader/Pipeline.client.vue +56 -0
- package/layers/shader/app/components/Shader/PipelineContext.vue +18 -0
- package/layers/shader/app/composables/useCSSColourUniform.ts +41 -0
- package/layers/shader/app/composables/useCSSFloatUniform.ts +34 -0
- package/layers/shader/app/composables/useShaderPerf.ts +73 -0
- package/layers/shader/app/composables/useShaderPipeline.ts +99 -0
- package/layers/shader/app/composables/useSunDirectionUniform.ts +54 -0
- package/layers/shader/app/composables/useTSLNodes.ts +0 -1
- package/layers/shader/app/shaders/common/complex.ts +29 -0
- package/layers/shader/app/shaders/common/shapes.ts +4 -4
- package/layers/shader/app/shaders/common/uv.ts +2 -2
- package/layers/shader/app/utils/tsl/patterns.ts +1 -1
- package/layers/shader/app/utils/tsl/uv.ts +3 -3
- package/layers/ui/app/app.config.ts +2 -16
- package/layers/ui/app/types/app-config.d.ts +17 -0
- package/package.json +9 -7
|
@@ -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.mul(c).add(ray.z.mul(s)), ray.y, ray.z.mul(c).sub(ray.x.mul(s)))
|
|
19
|
+
},
|
|
20
|
+
props.order,
|
|
21
|
+
'ray',
|
|
22
|
+
)
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<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.mul(c).sub(ray.y.mul(s)), ray.x.mul(s).add(ray.y.mul(c)), ray.z)
|
|
19
|
+
},
|
|
20
|
+
props.order,
|
|
21
|
+
'ray',
|
|
22
|
+
)
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<template><!-- --></template>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import { uniform, cos, sin, vec3 } from 'three/tsl'
|
|
4
|
+
|
|
5
|
+
const props = withDefaults(defineProps<{
|
|
6
|
+
/** Yaw offset in radians (horizontal look) */
|
|
7
|
+
yaw?: number
|
|
8
|
+
/** Pitch offset in radians (vertical tilt) */
|
|
9
|
+
pitch?: number
|
|
10
|
+
/** Roll offset in radians */
|
|
11
|
+
roll?: number
|
|
12
|
+
order?: number
|
|
13
|
+
}>(), { yaw: 0, pitch: 0, roll: 0, order: 0 })
|
|
14
|
+
|
|
15
|
+
const yawNode = uniform(props.yaw)
|
|
16
|
+
const pitchNode = uniform(props.pitch)
|
|
17
|
+
const rollNode = uniform(props.roll)
|
|
18
|
+
watch(() => props.yaw, v => { yawNode.value = v })
|
|
19
|
+
watch(() => props.pitch, v => { pitchNode.value = v })
|
|
20
|
+
watch(() => props.roll, v => { rollNode.value = v })
|
|
21
|
+
|
|
22
|
+
useShaderStage(
|
|
23
|
+
(ray) => {
|
|
24
|
+
// Yaw (Y)
|
|
25
|
+
const cy = cos(yawNode); const sy = sin(yawNode)
|
|
26
|
+
const r1 = vec3(ray.x.mul(cy).add(ray.z.mul(sy)), ray.y, ray.z.mul(cy).sub(ray.x.mul(sy)))
|
|
27
|
+
|
|
28
|
+
// Pitch (X)
|
|
29
|
+
const cp = cos(pitchNode); const sp = sin(pitchNode)
|
|
30
|
+
const r2 = vec3(r1.x, r1.y.mul(cp).sub(r1.z.mul(sp)), r1.y.mul(sp).add(r1.z.mul(cp)))
|
|
31
|
+
|
|
32
|
+
// Roll (Z)
|
|
33
|
+
const cr = cos(rollNode); const sr = sin(rollNode)
|
|
34
|
+
return vec3(r2.x.mul(cr).sub(r2.y.mul(sr)), r2.x.mul(sr).add(r2.y.mul(cr)), r2.z)
|
|
35
|
+
},
|
|
36
|
+
props.order,
|
|
37
|
+
'ray',
|
|
38
|
+
)
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
<template><!-- --></template>
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import { Color, Vector3 } from 'three'
|
|
4
|
+
import { Fn, uniform, time, Loop, If, Break, vec3, vec4, float, clamp, mix, sin, cos, abs } from 'three/tsl'
|
|
5
|
+
|
|
6
|
+
const props = withDefaults(defineProps<{
|
|
7
|
+
/** Tunnel inner radius */
|
|
8
|
+
radius?: number
|
|
9
|
+
/** How fast the camera flies forward */
|
|
10
|
+
speed?: number
|
|
11
|
+
/** Wall colour A */
|
|
12
|
+
colorA?: string
|
|
13
|
+
/** Wall colour B */
|
|
14
|
+
colorB?: string
|
|
15
|
+
/** Number of march steps (fixed at shader compile) */
|
|
16
|
+
steps?: number
|
|
17
|
+
order?: number
|
|
18
|
+
}>(), {
|
|
19
|
+
radius: 0.8,
|
|
20
|
+
speed: 1,
|
|
21
|
+
colorA: '#1a0a3a',
|
|
22
|
+
colorB: '#ff4488',
|
|
23
|
+
steps: 64,
|
|
24
|
+
order: 0,
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
const radiusNode = uniform(props.radius)
|
|
28
|
+
const speedNode = uniform(props.speed)
|
|
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
|
+
const colorANode = toVec3Node(props.colorA)
|
|
35
|
+
const colorBNode = toVec3Node(props.colorB)
|
|
36
|
+
|
|
37
|
+
watch(() => props.radius, v => { radiusNode.value = v })
|
|
38
|
+
watch(() => props.speed, v => { speedNode.value = v })
|
|
39
|
+
watch(() => props.colorA, v => { const c = new Color(v); colorANode.value.set(c.r, c.g, c.b) })
|
|
40
|
+
watch(() => props.colorB, v => { const c = new Color(v); colorBNode.value.set(c.r, c.g, c.b) })
|
|
41
|
+
|
|
42
|
+
const pipeline = useShaderPipelineContext()
|
|
43
|
+
|
|
44
|
+
// Fn defined once at setup — Loop/If/Break/toVar/addAssign require a Fn() stack at compile time
|
|
45
|
+
const raymarchFn = Fn(([ray]) => {
|
|
46
|
+
// Three.js calls Fn bodies with null args during type-inference — bail out safely
|
|
47
|
+
if (!ray) return vec4(0, 0, 0, 0)
|
|
48
|
+
|
|
49
|
+
// Camera flies forward along Z
|
|
50
|
+
const camZ = time.mul(speedNode)
|
|
51
|
+
const ro = vec3(float(0), float(0), camZ)
|
|
52
|
+
const rd = ray.normalize()
|
|
53
|
+
|
|
54
|
+
const t = float(0).toVar()
|
|
55
|
+
const colour = vec3(0, 0, 0).toVar()
|
|
56
|
+
const hit = float(0).toVar()
|
|
57
|
+
|
|
58
|
+
Loop(props.steps, () => {
|
|
59
|
+
const p = ro.add(rd.mul(t))
|
|
60
|
+
|
|
61
|
+
// Tunnel SDF: cylinder with twisted walls
|
|
62
|
+
const twist = sin(p.z.mul(0.3).add(camZ.mul(0.1))).mul(0.15)
|
|
63
|
+
const d = p.xy.add(vec3(twist, twist, float(0)).xy).length().sub(radiusNode)
|
|
64
|
+
|
|
65
|
+
If(d.lessThan(float(0.001)), () => {
|
|
66
|
+
// Pattern on wall: mix colours by angle around tunnel
|
|
67
|
+
const angle = p.y.atan(p.x).mul(0.5).add(0.5)
|
|
68
|
+
const stripe = sin(p.z.mul(4.0).add(time)).mul(0.5).add(0.5)
|
|
69
|
+
const band = mix(colorANode, colorBNode, clamp(angle.add(stripe.mul(0.3)), 0, 1))
|
|
70
|
+
colour.assign(band)
|
|
71
|
+
hit.assign(float(1))
|
|
72
|
+
Break()
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
t.addAssign(abs(d).max(float(0.01)))
|
|
76
|
+
|
|
77
|
+
If(t.greaterThan(float(20.0)), () => { Break() })
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
// Fog out the far end of the tunnel
|
|
81
|
+
const fog = clamp(float(1).sub(t.div(20.0)), 0, 1)
|
|
82
|
+
const finalColour = colour.mul(fog).mul(hit)
|
|
83
|
+
|
|
84
|
+
return vec4(finalColour, hit)
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
useShaderStage(
|
|
88
|
+
() => {
|
|
89
|
+
// Fall back to a simple perspective ray from UV when no ray node is set
|
|
90
|
+
const provided = pipeline.rayNode.value
|
|
91
|
+
const uvc = pipeline.uvNode.value
|
|
92
|
+
// Use +1 for Z so the ray points forward into the tunnel (matching Pipeline.client.vue screenRayNode)
|
|
93
|
+
const ray = provided ?? (uvc ? vec3(uvc.sub(0.5).mul(2).x, uvc.sub(0.5).mul(2).y, float(1)) : null)
|
|
94
|
+
if (!ray) return vec4(0, 0, 0, 0)
|
|
95
|
+
return raymarchFn([ray])
|
|
96
|
+
},
|
|
97
|
+
props.order,
|
|
98
|
+
)
|
|
99
|
+
</script>
|
|
100
|
+
|
|
101
|
+
<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 { roundedRect } from '../../shaders/common/shapes'
|
|
6
|
+
|
|
7
|
+
const props = withDefaults(defineProps<{
|
|
8
|
+
colorA?: string
|
|
9
|
+
colorB?: string
|
|
10
|
+
width?: number
|
|
11
|
+
height?: number
|
|
12
|
+
cornerRadius?: number
|
|
13
|
+
softness?: number
|
|
14
|
+
order?: number
|
|
15
|
+
}>(), { colorA: '#000000', colorB: '#ffffff', width: 0.6, height: 0.4, cornerRadius: 0.05, softness: 0.01, order: 0 })
|
|
16
|
+
|
|
17
|
+
function toVec3Node(hex: string) {
|
|
18
|
+
const c = new Color(hex)
|
|
19
|
+
return uniform(new Vector3(c.r, c.g, c.b))
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const colorANode = toVec3Node(props.colorA)
|
|
23
|
+
const colorBNode = toVec3Node(props.colorB)
|
|
24
|
+
const widthNode = uniform(props.width)
|
|
25
|
+
const heightNode = uniform(props.height)
|
|
26
|
+
const cornerNode = uniform(props.cornerRadius)
|
|
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.width, v => { widthNode.value = v })
|
|
31
|
+
watch(() => props.height, v => { heightNode.value = v })
|
|
32
|
+
watch(() => props.cornerRadius, v => { cornerNode.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 = roundedRect(uv, [0.5, 0.5], widthNode, cornerNode, softnessNode)
|
|
41
|
+
return vec4(mix(colorANode, colorBNode, mask), float(1))
|
|
42
|
+
},
|
|
43
|
+
props.order,
|
|
44
|
+
)
|
|
45
|
+
</script>
|
|
46
|
+
|
|
47
|
+
<template><!-- --></template>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import { vec4 } from 'three/tsl'
|
|
4
|
+
import { reinhardTonemap } from '../../shaders/common/tonemapping'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Simple Reinhard tone mapping: col / (col + 1).
|
|
8
|
+
* Compresses HDR values with no hard clip — highlights desaturate toward white.
|
|
9
|
+
*/
|
|
10
|
+
const { order = 0 } = defineProps<{ order?: number }>()
|
|
11
|
+
|
|
12
|
+
useShaderStage(
|
|
13
|
+
(prev) => vec4(reinhardTonemap(prev.xyz), prev.w),
|
|
14
|
+
order,
|
|
15
|
+
)
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
<template><!-- --></template>
|
|
@@ -0,0 +1,41 @@
|
|
|
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 { ridgedFbm2d } from '../../shaders/common/noise'
|
|
6
|
+
|
|
7
|
+
const props = withDefaults(defineProps<{
|
|
8
|
+
colorA?: string
|
|
9
|
+
colorB?: string
|
|
10
|
+
scale?: number
|
|
11
|
+
speed?: number
|
|
12
|
+
order?: number
|
|
13
|
+
}>(), { colorA: '#000000', colorB: '#ffffff', scale: 2, speed: 0.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 colorANode = toVec3Node(props.colorA)
|
|
21
|
+
const colorBNode = toVec3Node(props.colorB)
|
|
22
|
+
const scaleNode = uniform(props.scale)
|
|
23
|
+
const speedNode = uniform(props.speed)
|
|
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.scale, v => { scaleNode.value = v })
|
|
27
|
+
watch(() => props.speed, v => { speedNode.value = v })
|
|
28
|
+
|
|
29
|
+
const pipeline = useShaderPipelineContext()
|
|
30
|
+
|
|
31
|
+
useShaderStage(
|
|
32
|
+
() => {
|
|
33
|
+
const uv = pipeline.uvNode.value
|
|
34
|
+
const n = ridgedFbm2d(uv.mul(scaleNode).add(time.mul(speedNode)))
|
|
35
|
+
return vec4(mix(colorANode, colorBNode, n), float(1))
|
|
36
|
+
},
|
|
37
|
+
props.order,
|
|
38
|
+
)
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
<template><!-- --></template>
|
|
@@ -0,0 +1,44 @@
|
|
|
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 { ring } from '../../shaders/common/shapes'
|
|
6
|
+
|
|
7
|
+
const props = withDefaults(defineProps<{
|
|
8
|
+
colorA?: string
|
|
9
|
+
colorB?: string
|
|
10
|
+
innerRadius?: number
|
|
11
|
+
outerRadius?: number
|
|
12
|
+
softness?: number
|
|
13
|
+
order?: number
|
|
14
|
+
}>(), { colorA: '#000000', colorB: '#ffffff', innerRadius: 0.25, outerRadius: 0.4, softness: 0.01, order: 0 })
|
|
15
|
+
|
|
16
|
+
function toVec3Node(hex: string) {
|
|
17
|
+
const c = new Color(hex)
|
|
18
|
+
return uniform(new Vector3(c.r, c.g, c.b))
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const colorANode = toVec3Node(props.colorA)
|
|
22
|
+
const colorBNode = toVec3Node(props.colorB)
|
|
23
|
+
const innerNode = uniform(props.innerRadius)
|
|
24
|
+
const outerNode = uniform(props.outerRadius)
|
|
25
|
+
const softnessNode = uniform(props.softness)
|
|
26
|
+
watch(() => props.colorA, v => { const c = new Color(v); colorANode.value.set(c.r, c.g, c.b) })
|
|
27
|
+
watch(() => props.colorB, v => { const c = new Color(v); colorBNode.value.set(c.r, c.g, c.b) })
|
|
28
|
+
watch(() => props.innerRadius, v => { innerNode.value = v })
|
|
29
|
+
watch(() => props.outerRadius, v => { outerNode.value = v })
|
|
30
|
+
watch(() => props.softness, v => { softnessNode.value = v })
|
|
31
|
+
|
|
32
|
+
const pipeline = useShaderPipelineContext()
|
|
33
|
+
|
|
34
|
+
useShaderStage(
|
|
35
|
+
() => {
|
|
36
|
+
const uv = pipeline.uvNode.value
|
|
37
|
+
const mask = ring(uv, [0.5, 0.5], innerNode, outerNode, softnessNode)
|
|
38
|
+
return vec4(mix(colorANode, colorBNode, mask), float(1))
|
|
39
|
+
},
|
|
40
|
+
props.order,
|
|
41
|
+
)
|
|
42
|
+
</script>
|
|
43
|
+
|
|
44
|
+
<template><!-- --></template>
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import { uniform, vec4, float, abs } from 'three/tsl'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Accumulates ring-shaped SDF fields into a single float mask.
|
|
7
|
+
* Each ring: abs(length(uv + offset) - radius) * scale, then summed.
|
|
8
|
+
* Outputs a grayscale vec4 for consumption by CosinePalette (scalarSource: 'prev')
|
|
9
|
+
* or SDFColourMask.
|
|
10
|
+
*
|
|
11
|
+
* The flare8/flare9 pattern. Includes an optional radial vignette term.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* <RingField :order="0" :ring-radius="0.3" :ring-count="3" />
|
|
15
|
+
* <CosinePalette :order="1" scalar-source="prev" />
|
|
16
|
+
*/
|
|
17
|
+
const props = withDefaults(defineProps<{
|
|
18
|
+
/** Radius of the primary ring */
|
|
19
|
+
ringRadius?: number
|
|
20
|
+
/** Number of rings (stacked with equidistant offsets) */
|
|
21
|
+
ringCount?: number
|
|
22
|
+
/** Spacing between stacked rings */
|
|
23
|
+
ringSpread?: number
|
|
24
|
+
/** Sharpness multiplier applied per ring */
|
|
25
|
+
ringScale?: number
|
|
26
|
+
/** Vignette: oneMinus(length(uv * vignetteScale)) — 0 = disabled */
|
|
27
|
+
vignetteScale?: number
|
|
28
|
+
order?: number
|
|
29
|
+
}>(), { ringRadius: 0.3, ringCount: 1, ringSpread: 0.15, ringScale: 4, vignetteScale: 0.8, order: 0 })
|
|
30
|
+
|
|
31
|
+
const ringRadiusNode = uniform(props.ringRadius)
|
|
32
|
+
const ringSpreadNode = uniform(props.ringSpread)
|
|
33
|
+
const ringScaleNode = uniform(props.ringScale)
|
|
34
|
+
const vignetteScaleNode = uniform(props.vignetteScale)
|
|
35
|
+
watch(() => props.ringRadius, v => { ringRadiusNode.value = v })
|
|
36
|
+
watch(() => props.ringSpread, v => { ringSpreadNode.value = v })
|
|
37
|
+
watch(() => props.ringScale, v => { ringScaleNode.value = v })
|
|
38
|
+
watch(() => props.vignetteScale, v => { vignetteScaleNode.value = v })
|
|
39
|
+
|
|
40
|
+
const pipeline = useShaderPipelineContext()
|
|
41
|
+
|
|
42
|
+
useShaderStage(
|
|
43
|
+
() => {
|
|
44
|
+
const uvCurrent = pipeline.uvNode.value
|
|
45
|
+
const centered = uvCurrent.sub(0.5)
|
|
46
|
+
|
|
47
|
+
// Accumulate rings at evenly-spaced radii
|
|
48
|
+
let acc = float(0)
|
|
49
|
+
for (let i = 0; i < props.ringCount; i++) {
|
|
50
|
+
const offset = ringSpreadNode.mul(float(i - (props.ringCount - 1) / 2))
|
|
51
|
+
const r = ringRadiusNode.add(offset)
|
|
52
|
+
const d = abs(centered.length().sub(r)).mul(ringScaleNode).oneMinus().max(float(0))
|
|
53
|
+
acc = acc.add(d)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Optional vignette term
|
|
57
|
+
if (props.vignetteScale > 0) {
|
|
58
|
+
const vignette = float(1).sub(centered.mul(vignetteScaleNode).length()).max(float(0))
|
|
59
|
+
acc = acc.add(vignette)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const t = acc.div(float(props.ringCount)).min(float(1))
|
|
63
|
+
return vec4(t, t, t, float(1))
|
|
64
|
+
},
|
|
65
|
+
props.order,
|
|
66
|
+
)
|
|
67
|
+
</script>
|
|
68
|
+
|
|
69
|
+
<template><!-- --></template>
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import { clamp, floor, mix, time, uniform, vec3, vec4 } from 'three/tsl'
|
|
4
|
+
import { grain } from '../../shaders/common/grain'
|
|
5
|
+
import { blendOverlay, blendScreen, blendSoftLight } from '../../shaders/common/blend'
|
|
6
|
+
|
|
7
|
+
type GrainBlendMode = 'add' | 'sub' | 'screen' | 'overlay' | 'soft-light'
|
|
8
|
+
|
|
9
|
+
const props = withDefaults(defineProps<{
|
|
10
|
+
scale?: number
|
|
11
|
+
strength?: number
|
|
12
|
+
opacity?: number
|
|
13
|
+
misregistration?: number
|
|
14
|
+
fps?: number
|
|
15
|
+
blendMode?: GrainBlendMode
|
|
16
|
+
order?: number
|
|
17
|
+
}>(), { scale: 0.6, strength: 0.12, opacity: 1.0, misregistration: 0.003, fps: 8, blendMode: 'add', order: 0 })
|
|
18
|
+
|
|
19
|
+
const scaleNode = uniform(props.scale)
|
|
20
|
+
const strengthNode = uniform(props.strength)
|
|
21
|
+
const opacityNode = uniform(props.opacity)
|
|
22
|
+
const misregNode = uniform(props.misregistration)
|
|
23
|
+
const fpsNode = uniform(props.fps)
|
|
24
|
+
watch(() => props.scale, v => { scaleNode.value = v })
|
|
25
|
+
watch(() => props.strength, v => { strengthNode.value = v })
|
|
26
|
+
watch(() => props.opacity, v => { opacityNode.value = v })
|
|
27
|
+
watch(() => props.misregistration, v => { misregNode.value = v })
|
|
28
|
+
watch(() => props.fps, v => { fpsNode.value = v })
|
|
29
|
+
|
|
30
|
+
const pipeline = useShaderPipelineContext()
|
|
31
|
+
|
|
32
|
+
useShaderStage(
|
|
33
|
+
(prev) => {
|
|
34
|
+
const uv = pipeline.uvNode.value
|
|
35
|
+
const seed = floor(time.mul(fpsNode))
|
|
36
|
+
|
|
37
|
+
const uvR = uv.mul(scaleNode).add(misregNode)
|
|
38
|
+
const uvG = uv.mul(scaleNode)
|
|
39
|
+
const uvB = uv.mul(scaleNode).sub(misregNode)
|
|
40
|
+
|
|
41
|
+
// grain() returns (raw - 0.5) * strength → centred around 0
|
|
42
|
+
const rNoise = grain(uvR, strengthNode, seed)
|
|
43
|
+
const gNoise = grain(uvG, strengthNode, seed.add(17.0))
|
|
44
|
+
const bNoise = grain(uvB, strengthNode, seed.add(31.0))
|
|
45
|
+
const grainVec = vec3(rNoise, gNoise, bNoise)
|
|
46
|
+
|
|
47
|
+
// Lift centred delta back to [0,1] per-channel texture for blend modes
|
|
48
|
+
const rawVec = grainVec.div(strengthNode).add(0.5)
|
|
49
|
+
|
|
50
|
+
const mixFactor = strengthNode.mul(opacityNode)
|
|
51
|
+
let blended
|
|
52
|
+
switch (props.blendMode) {
|
|
53
|
+
case 'sub':
|
|
54
|
+
blended = prev.xyz.sub(grainVec.abs().mul(opacityNode))
|
|
55
|
+
break
|
|
56
|
+
case 'screen':
|
|
57
|
+
blended = mix(prev.xyz, blendScreen(prev.xyz, rawVec), mixFactor)
|
|
58
|
+
break
|
|
59
|
+
case 'overlay':
|
|
60
|
+
blended = mix(prev.xyz, blendOverlay(prev.xyz, rawVec), mixFactor)
|
|
61
|
+
break
|
|
62
|
+
case 'soft-light':
|
|
63
|
+
blended = mix(prev.xyz, blendSoftLight(prev.xyz, rawVec), mixFactor)
|
|
64
|
+
break
|
|
65
|
+
default: // 'add'
|
|
66
|
+
blended = prev.xyz.add(grainVec.mul(opacityNode))
|
|
67
|
+
}
|
|
68
|
+
return vec4(clamp(blended, 0, 1), prev.w)
|
|
69
|
+
},
|
|
70
|
+
props.order,
|
|
71
|
+
)
|
|
72
|
+
</script>
|
|
73
|
+
|
|
74
|
+
<template><!-- --></template>
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import { Color } from 'three'
|
|
4
|
+
import { mix, smoothstep, uniform, vec4 } from 'three/tsl'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Blends two colours along a rotated axis — the core Grainient colour pattern.
|
|
8
|
+
* Projects the current UV onto the rotated axis via (uv * Rot(angle)).x,
|
|
9
|
+
* then uses smoothstep to create the gradient.
|
|
10
|
+
*
|
|
11
|
+
* Stack multiple instances at consecutive orders to layer gradients.
|
|
12
|
+
*/
|
|
13
|
+
const props = withDefaults(defineProps<{
|
|
14
|
+
colorA?: string
|
|
15
|
+
colorB?: string
|
|
16
|
+
/** Rotation angle in degrees */
|
|
17
|
+
angle?: number
|
|
18
|
+
/** Smoothstep lower edge (0 = sharp at centre-left) */
|
|
19
|
+
edge0?: number
|
|
20
|
+
/** Smoothstep upper edge (1 = sharp at centre-right) */
|
|
21
|
+
edge1?: number
|
|
22
|
+
order?: number
|
|
23
|
+
}>(), {
|
|
24
|
+
colorA: '#000000',
|
|
25
|
+
colorB: '#ffffff',
|
|
26
|
+
angle: -5,
|
|
27
|
+
edge0: 0.25,
|
|
28
|
+
edge1: 0.75,
|
|
29
|
+
order: 0,
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
const colorAVal = new Color(props.colorA)
|
|
33
|
+
const colorBVal = new Color(props.colorB)
|
|
34
|
+
const colorANode = uniform(colorAVal)
|
|
35
|
+
const colorBNode = uniform(colorBVal)
|
|
36
|
+
const angleNode = uniform(props.angle * (Math.PI / 180))
|
|
37
|
+
const edge0Node = uniform(props.edge0)
|
|
38
|
+
const edge1Node = uniform(props.edge1)
|
|
39
|
+
|
|
40
|
+
watch(() => props.colorA, v => { colorANode.value.set(v) })
|
|
41
|
+
watch(() => props.colorB, v => { colorBNode.value.set(v) })
|
|
42
|
+
watch(() => props.angle, v => { angleNode.value = v * (Math.PI / 180) })
|
|
43
|
+
watch(() => props.edge0, v => { edge0Node.value = v })
|
|
44
|
+
watch(() => props.edge1, v => { edge1Node.value = v })
|
|
45
|
+
|
|
46
|
+
const { uvNode } = useShaderPipelineContext()
|
|
47
|
+
|
|
48
|
+
useShaderStage(
|
|
49
|
+
(_prev) => {
|
|
50
|
+
const cosA = angleNode.cos()
|
|
51
|
+
const sinA = angleNode.sin()
|
|
52
|
+
// Project UV onto rotated axis, shift to 0-1 range
|
|
53
|
+
const rotatedX = uvNode.value.x.mul(cosA).sub(uvNode.value.y.mul(sinA)).add(0.5)
|
|
54
|
+
const t = smoothstep(edge0Node, edge1Node, rotatedX)
|
|
55
|
+
return vec4(mix(colorANode, colorBNode, t), 1.0)
|
|
56
|
+
},
|
|
57
|
+
props.order,
|
|
58
|
+
)
|
|
59
|
+
</script>
|
|
60
|
+
|
|
61
|
+
<template><!-- --></template>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import { uniform, vec4, clamp, float } from 'three/tsl'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Multiplies RGB by prev.r (treating the previous stage as a grayscale scalar mask).
|
|
7
|
+
* Use after a scalar generator (RingField, ChebyshevNoiseField) and before CosinePalette
|
|
8
|
+
* to apply the `col.mul(t)` phobon pattern.
|
|
9
|
+
*
|
|
10
|
+
* Pipeline: RingField (order 0) → SDFColourMask (order 1) → CosinePalette (order 2, scalarSource: 'prev')
|
|
11
|
+
*/
|
|
12
|
+
const props = withDefaults(defineProps<{
|
|
13
|
+
/** Raise the mask to a power before applying — values > 1 increase contrast */
|
|
14
|
+
power?: number
|
|
15
|
+
/** Clamp the mask to [0, 1] before multiplying */
|
|
16
|
+
clampMask?: boolean
|
|
17
|
+
order?: number
|
|
18
|
+
}>(), { power: 1, clampMask: true, order: 0 })
|
|
19
|
+
|
|
20
|
+
const powerNode = uniform(props.power)
|
|
21
|
+
watch(() => props.power, v => { powerNode.value = v })
|
|
22
|
+
|
|
23
|
+
useShaderStage(
|
|
24
|
+
(prev) => {
|
|
25
|
+
let mask = prev.x.pow(powerNode)
|
|
26
|
+
if (props.clampMask) mask = clamp(mask, float(0), float(1))
|
|
27
|
+
return vec4(prev.xyz.mul(mask), prev.w)
|
|
28
|
+
},
|
|
29
|
+
props.order,
|
|
30
|
+
)
|
|
31
|
+
</script>
|
|
32
|
+
|
|
33
|
+
<template><!-- --></template>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import { uniform, vec4, float } from 'three/tsl'
|
|
4
|
+
|
|
5
|
+
const props = withDefaults(defineProps<{
|
|
6
|
+
/** Scale factor for the radial distance — larger = tighter mask */
|
|
7
|
+
scale?: number
|
|
8
|
+
/** Softness of the mask edge */
|
|
9
|
+
softness?: number
|
|
10
|
+
order?: number
|
|
11
|
+
}>(), { scale: 1.5, softness: 0.2, order: 0 })
|
|
12
|
+
|
|
13
|
+
const scaleNode = uniform(props.scale)
|
|
14
|
+
const softnessNode = uniform(props.softness)
|
|
15
|
+
watch(() => props.scale, v => { scaleNode.value = v })
|
|
16
|
+
watch(() => props.softness, v => { softnessNode.value = v })
|
|
17
|
+
|
|
18
|
+
const pipeline = useShaderPipelineContext()
|
|
19
|
+
|
|
20
|
+
useShaderStage(
|
|
21
|
+
(prev) => {
|
|
22
|
+
const uvCurrent = pipeline.uvNode.value
|
|
23
|
+
const dist = uvCurrent.sub(0.5).mul(scaleNode).length()
|
|
24
|
+
const mask = float(1).sub(dist).sub(softnessNode).max(0).div(float(1).sub(softnessNode))
|
|
25
|
+
return vec4(prev.xyz, prev.w.mul(mask))
|
|
26
|
+
},
|
|
27
|
+
props.order,
|
|
28
|
+
)
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<template><!-- --></template>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import { uniform, vec4, pow, float } from 'three/tsl'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Decodes sRGB to linear light — the inverse of LinearToSRGB.
|
|
7
|
+
* Apply before any physically-based blending or tonemapping.
|
|
8
|
+
* Approximate form: pow(col, 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)), gammaNode), prev.w),
|
|
21
|
+
props.order,
|
|
22
|
+
)
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<template><!-- --></template>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import { uniform, vec4 } from 'three/tsl'
|
|
4
|
+
import { saturate } from '../../shaders/common/blend'
|
|
5
|
+
|
|
6
|
+
const props = withDefaults(defineProps<{
|
|
7
|
+
/** Saturation boost: 0 = unchanged, positive = more saturated */
|
|
8
|
+
amount?: number
|
|
9
|
+
order?: number
|
|
10
|
+
}>(), { amount: 0.5, order: 0 })
|
|
11
|
+
|
|
12
|
+
const amountNode = uniform(props.amount)
|
|
13
|
+
watch(() => props.amount, v => { amountNode.value = v })
|
|
14
|
+
|
|
15
|
+
useShaderStage(
|
|
16
|
+
(prev) => vec4(saturate(prev.xyz, amountNode), prev.w),
|
|
17
|
+
props.order,
|
|
18
|
+
)
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<template><!-- --></template>
|