// Import styles import "./styles.css"; // Import THREE library import * as THREE from "three"; // Import vertex shader import vertex from "./shaders/vertex.glsl"; // Import fragment shader import fragment from "./shaders/fragment.glsl"; // Import texture images // import txt1 from "./TunnelbandMatrix15dec2.png"; // import txt2 from "./blackedoutleft.png"; import txt1 from "./blackoutright_30000x1500.png"; import txt2 from "./full30000x1500.png"; // import txt2 from "./swirl.gif"; // Replace with the actual path of your second texture // Initialize global timer variable let timer = 0; export default class Sketch { constructor(options) { this.clock = new THREE.Clock(); this.time = 0; this.container = options.domElement; this.height = this.container.offsetHeight; this.width = this.container.offsetWidth; this.camera = new THREE.PerspectiveCamera(75, this.width / this.height, 0.1, 1000); this.camera.position.set(0, 0, 10); this.scene = new THREE.Scene(); this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); this.renderer.setPixelRatio(window.devicePixelRatio * 2); this.container.appendChild(this.renderer.domElement); this.normal = new THREE.Vector3(); this.binormal = new THREE.Vector3(); this.resize(); this.addObjects(); this.render(); this.setUpResize(); // this.replaceTxt1(); this.setOpacityLayer1(1, 0); this.setOpacityLayer2(1, 30); } addObjects() { var texture1 = new THREE.TextureLoader().load(txt1, (texture) => { texture.minFilter = THREE.NearestFilter; texture.magFilter = THREE.NearestFilter; }); var texture2 = new THREE.TextureLoader().load(txt2, (texture) => { texture.minFilter = THREE.NearestFilter; texture.magFilter = THREE.NearestFilter; }); this.shaderMaterial = new THREE.ShaderMaterial({ side: THREE.DoubleSide, depthWrite: true, depthTest: true, transparent: true, // blending: THREE.NormalBlending, blending: THREE.NoBlending, uniforms: { time: { type: "f", value: 0 }, uResolution: { type: "v4", value: new THREE.Vector4() }, u_texture: { type: "t", value: texture1 }, u_texture2: { type: "t", value: texture2 }, distortionFactorX: { type: "f", value: 0 }, distortionFactorY: { type: "f", value: 0 }, repeatX: { type: "f", value: 12.0 }, repeatY: { type: "f", value: 6.0 }, aspectRatioCorrection: { type: "f", value: 15 }, transparency1: { type: "f", value: 0 }, transparency2: { type: "f", value: 0 }, // Set initial transparency for the second texture scale: { type: "v2", value: new THREE.Vector2(1.0, 1.0) }, offset: { type: "v2", value: new THREE.Vector2(0.0, 0.0) }, rotation: { type: "f", value: 0.0 }, turbulence: { type: "f", value: 0.0 }, colorOffset: { type: "f", value: 0.0 }, brightness: { type: "f", value: 1.0 }, waveSpeed: { type: "f", value: 0.0 }, globalScale: { type: "f", value: 1.0 }, twist: { type: "f", value: 1.0 }, waveFrequency: { type: "f", value: 0.0 }, depthFactor: { type: "f", value: 0.0 }, glowIntensity: { type: "f", value: 0.0 }, pulseSpeed: { type: "f", value: 0.0 }, colorR: { type: "f", value: 1.0 }, colorG: { type: "f", value: 1.0 }, colorB: { type: "f", value: 1.0 }, }, vertexShader: vertex, fragmentShader: fragment, }); class CustomSinCurve extends THREE.Curve { constructor(scale = 2) { super(); this.scale = scale; } getPoint(t, optionalTarget = new THREE.Vector3()) { const tx = Math.cos(2 * Math.PI * t); const ty = Math.sin(2 * Math.PI * t); const tz = 0.1 * Math.sin(8 * Math.PI * t); return optionalTarget.set(tx, ty, tz).multiplyScalar(this.scale); } } // const splineData = [ // [new THREE.Vector3(249.77046356468685, 932.2219407156813, -255.94041268503986), // new THREE.Vector3(184.2697143587856, 340.8431828885419, -137.50911515694105), // new THREE.Vector3(19.942904199485042, 228.58948494060985, 62.791664957972415), // new THREE.Vector3(129.44330187699228, 123.24717120015652, 180.72662546735586), // new THREE.Vector3(194.62366419209283, -50.957866448272654, 348.9131609506699), // new THREE.Vector3(233.83324329738002, -6.6805514372266215, 586.011268528852), // new THREE.Vector3(33.97204422946808, -11.55735269269492, 843.3100027995519), // new THREE.Vector3(122.26648943463792, -206.74514914968762, 925.883739846062), // new THREE.Vector3(386.39147370444016, -156.50797561120535, 1011.8913441984032), // new THREE.Vector3(711.7691000196912, -348.3088368387029, 1189.6414444065897)] // ]; // const splineData = [ // [new THREE.Vector3(473.11863126256065, 1148.7914983677936, -626.3088726774722), // new THREE.Vector3(245.61458415195102, 1116.9549354293442, -263.87118049677656), // new THREE.Vector3(245.61458415195102, 1116.9549354293442, -263.87118049677656), // new THREE.Vector3(245.61458415195102, 1116.9549354293442, -263.87118049677656), // new THREE.Vector3(204.61699075454024, 370.04031630467887, -68.48460037267392), // new THREE.Vector3(86.44131454502019, 269.45084890937585, 62.791664957972415), // new THREE.Vector3(72.15795829069751, 58.51161097159243, 171.57374030692884), // new THREE.Vector3(25.789881573044692, -33.22822178799524, 348.9131609506699), // new THREE.Vector3(136.00387125935322, -8.133815744630706, 585.6112333240656), // new THREE.Vector3(33.97204422946808, -11.55735269269492, 843.3100027995519), // new THREE.Vector3(125.44573300578595, -64.95811252917446, 1087.520327532037), // new THREE.Vector3(-229.4300492080865, -204.31919716633735, 1592.4021728239306), // new THREE.Vector3(-32.58894150524465, -427.4049046320883, 2072.332326149018), // new THREE.Vector3(508.9934515582963, -2499.952976214704, 5435.133591888159), // new THREE.Vector3(1759.943314976105, -3123.674630232325, 7714.175951240869)] // ] // const splineData = [[ // new THREE.Vector3(473.11863126256065, 1148.7914983677936, -626.3088726774722), // new THREE.Vector3(23.51828362256837, 1128.368276997569, -619.9291758003139), // new THREE.Vector3(63.43602909903811, 1094.885204825893, -460.9975125081666), // new THREE.Vector3(296.1407291653776, 959.7356327576776, -503.15980942417), // new THREE.Vector3(410.4183885943379, -618.6838591644985, -229.9284358044308), // new THREE.Vector3(204.61699075454024, 370.04031630467887, -68.48460037267392), // new THREE.Vector3(86.44131454502019, 269.45084890937585, 62.791664957972415), // new THREE.Vector3(72.15795829069751, 58.51161097159243, 171.57374030692884), // new THREE.Vector3(25.789881573044692, -33.22822178799524, 348.9131609506699), // new THREE.Vector3(136.00387125935322, -8.133815744630706, 585.6112333240656), // new THREE.Vector3(33.97204422946808, -11.55735269269492, 843.3100027995519), // new THREE.Vector3(125.44573300578595, -64.95811252917446, 1087.520327532037), // new THREE.Vector3(-229.4300492080865, -204.31919716633735, 1592.4021728239306), // new THREE.Vector3(-32.58894150524465, -427.4049046320883, 2072.332326149018), // new THREE.Vector3(508.9934515582963, -2499.952976214704, 5435.133591888159), // new THREE.Vector3(1759.943314976105, -3123.674630232325, 7714.175951240869)] // ] const splineData = [[ new THREE.Vector3(473.11863126256065, 1148.7914983677936, -626.3088726774722), new THREE.Vector3(119.89018791921463, 1106.433693900733, -832.5766659881987), new THREE.Vector3(117.90596454302678, 1033.555957750614, -612.8498670255568), new THREE.Vector3(182.54143644281098, 825.3080107623409, -480.6932058171036), new THREE.Vector3(118.67378490442167, 396.4887161528761, -380.5280111161988), new THREE.Vector3(280.3702856718703, 292.9366974262628, -76.78175980638068), new THREE.Vector3(86.44131454502019, 269.45084890937585, 62.791664957972415), new THREE.Vector3(72.15795829069751, 58.51161097159243, 171.57374030692884), new THREE.Vector3(-18.631970330989734, -12.469964424808147, 353.11898079093527), new THREE.Vector3(136.00387125935322, -8.133815744630706, 585.6112333240656), new THREE.Vector3(7.613134434090028, 114.78833598781391, 843.3100027995519), new THREE.Vector3(125.44573300578595, -64.95811252917446, 1087.520327532037), new THREE.Vector3(-136.7078013160953, -165.54943689384953, 1375.894502480654), new THREE.Vector3(350.7398762821747, -364.1460096594824, 2008.9271623961001), new THREE.Vector3(684.0517345033015, -496.61732486128324, 2253.715989472005), new THREE.Vector3(1759.943314976105, -3123.674630232325, 7714.175951240869)]] class CustomSplineCurve extends THREE.CatmullRomCurve3 { constructor(points) { // super(points, false, 'catmullrom', 0.9); // Set the type to 'catmullrom' with tension 0.1 super(points, false, 'chordal'); // Set the type to 'chordal' // super(points, false, 'centripetal'); // Set the type to 'centripetal' } } // // Convert splineData to THREE.Vector3 array // const splinePoints = splineData[0]; // const path = new CustomSplineCurve(splinePoints); const scaleFactor = .1; // Adjust as needed // Apply scaling to the spline points const scaledSplinePoints = splineData[0].map(point => new THREE.Vector3(point.x * scaleFactor, point.y * scaleFactor, point.z * scaleFactor) ); // Create a new spline curve with scaled points const path = new CustomSplineCurve(scaledSplinePoints); // Create a new spline curve // this.geometry = new THREE.TubeGeometry(path, splinePoints.length * 100, 0.5, 20, false); this.geometry = new THREE.TubeGeometry(path, scaledSplinePoints.length * 100, 0.5, 20, false); // const path = new CustomSinCurve(10); // this.geometry = new THREE.TubeGeometry(path, 200, 0.5, 20, false); this.mesh = new THREE.Mesh(this.geometry, this.shaderMaterial); this.scene.add(this.mesh); window.shaderUniforms = this.shaderMaterial.uniforms; // const defaultValues = { // distortionFactorX: 0.0, // distortionFactorY: 0.0, // repeatX: 12.0, // repeatY: 6.0, // aspectRatioCorrection: 10.0, // transparency1: 0.0, // Set initial transparency for the first texture // transparency2: 1.0, // Set initial transparency for the second texture // scale: new THREE.Vector2(1.0, 1.0), // offset: new THREE.Vector2(0.0, 0.0), // rotation: 0.0, // turbulence: 0.0, // colorOffset: 0.0, // brightness: 1.0, // waveFrequency: 1.0, // depthFactor: 0.0, // glowIntensity: 0.0, // pulseSpeed: 1.0, // colorR: 1.0, // colorG: 1.0, // colorB: 1.0, // }; // Object.keys(defaultValues).forEach((key) => { // window[key] = shaderUniforms[key].value = defaultValues[key]; // }); } replaceTxt1() { setTimeout(() => { console.log('texture 1 replaced') var texture = new THREE.TextureLoader().load(txt2, (texture) => { texture.minFilter = THREE.NearestFilter; texture.magFilter = THREE.NearestFilter; }); this.shaderMaterial.uniforms.u_texture.value = texture; }, 20000); } setOpacityLayer1(opacity, timeout) { setTimeout(() => { this.shaderMaterial.uniforms.transparency1.value = opacity; }, timeout); } setOpacityLayer2(opacity, timeout) { setTimeout(() => { this.shaderMaterial.uniforms.transparency2.value = opacity; }, timeout); } // -=-==-=-=-=-=-=-=-=-=-=-=-=-=--= Particle(scene, burst) { var radius = Math.random() * 0.003 + 0.0003; var geom = cell.geometry; var range = 10; var offset = burst ? 200 : 350; var saturate = Math.floor(Math.random() * 20 + 65); var light = burst ? 20 : 56; this.color = new THREE.Color("hsl(" + (Math.random() * range + offset) + "," + saturate + "%," + light + "%)"); var mat = new THREE.MeshPhongMaterial({ color: this.color, // shading: THREE.FlatShading }); this.mesh = new THREE.Mesh(geom, mat); this.mesh.scale.set(radius, radius, radius); this.mesh.scale.x += (Math.random() - 0.5) * 0.001; this.mesh.scale.y += (Math.random() - 0.5) * 0.001; this.mesh.scale.z += (Math.random() - 0.5) * 0.001; this.mesh.position.set(0, 0, 1.5); this.percent = burst ? 0.2 : Math.random(); this.burst = burst ? true : false; this.offset = new THREE.Vector3((Math.random() - 0.5) * 0.025, (Math.random() - 0.5) * 0.025, 0); this.speed = Math.random() * 0.004 + 0.0002; if (this.burst) { this.speed += 0.003; this.mesh.scale.x *= 1.4; this.mesh.scale.y *= 1.4; this.mesh.scale.z *= 1.4; } this.rotate = new THREE.Vector3(-Math.random() * 0.1 + 0.01, 0, Math.random() * 0.01); this.pos = new THREE.Vector3(0, 0, 0); }; // =--=-==-=--=-=-=-=-=-=-==--=-==--=-= render() { this.time = timer; let looptime = 10 * 1000; let t = (this.time % looptime) / looptime; let pos = this.geometry.parameters.path.getPointAt(t); let segments = this.geometry.tangents.length; let pickt = t * segments; let pick = Math.floor(pickt); let pickNext = (pick + 1) % segments; this.binormal.subVectors(this.geometry.binormals[pickNext], this.geometry.binormals[pick]); this.binormal.multiplyScalar(pickt - pick).add(this.geometry.binormals[pick]); let dir = this.geometry.parameters.path.getTangentAt(t); let offset = 0; this.normal.copy(this.binormal).cross(dir); pos.add(this.normal.clone().multiplyScalar(offset)); this.camera.position.copy(pos); let lookAt = this.geometry.parameters.path.getPointAt((t + 1 / this.geometry.parameters.path.getLength()) % 1); this.camera.matrix.lookAt(this.camera.position, lookAt, this.normal); this.camera.rotation.setFromRotationMatrix(this.camera.matrix, this.camera.rotation.order); this.shaderMaterial.uniforms.time.value = this.clock.getElapsedTime(); requestAnimationFrame(this.render.bind(this)); this.renderer.render(this.scene, this.camera); } resize() { this.width = this.container.offsetWidth; this.height = this.container.offsetHeight; this.renderer.setSize(this.width, this.height); this.camera.aspect = this.width / this.height; this.camera.updateProjectionMatrix(); } setUpResize() { window.addEventListener("resize", this.resize.bind(this)); } } new Sketch({ domElement: document.getElementById("container"), }); window.speed = 1; function render() { requestAnimationFrame(() => { timer += window.speed; render(); }); } render();