import { h, toRef, watch, inject } from 'https://unpkg.com/vue@3.0.5/dist/vue.esm-browser.prod.js'; import { Vector2, Vector3, Plane as Plane$1, Raycaster, WebGLRenderer, OrthographicCamera as OrthographicCamera$1, PerspectiveCamera as PerspectiveCamera$1, Group as Group$1, Scene as Scene$1, Color, BoxBufferGeometry, CircleBufferGeometry, ConeBufferGeometry, CylinderBufferGeometry, DodecahedronBufferGeometry, IcosahedronBufferGeometry, LatheBufferGeometry, OctahedronBufferGeometry, PolyhedronBufferGeometry, RingBufferGeometry, SphereBufferGeometry, TetrahedronBufferGeometry, TorusBufferGeometry, TorusKnotBufferGeometry, Curve, TubeBufferGeometry, AmbientLight as AmbientLight$1, DirectionalLight as DirectionalLight$1, PointLight as PointLight$1, SpotLight as SpotLight$1, FrontSide, MeshBasicMaterial, MeshLambertMaterial, TextureLoader, MeshMatcapMaterial, MeshPhongMaterial, MeshStandardMaterial, MeshPhysicalMaterial, ShaderChunk, UniformsUtils, ShaderLib, ShaderMaterial as ShaderMaterial$1, MeshToonMaterial, CubeTextureLoader, CubeRefractionMapping, Mesh as Mesh$1, PlaneBufferGeometry, FontLoader, TextBufferGeometry, WebGLCubeRenderTarget, RGBFormat, LinearMipmapLinearFilter, CubeCamera, BackSide, DoubleSide, InstancedMesh as InstancedMesh$1, SpriteMaterial, Sprite as Sprite$1, WebGLRenderTarget, ObjectSpaceNormalMap, Object3D, Face3, MathUtils, InstancedBufferAttribute } from 'https://unpkg.com/three@0.125.2/build/three.module.js'; import { OrbitControls } from 'https://unpkg.com/three@0.125.2/examples/jsm/controls/OrbitControls.js'; import { EffectComposer as EffectComposer$1 } from 'https://unpkg.com/three@0.125.2/examples/jsm/postprocessing/EffectComposer.js'; import { RenderPass as RenderPass$1 } from 'https://unpkg.com/three@0.125.2/examples/jsm/postprocessing/RenderPass.js'; import { BokehPass as BokehPass$1 } from 'https://unpkg.com/three@0.125.2/examples/jsm/postprocessing/BokehPass.js'; import { FilmPass as FilmPass$1 } from 'https://unpkg.com/three@0.125.2/examples/jsm/postprocessing/FilmPass.js'; import { ShaderPass } from 'https://unpkg.com/three@0.125.2/examples/jsm/postprocessing/ShaderPass.js'; import { FXAAShader } from 'https://unpkg.com/three@0.125.2/examples/jsm/shaders/FXAAShader.js'; import { HalftonePass as HalftonePass$1 } from 'https://unpkg.com/three@0.125.2/examples/jsm/postprocessing/HalftonePass.js'; import { SMAAPass as SMAAPass$1 } from 'https://unpkg.com/three@0.125.2/examples/jsm/postprocessing/SMAAPass.js'; import { UnrealBloomPass as UnrealBloomPass$1 } from 'https://unpkg.com/three@0.125.2/examples/jsm/postprocessing/UnrealBloomPass.js'; import { Pass } from 'https://unpkg.com/three@0.125.2/examples/jsm/postprocessing/Pass.js'; import { gsap, Power4 } from 'https://unpkg.com/gsap@3.5.1/index.js'; import { Geometry as Geometry$1 } from 'https://unpkg.com/three@0.125.2/examples/jsm/deprecated/Geometry.js'; import { resolveComponent, openBlock, createBlock, withCtx, createVNode, renderSlot } from 'https://unpkg.com/vue@3.0.5/dist/vue.esm-browser.prod.js'; import { GLTFLoader } from 'https://unpkg.com/three@0.125.2/examples/jsm/loaders/GLTFLoader.js'; /** * Three.js helper */ function useThree() { // default conf var conf = { canvas: null, antialias: true, alpha: false, autoClear: true, orbit_ctrl: false, mouse_move: false, mouse_raycast: false, mouse_over: false, click: false, resize: true, width: 0, height: 0, }; // size var size = { width: 1, height: 1, wWidth: 1, wHeight: 1, ratio: 1, }; // handlers var afterInitCallbacks = []; var afterResizeCallbacks = []; var beforeRenderCallbacks = []; // mouse tracking var mouse = new Vector2(); var mouseV3 = new Vector3(); var mousePlane = new Plane$1(new Vector3(0, 0, 1), 0); var raycaster = new Raycaster(); // raycast objects var intersectObjects = []; // returned object var obj = { conf: conf, renderer: null, camera: null, cameraCtrl: null, materials: {}, scene: null, size: size, mouse: mouse, mouseV3: mouseV3, init: init, dispose: dispose, render: render, renderC: renderC, setSize: setSize, onAfterInit: onAfterInit, onAfterResize: onAfterResize, offAfterResize: offAfterResize, onBeforeRender: onBeforeRender, offBeforeRender: offBeforeRender, addIntersectObject: addIntersectObject, removeIntersectObject: removeIntersectObject, }; /** * init three */ function init(params) { if (params) { Object.entries(params).forEach(function (ref) { var key = ref[0]; var value = ref[1]; conf[key] = value; }); } if (!obj.scene) { console.error('Missing Scene'); return; } if (!obj.camera) { console.error('Missing Camera'); return; } obj.renderer = new WebGLRenderer({ canvas: conf.canvas, antialias: conf.antialias, alpha: conf.alpha }); obj.renderer.autoClear = conf.autoClear; if (conf.orbit_ctrl) { obj.orbitCtrl = new OrbitControls(obj.camera, obj.renderer.domElement); if (conf.orbit_ctrl instanceof Object) { Object.entries(conf.orbit_ctrl).forEach(function (ref) { var key = ref[0]; var value = ref[1]; obj.orbitCtrl[key] = value; }); } } if (conf.width && conf.height) { setSize(conf.width, conf.height); } else if (conf.resize) { onResize(); window.addEventListener('resize', onResize); } conf.mouse_move = conf.mouse_move || conf.mouse_over; if (conf.mouse_move) { if (conf.mouse_move === 'body') { obj.mouse_move_element = document.body; } else { obj.mouse_move_element = obj.renderer.domElement; } obj.mouse_move_element.addEventListener('mousemove', onMousemove); obj.mouse_move_element.addEventListener('mouseleave', onMouseleave); } if (conf.click) { obj.renderer.domElement.addEventListener('click', onClick); } afterInitCallbacks.forEach(function (c) { return c(); }); return true; } /** * add after init callback */ function onAfterInit(callback) { afterInitCallbacks.push(callback); } /** * add after resize callback */ function onAfterResize(callback) { afterResizeCallbacks.push(callback); } /** * remove after resize callback */ function offAfterResize(callback) { afterResizeCallbacks = afterResizeCallbacks.filter(function (c) { return c !== callback; }); } /** * add before render callback */ function onBeforeRender(callback) { beforeRenderCallbacks.push(callback); } /** * remove before render callback */ function offBeforeRender(callback) { beforeRenderCallbacks = beforeRenderCallbacks.filter(function (c) { return c !== callback; }); } /** * default render */ function render() { if (obj.orbitCtrl) { obj.orbitCtrl.update(); } beforeRenderCallbacks.forEach(function (c) { return c(); }); obj.renderer.render(obj.scene, obj.camera); } /** * composer render */ function renderC() { if (obj.orbitCtrl) { obj.orbitCtrl.update(); } beforeRenderCallbacks.forEach(function (c) { return c(); }); obj.composer.render(); } /** * add intersect object */ function addIntersectObject(o) { if (intersectObjects.indexOf(o) === -1) { intersectObjects.push(o); } } /** * remove intersect object */ function removeIntersectObject(o) { var i = intersectObjects.indexOf(o); if (i !== -1) { intersectObjects.splice(i, 1); } } /** * remove listeners */ function dispose() { beforeRenderCallbacks = []; window.removeEventListener('resize', onResize); if (obj.mouse_move_element) { obj.mouse_move_element.removeEventListener('mousemove', onMousemove); obj.mouse_move_element.removeEventListener('mouseleave', onMouseleave); } obj.renderer.domElement.removeEventListener('click', onClick); if (obj.orbitCtrl) { obj.orbitCtrl.dispose(); } this.renderer.dispose(); } /** */ function updateMouse(e) { var rect = e.target.getBoundingClientRect(); mouse.x = ((e.clientX - rect.left) / size.width) * 2 - 1; mouse.y = -((e.clientY - rect.top) / size.height) * 2 + 1; } /** * click listener */ function onClick(e) { updateMouse(e); raycaster.setFromCamera(mouse, obj.camera); var objects = raycaster.intersectObjects(intersectObjects); for (var i = 0; i < objects.length; i++) { var o = objects[i].object; if (o.onClick) { o.onClick(e); } } } /** * mousemove listener */ function onMousemove(e) { updateMouse(e); onMousechange(); } /** * mouseleave listener */ function onMouseleave(e) { // mouse.x = 0; // mouse.y = 0; onMousechange(); } /** * mouse change */ function onMousechange(e) { if (conf.mouse_over || conf.mouse_raycast) { raycaster.setFromCamera(mouse, obj.camera); if (conf.mouse_raycast) { // get mouse 3d position obj.camera.getWorldDirection(mousePlane.normal); mousePlane.normal.normalize(); raycaster.ray.intersectPlane(mousePlane, mouseV3); } if (conf.mouse_over) { var onObjects = raycaster.intersectObjects(intersectObjects); var offObjects = [].concat( intersectObjects ); for (var i = 0; i < onObjects.length; i++) { var o = onObjects[i].object; if (!o.hover && o.onHover) { o.hover = true; o.onHover(true); } offObjects.splice(offObjects.indexOf(o), 1); } for (var i$1 = 0; i$1 < offObjects.length; i$1++) { var o$1 = offObjects[i$1]; if (o$1.hover && o$1.onHover) { o$1.hover = false; o$1.onHover(false); } } } } } /** * resize listener */ function onResize() { if (conf.resize === 'window') { setSize(window.innerWidth, window.innerHeight); } else { var elt = obj.renderer.domElement.parentNode; setSize(elt.clientWidth, elt.clientHeight); } afterResizeCallbacks.forEach(function (c) { return c(); }); } /** * update renderer size and camera */ function setSize(width, height) { size.width = width; size.height = height; size.ratio = width / height; obj.renderer.setSize(width, height, false); obj.camera.aspect = size.ratio; obj.camera.updateProjectionMatrix(); if (obj.composer) { obj.composer.setSize(width, height); } if (obj.camera.type === 'OrthographicCamera') { size.wWidth = obj.camera.right - obj.camera.left; size.wHeight = obj.camera.top - obj.camera.bottom; } else { var wsize = getCameraSize(); size.wWidth = wsize[0]; size.wHeight = wsize[1]; } } /** * calculate camera visible area size */ function getCameraSize() { var vFOV = (obj.camera.fov * Math.PI) / 180; var h = 2 * Math.tan(vFOV / 2) * Math.abs(obj.camera.position.z); var w = h * obj.camera.aspect; return [w, h]; } return obj; } var Renderer = { props: { antialias: Boolean, alpha: Boolean, autoClear: { type: Boolean, default: true }, mouseMove: { type: [Boolean, String], default: false }, mouseRaycast: { type: Boolean, default: false }, mouseOver: { type: Boolean, default: false }, click: { type: Boolean, default: false }, orbitCtrl: { type: [Boolean, Object], default: false }, resize: { type: [Boolean, String], default: true }, shadow: Boolean, width: String, height: String, }, setup: function setup() { return { three: useThree(), raf: true, onMountedCallbacks: [], }; }, provide: function provide() { return { three: this.three, // renderer: this.three.renderer, rendererComponent: this, }; }, mounted: function mounted() { var params = { canvas: this.$el, antialias: this.antialias, alpha: this.alpha, autoClear: this.autoClear, orbit_ctrl: this.orbitCtrl, mouse_move: this.mouseMove, mouse_raycast: this.mouseRaycast, mouse_over: this.mouseOver, click: this.click, resize: this.resize, width: this.width, height: this.height, }; if (this.three.init(params)) { this.three.renderer.shadowMap.enabled = this.shadow; if (this.three.composer) { this.animateC(); } else { this.animate(); } } this.onMountedCallbacks.forEach(function (c) { return c(); }); }, beforeUnmount: function beforeUnmount() { this.raf = false; this.three.dispose(); }, methods: { onMounted: function onMounted(callback) { this.onMountedCallbacks.push(callback); }, onBeforeRender: function onBeforeRender(callback) { this.three.onBeforeRender(callback); }, onAfterResize: function onAfterResize(callback) { this.three.onAfterResize(callback); }, animate: function animate() { if (this.raf) { requestAnimationFrame(this.animate); } this.three.render(); }, animateC: function animateC() { if (this.raf) { requestAnimationFrame(this.animateC); } this.three.renderC(); }, }, render: function render() { return h('canvas', {}, this.$slots.default()); }, }; function setFromProp(o, prop) { if (prop instanceof Object) { Object.entries(prop).forEach(function (ref) { var key = ref[0]; var value = ref[1]; o[key] = value; }); } } function propsValues(props, exclude) { var values = {}; Object.entries(props).forEach(function (ref) { var key = ref[0]; var value = ref[1]; if (!exclude || (exclude && !exclude.includes(key))) { values[key] = value; } }); return values; } function lerp(value1, value2, amount) { amount = amount < 0 ? 0 : amount; amount = amount > 1 ? 1 : amount; return value1 + (value2 - value1) * amount; } function lerpv2(v1, v2, amount) { v1.x = lerp(v1.x, v2.x, amount); v1.y = lerp(v1.y, v2.y, amount); } function lerpv3(v1, v2, amount) { v1.x = lerp(v1.x, v2.x, amount); v1.y = lerp(v1.y, v2.y, amount); v1.z = lerp(v1.z, v2.z, amount); } function limit(val, min, max) { return val < min ? min : (val > max ? max : val); } // from https://github.com/pmndrs/drei/blob/master/src/useMatcapTexture.tsx var MATCAP_ROOT = 'https://rawcdn.githack.com/emmelleppi/matcaps/9b36ccaaf0a24881a39062d05566c9e92be4aa0d'; function getMatcapUrl(hash, format) { if ( format === void 0 ) format = 1024; var fileName = "" + hash + (getMatcapFormatString(format)) + ".png"; return (MATCAP_ROOT + "/" + format + "/" + fileName); } function getMatcapFormatString(format) { switch (format) { case 64: return '-64px'; case 128: return '-128px'; case 256: return '-256px'; case 512: return '-512px'; default: return ''; } } function useBindProp(comp, prop, object) { if (comp[prop]) { var ref = toRef(comp, prop); setFromProp(object, ref.value); watch(ref, function () { setFromProp(object, ref.value); }, { deep: true }); } } var OrthographicCamera = { inject: ['three'], props: { left: { type: Number, default: -1 }, right: { type: Number, default: 1 }, top: { type: Number, default: 1 }, bottom: { type: Number, default: -1 }, near: { type: Number, default: 0.1 }, far: { type: Number, default: 2000 }, zoom: { type: Number, default: 1 }, position: { type: [Object, Vector3], default: { x: 0, y: 0, z: 0 } }, }, created: function created() { var this$1 = this; this.camera = new OrthographicCamera$1(this.left, this.right, this.top, this.bottom, this.near, this.far); useBindProp(this, 'position', this.camera.position); ['left', 'right', 'top', 'bottom', 'near', 'far', 'zoom'].forEach(function (p) { watch(function () { return this$1[p]; }, function () { this$1.camera[p] = this$1[p]; this$1.camera.updateProjectionMatrix(); }); }); this.three.camera = this.camera; }, render: function render() { return []; }, __hmrId: 'OrthographicCamera', }; var PerspectiveCamera = { inject: ['three'], props: { aspect: { type: Number, default: 1 }, far: { type: Number, default: 2000 }, fov: { type: Number, default: 50 }, near: { type: Number, default: 0.1 }, position: { type: [Object, Vector3], default: { x: 0, y: 0, z: 0 } }, }, created: function created() { var this$1 = this; this.camera = new PerspectiveCamera$1(this.fov, this.aspect, this.near, this.far); useBindProp(this, 'position', this.camera.position); ['aspect', 'far', 'fov', 'near'].forEach(function (p) { watch(function () { return this$1[p]; }, function () { this$1.camera[p] = this$1[p]; this$1.camera.updateProjectionMatrix(); }); }); this.three.camera = this.camera; }, render: function render() { return []; }, __hmrId: 'PerspectiveCamera', }; var Group = { inject: ['three', 'scene'], props: { position: Object, rotation: Object, scale: Object, }, setup: function setup(props) { var parent = inject('group', inject('scene')); var group = new Group$1(); useBindProp(props, 'position', group.position); useBindProp(props, 'rotation', group.rotation); useBindProp(props, 'scale', group.scale); return { parent: parent, group: group }; }, provide: function provide() { return { group: this.group, }; }, created: function created() { this.parent.add(this.group); }, unmounted: function unmounted() { this.parent.remove(this.group); }, render: function render() { if (this.$slots.default) { return this.$slots.default(); } return []; }, __hmrId: 'Group', }; var Scene = { inject: ['three'], props: { id: String, background: [String, Number], }, setup: function setup(props) { var scene = new Scene$1(); if (props.background) { scene.background = new Color(props.background); } watch(function () { return props.background; }, function (value) { scene.background = new Color(value); }); return { scene: scene }; }, provide: function provide() { return { scene: this.scene, }; }, mounted: function mounted() { if (!this.three.scene) { this.three.scene = this.scene; } }, methods: { // add(o) { // this.scene.add(o); // }, // remove(o) { // this.scene.remove(o); // }, }, render: function render() { if (this.$slots.default) { return this.$slots.default(); } return []; }, }; var Geometry = { emits: ['ready'], inject: ['mesh'], props: { rotateX: Number, rotateY: Number, rotateZ: Number, }, created: function created() { var this$1 = this; if (!this.mesh) { console.error('Missing parent Mesh'); } this.watchProps = []; Object.entries(this.$props).forEach(function (e) { return this$1.watchProps.push(e[0]); }); }, beforeMount: function beforeMount() { this.createGeometry(); this.rotateGeometry(); this.mesh.setGeometry(this.geometry); }, mounted: function mounted() { this.addWatchers(); }, unmounted: function unmounted() { this.geometry.dispose(); }, methods: { rotateGeometry: function rotateGeometry() { if (this.rotateX) { this.geometry.rotateX(this.rotateX); } if (this.rotateY) { this.geometry.rotateY(this.rotateY); } if (this.rotateZ) { this.geometry.rotateZ(this.rotateZ); } }, addWatchers: function addWatchers() { var this$1 = this; this.watchProps.forEach(function (prop) { watch(function () { return this$1[prop]; }, function () { this$1.refreshGeometry(); }); }); }, refreshGeometry: function refreshGeometry() { var oldGeo = this.geometry; this.createGeometry(); this.rotateGeometry(); this.mesh.setGeometry(this.geometry); oldGeo.dispose(); }, }, render: function render() { return []; }, }; var BoxGeometry = { extends: Geometry, props: { size: Number, width: { type: Number, default: 1 }, height: { type: Number, default: 1 }, depth: { type: Number, default: 1 }, widthSegments: { type: Number, default: 1 }, heightSegments: { type: Number, default: 1 }, depthSegments: { type: Number, default: 1 }, }, methods: { createGeometry: function createGeometry() { var w = this.width, h = this.height, d = this.depth; if (this.size) { w = this.size; h = this.size; d = this.size; } this.geometry = new BoxBufferGeometry(w, h, d, this.widthSegments, this.heightSegments, this.depthSegments); }, }, }; var CircleGeometry = { extends: Geometry, props: { radius: { type: Number, default: 1 }, segments: { type: Number, default: 8 }, thetaStart: { type: Number, default: 0 }, thetaLength: { type: Number, default: Math.PI * 2 }, }, methods: { createGeometry: function createGeometry() { this.geometry = new CircleBufferGeometry(this.radius, this.segments, this.thetaStart, this.thetaLength); }, }, }; var ConeGeometry = { extends: Geometry, props: { radius: { type: Number, default: 1 }, height: { type: Number, default: 1 }, radialSegments: { type: Number, default: 8 }, heightSegments: { type: Number, default: 1 }, openEnded: { type: Boolean, default: false }, thetaStart: { type: Number, default: 0 }, thetaLength: { type: Number, default: Math.PI * 2 }, }, methods: { createGeometry: function createGeometry() { this.geometry = new ConeBufferGeometry(this.radius, this.height, this.radialSegments, this.heightSegments, this.openEnded, this.thetaStart, this.thetaLength); }, }, }; var CylinderGeometry = { extends: Geometry, props: { radiusTop: { type: Number, default: 1 }, radiusBottom: { type: Number, default: 1 }, height: { type: Number, default: 1 }, radialSegments: { type: Number, default: 8 }, heightSegments: { type: Number, default: 1 }, openEnded: { type: Boolean, default: false }, thetaStart: { type: Number, default: 0 }, thetaLength: { type: Number, default: Math.PI * 2 }, }, methods: { createGeometry: function createGeometry() { this.geometry = new CylinderBufferGeometry(this.radiusTop, this.radiusBottom, this.height, this.radialSegments, this.heightSegments, this.openEnded, this.thetaStart, this.thetaLength); }, }, }; var DodecahedronGeometry = { extends: Geometry, props: { radius: { type: Number, default: 1 }, detail: { type: Number, default: 0 }, }, methods: { createGeometry: function createGeometry() { this.geometry = new DodecahedronBufferGeometry(this.radius, this.detail); }, }, }; var IcosahedronGeometry = { extends: Geometry, props: { radius: { type: Number, default: 1 }, detail: { type: Number, default: 0 }, }, methods: { createGeometry: function createGeometry() { this.geometry = new IcosahedronBufferGeometry(this.radius, this.detail); }, }, }; var LatheGeometry = { extends: Geometry, props: { points: Array, segments: { type: Number, default: 12 }, phiStart: { type: Number, default: 0 }, phiLength: { type: Number, default: Math.PI * 2 }, }, methods: { createGeometry: function createGeometry() { this.geometry = new LatheBufferGeometry(this.points, this.segments, this.phiStart, this.phiLength); }, }, }; var OctahedronGeometry = { extends: Geometry, props: { radius: { type: Number, default: 1 }, detail: { type: Number, default: 0 }, }, methods: { createGeometry: function createGeometry() { this.geometry = new OctahedronBufferGeometry(this.radius, this.detail); }, }, }; var PolyhedronGeometry = { extends: Geometry, props: { vertices: Array, indices: Array, radius: { type: Number, default: 1 }, detail: { type: Number, default: 0 }, }, methods: { createGeometry: function createGeometry() { this.geometry = new PolyhedronBufferGeometry(this.vertices, this.indices, this.radius, this.detail); }, }, }; var RingGeometry = { extends: Geometry, props: { innerRadius: { type: Number, default: 0.5 }, outerRadius: { type: Number, default: 1 }, thetaSegments: { type: Number, default: 8 }, phiSegments: { type: Number, default: 1 }, thetaStart: { type: Number, default: 0 }, thetaLength: { type: Number, default: Math.PI * 2 }, }, methods: { createGeometry: function createGeometry() { this.geometry = new RingBufferGeometry(this.innerRadius, this.outerRadius, this.thetaSegments, this.phiSegments, this.thetaStart, this.thetaLength); }, }, }; var SphereGeometry = { extends: Geometry, props: { radius: { type: Number, default: 1 }, widthSegments: { type: Number, default: 12 }, heightSegments: { type: Number, default: 12 }, }, methods: { createGeometry: function createGeometry() { this.geometry = new SphereBufferGeometry(this.radius, this.widthSegments, this.heightSegments); }, }, }; var TetrahedronGeometry = { extends: Geometry, props: { radius: { type: Number, default: 1 }, detail: { type: Number, default: 0 }, }, methods: { createGeometry: function createGeometry() { this.geometry = new TetrahedronBufferGeometry(this.radius, this.detail); }, }, }; var TorusGeometry = { extends: Geometry, props: { radius: { type: Number, default: 1 }, tube: { type: Number, default: 0.4 }, radialSegments: { type: Number, default: 8 }, tubularSegments: { type: Number, default: 6 }, arc: { type: Number, default: Math.PI * 2 }, }, methods: { createGeometry: function createGeometry() { this.geometry = new TorusBufferGeometry(this.radius, this.tube, this.radialSegments, this.tubularSegments, this.arc); }, }, }; var TorusKnotGeometry = { extends: Geometry, props: { radius: { type: Number, default: 1 }, tube: { type: Number, default: 0.4 }, radialSegments: { type: Number, default: 64 }, tubularSegments: { type: Number, default: 8 }, p: { type: Number, default: 2 }, q: { type: Number, default: 3 }, }, methods: { createGeometry: function createGeometry() { this.geometry = new TorusKnotBufferGeometry(this.radius, this.tube, this.radialSegments, this.tubularSegments, this.p, this.q); }, }, }; var TubeGeometry = { extends: Geometry, props: { path: Curve, tubularSegments: { type: Number, default: 64 }, radius: { type: Number, default: 1 }, radiusSegments: { type: Number, default: 8 }, closed: { type: Boolean, default: false }, }, methods: { createGeometry: function createGeometry() { this.geometry = new TubeBufferGeometry(this.path, this.tubularSegments, this.radius, this.radiusSegments, this.closed); }, }, }; var Light = { inject: { scene: 'scene', parent: { from: 'group', default: function () { return inject('scene'); }, }, }, props: { color: { type: String, default: '#ffffff', }, intensity: { type: Number, default: 1, }, castShadow: { type: Boolean, default: false, }, shadowMapSize: Object, position: Object, }, // can't use setup because it will not be used in sub components // setup() {}, mounted: function mounted() { var this$1 = this; useBindProp(this, 'position', this.light.position); if (this.light.target) { useBindProp(this, 'target', this.light.target.position); } if (this.light.shadow) { this.light.castShadow = this.castShadow; setFromProp(this.light.shadow.mapSize, this.shadowMapSize); } ['color', 'intensity', 'castShadow'].forEach(function (p) { watch(function () { return this$1[p]; }, function () { if (p === 'color') { this$1.light.color = new Color(this$1.color); } else { this$1.light[p] = this$1[p]; } }); }); this.parent.add(this.light); if (this.light.target) { this.parent.add(this.light.target); } }, unmounted: function unmounted() { this.parent.remove(this.light); if (this.light.target) { this.parent.remove(this.light.target); } }, render: function render() { return []; }, __hmrId: 'Light', }; var AmbientLight = { extends: Light, created: function created() { this.light = new AmbientLight$1(this.color, this.intensity); }, __hmrId: 'AmbientLight', }; var DirectionalLight = { extends: Light, props: { target: Object, }, created: function created() { this.light = new DirectionalLight$1(this.color, this.intensity); }, __hmrId: 'DirectionalLight', }; var PointLight = { extends: Light, props: { distance: { type: Number, default: 0, }, decay: { type: Number, default: 1, }, }, created: function created() { this.light = new PointLight$1(this.color, this.intensity, this.distance, this.decay); }, __hmrId: 'PointLight', }; var SpotLight = { extends: Light, props: { angle: { type: Number, default: Math.PI / 3, }, decay: { type: Number, default: 1, }, distance: { type: Number, default: 0, }, penumbra: { type: Number, default: 0, }, target: Object, }, created: function created() { var this$1 = this; this.light = new SpotLight$1(this.color, this.intensity, this.distance, this.angle, this.penumbra, this.decay); ['angle', 'decay', 'distance', 'penumbra'].forEach(function (p) { watch(function () { return this$1[p]; }, function () { this$1.light[p] = this$1[p]; }); }); }, __hmrId: 'SpotLight', }; var Material = { inject: ['three', 'mesh'], props: { id: String, color: { type: [String, Number], default: '#ffffff' }, depthTest: { type: Boolean, default: true }, depthWrite: { type: Boolean, default: true }, flatShading: Boolean, fog: { type: Boolean, default: true }, opacity: { type: Number, default: 1 }, side: { type: Number, default: FrontSide }, transparent: Boolean, vertexColors: Boolean, }, provide: function provide() { return { material: this, }; }, beforeMount: function beforeMount() { this.createMaterial(); if (this.id) { this.three.materials[this.id] = this.material; } this.mesh.setMaterial(this.material); }, mounted: function mounted() { this._addWatchers(); if (this.addWatchers) { this.addWatchers(); } }, unmounted: function unmounted() { this.material.dispose(); if (this.id) { delete this.three.materials[this.id]; } }, methods: { setProp: function setProp(key, value, needsUpdate) { if ( needsUpdate === void 0 ) needsUpdate = false; this.material[key] = value; this.material.needsUpdate = needsUpdate; }, setTexture: function setTexture(texture, key) { if ( key === void 0 ) key = 'map'; this.setProp(key, texture, true); }, _addWatchers: function _addWatchers() { var this$1 = this; // don't work for flatShading ['color', 'depthTest', 'depthWrite', 'fog', 'opacity', 'side', 'transparent'].forEach(function (p) { watch(function () { return this$1[p]; }, function () { if (p === 'color') { this$1.material.color.set(this$1.color); } else { this$1.material[p] = this$1[p]; } }); }); }, }, render: function render() { if (this.$slots.default) { return this.$slots.default(); } return []; }, __hmrId: 'Material', }; var BasicMaterial = { extends: Material, methods: { createMaterial: function createMaterial() { this.material = new MeshBasicMaterial(propsValues(this.$props, ['id'])); }, }, __hmrId: 'BasicMaterial', }; var LambertMaterial = { extends: Material, methods: { createMaterial: function createMaterial() { this.material = new MeshLambertMaterial(propsValues(this.$props, ['id'])); }, }, __hmrId: 'LambertMaterial', }; var MatcapMaterial = { extends: Material, props: { src: String, name: String, }, methods: { createMaterial: function createMaterial() { var src = this.name ? getMatcapUrl(this.name) : this.src; var opts = propsValues(this.$props, ['id', 'src', 'name']); opts.matcap = new TextureLoader().load(src); this.material = new MeshMatcapMaterial(opts); }, }, __hmrId: 'MatcapMaterial', }; var PhongMaterial = { extends: Material, props: { emissive: { type: [Number, String], default: 0 }, emissiveIntensity: { type: Number, default: 1 }, reflectivity: { type: Number, default: 1 }, shininess: { type: Number, default: 30 }, specular: { type: [String, Number], default: 0x111111 }, }, methods: { createMaterial: function createMaterial() { this.material = new MeshPhongMaterial(propsValues(this.$props, ['id'])); }, addWatchers: function addWatchers() { var this$1 = this; ['emissive', 'emissiveIntensity', 'reflectivity', 'shininess', 'specular'].forEach(function (p) { watch(function () { return this$1[p]; }, function (value) { if (p === 'emissive' || p === 'specular') { this$1.material[p].set(value); } else { this$1.material[p] = value; } }); }); }, }, __hmrId: 'PhongMaterial', }; var props = { aoMapIntensity: { type: Number, default: 1 }, bumpScale: { type: Number, default: 1 }, displacementBias: { type: Number, default: 0 }, displacementScale: { type: Number, default: 1 }, emissive: { type: [Number, String], default: 0 }, emissiveIntensity: { type: Number, default: 1 }, envMapIntensity: { type: Number, default: 1 }, lightMapIntensity: { type: Number, default: 1 }, metalness: { type: Number, default: 0 }, normalScale: { type: Object, default: function () { return new Vector2(1, 1); } }, roughness: { type: Number, default: 1 }, refractionRatio: { type: Number, default: 0.98 }, wireframe: Boolean, }; var StandardMaterial = { extends: Material, props: props, methods: { createMaterial: function createMaterial() { this.material = new MeshStandardMaterial(propsValues(this.$props, ['id', 'normalScale'])); }, addWatchers: function addWatchers() { var this$1 = this; // todo : use setProp ? Object.keys(props).forEach(function (p) { if (p === 'normalScale') { return; } watch(function () { return this$1[p]; }, function (value) { if (p === 'emissive') { this$1.material[p].set(value); } else { this$1.material[p] = value; } }); }); useBindProp(this, 'normalScale', this.material.normalScale); }, }, __hmrId: 'StandardMaterial', }; var PhysicalMaterial = { extends: StandardMaterial, methods: { createMaterial: function createMaterial() { this.material = new MeshPhysicalMaterial(propsValues(this.$props, ['id'])); }, }, __hmrId: 'PhysicalMaterial', }; /** * ------------------------------------------------------------------------------------------ * Subsurface Scattering shader * Based on three/examples/jsm/shaders/SubsurfaceScatteringShader.js * Based on GDC 2011 – Approximating Translucency for a Fast, Cheap and Convincing Subsurface Scattering Look * https://colinbarrebrisebois.com/2011/03/07/gdc-2011-approximating-translucency-for-a-fast-cheap-and-convincing-subsurface-scattering-look/ *------------------------------------------------------------------------------------------ */ function replaceAll(string, find, replace) { return string.split(find).join(replace); } var meshphongFragHead = ShaderChunk.meshphong_frag.slice(0, ShaderChunk.meshphong_frag.indexOf('void main() {')); var meshphongFragBody = ShaderChunk.meshphong_frag.slice(ShaderChunk.meshphong_frag.indexOf('void main() {')); var SubsurfaceScatteringShader = { uniforms: UniformsUtils.merge([ ShaderLib.phong.uniforms, { thicknessColor: { value: new Color(0x668597) }, thicknessDistortion: { value: 0.1 }, thicknessAmbient: { value: 0.0 }, thicknessAttenuation: { value: 0.1 }, thicknessPower: { value: 2.0 }, thicknessScale: { value: 10.0 }, } ]), vertexShader: ("\n #define USE_UV\n " + (ShaderChunk.meshphong_vert) + "\n "), fragmentShader: "\n #define USE_UV\n #define SUBSURFACE\n\n " + meshphongFragHead + "\n\n uniform float thicknessPower;\n uniform float thicknessScale;\n uniform float thicknessDistortion;\n uniform float thicknessAmbient;\n uniform float thicknessAttenuation;\n uniform vec3 thicknessColor;\n\n void RE_Direct_Scattering(const in IncidentLight directLight, const in vec2 uv, const in GeometricContext geometry, inout ReflectedLight reflectedLight) {\n #ifdef USE_COLOR\n vec3 thickness = vColor * thicknessColor;\n #else\n vec3 thickness = thicknessColor;\n #endif\n vec3 scatteringHalf = normalize(directLight.direction + (geometry.normal * thicknessDistortion));\n float scatteringDot = pow(saturate(dot(geometry.viewDir, -scatteringHalf)), thicknessPower) * thicknessScale;\n vec3 scatteringIllu = (scatteringDot + thicknessAmbient) * thickness;\n reflectedLight.directDiffuse += scatteringIllu * thicknessAttenuation * directLight.color;\n }\n " + meshphongFragBody.replace( '#include ', replaceAll( ShaderChunk.lights_fragment_begin, 'RE_Direct( directLight, geometry, material, reflectedLight );', "\n RE_Direct( directLight, geometry, material, reflectedLight );\n #if defined( SUBSURFACE ) && defined( USE_UV )\n RE_Direct_Scattering(directLight, vUv, geometry, reflectedLight);\n #endif\n " ) ), }; var ShaderMaterial = { inject: ['three', 'mesh'], props: { id: String, uniforms: Object, vertexShader: String, fragmentShader: String, }, beforeMount: function beforeMount() { this.createMaterial(); if (this.id) { this.three.materials[this.id] = this.material; } this.mesh.setMaterial(this.material); }, mounted: function mounted() { if (this.addWatchers) { this.addWatchers(); } }, unmounted: function unmounted() { this.material.dispose(); if (this.id) { delete this.three.materials[this.id]; } }, render: function render() { return []; }, __hmrId: 'ShaderMaterial', }; var SubSurfaceMaterial = { extends: ShaderMaterial, props: { diffuse: { type: String, default: '#ffffff' }, thicknessColor: { type: String, default: '#ffffff' }, thicknessDistortion: { type: Number, default: 0.4 }, thicknessAmbient: { type: Number, default: 0.01 }, thicknessAttenuation: { type: Number, default: 0.7 }, thicknessPower: { type: Number, default: 2 }, thicknessScale: { type: Number, default: 4 }, transparent: { type: Boolean, default: false }, opacity: { type: Number, default: 1 }, vertexColors: { type: Boolean, default: false }, }, methods: { createMaterial: function createMaterial() { var params = SubsurfaceScatteringShader; var uniforms = UniformsUtils.clone(params.uniforms); Object.entries(this.$props).forEach(function (ref) { var key = ref[0]; var value = ref[1]; if (key === 'diffuse' || key === 'thicknessColor') { value = new Color(value); } if (key !== 'id' && key !== 'transparent' && key !== 'vertexColors') { uniforms[key].value = value; } }); this.material = new ShaderMaterial$1(Object.assign({}, params, {uniforms: uniforms, lights: true, transparent: this.transparent, vertexColors: this.vertexColors})); }, }, __hmrId: 'SubSurfaceMaterial', }; var ToonMaterial = { extends: Material, methods: { createMaterial: function createMaterial() { this.material = new MeshToonMaterial(propsValues(this.$props, ['id'])); }, }, __hmrId: 'ToonMaterial', }; var Texture = { inject: ['material'], emits: ['loaded'], props: { src: String, onLoad: Function, onProgress: Function, onError: Function, id: { type: String, default: 'map' }, }, created: function created() { var this$1 = this; this.refreshTexture(); watch(function () { return this$1.src; }, this.refreshTexture); }, unmounted: function unmounted() { this.material.setTexture(null, this.id); this.texture.dispose(); }, methods: { createTexture: function createTexture() { this.texture = new TextureLoader().load(this.src, this.onLoaded, this.onProgress, this.onError); }, refreshTexture: function refreshTexture() { this.createTexture(); this.material.setTexture(this.texture, this.id); }, onLoaded: function onLoaded() { if (this.onLoad) { this.onLoad(); } this.$emit('loaded'); }, }, render: function render() { return []; }, }; var CubeTexture = { inject: ['material'], emits: ['loaded'], props: { path: String, urls: { type: Array, default: ['px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg'], }, onLoad: Function, onProgress: Function, onError: Function, id: { type: String, default: 'envMap' }, refraction: Boolean, // todo: remove ? refractionRatio: { type: Number, default: 0.98 }, }, created: function created() { var this$1 = this; this.refreshTexture(); watch(function () { return this$1.path; }, this.refreshTexture); watch(function () { return this$1.urls; }, this.refreshTexture); }, unmounted: function unmounted() { this.material.setTexture(null, this.id); this.texture.dispose(); }, methods: { createTexture: function createTexture() { this.texture = new CubeTextureLoader() .setPath(this.path) .load(this.urls, this.onLoaded, this.onProgress, this.onError); }, refreshTexture: function refreshTexture() { this.createTexture(); this.material.setTexture(this.texture, this.id); if (this.refraction) { this.texture.mapping = CubeRefractionMapping; this.material.setProp('refractionRatio', this.refractionRatio); } }, onLoaded: function onLoaded() { if (this.onLoad) { this.onLoad(); } this.$emit('loaded'); }, }, render: function render() { return []; }, }; var Mesh = { inject: { three: 'three', scene: 'scene', rendererComponent: 'rendererComponent', parent: { from: 'group', default: function () { return inject('scene'); }, }, }, emits: ['ready'], props: { materialId: String, position: Object, rotation: Object, scale: Object, castShadow: Boolean, receiveShadow: Boolean, onHover: Function, onClick: Function, }, // can't use setup because it will not be used in sub components // setup() {}, provide: function provide() { return { mesh: this, }; }, mounted: function mounted() { // console.log('Mesh mounted'); if (this.geometry && !this.mesh) { this.initMesh(); } }, unmounted: function unmounted() { // console.log('Mesh unmounted'); if (this.mesh) { this.three.removeIntersectObject(this.mesh); this.parent.remove(this.mesh); } if (this.geometry) { this.geometry.dispose(); } if (this.material && !this.materialId) { this.material.dispose(); } }, methods: { initMesh: function initMesh() { var this$1 = this; if (!this.material && this.materialId) { this.material = this.three.materials[this.materialId]; } this.mesh = new Mesh$1(this.geometry, this.material); if (this.onHover) { this.mesh.onHover = function (over) { this$1.onHover({ component: this$1, over: over }); }; this.three.addIntersectObject(this.mesh); } if (this.onClick) { this.mesh.onClick = function (e) { this$1.onClick({ component: this$1, event: e }); }; this.three.addIntersectObject(this.mesh); } this.bindProps(); this.parent.add(this.mesh); this.$emit('ready'); }, bindProps: function bindProps() { var this$1 = this; useBindProp(this, 'position', this.mesh.position); useBindProp(this, 'rotation', this.mesh.rotation); useBindProp(this, 'scale', this.mesh.scale); ['castShadow', 'receiveShadow'].forEach(function (p) { this$1.mesh[p] = this$1[p]; watch(function () { return this$1[p]; }, function () { this$1.mesh[p] = this$1[p]; }); }); watch(function () { return this$1.materialId; }, function () { this$1.mesh.material = this$1.three.materials[this$1.materialId]; }); }, setGeometry: function setGeometry(geometry) { this.geometry = geometry; if (this.mesh) { this.mesh.geometry = geometry; } }, setMaterial: function setMaterial(material) { this.material = material; if (this.mesh) { this.mesh.material = material; } }, refreshGeometry: function refreshGeometry() { var oldGeo = this.geometry; this.createGeometry(); this.mesh.geometry = this.geometry; oldGeo.dispose(); }, }, render: function render() { if (this.$slots.default) { return this.$slots.default(); } return []; }, __hmrId: 'Mesh', }; var Box = { extends: Mesh, props: { size: Number, width: { type: Number, default: 1 }, height: { type: Number, default: 1 }, depth: { type: Number, default: 1 }, widthSegments: { type: Number, default: 1 }, heightSegments: { type: Number, default: 1 }, depthSegments: { type: Number, default: 1 }, }, created: function created() { var this$1 = this; this.createGeometry(); ['size', 'width', 'height', 'depth', 'widthSegments', 'heightSegments', 'depthSegments'].forEach(function (prop) { watch(function () { return this$1[prop]; }, function () { this$1.refreshGeometry(); }); }); }, methods: { createGeometry: function createGeometry() { if (this.size) { this.geometry = new BoxBufferGeometry(this.size, this.size, this.size); } else { this.geometry = new BoxBufferGeometry(this.width, this.height, this.depth); } }, }, __hmrId: 'Box', }; var Circle = { extends: Mesh, props: { radius: { type: Number, default: 1 }, segments: { type: Number, default: 8 }, thetaStart: { type: Number, default: 0 }, thetaLength: { type: Number, default: Math.PI * 2 }, }, created: function created() { var this$1 = this; this.createGeometry(); var watchProps = ['radius', 'segments', 'thetaStart', 'thetaLength']; watchProps.forEach(function (prop) { watch(function () { return this$1[prop]; }, function () { this$1.refreshGeometry(); }); }); }, methods: { createGeometry: function createGeometry() { this.geometry = new CircleBufferGeometry(this.radius, this.segments, this.thetaStart, this.thetaLength); }, }, __hmrId: 'Circle', }; var Cone = { extends: Mesh, props: { radius: { type: Number, default: 1 }, height: { type: Number, default: 1 }, radialSegments: { type: Number, default: 8 }, heightSegments: { type: Number, default: 1 }, openEnded: { type: Boolean, default: false }, thetaStart: { type: Number, default: 0 }, thetaLength: { type: Number, default: Math.PI * 2 }, }, created: function created() { var this$1 = this; this.createGeometry(); var watchProps = ['radius', 'height', 'radialSegments', 'heightSegments', 'openEnded', 'thetaStart', 'thetaLength']; watchProps.forEach(function (prop) { watch(function () { return this$1[prop]; }, function () { this$1.refreshGeometry(); }); }); }, methods: { createGeometry: function createGeometry() { this.geometry = new ConeBufferGeometry(this.radius, this.height, this.radialSegments, this.heightSegments, this.openEnded, this.thetaStart, this.thetaLength); }, }, __hmrId: 'Cone', }; var Cylinder = { extends: Mesh, props: { radiusTop: { type: Number, default: 1 }, radiusBottom: { type: Number, default: 1 }, height: { type: Number, default: 1 }, radialSegments: { type: Number, default: 8 }, heightSegments: { type: Number, default: 1 }, openEnded: { type: Boolean, default: false }, thetaStart: { type: Number, default: 0 }, thetaLength: { type: Number, default: Math.PI * 2 }, }, created: function created() { var this$1 = this; this.createGeometry(); var watchProps = ['radiusTop', 'radiusBottom', 'height', 'radialSegments', 'heightSegments', 'openEnded', 'thetaStart', 'thetaLength']; watchProps.forEach(function (prop) { watch(function () { return this$1[prop]; }, function () { this$1.refreshGeometry(); }); }); }, methods: { createGeometry: function createGeometry() { this.geometry = new CylinderBufferGeometry(this.radiusTop, this.radiusBottom, this.height, this.radialSegments, this.heightSegments, this.openEnded, this.thetaStart, this.thetaLength); }, }, __hmrId: 'Cylinder', }; var Dodecahedron = { extends: Mesh, props: { radius: { type: Number, default: 1 }, detail: { type: Number, default: 0 }, }, created: function created() { var this$1 = this; this.createGeometry(); var watchProps = ['radius', 'detail']; watchProps.forEach(function (prop) { watch(function () { return this$1[prop]; }, function () { this$1.refreshGeometry(); }); }); }, methods: { createGeometry: function createGeometry() { this.geometry = new DodecahedronBufferGeometry(this.radius, this.detail); }, }, __hmrId: 'Dodecahedron', }; var Icosahedron = { extends: Mesh, props: { radius: { type: Number, default: 1 }, detail: { type: Number, default: 0 }, }, created: function created() { var this$1 = this; this.createGeometry(); var watchProps = ['radius', 'detail']; watchProps.forEach(function (prop) { watch(function () { return this$1[prop]; }, function () { this$1.refreshGeometry(); }); }); }, methods: { createGeometry: function createGeometry() { this.geometry = new IcosahedronBufferGeometry(this.radius, this.detail); }, }, __hmrId: 'Icosahedron', }; var Lathe = { extends: Mesh, props: { points: Array, segments: { type: Number, default: 12 }, phiStart: { type: Number, default: 0 }, phiLength: { type: Number, default: Math.PI * 2 }, }, created: function created() { var this$1 = this; this.createGeometry(); var watchProps = ['points', 'segments', 'phiStart', 'phiLength']; watchProps.forEach(function (prop) { watch(function () { return this$1[prop]; }, function () { this$1.refreshGeometry(); }); }); }, methods: { createGeometry: function createGeometry() { this.geometry = new LatheBufferGeometry(this.points, this.segments, this.phiStart, this.phiLength); }, }, __hmrId: 'Lathe', }; var Octahedron = { extends: Mesh, props: { radius: { type: Number, default: 1 }, detail: { type: Number, default: 0 }, }, created: function created() { var this$1 = this; this.createGeometry(); var watchProps = ['radius', 'detail']; watchProps.forEach(function (prop) { watch(function () { return this$1[prop]; }, function () { this$1.refreshGeometry(); }); }); }, methods: { createGeometry: function createGeometry() { this.geometry = new OctahedronBufferGeometry(this.radius, this.detail); }, }, __hmrId: 'Octahedron', }; var Plane = { extends: Mesh, props: { width: { type: Number, default: 1 }, height: { type: Number, default: 1 }, widthSegments: { type: Number, default: 1 }, heightSegments: { type: Number, default: 1 }, }, created: function created() { var this$1 = this; this.createGeometry(); var watchProps = ['width', 'height', 'widthSegments', 'heightSegments']; watchProps.forEach(function (prop) { watch(function () { return this$1[prop]; }, function () { this$1.refreshGeometry(); }); }); }, methods: { createGeometry: function createGeometry() { this.geometry = new PlaneBufferGeometry(this.width, this.height, this.widthSegments, this.heightSegments); }, }, __hmrId: 'Plane', }; var Polyhedron = { extends: Mesh, props: { vertices: Array, indices: Array, radius: { type: Number, default: 1 }, detail: { type: Number, default: 0 }, }, created: function created() { var this$1 = this; this.createGeometry(); var watchProps = ['vertices', 'indices', 'radius', 'detail']; watchProps.forEach(function (prop) { watch(function () { return this$1[prop]; }, function () { this$1.refreshGeometry(); }); }); }, methods: { createGeometry: function createGeometry() { this.geometry = new PolyhedronBufferGeometry(this.vertices, this.indices, this.radius, this.detail); }, }, __hmrId: 'Polyhedron', }; var Ring = { extends: Mesh, props: { innerRadius: { type: Number, default: 0.5 }, outerRadius: { type: Number, default: 1 }, thetaSegments: { type: Number, default: 8 }, phiSegments: { type: Number, default: 1 }, thetaStart: { type: Number, default: 0 }, thetaLength: { type: Number, default: Math.PI * 2 }, }, created: function created() { var this$1 = this; this.createGeometry(); var watchProps = ['innerRadius', 'outerRadius', 'thetaSegments', 'phiSegments', 'thetaStart', 'thetaLength']; watchProps.forEach(function (prop) { watch(function () { return this$1[prop]; }, function () { this$1.refreshGeometry(); }); }); }, methods: { createGeometry: function createGeometry() { this.geometry = new RingBufferGeometry(this.innerRadius, this.outerRadius, this.thetaSegments, this.phiSegments, this.thetaStart, this.thetaLength); }, }, __hmrId: 'Ring', }; var Sphere = { extends: Mesh, props: { radius: Number, widthSegments: { type: Number, default: 12 }, heightSegments: { type: Number, default: 12 }, }, watch: { radius: function radius() { this.refreshGeometry(); }, widthSegments: function widthSegments() { this.refreshGeometry(); }, heightSegments: function heightSegments() { this.refreshGeometry(); }, }, created: function created() { this.createGeometry(); }, methods: { createGeometry: function createGeometry() { this.geometry = new SphereBufferGeometry(this.radius, this.widthSegments, this.heightSegments); }, }, __hmrId: 'Sphere', }; var Tetrahedron = { extends: Mesh, props: { radius: { type: Number, default: 1 }, detail: { type: Number, default: 0 }, }, created: function created() { var this$1 = this; this.createGeometry(); var watchProps = ['radius', 'detail']; watchProps.forEach(function (prop) { watch(function () { return this$1[prop]; }, function () { this$1.refreshGeometry(); }); }); }, methods: { createGeometry: function createGeometry() { this.geometry = new TetrahedronBufferGeometry(this.radius, this.detail); }, }, __hmrId: 'Tetrahedron', }; var TextProps = { text: String, fontSrc: String, size: { type: Number, default: 80 }, height: { type: Number, default: 5 }, depth: { type: Number, default: 1 }, curveSegments: { type: Number, default: 12 }, bevelEnabled: { type: Boolean, default: false }, bevelThickness: { type: Number, default: 10 }, bevelSize: { type: Number, default: 8 }, bevelOffset: { type: Number, default: 0 }, bevelSegments: { type: Number, default: 5 }, align: { type: [Boolean, String], default: false }, }; var Text = { extends: Mesh, props: Object.assign({}, TextProps), created: function created() { var this$1 = this; // add watchers var watchProps = [ 'text', 'size', 'height', 'curveSegments', 'bevelEnabled', 'bevelThickness', 'bevelSize', 'bevelOffset', 'bevelSegments', 'align' ]; watchProps.forEach(function (p) { watch(function () { return this$1[p]; }, function () { if (this$1.font) { this$1.refreshGeometry(); } }); }); var loader = new FontLoader(); loader.load(this.fontSrc, function (font) { this$1.font = font; this$1.createGeometry(); this$1.initMesh(); }); }, methods: { createGeometry: function createGeometry() { this.geometry = new TextBufferGeometry(this.text, { font: this.font, size: this.size, height: this.height, depth: this.depth, curveSegments: this.curveSegments, bevelEnabled: this.bevelEnabled, bevelThickness: this.bevelThickness, bevelSize: this.bevelSize, bevelOffset: this.bevelOffset, bevelSegments: this.bevelSegments, }); if (this.align === 'center') { this.geometry.center(); } }, }, }; var Torus = { extends: Mesh, props: { radius: { type: Number, default: 0.5 }, tube: { type: Number, default: 0.4 }, radialSegments: { type: Number, default: 8 }, tubularSegments: { type: Number, default: 6 }, arc: { type: Number, default: Math.PI * 2 }, }, created: function created() { var this$1 = this; this.createGeometry(); var watchProps = ['radius', 'tube', 'radialSegments', 'tubularSegments', 'arc']; watchProps.forEach(function (prop) { watch(function () { return this$1[prop]; }, function () { this$1.refreshGeometry(); }); }); }, methods: { createGeometry: function createGeometry() { this.geometry = new TorusBufferGeometry(this.radius, this.tube, this.radialSegments, this.tubularSegments, this.arc); }, }, __hmrId: 'Torus', }; var TorusKnot = { extends: Mesh, props: { radius: { type: Number, default: 0.5 }, tube: { type: Number, default: 0.4 }, radialSegments: { type: Number, default: 64 }, tubularSegments: { type: Number, default: 8 }, p: { type: Number, default: 2 }, q: { type: Number, default: 3 }, }, created: function created() { var this$1 = this; this.createGeometry(); var watchProps = ['radius', 'tube', 'radialSegments', 'tubularSegments', 'p', 'q']; watchProps.forEach(function (prop) { watch(function () { return this$1[prop]; }, function () { this$1.refreshGeometry(); }); }); }, methods: { createGeometry: function createGeometry() { this.geometry = new TorusKnotBufferGeometry(this.radius, this.tube, this.radialSegments, this.tubularSegments, this.p, this.q); }, }, __hmrId: 'TorusKnot', }; var Tube = { extends: Mesh, props: { path: Curve, tubularSegments: { type: Number, default: 64 }, radius: { type: Number, default: 1 }, radialSegments: { type: Number, default: 8 }, closed: { type: Boolean, default: false }, }, created: function created() { var this$1 = this; this.createGeometry(); var watchProps = ['path', 'tubularSegments', 'radius', 'radialSegments', 'closed']; watchProps.forEach(function (prop) { watch(function () { return this$1[prop]; }, function () { this$1.refreshGeometry(); }); }); }, methods: { createGeometry: function createGeometry() { this.geometry = new TubeBufferGeometry(this.path, this.tubularSegments, this.radius, this.radialSegments, this.closed); }, }, __hmrId: 'Tube', }; var Gem = { extends: Mesh, props: { cubeRTSize: { type: Number, default: 256 }, cubeCameraNear: { type: Number, default: 0.1 }, cubeCameraFar: { type: Number, default: 2000 }, autoUpdate: Boolean, }, mounted: function mounted() { this.initGem(); if (this.autoUpdate) { this.three.onBeforeRender(this.updateCubeRT); } else { this.rendererComponent.onMounted(this.updateCubeRT); } }, unmounted: function unmounted() { this.three.offBeforeRender(this.updateCubeRT); if (this.meshBack) { this.parent.remove(this.meshBack); } if (this.materialBack) { this.materialBack.dispose(); } }, methods: { initGem: function initGem() { var cubeRT = new WebGLCubeRenderTarget(this.cubeRTSize, { format: RGBFormat, generateMipmaps: true, minFilter: LinearMipmapLinearFilter }); this.cubeCamera = new CubeCamera(this.cubeCameraNear, this.cubeCameraFar, cubeRT); useBindProp(this, 'position', this.cubeCamera.position); this.parent.add(this.cubeCamera); this.material.side = FrontSide; this.material.envMap = cubeRT.texture; this.material.envMapIntensity = 10; this.material.metalness = 0; this.material.roughness = 0; this.material.opacity = 0.75; this.material.transparent = true; this.material.premultipliedAlpha = true; this.material.needsUpdate = true; this.materialBack = this.material.clone(); this.materialBack.side = BackSide; this.materialBack.envMapIntensity = 5; this.materialBack.metalness = 1; this.materialBack.roughness = 0; this.materialBack.opacity = 0.5; this.meshBack = new Mesh$1(this.geometry, this.materialBack); useBindProp(this, 'position', this.meshBack.position); useBindProp(this, 'rotation', this.meshBack.rotation); useBindProp(this, 'scale', this.meshBack.scale); this.parent.add(this.meshBack); }, updateCubeRT: function updateCubeRT() { this.mesh.visible = false; this.meshBack.visible = false; this.cubeCamera.update(this.three.renderer, this.scene); this.mesh.visible = true; this.meshBack.visible = true; }, }, __hmrId: 'Gem', }; var Image = { emits: ['loaded'], extends: Mesh, props: { src: String, width: Number, height: Number, keepSize: Boolean, }, created: function created() { var this$1 = this; this.createGeometry(); this.createMaterial(); this.initMesh(); watch(function () { return this$1.src; }, this.refreshTexture); ['width', 'height'].forEach(function (p) { watch(function () { return this$1[p]; }, this$1.resize); }); if (this.keepSize) { this.three.onAfterResize(this.resize); } }, methods: { createGeometry: function createGeometry() { this.geometry = new PlaneBufferGeometry(1, 1, 1, 1); }, createMaterial: function createMaterial() { this.material = new MeshBasicMaterial({ side: DoubleSide, map: this.loadTexture() }); }, loadTexture: function loadTexture() { return new TextureLoader().load(this.src, this.onLoaded); }, refreshTexture: function refreshTexture() { if (this.texture) { this.texture.dispose(); } this.material.map = this.loadTexture(); this.material.needsUpdate = true; }, onLoaded: function onLoaded(texture) { this.texture = texture; this.resize(); this.$emit('loaded'); }, resize: function resize() { if (!this.texture) { return; } var screen = this.three.size; var iW = this.texture.image.width; var iH = this.texture.image.height; var iRatio = iW / iH; var w, h; if (this.width && this.height) { w = this.width * screen.wWidth / screen.width; h = this.height * screen.wHeight / screen.height; } else if (this.width) { w = this.width * screen.wWidth / screen.width; h = w / iRatio; } else if (this.height) { h = this.height * screen.wHeight / screen.height; w = h * iRatio; } this.mesh.scale.x = w; this.mesh.scale.y = h; }, }, __hmrId: 'Image', }; var InstancedMesh = { inject: ['three', 'scene'], props: { materialId: String, count: Number, position: Object, castShadow: Boolean, receiveShadow: Boolean, }, setup: function setup() { var parent = inject('group', inject('scene')); return { parent: parent }; }, provide: function provide() { return { mesh: this, }; }, beforeMount: function beforeMount() { if (!this.$slots.default) { console.error('Missing Geometry'); } }, mounted: function mounted() { this.initMesh(); }, unmounted: function unmounted() { this.parent.remove(this.mesh); }, methods: { initMesh: function initMesh() { var this$1 = this; if (!this.material && this.materialId) { this.material = this.three.materials[this.materialId]; } this.mesh = new InstancedMesh$1(this.geometry, this.material, this.count); useBindProp(this, 'position', this.mesh.position); useBindProp(this, 'rotation', this.mesh.rotation); useBindProp(this, 'scale', this.mesh.scale); ['castShadow', 'receiveShadow'].forEach(function (p) { this$1.mesh[p] = this$1[p]; watch(function () { return this$1[p]; }, function () { this$1.mesh[p] = this$1[p]; }); }); // watch(() => this.materialId, () => { // this.mesh.material = this.three.materials[this.materialId]; // }); this.parent.add(this.mesh); }, setGeometry: function setGeometry(geometry) { this.geometry = geometry; if (this.mesh) { this.mesh.geometry = geometry; } }, setMaterial: function setMaterial(material) { this.material = material; if (this.mesh) { this.mesh.material = material; } }, }, render: function render() { return this.$slots.default(); }, __hmrId: 'InstancedMesh', }; var MirrorMesh = { extends: Mesh, props: { cubeRTSize: { type: Number, default: 256 }, cubeCameraNear: { type: Number, default: 0.1 }, cubeCameraFar: { type: Number, default: 2000 }, autoUpdate: Boolean, }, mounted: function mounted() { this.initMirrorMesh(); if (this.autoUpdate) { this.three.onBeforeRender(this.updateCubeRT); } else { this.rendererComponent.onMounted(this.updateCubeRT); } }, unmounted: function unmounted() { this.three.offBeforeRender(this.updateCubeRT); if (this.cubeCamera) { this.parent.remove(this.cubeCamera); } }, methods: { initMirrorMesh: function initMirrorMesh() { var cubeRT = new WebGLCubeRenderTarget(this.cubeRTSize, { format: RGBFormat, generateMipmaps: true, minFilter: LinearMipmapLinearFilter }); this.cubeCamera = new CubeCamera(this.cubeCameraNear, this.cubeCameraFar, cubeRT); this.parent.add(this.cubeCamera); this.material.envMap = cubeRT.texture; this.material.needsUpdate = true; }, updateCubeRT: function updateCubeRT() { this.mesh.visible = false; this.cubeCamera.update(this.three.renderer, this.scene); this.mesh.visible = true; }, }, __hmrId: 'MirrorMesh', }; var RefractionMesh = { extends: Mesh, props: { cubeRTSize: { type: Number, default: 256 }, cubeCameraNear: { type: Number, default: 0.1 }, cubeCameraFar: { type: Number, default: 2000 }, refractionRatio: { type: Number, default: 0.98 }, autoUpdate: Boolean, }, mounted: function mounted() { this.initMirrorMesh(); if (this.autoUpdate) { this.three.onBeforeRender(this.updateCubeRT); } else { this.rendererComponent.onMounted(this.updateCubeRT); } }, unmounted: function unmounted() { this.three.offBeforeRender(this.updateCubeRT); if (this.cubeCamera) { this.parent.remove(this.cubeCamera); } }, methods: { initMirrorMesh: function initMirrorMesh() { var cubeRT = new WebGLCubeRenderTarget(this.cubeRTSize, { mapping: CubeRefractionMapping, format: RGBFormat, generateMipmaps: true, minFilter: LinearMipmapLinearFilter }); this.cubeCamera = new CubeCamera(this.cubeCameraNear, this.cubeCameraFar, cubeRT); useBindProp(this, 'position', this.cubeCamera.position); this.parent.add(this.cubeCamera); this.material.envMap = cubeRT.texture; this.material.refractionRatio = this.refractionRatio; this.material.needsUpdate = true; }, updateCubeRT: function updateCubeRT() { this.mesh.visible = false; this.cubeCamera.update(this.three.renderer, this.scene); this.mesh.visible = true; }, }, __hmrId: 'RefractionMesh', }; var Sprite = { emits: ['ready', 'loaded'], inject: ['three', 'scene'], props: { src: String, position: Object, scale: Object, }, setup: function setup() { var parent = inject('group', inject('scene')); return { parent: parent }; }, mounted: function mounted() { this.texture = new TextureLoader().load(this.src, this.onLoaded); this.material = new SpriteMaterial({ map: this.texture }); this.sprite = new Sprite$1(this.material); this.geometry = this.sprite.geometry; useBindProp(this, 'position', this.sprite.position); useBindProp(this, 'scale', this.sprite.scale); this.parent.add(this.sprite); this.$emit('ready'); }, unmounted: function unmounted() { this.texture.dispose(); this.material.dispose(); this.parent.remove(this.sprite); }, methods: { onLoaded: function onLoaded() { this.updateUV(); this.$emit('loaded'); }, updateUV: function updateUV() { this.iWidth = this.texture.image.width; this.iHeight = this.texture.image.height; this.iRatio = this.iWidth / this.iHeight; var x = 0.5, y = 0.5; if (this.iRatio > 1) { y = 0.5 / this.iRatio; } else { x = 0.5 / this.iRatio; } var positions = this.geometry.attributes.position.array; positions[0] = -x; positions[1] = -y; positions[5] = x; positions[6] = -y; positions[10] = x; positions[11] = y; positions[15] = -x; positions[16] = y; this.geometry.attributes.position.needsUpdate = true; }, }, render: function render() { return []; }, __hmrId: 'Sprite', }; var EffectComposer = { setup: function setup() { return { passes: [], }; }, inject: ['three'], provide: function provide() { return { passes: this.passes, }; }, mounted: function mounted() { var this$1 = this; this.three.onAfterInit(function () { this$1.composer = new EffectComposer$1(this$1.three.renderer); this$1.three.renderer.autoClear = false; this$1.passes.forEach(function (pass) { this$1.composer.addPass(pass); }); this$1.three.composer = this$1.composer; this$1.resize(); this$1.three.onAfterResize(this$1.resize); }); }, unmounted: function unmounted() { this.three.offAfterResize(this.resize); }, methods: { resize: function resize() { this.composer.setSize(this.three.size.width, this.three.size.height); }, }, render: function render() { return this.$slots.default(); }, __hmrId: 'EffectComposer', }; var EffectPass = { inject: ['three', 'passes'], beforeMount: function beforeMount() { if (!this.passes) { console.error('Missing parent EffectComposer'); } }, unmounted: function unmounted() { if (this.pass.dispose) { this.pass.dispose(); } }, render: function render() { return []; }, __hmrId: 'EffectPass', }; var RenderPass = { extends: EffectPass, mounted: function mounted() { if (!this.three.scene) { console.error('Missing Scene'); } if (!this.three.camera) { console.error('Missing Camera'); } var pass = new RenderPass$1(this.three.scene, this.three.camera); this.passes.push(pass); this.pass = pass; }, __hmrId: 'RenderPass', }; var BokehPass = { extends: EffectPass, props: { focus: { type: Number, default: 1, }, aperture: { type: Number, default: 0.025, }, maxblur: { type: Number, default: 0.01, }, }, watch: { focus: function focus() { this.pass.uniforms.focus.value = this.focus; }, aperture: function aperture() { this.pass.uniforms.aperture.value = this.aperture; }, maxblur: function maxblur() { this.pass.uniforms.maxblur.value = this.maxblur; }, }, mounted: function mounted() { if (!this.three.scene) { console.error('Missing Scene'); } if (!this.three.camera) { console.error('Missing Camera'); } var params = { focus: this.focus, aperture: this.aperture, maxblur: this.maxblur, width: this.three.size.width, height: this.three.size.height, }; var pass = new BokehPass$1(this.three.scene, this.three.camera, params); this.passes.push(pass); this.pass = pass; }, __hmrId: 'BokehPass', }; var FilmPass = { extends: EffectPass, props: { noiseIntensity: { type: Number, default: 0.5, }, scanlinesIntensity: { type: Number, default: 0.05, }, scanlinesCount: { type: Number, default: 4096, }, grayscale: { type: Number, default: 0, }, }, watch: { noiseIntensity: function noiseIntensity() { this.pass.uniforms.nIntensity.value = this.noiseIntensity; }, scanlinesIntensity: function scanlinesIntensity() { this.pass.uniforms.sIntensity.value = this.scanlinesIntensity; }, scanlinesCount: function scanlinesCount() { this.pass.uniforms.sCount.value = this.scanlinesCount; }, grayscale: function grayscale() { this.pass.uniforms.grayscale.value = this.grayscale; }, }, mounted: function mounted() { var pass = new FilmPass$1(this.noiseIntensity, this.scanlinesIntensity, this.scanlinesCount, this.grayscale); this.passes.push(pass); this.pass = pass; }, __hmrId: 'FilmPass', }; var FXAAPass = { extends: EffectPass, mounted: function mounted() { var pass = new ShaderPass(FXAAShader); this.passes.push(pass); this.pass = pass; // resize will be called in three init this.three.onAfterResize(this.resize); }, unmounted: function unmounted() { this.three.offAfterResize(this.resize); }, methods: { resize: function resize() { var ref = this.pass.material.uniforms; var resolution = ref.resolution; resolution.value.x = 1 / this.three.size.width; resolution.value.y = 1 / this.three.size.height; }, }, __hmrId: 'FXAAPass', }; var HalftonePass = { extends: EffectPass, props: { shape: { type: Number, default: 1 }, radius: { type: Number, default: 4 }, rotateR: { type: Number, default: Math.PI / 12 * 1 }, rotateG: { type: Number, default: Math.PI / 12 * 2 }, rotateB: { type: Number, default: Math.PI / 12 * 3 }, scatter: { type: Number, default: 0 }, }, mounted: function mounted() { var this$1 = this; var pass = new HalftonePass$1(this.three.size.width, this.three.size.height, {}); ['shape', 'radius', 'rotateR', 'rotateG', 'rotateB', 'scatter'].forEach(function (p) { pass.uniforms[p].value = this$1[p]; watch(function () { return this$1[p]; }, function () { pass.uniforms[p].value = this$1[p]; }); }); this.passes.push(pass); this.pass = pass; }, __hmrId: 'HalftonePass', }; var SMAAPass = { extends: EffectPass, mounted: function mounted() { // three size is not set yet, but this pass will be resized by effect composer var pass = new SMAAPass$1(this.three.size.width, this.three.size.height); this.passes.push(pass); this.pass = pass; }, __hmrId: 'SMAAPass', }; var DefaultShader = { uniforms: {}, vertexShader: "\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n ", fragmentShader: "\n varying vec2 vUv;\n void main() {\n gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n }\n ", }; // From https://github.com/evanw/glfx.js var TiltShift = { uniforms: { tDiffuse: { value: null }, blurRadius: { value: 0 }, gradientRadius: { value: 0 }, start: { value: new Vector2() }, end: { value: new Vector2() }, delta: { value: new Vector2() }, texSize: { value: new Vector2() }, }, vertexShader: DefaultShader.vertexShader, fragmentShader: "\n uniform sampler2D tDiffuse;\n uniform float blurRadius;\n uniform float gradientRadius;\n uniform vec2 start;\n uniform vec2 end;\n uniform vec2 delta;\n uniform vec2 texSize;\n varying vec2 vUv;\n\n float random(vec3 scale, float seed) {\n /* use the fragment position for a different seed per-pixel */\n return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed);\n }\n\n void main() {\n vec4 color = vec4(0.0);\n float total = 0.0;\n\n /* randomize the lookup values to hide the fixed number of samples */\n float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);\n\n vec2 normal = normalize(vec2(start.y - end.y, end.x - start.x));\n float radius = smoothstep(0.0, 1.0, abs(dot(vUv * texSize - start, normal)) / gradientRadius) * blurRadius;\n for (float t = -30.0; t <= 30.0; t++) {\n float percent = (t + offset - 0.5) / 30.0;\n float weight = 1.0 - abs(percent);\n vec4 texel = texture2D(tDiffuse, vUv + delta / texSize * percent * radius);\n // vec4 texel2 = texture2D(tDiffuse, vUv + vec2(-delta.y, delta.x) / texSize * percent * radius);\n\n /* switch to pre-multiplied alpha to correctly blur transparent images */\n texel.rgb *= texel.a;\n // texel2.rgb *= texel2.a;\n\n color += texel * weight;\n total += 2.0 * weight;\n }\n\n gl_FragColor = color / total;\n\n /* switch back from pre-multiplied alpha */\n gl_FragColor.rgb /= gl_FragColor.a + 0.00001;\n }\n ", }; function useBindPropValue(src, srcProp, dst, dstProp) { if ( dstProp === void 0 ) dstProp = 'value'; if (src[srcProp]) { dst[dstProp] = src[srcProp]; watch(function () { return src[srcProp]; }, function (value) { dst[dstProp] = value; }); } } var TiltShiftPass = { extends: EffectPass, props: { blurRadius: { type: Number, default: 10 }, gradientRadius: { type: Number, default: 100 }, start: { type: Object, default: { x: 0, y: 100 } }, end: { type: Object, default: { x: 10, y: 100 } }, }, mounted: function mounted() { var this$1 = this; this.pass = new ShaderPass(TiltShift); this.passes.push(this.pass); this.pass1 = new ShaderPass(TiltShift); this.passes.push(this.pass1); var uniforms = this.uniforms = this.pass.uniforms; var uniforms1 = this.uniforms1 = this.pass1.uniforms; uniforms1.blurRadius = uniforms.blurRadius; uniforms1.gradientRadius = uniforms.gradientRadius; uniforms1.start = uniforms.start; uniforms1.end = uniforms.end; uniforms1.texSize = uniforms.texSize; useBindPropValue(this, 'blurRadius', uniforms.blurRadius); useBindPropValue(this, 'gradientRadius', uniforms.gradientRadius); this.updateFocusLine(); ['start', 'end'].forEach(function (p) { watch(function () { return this$1[p]; }, this$1.updateFocusLine); }); this.pass.setSize = function (width, height) { uniforms.texSize.value.set(width, height); }; }, methods: { updateFocusLine: function updateFocusLine() { this.uniforms.start.value.copy(this.start); this.uniforms.end.value.copy(this.end); var dv = new Vector2().copy(this.end).sub(this.start).normalize(); this.uniforms.delta.value.copy(dv); this.uniforms1.delta.value.set(-dv.y, dv.x); }, }, __hmrId: 'TiltShiftPass', }; var UnrealBloomPass = { extends: EffectPass, props: { strength: { type: Number, default: 1.5 }, radius: { type: Number, default: 0 }, threshold: { type: Number, default: 0 }, }, watch: { strength: function strength() { this.pass.strength = this.strength; }, radius: function radius() { this.pass.radius = this.radius; }, threshold: function threshold() { this.pass.threshold = this.threshold; }, }, mounted: function mounted() { var size = new Vector2(this.three.size.width, this.three.size.height); var pass = new UnrealBloomPass$1(size, this.strength, this.radius, this.threshold); this.passes.push(pass); this.pass = pass; }, __hmrId: 'UnrealBloomPass', }; // From https://github.com/evanw/glfx.js var ZoomBlur = { uniforms: { tDiffuse: { value: null }, center: { value: new Vector2(0.5, 0.5) }, strength: { value: 0 }, }, vertexShader: DefaultShader.vertexShader, fragmentShader: "\n uniform sampler2D tDiffuse;\n uniform vec2 center;\n uniform float strength;\n varying vec2 vUv;\n\n float random(vec3 scale, float seed) {\n /* use the fragment position for a different seed per-pixel */\n return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed);\n }\n \n void main() {\n vec4 color = vec4(0.0);\n float total = 0.0;\n vec2 toCenter = center - vUv;\n \n /* randomize the lookup values to hide the fixed number of samples */\n float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);\n \n for (float t = 0.0; t <= 40.0; t++) {\n float percent = (t + offset) / 40.0;\n float weight = 4.0 * (percent - percent * percent);\n vec4 texel = texture2D(tDiffuse, vUv + toCenter * percent * strength);\n\n /* switch to pre-multiplied alpha to correctly blur transparent images */\n texel.rgb *= texel.a;\n\n color += texel * weight;\n total += weight;\n }\n\n gl_FragColor = color / total;\n\n /* switch back from pre-multiplied alpha */\n gl_FragColor.rgb /= gl_FragColor.a + 0.00001;\n }\n ", }; var ZoomBlurPass = { extends: EffectPass, props: { center: { type: Object, default: { x: 0.5, y: 0.5 } }, strength: { type: Number, default: 0.5 }, }, mounted: function mounted() { this.pass = new ShaderPass(ZoomBlur); this.passes.push(this.pass); var uniforms = this.uniforms = this.pass.uniforms; useBindProp(this, 'center', uniforms.center.value); useBindPropValue(this, 'strength', uniforms.strength); }, __hmrId: 'ZoomBlurPass', }; var snoise2 = "\n//\n// Description : Array and textureless GLSL 2D simplex noise function.\n// Author : Ian McEwan, Ashima Arts.\n// Maintainer : ijm\n// Lastmod : 20110822 (ijm)\n// License : Copyright (C) 2011 Ashima Arts. All rights reserved.\n// Distributed under the MIT License. See LICENSE file.\n// https://github.com/ashima/webgl-noise\n//\n\nvec3 mod289(vec3 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\n\nvec2 mod289(vec2 x) {\n return x - floor(x * (1.0 / 289.0)) * 289.0;\n}\n\nvec3 permute(vec3 x) {\n return mod289(((x*34.0)+1.0)*x);\n}\n\nfloat snoise(vec2 v)\n{\n const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0\n 0.366025403784439, // 0.5*(sqrt(3.0)-1.0)\n -0.577350269189626, // -1.0 + 2.0 * C.x\n 0.024390243902439); // 1.0 / 41.0\n // First corner\n vec2 i = floor(v + dot(v, C.yy) );\n vec2 x0 = v - i + dot(i, C.xx);\n\n // Other corners\n vec2 i1;\n i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\n vec4 x12 = x0.xyxy + C.xxzz;\n x12.xy -= i1;\n\n // Permutations\n i = mod289(i); // Avoid truncation effects in permutation\n vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 ))\n + i.x + vec3(0.0, i1.x, 1.0 ));\n\n vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0);\n m = m*m ;\n m = m*m ;\n\n // Gradients: 41 points uniformly over a line, mapped onto a diamond.\n // The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287)\n\n vec3 x = 2.0 * fract(p * C.www) - 1.0;\n vec3 h = abs(x) - 0.5;\n vec3 ox = floor(x + 0.5);\n vec3 a0 = x - ox;\n\n // Normalise gradients implicitly by scaling m\n // Approximation of: m *= inversesqrt( a0*a0 + h*h );\n m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h );\n\n // Compute final noise value at P\n vec3 g;\n g.x = a0.x * x0.x + h.x * x0.y;\n g.yz = a0.yz * x12.xz + h.yz * x12.yw;\n return 130.0 * dot(m, g);\n}\n"; var NoisyImage = { extends: Image, props: { widthSegments: { type: Number, default: 20 }, heightSegments: { type: Number, default: 20 }, timeCoef: { type: Number, default: 0.001 }, noiseCoef: { type: Number, default: 1 }, zCoef: { type: Number, default: 5 }, dispCoef: { type: Number, default: 0.05 }, }, setup: function setup(props) { // uniforms var uTime = { value: 0 }; var uNoiseCoef = { value: props.noiseCoef }; watch(function () { return props.noiseCoef; }, function (value) { uNoiseCoef.value = value; }); var uZCoef = { value: props.zCoef }; watch(function () { return props.zCoef; }, function (value) { uZCoef.value = value; }); var uDispCoef = { value: props.dispCoef }; watch(function () { return props.dispCoef; }, function (value) { uDispCoef.value = value; }); return { uTime: uTime, uNoiseCoef: uNoiseCoef, uZCoef: uZCoef, uDispCoef: uDispCoef, }; }, mounted: function mounted() { this.startTime = Date.now(); this.three.onBeforeRender(this.updateTime); }, unmounted: function unmounted() { this.three.offBeforeRender(this.updateTime); }, methods: { createGeometry: function createGeometry() { this.geometry = new PlaneBufferGeometry(1, 1, this.widthSegments, this.heightSegments); }, createMaterial: function createMaterial() { var this$1 = this; this.material = new MeshBasicMaterial({ side: DoubleSide, map: this.loadTexture() }); this.material.onBeforeCompile = function (shader) { shader.uniforms.uTime = this$1.uTime; shader.uniforms.uNoiseCoef = this$1.uNoiseCoef; shader.uniforms.uZCoef = this$1.uZCoef; shader.uniforms.uDispCoef = this$1.uDispCoef; shader.vertexShader = "\n uniform float uTime;\n uniform float uNoiseCoef;\n uniform float uZCoef;\n varying float vNoise;\n " + snoise2 + "\n " + shader.vertexShader; shader.vertexShader = shader.vertexShader.replace( '#include ', " \n vec3 p = vec3(position * uNoiseCoef);\n p.x += uTime;\n vNoise = snoise(p.xy);\n vec3 transformed = vec3(position);\n transformed.z += vNoise * uZCoef;\n " ); shader.fragmentShader = "\n uniform float uDispCoef;\n varying float vNoise;\n " + shader.fragmentShader; shader.fragmentShader = shader.fragmentShader.replace( '#include ', "\n vec4 texelColor = texture2D(map, vUv);\n vec4 dispTexel = texture2D(map, vUv + vec2(vNoise * uDispCoef, 0));\n texelColor.r = dispTexel.r;\n diffuseColor = texelColor;\n " ); this$1.materialShader = shader; }; }, updateTime: function updateTime() { this.uTime.value = (Date.now() - this.startTime) * this.timeCoef; }, }, __hmrId: 'NoisyImage', }; var snoise3 = "\n//\n// Description : Array and textureless GLSL 2D/3D/4D simplex\n// noise functions.\n// Author : Ian McEwan, Ashima Arts.\n// Maintainer : ijm\n// Lastmod : 20110822 (ijm)\n// License : Copyright (C) 2011 Ashima Arts. All rights reserved.\n// Distributed under the MIT License. See LICENSE file.\n// https://github.com/ashima/webgl-noise\n//\n\nvec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }\nvec4 mod289(vec4 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }\nvec4 permute(vec4 x) { return mod289(((x*34.0)+1.0)*x); }\nvec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; }\n\nfloat snoise(vec3 v)\n{\n const vec2 C = vec2(1.0/6.0, 1.0/3.0) ;\n const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);\n\n // First corner\n vec3 i = floor(v + dot(v, C.yyy) );\n vec3 x0 = v - i + dot(i, C.xxx) ;\n\n // Other corners\n vec3 g = step(x0.yzx, x0.xyz);\n vec3 l = 1.0 - g;\n vec3 i1 = min( g.xyz, l.zxy );\n vec3 i2 = max( g.xyz, l.zxy );\n\n vec3 x1 = x0 - i1 + C.xxx;\n vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y\n vec3 x3 = x0 - D.yyy; // -1.0+3.0*C.x = -0.5 = -D.y\n\n // Permutations\n i = mod289(i);\n vec4 p = permute( permute( permute(\n i.z + vec4(0.0, i1.z, i2.z, 1.0 ))\n + i.y + vec4(0.0, i1.y, i2.y, 1.0 ))\n + i.x + vec4(0.0, i1.x, i2.x, 1.0 ));\n\n // Gradients: 7x7 points over a square, mapped onto an octahedron.\n // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)\n float n_ = 0.142857142857; // 1.0/7.0\n vec3 ns = n_ * D.wyz - D.xzx;\n\n vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7)\n\n vec4 x_ = floor(j * ns.z);\n vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N)\n\n vec4 x = x_ *ns.x + ns.yyyy;\n vec4 y = y_ *ns.x + ns.yyyy;\n vec4 h = 1.0 - abs(x) - abs(y);\n\n vec4 b0 = vec4( x.xy, y.xy );\n vec4 b1 = vec4( x.zw, y.zw );\n\n vec4 s0 = floor(b0)*2.0 + 1.0;\n vec4 s1 = floor(b1)*2.0 + 1.0;\n vec4 sh = -step(h, vec4(0.0));\n\n vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ;\n vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ;\n\n vec3 p0 = vec3(a0.xy,h.x);\n vec3 p1 = vec3(a0.zw,h.y);\n vec3 p2 = vec3(a1.xy,h.z);\n vec3 p3 = vec3(a1.zw,h.w);\n\n // Normalise gradients\n vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));\n p0 *= norm.x;\n p1 *= norm.y;\n p2 *= norm.z;\n p3 *= norm.w;\n\n // Mix final noise value\n vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);\n m = m * m;\n return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1),\n dot(p2,x2), dot(p3,x3) ) );\n}\n"; var NoisyPlane = { extends: Plane, props: { timeCoef: { type: Number, default: 0.001 }, noiseCoef: { type: Number, default: 5 }, deltaCoef: { type: Number, default: 1 / 512 }, displacementScale: { type: Number, default: 5 }, }, setup: function setup(props) { // uniforms var uTime = { value: 0 }; var uNoiseCoef = { value: props.noiseCoef }; watch(function () { return props.noiseCoef; }, function (value) { uNoiseCoef.value = value; }); var uDelta = { value: new Vector2(props.deltaCoef, props.deltaCoef) }; watch(function () { return props.deltaCoef; }, function (value) { uDelta.value.set(value, value); }); return { uTime: uTime, uNoiseCoef: uNoiseCoef, uDelta: uDelta, }; }, mounted: function mounted() { var this$1 = this; this.init(); watch(function () { return this$1.displacementScale; }, function (value) { this$1.material.displacementScale = value; }); this.startTime = Date.now(); this.three.onBeforeRender(this.update); }, unmounted: function unmounted() { this.three.offBeforeRender(this.update); this.fsQuad.dispose(); this.dispRT.dispose(); this.dispMat.dispose(); this.normRT.dispose(); this.normMat.dispose(); }, methods: { init: function init() { this.fsQuad = new Pass.FullScreenQuad(); // displacement map this.dispRT = new WebGLRenderTarget(512, 512, { depthBuffer: false, stencilBuffer: false }); this.dispMat = new ShaderMaterial$1({ uniforms: { uTime: this.uTime, uNoiseCoef: this.uNoiseCoef, }, vertexShader: "\n varying vec2 vUv;\n void main() {\n vUv = uv;\n // gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n gl_Position = vec4(position, 1.0);\n }\n ", fragmentShader: ("\n uniform float uTime;\n uniform float uNoiseCoef;\n varying vec2 vUv;\n " + snoise3 + "\n void main() {\n vec2 p = vec2(vUv * uNoiseCoef);\n float noise = (snoise(vec3(p.x, p.y, uTime)) + 1.0) / 2.0;\n gl_FragColor = vec4(noise, 0.0, 0.0, 1.0);\n }\n "), }); // normal map this.normRT = new WebGLRenderTarget(512, 512, { depthBuffer: false, stencilBuffer: false }); this.normMat = new ShaderMaterial$1({ uniforms: { dispMap: { value: this.dispRT.texture }, delta: this.uDelta, }, vertexShader: "\n varying vec2 vUv;\n void main() {\n vUv = uv;\n // gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n gl_Position = vec4(position, 1.0);\n }\n ", fragmentShader: "\n uniform sampler2D dispMap;\n uniform vec2 delta;\n varying vec2 vUv;\n void main() {\n // gl_FragColor = vec4(0.5, 0.5, 1.0, 0.0);\n float x1 = texture2D(dispMap, vec2(vUv.x - delta.x, vUv.y)).r;\n float x2 = texture2D(dispMap, vec2(vUv.x + delta.x, vUv.y)).r;\n float y1 = texture2D(dispMap, vec2(vUv.x, vUv.y - delta.y)).r;\n float y2 = texture2D(dispMap, vec2(vUv.x, vUv.y + delta.y)).r;\n gl_FragColor = vec4(0.5 + (x1 - x2), 0.5 + (y1 - y2), 1.0, 1.0);\n }\n ", }); this.material.displacementMap = this.dispRT.texture; this.material.displacementScale = this.displacementScale; this.material.normalMap = this.normRT.texture; this.material.normalMapType = ObjectSpaceNormalMap; // this.material.needsUpdate = true; }, update: function update() { this.uTime.value = (Date.now() - this.startTime) * this.timeCoef; this.renderDisp(); }, renderDisp: function renderDisp() { this.renderMat(this.dispMat, this.dispRT); this.renderMat(this.normMat, this.normRT); }, renderMat: function renderMat(mat, target) { var renderer = this.three.renderer; this.fsQuad.material = mat; var oldTarget = renderer.getRenderTarget(); renderer.setRenderTarget(target); this.fsQuad.render(renderer); renderer.setRenderTarget(oldTarget); }, }, __hmrId: 'NoisyPlane', }; var snoise4 = "\n//\n// Description : Array and textureless GLSL 2D/3D/4D simplex\n// noise functions.\n// Author : Ian McEwan, Ashima Arts.\n// Maintainer : ijm\n// Lastmod : 20110822 (ijm)\n// License : Copyright (C) 2011 Ashima Arts. All rights reserved.\n// Distributed under the MIT License. See LICENSE file.\n// https://github.com/ashima/webgl-noise\n//\n\nvec4 mod289(vec4 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }\nfloat mod289(float x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }\nvec4 permute(vec4 x) { return mod289(((x*34.0)+1.0)*x); }\nfloat permute(float x) { return mod289(((x*34.0)+1.0)*x); }\nvec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; }\nfloat taylorInvSqrt(float r) { return 1.79284291400159 - 0.85373472095314 * r; }\n\nvec4 grad4(float j, vec4 ip)\n{\n const vec4 ones = vec4(1.0, 1.0, 1.0, -1.0);\n vec4 p,s;\n\n p.xyz = floor( fract (vec3(j) * ip.xyz) * 7.0) * ip.z - 1.0;\n p.w = 1.5 - dot(abs(p.xyz), ones.xyz);\n s = vec4(lessThan(p, vec4(0.0)));\n p.xyz = p.xyz + (s.xyz*2.0 - 1.0) * s.www;\n\n return p;\n}\n\n// (sqrt(5) - 1)/4 = F4, used once below\n#define F4 0.309016994374947451\n\nfloat snoise(vec4 v)\n{\n const vec4 C = vec4( 0.138196601125011, // (5 - sqrt(5))/20 G4\n 0.276393202250021, // 2 * G4\n 0.414589803375032, // 3 * G4\n -0.447213595499958); // -1 + 4 * G4\n\n // First corner\n vec4 i = floor(v + dot(v, vec4(F4)) );\n vec4 x0 = v - i + dot(i, C.xxxx);\n\n // Other corners\n\n // Rank sorting originally contributed by Bill Licea-Kane, AMD (formerly ATI)\n vec4 i0;\n vec3 isX = step( x0.yzw, x0.xxx );\n vec3 isYZ = step( x0.zww, x0.yyz );\n // i0.x = dot( isX, vec3( 1.0 ) );\n i0.x = isX.x + isX.y + isX.z;\n i0.yzw = 1.0 - isX;\n // i0.y += dot( isYZ.xy, vec2( 1.0 ) );\n i0.y += isYZ.x + isYZ.y;\n i0.zw += 1.0 - isYZ.xy;\n i0.z += isYZ.z;\n i0.w += 1.0 - isYZ.z;\n\n // i0 now contains the unique values 0,1,2,3 in each channel\n vec4 i3 = clamp( i0, 0.0, 1.0 );\n vec4 i2 = clamp( i0-1.0, 0.0, 1.0 );\n vec4 i1 = clamp( i0-2.0, 0.0, 1.0 );\n\n vec4 x1 = x0 - i1 + C.xxxx;\n vec4 x2 = x0 - i2 + C.yyyy;\n vec4 x3 = x0 - i3 + C.zzzz;\n vec4 x4 = x0 + C.wwww;\n\n // Permutations\n i = mod289(i);\n float j0 = permute( permute( permute( permute(i.w) + i.z) + i.y) + i.x);\n vec4 j1 = permute( permute( permute( permute (\n i.w + vec4(i1.w, i2.w, i3.w, 1.0 ))\n + i.z + vec4(i1.z, i2.z, i3.z, 1.0 ))\n + i.y + vec4(i1.y, i2.y, i3.y, 1.0 ))\n + i.x + vec4(i1.x, i2.x, i3.x, 1.0 ));\n\n // Gradients: 7x7x6 points over a cube, mapped onto a 4-cross polytope\n // 7*7*6 = 294, which is close to the ring size 17*17 = 289.\n vec4 ip = vec4(1.0/294.0, 1.0/49.0, 1.0/7.0, 0.0) ;\n\n vec4 p0 = grad4(j0, ip);\n vec4 p1 = grad4(j1.x, ip);\n vec4 p2 = grad4(j1.y, ip);\n vec4 p3 = grad4(j1.z, ip);\n vec4 p4 = grad4(j1.w, ip);\n\n // Normalise gradients\n vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));\n p0 *= norm.x;\n p1 *= norm.y;\n p2 *= norm.z;\n p3 *= norm.w;\n p4 *= taylorInvSqrt(dot(p4,p4));\n\n // Mix contributions from the five corners\n vec3 m0 = max(0.6 - vec3(dot(x0,x0), dot(x1,x1), dot(x2,x2)), 0.0);\n vec2 m1 = max(0.6 - vec2(dot(x3,x3), dot(x4,x4) ), 0.0);\n m0 = m0 * m0;\n m1 = m1 * m1;\n return 49.0 * ( dot(m0*m0, vec3( dot( p0, x0 ), dot( p1, x1 ), dot( p2, x2 )))\n + dot(m1*m1, vec2( dot( p3, x3 ), dot( p4, x4 ) ) ) ) ;\n\n}\n"; var NoisySphere = { extends: Sphere, props: { radius: { type: Number, default: 20 }, widthSegments: { type: Number, default: 128 }, heightSegments: { type: Number, default: 128 }, timeCoef: { type: Number, default: 0.001 }, noiseCoef: { type: Number, default: 0.05 }, dispCoef: { type: Number, default: 5 }, }, setup: function setup(props) { // uniforms var uTime = { value: 0 }; var uNoiseCoef = { value: props.noiseCoef }; watch(function () { return props.noiseCoef; }, function (value) { uNoiseCoef.value = value; }); var uDispCoef = { value: props.dispCoef }; watch(function () { return props.dispCoef; }, function (value) { uDispCoef.value = value; }); return { uTime: uTime, uNoiseCoef: uNoiseCoef, uDispCoef: uDispCoef, }; }, mounted: function mounted() { this.updateMaterial(); this.startTime = Date.now(); this.three.onBeforeRender(this.updateTime); }, unmounted: function unmounted() { this.three.offBeforeRender(this.updateTime); }, methods: { updateMaterial: function updateMaterial() { var this$1 = this; this.material.onBeforeCompile = function (shader) { shader.uniforms.uTime = this$1.uTime; shader.uniforms.uNoiseCoef = this$1.uNoiseCoef; shader.uniforms.uDispCoef = this$1.uDispCoef; shader.vertexShader = "\n uniform float uTime;\n uniform float uNoiseCoef;\n uniform float uDispCoef;\n varying float vNoise;\n " + snoise4 + "\n " + shader.vertexShader; shader.vertexShader = shader.vertexShader.replace( '#include ', "\n vec4 p = vec4(vec3(position * uNoiseCoef), uTime);\n vNoise = snoise(p);\n vec3 transformed = vec3(position);\n transformed += normalize(position) * vNoise * uDispCoef;\n " ); this$1.materialShader = shader; }; this.material.needsupdate = true; }, updateTime: function updateTime() { this.uTime.value = (Date.now() - this.startTime) * this.timeCoef; }, }, __hmrId: 'NoisySphere', }; var NoisyText = { extends: Text, props: { timeCoef: { type: Number, default: 0.001 }, noiseCoef: { type: Number, default: 0.015 }, zCoef: { type: Number, default: 10 }, }, setup: function setup(props) { // uniforms var uTime = { value: 0 }; var uNoiseCoef = { value: props.noiseCoef }; watch(function () { return props.noiseCoef; }, function (value) { uNoiseCoef.value = value; }); var uZCoef = { value: props.zCoef }; watch(function () { return props.zCoef; }, function (value) { uZCoef.value = value; }); return { uTime: uTime, uNoiseCoef: uNoiseCoef, uZCoef: uZCoef, }; }, mounted: function mounted() { this.updateMaterial(); this.startTime = Date.now(); this.three.onBeforeRender(this.updateTime); }, unmounted: function unmounted() { this.three.offBeforeRender(this.updateTime); }, methods: { updateMaterial: function updateMaterial() { var this$1 = this; this.material.onBeforeCompile = function (shader) { shader.uniforms.uTime = this$1.uTime; shader.uniforms.uNoiseCoef = this$1.uNoiseCoef; shader.uniforms.uZCoef = this$1.uZCoef; shader.vertexShader = "\n uniform float uTime;\n uniform float uNoiseCoef;\n uniform float uZCoef;\n " + snoise2 + "\n " + shader.vertexShader; shader.vertexShader = shader.vertexShader.replace( '#include ', " \n vec3 p = vec3(position * uNoiseCoef);\n p.x += uTime;\n float noise = snoise(p.xy);\n vec3 transformed = vec3(position);\n transformed.z += noise * uZCoef;\n " ); this$1.materialShader = shader; }; this.material.needsupdate = true; }, updateTime: function updateTime() { this.uTime.value = (Date.now() - this.startTime) * this.timeCoef; }, }, __hmrId: 'NoisyText', }; var AnimatedPlane = function AnimatedPlane(params) { var this$1 = this; Object.entries(params).forEach(function (ref) { var key = ref[0]; var value = ref[1]; this$1[key] = value; }); this.o3d = new Object3D(); this.uProgress = { value: 0 }; this.uvScale = new Vector2(); this.initMaterial(); this.initPlane(); }; AnimatedPlane.prototype.initMaterial = function initMaterial () { var this$1 = this; this.material = new MeshBasicMaterial({ side: DoubleSide, transparent: true, map: this.texture, onBeforeCompile: function (shader) { shader.uniforms.progress = this$1.uProgress; shader.uniforms.uvScale = { value: this$1.uvScale }; shader.vertexShader = "\n uniform float progress;\n uniform vec2 uvScale;\n\n attribute vec3 offset;\n attribute vec3 rotation;\n attribute vec2 uvOffset;\n\n mat3 rotationMatrixXYZ(vec3 r)\n {\n float cx = cos(r.x);\n float sx = sin(r.x);\n float cy = cos(r.y);\n float sy = sin(r.y);\n float cz = cos(r.z);\n float sz = sin(r.z);\n\n return mat3(\n cy * cz, cx * sz + sx * sy * cz, sx * sz - cx * sy * cz,\n -cy * sz, cx * cz - sx * sy * sz, sx * cz + cx * sy * sz,\n sy, -sx * cy, cx * cy\n );\n }\n " + shader.vertexShader; shader.vertexShader = shader.vertexShader.replace('#include ', "\n #include \n vUv = vUv * uvScale + uvOffset;\n "); shader.vertexShader = shader.vertexShader.replace('#include ', "\n mat3 rotMat = rotationMatrixXYZ(progress * rotation);\n transformed = rotMat * transformed;\n\n vec4 mvPosition = vec4(transformed, 1.0);\n #ifdef USE_INSTANCING\n mvPosition = instanceMatrix * mvPosition;\n #endif\n\n mvPosition.xyz += progress * offset;\n\n mvPosition = modelViewMatrix * mvPosition;\n gl_Position = projectionMatrix * mvPosition;\n "); }, }); }; AnimatedPlane.prototype.initPlane = function initPlane () { var ref = this.screen; var width = ref.width; var wWidth = ref.wWidth; var wHeight = ref.wHeight; this.wSize = this.size * wWidth / width; this.nx = Math.ceil(wWidth / this.wSize) + 1; this.ny = Math.ceil(wHeight / this.wSize) + 1; this.icount = this.nx * this.ny; this.initGeometry(); this.initUV(); this.initAnimAttributes(); if (this.imesh) { this.o3d.remove(this.imesh); } this.imesh = new InstancedMesh$1(this.bGeometry, this.material, this.icount); this.o3d.add(this.imesh); var dummy = new Object3D(); var index = 0; var x = -(wWidth - (wWidth - this.nx * this.wSize)) / 2 + this.dx; for (var i = 0; i < this.nx; i++) { var y = -(wHeight - (wHeight - this.ny * this.wSize)) / 2 + this.dy; for (var j = 0; j < this.ny; j++) { dummy.position.set(x, y, 0); dummy.updateMatrix(); this.imesh.setMatrixAt(index++, dummy.matrix); y += this.wSize; } x += this.wSize; } }; AnimatedPlane.prototype.initGeometry = function initGeometry () { // square var geometry = new Geometry$1(); geometry.vertices.push(new Vector3(0, 0, 0)); geometry.vertices.push(new Vector3(this.wSize, 0, 0)); geometry.vertices.push(new Vector3(0, this.wSize, 0)); geometry.vertices.push(new Vector3(this.wSize, this.wSize, 0)); geometry.faces.push(new Face3(0, 2, 1)); geometry.faces.push(new Face3(2, 3, 1)); geometry.faceVertexUvs[0].push([ new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 0) ]); geometry.faceVertexUvs[0].push([ new Vector2(0, 1), new Vector2(1, 1), new Vector2(1, 0) ]); // geometry.computeFaceNormals(); // geometry.computeVertexNormals(); // center this.dx = this.wSize / 2; this.dy = this.wSize / 2; geometry.translate(-this.dx, -this.dy, 0); this.bGeometry = geometry.toBufferGeometry(); }; AnimatedPlane.prototype.initAnimAttributes = function initAnimAttributes () { var rnd = MathUtils.randFloat; var rndFS = MathUtils.randFloatSpread; var v3 = new Vector3(); var offsets = new Float32Array(this.icount * 3); for (var i = 0; i < offsets.length; i += 3) { if (this.anim === 1) { v3.set(rndFS(10), rnd(50, 100), rnd(20, 50)).toArray(offsets, i); } else { v3.set(rndFS(20), rndFS(20), rnd(20, 200)).toArray(offsets, i); } } this.bGeometry.setAttribute('offset', new InstancedBufferAttribute(offsets, 3)); var rotations = new Float32Array(this.icount * 3); var angle = Math.PI * 4; for (var i$1 = 0; i$1 < rotations.length; i$1 += 3) { rotations[i$1] = rndFS(angle); rotations[i$1 + 1] = rndFS(angle); rotations[i$1 + 2] = rndFS(angle); } this.bGeometry.setAttribute('rotation', new InstancedBufferAttribute(rotations, 3)); }; AnimatedPlane.prototype.initUV = function initUV () { var ratio = this.nx / this.ny; var tRatio = this.texture.image.width / this.texture.image.height; if (ratio > tRatio) { this.uvScale.set(1 / this.nx, (tRatio / ratio) / this.ny); } else { this.uvScale.set((ratio / tRatio) / this.nx, 1 / this.ny); } var nW = this.uvScale.x * this.nx; var nH = this.uvScale.y * this.ny; var v2 = new Vector2(); var uvOffsets = new Float32Array(this.icount * 2); for (var i = 0; i < this.nx; i++) { for (var j = 0; j < this.ny; j++) { v2.set( this.uvScale.x * i + (1 - nW) / 2, this.uvScale.y * j + (1 - nH) / 2 ).toArray(uvOffsets, (i * this.ny + j) * 2); } } this.bGeometry.setAttribute('uvOffset', new InstancedBufferAttribute(uvOffsets, 2)); }; AnimatedPlane.prototype.setTexture = function setTexture (texture) { this.texture = texture; this.material.map = texture; this.initUV(); }; AnimatedPlane.prototype.resize = function resize () { this.initPlane(); }; function useTextures() { var obj = { loader: new TextureLoader(), count: 0, textures: [], loadProgress: 0, loadTextures: loadTextures, dispose: dispose, }; return obj; function loadTextures(images, cb) { obj.count = images.length; obj.textures.splice(0); obj.loadProgress = 0; Promise.all(images.map(loadTexture)).then(cb); } function loadTexture(img, index) { return new Promise(function (resolve) { obj.loader.load( img.src, function (texture) { obj.loadProgress += 1 / obj.count; obj.textures[index] = texture; resolve(texture); } ); }); } function dispose() { obj.textures.forEach(function (t) { return t.dispose(); }); } } var script = { props: { images: Array, events: { type: Object, default: function () { return { wheel: true, click: true, keyup: true }; } }, }, setup: function setup() { var loader = useTextures(); return { loader: loader, progress: 0, targetProgress: 0, }; }, mounted: function mounted() { this.three = this.$refs.renderer.three; if (this.images.length < 2) { console.error('This slider needs at least 2 images.'); } else { this.loader.loadTextures(this.images, this.init); } }, unmounted: function unmounted() { this.loader.dispose(); var domElement = this.three.renderer.domElement; domElement.removeEventListener('click', this.onClick); domElement.removeEventListener('wheel', this.onWheel); document.removeEventListener('keyup', this.onKeyup); }, methods: { init: function init() { this.initScene(); gsap.fromTo(this.plane1.uProgress, { value: -2, }, { value: 0, duration: 2.5, ease: Power4.easeOut, } ); var domElement = this.three.renderer.domElement; if (this.events.click) { domElement.addEventListener('click', this.onClick); } if (this.events.wheel) { domElement.addEventListener('wheel', this.onWheel); } if (this.events.keyup) { document.addEventListener('keyup', this.onKeyup); } this.three.onBeforeRender(this.updateProgress); this.three.onAfterResize(this.onResize); }, initScene: function initScene() { var renderer = this.three.renderer; var scene = this.$refs.scene.scene; this.plane1 = new AnimatedPlane({ renderer: renderer, screen: this.three.size, size: 10, anim: 1, texture: this.loader.textures[0], }); this.plane2 = new AnimatedPlane({ renderer: renderer, screen: this.three.size, size: 10, anim: 2, texture: this.loader.textures[1], }); this.setPlanesProgress(0); this.planes = new Object3D(); this.planes.add(this.plane1.o3d); this.planes.add(this.plane2.o3d); scene.add(this.planes); }, onResize: function onResize() { this.plane1.resize(); this.plane2.resize(); }, onWheel: function onWheel(e) { // e.preventDefault(); if (e.deltaY > 0) { this.setTargetProgress(this.targetProgress + 1 / 20); } else { this.setTargetProgress(this.targetProgress - 1 / 20); } }, onClick: function onClick(e) { if (e.clientY < this.three.size.height / 2) { this.navPrevious(); } else { this.navNext(); } }, onKeyup: function onKeyup(e) { if (e.keyCode === 37 || e.keyCode === 38) { this.navPrevious(); } else if (e.keyCode === 39 || e.keyCode === 40) { this.navNext(); } }, navNext: function navNext() { if (Number.isInteger(this.targetProgress)) { this.setTargetProgress(this.targetProgress + 1); } else { this.setTargetProgress(Math.ceil(this.targetProgress)); } }, navPrevious: function navPrevious() { if (Number.isInteger(this.targetProgress)) { this.setTargetProgress(this.targetProgress - 1); } else { this.setTargetProgress(Math.floor(this.targetProgress)); } }, setTargetProgress: function setTargetProgress(value) { this.targetProgress = value; if (this.targetProgress < 0) { this.progress += this.images.length; this.targetProgress += this.images.length; } }, updateProgress: function updateProgress() { var progress1 = lerp(this.progress, this.targetProgress, 0.1); var pdiff = progress1 - this.progress; if (pdiff === 0) { return; } var p0 = this.progress % 1; var p1 = progress1 % 1; if ((pdiff > 0 && p1 < p0) || (pdiff < 0 && p0 < p1)) { var i = Math.floor(progress1) % this.images.length; var j = (i + 1) % this.images.length; this.plane1.setTexture(this.loader.textures[i]); this.plane2.setTexture(this.loader.textures[j]); } this.progress = progress1; this.setPlanesProgress(this.progress % 1); }, setPlanesProgress: function setPlanesProgress(progress) { this.plane1.uProgress.value = progress; this.plane2.uProgress.value = -1 + progress; this.plane1.material.opacity = 1 - progress; this.plane2.material.opacity = progress; this.plane1.o3d.position.z = progress; this.plane2.o3d.position.z = progress - 1; }, }, }; function render(_ctx, _cache, $props, $setup, $data, $options) { var _component_Camera = resolveComponent("Camera"); var _component_Scene = resolveComponent("Scene"); var _component_Renderer = resolveComponent("Renderer"); return (openBlock(), createBlock(_component_Renderer, { ref: "renderer", antialias: "" }, { default: withCtx(function () { return [ createVNode(_component_Camera, { ref: "camera", position: { z: 150 } }, null, 512 /* NEED_PATCH */), createVNode(_component_Scene, { ref: "scene" }, null, 512 /* NEED_PATCH */) ]; }), _: 1 /* STABLE */ }, 512 /* NEED_PATCH */)) } script.render = render; script.__file = "src/components/sliders/Slider1.vue"; function ZoomBlurImage(three) { var geometry, material, mesh; var uMap = { value: null }; var uCenter = { value: new Vector2(0.5, 0.5) }; var uStrength = { value: 0 }; var uUVOffset = { value: new Vector2(0, 0) }; var uUVScale = { value: new Vector2(1, 1) }; init(); return { geometry: geometry, material: material, mesh: mesh, uCenter: uCenter, uStrength: uStrength, setMap: setMap, updateUV: updateUV }; function init() { geometry = new PlaneBufferGeometry(2, 2, 1, 1); material = new ShaderMaterial$1({ transparent: true, uniforms: { map: uMap, center: uCenter, strength: uStrength, uvOffset: uUVOffset, uvScale: uUVScale, }, vertexShader: "\n varying vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n ", // adapted from https://github.com/evanw/glfx.js fragmentShader: "\n uniform sampler2D map;\n uniform vec2 center;\n uniform float strength;\n uniform vec2 uvOffset;\n uniform vec2 uvScale;\n varying vec2 vUv;\n\n float random(vec3 scale, float seed) {\n /* use the fragment position for a different seed per-pixel */\n return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed);\n }\n \n void main() {\n vec2 tUv = vUv * uvScale + uvOffset;\n if (abs(strength) > 0.001) {\n vec4 color = vec4(0.0);\n float total = 0.0;\n vec2 toCenter = center * uvScale + uvOffset - tUv;\n \n /* randomize the lookup values to hide the fixed number of samples */\n float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);\n \n for (float t = 0.0; t <= 20.0; t++) {\n float percent = (t + offset) / 20.0;\n float weight = 2.0 * (percent - percent * percent);\n vec4 texel = texture2D(map, tUv + toCenter * percent * strength);\n\n /* switch to pre-multiplied alpha to correctly blur transparent images */\n texel.rgb *= texel.a;\n\n color += texel * weight;\n total += weight;\n }\n\n gl_FragColor = color / total;\n\n /* switch back from pre-multiplied alpha */\n gl_FragColor.rgb /= gl_FragColor.a + 0.00001;\n gl_FragColor.a = 1.0 - abs(strength);\n } else {\n gl_FragColor = texture2D(map, tUv);\n }\n }\n ", }); mesh = new Mesh$1(geometry, material); } function setMap(value) { uMap.value = value; updateUV(); } function updateUV() { var ratio = three.size.ratio; var iRatio = uMap.value.image.width / uMap.value.image.height; uUVOffset.value.set(0, 0); uUVScale.value.set(1, 1); if (iRatio > ratio) { uUVScale.value.x = ratio / iRatio; uUVOffset.value.x = (1 - uUVScale.value.x) / 2; } else { uUVScale.value.y = iRatio / ratio; uUVOffset.value.y = (1 - uUVScale.value.y) / 2; } } } var script$1 = { props: { images: Array, events: { type: Object, default: function () { return { wheel: true, click: true, keyup: true }; } }, }, setup: function setup() { var center = new Vector2(); var loader = useTextures(); return { loader: loader, center: center, progress: 0, targetProgress: 0, }; }, mounted: function mounted() { this.three = this.$refs.renderer.three; if (this.images.length < 2) { console.error('This slider needs at least 2 images.'); } else { this.loader.loadTextures(this.images, this.init); } }, unmounted: function unmounted() { this.loader.dispose(); var domElement = this.three.renderer.domElement; domElement.removeEventListener('click', this.onClick); domElement.removeEventListener('wheel', this.onWheel); document.removeEventListener('keyup', this.onKeyup); }, methods: { init: function init() { this.initScene(); gsap.fromTo(this.image1.uStrength, { value: -2, }, { value: 0, duration: 2.5, ease: Power4.easeOut, } ); var domElement = this.three.renderer.domElement; if (this.events.click) { domElement.addEventListener('click', this.onClick); } if (this.events.wheel) { domElement.addEventListener('wheel', this.onWheel); } if (this.events.keyup) { document.addEventListener('keyup', this.onKeyup); } this.three.onBeforeRender(this.animate); this.three.onAfterResize(this.onResize); }, initScene: function initScene() { var scene = this.$refs.scene.scene; this.image1 = new ZoomBlurImage(this.three); this.image1.setMap(this.loader.textures[0]); this.image2 = new ZoomBlurImage(this.three); this.image2.setMap(this.loader.textures[1]); this.setImagesProgress(0); scene.add(this.image1.mesh); scene.add(this.image2.mesh); }, animate: function animate() { var ref = this.three; var mouse = ref.mouse; this.center.copy(mouse).divideScalar(2).addScalar(0.5); lerpv2(this.image1.uCenter.value, this.center, 0.1); lerpv2(this.image2.uCenter.value, this.center, 0.1); this.updateProgress(); }, onResize: function onResize() { this.image1.updateUV(); this.image2.updateUV(); }, onWheel: function onWheel(e) { // e.preventDefault(); if (e.deltaY > 0) { this.setTargetProgress(this.targetProgress + 1 / 20); } else { this.setTargetProgress(this.targetProgress - 1 / 20); } }, onClick: function onClick(e) { if (e.clientY < this.three.size.height / 2) { this.navPrevious(); } else { this.navNext(); } }, onKeyup: function onKeyup(e) { if (e.keyCode === 37 || e.keyCode === 38) { this.navPrevious(); } else if (e.keyCode === 39 || e.keyCode === 40) { this.navNext(); } }, navNext: function navNext() { if (Number.isInteger(this.targetProgress)) { this.setTargetProgress(this.targetProgress + 1); } else { this.setTargetProgress(Math.ceil(this.targetProgress)); } }, navPrevious: function navPrevious() { if (Number.isInteger(this.targetProgress)) { this.setTargetProgress(this.targetProgress - 1); } else { this.setTargetProgress(Math.floor(this.targetProgress)); } }, setTargetProgress: function setTargetProgress(value) { this.targetProgress = value; if (this.targetProgress < 0) { this.progress += this.images.length; this.targetProgress += this.images.length; } }, updateProgress: function updateProgress() { var progress1 = lerp(this.progress, this.targetProgress, 0.1); var pdiff = progress1 - this.progress; if (pdiff === 0) { return; } var p0 = this.progress % 1; var p1 = progress1 % 1; if ((pdiff > 0 && p1 < p0) || (pdiff < 0 && p0 < p1)) { var i = Math.floor(progress1) % this.images.length; var j = (i + 1) % this.images.length; this.image1.setMap(this.loader.textures[i]); this.image2.setMap(this.loader.textures[j]); } this.progress = progress1; this.setImagesProgress(this.progress % 1); }, setImagesProgress: function setImagesProgress(progress) { this.image1.uStrength.value = progress; this.image2.uStrength.value = -1 + progress; }, }, }; function render$1(_ctx, _cache, $props, $setup, $data, $options) { var _component_OrthographicCamera = resolveComponent("OrthographicCamera"); var _component_Scene = resolveComponent("Scene"); var _component_Renderer = resolveComponent("Renderer"); return (openBlock(), createBlock(_component_Renderer, { ref: "renderer", antialias: "", "mouse-move": "" }, { default: withCtx(function () { return [ createVNode(_component_OrthographicCamera, { ref: "camera", position: { z: 10 } }, null, 512 /* NEED_PATCH */), createVNode(_component_Scene, { ref: "scene" }, null, 512 /* NEED_PATCH */) ]; }), _: 1 /* STABLE */ }, 512 /* NEED_PATCH */)) } script$1.render = render$1; script$1.__file = "src/components/sliders/Slider2.vue"; var script$2 = { props: { src: String, cameraPosition: Object, }, mounted: function mounted() { var this$1 = this; this.renderer = this.$refs.renderer; var loader = new GLTFLoader(); loader.load(this.src, function (gltf) { this$1.renderer.three.scene.add(gltf.scene); }); }, }; function render$2(_ctx, _cache, $props, $setup, $data, $options) { var _component_Camera = resolveComponent("Camera"); var _component_Scene = resolveComponent("Scene"); var _component_Renderer = resolveComponent("Renderer"); return (openBlock(), createBlock(_component_Renderer, { ref: "renderer", "orbit-ctrl": { enableDamping: true, dampingFactor: 0.05 } }, { default: withCtx(function () { return [ createVNode(_component_Camera, { ref: "camera", position: $props.cameraPosition }, null, 8 /* PROPS */, ["position"]), createVNode(_component_Scene, null, { default: withCtx(function () { return [ renderSlot(_ctx.$slots, "default") ]; }), _: 3 /* FORWARDED */ }) ]; }), _: 1 /* STABLE */ }, 8 /* PROPS */, ["orbit-ctrl"])) } script$2.render = render$2; script$2.__file = "src/components/viewers/GLTFViewer.vue"; var TROIS = /*#__PURE__*/Object.freeze({ __proto__: null, Renderer: Renderer, OrthographicCamera: OrthographicCamera, PerspectiveCamera: PerspectiveCamera, Camera: PerspectiveCamera, Group: Group, Scene: Scene, BoxGeometry: BoxGeometry, CircleGeometry: CircleGeometry, ConeGeometry: ConeGeometry, CylinderGeometry: CylinderGeometry, DodecahedronGeometry: DodecahedronGeometry, IcosahedronGeometry: IcosahedronGeometry, LatheGeometry: LatheGeometry, OctahedronGeometry: OctahedronGeometry, PolyhedronGeometry: PolyhedronGeometry, RingGeometry: RingGeometry, SphereGeometry: SphereGeometry, TetrahedronGeometry: TetrahedronGeometry, TorusGeometry: TorusGeometry, TorusKnotGeometry: TorusKnotGeometry, TubeGeometry: TubeGeometry, AmbientLight: AmbientLight, DirectionalLight: DirectionalLight, PointLight: PointLight, SpotLight: SpotLight, BasicMaterial: BasicMaterial, LambertMaterial: LambertMaterial, MatcapMaterial: MatcapMaterial, PhongMaterial: PhongMaterial, PhysicalMaterial: PhysicalMaterial, StandardMaterial: StandardMaterial, SubSurfaceMaterial: SubSurfaceMaterial, ToonMaterial: ToonMaterial, Texture: Texture, CubeTexture: CubeTexture, Mesh: Mesh, Box: Box, Circle: Circle, Cone: Cone, Cylinder: Cylinder, Dodecahedron: Dodecahedron, Icosahedron: Icosahedron, Lathe: Lathe, Octahedron: Octahedron, Plane: Plane, Polyhedron: Polyhedron, Ring: Ring, Sphere: Sphere, Tetrahedron: Tetrahedron, Text: Text, Torus: Torus, TorusKnot: TorusKnot, Tube: Tube, Gem: Gem, Image: Image, InstancedMesh: InstancedMesh, MirrorMesh: MirrorMesh, RefractionMesh: RefractionMesh, Sprite: Sprite, EffectComposer: EffectComposer, RenderPass: RenderPass, BokehPass: BokehPass, FilmPass: FilmPass, FXAAPass: FXAAPass, HalftonePass: HalftonePass, SMAAPass: SMAAPass, TiltShiftPass: TiltShiftPass, UnrealBloomPass: UnrealBloomPass, ZoomBlurPass: ZoomBlurPass, NoisyImage: NoisyImage, NoisyPlane: NoisyPlane, NoisySphere: NoisySphere, NoisyText: NoisyText, Slider1: script, Slider2: script$1, GLTFViewer: script$2, setFromProp: setFromProp, propsValues: propsValues, lerp: lerp, lerpv2: lerpv2, lerpv3: lerpv3, limit: limit, getMatcapUrl: getMatcapUrl }); var TroisJSVuePlugin = { install: function (app) { var comps = [ 'Camera', 'OrthographicCamera', 'PerspectiveCamera', 'Renderer', 'Scene', 'Group', 'BoxGeometry', 'CircleGeometry', 'ConeGeometry', 'CylinderGeometry', 'DodecahedronGeometry', 'IcosahedronGeometry', 'LatheGeometry', 'OctahedronGeometry', 'PolyhedronGeometry', 'RingGeometry', 'SphereGeometry', 'TetrahedronGeometry', 'TorusGeometry', 'TorusKnotGeometry', 'TubeGeometry', 'AmbientLight', 'DirectionalLight', 'PointLight', 'SpotLight', 'BasicMaterial', 'LambertMaterial', 'MatcapMaterial', 'PhongMaterial', 'PhysicalMaterial', 'ShaderMaterial', 'StandardMaterial', 'SubSurfaceMaterial', 'ToonMaterial', 'Texture', 'CubeTexture', 'Box', 'Circle', 'Cone', 'Cylinder', 'Dodecahedron', 'Icosahedron', 'Mesh', 'Lathe', 'Octahedron', 'Plane', 'Polyhedron', 'Ring', 'Sphere', 'Tetrahedron', 'Text', 'Torus', 'TorusKnot', 'Tube', 'Gem', 'Image', 'InstancedMesh', 'MirrorMesh', 'RefractionMesh', 'Sprite', 'BokehPass', 'EffectComposer', 'FilmPass', 'FXAAPass', 'HalftonePass', 'RenderPass', 'SAOPass', 'SMAAPass', 'TiltShiftPass', 'UnrealBloomPass', 'ZoomBlurPass', 'GLTFViewer' ]; comps.forEach(function (comp) { app.component(comp, TROIS[comp]); }); }, }; export { AmbientLight, BasicMaterial, BokehPass, Box, BoxGeometry, PerspectiveCamera as Camera, Circle, CircleGeometry, Cone, ConeGeometry, CubeTexture, Cylinder, CylinderGeometry, DirectionalLight, Dodecahedron, DodecahedronGeometry, EffectComposer, FXAAPass, FilmPass, script$2 as GLTFViewer, Gem, Group, HalftonePass, Icosahedron, IcosahedronGeometry, Image, InstancedMesh, LambertMaterial, Lathe, LatheGeometry, MatcapMaterial, Mesh, MirrorMesh, NoisyImage, NoisyPlane, NoisySphere, NoisyText, Octahedron, OctahedronGeometry, OrthographicCamera, PerspectiveCamera, PhongMaterial, PhysicalMaterial, Plane, PointLight, Polyhedron, PolyhedronGeometry, RefractionMesh, RenderPass, Renderer, Ring, RingGeometry, SMAAPass, Scene, script as Slider1, script$1 as Slider2, Sphere, SphereGeometry, SpotLight, Sprite, StandardMaterial, SubSurfaceMaterial, Tetrahedron, TetrahedronGeometry, Text, Texture, TiltShiftPass, ToonMaterial, Torus, TorusGeometry, TorusKnot, TorusKnotGeometry, TroisJSVuePlugin, Tube, TubeGeometry, UnrealBloomPass, ZoomBlurPass, getMatcapUrl, lerp, lerpv2, lerpv3, limit, propsValues, setFromProp }; //# sourceMappingURL=trois.module.cdn.js.map