almost final
This commit is contained in:
parent
8d52d89024
commit
6bd4a96e2d
|
@ -8,7 +8,7 @@ const FluidSimShader = {
|
||||||
iResolution: { value: new THREE.Vector2() },
|
iResolution: { value: new THREE.Vector2() },
|
||||||
iTime: { value: 0.0 },
|
iTime: { value: 0.0 },
|
||||||
mouse: { value: new THREE.Vector3(-1, -1, 0.0) },
|
mouse: { value: new THREE.Vector3(-1, -1, 0.0) },
|
||||||
dissipation: { value: 0.950 }, // Slightly more persistent for trails
|
dissipation: { value: 0.95 }, // Slightly more persistent for trails
|
||||||
tension: { value: 2.2 }, // Higher tension for stronger ripples
|
tension: { value: 2.2 }, // Higher tension for stronger ripples
|
||||||
radius: { value: 20.0 }, // Larger splat radius
|
radius: { value: 20.0 }, // Larger splat radius
|
||||||
trailLength: { value: 5 }, // Number of trailing ripples
|
trailLength: { value: 5 }, // Number of trailing ripples
|
||||||
|
@ -80,7 +80,7 @@ const FluidSimShader = {
|
||||||
|
|
||||||
// Gaussian with sine wave for ripple pattern
|
// Gaussian with sine wave for ripple pattern
|
||||||
float g = exp(-pow(dist - offset, 2.0) / (r * r * 0.5));
|
float g = exp(-pow(dist - offset, 2.0) / (r * r * 0.5));
|
||||||
float ripple = sin(dist * 0.2 - iTime * 8.0 + timeOffset) * g;
|
float ripple = sin(dist * 0.2 - iTime * 16.0 + timeOffset) * g;
|
||||||
|
|
||||||
// Diminishing strength for trailing ripples
|
// Diminishing strength for trailing ripples
|
||||||
float strength = mouse.z * (1.0 - i * 0.2) * 0.8;
|
float strength = mouse.z * (1.0 - i * 0.2) * 0.8;
|
||||||
|
|
149
src/main.js
149
src/main.js
|
@ -12,7 +12,8 @@ import {
|
||||||
updateTransition,
|
updateTransition,
|
||||||
onMouseScroll,
|
onMouseScroll,
|
||||||
setCurrentModel,
|
setCurrentModel,
|
||||||
setMixer
|
setMixer,
|
||||||
|
setGLBRepulsionSystem
|
||||||
} from './transitionManager.js';
|
} from './transitionManager.js';
|
||||||
import {
|
import {
|
||||||
startBoldRoughnessAnimation,
|
startBoldRoughnessAnimation,
|
||||||
|
@ -48,7 +49,6 @@ let preloadedModels = {};
|
||||||
// Enhanced fluid simulation + distortion pass
|
// Enhanced fluid simulation + distortion pass
|
||||||
const dpr = renderer.getPixelRatio ? renderer.getPixelRatio() : Math.min(window.devicePixelRatio || 1, 2);
|
const dpr = renderer.getPixelRatio ? renderer.getPixelRatio() : Math.min(window.devicePixelRatio || 1, 2);
|
||||||
const fluid = createFluidSimulation(renderer, dpr);
|
const fluid = createFluidSimulation(renderer, dpr);
|
||||||
|
|
||||||
const distortionPass = new ShaderPass(FluidDistortionShader);
|
const distortionPass = new ShaderPass(FluidDistortionShader);
|
||||||
distortionPass.material.uniforms.tSim.value = fluid.getTexture();
|
distortionPass.material.uniforms.tSim.value = fluid.getTexture();
|
||||||
distortionPass.material.uniforms.iResolution.value.set(window.innerWidth * dpr, window.innerHeight * dpr);
|
distortionPass.material.uniforms.iResolution.value.set(window.innerWidth * dpr, window.innerHeight * dpr);
|
||||||
|
@ -64,7 +64,6 @@ distortionPass.material.uniforms.ambientLight.value = 1;
|
||||||
// New ripple whiteness parameters
|
// New ripple whiteness parameters
|
||||||
distortionPass.material.uniforms.rippleWhiteness.value = 0.025; // Amount of white tint
|
distortionPass.material.uniforms.rippleWhiteness.value = 0.025; // Amount of white tint
|
||||||
distortionPass.material.uniforms.rippleBrightness.value = 1; // Brightness boost for ripples
|
distortionPass.material.uniforms.rippleBrightness.value = 1; // Brightness boost for ripples
|
||||||
|
|
||||||
composer.addPass(distortionPass);
|
composer.addPass(distortionPass);
|
||||||
|
|
||||||
// Enhanced pointer tracking
|
// Enhanced pointer tracking
|
||||||
|
@ -78,8 +77,22 @@ const pointer = {
|
||||||
maxTrailLength: 5
|
maxTrailLength: 5
|
||||||
};
|
};
|
||||||
|
|
||||||
// Mouse coordinates for starfield
|
// Mouse coordinates for starfield and GLB interaction
|
||||||
const mouse = new THREE.Vector2();
|
const mouse = new THREE.Vector2();
|
||||||
|
const raycaster = new THREE.Raycaster();
|
||||||
|
|
||||||
|
// GLB cursor repulsion parameters
|
||||||
|
const glbRepulsion = {
|
||||||
|
radius: 30, // Repulsion radius
|
||||||
|
maxDistance: 2, // Maximum distance GLB can move from original position
|
||||||
|
strength: 8, // Repulsion strength
|
||||||
|
originalPositions: new Map(), // Store original positions for each model
|
||||||
|
currentTargets: new Map(), // Store current target positions
|
||||||
|
interpolationSpeed: 3 // Speed of position interpolation
|
||||||
|
};
|
||||||
|
|
||||||
|
// Connect GLB repulsion system to transition manager
|
||||||
|
setGLBRepulsionSystem(glbRepulsion);
|
||||||
|
|
||||||
function toSimPixels(e) {
|
function toSimPixels(e) {
|
||||||
const rect = renderer.domElement.getBoundingClientRect();
|
const rect = renderer.domElement.getBoundingClientRect();
|
||||||
|
@ -93,7 +106,6 @@ renderer.domElement.addEventListener('pointermove', (e) => {
|
||||||
const dx = (pointer.prevX < 0) ? 0 : Math.abs(x - pointer.prevX);
|
const dx = (pointer.prevX < 0) ? 0 : Math.abs(x - pointer.prevX);
|
||||||
const dy = (pointer.prevY < 0) ? 0 : Math.abs(y - pointer.prevY);
|
const dy = (pointer.prevY < 0) ? 0 : Math.abs(y - pointer.prevY);
|
||||||
const speed = Math.min(Math.sqrt(dx * dx + dy * dy) / (6.0 * dpr), 1.0); // More sensitive
|
const speed = Math.min(Math.sqrt(dx * dx + dy * dy) / (6.0 * dpr), 1.0); // More sensitive
|
||||||
|
|
||||||
pointer.x = x;
|
pointer.x = x;
|
||||||
pointer.y = y;
|
pointer.y = y;
|
||||||
pointer.strength = speed * 1.2; // Enhanced strength
|
pointer.strength = speed * 1.2; // Enhanced strength
|
||||||
|
@ -106,7 +118,7 @@ renderer.domElement.addEventListener('pointermove', (e) => {
|
||||||
const normalizedY = 1.0 - (e.clientY - rect.top) / rect.height; // Flip Y
|
const normalizedY = 1.0 - (e.clientY - rect.top) / rect.height; // Flip Y
|
||||||
distortionPass.material.uniforms.lightPosition.value.set(normalizedX, normalizedY, 1.0);
|
distortionPass.material.uniforms.lightPosition.value.set(normalizedX, normalizedY, 1.0);
|
||||||
|
|
||||||
// Update mouse coordinates for starfield
|
// Update mouse coordinates for starfield and GLB interaction
|
||||||
mouse.x = ((e.clientX - rect.left) / rect.width) * 2 - 1;
|
mouse.x = ((e.clientX - rect.left) / rect.width) * 2 - 1;
|
||||||
mouse.y = -((e.clientY - rect.top) / rect.height) * 2 + 1;
|
mouse.y = -((e.clientY - rect.top) / rect.height) * 2 + 1;
|
||||||
}, { passive: true });
|
}, { passive: true });
|
||||||
|
@ -117,11 +129,119 @@ renderer.domElement.addEventListener('pointerleave', () => {
|
||||||
pointer.strength = 0.0;
|
pointer.strength = 0.0;
|
||||||
mouse.x = -999;
|
mouse.x = -999;
|
||||||
mouse.y = -999;
|
mouse.y = -999;
|
||||||
|
|
||||||
// Reset light to center when mouse leaves
|
// Reset light to center when mouse leaves
|
||||||
distortionPass.material.uniforms.lightPosition.value.set(0.5, 0.5, 1.0);
|
distortionPass.material.uniforms.lightPosition.value.set(0.5, 0.5, 1.0);
|
||||||
}, { passive: true });
|
}, { passive: true });
|
||||||
|
|
||||||
|
// GLB cursor repulsion function
|
||||||
|
function updateGLBRepulsion(camera, mouse, deltaTime) {
|
||||||
|
if (!mouse || mouse.x === -999 || mouse.y === -999) {
|
||||||
|
// Mouse is not active, return models to original positions
|
||||||
|
if (currentModel) {
|
||||||
|
const originalPos = glbRepulsion.originalPositions.get(currentModel);
|
||||||
|
if (originalPos) {
|
||||||
|
const currentTarget = glbRepulsion.currentTargets.get(currentModel) || new THREE.Vector3();
|
||||||
|
currentTarget.copy(originalPos);
|
||||||
|
glbRepulsion.currentTargets.set(currentModel, currentTarget);
|
||||||
|
// Interpolate to original position
|
||||||
|
const lerpFactor = Math.min(glbRepulsion.interpolationSpeed * deltaTime, 1.0);
|
||||||
|
currentModel.position.lerp(currentTarget, lerpFactor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nextModel) {
|
||||||
|
const originalPos = glbRepulsion.originalPositions.get(nextModel);
|
||||||
|
if (originalPos) {
|
||||||
|
const currentTarget = glbRepulsion.currentTargets.get(nextModel) || new THREE.Vector3();
|
||||||
|
currentTarget.copy(originalPos);
|
||||||
|
glbRepulsion.currentTargets.set(nextModel, currentTarget);
|
||||||
|
// Interpolate to original position
|
||||||
|
const lerpFactor = Math.min(glbRepulsion.interpolationSpeed * deltaTime, 1.0);
|
||||||
|
nextModel.position.lerp(currentTarget, lerpFactor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get mouse position in 3D world space
|
||||||
|
raycaster.setFromCamera(mouse, camera);
|
||||||
|
const distance = 50; // Project to a plane at fixed distance
|
||||||
|
const mouseWorldPos = raycaster.ray.direction.clone().multiplyScalar(distance).add(raycaster.ray.origin);
|
||||||
|
|
||||||
|
// Handle current model repulsion
|
||||||
|
if (currentModel) {
|
||||||
|
let originalPos = glbRepulsion.originalPositions.get(currentModel);
|
||||||
|
if (!originalPos) {
|
||||||
|
originalPos = currentModel.position.clone();
|
||||||
|
glbRepulsion.originalPositions.set(currentModel, originalPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate repulsion
|
||||||
|
const modelPos = currentModel.position.clone();
|
||||||
|
const dx = modelPos.x - mouseWorldPos.x;
|
||||||
|
const dy = modelPos.y - mouseWorldPos.y;
|
||||||
|
const dz = modelPos.z - mouseWorldPos.z;
|
||||||
|
const dist = Math.sqrt(dx * dx + dy * dy + dz * dz);
|
||||||
|
|
||||||
|
let targetPos = originalPos.clone();
|
||||||
|
if (dist < glbRepulsion.radius && dist > 0) {
|
||||||
|
const force = (1 - dist / glbRepulsion.radius) * glbRepulsion.strength;
|
||||||
|
const nx = dx / dist;
|
||||||
|
const ny = dy / dist;
|
||||||
|
const nz = dz / dist;
|
||||||
|
const repulsionVector = new THREE.Vector3(nx * force, ny * force, nz * force);
|
||||||
|
targetPos.add(repulsionVector);
|
||||||
|
// Limit maximum distance from original position
|
||||||
|
const offsetFromOriginal = targetPos.clone().sub(originalPos);
|
||||||
|
if (offsetFromOriginal.length() > glbRepulsion.maxDistance) {
|
||||||
|
offsetFromOriginal.normalize().multiplyScalar(glbRepulsion.maxDistance);
|
||||||
|
targetPos = originalPos.clone().add(offsetFromOriginal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store and interpolate to target position
|
||||||
|
glbRepulsion.currentTargets.set(currentModel, targetPos);
|
||||||
|
const lerpFactor = Math.min(glbRepulsion.interpolationSpeed * deltaTime, 1.0);
|
||||||
|
currentModel.position.lerp(targetPos, lerpFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle next model repulsion during transitions
|
||||||
|
if (nextModel) {
|
||||||
|
let originalPos = glbRepulsion.originalPositions.get(nextModel);
|
||||||
|
if (!originalPos) {
|
||||||
|
originalPos = nextModel.position.clone();
|
||||||
|
glbRepulsion.originalPositions.set(nextModel, originalPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate repulsion
|
||||||
|
const modelPos = nextModel.position.clone();
|
||||||
|
const dx = modelPos.x - mouseWorldPos.x;
|
||||||
|
const dy = modelPos.y - mouseWorldPos.y;
|
||||||
|
const dz = modelPos.z - mouseWorldPos.z;
|
||||||
|
const dist = Math.sqrt(dx * dx + dy * dy + dz * dz);
|
||||||
|
|
||||||
|
let targetPos = originalPos.clone();
|
||||||
|
if (dist < glbRepulsion.radius && dist > 0) {
|
||||||
|
const force = (1 - dist / glbRepulsion.radius) * glbRepulsion.strength;
|
||||||
|
const nx = dx / dist;
|
||||||
|
const ny = dy / dist;
|
||||||
|
const nz = dz / dist;
|
||||||
|
const repulsionVector = new THREE.Vector3(nx * force, ny * force, nz * force);
|
||||||
|
targetPos.add(repulsionVector);
|
||||||
|
// Limit maximum distance from original position
|
||||||
|
const offsetFromOriginal = targetPos.clone().sub(originalPos);
|
||||||
|
if (offsetFromOriginal.length() > glbRepulsion.maxDistance) {
|
||||||
|
offsetFromOriginal.normalize().multiplyScalar(glbRepulsion.maxDistance);
|
||||||
|
targetPos = originalPos.clone().add(offsetFromOriginal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store and interpolate to target position
|
||||||
|
glbRepulsion.currentTargets.set(nextModel, targetPos);
|
||||||
|
const lerpFactor = Math.min(glbRepulsion.interpolationSpeed * deltaTime, 1.0);
|
||||||
|
nextModel.position.lerp(targetPos, lerpFactor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize first scene
|
// Initialize first scene
|
||||||
function initializeScene() {
|
function initializeScene() {
|
||||||
console.log('Initializing first scene (bold)');
|
console.log('Initializing first scene (bold)');
|
||||||
|
@ -129,13 +249,14 @@ function initializeScene() {
|
||||||
setCurrentModel(model);
|
setCurrentModel(model);
|
||||||
setMixer(animMixer);
|
setMixer(animMixer);
|
||||||
scene.add(currentModel);
|
scene.add(currentModel);
|
||||||
|
// Store original position for repulsion
|
||||||
|
glbRepulsion.originalPositions.set(currentModel, currentModel.position.clone());
|
||||||
startBoldRoughnessAnimation(true);
|
startBoldRoughnessAnimation(true);
|
||||||
console.log('Bold scene initialized');
|
console.log('Bold scene initialized');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Animation loop
|
// Animation loop
|
||||||
const clock = new THREE.Clock();
|
const clock = new THREE.Clock();
|
||||||
|
|
||||||
function animate() {
|
function animate() {
|
||||||
requestAnimationFrame(animate);
|
requestAnimationFrame(animate);
|
||||||
const delta = clock.getDelta();
|
const delta = clock.getDelta();
|
||||||
|
@ -149,6 +270,11 @@ function animate() {
|
||||||
updateTransition(delta, scene);
|
updateTransition(delta, scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GLB cursor repulsion (only when not transitioning to avoid conflicts)
|
||||||
|
if (!isTransitioning) {
|
||||||
|
updateGLBRepulsion(camera, mouse, delta);
|
||||||
|
}
|
||||||
|
|
||||||
// Turntable rotation
|
// Turntable rotation
|
||||||
if (currentModel) {
|
if (currentModel) {
|
||||||
currentModel.rotation.y += turntableSpeed * delta;
|
currentModel.rotation.y += turntableSpeed * delta;
|
||||||
|
@ -179,16 +305,13 @@ async function init() {
|
||||||
console.log('Starting application initialization');
|
console.log('Starting application initialization');
|
||||||
preloadedModels = await sceneLoader.loadAllModels();
|
preloadedModels = await sceneLoader.loadAllModels();
|
||||||
console.log('All models loaded successfully');
|
console.log('All models loaded successfully');
|
||||||
|
|
||||||
initializeScene();
|
initializeScene();
|
||||||
animate();
|
animate();
|
||||||
console.log('Animation loop started');
|
console.log('Animation loop started');
|
||||||
|
|
||||||
window.addEventListener('wheel', (event) => {
|
window.addEventListener('wheel', (event) => {
|
||||||
onMouseScroll(event, preloadedModels, scene, camera, controls);
|
onMouseScroll(event, preloadedModels, scene, camera, controls);
|
||||||
}, { passive: true });
|
}, { passive: true });
|
||||||
console.log('Scroll event listener attached');
|
console.log('Scroll event listener attached');
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to initialize scene:', error);
|
console.error('Failed to initialize scene:', error);
|
||||||
sceneLoader.setLoadingMessage('Error loading experience. Please refresh.');
|
sceneLoader.setLoadingMessage('Error loading experience. Please refresh.');
|
||||||
|
@ -200,16 +323,14 @@ window.addEventListener('resize', () => {
|
||||||
console.log('Window resized');
|
console.log('Window resized');
|
||||||
const w = window.innerWidth;
|
const w = window.innerWidth;
|
||||||
const h = window.innerHeight;
|
const h = window.innerHeight;
|
||||||
|
|
||||||
camera.aspect = w / h;
|
camera.aspect = w / h;
|
||||||
camera.updateProjectionMatrix();
|
camera.updateProjectionMatrix();
|
||||||
renderer.setSize(w, h);
|
renderer.setSize(w, h);
|
||||||
composer.setSize(w, h);
|
composer.setSize(w, h);
|
||||||
|
|
||||||
const pixelRatio = renderer.getPixelRatio ? renderer.getPixelRatio() : Math.min(window.devicePixelRatio || 1, 2);
|
const pixelRatio = renderer.getPixelRatio ? renderer.getPixelRatio() : Math.min(window.devicePixelRatio || 1, 2);
|
||||||
distortionPass.material.uniforms.iResolution.value.set(w * pixelRatio, h * pixelRatio);
|
distortionPass.material.uniforms.iResolution.value.set(w * pixelRatio, h * pixelRatio);
|
||||||
fluid.resize(w, h, pixelRatio);
|
fluid.resize(w, h, pixelRatio);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Start the application
|
// Start the application
|
||||||
init();
|
init();
|
|
@ -30,7 +30,6 @@ export function createScene() {
|
||||||
const composer = new EffectComposer(renderer);
|
const composer = new EffectComposer(renderer);
|
||||||
const renderPass = new RenderPass(scene, camera);
|
const renderPass = new RenderPass(scene, camera);
|
||||||
composer.addPass(renderPass);
|
composer.addPass(renderPass);
|
||||||
|
|
||||||
const bloomPass = new UnrealBloomPass(
|
const bloomPass = new UnrealBloomPass(
|
||||||
new THREE.Vector2(window.innerWidth, window.innerHeight),
|
new THREE.Vector2(window.innerWidth, window.innerHeight),
|
||||||
1.0, // strength
|
1.0, // strength
|
||||||
|
@ -54,55 +53,45 @@ export function setupLighting(scene, camera) {
|
||||||
// Consistent Lighting Setup
|
// Consistent Lighting Setup
|
||||||
const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
|
const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
|
||||||
scene.add(ambientLight);
|
scene.add(ambientLight);
|
||||||
|
|
||||||
const hemiLight = new THREE.HemisphereLight(0xffffff, 0x666666, 1.5);
|
const hemiLight = new THREE.HemisphereLight(0xffffff, 0x666666, 1.5);
|
||||||
hemiLight.position.set(0, 20, 0);
|
hemiLight.position.set(0, 20, 0);
|
||||||
scene.add(hemiLight);
|
scene.add(hemiLight);
|
||||||
|
|
||||||
const fillLight = new THREE.DirectionalLight(0xffffff, 1.2);
|
const fillLight = new THREE.DirectionalLight(0xffffff, 1.2);
|
||||||
fillLight.position.set(-12, 6, -8);
|
fillLight.position.set(-12, 6, -8);
|
||||||
scene.add(fillLight);
|
scene.add(fillLight);
|
||||||
|
|
||||||
const topLight = new THREE.DirectionalLight(0xffffff, 1.5);
|
const topLight = new THREE.DirectionalLight(0xffffff, 1.5);
|
||||||
topLight.position.set(5, 15, 5);
|
topLight.position.set(5, 15, 5);
|
||||||
scene.add(topLight);
|
scene.add(topLight);
|
||||||
|
|
||||||
const bottomLight = new THREE.DirectionalLight(0xffffff, 0.8);
|
const bottomLight = new THREE.DirectionalLight(0xffffff, 0.8);
|
||||||
bottomLight.position.set(-3, -8, 3);
|
bottomLight.position.set(-3, -8, 3);
|
||||||
scene.add(bottomLight);
|
scene.add(bottomLight);
|
||||||
|
|
||||||
const leftLight = new THREE.DirectionalLight(0xffffff, 1.0);
|
const leftLight = new THREE.DirectionalLight(0xffffff, 1.0);
|
||||||
leftLight.position.set(-12, 2, 5);
|
leftLight.position.set(-12, 2, 5);
|
||||||
scene.add(leftLight);
|
scene.add(leftLight);
|
||||||
|
|
||||||
const rightLight = new THREE.DirectionalLight(0xffffff, 1.0);
|
const rightLight = new THREE.DirectionalLight(0xffffff, 1.0);
|
||||||
rightLight.position.set(12, 2, -5);
|
rightLight.position.set(12, 2, -5);
|
||||||
scene.add(rightLight);
|
scene.add(rightLight);
|
||||||
|
|
||||||
const frontLight = new THREE.DirectionalLight(0xffffff, 0.8);
|
const frontLight = new THREE.DirectionalLight(0xffffff, 0.8);
|
||||||
frontLight.position.set(8, 4, 12);
|
frontLight.position.set(8, 4, 12);
|
||||||
scene.add(frontLight);
|
scene.add(frontLight);
|
||||||
|
|
||||||
const backLight = new THREE.DirectionalLight(0xffffff, 0.8);
|
const backLight = new THREE.DirectionalLight(0xffffff, 0.8);
|
||||||
backLight.position.set(-8, 4, -12);
|
backLight.position.set(-8, 4, -12);
|
||||||
scene.add(backLight);
|
scene.add(backLight);
|
||||||
|
|
||||||
const cameraLight = new THREE.PointLight(0xffffff, 0.8, 0, 2);
|
const cameraLight = new THREE.PointLight(0xffffff, 0.8, 0, 2);
|
||||||
camera.add(cameraLight);
|
camera.add(cameraLight);
|
||||||
scene.add(camera);
|
scene.add(camera);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setupControls(camera, renderer) {
|
export function setupControls(camera, renderer) {
|
||||||
// Controls with zoom disabled and camera constraints
|
// Controls with zoom and pan disabled and camera constraints
|
||||||
const controls = new OrbitControls(camera, renderer.domElement);
|
const controls = new OrbitControls(camera, renderer.domElement);
|
||||||
controls.enableDamping = true;
|
controls.enableDamping = true;
|
||||||
controls.dampingFactor = 0.25;
|
controls.dampingFactor = 0.25;
|
||||||
controls.enableZoom = false; // Disable zoom
|
controls.enableZoom = false; // Disable zoom
|
||||||
|
controls.enablePan = false; // Disable panning
|
||||||
// Add camera constraints to prevent extreme angles
|
// Add camera constraints to prevent extreme angles
|
||||||
controls.maxPolarAngle = Math.PI * 0.8; // Prevent looking too far up
|
controls.maxPolarAngle = Math.PI * 0.8; // Prevent looking too far up
|
||||||
controls.minPolarAngle = Math.PI * 0.2; // Prevent looking too far down
|
controls.minPolarAngle = Math.PI * 0.2; // Prevent looking too far down
|
||||||
|
console.log('Orbit controls initialized with camera constraints and pan disabled');
|
||||||
console.log('Orbit controls initialized with camera constraints');
|
|
||||||
return controls;
|
return controls;
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
import * as THREE from 'three';
|
import * as THREE from 'three';
|
||||||
|
|
||||||
export function createStarfield(scene) {
|
export function createStarfield(scene) {
|
||||||
const starCount = 12000;
|
const starCount = 16000;
|
||||||
const starDistance = 300;
|
const starDistance = 300;
|
||||||
|
|
||||||
// Create geometry for stars
|
// Create geometry for stars
|
||||||
|
|
Loading…
Reference in a new issue