@3driseai/3drise-viewer 0.1.40 → 0.1.42
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/dist/animationsV2/ClipsRuntime.d.ts.map +1 -1
- package/dist/animationsV2/ClipsRuntime.js +9 -5
- package/dist/animationsV2/clipUtils.d.ts +9 -0
- package/dist/animationsV2/clipUtils.d.ts.map +1 -1
- package/dist/animationsV2/clipUtils.js +11 -2
- package/dist/animationsV2/normalize.d.ts.map +1 -1
- package/dist/animationsV2/normalize.js +2 -0
- package/dist/animationsV2/types.d.ts +4 -0
- package/dist/animationsV2/types.d.ts.map +1 -1
- package/dist/api/sceneHandle.d.ts +40 -3
- package/dist/api/sceneHandle.d.ts.map +1 -1
- package/dist/api/sceneHandle.js +40 -0
- package/dist/components/GalleryObject.d.ts +13 -0
- package/dist/components/GalleryObject.d.ts.map +1 -0
- package/dist/components/GalleryObject.js +46 -0
- package/dist/components/ImageObject.d.ts +9 -0
- package/dist/components/ImageObject.d.ts.map +1 -0
- package/dist/components/ImageObject.js +26 -0
- package/dist/components/ObjectNode.d.ts.map +1 -1
- package/dist/components/ObjectNode.js +11 -5
- package/dist/components/ProjectLoader.d.ts +2 -0
- package/dist/components/ProjectLoader.d.ts.map +1 -1
- package/dist/components/ProjectLoader.js +2 -2
- package/dist/components/SceneBuilder.d.ts +10 -0
- package/dist/components/SceneBuilder.d.ts.map +1 -1
- package/dist/components/SceneBuilder.js +3 -2
- package/dist/components/gallery/BasicCarouselGallery.d.ts +18 -0
- package/dist/components/gallery/BasicCarouselGallery.d.ts.map +1 -0
- package/dist/components/gallery/BasicCarouselGallery.js +9 -0
- package/dist/components/gallery/ContourLinesGallery.d.ts +18 -0
- package/dist/components/gallery/ContourLinesGallery.d.ts.map +1 -0
- package/dist/components/gallery/ContourLinesGallery.js +9 -0
- package/dist/components/gallery/DepthLayersGallery.d.ts +18 -0
- package/dist/components/gallery/DepthLayersGallery.d.ts.map +1 -0
- package/dist/components/gallery/DepthLayersGallery.js +9 -0
- package/dist/components/gallery/EngravingGallery.d.ts +18 -0
- package/dist/components/gallery/EngravingGallery.d.ts.map +1 -0
- package/dist/components/gallery/EngravingGallery.js +9 -0
- package/dist/components/gallery/FlowLinesGallery.d.ts +18 -0
- package/dist/components/gallery/FlowLinesGallery.d.ts.map +1 -0
- package/dist/components/gallery/FlowLinesGallery.js +9 -0
- package/dist/components/gallery/FoldGallery.d.ts +18 -0
- package/dist/components/gallery/FoldGallery.d.ts.map +1 -0
- package/dist/components/gallery/FoldGallery.js +9 -0
- package/dist/components/gallery/GlassPanesGallery.d.ts +18 -0
- package/dist/components/gallery/GlassPanesGallery.d.ts.map +1 -0
- package/dist/components/gallery/GlassPanesGallery.js +9 -0
- package/dist/components/gallery/HaloGallery.d.ts +18 -0
- package/dist/components/gallery/HaloGallery.d.ts.map +1 -0
- package/dist/components/gallery/HaloGallery.js +9 -0
- package/dist/components/gallery/LightThreadsGallery.d.ts +18 -0
- package/dist/components/gallery/LightThreadsGallery.d.ts.map +1 -0
- package/dist/components/gallery/LightThreadsGallery.js +9 -0
- package/dist/components/gallery/LoomGallery.d.ts +18 -0
- package/dist/components/gallery/LoomGallery.d.ts.map +1 -0
- package/dist/components/gallery/LoomGallery.js +9 -0
- package/dist/components/gallery/PaperLanternsGallery.d.ts +18 -0
- package/dist/components/gallery/PaperLanternsGallery.d.ts.map +1 -0
- package/dist/components/gallery/PaperLanternsGallery.js +9 -0
- package/dist/components/gallery/ParticleShiftGallery.d.ts +18 -0
- package/dist/components/gallery/ParticleShiftGallery.d.ts.map +1 -0
- package/dist/components/gallery/ParticleShiftGallery.js +9 -0
- package/dist/components/gallery/PinscreenGallery.d.ts +18 -0
- package/dist/components/gallery/PinscreenGallery.d.ts.map +1 -0
- package/dist/components/gallery/PinscreenGallery.js +9 -0
- package/dist/components/gallery/PopUpGallery.d.ts +18 -0
- package/dist/components/gallery/PopUpGallery.d.ts.map +1 -0
- package/dist/components/gallery/PopUpGallery.js +9 -0
- package/dist/components/gallery/PrismSplitGallery.d.ts +18 -0
- package/dist/components/gallery/PrismSplitGallery.d.ts.map +1 -0
- package/dist/components/gallery/PrismSplitGallery.js +9 -0
- package/dist/components/gallery/RidgelinesGallery.d.ts +18 -0
- package/dist/components/gallery/RidgelinesGallery.d.ts.map +1 -0
- package/dist/components/gallery/RidgelinesGallery.js +9 -0
- package/dist/components/gallery/ShadowBoxGallery.d.ts +18 -0
- package/dist/components/gallery/ShadowBoxGallery.d.ts.map +1 -0
- package/dist/components/gallery/ShadowBoxGallery.js +9 -0
- package/dist/components/gallery/SilkGallery.d.ts +18 -0
- package/dist/components/gallery/SilkGallery.d.ts.map +1 -0
- package/dist/components/gallery/SilkGallery.js +9 -0
- package/dist/components/gallery/SlatsGallery.d.ts +18 -0
- package/dist/components/gallery/SlatsGallery.d.ts.map +1 -0
- package/dist/components/gallery/SlatsGallery.js +9 -0
- package/dist/components/gallery/StrataGallery.d.ts +18 -0
- package/dist/components/gallery/StrataGallery.d.ts.map +1 -0
- package/dist/components/gallery/StrataGallery.js +9 -0
- package/dist/components/gallery/TerracesGallery.d.ts +18 -0
- package/dist/components/gallery/TerracesGallery.d.ts.map +1 -0
- package/dist/components/gallery/TerracesGallery.js +9 -0
- package/dist/components/gallery/WireReliefGallery.d.ts +18 -0
- package/dist/components/gallery/WireReliefGallery.d.ts.map +1 -0
- package/dist/components/gallery/WireReliefGallery.js +9 -0
- package/dist/components/gallery/index.d.ts +46 -0
- package/dist/components/gallery/index.d.ts.map +1 -0
- package/dist/components/gallery/index.js +22 -0
- package/dist/components/gallery/kit/GalleryVariant.d.ts +68 -0
- package/dist/components/gallery/kit/GalleryVariant.d.ts.map +1 -0
- package/dist/components/gallery/kit/GalleryVariant.js +231 -0
- package/dist/components/gallery/kit/feeds.d.ts +7 -0
- package/dist/components/gallery/kit/feeds.d.ts.map +1 -0
- package/dist/components/gallery/kit/feeds.js +83 -0
- package/dist/components/gallery/kit/galleryKit.d.ts +118 -0
- package/dist/components/gallery/kit/galleryKit.d.ts.map +1 -0
- package/dist/components/gallery/kit/galleryKit.js +298 -0
- package/dist/components/gallery/kit/lookBase.d.ts +157 -0
- package/dist/components/gallery/kit/lookBase.d.ts.map +1 -0
- package/dist/components/gallery/kit/lookBase.js +211 -0
- package/dist/components/gallery/kit/pictures.d.ts +14 -0
- package/dist/components/gallery/kit/pictures.d.ts.map +1 -0
- package/dist/components/gallery/kit/pictures.js +81 -0
- package/dist/components/gallery/looks/basicCarousel.d.ts +177 -0
- package/dist/components/gallery/looks/basicCarousel.d.ts.map +1 -0
- package/dist/components/gallery/looks/basicCarousel.js +315 -0
- package/dist/components/gallery/looks/contourLines.d.ts +153 -0
- package/dist/components/gallery/looks/contourLines.d.ts.map +1 -0
- package/dist/components/gallery/looks/contourLines.js +91 -0
- package/dist/components/gallery/looks/depthLayers.d.ts +155 -0
- package/dist/components/gallery/looks/depthLayers.d.ts.map +1 -0
- package/dist/components/gallery/looks/depthLayers.js +87 -0
- package/dist/components/gallery/looks/engraving.d.ts +162 -0
- package/dist/components/gallery/looks/engraving.d.ts.map +1 -0
- package/dist/components/gallery/looks/engraving.js +96 -0
- package/dist/components/gallery/looks/flowLines.d.ts +180 -0
- package/dist/components/gallery/looks/flowLines.d.ts.map +1 -0
- package/dist/components/gallery/looks/flowLines.js +113 -0
- package/dist/components/gallery/looks/fold.d.ts +209 -0
- package/dist/components/gallery/looks/fold.d.ts.map +1 -0
- package/dist/components/gallery/looks/fold.js +155 -0
- package/dist/components/gallery/looks/glassPanes.d.ts +133 -0
- package/dist/components/gallery/looks/glassPanes.d.ts.map +1 -0
- package/dist/components/gallery/looks/glassPanes.js +208 -0
- package/dist/components/gallery/looks/halo.d.ts +100 -0
- package/dist/components/gallery/looks/halo.d.ts.map +1 -0
- package/dist/components/gallery/looks/halo.js +119 -0
- package/dist/components/gallery/looks/lightThreads.d.ts +199 -0
- package/dist/components/gallery/looks/lightThreads.d.ts.map +1 -0
- package/dist/components/gallery/looks/lightThreads.js +246 -0
- package/dist/components/gallery/looks/loom.d.ts +238 -0
- package/dist/components/gallery/looks/loom.d.ts.map +1 -0
- package/dist/components/gallery/looks/loom.js +256 -0
- package/dist/components/gallery/looks/paperLanterns.d.ts +181 -0
- package/dist/components/gallery/looks/paperLanterns.d.ts.map +1 -0
- package/dist/components/gallery/looks/paperLanterns.js +399 -0
- package/dist/components/gallery/looks/particleShift.d.ts +193 -0
- package/dist/components/gallery/looks/particleShift.d.ts.map +1 -0
- package/dist/components/gallery/looks/particleShift.js +282 -0
- package/dist/components/gallery/looks/pinscreen.d.ts +175 -0
- package/dist/components/gallery/looks/pinscreen.d.ts.map +1 -0
- package/dist/components/gallery/looks/pinscreen.js +96 -0
- package/dist/components/gallery/looks/popUp.d.ts +206 -0
- package/dist/components/gallery/looks/popUp.d.ts.map +1 -0
- package/dist/components/gallery/looks/popUp.js +132 -0
- package/dist/components/gallery/looks/prismSplit.d.ts +151 -0
- package/dist/components/gallery/looks/prismSplit.d.ts.map +1 -0
- package/dist/components/gallery/looks/prismSplit.js +84 -0
- package/dist/components/gallery/looks/ridgelines.d.ts +179 -0
- package/dist/components/gallery/looks/ridgelines.d.ts.map +1 -0
- package/dist/components/gallery/looks/ridgelines.js +111 -0
- package/dist/components/gallery/looks/shadowBox.d.ts +152 -0
- package/dist/components/gallery/looks/shadowBox.d.ts.map +1 -0
- package/dist/components/gallery/looks/shadowBox.js +82 -0
- package/dist/components/gallery/looks/silk.d.ts +140 -0
- package/dist/components/gallery/looks/silk.d.ts.map +1 -0
- package/dist/components/gallery/looks/silk.js +346 -0
- package/dist/components/gallery/looks/slats.d.ts +176 -0
- package/dist/components/gallery/looks/slats.d.ts.map +1 -0
- package/dist/components/gallery/looks/slats.js +93 -0
- package/dist/components/gallery/looks/strata.d.ts +172 -0
- package/dist/components/gallery/looks/strata.d.ts.map +1 -0
- package/dist/components/gallery/looks/strata.js +88 -0
- package/dist/components/gallery/looks/terraces.d.ts +168 -0
- package/dist/components/gallery/looks/terraces.d.ts.map +1 -0
- package/dist/components/gallery/looks/terraces.js +91 -0
- package/dist/components/gallery/looks/wireRelief.d.ts +153 -0
- package/dist/components/gallery/looks/wireRelief.d.ts.map +1 -0
- package/dist/components/gallery/looks/wireRelief.js +128 -0
- package/dist/components/image/ContourImage.d.ts +7 -0
- package/dist/components/image/ContourImage.d.ts.map +1 -0
- package/dist/components/image/ContourImage.js +6 -0
- package/dist/components/image/EngravingImage.d.ts +7 -0
- package/dist/components/image/EngravingImage.d.ts.map +1 -0
- package/dist/components/image/EngravingImage.js +6 -0
- package/dist/components/image/FrostImage.d.ts +7 -0
- package/dist/components/image/FrostImage.d.ts.map +1 -0
- package/dist/components/image/FrostImage.js +6 -0
- package/dist/components/image/LenticularImage.d.ts +7 -0
- package/dist/components/image/LenticularImage.d.ts.map +1 -0
- package/dist/components/image/LenticularImage.js +6 -0
- package/dist/components/image/PinscreenImage.d.ts +7 -0
- package/dist/components/image/PinscreenImage.d.ts.map +1 -0
- package/dist/components/image/PinscreenImage.js +6 -0
- package/dist/components/image/PrismImage.d.ts +7 -0
- package/dist/components/image/PrismImage.d.ts.map +1 -0
- package/dist/components/image/PrismImage.js +6 -0
- package/dist/components/image/ProjectorImage.d.ts +7 -0
- package/dist/components/image/ProjectorImage.d.ts.map +1 -0
- package/dist/components/image/ProjectorImage.js +6 -0
- package/dist/components/image/ReliefImage.d.ts +7 -0
- package/dist/components/image/ReliefImage.d.ts.map +1 -0
- package/dist/components/image/ReliefImage.js +6 -0
- package/dist/components/image/RollImage.d.ts +7 -0
- package/dist/components/image/RollImage.d.ts.map +1 -0
- package/dist/components/image/RollImage.js +6 -0
- package/dist/components/image/ShardsImage.d.ts +126 -0
- package/dist/components/image/ShardsImage.d.ts.map +1 -0
- package/dist/components/image/ShardsImage.js +470 -0
- package/dist/components/image/core/contour.d.ts +126 -0
- package/dist/components/image/core/contour.d.ts.map +1 -0
- package/dist/components/image/core/contour.js +123 -0
- package/dist/components/image/core/engraving.d.ts +135 -0
- package/dist/components/image/core/engraving.d.ts.map +1 -0
- package/dist/components/image/core/engraving.js +163 -0
- package/dist/components/image/core/frost.d.ts +126 -0
- package/dist/components/image/core/frost.d.ts.map +1 -0
- package/dist/components/image/core/frost.js +156 -0
- package/dist/components/image/core/imageCore.d.ts +110 -0
- package/dist/components/image/core/imageCore.d.ts.map +1 -0
- package/dist/components/image/core/imageCore.js +269 -0
- package/dist/components/image/core/lenticular.d.ts +129 -0
- package/dist/components/image/core/lenticular.d.ts.map +1 -0
- package/dist/components/image/core/lenticular.js +132 -0
- package/dist/components/image/core/pinscreen.d.ts +126 -0
- package/dist/components/image/core/pinscreen.d.ts.map +1 -0
- package/dist/components/image/core/pinscreen.js +147 -0
- package/dist/components/image/core/prism.d.ts +120 -0
- package/dist/components/image/core/prism.d.ts.map +1 -0
- package/dist/components/image/core/prism.js +164 -0
- package/dist/components/image/core/projector.d.ts +135 -0
- package/dist/components/image/core/projector.d.ts.map +1 -0
- package/dist/components/image/core/projector.js +225 -0
- package/dist/components/image/core/relief.d.ts +111 -0
- package/dist/components/image/core/relief.d.ts.map +1 -0
- package/dist/components/image/core/relief.js +94 -0
- package/dist/components/image/core/roll.d.ts +114 -0
- package/dist/components/image/core/roll.d.ts.map +1 -0
- package/dist/components/image/core/roll.js +116 -0
- package/dist/components/image/imageVariant.d.ts +46 -0
- package/dist/components/image/imageVariant.d.ts.map +1 -0
- package/dist/components/image/imageVariant.js +128 -0
- package/dist/components/image/index.d.ts +22 -0
- package/dist/components/image/index.d.ts.map +1 -0
- package/dist/components/image/index.js +10 -0
- package/dist/components/image/pictureCycle.d.ts +15 -0
- package/dist/components/image/pictureCycle.d.ts.map +1 -0
- package/dist/components/image/pictureCycle.js +82 -0
- package/dist/components/index.d.ts +4 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +4 -0
- package/dist/components/volumetricClouds/VolumetricCloudsPass.d.ts +9 -7
- package/dist/components/volumetricClouds/VolumetricCloudsPass.d.ts.map +1 -1
- package/dist/components/volumetricClouds/VolumetricCloudsPass.js +39 -27
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +2 -0
- package/dist/galleryRuntime.d.ts +57 -0
- package/dist/galleryRuntime.d.ts.map +1 -0
- package/dist/galleryRuntime.js +105 -0
- package/dist/hooks/useConfigLive.d.ts +1 -1
- package/dist/hooks/useConfigLive.d.ts.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/keyPad/KeyPadControls.d.ts +16 -0
- package/dist/keyPad/KeyPadControls.d.ts.map +1 -0
- package/dist/keyPad/KeyPadControls.js +176 -0
- package/dist/keyPad/index.d.ts +16 -0
- package/dist/keyPad/index.d.ts.map +1 -0
- package/dist/keyPad/index.js +8 -0
- package/dist/keyPad/keyBindings.d.ts +43 -0
- package/dist/keyPad/keyBindings.d.ts.map +1 -0
- package/dist/keyPad/keyBindings.js +92 -0
- package/dist/keyPad/keyPadAnimation.d.ts +28 -0
- package/dist/keyPad/keyPadAnimation.d.ts.map +1 -0
- package/dist/keyPad/keyPadAnimation.js +131 -0
- package/dist/keyPad/keyPadMotion.d.ts +68 -0
- package/dist/keyPad/keyPadMotion.d.ts.map +1 -0
- package/dist/keyPad/keyPadMotion.js +283 -0
- package/dist/keyPad/keyPadStore.d.ts +25 -0
- package/dist/keyPad/keyPadStore.d.ts.map +1 -0
- package/dist/keyPad/keyPadStore.js +63 -0
- package/dist/keyPad/types.d.ts +23 -0
- package/dist/keyPad/types.d.ts.map +1 -0
- package/dist/keyPad/types.js +9 -0
- package/dist/operations/catalogue/visibility.d.ts.map +1 -1
- package/dist/operations/catalogue/visibility.js +23 -1
- package/dist/shaders/clouds/CloudResolveMaterial.d.ts +2 -1
- package/dist/shaders/clouds/CloudResolveMaterial.d.ts.map +1 -1
- package/dist/shaders/clouds/CloudResolveMaterial.js +37 -12
- package/dist/shaders/clouds/CloudVolumeMaterial.d.ts +4 -0
- package/dist/shaders/clouds/CloudVolumeMaterial.d.ts.map +1 -1
- package/dist/shaders/clouds/CloudVolumeMaterial.js +15 -3
- package/dist/triggers/kinds/gallery.d.ts +2 -0
- package/dist/triggers/kinds/gallery.d.ts.map +1 -0
- package/dist/triggers/kinds/gallery.js +39 -0
- package/dist/triggers/kinds/index.d.ts +1 -0
- package/dist/triggers/kinds/index.d.ts.map +1 -1
- package/dist/triggers/kinds/index.js +1 -0
- package/dist/ui/UiLayers.d.ts +17 -1
- package/dist/ui/UiLayers.d.ts.map +1 -1
- package/dist/ui/UiLayers.js +76 -3
- package/dist/ui/index.d.ts +2 -2
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
// GENERATED from the lab (Claude outputs/gallery-lab/image/prism.mjs) by emit_image.mjs — change the lab and re-emit.
|
|
2
|
+
// prism — an image variant (type 'image', config.type 'prism'). Material: MeshStandardMaterial (lit by the scene;
|
|
3
|
+
// object effects attach).
|
|
4
|
+
//
|
|
5
|
+
// A trivision sign: the picture is printed across a row of slim triangular prisms standing side by side. Each
|
|
6
|
+
// prism has three faces; the outgoing picture is on the face turned to the viewer, the incoming one on the next
|
|
7
|
+
// face. A change turns every prism a third of a turn about its own axis, one after the other in a travelling
|
|
8
|
+
// wave, with a short critically-damped settle — the faces pass through the scene's light, so the turn reads as
|
|
9
|
+
// light travelling across facets. The third face carries the slat colour. Rest angles accumulate (uSeq), so a
|
|
10
|
+
// change that is reversed half-way turns the prisms back the way they came. Idle: a barely visible ripple of
|
|
11
|
+
// the prisms (a degree) runs across, making the facets shimmer. One InstancedMesh, one draw call.
|
|
12
|
+
// Cursor: `tilt` turns the prisms near the cursor a few degrees toward it (glints), `wave` sends a small
|
|
13
|
+
// ripple of turns out from the cursor.
|
|
14
|
+
import * as THREE from 'three';
|
|
15
|
+
import { baseUniforms, applyBase, setU, createPicture, stepPointer, patchMaterial, depthTwin } from './imageCore.js';
|
|
16
|
+
export const POINTER_MODES = ['tilt', 'wave'];
|
|
17
|
+
export const STRUCTURAL = ['imageUrls', 'count', 'vertical'];
|
|
18
|
+
export function createUniforms() {
|
|
19
|
+
return { ...baseUniforms(), uCount: { value: 56 }, uVert: { value: 1 }, uSettle: { value: 0.5 }, uGap: { value: 0.06 }, uSlat: { value: new THREE.Color('#15171c') }, uSelf: { value: 0.1 } };
|
|
20
|
+
}
|
|
21
|
+
export function applyConfig(u, c) {
|
|
22
|
+
applyBase(u, c, POINTER_MODES);
|
|
23
|
+
setU(u, 'uSettle', c.settle);
|
|
24
|
+
setU(u, 'uGap', c.gap);
|
|
25
|
+
setU(u, 'uSlat', c.slatColor);
|
|
26
|
+
setU(u, 'uSelf', c.selfLight);
|
|
27
|
+
}
|
|
28
|
+
const vertexPars = /* glsl */ `
|
|
29
|
+
uniform float uCount, uVert, uSettle, uGap, uSelf; uniform vec3 uSlat;
|
|
30
|
+
attribute float aIndex; attribute float aFace; // prism index (instance), face of this vertex (0..2, 3 = cap)
|
|
31
|
+
varying vec2 vPic; varying float vFace; varying float vWhich;
|
|
32
|
+
// the turn of one prism: 0 -> 1 with a critically-damped settle (overshoot ~ uSettle)
|
|
33
|
+
float turnCurve(float l){
|
|
34
|
+
float x = clamp(l, 0.0, 1.0);
|
|
35
|
+
float e = 1.0 - pow(1.0 - x, 3.0);
|
|
36
|
+
return e + uSettle * 0.12 * sin(PI * x) * sin(PI * x) * (x > 0.5 ? 1.0 : 0.0) * sin(PI * (x - 0.5) * 2.0);
|
|
37
|
+
}
|
|
38
|
+
`;
|
|
39
|
+
const fragPars = /* glsl */ `
|
|
40
|
+
uniform float uCount, uVert, uSettle, uGap, uSelf; uniform vec3 uSlat;
|
|
41
|
+
varying vec2 vPic; varying float vFace; varying float vWhich;
|
|
42
|
+
`;
|
|
43
|
+
// The cross-section lives in (across, depth) with depth toward the viewer. Face k's outward normal is at
|
|
44
|
+
// 90 + 120 k degrees, so a turn of a = -120 (seq + t) degrees brings face (seq + t) mod 3 to the front: A sits on face
|
|
45
|
+
// seq mod 3, B on the next, the third face is the slat. Face k's tangent (its left -> right when in front) is at 120 k.
|
|
46
|
+
const vertex = /* glsl */ `
|
|
47
|
+
float i = aIndex; float face = aFace;
|
|
48
|
+
float across = (i + 0.5) / uCount; // centre of this prism, 0..1 across
|
|
49
|
+
float along0 = position.y + 0.5; // 0..1 along the prism
|
|
50
|
+
vec2 suv = uVert > 0.5 ? vec2(across, along0) : vec2(along0, across);
|
|
51
|
+
float l = localP(suv);
|
|
52
|
+
float t = turnCurve(l);
|
|
53
|
+
float pitch = (uVert > 0.5 ? uSize.x : uSize.y) / uCount;
|
|
54
|
+
vec2 xy = (suv - 0.5) * uSize;
|
|
55
|
+
float rest = uBreathe * 0.018 * sin(uTime * 0.7 - across * 9.0); // idle shimmer (about a degree)
|
|
56
|
+
float pb = pointerBump(xy);
|
|
57
|
+
float toward = uVert > 0.5 ? clamp((uPointer.x - xy.x) * 3.0, -1.0, 1.0) : clamp((uPointer.y - xy.y) * 3.0, -1.0, 1.0);
|
|
58
|
+
if (uPointerMode > -0.5 && uPointerMode < 0.5) rest += 0.22 * pb * toward;
|
|
59
|
+
else if (uPointerMode > 0.5) { float d = length(xy - uPointer.xy); rest += 0.2 * uPointerActive * uPointerStrength * sin(d * 18.0 - uTime * 5.0) * exp(-d * 2.5 / max(uPointerRadius, 0.05)); }
|
|
60
|
+
float ang = -(uSeq + t) * 2.0943951 + rest;
|
|
61
|
+
vec2 cs = position.xz, csn = normal.xz;
|
|
62
|
+
float ca = cos(ang), sa = sin(ang);
|
|
63
|
+
vec2 rc = vec2(ca * cs.x - sa * cs.y, sa * cs.x + ca * cs.y);
|
|
64
|
+
vec2 rn = vec2(ca * csn.x - sa * csn.y, sa * csn.x + ca * csn.y);
|
|
65
|
+
float R = pitch * (1.0 - uGap) / 1.7320508; // circumradius from the face width
|
|
66
|
+
float zc = -R * 0.5; // the front face sits at z = 0 at rest
|
|
67
|
+
if (uVert > 0.5) { fxP = vec3(xy.x + rc.x * R, xy.y, zc + rc.y * R); fxN = vec3(rn.x, normal.y, rn.y); }
|
|
68
|
+
else { fxP = vec3(xy.x, xy.y + rc.x * R, zc + rc.y * R); fxN = vec3(normal.y, rn.x, rn.y); }
|
|
69
|
+
float fa = mod(uSeq, 3.0), fb = mod(uSeq + 1.0, 3.0);
|
|
70
|
+
vWhich = face > 2.5 ? 2.0 : (abs(face - fa) < 0.5 ? 0.0 : (abs(face - fb) < 0.5 ? 1.0 : 2.0));
|
|
71
|
+
vec2 tk = vec2(cos(face * 2.0943951), sin(face * 2.0943951));
|
|
72
|
+
float acrossUv = across + dot(cs, tk) / 1.7320508 / uCount * (1.0 - uGap);
|
|
73
|
+
vPic = uVert > 0.5 ? vec2(acrossUv, along0) : vec2(along0, acrossUv);
|
|
74
|
+
vFace = face;
|
|
75
|
+
`;
|
|
76
|
+
const diffuse = /* glsl */ `
|
|
77
|
+
vec3 c = vWhich < 0.5 ? picA(vPic) : (vWhich < 1.5 ? picB(vPic) : uSlat);
|
|
78
|
+
diffuseColor.rgb = c * (vWhich < 1.5 ? uIntensity : 1.0);
|
|
79
|
+
diffuseColor.a *= uOpacity;
|
|
80
|
+
`;
|
|
81
|
+
const emissive = /* glsl */ `
|
|
82
|
+
totalEmissiveRadiance += (vWhich < 1.5 ? diffuseColor.rgb * uSelf : vec3(0.0));
|
|
83
|
+
`;
|
|
84
|
+
/** One prism: three flat faces + two end caps; the cross-section (x across, z toward the viewer) is a unit-circumradius triangle, length 1 along y. */
|
|
85
|
+
function prismGeometry(segsAlong) {
|
|
86
|
+
const pos = [], nor = [], face = [], idx = [];
|
|
87
|
+
const D = Math.PI / 180;
|
|
88
|
+
for (let f = 0; f < 3; f++) {
|
|
89
|
+
const th = (90 + 120 * f) * D;
|
|
90
|
+
const nx = Math.cos(th), nz = Math.sin(th);
|
|
91
|
+
const L = [Math.cos(th + 60 * D), Math.sin(th + 60 * D)], Rr = [Math.cos(th - 60 * D), Math.sin(th - 60 * D)]; // left / right corners when in front
|
|
92
|
+
const base = pos.length / 3;
|
|
93
|
+
for (let j = 0; j <= segsAlong; j++) {
|
|
94
|
+
const y = j / segsAlong - 0.5;
|
|
95
|
+
pos.push(L[0], y, L[1], Rr[0], y, Rr[1]);
|
|
96
|
+
nor.push(nx, 0, nz, nx, 0, nz);
|
|
97
|
+
face.push(f, f);
|
|
98
|
+
}
|
|
99
|
+
for (let j = 0; j < segsAlong; j++) {
|
|
100
|
+
const a = base + j * 2;
|
|
101
|
+
idx.push(a, a + 1, a + 3, a, a + 3, a + 2);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
for (const y of [-0.5, 0.5]) {
|
|
105
|
+
const base = pos.length / 3;
|
|
106
|
+
for (let k = 0; k < 3; k++) {
|
|
107
|
+
const a = (90 + 60 + 120 * k) * D;
|
|
108
|
+
pos.push(Math.cos(a), y, Math.sin(a));
|
|
109
|
+
nor.push(0, Math.sign(y), 0);
|
|
110
|
+
face.push(3);
|
|
111
|
+
}
|
|
112
|
+
if (y > 0)
|
|
113
|
+
idx.push(base, base + 2, base + 1);
|
|
114
|
+
else
|
|
115
|
+
idx.push(base, base + 1, base + 2);
|
|
116
|
+
}
|
|
117
|
+
const g = new THREE.BufferGeometry();
|
|
118
|
+
g.setAttribute('position', new THREE.Float32BufferAttribute(pos, 3));
|
|
119
|
+
g.setAttribute('normal', new THREE.Float32BufferAttribute(nor, 3));
|
|
120
|
+
g.setAttribute('aFace', new THREE.Float32BufferAttribute(face, 1));
|
|
121
|
+
g.setIndex(idx);
|
|
122
|
+
return g;
|
|
123
|
+
}
|
|
124
|
+
export function build(u, c) {
|
|
125
|
+
const object = new THREE.Group();
|
|
126
|
+
const n = Math.max(4, c.count | 0);
|
|
127
|
+
u.uCount.value = n;
|
|
128
|
+
u.uVert.value = c.vertical ? 1 : 0;
|
|
129
|
+
const base = prismGeometry(24);
|
|
130
|
+
const geo = new THREE.InstancedBufferGeometry();
|
|
131
|
+
geo.index = base.index;
|
|
132
|
+
geo.setAttribute('position', base.attributes.position);
|
|
133
|
+
geo.setAttribute('normal', base.attributes.normal);
|
|
134
|
+
geo.setAttribute('aFace', base.attributes.aFace);
|
|
135
|
+
const ids = new Float32Array(n);
|
|
136
|
+
for (let i = 0; i < n; i++)
|
|
137
|
+
ids[i] = i;
|
|
138
|
+
geo.setAttribute('aIndex', new THREE.InstancedBufferAttribute(ids, 1));
|
|
139
|
+
geo.instanceCount = n;
|
|
140
|
+
geo.boundingSphere = new THREE.Sphere(new THREE.Vector3(), 1.4);
|
|
141
|
+
const P = { key: 'prism', uniforms: u, pars: '', vertexPars, fragmentPars: fragPars, vertex, diffuse, emissive };
|
|
142
|
+
const mat = patchMaterial(new THREE.MeshStandardMaterial({ roughness: c.roughness, metalness: 0 }), P);
|
|
143
|
+
const mesh = new THREE.Mesh(geo, mat);
|
|
144
|
+
mesh.castShadow = true;
|
|
145
|
+
mesh.receiveShadow = true;
|
|
146
|
+
mesh.frustumCulled = false;
|
|
147
|
+
mat.side = THREE.FrontSide;
|
|
148
|
+
mesh.customDepthMaterial = depthTwin(P);
|
|
149
|
+
object.add(mesh);
|
|
150
|
+
const cfg = { ...c };
|
|
151
|
+
const pic = createPicture(u, cfg);
|
|
152
|
+
const pst = {};
|
|
153
|
+
const api = {
|
|
154
|
+
object, materials: [mat],
|
|
155
|
+
controls: { show: (t) => pic.show(t), get busy() { return pic.busy; }, pic },
|
|
156
|
+
apply(k) { Object.assign(cfg, k); applyConfig(u, k); if (k.roughness !== undefined)
|
|
157
|
+
mat.roughness = k.roughness; if (k.opacity !== undefined) {
|
|
158
|
+
mat.transparent = k.opacity < 1;
|
|
159
|
+
} },
|
|
160
|
+
update(dt, pointer) { dt = Math.min(dt, 0.1); u.uTime.value += dt; pic.step(dt); stepPointer(u, pointer, dt, pst); },
|
|
161
|
+
dispose() { base.dispose(); geo.dispose(); mat.dispose(); mesh.customDepthMaterial.dispose(); pic.dispose(); },
|
|
162
|
+
};
|
|
163
|
+
return api;
|
|
164
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
export declare const POINTER_MODES: string[];
|
|
3
|
+
export declare const STRUCTURAL: string[];
|
|
4
|
+
export declare function createUniforms(): {
|
|
5
|
+
uLens: {
|
|
6
|
+
value: THREE.Vector3;
|
|
7
|
+
};
|
|
8
|
+
uHaze: {
|
|
9
|
+
value: number;
|
|
10
|
+
};
|
|
11
|
+
uDust: {
|
|
12
|
+
value: number;
|
|
13
|
+
};
|
|
14
|
+
uDrift: {
|
|
15
|
+
value: number;
|
|
16
|
+
};
|
|
17
|
+
uFocus: {
|
|
18
|
+
value: number;
|
|
19
|
+
};
|
|
20
|
+
uGate: {
|
|
21
|
+
value: number;
|
|
22
|
+
};
|
|
23
|
+
uLamp: {
|
|
24
|
+
value: number;
|
|
25
|
+
};
|
|
26
|
+
uVignette: {
|
|
27
|
+
value: number;
|
|
28
|
+
};
|
|
29
|
+
uLampColor: {
|
|
30
|
+
value: THREE.Color;
|
|
31
|
+
};
|
|
32
|
+
uGain: {
|
|
33
|
+
value: number;
|
|
34
|
+
};
|
|
35
|
+
uHot: {
|
|
36
|
+
value: THREE.Vector2;
|
|
37
|
+
};
|
|
38
|
+
uTexA: {
|
|
39
|
+
value: any;
|
|
40
|
+
};
|
|
41
|
+
uTexB: {
|
|
42
|
+
value: any;
|
|
43
|
+
};
|
|
44
|
+
uFitA: {
|
|
45
|
+
value: THREE.Vector2;
|
|
46
|
+
};
|
|
47
|
+
uFitB: {
|
|
48
|
+
value: THREE.Vector2;
|
|
49
|
+
};
|
|
50
|
+
uP: {
|
|
51
|
+
value: number;
|
|
52
|
+
};
|
|
53
|
+
uHasA: {
|
|
54
|
+
value: number;
|
|
55
|
+
};
|
|
56
|
+
uSeq: {
|
|
57
|
+
value: number;
|
|
58
|
+
};
|
|
59
|
+
uSize: {
|
|
60
|
+
value: THREE.Vector2;
|
|
61
|
+
};
|
|
62
|
+
uTime: {
|
|
63
|
+
value: number;
|
|
64
|
+
};
|
|
65
|
+
uDir: {
|
|
66
|
+
value: THREE.Vector2;
|
|
67
|
+
};
|
|
68
|
+
uSpread: {
|
|
69
|
+
value: number;
|
|
70
|
+
};
|
|
71
|
+
uBlank: {
|
|
72
|
+
value: THREE.Color;
|
|
73
|
+
};
|
|
74
|
+
uIntensity: {
|
|
75
|
+
value: number;
|
|
76
|
+
};
|
|
77
|
+
uOpacity: {
|
|
78
|
+
value: number;
|
|
79
|
+
};
|
|
80
|
+
uBreathe: {
|
|
81
|
+
value: number;
|
|
82
|
+
};
|
|
83
|
+
uPointer: {
|
|
84
|
+
value: THREE.Vector3;
|
|
85
|
+
};
|
|
86
|
+
uPointerVel: {
|
|
87
|
+
value: THREE.Vector2;
|
|
88
|
+
};
|
|
89
|
+
uPointerActive: {
|
|
90
|
+
value: number;
|
|
91
|
+
};
|
|
92
|
+
uPointerMode: {
|
|
93
|
+
value: number;
|
|
94
|
+
};
|
|
95
|
+
uPointerStrength: {
|
|
96
|
+
value: number;
|
|
97
|
+
};
|
|
98
|
+
uPointerRadius: {
|
|
99
|
+
value: number;
|
|
100
|
+
};
|
|
101
|
+
uPointerColor: {
|
|
102
|
+
value: THREE.Color;
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
export declare function applyConfig(u: any, c: any): void;
|
|
106
|
+
export declare function build(u: any, c: any): {
|
|
107
|
+
object: THREE.Group<THREE.Object3DEventMap>;
|
|
108
|
+
materials: THREE.ShaderMaterial[];
|
|
109
|
+
controls: {
|
|
110
|
+
show: (t: any) => void;
|
|
111
|
+
readonly busy: boolean;
|
|
112
|
+
pic: {
|
|
113
|
+
st: {
|
|
114
|
+
A: any;
|
|
115
|
+
B: any;
|
|
116
|
+
aspA: number;
|
|
117
|
+
aspB: number;
|
|
118
|
+
p: number;
|
|
119
|
+
dir: number;
|
|
120
|
+
pending: any;
|
|
121
|
+
seq: number;
|
|
122
|
+
frame: number;
|
|
123
|
+
};
|
|
124
|
+
show: (tex: any) => void;
|
|
125
|
+
jump: (tex: any) => void;
|
|
126
|
+
step: (dt: any) => void;
|
|
127
|
+
readonly busy: boolean;
|
|
128
|
+
dispose(): void;
|
|
129
|
+
};
|
|
130
|
+
};
|
|
131
|
+
apply(k: any): void;
|
|
132
|
+
update(dt: any, pointer: any): void;
|
|
133
|
+
dispose(): void;
|
|
134
|
+
};
|
|
135
|
+
//# sourceMappingURL=projector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projector.d.ts","sourceRoot":"","sources":["../../../../src/components/image/core/projector.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,eAAO,MAAM,aAAa,UAAsB,CAAC;AACjD,eAAO,MAAM,UAAU,UAA6B,CAAC;AAErD,wBAAgB,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAG7B;AACD,wBAAgB,WAAW,CAAC,CAAC,KAAA,EAAE,CAAC,KAAA,QAG/B;AAqHD,wBAAgB,KAAK,CAAC,CAAC,KAAA,EAAE,CAAC,KAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyDzB"}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
// GENERATED from the lab (Claude outputs/gallery-lab/image/projector.mjs) by emit_image.mjs — change the lab and re-emit.
|
|
2
|
+
// projector — an image variant (type 'image', config.type 'projector'). Material: own ShaderMaterials, self-coloured.
|
|
3
|
+
// No light of its own: the projected picture, the beam and the dust are emissive, the scene's lights are untouched.
|
|
4
|
+
//
|
|
5
|
+
// The picture is projected: it exists as light on a matte screen, thrown from a lens that hangs above and in front
|
|
6
|
+
// of it. The beam is visible in the air — a haze pyramid from the lens to the screen whose every fragment shows
|
|
7
|
+
// the colour of the picture where its ray lands, fading with the lamp's inverse square — and dust motes drift
|
|
8
|
+
// through it, each lit by the pixel it floats in. All three read one function, proj(uv): the slide in the gate,
|
|
9
|
+
// the gate's focus and the lamp, so beam, dust and screen always agree. A change is a slide change: the lens
|
|
10
|
+
// racks softly out of focus, the slide carriage moves — the old slide slides out of the gate as the new one slides
|
|
11
|
+
// in, its frame edge passing across the screen as a soft, defocused shadow — and focus comes back with a small
|
|
12
|
+
// hunt. The first picture is the lamp warming up on a fresh slide. Idle: the dust drifts, the lamp breathes a
|
|
13
|
+
// percent. Cursor: `stir` — the dust swirls where the cursor's ray crosses the beam; `hotspot` — the lamp's
|
|
14
|
+
// hotspot leans toward the cursor.
|
|
15
|
+
import * as THREE from 'three';
|
|
16
|
+
import { baseUniforms, applyBase, setU, createPicture, stepPointer, GLSL_COMMON, fragHead, mulberry32 } from './imageCore.js';
|
|
17
|
+
export const POINTER_MODES = ['stir', 'hotspot'];
|
|
18
|
+
export const STRUCTURAL = ['imageUrls', 'dustCount'];
|
|
19
|
+
export function createUniforms() {
|
|
20
|
+
return { ...baseUniforms(), uLens: { value: new THREE.Vector3(0, 1.3, 2.4) }, uHaze: { value: 0.6 }, uDust: { value: 0.5 }, uDrift: { value: 0 }, uFocus: { value: 0 }, uGate: { value: 0 },
|
|
21
|
+
uLamp: { value: 1 }, uVignette: { value: 0.35 }, uLampColor: { value: new THREE.Color('#fff3e2') }, uGain: { value: 1 }, uHot: { value: new THREE.Vector2() } };
|
|
22
|
+
}
|
|
23
|
+
export function applyConfig(u, c) {
|
|
24
|
+
applyBase(u, c, POINTER_MODES);
|
|
25
|
+
setU(u, 'uHaze', c.haze);
|
|
26
|
+
setU(u, 'uDust', c.dust);
|
|
27
|
+
setU(u, 'uVignette', c.vignette);
|
|
28
|
+
setU(u, 'uLampColor', c.lampColor);
|
|
29
|
+
setU(u, 'uGain', c.screenGain);
|
|
30
|
+
}
|
|
31
|
+
// proj(uv): what the lens puts on the screen at uv — the two slides in the moving gate, out of focus by uFocus
|
|
32
|
+
const projGlsl = /* glsl */ `
|
|
33
|
+
uniform vec3 uLens; uniform float uHaze, uDust, uDrift, uFocus, uGate, uLamp, uVignette, uGain; uniform vec3 uLampColor; uniform vec2 uHot;
|
|
34
|
+
vec3 slide(sampler2D t, vec2 fitS, vec2 uv, float has, float off, float blur){
|
|
35
|
+
// the slide in the gate; out of focus = a small disc of taps on a pre-blurred mip (smooth, never blocky)
|
|
36
|
+
vec2 g = uv + vec2(off, 0.0);
|
|
37
|
+
float soft = 0.004 + 0.05 * blur;
|
|
38
|
+
float m = smoothstep(-soft, soft, g.x) * smoothstep(-soft, soft, 1.0 - g.x);
|
|
39
|
+
if (m <= 0.0 || has <= 0.0) return vec3(0.0);
|
|
40
|
+
float r = 0.022 * blur;
|
|
41
|
+
float lod = blur * 2.5;
|
|
42
|
+
vec3 c = vec3(0.0);
|
|
43
|
+
for (int i = 0; i < 7; i++) {
|
|
44
|
+
float a = float(i) * 2.3999632 + 0.5;
|
|
45
|
+
vec2 o = (i == 0) ? vec2(0.0) : vec2(cos(a), sin(a)) * r * sqrt(float(i) / 6.0);
|
|
46
|
+
vec2 q = clamp(g + o, 0.0, 1.0);
|
|
47
|
+
c += PROJ_SAMPLE(t, 0.5 + (q - 0.5) * fitS, lod).rgb;
|
|
48
|
+
}
|
|
49
|
+
return c / 7.0 * m * has;
|
|
50
|
+
}
|
|
51
|
+
vec3 proj(vec2 uv){
|
|
52
|
+
float blur = uFocus;
|
|
53
|
+
vec3 c = slide(uTexA, uFitA, uv, uHasA, -uGate * 1.08, blur) + slide(uTexB, uFitB, uv, 1.0, (1.0 - uGate) * 1.08, blur);
|
|
54
|
+
vec2 q = (uv - 0.5) * vec2(uSize.x / uSize.y, 1.0) - uHot;
|
|
55
|
+
float vig = 1.0 - uVignette * 0.6 * dot(q, q);
|
|
56
|
+
return c * uLampColor * uLamp * vig;
|
|
57
|
+
}
|
|
58
|
+
// the ray from the lens through a local point p lands on the screen (z = 0) at:
|
|
59
|
+
vec2 screenUv(vec3 p){ float t = uLens.z / max(uLens.z - p.z, 1e-4); vec2 s = uLens.xy + (p.xy - uLens.xy) * t; return s / uSize + 0.5; }
|
|
60
|
+
`;
|
|
61
|
+
const screenVert = /* glsl */ `
|
|
62
|
+
${GLSL_COMMON}
|
|
63
|
+
varying vec2 vPic;
|
|
64
|
+
void main(){ vPic = position.xy + 0.5; gl_Position = projectionMatrix * modelViewMatrix * vec4(position.xy * uSize, 0.0, 1.0); }`;
|
|
65
|
+
const screenFrag = /* glsl */ `
|
|
66
|
+
${fragHead}
|
|
67
|
+
${GLSL_COMMON}
|
|
68
|
+
#define PROJ_SAMPLE texture
|
|
69
|
+
${projGlsl}
|
|
70
|
+
varying vec2 vPic;
|
|
71
|
+
void main(){
|
|
72
|
+
vec3 c = proj(vPic) * uGain;
|
|
73
|
+
c += (hash12(gl_FragCoord.xy) - 0.5) * 0.006; // matte screen grain / dither
|
|
74
|
+
gl_FragColor = vec4(max(c, 0.0) * uIntensity, uOpacity);
|
|
75
|
+
#include <tonemapping_fragment>
|
|
76
|
+
#include <colorspace_fragment>
|
|
77
|
+
}`;
|
|
78
|
+
const hazeVert = /* glsl */ `
|
|
79
|
+
${GLSL_COMMON}
|
|
80
|
+
attribute float aSurf;
|
|
81
|
+
varying vec3 vP; varying float vSurf;
|
|
82
|
+
void main(){ vP = position; vSurf = aSurf; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); }`;
|
|
83
|
+
const hazeFrag = /* glsl */ `
|
|
84
|
+
${fragHead}
|
|
85
|
+
${GLSL_COMMON}
|
|
86
|
+
#define PROJ_SAMPLE(t, uv, b) textureLod(t, uv, 2.0 + b)
|
|
87
|
+
${projGlsl}
|
|
88
|
+
varying vec3 vP; varying float vSurf;
|
|
89
|
+
void main(){
|
|
90
|
+
vec2 uv = screenUv(vP);
|
|
91
|
+
float t = clamp(1.0 - vP.z / uLens.z, 0.0, 1.0); // 0 at the lens, 1 at the screen
|
|
92
|
+
vec2 e = min(uv, 1.0 - uv);
|
|
93
|
+
float edge = smoothstep(0.0, 0.06, min(e.x, e.y));
|
|
94
|
+
float falloff = 1.0 / (0.3 + 3.0 * t * t);
|
|
95
|
+
float wisps = 0.8 + 0.2 * vnoise(vec2(uv.x * 6.0 + uTime * 0.05, t * 4.0 - uTime * 0.04));
|
|
96
|
+
vec3 c = (0.65 * proj(clamp(uv, 0.0, 1.0)) + 0.06 * uLampColor * uLamp) * edge * falloff * wisps * uHaze * (vSurf > 0.5 ? 0.12 : 0.22);
|
|
97
|
+
c *= smoothstep(0.0, 0.08, t) * smoothstep(1.0, 0.97, t);
|
|
98
|
+
c += (hash12(gl_FragCoord.xy) - 0.5) * 0.003;
|
|
99
|
+
gl_FragColor = vec4(max(c, 0.0) * uIntensity * uOpacity, 0.0);
|
|
100
|
+
#include <tonemapping_fragment>
|
|
101
|
+
#include <colorspace_fragment>
|
|
102
|
+
}`;
|
|
103
|
+
const dustVert = /* glsl */ `
|
|
104
|
+
${GLSL_COMMON}
|
|
105
|
+
#define PROJ_SAMPLE(t, uv, b) textureLod(t, uv, 1.5 + b)
|
|
106
|
+
${projGlsl}
|
|
107
|
+
attribute vec4 aSeed;
|
|
108
|
+
varying vec3 vCol; varying vec2 vQ;
|
|
109
|
+
void main(){
|
|
110
|
+
float h = aSeed.w;
|
|
111
|
+
vec2 uv = aSeed.xy + 0.05 * vec2(sin(uDrift * (0.21 + 0.3 * h) + h * 31.0), cos(uDrift * (0.17 + 0.25 * h) + h * 17.0));
|
|
112
|
+
float t = fract(aSeed.z + uDrift * 0.01 * (0.5 + h));
|
|
113
|
+
uv = fract(uv);
|
|
114
|
+
vec3 S = vec3((uv - 0.5) * uSize, 0.0);
|
|
115
|
+
vec3 p = mix(uLens, S, 0.08 + 0.9 * t);
|
|
116
|
+
if (uPointerMode > -0.5 && uPointerMode < 0.5) { // stir: swirl about the cursor's ray
|
|
117
|
+
vec3 a = uLens, b = vec3(uPointer.xy, 0.0); vec3 ab = normalize(b - a);
|
|
118
|
+
vec3 ap = p - a; vec3 off = ap - ab * dot(ap, ab);
|
|
119
|
+
float d = length(off);
|
|
120
|
+
float w = uPointerActive * uPointerStrength * (1.0 - smoothstep(0.0, uPointerRadius * 0.5, d));
|
|
121
|
+
vec3 sw = cross(ab, off);
|
|
122
|
+
p += (sw * 1.4 + off * 0.25) * w * (0.7 + 0.3 * sin(uTime * 2.0 + h * 40.0));
|
|
123
|
+
}
|
|
124
|
+
vec2 suv = screenUv(p);
|
|
125
|
+
vec2 e = min(suv, 1.0 - suv);
|
|
126
|
+
float inside = smoothstep(0.0, 0.03, min(e.x, e.y));
|
|
127
|
+
float falloff = smoothstep(0.0, 0.35, t) / (0.6 + 2.0 * t * t);
|
|
128
|
+
vCol = (proj(clamp(suv, 0.0, 1.0)) + 0.05 * uLampColor) * inside * falloff * (0.35 + 0.65 * h) * uDust;
|
|
129
|
+
vQ = position.xy;
|
|
130
|
+
vec4 mv = modelViewMatrix * vec4(p, 1.0);
|
|
131
|
+
mv.xy += position.xy * (0.003 + 0.005 * h);
|
|
132
|
+
gl_Position = projectionMatrix * mv;
|
|
133
|
+
}`;
|
|
134
|
+
const dustFrag = /* glsl */ `
|
|
135
|
+
${fragHead}
|
|
136
|
+
uniform float uIntensity, uOpacity;
|
|
137
|
+
varying vec3 vCol; varying vec2 vQ;
|
|
138
|
+
void main(){
|
|
139
|
+
float r = length(vQ); if (r > 1.0) discard;
|
|
140
|
+
float core = exp(-r * r * 3.5);
|
|
141
|
+
gl_FragColor = vec4(vCol * core * 0.6 * uIntensity * uOpacity, 0.0);
|
|
142
|
+
#include <tonemapping_fragment>
|
|
143
|
+
#include <colorspace_fragment>
|
|
144
|
+
}`;
|
|
145
|
+
export function build(u, c) {
|
|
146
|
+
const object = new THREE.Group();
|
|
147
|
+
const geo = new THREE.PlaneGeometry(1, 1);
|
|
148
|
+
const screenMat = new THREE.ShaderMaterial({ uniforms: u, vertexShader: screenVert, fragmentShader: screenFrag, glslVersion: THREE.GLSL3 });
|
|
149
|
+
const screen = new THREE.Mesh(geo, screenMat);
|
|
150
|
+
screen.frustumCulled = false;
|
|
151
|
+
// the beam: 4 faces of the pyramid (lens -> screen corners) + 2 slices through its axis, rewritten when the frame / lens move
|
|
152
|
+
const hazeGeo = new THREE.BufferGeometry();
|
|
153
|
+
hazeGeo.setAttribute('position', new THREE.BufferAttribute(new Float32Array(18 * 3), 3));
|
|
154
|
+
hazeGeo.setAttribute('aSurf', new THREE.BufferAttribute(new Float32Array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0]), 1));
|
|
155
|
+
const hazeMat = new THREE.ShaderMaterial({ uniforms: u, vertexShader: hazeVert, fragmentShader: hazeFrag, glslVersion: THREE.GLSL3, transparent: true, depthWrite: false, blending: THREE.AdditiveBlending, premultipliedAlpha: true, side: THREE.DoubleSide });
|
|
156
|
+
const haze = new THREE.Mesh(hazeGeo, hazeMat);
|
|
157
|
+
haze.frustumCulled = false;
|
|
158
|
+
haze.renderOrder = 5;
|
|
159
|
+
haze.raycast = () => { };
|
|
160
|
+
const n = Math.max(0, c.dustCount | 0), rnd = mulberry32(11);
|
|
161
|
+
const quad = new THREE.PlaneGeometry(2, 2);
|
|
162
|
+
const dgeo = new THREE.InstancedBufferGeometry();
|
|
163
|
+
dgeo.index = quad.index;
|
|
164
|
+
dgeo.setAttribute('position', quad.attributes.position);
|
|
165
|
+
const seeds = new Float32Array(Math.max(1, n) * 4);
|
|
166
|
+
for (let i = 0; i < n * 4; i++)
|
|
167
|
+
seeds[i] = rnd();
|
|
168
|
+
dgeo.setAttribute('aSeed', new THREE.InstancedBufferAttribute(seeds, 4));
|
|
169
|
+
dgeo.instanceCount = n;
|
|
170
|
+
const dustMat = new THREE.ShaderMaterial({ uniforms: u, vertexShader: dustVert, fragmentShader: dustFrag, glslVersion: THREE.GLSL3, transparent: true, depthWrite: false, blending: THREE.AdditiveBlending, premultipliedAlpha: true });
|
|
171
|
+
const dust = new THREE.Mesh(dgeo, dustMat);
|
|
172
|
+
dust.frustumCulled = false;
|
|
173
|
+
dust.renderOrder = 6;
|
|
174
|
+
dust.raycast = () => { };
|
|
175
|
+
object.add(screen, haze, dust);
|
|
176
|
+
const cfg = { ...c };
|
|
177
|
+
const pic = createPicture(u, cfg);
|
|
178
|
+
const pst = {};
|
|
179
|
+
let flickT = 0, last = '';
|
|
180
|
+
function beam() {
|
|
181
|
+
const L = u.uLens.value.set(0, cfg.lensHeight, cfg.throw), s = u.uSize.value;
|
|
182
|
+
const key = `${L.y},${L.z},${s.x},${s.y}`;
|
|
183
|
+
if (key === last)
|
|
184
|
+
return;
|
|
185
|
+
last = key;
|
|
186
|
+
const hx = s.x / 2, hy = s.y / 2, Lp = [L.x, L.y, L.z];
|
|
187
|
+
const C = [[-hx, -hy, 0], [hx, -hy, 0], [hx, hy, 0], [-hx, hy, 0]];
|
|
188
|
+
const tris = [Lp, C[0], C[1], Lp, C[1], C[2], Lp, C[2], C[3], Lp, C[3], C[0], Lp, [0, -hy, 0], [0, hy, 0], Lp, [-hx, 0, 0], [hx, 0, 0]];
|
|
189
|
+
const a = hazeGeo.attributes.position.array;
|
|
190
|
+
tris.forEach((p, i) => a.set(p, i * 3));
|
|
191
|
+
hazeGeo.attributes.position.needsUpdate = true;
|
|
192
|
+
hazeGeo.computeBoundingSphere();
|
|
193
|
+
}
|
|
194
|
+
const api = {
|
|
195
|
+
object, materials: [screenMat, hazeMat, dustMat],
|
|
196
|
+
controls: { show: (t) => pic.show(t), get busy() { return pic.busy; }, pic },
|
|
197
|
+
apply(k) { Object.assign(cfg, k); applyConfig(u, k); },
|
|
198
|
+
update(dt, pointer) {
|
|
199
|
+
dt = Math.min(dt, 0.1);
|
|
200
|
+
u.uTime.value += dt;
|
|
201
|
+
pic.step(dt);
|
|
202
|
+
stepPointer(u, pointer, dt, pst);
|
|
203
|
+
u.uDrift.value += dt * cfg.dustDrift;
|
|
204
|
+
const p = u.uP.value;
|
|
205
|
+
// the slide change: focus racks out and back with a small hunt; the carriage moves in the middle
|
|
206
|
+
const out = Math.pow(Math.sin(Math.PI * p), 1.3);
|
|
207
|
+
const hunt = cfg.hunt * 0.25 * Math.sin(Math.PI * Math.min(1, Math.max(0, (p - 0.7) / 0.3))) * (p > 0.7 ? 1 : 0);
|
|
208
|
+
u.uFocus.value = Math.max(0, cfg.defocus * (out + hunt));
|
|
209
|
+
const g = Math.min(1, Math.max(0, (p - 0.2) / 0.6));
|
|
210
|
+
u.uGate.value = g * g * (3 - 2 * g);
|
|
211
|
+
// the lamp: a slow breath, a fine flicker, a slight dip as the carriage moves; the entrance warms it up
|
|
212
|
+
flickT += dt;
|
|
213
|
+
const fl = 1 - cfg.flicker * (0.03 * Math.sin(flickT * 23) * Math.sin(flickT * 7.3) + 0.015 * Math.sin(flickT * 1.3)) - cfg.breathe * 0.01 * Math.sin(flickT * 0.5);
|
|
214
|
+
const warm = u.uHasA.value > 0.5 ? 1 : Math.min(1, p * 1.4);
|
|
215
|
+
u.uLamp.value = fl * (1 - 0.12 * out) * warm;
|
|
216
|
+
// hotspot leans toward the cursor
|
|
217
|
+
const hot = (cfg.pointerMode === 'hotspot' && pointer) ? [pointer.x * 0.25 * cfg.pointerStrength / u.uSize.value.y, pointer.y * 0.25 * cfg.pointerStrength / u.uSize.value.y] : [0, 0];
|
|
218
|
+
u.uHot.value.x += (hot[0] - u.uHot.value.x) * (1 - Math.exp(-dt * 3));
|
|
219
|
+
u.uHot.value.y += (hot[1] - u.uHot.value.y) * (1 - Math.exp(-dt * 3));
|
|
220
|
+
beam();
|
|
221
|
+
},
|
|
222
|
+
dispose() { geo.dispose(); hazeGeo.dispose(); quad.dispose(); dgeo.dispose(); screenMat.dispose(); hazeMat.dispose(); dustMat.dispose(); pic.dispose(); },
|
|
223
|
+
};
|
|
224
|
+
return api;
|
|
225
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
export declare const POINTER_MODES: string[];
|
|
3
|
+
export declare const STRUCTURAL: string[];
|
|
4
|
+
export declare function createUniforms(): {
|
|
5
|
+
uDepth: {
|
|
6
|
+
value: number;
|
|
7
|
+
};
|
|
8
|
+
uCrest: {
|
|
9
|
+
value: number;
|
|
10
|
+
};
|
|
11
|
+
uSelf: {
|
|
12
|
+
value: number;
|
|
13
|
+
};
|
|
14
|
+
uTexA: {
|
|
15
|
+
value: any;
|
|
16
|
+
};
|
|
17
|
+
uTexB: {
|
|
18
|
+
value: any;
|
|
19
|
+
};
|
|
20
|
+
uFitA: {
|
|
21
|
+
value: THREE.Vector2;
|
|
22
|
+
};
|
|
23
|
+
uFitB: {
|
|
24
|
+
value: THREE.Vector2;
|
|
25
|
+
};
|
|
26
|
+
uP: {
|
|
27
|
+
value: number;
|
|
28
|
+
};
|
|
29
|
+
uHasA: {
|
|
30
|
+
value: number;
|
|
31
|
+
};
|
|
32
|
+
uSeq: {
|
|
33
|
+
value: number;
|
|
34
|
+
};
|
|
35
|
+
uSize: {
|
|
36
|
+
value: THREE.Vector2;
|
|
37
|
+
};
|
|
38
|
+
uTime: {
|
|
39
|
+
value: number;
|
|
40
|
+
};
|
|
41
|
+
uDir: {
|
|
42
|
+
value: THREE.Vector2;
|
|
43
|
+
};
|
|
44
|
+
uSpread: {
|
|
45
|
+
value: number;
|
|
46
|
+
};
|
|
47
|
+
uBlank: {
|
|
48
|
+
value: THREE.Color;
|
|
49
|
+
};
|
|
50
|
+
uIntensity: {
|
|
51
|
+
value: number;
|
|
52
|
+
};
|
|
53
|
+
uOpacity: {
|
|
54
|
+
value: number;
|
|
55
|
+
};
|
|
56
|
+
uBreathe: {
|
|
57
|
+
value: number;
|
|
58
|
+
};
|
|
59
|
+
uPointer: {
|
|
60
|
+
value: THREE.Vector3;
|
|
61
|
+
};
|
|
62
|
+
uPointerVel: {
|
|
63
|
+
value: THREE.Vector2;
|
|
64
|
+
};
|
|
65
|
+
uPointerActive: {
|
|
66
|
+
value: number;
|
|
67
|
+
};
|
|
68
|
+
uPointerMode: {
|
|
69
|
+
value: number;
|
|
70
|
+
};
|
|
71
|
+
uPointerStrength: {
|
|
72
|
+
value: number;
|
|
73
|
+
};
|
|
74
|
+
uPointerRadius: {
|
|
75
|
+
value: number;
|
|
76
|
+
};
|
|
77
|
+
uPointerColor: {
|
|
78
|
+
value: THREE.Color;
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
export declare function applyConfig(u: any, c: any): void;
|
|
82
|
+
export declare function build(u: any, c: any): {
|
|
83
|
+
object: THREE.Group<THREE.Object3DEventMap>;
|
|
84
|
+
materials: any[];
|
|
85
|
+
controls: {
|
|
86
|
+
show: (t: any) => void;
|
|
87
|
+
readonly busy: boolean;
|
|
88
|
+
pic: {
|
|
89
|
+
st: {
|
|
90
|
+
A: any;
|
|
91
|
+
B: any;
|
|
92
|
+
aspA: number;
|
|
93
|
+
aspB: number;
|
|
94
|
+
p: number;
|
|
95
|
+
dir: number;
|
|
96
|
+
pending: any;
|
|
97
|
+
seq: number;
|
|
98
|
+
frame: number;
|
|
99
|
+
};
|
|
100
|
+
show: (tex: any) => void;
|
|
101
|
+
jump: (tex: any) => void;
|
|
102
|
+
step: (dt: any) => void;
|
|
103
|
+
readonly busy: boolean;
|
|
104
|
+
dispose(): void;
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
apply(k: any): void;
|
|
108
|
+
update(dt: any, pointer: any): void;
|
|
109
|
+
dispose(): void;
|
|
110
|
+
};
|
|
111
|
+
//# sourceMappingURL=relief.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relief.d.ts","sourceRoot":"","sources":["../../../../src/components/image/core/relief.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,eAAO,MAAM,aAAa,UAAoB,CAAC;AAC/C,eAAO,MAAM,UAAU,UAA0B,CAAC;AAElD,wBAAgB,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAE7B;AACD,wBAAgB,WAAW,CAAC,CAAC,KAAA,EAAE,CAAC,KAAA,QAG/B;AA2CD,wBAAgB,KAAK,CAAC,CAAC,KAAA,EAAE,CAAC,KAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoBzB"}
|