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.
- 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/package.json +9 -7
|
@@ -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
|
+
/** Chebyshev-distance diamond gradient: max(|x|, |y|) from centre. */
|
|
7
|
+
const props = withDefaults(defineProps<{
|
|
8
|
+
colorA?: string
|
|
9
|
+
colorB?: string
|
|
10
|
+
/** Scale — higher = faster falloff */
|
|
11
|
+
scale?: number
|
|
12
|
+
order?: number
|
|
13
|
+
}>(), { colorA: '#000000', colorB: '#ffffff', scale: 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
|
+
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.scale, v => { scaleNode.value = v })
|
|
26
|
+
|
|
27
|
+
const pipeline = useShaderPipelineContext()
|
|
28
|
+
|
|
29
|
+
useShaderStage(
|
|
30
|
+
() => {
|
|
31
|
+
const uv = pipeline.uvNode.value
|
|
32
|
+
const centered = uv.sub(0.5).abs()
|
|
33
|
+
const t = centered.x.max(centered.y).mul(scaleNode).mul(2).min(float(1))
|
|
34
|
+
return vec4(mix(colorANode, colorBNode, t), float(1))
|
|
35
|
+
},
|
|
36
|
+
props.order,
|
|
37
|
+
)
|
|
38
|
+
</script>
|
|
39
|
+
|
|
40
|
+
<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 { blendDifference } 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, blendDifference(prev.xyz, colorNode), opacityNode), prev.w),
|
|
20
|
+
props.order,
|
|
21
|
+
)
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<template><!-- --></template>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import { Color, Vector3 } from 'three'
|
|
4
|
+
import { uniform, vec4, mix, clamp, float } from 'three/tsl'
|
|
5
|
+
|
|
6
|
+
const props = withDefaults(defineProps<{
|
|
7
|
+
color?: string
|
|
8
|
+
opacity?: number
|
|
9
|
+
order?: number
|
|
10
|
+
}>(), { color: '#808080', opacity: 1, order: 0 })
|
|
11
|
+
|
|
12
|
+
const colorNode = (() => { const c = new Color(props.color); return uniform(new Vector3(c.r, c.g, c.b)) })()
|
|
13
|
+
const opacityNode = uniform(props.opacity)
|
|
14
|
+
watch(() => props.color, v => { const c = new Color(v); colorNode.value.set(c.r, c.g, c.b) })
|
|
15
|
+
watch(() => props.opacity, v => { opacityNode.value = v })
|
|
16
|
+
|
|
17
|
+
useShaderStage(
|
|
18
|
+
(prev) => {
|
|
19
|
+
const divided = clamp(prev.xyz.div(colorNode.max(float(0.001))), float(0), float(1))
|
|
20
|
+
return vec4(mix(prev.xyz, divided, opacityNode), prev.w)
|
|
21
|
+
},
|
|
22
|
+
props.order,
|
|
23
|
+
)
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<template><!-- --></template>
|
|
@@ -0,0 +1,48 @@
|
|
|
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 { domainWarp2D } from '../../shaders/common/noise'
|
|
6
|
+
|
|
7
|
+
const props = withDefaults(defineProps<{
|
|
8
|
+
colorA?: string
|
|
9
|
+
colorB?: string
|
|
10
|
+
scale?: number
|
|
11
|
+
warpStrength?: number
|
|
12
|
+
warpScale?: number
|
|
13
|
+
speed?: number
|
|
14
|
+
order?: number
|
|
15
|
+
}>(), { colorA: '#000000', colorB: '#ffffff', scale: 2, warpStrength: 0.5, warpScale: 2, speed: 0.1, 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 scaleNode = uniform(props.scale)
|
|
25
|
+
const warpStrNode = uniform(props.warpStrength)
|
|
26
|
+
const warpScaleNode = uniform(props.warpScale)
|
|
27
|
+
const speedNode = uniform(props.speed)
|
|
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.scale, v => { scaleNode.value = v })
|
|
31
|
+
watch(() => props.warpStrength, v => { warpStrNode.value = v })
|
|
32
|
+
watch(() => props.warpScale, v => { warpScaleNode.value = v })
|
|
33
|
+
watch(() => props.speed, v => { speedNode.value = v })
|
|
34
|
+
|
|
35
|
+
const pipeline = useShaderPipelineContext()
|
|
36
|
+
|
|
37
|
+
useShaderStage(
|
|
38
|
+
() => {
|
|
39
|
+
const uv = pipeline.uvNode.value
|
|
40
|
+
const animated = uv.add(time.mul(speedNode))
|
|
41
|
+
const n = domainWarp2D(animated.mul(scaleNode), warpStrNode, warpScaleNode).mul(0.5).add(0.5)
|
|
42
|
+
return vec4(mix(colorANode, colorBNode, n), float(1))
|
|
43
|
+
},
|
|
44
|
+
props.order,
|
|
45
|
+
)
|
|
46
|
+
</script>
|
|
47
|
+
|
|
48
|
+
<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 { dots } from '../../shaders/common/shapes'
|
|
6
|
+
|
|
7
|
+
const props = withDefaults(defineProps<{
|
|
8
|
+
colorA?: string
|
|
9
|
+
colorB?: string
|
|
10
|
+
cellSize?: number
|
|
11
|
+
dotRadius?: number
|
|
12
|
+
softness?: number
|
|
13
|
+
order?: number
|
|
14
|
+
}>(), { colorA: '#000000', colorB: '#ffffff', cellSize: 0.08, dotRadius: 0.025, softness: 0.005, 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 cellNode = uniform(props.cellSize)
|
|
24
|
+
const dotNode = uniform(props.dotRadius)
|
|
25
|
+
const softNode = 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.cellSize, v => { cellNode.value = v })
|
|
29
|
+
watch(() => props.dotRadius, v => { dotNode.value = v })
|
|
30
|
+
watch(() => props.softness, v => { softNode.value = v })
|
|
31
|
+
|
|
32
|
+
const pipeline = useShaderPipelineContext()
|
|
33
|
+
|
|
34
|
+
useShaderStage(
|
|
35
|
+
() => {
|
|
36
|
+
const uv = pipeline.uvNode.value
|
|
37
|
+
const mask = dots(uv, cellNode, dotNode, softNode)
|
|
38
|
+
return vec4(mix(colorANode, colorBNode, mask), float(1))
|
|
39
|
+
},
|
|
40
|
+
props.order,
|
|
41
|
+
)
|
|
42
|
+
</script>
|
|
43
|
+
|
|
44
|
+
<template><!-- --></template>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import { Color, Vector3 } from 'three'
|
|
4
|
+
import { uniform, vec4, mix } from 'three/tsl'
|
|
5
|
+
import { luminance } from '../../shaders/common/blend'
|
|
6
|
+
|
|
7
|
+
const props = withDefaults(defineProps<{
|
|
8
|
+
/** Shadow colour (low luminance) */
|
|
9
|
+
shadowColor?: string
|
|
10
|
+
/** Highlight colour (high luminance) */
|
|
11
|
+
highlightColor?: string
|
|
12
|
+
order?: number
|
|
13
|
+
}>(), { shadowColor: '#1a0033', highlightColor: '#ffcc00', 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 shadowNode = toVec3Node(props.shadowColor)
|
|
21
|
+
const highlightNode = toVec3Node(props.highlightColor)
|
|
22
|
+
watch(() => props.shadowColor, v => { const c = new Color(v); shadowNode.value.set(c.r, c.g, c.b) })
|
|
23
|
+
watch(() => props.highlightColor, v => { const c = new Color(v); highlightNode.value.set(c.r, c.g, c.b) })
|
|
24
|
+
|
|
25
|
+
useShaderStage(
|
|
26
|
+
(prev) => {
|
|
27
|
+
const lum = luminance(prev.xyz)
|
|
28
|
+
return vec4(mix(shadowNode, highlightNode, lum), prev.w)
|
|
29
|
+
},
|
|
30
|
+
props.order,
|
|
31
|
+
)
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<template><!-- --></template>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import { Color, Vector3 } from 'three'
|
|
4
|
+
import { uniform, vec4, mix } from 'three/tsl'
|
|
5
|
+
import { blendExclusion } from '../../shaders/common/blend'
|
|
6
|
+
|
|
7
|
+
const props = withDefaults(defineProps<{
|
|
8
|
+
color?: string
|
|
9
|
+
opacity?: number
|
|
10
|
+
order?: number
|
|
11
|
+
}>(), { color: '#ffffff', opacity: 1, order: 0 })
|
|
12
|
+
|
|
13
|
+
const colorNode = (() => { const c = new Color(props.color); return uniform(new Vector3(c.r, c.g, c.b)) })()
|
|
14
|
+
const opacityNode = uniform(props.opacity)
|
|
15
|
+
watch(() => props.color, v => { const c = new Color(v); colorNode.value.set(c.r, c.g, c.b) })
|
|
16
|
+
watch(() => props.opacity, v => { opacityNode.value = v })
|
|
17
|
+
|
|
18
|
+
useShaderStage(
|
|
19
|
+
(prev) => vec4(mix(prev.xyz, blendExclusion(prev.xyz, colorNode), opacityNode), prev.w),
|
|
20
|
+
props.order,
|
|
21
|
+
)
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<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 } from 'three/tsl'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Height-based exponential fog: exp2(-ray.y * density).
|
|
8
|
+
* Blends prev colour toward fogColor as the ray approaches the horizon.
|
|
9
|
+
* Pairs naturally with SkyAtmosphere — place before it so terrain gets fog too.
|
|
10
|
+
*/
|
|
11
|
+
const props = withDefaults(defineProps<{
|
|
12
|
+
/** Fog colour */
|
|
13
|
+
fogColor?: string
|
|
14
|
+
/** Controls how quickly fog builds near the horizon — higher = thicker */
|
|
15
|
+
density?: number
|
|
16
|
+
/** Clamp the minimum ray Y used for fog (prevents underground fog) */
|
|
17
|
+
horizonBias?: number
|
|
18
|
+
order?: number
|
|
19
|
+
}>(), { fogColor: '#c8d8e8', density: 4, horizonBias: 0, order: 0 })
|
|
20
|
+
|
|
21
|
+
function toVec3Node(hex: string) {
|
|
22
|
+
const c = new Color(hex)
|
|
23
|
+
return uniform(new Vector3(c.r, c.g, c.b))
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const fogColorNode = toVec3Node(props.fogColor)
|
|
27
|
+
const densityNode = uniform(props.density)
|
|
28
|
+
const horizonBiasNode = uniform(props.horizonBias)
|
|
29
|
+
watch(() => props.fogColor, v => { const c = new Color(v); fogColorNode.value.set(c.r, c.g, c.b) })
|
|
30
|
+
watch(() => props.density, v => { densityNode.value = v })
|
|
31
|
+
watch(() => props.horizonBias, v => { horizonBiasNode.value = v })
|
|
32
|
+
|
|
33
|
+
const pipeline = useShaderPipelineContext()
|
|
34
|
+
|
|
35
|
+
useShaderStage(
|
|
36
|
+
(prev) => {
|
|
37
|
+
const ray = pipeline.rayNode.value
|
|
38
|
+
const h = ray ? ray.y.max(horizonBiasNode) : horizonBiasNode
|
|
39
|
+
const fogFactor = h.mul(densityNode).negate().exp2()
|
|
40
|
+
return vec4(mix(fogColorNode, prev.xyz, fogFactor), prev.w)
|
|
41
|
+
},
|
|
42
|
+
props.order,
|
|
43
|
+
)
|
|
44
|
+
</script>
|
|
45
|
+
|
|
46
|
+
<template><!-- --></template>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import { uniform, vec4, pow, float } from 'three/tsl'
|
|
4
|
+
|
|
5
|
+
const props = withDefaults(defineProps<{
|
|
6
|
+
/** Exposure in stops: 0 = unchanged, +1 = 2× brighter, -1 = 2× darker */
|
|
7
|
+
stops?: number
|
|
8
|
+
order?: number
|
|
9
|
+
}>(), { stops: 0, order: 0 })
|
|
10
|
+
|
|
11
|
+
const stopsNode = uniform(props.stops)
|
|
12
|
+
watch(() => props.stops, v => { stopsNode.value = v })
|
|
13
|
+
|
|
14
|
+
useShaderStage(
|
|
15
|
+
(prev) => {
|
|
16
|
+
const scale = pow(float(2), stopsNode)
|
|
17
|
+
return vec4(prev.xyz.mul(scale), prev.w)
|
|
18
|
+
},
|
|
19
|
+
props.order,
|
|
20
|
+
)
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<template><!-- --></template>
|
|
@@ -0,0 +1,50 @@
|
|
|
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 { fbm2D } from '../../shaders/common/noise'
|
|
6
|
+
|
|
7
|
+
const props = withDefaults(defineProps<{
|
|
8
|
+
colorA?: string
|
|
9
|
+
colorB?: string
|
|
10
|
+
scale?: number
|
|
11
|
+
octaves?: number
|
|
12
|
+
animated?: boolean
|
|
13
|
+
speed?: number
|
|
14
|
+
order?: number
|
|
15
|
+
}>(), {
|
|
16
|
+
colorA: '#000000',
|
|
17
|
+
colorB: '#ffffff',
|
|
18
|
+
scale: 3,
|
|
19
|
+
octaves: 5,
|
|
20
|
+
animated: true,
|
|
21
|
+
speed: 0.15,
|
|
22
|
+
order: 0,
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
const colorAVal = new Color(props.colorA)
|
|
26
|
+
const colorBVal = new Color(props.colorB)
|
|
27
|
+
const colorANode = uniform(colorAVal)
|
|
28
|
+
const colorBNode = uniform(colorBVal)
|
|
29
|
+
const scaleNode = uniform(props.scale)
|
|
30
|
+
const speedNode = uniform(props.speed)
|
|
31
|
+
|
|
32
|
+
watch(() => props.colorA, v => { colorANode.value.set(v) })
|
|
33
|
+
watch(() => props.colorB, v => { colorBNode.value.set(v) })
|
|
34
|
+
watch(() => props.scale, v => { scaleNode.value = v })
|
|
35
|
+
watch(() => props.speed, v => { speedNode.value = v })
|
|
36
|
+
|
|
37
|
+
const { uvNode } = useShaderPipelineContext()
|
|
38
|
+
|
|
39
|
+
useShaderStage(
|
|
40
|
+
(_prev) => {
|
|
41
|
+
const offset = props.animated ? time.mul(speedNode) : float(0)
|
|
42
|
+
const input = uvNode.value.mul(scaleNode).add(vec2(offset, 0))
|
|
43
|
+
const n = fbm2D(input, { octaves: props.octaves }).mul(0.5).add(0.5)
|
|
44
|
+
return vec4(mix(colorANode, colorBNode, n), 1.0)
|
|
45
|
+
},
|
|
46
|
+
props.order,
|
|
47
|
+
)
|
|
48
|
+
</script>
|
|
49
|
+
|
|
50
|
+
<template><!-- --></template>
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import { Color, Vector2, Vector3 } from 'three'
|
|
4
|
+
import { uniform, vec4, vec2, mix, smoothstep, float } from 'three/tsl'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Orange/warm light leak emanating from a screen corner.
|
|
8
|
+
* Additive over-exposure effect — common in analogue film.
|
|
9
|
+
*/
|
|
10
|
+
const props = withDefaults(defineProps<{
|
|
11
|
+
/** Light leak colour */
|
|
12
|
+
color?: string
|
|
13
|
+
/** Corner origin [0,1] — default top-left */
|
|
14
|
+
origin?: [number, number]
|
|
15
|
+
/** Reach of the leak */
|
|
16
|
+
radius?: number
|
|
17
|
+
/** Peak brightness */
|
|
18
|
+
intensity?: number
|
|
19
|
+
order?: number
|
|
20
|
+
}>(), { color: '#ff8822', origin: () => [0, 1], radius: 0.7, intensity: 0.5, order: 0 })
|
|
21
|
+
|
|
22
|
+
function toVec3Node(hex: string) {
|
|
23
|
+
const c = new Color(hex)
|
|
24
|
+
return uniform(new Vector3(c.r, c.g, c.b))
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const colorNode = toVec3Node(props.color)
|
|
28
|
+
const originNode = uniform(new Vector2(...props.origin))
|
|
29
|
+
const radiusNode = uniform(props.radius)
|
|
30
|
+
const intensityNode = uniform(props.intensity)
|
|
31
|
+
watch(() => props.color, v => { const c = new Color(v); colorNode.value.set(c.r, c.g, c.b) })
|
|
32
|
+
watch(() => props.origin, ([x, y]) => { originNode.value.set(x, y) })
|
|
33
|
+
watch(() => props.radius, v => { radiusNode.value = v })
|
|
34
|
+
watch(() => props.intensity, v => { intensityNode.value = v })
|
|
35
|
+
|
|
36
|
+
const pipeline = useShaderPipelineContext()
|
|
37
|
+
|
|
38
|
+
useShaderStage(
|
|
39
|
+
(prev) => {
|
|
40
|
+
const uv = pipeline.uvNode.value
|
|
41
|
+
const dist = uv.sub(vec2(originNode.x, originNode.y)).length()
|
|
42
|
+
const leak = smoothstep(radiusNode, float(0), dist).mul(intensityNode)
|
|
43
|
+
return vec4(prev.xyz.add(colorNode.mul(leak)), prev.w)
|
|
44
|
+
},
|
|
45
|
+
props.order,
|
|
46
|
+
)
|
|
47
|
+
</script>
|
|
48
|
+
|
|
49
|
+
<template><!-- --></template>
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import { clamp, float, fract, mix, sin, time, uniform, vec2, vec4 } from 'three/tsl'
|
|
4
|
+
import { blendOverlay, blendScreen, blendSoftLight } from '../../shaders/common/blend'
|
|
5
|
+
|
|
6
|
+
type GrainBlendMode = 'add' | 'sub' | 'screen' | 'overlay' | 'soft-light'
|
|
7
|
+
|
|
8
|
+
const props = withDefaults(defineProps<{
|
|
9
|
+
/** Grain intensity — amplitude of the noise effect */
|
|
10
|
+
intensity?: number
|
|
11
|
+
/** Blend opacity — how strongly grain mixes into the output */
|
|
12
|
+
opacity?: number
|
|
13
|
+
/** UV scale — higher = finer dots, lower = coarser */
|
|
14
|
+
size?: number
|
|
15
|
+
fps?: number
|
|
16
|
+
blendMode?: GrainBlendMode
|
|
17
|
+
order?: number
|
|
18
|
+
}>(), { intensity: 0.06, opacity: 1.0, size: 1.0, fps: 24, blendMode: 'sub', order: 0 })
|
|
19
|
+
|
|
20
|
+
const intensityNode = uniform(props.intensity)
|
|
21
|
+
const opacityNode = uniform(props.opacity)
|
|
22
|
+
const sizeNode = uniform(props.size)
|
|
23
|
+
const fpsNode = uniform(props.fps)
|
|
24
|
+
watch(() => props.intensity, v => { intensityNode.value = v })
|
|
25
|
+
watch(() => props.opacity, v => { opacityNode.value = v })
|
|
26
|
+
watch(() => props.size, v => { sizeNode.value = v })
|
|
27
|
+
watch(() => props.fps, v => { fpsNode.value = v })
|
|
28
|
+
|
|
29
|
+
const pipeline = useShaderPipelineContext()
|
|
30
|
+
|
|
31
|
+
useShaderStage(
|
|
32
|
+
(prev) => {
|
|
33
|
+
const uvScaled = pipeline.uvNode.value.mul(sizeNode)
|
|
34
|
+
const t = time.mul(fpsNode).floor().div(fpsNode)
|
|
35
|
+
|
|
36
|
+
// Two-pass hash for coarser, more organic texture
|
|
37
|
+
const k1 = vec2(127.1, 311.7)
|
|
38
|
+
const k2 = vec2(269.5, 183.3)
|
|
39
|
+
const p = uvScaled.add(t)
|
|
40
|
+
const h1 = p.dot(k1).sin().mul(43758.5453).fract()
|
|
41
|
+
const h2 = p.add(t.mul(0.3)).dot(k2).sin().mul(43758.5453).fract()
|
|
42
|
+
// Raw [0,1] noise from vector length, normalised by max possible (√2)
|
|
43
|
+
const raw = vec2(h1, h2).length().mul(float(0.7071))
|
|
44
|
+
|
|
45
|
+
const mixFactor = intensityNode.mul(opacityNode)
|
|
46
|
+
let blended
|
|
47
|
+
switch (props.blendMode) {
|
|
48
|
+
case 'add':
|
|
49
|
+
blended = prev.xyz.add(raw.sub(0.5).mul(intensityNode).mul(opacityNode))
|
|
50
|
+
break
|
|
51
|
+
case 'screen':
|
|
52
|
+
blended = mix(prev.xyz, blendScreen(prev.xyz, raw), mixFactor)
|
|
53
|
+
break
|
|
54
|
+
case 'overlay':
|
|
55
|
+
blended = mix(prev.xyz, blendOverlay(prev.xyz, raw), mixFactor)
|
|
56
|
+
break
|
|
57
|
+
case 'soft-light':
|
|
58
|
+
blended = mix(prev.xyz, blendSoftLight(prev.xyz, raw), mixFactor)
|
|
59
|
+
break
|
|
60
|
+
default: // 'sub' — original darkening behaviour
|
|
61
|
+
blended = prev.xyz.sub(raw.mul(intensityNode).mul(opacityNode))
|
|
62
|
+
}
|
|
63
|
+
return vec4(clamp(blended, 0, 1), prev.w)
|
|
64
|
+
},
|
|
65
|
+
props.order,
|
|
66
|
+
)
|
|
67
|
+
</script>
|
|
68
|
+
|
|
69
|
+
<template><!-- --></template>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import { uniform, float, atan, vec3 } from 'three/tsl'
|
|
4
|
+
|
|
5
|
+
const props = withDefaults(defineProps<{
|
|
6
|
+
/**
|
|
7
|
+
* Field-of-view in radians for the fisheye projection.
|
|
8
|
+
* π = 180° hemisphere, π*2 = full sphere.
|
|
9
|
+
*/
|
|
10
|
+
fov?: number
|
|
11
|
+
order?: number
|
|
12
|
+
}>(), { fov: Math.PI, order: 0 })
|
|
13
|
+
|
|
14
|
+
const fovNode = uniform(props.fov)
|
|
15
|
+
watch(() => props.fov, v => { fovNode.value = v })
|
|
16
|
+
|
|
17
|
+
useShaderStage(
|
|
18
|
+
(ray) => {
|
|
19
|
+
// Screen-space xy from the linear ray (z = 1 focal plane)
|
|
20
|
+
const screen = vec3(ray.x, ray.y, float(0))
|
|
21
|
+
const r = screen.length()
|
|
22
|
+
|
|
23
|
+
// Fisheye: map linear distance → angle on sphere
|
|
24
|
+
const theta = atan(r).mul(fovNode).div(Math.PI * 0.5)
|
|
25
|
+
const phi = screen.y.atan(screen.x)
|
|
26
|
+
|
|
27
|
+
const sinTheta = theta.sin()
|
|
28
|
+
return vec3(phi.cos().mul(sinTheta), phi.sin().mul(sinTheta), theta.cos()).normalize()
|
|
29
|
+
},
|
|
30
|
+
props.order,
|
|
31
|
+
'ray',
|
|
32
|
+
)
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
<template><!-- --></template>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import { Color, Vector3 } from 'three'
|
|
4
|
+
import { uniform, time, vec3, vec4, mix, clamp, float } from 'three/tsl'
|
|
5
|
+
import { fbm2D } from '../../shaders/common/noise'
|
|
6
|
+
|
|
7
|
+
const props = withDefaults(defineProps<{
|
|
8
|
+
/** Base flame colour (cool, inner) */
|
|
9
|
+
colorBase?: string
|
|
10
|
+
/** Tip flame colour (hot, outer) */
|
|
11
|
+
colorTip?: string
|
|
12
|
+
/** Flame height scale */
|
|
13
|
+
scale?: number
|
|
14
|
+
/** Rise speed */
|
|
15
|
+
speed?: number
|
|
16
|
+
order?: number
|
|
17
|
+
}>(), { colorBase: '#ffcc00', colorTip: '#ff2200', scale: 3, speed: 1.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 colorBaseNode = toVec3Node(props.colorBase)
|
|
25
|
+
const colorTipNode = toVec3Node(props.colorTip)
|
|
26
|
+
const scaleNode = uniform(props.scale)
|
|
27
|
+
const speedNode = uniform(props.speed)
|
|
28
|
+
watch(() => props.colorBase, v => { const c = new Color(v); colorBaseNode.value.set(c.r, c.g, c.b) })
|
|
29
|
+
watch(() => props.colorTip, v => { const c = new Color(v); colorTipNode.value.set(c.r, c.g, c.b) })
|
|
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
|
+
() => {
|
|
37
|
+
const uv = pipeline.uvNode.value
|
|
38
|
+
// Animate upward by subtracting time from Y
|
|
39
|
+
const pos = uv.mul(scaleNode).sub(time.mul(speedNode))
|
|
40
|
+
const n = fbm2D(pos).mul(0.5).add(0.5)
|
|
41
|
+
// Heat = noise * (1 - uv.y): flames die out at the top
|
|
42
|
+
const heat = clamp(n.mul(float(1).sub(uv.y).mul(1.5)), float(0), float(1))
|
|
43
|
+
// Black background → tip colour → base colour
|
|
44
|
+
const fireColor = mix(vec3(0, 0, 0), mix(colorTipNode, colorBaseNode, heat), heat)
|
|
45
|
+
return vec4(fireColor, heat)
|
|
46
|
+
},
|
|
47
|
+
props.order,
|
|
48
|
+
)
|
|
49
|
+
</script>
|
|
50
|
+
|
|
51
|
+
<template><!-- --></template>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import { Color, Vector2, Vector3 } from 'three'
|
|
4
|
+
import { uniform, vec2, vec4, mix, float } from 'three/tsl'
|
|
5
|
+
|
|
6
|
+
/** Radial gradient with an offset focal point — asymmetric radial. */
|
|
7
|
+
const props = withDefaults(defineProps<{
|
|
8
|
+
colorA?: string
|
|
9
|
+
colorB?: string
|
|
10
|
+
/** Focal point in UV space [0,1] */
|
|
11
|
+
focal?: [number, number]
|
|
12
|
+
/** Radius of full falloff */
|
|
13
|
+
radius?: number
|
|
14
|
+
order?: number
|
|
15
|
+
}>(), { colorA: '#ffffff', colorB: '#000000', focal: () => [0.3, 0.3], radius: 1.2, 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 focalNode = uniform(new Vector2(...props.focal))
|
|
25
|
+
const radiusNode = uniform(props.radius)
|
|
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.focal, ([x, y]) => { focalNode.value.set(x, y) })
|
|
29
|
+
watch(() => props.radius, v => { radiusNode.value = v })
|
|
30
|
+
|
|
31
|
+
const pipeline = useShaderPipelineContext()
|
|
32
|
+
|
|
33
|
+
useShaderStage(
|
|
34
|
+
() => {
|
|
35
|
+
const uv = pipeline.uvNode.value
|
|
36
|
+
const t = uv.sub(vec2(focalNode.x, focalNode.y)).length().div(radiusNode).min(float(1))
|
|
37
|
+
return vec4(mix(colorANode, colorBNode, t), float(1))
|
|
38
|
+
},
|
|
39
|
+
props.order,
|
|
40
|
+
)
|
|
41
|
+
</script>
|
|
42
|
+
|
|
43
|
+
<template><!-- --></template>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
import { uniform, vec4, pow, float } from 'three/tsl'
|
|
4
|
+
|
|
5
|
+
const props = withDefaults(defineProps<{
|
|
6
|
+
/** Gamma value: 1 = unchanged, 2.2 = standard display gamma */
|
|
7
|
+
gamma?: number
|
|
8
|
+
order?: number
|
|
9
|
+
}>(), { gamma: 2.2, order: 0 })
|
|
10
|
+
|
|
11
|
+
const gammaNode = uniform(props.gamma)
|
|
12
|
+
watch(() => props.gamma, v => { gammaNode.value = v })
|
|
13
|
+
|
|
14
|
+
useShaderStage(
|
|
15
|
+
(prev) => {
|
|
16
|
+
const corrected = pow(prev.xyz.max(float(0)), float(1).div(gammaNode))
|
|
17
|
+
return vec4(corrected, prev.w)
|
|
18
|
+
},
|
|
19
|
+
props.order,
|
|
20
|
+
)
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<template><!-- --></template>
|