final, abandoning
This commit is contained in:
parent
63c6e78b18
commit
587bd28fd0
BIN
public/noise.jpg
Normal file
BIN
public/noise.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 260 KiB |
BIN
public/noisex.jpg
Normal file
BIN
public/noisex.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 275 KiB |
BIN
public/noisexx.jpg
Normal file
BIN
public/noisexx.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
|
@ -1,20 +1,24 @@
|
|||
import * as THREE from 'three';
|
||||
|
||||
const textureLoader = new THREE.TextureLoader();
|
||||
const noiseTexture = textureLoader.load('./noise.jpg');
|
||||
noiseTexture.wrapS = THREE.RepeatWrapping;
|
||||
noiseTexture.wrapT = THREE.RepeatWrapping;
|
||||
|
||||
const InkSimShader = {
|
||||
uniforms: {
|
||||
tPrev: { value: null },
|
||||
iResolution: { value: new THREE.Vector2() },
|
||||
iTime: { value: 0.0 },
|
||||
mouse: { value: new THREE.Vector3(-1, -1, 0.0) },
|
||||
dissipation: { value: 0.96 },
|
||||
turbulence: { value: 2.2 },
|
||||
dissipation: { value: 0.97 },
|
||||
turbulence: { value: 0.2 },
|
||||
scale: { value: 0.9 },
|
||||
speed: { value: 1.0 },
|
||||
octaves: { value: 4 },
|
||||
speed: { value: 0.5 },
|
||||
octaves: { value: 2 },
|
||||
lacunarity: { value: 2.0 },
|
||||
gain: { value: 0.5 },
|
||||
mouseRadius: { value: 0.25 },
|
||||
globalChaos: { value: 0.15 }
|
||||
mouseRadius: { value: 0.15 }
|
||||
},
|
||||
vertexShader: `
|
||||
varying vec2 vUv;
|
||||
|
@ -38,7 +42,6 @@ const InkSimShader = {
|
|||
uniform float lacunarity;
|
||||
uniform float gain;
|
||||
uniform float mouseRadius;
|
||||
uniform float globalChaos;
|
||||
|
||||
vec2 hash22(vec2 p) {
|
||||
p = vec2(dot(p, vec2(127.1, 311.7)), dot(p, vec2(269.5, 183.3)));
|
||||
|
@ -73,59 +76,34 @@ const InkSimShader = {
|
|||
vec2 uv = vUv;
|
||||
vec4 prev = texture2D(tPrev, uv);
|
||||
float time = iTime * speed;
|
||||
|
||||
float distortion = 0.0;
|
||||
|
||||
// Global background chaos - always present but subtle
|
||||
vec2 globalP = uv * 3.0 + time * 0.12;
|
||||
vec2 q = vec2(fbm(globalP), fbm(globalP + vec2(5.2, 1.3)));
|
||||
distortion = fbm(globalP + 2.0 * q) * globalChaos;
|
||||
|
||||
// Mouse-driven intense ink distortion
|
||||
if(mouse.z > 0.001) {
|
||||
vec2 mouseUv = mouse.xy / iResolution;
|
||||
vec2 diff = uv - mouseUv;
|
||||
float dist = length(diff);
|
||||
|
||||
// Larger, softer falloff around mouse cursor
|
||||
float falloff = 1.0 - smoothstep(0.0, mouseRadius * 2.0, dist);
|
||||
float coreFalloff = 1.0 - smoothstep(0.0, mouseRadius * 0.5, dist);
|
||||
|
||||
if(falloff > 0.0) {
|
||||
// Domain warping near cursor
|
||||
vec2 p = uv * 6.0 + time * 0.3;
|
||||
vec2 warpQ = vec2(fbm(p), fbm(p + vec2(5.2, 1.3)));
|
||||
vec2 warpR = vec2(fbm(p + 3.0 * warpQ + vec2(1.7, 9.2) + time * 0.15),
|
||||
fbm(p + 3.0 * warpQ + vec2(8.3, 2.8) + time * 0.12));
|
||||
|
||||
// Chaotic ink splash effect
|
||||
float inkDistortion = fbm(p + 4.0 * warpR + diff * 8.0) * turbulence;
|
||||
|
||||
// Add swirling motion around cursor
|
||||
float angle = atan(diff.y, diff.x);
|
||||
float spiral = sin(angle * 4.0 + time * 10.0 + dist * 15.0) * 0.6;
|
||||
inkDistortion += spiral * coreFalloff;
|
||||
|
||||
// Add noise based on mouse movement speed
|
||||
float mouseNoise = fbm(uv * 10.0 + time * 4.0 + mouseUv * 6.0);
|
||||
inkDistortion += mouseNoise * mouse.z * 1.2;
|
||||
|
||||
// Apply falloff and strength
|
||||
distortion += inkDistortion * falloff * mouse.z * 0.8;
|
||||
}
|
||||
|
||||
// Add trailing effect that persists even outside main radius
|
||||
float trailFalloff = 1.0 - smoothstep(0.0, mouseRadius * 4.0, dist);
|
||||
if(trailFalloff > 0.0) {
|
||||
float trail = fbm(uv * 8.0 + time * 2.0 + mouseUv * 4.0) * mouse.z * 0.3;
|
||||
distortion += trail * trailFalloff;
|
||||
}
|
||||
}
|
||||
|
||||
// Apply dissipation and combine
|
||||
float newValue = prev.r * dissipation + distortion * 0.12;
|
||||
newValue = clamp(newValue, -2.0, 2.0);
|
||||
|
||||
gl_FragColor = vec4(newValue, prev.r, 0.0, 1.0);
|
||||
}
|
||||
`
|
||||
|
@ -135,6 +113,7 @@ export const InkDistortionShader = {
|
|||
uniforms: {
|
||||
tDiffuse: { value: null },
|
||||
tSim: { value: null },
|
||||
tNoise: { value: noiseTexture },
|
||||
iResolution: { value: new THREE.Vector2() },
|
||||
amount: { value: 0.035 },
|
||||
chromaticAmount: { value: 0.015 },
|
||||
|
@ -142,7 +121,9 @@ export const InkDistortionShader = {
|
|||
noiseScale: { value: 2.0 },
|
||||
flowSpeed: { value: 1.0 },
|
||||
inkDensity: { value: 0.4 },
|
||||
chaosAmount: { value: 1.3 }
|
||||
chaosAmount: { value: 1.3 },
|
||||
grainStrength: { value: 3.12 },
|
||||
grainScale: { value: 8.0 }
|
||||
},
|
||||
vertexShader: `
|
||||
varying vec2 vUv;
|
||||
|
@ -156,6 +137,7 @@ export const InkDistortionShader = {
|
|||
varying vec2 vUv;
|
||||
uniform sampler2D tDiffuse;
|
||||
uniform sampler2D tSim;
|
||||
uniform sampler2D tNoise;
|
||||
uniform vec2 iResolution;
|
||||
uniform float amount;
|
||||
uniform float chromaticAmount;
|
||||
|
@ -164,6 +146,8 @@ export const InkDistortionShader = {
|
|||
uniform float flowSpeed;
|
||||
uniform float inkDensity;
|
||||
uniform float chaosAmount;
|
||||
uniform float grainStrength;
|
||||
uniform float grainScale;
|
||||
|
||||
vec2 hash22(vec2 p) {
|
||||
p = vec2(dot(p, vec2(127.1, 311.7)), dot(p, vec2(269.5, 183.3)));
|
||||
|
@ -195,56 +179,42 @@ export const InkDistortionShader = {
|
|||
|
||||
void main() {
|
||||
float distortionField = texture2D(tSim, vUv).r;
|
||||
|
||||
// Apply base distortion everywhere there's simulation data
|
||||
vec2 totalDistortion = vec2(distortionField) * amount;
|
||||
|
||||
// Add procedural chaos based on distortion intensity
|
||||
float distortionIntensity = abs(distortionField);
|
||||
|
||||
if(distortionIntensity > 0.005) {
|
||||
if(distortionIntensity > 0.01) {
|
||||
vec2 flowTime = vec2(time * flowSpeed * 0.3, time * flowSpeed * 0.2);
|
||||
vec2 flowNoise = vec2(
|
||||
fbm(vUv * noiseScale + flowTime),
|
||||
fbm(vUv * noiseScale + flowTime + vec2(100.0, 50.0))
|
||||
);
|
||||
|
||||
totalDistortion += flowNoise * chaosAmount * 0.02 * distortionIntensity;
|
||||
|
||||
// Swirls based on distortion field
|
||||
float swirl = sin(time * 2.0 + vUv.x * 15.0) * cos(time * 1.7 + vUv.y * 12.0);
|
||||
vec2 swirlOffset = vec2(-swirl, swirl) * 0.01 * chaosAmount * distortionIntensity;
|
||||
totalDistortion += swirlOffset;
|
||||
}
|
||||
|
||||
// Enhanced chromatic aberration
|
||||
vec2 chromaticOffset = totalDistortion * chromaticAmount;
|
||||
vec2 chaosChromatic = totalDistortion * 0.3;
|
||||
|
||||
vec2 uvR = vUv + totalDistortion + chromaticOffset + chaosChromatic;
|
||||
vec2 uvG = vUv + totalDistortion;
|
||||
vec2 uvB = vUv + totalDistortion - chromaticOffset - chaosChromatic * 0.5;
|
||||
|
||||
uvR = clamp(uvR, vec2(0.0), vec2(1.0));
|
||||
uvG = clamp(uvG, vec2(0.0), vec2(1.0));
|
||||
uvB = clamp(uvB, vec2(0.0), vec2(1.0));
|
||||
|
||||
float r = texture2D(tDiffuse, uvR).r;
|
||||
float g = texture2D(tDiffuse, uvG).g;
|
||||
float b = texture2D(tDiffuse, uvB).b;
|
||||
|
||||
vec3 color = vec3(r, g, b);
|
||||
|
||||
// Apply ink effects based on distortion intensity
|
||||
if(distortionIntensity > 0.005) {
|
||||
if(distortionIntensity > 0.01) {
|
||||
float density = distortionIntensity * inkDensity;
|
||||
float inkEffect = 1.0 + density * 0.5;
|
||||
color *= inkEffect;
|
||||
|
||||
float bleeding = smoothstep(0.02, 0.6, distortionIntensity);
|
||||
color = mix(color, color * 0.92, bleeding * 0.3);
|
||||
vec2 grainUv = vUv * grainScale + vec2(time * 0.05, time * 0.03);
|
||||
vec3 grainColor = texture2D(tNoise, grainUv).rgb;
|
||||
grainColor = (grainColor - 0.5) * grainStrength * distortionIntensity;
|
||||
color += grainColor;
|
||||
}
|
||||
|
||||
gl_FragColor = vec4(color, 1.0);
|
||||
}
|
||||
`
|
||||
|
@ -264,7 +234,6 @@ export function createInkSimulation(renderer, dpr = 1) {
|
|||
})
|
||||
);
|
||||
simScene.add(quad);
|
||||
|
||||
const params = {
|
||||
minFilter: THREE.LinearFilter,
|
||||
magFilter: THREE.LinearFilter,
|
||||
|
@ -273,27 +242,22 @@ export function createInkSimulation(renderer, dpr = 1) {
|
|||
depthBuffer: false,
|
||||
stencilBuffer: false
|
||||
};
|
||||
|
||||
let width = Math.max(2, Math.floor(window.innerWidth * dpr * 0.5));
|
||||
let height = Math.max(2, Math.floor(window.innerHeight * dpr * 0.5));
|
||||
let rtA = new THREE.WebGLRenderTarget(width, height, params);
|
||||
let rtB = new THREE.WebGLRenderTarget(width, height, params);
|
||||
|
||||
renderer.setRenderTarget(rtA);
|
||||
renderer.clear();
|
||||
renderer.setRenderTarget(rtB);
|
||||
renderer.clear();
|
||||
renderer.setRenderTarget(null);
|
||||
|
||||
quad.material.uniforms.iResolution.value.set(width, height);
|
||||
quad.material.uniforms.tPrev.value = rtA.texture;
|
||||
|
||||
function swap() {
|
||||
const tmp = rtA;
|
||||
rtA = rtB;
|
||||
rtB = tmp;
|
||||
}
|
||||
|
||||
function update(mouseX, mouseY, strength, timeSec) {
|
||||
quad.material.uniforms.iTime.value = timeSec;
|
||||
if (mouseX < 0.0 || mouseY < 0.0) {
|
||||
|
@ -308,11 +272,9 @@ export function createInkSimulation(renderer, dpr = 1) {
|
|||
renderer.setRenderTarget(null);
|
||||
swap();
|
||||
}
|
||||
|
||||
function getTexture() {
|
||||
return rtA.texture;
|
||||
}
|
||||
|
||||
function resize(w, h, newDpr = dpr) {
|
||||
width = Math.max(2, Math.floor(w * newDpr * 0.5));
|
||||
height = Math.max(2, Math.floor(h * newDpr * 0.5));
|
||||
|
@ -320,6 +282,5 @@ export function createInkSimulation(renderer, dpr = 1) {
|
|||
rtB.setSize(width, height);
|
||||
quad.material.uniforms.iResolution.value.set(width, height);
|
||||
}
|
||||
|
||||
return { update, getTexture, resize };
|
||||
}
|
||||
|
|
24
src/main.js
24
src/main.js
|
@ -27,34 +27,30 @@ import { createStarfield } from './starfield.js';
|
|||
|
||||
const sceneLoader = new SceneLoader();
|
||||
sceneLoader.setLoadingMessage('Preparing Your Experience...');
|
||||
|
||||
const { scene, camera, renderer, composer } = createScene();
|
||||
setupLighting(scene, camera);
|
||||
const controls = setupControls(camera, renderer);
|
||||
|
||||
controls.addEventListener('change', () => calculateTransitionVectors(camera));
|
||||
|
||||
const starfield = createStarfield(scene);
|
||||
const turntableSpeed = 0.5;
|
||||
let preloadedModels = {};
|
||||
|
||||
const dpr = renderer.getPixelRatio ? renderer.getPixelRatio() : Math.min(window.devicePixelRatio || 1, 2);
|
||||
const inkSim = createInkSimulation(renderer, dpr);
|
||||
const distortionPass = new ShaderPass(InkDistortionShader);
|
||||
distortionPass.material.uniforms.tSim.value = inkSim.getTexture();
|
||||
distortionPass.material.uniforms.iResolution.value.set(window.innerWidth * dpr, window.innerHeight * dpr);
|
||||
distortionPass.material.uniforms.amount.value = 0.025;
|
||||
distortionPass.material.uniforms.amount.value = 0.03;
|
||||
distortionPass.material.uniforms.chromaticAmount.value = 0.100;
|
||||
distortionPass.material.uniforms.noiseScale.value = 2.5;
|
||||
distortionPass.material.uniforms.flowSpeed.value = 1.2;
|
||||
distortionPass.material.uniforms.noiseScale.value = 0.05;
|
||||
distortionPass.material.uniforms.flowSpeed.value = 2.2;
|
||||
distortionPass.material.uniforms.inkDensity.value = 0.35;
|
||||
distortionPass.material.uniforms.chaosAmount.value = 1.5;
|
||||
distortionPass.material.uniforms.chaosAmount.value = 0.05;
|
||||
distortionPass.material.uniforms.grainStrength.value = 0.8;
|
||||
distortionPass.material.uniforms.grainScale.value = 5.0;
|
||||
composer.addPass(distortionPass);
|
||||
|
||||
const pointer = { x: -1, y: -1, strength: 0, prevX: -1, prevY: -1 };
|
||||
const mouse = new THREE.Vector2();
|
||||
const raycaster = new THREE.Raycaster();
|
||||
|
||||
const glbRepulsion = {
|
||||
radius: 30,
|
||||
maxDistance: 2,
|
||||
|
@ -64,14 +60,12 @@ const glbRepulsion = {
|
|||
interpolationSpeed: 3
|
||||
};
|
||||
setGLBRepulsionSystem(glbRepulsion);
|
||||
|
||||
function toSimPixels(e) {
|
||||
const rect = renderer.domElement.getBoundingClientRect();
|
||||
const x = (e.clientX - rect.left) * dpr;
|
||||
const y = (rect.height - (e.clientY - rect.top)) * dpr;
|
||||
return { x, y };
|
||||
}
|
||||
|
||||
renderer.domElement.addEventListener('pointermove', (e) => {
|
||||
const { x, y } = toSimPixels(e);
|
||||
const dx = pointer.prevX < 0 ? 0 : Math.abs(x - pointer.prevX);
|
||||
|
@ -88,12 +82,10 @@ renderer.domElement.addEventListener('pointermove', (e) => {
|
|||
mouse.x = nx * 2 - 1;
|
||||
mouse.y = -ny * 2 + 1;
|
||||
}, { passive: true });
|
||||
|
||||
renderer.domElement.addEventListener('pointerleave', () => {
|
||||
Object.assign(pointer, { x: -1, y: -1, strength: 0 });
|
||||
mouse.set(-999, -999);
|
||||
}, { passive: true });
|
||||
|
||||
function updateGLBRepulsion(camera, mouse, dt) {
|
||||
if (mouse.x === -999) {
|
||||
[currentModel, nextModel].forEach(m => {
|
||||
|
@ -130,7 +122,6 @@ function updateGLBRepulsion(camera, mouse, dt) {
|
|||
m.position.lerp(target, Math.min(glbRepulsion.interpolationSpeed * dt, 1));
|
||||
});
|
||||
}
|
||||
|
||||
function initializeScene() {
|
||||
const { model, animMixer } = createModelFromPreloaded('bold', preloadedModels, camera, controls);
|
||||
setCurrentModel(model);
|
||||
|
@ -139,7 +130,6 @@ function initializeScene() {
|
|||
glbRepulsion.originalPositions.set(currentModel, currentModel.position.clone());
|
||||
startBoldRoughnessAnimation(true);
|
||||
}
|
||||
|
||||
const clock = new THREE.Clock();
|
||||
function animate() {
|
||||
requestAnimationFrame(animate);
|
||||
|
@ -160,7 +150,6 @@ function animate() {
|
|||
controls.update();
|
||||
composer.render();
|
||||
}
|
||||
|
||||
async function init() {
|
||||
try {
|
||||
preloadedModels = await sceneLoader.loadAllModels();
|
||||
|
@ -182,5 +171,4 @@ async function init() {
|
|||
sceneLoader.setLoadingMessage('Error loading experience. Please refresh.');
|
||||
}
|
||||
}
|
||||
|
||||
init();
|
||||
|
|
|
@ -40,7 +40,7 @@ export const boldGlassMaterial = new THREE.MeshPhysicalMaterial({
|
|||
|
||||
// Orange wireframe material for bold Cubewire mesh
|
||||
export const boldWireframeMaterial = new THREE.MeshStandardMaterial({
|
||||
color: 0xff8600,
|
||||
color: 0xffa000,
|
||||
metalness: 0.05,
|
||||
roughness: 0.5
|
||||
});
|
||||
|
@ -69,7 +69,7 @@ export const innovationGlassMaterial = new THREE.MeshPhysicalMaterial({
|
|||
export const frostedGlassMaterial = new THREE.MeshPhysicalMaterial({
|
||||
color: 0xffffff,
|
||||
metalness: 0.0,
|
||||
roughness: 0.25,
|
||||
roughness: 0.35,
|
||||
transmission: 1.0,
|
||||
ior: 1.5,
|
||||
thickness: 2.0,
|
||||
|
@ -87,11 +87,11 @@ export const frostedGlassMaterial = new THREE.MeshPhysicalMaterial({
|
|||
|
||||
// Orange material with video shader for innovation
|
||||
export const lightOrangeMaterial = new THREE.MeshStandardMaterial({
|
||||
color: 0xff8600,
|
||||
color: 0xffa000,
|
||||
metalness: 0.05,
|
||||
roughness: 0.4,
|
||||
envMapIntensity: 0,
|
||||
emissive: new THREE.Color(0xffad47),
|
||||
emissive: new THREE.Color(0xddbbbb),
|
||||
emissiveMap: videoTexture,
|
||||
emissiveIntensity: 2.25
|
||||
});
|
||||
|
|
|
@ -32,8 +32,8 @@ export function createScene() {
|
|||
composer.addPass(renderPass);
|
||||
const bloomPass = new UnrealBloomPass(
|
||||
new THREE.Vector2(window.innerWidth, window.innerHeight),
|
||||
1.0, // strength
|
||||
0.45, // radius
|
||||
0.8, // strength
|
||||
0.4, // radius
|
||||
0.85 // threshold
|
||||
);
|
||||
composer.addPass(bloomPass);
|
||||
|
@ -51,33 +51,33 @@ export function createScene() {
|
|||
|
||||
export function setupLighting(scene, camera) {
|
||||
// Consistent Lighting Setup
|
||||
const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
|
||||
const ambientLight = new THREE.AmbientLight(0xffffff, 1);
|
||||
scene.add(ambientLight);
|
||||
const hemiLight = new THREE.HemisphereLight(0xffffff, 0x666666, 1.5);
|
||||
const hemiLight = new THREE.HemisphereLight(0xffffff, 0x666666, 2);
|
||||
hemiLight.position.set(0, 20, 0);
|
||||
scene.add(hemiLight);
|
||||
const fillLight = new THREE.DirectionalLight(0xffffff, 1.2);
|
||||
const fillLight = new THREE.DirectionalLight(0xffffff, 1.8);
|
||||
fillLight.position.set(-12, 6, -8);
|
||||
scene.add(fillLight);
|
||||
const topLight = new THREE.DirectionalLight(0xffffff, 1.5);
|
||||
const topLight = new THREE.DirectionalLight(0xffffff, 2);
|
||||
topLight.position.set(5, 15, 5);
|
||||
scene.add(topLight);
|
||||
const bottomLight = new THREE.DirectionalLight(0xffffff, 0.8);
|
||||
const bottomLight = new THREE.DirectionalLight(0xffffff, 2.2);
|
||||
bottomLight.position.set(-3, -8, 3);
|
||||
scene.add(bottomLight);
|
||||
const leftLight = new THREE.DirectionalLight(0xffffff, 1.0);
|
||||
const leftLight = new THREE.DirectionalLight(0xffffff, 1.5);
|
||||
leftLight.position.set(-12, 2, 5);
|
||||
scene.add(leftLight);
|
||||
const rightLight = new THREE.DirectionalLight(0xffffff, 1.0);
|
||||
const rightLight = new THREE.DirectionalLight(0xffffff, 1.5);
|
||||
rightLight.position.set(12, 2, -5);
|
||||
scene.add(rightLight);
|
||||
const frontLight = new THREE.DirectionalLight(0xffffff, 0.8);
|
||||
const frontLight = new THREE.DirectionalLight(0xffffff, 1.2);
|
||||
frontLight.position.set(8, 4, 12);
|
||||
scene.add(frontLight);
|
||||
const backLight = new THREE.DirectionalLight(0xffffff, 0.8);
|
||||
const backLight = new THREE.DirectionalLight(0xffffff, 1.2);
|
||||
backLight.position.set(-8, 4, -12);
|
||||
scene.add(backLight);
|
||||
const cameraLight = new THREE.PointLight(0xffffff, 0.8, 0, 2);
|
||||
const cameraLight = new THREE.PointLight(0xffffff, 0.8, 0, 3);
|
||||
camera.add(cameraLight);
|
||||
scene.add(camera);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue