274 lines
10 KiB
HTML
274 lines
10 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Three.js - Geometry Gallery</title>
|
|
<style>
|
|
body {
|
|
margin: 0;
|
|
overflow: hidden;
|
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
}
|
|
canvas {
|
|
display: block;
|
|
width: 100vw;
|
|
height: 100vh;
|
|
}
|
|
#info {
|
|
position: absolute;
|
|
top: 10px;
|
|
left: 10px;
|
|
color: white;
|
|
background: rgba(0, 0, 0, 0.7);
|
|
padding: 15px;
|
|
border-radius: 8px;
|
|
font-size: 14px;
|
|
max-width: 400px;
|
|
z-index: 100;
|
|
}
|
|
#info h2 {
|
|
margin: 0 0 10px 0;
|
|
font-size: 18px;
|
|
}
|
|
#info .web-source {
|
|
margin-top: 10px;
|
|
padding-top: 10px;
|
|
border-top: 1px solid rgba(255,255,255,0.3);
|
|
font-size: 12px;
|
|
opacity: 0.8;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div id="info">
|
|
<h2>Geometry Gallery</h2>
|
|
<p><strong>Technique:</strong> Multiple advanced geometries with varied materials</p>
|
|
<p><strong>Learning:</strong> Learned about 6 different geometry types: TorusGeometry (donut ring), IcosahedronGeometry (20-sided polyhedron), OctahedronGeometry (8-sided polyhedron), TorusKnotGeometry (twisted tube), DodecahedronGeometry (12-sided polyhedron), and TetrahedronGeometry (4-sided polyhedron). Each geometry accepts different parameters for customization and can be combined in a scene using different materials and positions.</p>
|
|
<div class="web-source">
|
|
<strong>Web Source:</strong><br>
|
|
<a href="https://sbcode.net/threejs/geometries/" target="_blank" style="color: #4fc3f7;">sbcode.net/threejs/geometries/</a><br>
|
|
<em>Applied: Created a 3D gallery showcasing 6 distinct geometry types, each with unique materials (wireframe, standard, phong) and synchronized orbital animations. Demonstrates parameter customization and effective scene composition.</em>
|
|
</div>
|
|
</div>
|
|
|
|
<script type="importmap">
|
|
{
|
|
"imports": {
|
|
"three": "https://cdn.jsdelivr.net/npm/three@0.170.0/build/three.module.js",
|
|
"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.170.0/examples/jsm/"
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<script type="module">
|
|
import * as THREE from 'three';
|
|
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
|
|
|
|
// Scene setup
|
|
let camera, scene, renderer, controls;
|
|
let geometries = [];
|
|
let time = 0;
|
|
|
|
init();
|
|
animate();
|
|
|
|
function init() {
|
|
// Camera setup
|
|
camera = new THREE.PerspectiveCamera(
|
|
60,
|
|
window.innerWidth / window.innerHeight,
|
|
0.1,
|
|
1000
|
|
);
|
|
camera.position.set(0, 3, 12);
|
|
camera.lookAt(0, 0, 0);
|
|
|
|
// Scene
|
|
scene = new THREE.Scene();
|
|
scene.background = new THREE.Color(0x0a0a1a);
|
|
scene.fog = new THREE.Fog(0x0a0a1a, 10, 25);
|
|
|
|
// Renderer (WebGL)
|
|
renderer = new THREE.WebGLRenderer({ antialias: true });
|
|
renderer.setPixelRatio(window.devicePixelRatio);
|
|
renderer.setSize(window.innerWidth, window.innerHeight);
|
|
document.body.appendChild(renderer.domElement);
|
|
|
|
// Orbit controls for user interaction
|
|
controls = new OrbitControls(camera, renderer.domElement);
|
|
controls.enableDamping = true;
|
|
controls.dampingFactor = 0.05;
|
|
controls.minDistance = 5;
|
|
controls.maxDistance = 30;
|
|
|
|
// Create visualization using learned technique
|
|
createVisualization();
|
|
|
|
// Lighting
|
|
const ambientLight = new THREE.AmbientLight(0xffffff, 0.4);
|
|
scene.add(ambientLight);
|
|
|
|
const directionalLight1 = new THREE.DirectionalLight(0x4fc3f7, 0.8);
|
|
directionalLight1.position.set(5, 5, 5);
|
|
scene.add(directionalLight1);
|
|
|
|
const directionalLight2 = new THREE.DirectionalLight(0xf06292, 0.6);
|
|
directionalLight2.position.set(-5, 3, -5);
|
|
scene.add(directionalLight2);
|
|
|
|
const directionalLight3 = new THREE.DirectionalLight(0xffd54f, 0.5);
|
|
directionalLight3.position.set(0, -5, 0);
|
|
scene.add(directionalLight3);
|
|
|
|
// Handle resize
|
|
window.addEventListener('resize', onWindowResize);
|
|
}
|
|
|
|
function createVisualization() {
|
|
// Define geometry configurations with different types
|
|
// Arranged in two rows of 3 geometries each
|
|
const geometryConfigs = [
|
|
{
|
|
// TorusGeometry - donut ring shape
|
|
geometry: new THREE.TorusGeometry(1, 0.4, 16, 100),
|
|
material: new THREE.MeshStandardMaterial({
|
|
color: 0x4fc3f7,
|
|
metalness: 0.7,
|
|
roughness: 0.3,
|
|
emissive: 0x004466,
|
|
emissiveIntensity: 0.2
|
|
}),
|
|
position: [-4, 2, 0],
|
|
rotation: [0, 0, 0],
|
|
rotationSpeed: [0.3, 0.5, 0.1]
|
|
},
|
|
{
|
|
// IcosahedronGeometry - 20-sided polyhedron
|
|
geometry: new THREE.IcosahedronGeometry(1.2, 0),
|
|
material: new THREE.MeshPhongMaterial({
|
|
color: 0xf06292,
|
|
shininess: 100,
|
|
specular: 0xffffff,
|
|
flatShading: true
|
|
}),
|
|
position: [0, 2, 0],
|
|
rotation: [0, 0, 0],
|
|
rotationSpeed: [0.2, 0.4, 0.3]
|
|
},
|
|
{
|
|
// OctahedronGeometry - 8-sided polyhedron
|
|
geometry: new THREE.OctahedronGeometry(1.3, 1),
|
|
material: new THREE.MeshStandardMaterial({
|
|
color: 0xffd54f,
|
|
metalness: 0.5,
|
|
roughness: 0.4,
|
|
emissive: 0x664400,
|
|
emissiveIntensity: 0.15
|
|
}),
|
|
position: [4, 2, 0],
|
|
rotation: [0, 0, 0],
|
|
rotationSpeed: [0.4, 0.2, 0.5]
|
|
},
|
|
{
|
|
// TorusKnotGeometry - twisted tube shape
|
|
geometry: new THREE.TorusKnotGeometry(0.8, 0.3, 100, 16),
|
|
material: new THREE.MeshStandardMaterial({
|
|
color: 0x9575cd,
|
|
wireframe: false,
|
|
metalness: 0.8,
|
|
roughness: 0.2
|
|
}),
|
|
position: [-4, -2, 0],
|
|
rotation: [0, 0, 0],
|
|
rotationSpeed: [0.15, 0.35, 0.25]
|
|
},
|
|
{
|
|
// DodecahedronGeometry - 12-sided polyhedron
|
|
geometry: new THREE.DodecahedronGeometry(1.2, 0),
|
|
material: new THREE.MeshPhongMaterial({
|
|
color: 0x4db6ac,
|
|
shininess: 80,
|
|
flatShading: true,
|
|
wireframe: false
|
|
}),
|
|
position: [0, -2, 0],
|
|
rotation: [0, 0, 0],
|
|
rotationSpeed: [0.25, 0.15, 0.4]
|
|
},
|
|
{
|
|
// TetrahedronGeometry - 4-sided polyhedron
|
|
geometry: new THREE.TetrahedronGeometry(1.3, 1),
|
|
material: new THREE.MeshStandardMaterial({
|
|
color: 0xff8a65,
|
|
metalness: 0.6,
|
|
roughness: 0.3,
|
|
emissive: 0x442200,
|
|
emissiveIntensity: 0.25
|
|
}),
|
|
position: [4, -2, 0],
|
|
rotation: [0, 0, 0],
|
|
rotationSpeed: [0.35, 0.45, 0.2]
|
|
}
|
|
];
|
|
|
|
// Create meshes from configurations
|
|
geometryConfigs.forEach(config => {
|
|
const mesh = new THREE.Mesh(config.geometry, config.material);
|
|
mesh.position.set(...config.position);
|
|
mesh.rotation.set(...config.rotation);
|
|
|
|
// Store rotation speed for animation
|
|
mesh.userData.rotationSpeed = config.rotationSpeed;
|
|
|
|
// Add wireframe overlay for some geometries
|
|
if (config.position[1] === 2) {
|
|
const wireframe = new THREE.WireframeGeometry(config.geometry);
|
|
const line = new THREE.LineSegments(wireframe);
|
|
line.material.color.setHex(0xffffff);
|
|
line.material.opacity = 0.15;
|
|
line.material.transparent = true;
|
|
mesh.add(line);
|
|
}
|
|
|
|
scene.add(mesh);
|
|
geometries.push(mesh);
|
|
});
|
|
|
|
// Add subtle grid for spatial reference
|
|
const gridHelper = new THREE.GridHelper(20, 20, 0x444466, 0x222233);
|
|
gridHelper.position.y = -4;
|
|
scene.add(gridHelper);
|
|
}
|
|
|
|
function onWindowResize() {
|
|
camera.aspect = window.innerWidth / window.innerHeight;
|
|
camera.updateProjectionMatrix();
|
|
renderer.setSize(window.innerWidth, window.innerHeight);
|
|
}
|
|
|
|
function animate() {
|
|
requestAnimationFrame(animate);
|
|
|
|
time += 0.01;
|
|
|
|
// Animate each geometry with its unique rotation speed
|
|
geometries.forEach((mesh, index) => {
|
|
const speeds = mesh.userData.rotationSpeed;
|
|
mesh.rotation.x += speeds[0] * 0.01;
|
|
mesh.rotation.y += speeds[1] * 0.01;
|
|
mesh.rotation.z += speeds[2] * 0.01;
|
|
|
|
// Add subtle floating motion
|
|
mesh.position.y += Math.sin(time * 2 + index) * 0.003;
|
|
});
|
|
|
|
// Update controls
|
|
controls.update();
|
|
|
|
renderer.render(scene, camera);
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|