non ce n'est pas réaliste. Je veux
Browse files- index.html +67 -128
index.html
CHANGED
|
@@ -88,146 +88,87 @@
|
|
| 88 |
});
|
| 89 |
renderer.setPixelRatio(window.devicePixelRatio);
|
| 90 |
renderer.setSize(canvasContainer.clientWidth, canvasContainer.clientHeight);
|
| 91 |
-
// === Create
|
| 92 |
const headGroup = new THREE.Group();
|
| 93 |
scene.add(headGroup);
|
| 94 |
|
| 95 |
-
//
|
| 96 |
-
const headGeometry = new THREE.SphereGeometry(1.
|
| 97 |
-
headGeometry.scale(0.8, 1.1, 0.9); // More oval shape
|
| 98 |
const headMaterial = new THREE.MeshStandardMaterial({
|
| 99 |
-
color:
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
});
|
| 104 |
const head = new THREE.Mesh(headGeometry, headMaterial);
|
| 105 |
headGroup.add(head);
|
| 106 |
|
| 107 |
-
// Eyes
|
| 108 |
-
const eyeGeometry = new THREE.SphereGeometry(0.
|
| 109 |
const eyeMaterial = new THREE.MeshStandardMaterial({
|
| 110 |
-
color:
|
| 111 |
-
|
| 112 |
-
|
| 113 |
});
|
| 114 |
|
| 115 |
// Left Eye
|
| 116 |
const eyeLeft = new THREE.Mesh(eyeGeometry, eyeMaterial);
|
| 117 |
-
eyeLeft.position.set(-0.
|
| 118 |
headGroup.add(eyeLeft);
|
| 119 |
|
| 120 |
// Right Eye
|
| 121 |
const eyeRight = new THREE.Mesh(eyeGeometry, eyeMaterial.clone());
|
| 122 |
-
eyeRight.position.set(0.
|
| 123 |
headGroup.add(eyeRight);
|
| 124 |
|
| 125 |
-
//
|
| 126 |
-
const
|
| 127 |
-
const
|
| 128 |
-
color:
|
|
|
|
|
|
|
| 129 |
});
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
const
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
// Eyelashes
|
| 142 |
-
const eyelashGeometry = new THREE.ConeGeometry(0.02, 0.15, 4);
|
| 143 |
-
const eyelashMaterial = new THREE.MeshBasicMaterial({ color: 0x000000 });
|
| 144 |
-
|
| 145 |
-
// Left Eyelashes
|
| 146 |
-
for (let i = 0; i < 8; i++) {
|
| 147 |
-
const angle = (i / 8) * Math.PI * 0.5 - Math.PI * 0.25;
|
| 148 |
-
const eyelash = new THREE.Mesh(eyelashGeometry, eyelashMaterial);
|
| 149 |
-
eyelash.position.set(-0.7 + Math.cos(angle) * 0.3, 0.3 + Math.sin(angle) * 0.3, 1.85);
|
| 150 |
-
eyelash.rotation.z = angle;
|
| 151 |
-
headGroup.add(eyelash);
|
| 152 |
-
}
|
| 153 |
-
|
| 154 |
-
// Right Eyelashes
|
| 155 |
-
for (let i = 0; i < 8; i++) {
|
| 156 |
-
const angle = (i / 8) * Math.PI * 0.5 - Math.PI * 0.25;
|
| 157 |
-
const eyelash = new THREE.Mesh(eyelashGeometry, eyelashMaterial.clone());
|
| 158 |
-
eyelash.position.set(0.7 + Math.cos(angle) * 0.3, 0.3 + Math.sin(angle) * 0.3, 1.85);
|
| 159 |
-
eyelash.rotation.z = angle;
|
| 160 |
-
headGroup.add(eyelash);
|
| 161 |
-
}
|
| 162 |
-
|
| 163 |
-
// Nose (more refined)
|
| 164 |
-
const noseGeometry = new THREE.ConeGeometry(0.3, 0.6, 32);
|
| 165 |
-
const noseMaterial = new THREE.MeshStandardMaterial({
|
| 166 |
-
color: 0xE8BBA5,
|
| 167 |
-
roughness: 0.4
|
| 168 |
});
|
| 169 |
-
const nose = new THREE.Mesh(noseGeometry, noseMaterial);
|
| 170 |
-
nose.position.set(0, 0, 1.9);
|
| 171 |
-
nose.rotation.x = Math.PI / 10;
|
| 172 |
-
headGroup.add(nose);
|
| 173 |
|
| 174 |
-
//
|
| 175 |
-
const
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
|
| 179 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 180 |
});
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
lips.rotation.x = Math.PI / 8;
|
| 184 |
-
headGroup.add(lips);
|
| 185 |
-
|
| 186 |
-
// Eyebrows
|
| 187 |
-
const eyebrowGeometry = new THREE.BoxGeometry(0.5, 0.05, 0.02);
|
| 188 |
-
const eyebrowMaterial = new THREE.MeshStandardMaterial({ color: 0x3A2A1A });
|
| 189 |
-
|
| 190 |
-
// Left Eyebrow
|
| 191 |
-
const leftEyebrow = new THREE.Mesh(eyebrowGeometry, eyebrowMaterial);
|
| 192 |
-
leftEyebrow.position.set(-0.7, 0.5, 1.8);
|
| 193 |
-
leftEyebrow.rotation.z = -0.2;
|
| 194 |
-
headGroup.add(leftEyebrow);
|
| 195 |
-
|
| 196 |
-
// Right Eyebrow
|
| 197 |
-
const rightEyebrow = new THREE.Mesh(eyebrowGeometry, eyebrowMaterial.clone());
|
| 198 |
-
rightEyebrow.position.set(0.7, 0.5, 1.8);
|
| 199 |
-
rightEyebrow.rotation.z = 0.2;
|
| 200 |
-
headGroup.add(rightEyebrow);
|
| 201 |
-
|
| 202 |
-
// Hair (simplified)
|
| 203 |
-
const hairGeometry = new THREE.SphereGeometry(2.0, 32, 32);
|
| 204 |
-
hairGeometry.scale(0.9, 1.2, 1.0);
|
| 205 |
-
const hairMaterial = new THREE.MeshStandardMaterial({
|
| 206 |
-
color: 0x4B3A2D,
|
| 207 |
-
roughness: 0.8,
|
| 208 |
-
metalness: 0.1
|
| 209 |
-
});
|
| 210 |
-
const hair = new THREE.Mesh(hairGeometry, hairMaterial);
|
| 211 |
-
hair.position.set(0, 0.4, 0);
|
| 212 |
-
headGroup.add(hair);
|
| 213 |
-
// Enhanced Lighting
|
| 214 |
-
const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
|
| 215 |
scene.add(ambientLight);
|
| 216 |
|
| 217 |
-
const
|
| 218 |
-
|
| 219 |
-
|
| 220 |
-
directionalLight.shadow.mapSize.width = 1024;
|
| 221 |
-
directionalLight.shadow.mapSize.height = 1024;
|
| 222 |
-
scene.add(directionalLight);
|
| 223 |
|
| 224 |
-
const
|
| 225 |
-
|
| 226 |
-
scene.add(
|
| 227 |
|
| 228 |
-
const
|
| 229 |
-
|
| 230 |
-
scene.add(
|
| 231 |
// === Controls ===
|
| 232 |
const sliderY = document.getElementById('rotate-y');
|
| 233 |
const sliderX = document.getElementById('rotate-x');
|
|
@@ -254,27 +195,25 @@
|
|
| 254 |
rotateYValue.textContent = '0°';
|
| 255 |
rotateXValue.textContent = '0°';
|
| 256 |
});
|
| 257 |
-
// Animation Loop with
|
| 258 |
-
let
|
| 259 |
-
let
|
| 260 |
|
| 261 |
function animate() {
|
| 262 |
requestAnimationFrame(animate);
|
| 263 |
|
| 264 |
-
//
|
| 265 |
-
|
| 266 |
-
if (
|
| 267 |
-
|
| 268 |
-
eyeRight.scale.y = 0.05;
|
| 269 |
-
blinkState = true;
|
| 270 |
-
blinkTimer = 0;
|
| 271 |
-
} else if (blinkTimer > 0.1 && blinkState) {
|
| 272 |
-
eyeLeft.scale.y = 1;
|
| 273 |
-
eyeRight.scale.y = 1;
|
| 274 |
-
blinkState = false;
|
| 275 |
-
blinkTimer = 0;
|
| 276 |
}
|
| 277 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 278 |
renderer.render(scene, camera);
|
| 279 |
}
|
| 280 |
// Handle Window Resize
|
|
|
|
| 88 |
});
|
| 89 |
renderer.setPixelRatio(window.devicePixelRatio);
|
| 90 |
renderer.setSize(canvasContainer.clientWidth, canvasContainer.clientHeight);
|
| 91 |
+
// === Create Abstract Face Mesh ===
|
| 92 |
const headGroup = new THREE.Group();
|
| 93 |
scene.add(headGroup);
|
| 94 |
|
| 95 |
+
// Main face shape (simple sphere)
|
| 96 |
+
const headGeometry = new THREE.SphereGeometry(1.5, 32, 32);
|
|
|
|
| 97 |
const headMaterial = new THREE.MeshStandardMaterial({
|
| 98 |
+
color: 0x3498db,
|
| 99 |
+
wireframe: true,
|
| 100 |
+
transparent: true,
|
| 101 |
+
opacity: 0.8
|
| 102 |
});
|
| 103 |
const head = new THREE.Mesh(headGeometry, headMaterial);
|
| 104 |
headGroup.add(head);
|
| 105 |
|
| 106 |
+
// Eyes (simple dots)
|
| 107 |
+
const eyeGeometry = new THREE.SphereGeometry(0.15, 16, 16);
|
| 108 |
const eyeMaterial = new THREE.MeshStandardMaterial({
|
| 109 |
+
color: 0x2ecc71,
|
| 110 |
+
emissive: 0x2ecc71,
|
| 111 |
+
emissiveIntensity: 0.5
|
| 112 |
});
|
| 113 |
|
| 114 |
// Left Eye
|
| 115 |
const eyeLeft = new THREE.Mesh(eyeGeometry, eyeMaterial);
|
| 116 |
+
eyeLeft.position.set(-0.5, 0.2, 1.2);
|
| 117 |
headGroup.add(eyeLeft);
|
| 118 |
|
| 119 |
// Right Eye
|
| 120 |
const eyeRight = new THREE.Mesh(eyeGeometry, eyeMaterial.clone());
|
| 121 |
+
eyeRight.position.set(0.5, 0.2, 1.2);
|
| 122 |
headGroup.add(eyeRight);
|
| 123 |
|
| 124 |
+
// Mouth (simple line)
|
| 125 |
+
const mouthGeometry = new THREE.TorusGeometry(0.3, 0.02, 8, 32, Math.PI);
|
| 126 |
+
const mouthMaterial = new THREE.MeshStandardMaterial({
|
| 127 |
+
color: 0xe74c3c,
|
| 128 |
+
emissive: 0xe74c3c,
|
| 129 |
+
emissiveIntensity: 0.3
|
| 130 |
});
|
| 131 |
+
const mouth = new THREE.Mesh(mouthGeometry, mouthMaterial);
|
| 132 |
+
mouth.position.set(0, -0.3, 1.2);
|
| 133 |
+
mouth.rotation.x = Math.PI / 8;
|
| 134 |
+
headGroup.add(mouth);
|
| 135 |
+
|
| 136 |
+
// Facial points (abstract representation)
|
| 137 |
+
const pointsGeometry = new THREE.SphereGeometry(0.05, 8, 8);
|
| 138 |
+
const pointsMaterial = new THREE.MeshStandardMaterial({
|
| 139 |
+
color: 0xf1c40f,
|
| 140 |
+
emissive: 0xf1c40f,
|
| 141 |
+
emissiveIntensity: 0.2
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 142 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
| 143 |
|
| 144 |
+
// Create facial points
|
| 145 |
+
const pointsPositions = [
|
| 146 |
+
[0, 0.5, 1.3], // Forehead
|
| 147 |
+
[-0.3, -0.1, 1.3], // Left cheek
|
| 148 |
+
[0.3, -0.1, 1.3], // Right cheek
|
| 149 |
+
[0, 0.1, 1.5] // Nose
|
| 150 |
+
];
|
| 151 |
+
|
| 152 |
+
pointsPositions.forEach(pos => {
|
| 153 |
+
const point = new THREE.Mesh(pointsGeometry, pointsMaterial.clone());
|
| 154 |
+
point.position.set(pos[0], pos[1], pos[2]);
|
| 155 |
+
headGroup.add(point);
|
| 156 |
});
|
| 157 |
+
// Abstract Lighting
|
| 158 |
+
const ambientLight = new THREE.AmbientLight(0x333333, 0.8);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 159 |
scene.add(ambientLight);
|
| 160 |
|
| 161 |
+
const directionalLight1 = new THREE.DirectionalLight(0x3498db, 0.8);
|
| 162 |
+
directionalLight1.position.set(5, 3, 5);
|
| 163 |
+
scene.add(directionalLight1);
|
|
|
|
|
|
|
|
|
|
| 164 |
|
| 165 |
+
const directionalLight2 = new THREE.DirectionalLight(0xe74c3c, 0.5);
|
| 166 |
+
directionalLight2.position.set(-5, 3, 5);
|
| 167 |
+
scene.add(directionalLight2);
|
| 168 |
|
| 169 |
+
const directionalLight3 = new THREE.DirectionalLight(0x2ecc71, 0.3);
|
| 170 |
+
directionalLight3.position.set(0, -5, 5);
|
| 171 |
+
scene.add(directionalLight3);
|
| 172 |
// === Controls ===
|
| 173 |
const sliderY = document.getElementById('rotate-y');
|
| 174 |
const sliderX = document.getElementById('rotate-x');
|
|
|
|
| 195 |
rotateYValue.textContent = '0°';
|
| 196 |
rotateXValue.textContent = '0°';
|
| 197 |
});
|
| 198 |
+
// Animation Loop with pulsing effect
|
| 199 |
+
let pulseDirection = 1;
|
| 200 |
+
let pulseIntensity = 0;
|
| 201 |
|
| 202 |
function animate() {
|
| 203 |
requestAnimationFrame(animate);
|
| 204 |
|
| 205 |
+
// Pulsing animation
|
| 206 |
+
pulseIntensity += 0.01 * pulseDirection;
|
| 207 |
+
if (pulseIntensity > 0.3 || pulseIntensity < 0) {
|
| 208 |
+
pulseDirection *= -1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 209 |
}
|
| 210 |
|
| 211 |
+
headGroup.children.forEach(child => {
|
| 212 |
+
if (child.material && child.material.emissiveIntensity !== undefined) {
|
| 213 |
+
child.material.emissiveIntensity = 0.2 + pulseIntensity;
|
| 214 |
+
}
|
| 215 |
+
});
|
| 216 |
+
|
| 217 |
renderer.render(scene, camera);
|
| 218 |
}
|
| 219 |
// Handle Window Resize
|