drqxab / index.html
openfree's picture
Upload index.html with huggingface_hub
d069959 verified
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Procedural Terrain</title>
<style>
body { margin: 0; overflow: hidden; }
#controls {
position: fixed;
top: 20px;
left: 20px;
background: rgba(0,0,0,0.7);
padding: 20px;
border-radius: 10px;
color: white;
font-family: Arial, sans-serif;
}
.control-group {
margin: 10px 0;
}
label {
display: inline-block;
width: 120px;
}
input[type="range"] {
width: 200px;
}
</style>
</head>
<body>
<div id="controls">
<div class="control-group">
<label>Height Scale:</label>
<input type="range" id="heightScale" min="0" max="100" value="20">
</div>
<div class="control-group">
<label>Water Level:</label>
<input type="range" id="waterLevel" min="0" max="50" value="10">
</div>
<div class="control-group">
<label>Roughness:</label>
<input type="range" id="roughness" min="0" max="10" value="3" step="0.1">
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script>
let scene, camera, renderer, terrain, water;
const size = 128;
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// Add lighting
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
directionalLight.position.set(1, 1, 1);
scene.add(directionalLight);
camera.position.set(50, 50, 50);
camera.lookAt(0, 0, 0);
createTerrain();
createWater();
animate();
}
function createTerrain() {
const geometry = new THREE.PlaneGeometry(100, 100, size, size);
const material = new THREE.MeshPhongMaterial({
color: 0x808080,
wireframe: false,
flatShading: true
});
terrain = new THREE.Mesh(geometry, material);
terrain.rotation.x = -Math.PI / 2;
scene.add(terrain);
updateTerrain();
}
function createWater() {
const geometry = new THREE.PlaneGeometry(100, 100);
const material = new THREE.MeshPhongMaterial({
color: 0x0077ff,
transparent: true,
opacity: 0.6
});
water = new THREE.Mesh(geometry, material);
water.rotation.x = -Math.PI / 2;
scene.add(water);
}
function updateTerrain() {
const heightScale = document.getElementById('heightScale').value;
const roughness = document.getElementById('roughness').value;
const vertices = terrain.geometry.attributes.position.array;
for(let i = 0; i < vertices.length; i += 3) {
const x = i / 3 % (size + 1);
const y = Math.floor(i / 3 / (size + 1));
vertices[i + 2] = generateHeight(x, y) * heightScale / 20;
}
terrain.geometry.attributes.position.needsUpdate = true;
terrain.geometry.computeVertexNormals();
}
function generateHeight(x, y) {
const roughness = document.getElementById('roughness').value;
return (Math.sin(x/10 * roughness) + Math.sin(y/10 * roughness)) / 2;
}
function updateWater() {
const waterLevel = document.getElementById('waterLevel').value;
water.position.y = waterLevel / 5;
}
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
updateWater();
}
// Event Listeners
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
document.getElementById('heightScale').addEventListener('input', updateTerrain);
document.getElementById('roughness').addEventListener('input', updateTerrain);
init();
</script>
</body>
</html>