स्व-निहित Three.js वोक्सेल पर्वत घाटी विश्व निर्माता
Wikiprompt से, मुफ्त प्रॉम्प्ट विश्वकोश
स्व-निहित Three.js वोक्सेल पर्वत घाटी विश्व निर्माता Three.js में प्रक्रियात्मक रूप से निर्मित, एनिमेटेड वोक्सेल पर्वत-घाटी दुनिया उत्पन्न करने के लिए एक विस्तृत एकल-फ़ाइल प्रॉम्प्ट, जिसमें भटकते ग्रामीण, दिन/रात चक्र, और एक कस्टम ऑर्बिट कैमरा शामिल है।
प्रॉम्प्ट सामग्रीसहेजें
🌐
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Voxel Valley · day/night</title>
<style>
body { margin: 0; overflow: hidden; font-family: 'Segoe UI', system-ui, sans-serif; }
#info {
position: absolute;
bottom: 20px;
left: 20px;
background: rgba(10, 20, 30, 0.6);
color: #e0f0ff;
padding: 8px 16px;
border-radius: 40px;
backdrop-filter: blur(6px);
font-size: 14px;
letter-spacing: 0.5px;
border: 1px solid rgba(255,255,255,0.2);
pointer-events: none;
z-index: 10;
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
}
#info i {
font-style: normal;
display: inline-block;
margin: 0 4px;
}
.hint-icon {
opacity: 0.8;
}
</style>
</head>
<body>
<div id="info">
<span class="hint-icon">🖱️</span> Drag to rotate · <span class="hint-icon">⚲</span> Scroll to zoom
</div>
<!-- Three.js from CDN (no external assets) -->
<script type="importmap">
{
"imports": {
"three": "https://unpkg.com/three@0.128.0/build/three.module.js"
}
}
</script>
<script type="module">
import * as THREE from 'three';
// --- setup scene, camera, renderer ---
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x87CEEB); // will change with day/night
const camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(25, 18, 35);
camera.lookAt(0, 4, 0);
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
document.body.appendChild(renderer.domElement);
// --- lights ---
const sunLight = new THREE.DirectionalLight(0xfff5e6, 1.2);
sunLight.position.set(30, 40, 20);
sunLight.castShadow = true;
sunLight.shadow.mapSize.width = 1024;
sunLight.shadow.mapSize.height = 1024;
scene.add(sunLight);
const ambientLight = new THREE.AmbientLight(0x404060);
scene.add(ambientLight);
// additional fill light
const fillLight = new THREE.DirectionalLight(0xccddff, 0.4);
fillLight.position.set(-20, 10, -20);
scene.add(fillLight);
// stars container (will be populated)
const stars = new THREE.Group();
scene.add(stars);
// --- procedural voxel world ---
// ground base: 40x40 area, heightmap simple
const groundSize = 40;
const groundMat = new THREE.MeshStandardMaterial({ color: 0x5a8f4c, roughness: 0.9 });
const stoneMat = new THREE.MeshStandardMaterial({ color: 0x7a7a7a, roughness: 0.8 });
const snowMat = new THREE.MeshStandardMaterial({ color: 0xf0f8ff, roughness: 0.6 });
const waterMat = new THREE.MeshStandardMaterial({ color: 0x3a6ea5, roughness: 0.2, metalness: 0.1 });
const woodMat = new THREE.MeshStandardMaterial({ color: 0x8b5a2b });
const leafMat = new THREE.MeshStandardMaterial({ color: 0x2d6a4f });
const windowMat = new THREE.MeshStandardMaterial({ color: 0xffdd77, emissive: 0xffaa33, emissiveIntensity: 0.8 });
// simple height function: mountains at edges, valley center
function getHeight(x, z) {
// distance from center
const dx = x - 0;
const dz = z - 0;
const dist = Math.sqrt(dx*dx + dz*dz);
// mountain ring
const h = 6 * Math.exp(-dist / 12) + 2 * Math.sin(x * 0.5) * Math.cos(z * 0.5);
// valley floor
const valley = -2 * Math.exp(-dist / 20);
return h + valley + 2.5;
}
// generate voxel cubes (1x1x1) for terrain
const voxelGroup = new THREE.Group();
const cubeGeo = new THREE.BoxGeometry(1, 1, 1);
// water level
const waterLevel = 2.0;
for (let x = -20; x < 20; x++) {
for (let z = -20; z < 20; z++) {
const h = getHeight(x, z);
const hInt = Math.floor(h);
// place cubes from y=0 up to hInt
for (let y = 0; y <= hInt; y++) {
let mat;
if (y < hInt - 2) mat = stoneMat;
else if (y < hInt) mat = groundMat;
else mat = snowMat; // top layer snow if high enough
// but if low valley, use grass
if (hInt < 3) mat = groundMat;
if (hInt > 6) mat = snowMat;
// water layer
if (y <= waterLevel && hInt <= waterLevel) {
mat = waterMat;
}
const cube = new THREE.Mesh(cubeGeo, mat);
cube.position.set(x, y + 0.5, z);
cube.castShadow = true;
cube.receiveShadow = true;
voxelGroup.add(cube);
}
// water surface if terrain below water level
if (hInt < waterLevel) {
for (let y = hInt+1; y <= waterLevel; y++) {
const cube = new THREE.Mesh(cubeGeo, waterMat);
cube.position.set(x, y + 0.5, z);
cube.castShadow = false;
cube.receiveShadow = true;
voxelGroup.add(cube);
}
}
}
}
scene.add(voxelGroup);
// --- trees (simple voxel pines) ---
function addTree(x, z) {
const trunkH = 2;
const trunkMat = new THREE.MeshStandardMaterial({ color: 0x6b4e3a });
const leafMat = new THREE.MeshStandardMaterial({ color: 0x2e6b34 });
for (let y = 1; y <= trunkH; y++) {
const cube = new THREE.Mesh(cubeGeo, trunkMat);
cube.position.set(x, y + 0.5, z);
cube.castShadow = true;
scene.add(cube);
}
// leaves layers
for (let ly = trunkH+1; ly <= trunkH+3; ly++) {
const offset = (ly === trunkH+1) ? 1 : 0;
for (let dx = -1; dx <= 1; dx++) {
for (let dz = -1; dz <= 1; dz++) {
if (Math.abs(dx) === 1 && Math.abs(dz) === 1) continue; // corners
const cube = new THREE.Mesh(cubeGeo, leafMat);
cube.position.set(x + dx, ly + 0.5, z + dz);
cube.castShadow = true;
scene.add(cube);
}
}
}
// top
const top = new THREE.Mesh(cubeGeo, leafMat);
top.position.set(x, trunkH+4 + 0.5, z);
scene.add(top);
}
// place trees around valley
const treePositions = [
[-6, -4], [5, -7], [8, 3], [-9, 6], [12, -2], [-12, -8], [3, 10], [-4, 12]
];
treePositions.forEach(([x, z]) => addTree(x, z));
// --- village houses (blocky) ---
function addHouse(cx, cz) {
const houseGroup = new THREE.Group();
const baseMat = new THREE.MeshStandardMaterial({ color: 0xd2b48c });
const roofMat = new THREE.MeshStandardMaterial({ color: 0x8b3a3a });
// base
for (let dx = -1; dx <= 1; dx++) {
for (let dz = -1; dz <= 1; dz++) {
const cube = new THREE.Mesh(cubeGeo, baseMat);
cube.position.set(cx + dx, 1.5, cz + dz);
cube.castShadow = true;
scene.add(cube);
}
}
// roof (pyramid-ish)
for (let y = 2; y <= 3; y++) {
const range = (y === 2) ? 1 : 0;
for (let dx = -range; dx <= range; dx++) {
for (let dz = -range; dz <= range; dz++) {
if (Math.abs(dx) === range && Math.abs(dz) === range) continue;
const cube = new THREE.Mesh(cubeGeo, roofMat);
cube.position.set(cx + dx, y + 0.5, cz + dz);
cube.castShadow = true;
scene.add(cube);
}
}
}
// windows (glowing)
const windowPos = [
[cx, 1.5, cz-1], [cx, 1.5, cz+1], [cx-1, 1.5, cz], [cx+1, 1.5, cz]
];
windowPos.forEach(([wx, wy, wz]) => {
const win = new THREE.Mesh(new THREE.BoxGeometry(0.4, 0.4, 0.1), windowMat);
win.position.set(wx, wy, wz);
scene.add(win);
});
}
// village cluster
const villageSpots = [[-3, -2], [0, -3], [3, -2], [-2, 1], [2, 1], [-5, 2], [5, 2]];
villageSpots.forEach(([x, z]) => addHouse(x, z));
// --- clouds (blocky) ---
function addCloud(x, y, z) {
const cloudMat = new THREE.MeshStandardMaterial({ color: 0xffffff, transparent: true, opacity: 0.85 });
for (let dx = -1; dx <= 1; dx++) {
for (let dz = -1; dz <= 1; dz++) {
if (Math.random() > 0.7) continue;
const cube = new THREE.Mesh(cubeGeo, cloudMat);
cube.position.set(x + dx * 1.2, y + Math.random()*0.3, z + dz * 1.2);
cube.castShadow = false;
scene.add(cube);
}
}
}
addCloud(5, 12, -5);
addCloud(-8, 13, 6);
addCloud(10, 14, 8);
addCloud(-5, 12, -10);
// --- villagers & animals (simple wandering cubes) ---
const characters = [];
const charColors = [0xe0ac69, 0xc68642, 0x8b5a2b, 0x6b8e23, 0xcd853f, 0xbc8f8f, 0xd2b48c, 0xdeb887];
function createCharacter(x, z) {
const group = new THREE.Group();
const bodyMat = new THREE.MeshStandardMaterial({ color: charColors[Math.floor(Math.random() * charColors.length)] });
const headMat = new THREE.MeshStandardMaterial({ color: 0xffddbb });
// body
const body = new THREE.Mesh(cubeGeo, bodyMat);
body.scale.set(0.8, 1.0, 0.8);
body.position.y = 1.0;
group.add(body);
// head
const head = new THREE.Mesh(cubeGeo, headMat);
head.scale.set(0.6, 0.6, 0.6);
head.position.y = 1.8;
group.add(head);
group.position.set(x, 0.5, z);
scene.add(group);
characters.push({
group,
target: new THREE.Vector3(x, 0.5, z),
speed: 0.02 + Math.random() * 0.03,
pause: 0,
waddlePhase: Math.random() * Math.PI * 2
});
}
// spawn characters near village
const spawnPoints = [[-2, -1], [1, -2], [4, 0], [-4, 0], [0, 2], [3, 3], [-3, 3], [6, -1]];
spawnPoints.forEach(([x, z]) => createCharacter(x, z));
// --- stars (simple points) ---
const starsGeo = new THREE.BufferGeometry();
const starsCount = 400;
const starsPos = new Float32Array(starsCount * 3);
for (let i = 0; i < starsCount; i++) {
starsPos[i*3] = (Math.random() - 0.5) * 200;
starsPos[i*3+1] = 30 + Math.random() * 40;
starsPos[i*3+2] = (Math.random() - 0.5) * 200;
}
starsGeo.setAttribute('position', new THREE.BufferAttribute(starsPos, 3));
const starsMat = new THREE.PointsMaterial({ color: 0xffffff, size: 0.3, transparent: true });
const starsPoints = new THREE.Points(starsGeo, starsMat);
stars.add(starsPoints);
// --- day/night cycle variables ---
let timeOfDay = 0.2; // start morning
const daySpeed = 0.005; // 60 sec full cycle ~ 2*PI
// --- camera orbit (custom) ---
let cameraAngle = 0.5;
let cameraRadius = 35;
let cameraHeight = 14;
let isDragging = false;
let previousMouse = { x: 0, y: 0 };
renderer.domElement.addEventListener('mousedown', (e) => {
isDragging = true;
previousMouse = { x: e.clientX, y: e.clientY };
});
window.addEventListener('mouseup', () => isDragging = false);
window.addEventListener('mousemove', (e) => {
if (!isDragging) return;
const dx = e.clientX - previousMouse.x;
const dy = e.clientY - previousMouse.y;
cameraAngle -= dx * 0.005;
cameraHeight = Math.min(30, Math.max(6, cameraHeight + dy * 0.05));
previousMouse = { x: e.clientX, y: e.clientY };
});
renderer.domElement.addEventListener('wheel', (e) => {
cameraRadius = Math.min(60, Math.max(15, cameraRadius + e.deltaY * 0.05));
});
// --- animation loop ---
function animate() {
requestAnimationFrame(animate);
// day/night update
timeOfDay += daySpeed;
if (timeOfDay > 1) timeOfDay -= 1;
// sun position
const sunAngle = timeOfDay * Math.PI * 2;
const sunX = Math.cos(sunAngle) * 40;
const sunY = Math.sin(sunAngle) * 30 + 5;
sunLight.position.set(sunX, sunY, 15);
sunLight.intensity = Math.max(0.2, Math.sin(sunAngle) * 1.2);
// sky color
const skyColor = new THREE.Color();
if (timeOfDay < 0.25) skyColor.setHSL(0.6, 0.7, 0.6); // morning
else if (timeOfDay < 0.5) skyColor.setHSL(0.1, 0.8, 0.6); // noon
else if (timeOfDay < 0.75) skyColor.setHSL(0.08, 0.9, 0.5); // sunset
else skyColor.setHSL(0.65, 0.6, 0.2); // night
scene.background = skyColor;
// stars visibility
stars.visible = (timeOfDay > 0.7 || timeOfDay < 0.15);
// window glow intensity
windowMat.emissiveIntensity = (timeOfDay > 0.6 || timeOfDay < 0.2) ? 1.5 : 0.3;
// auto-rotate camera if not dragging
if (!isDragging) {
cameraAngle += 0.002;
}
// camera position
const camX = Math.sin(cameraAngle) * cameraRadius;
const camZ = Math.cos(cameraAngle) * cameraRadius;
camera.position.set(camX, cameraHeight, camZ);
camera.lookAt(0, 4, 0);
// characters wandering
characters.forEach(ch => {
if (ch.pause > 0) {
ch.pause -= 0.02;
// waddle
ch.group.rotation.y = Math.sin(ch.waddlePhase + performance.now() * 0.01) * 0.2;
return;
}
// move towards target
const pos = ch.group.position;
const dx = ch.target.x - pos.x;
const dz = ch.target.z - pos.z;
const dist = Math.sqrt(dx*dx + dz*dz);
if (dist < 0.3) {
// pick new target within valley, not water
let newX, newZ;
do {
newX = pos.x + (Math.random() - 0.5) * 8;
newZ = pos.z + (Math.random() - 0.5) * 8;
} while (Math.abs(newX) > 15 || Math.abs(newZ) > 15 || getHeight(newX, newZ) < 2.5);
ch.target.set(newX, 0.5, newZ);
ch.pause = 0.5 + Math.random() * 1.5;
} else {
// move
const step = ch.speed;
pos.x += (dx / dist) * step;
pos.z += (dz / dist) * step;
// keep on terrain
const h = getHeight(pos.x, pos.z);
if (h < 2.2) {
// avoid water
pos.x = ch.target.x;
pos.z = ch.target.z;
}
// waddle
ch.group.rotation.y = Math.sin(ch.waddlePhase + performance.now() * 0.02) * 0.3;
}
});
renderer.render(scene, camera);
}
animate();
// resize handler
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
// initial camera angle
cameraAngle = 0.8;
cameraHeight = 16;
cameraRadius = 38;
</script>
</body>
</html>
पूरा प्रॉम्प्ट देखने के लिए साइन इन करें
Continue with:
By logging in, you agree to our Terms of Use and Privacy Policy
उपयोग
यह प्रॉम्प्ट coding के साथ उपयोग के लिए डिज़ाइन किया गया है। ऊपर प्रॉम्प्ट सामग्री कॉपी करें और अपने पसंदीदा AI टूल में पेस्ट करें।
सर्वोत्तम परिणामों के लिए, आप अपनी विशिष्ट आवश्यकताओं के अनुसार प्लेसहोल्डर (वर्ग कोष्ठक या बड़े अक्षरों में दर्शाए गए) को अनुकूलित कर सकते हैं।
चर्चा
0 टिप्पणियाँ