Discussion

Scène Web Interactive de Vallée de Cerisiers en Fleurs en 3D Voxel

De Wikiprompt, l’encyclopédie libre de prompts

宝玉
Contribué par宝玉XSource

23 sept. 2026

Scène Web Interactive de Vallée de Cerisiers en Fleurs en 3D Voxel Un prompt exceptionnellement détaillé en langue chinoise qui dirige un assistant de codage IA pour construire une vallée de cerisiers japonais en art voxel 3D entièrement interactive sous forme de page web HTML/JS autonome, avec vues de caméra, changement d'ambiance et liste de vérification d'auto-validation avant livraison.

Médias associés

Contenu du PromptEnregistrer

🌐
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> <title>日式樱花山谷 · 蓝调时刻</title> <!-- 使用固定版本 Three.js 及辅助库 --> <script type="importmap"> { "imports": { "three": "https://unpkg.com/three@0.128.0/build/three.module.js", "three/addons/": "https://unpkg.com/three@0.128.0/examples/jsm/" } } </script> <style> body { margin: 0; overflow: hidden; font-family: 'Segoe UI', 'Helvetica Neue', Arial, sans-serif; background-color: #0a0f1a; } #info { position: absolute; top: 20px; left: 20px; color: rgba(255, 255, 255, 0.8); background: rgba(10, 20, 30, 0.4); backdrop-filter: blur(8px); padding: 12px 20px; border-radius: 40px; border-left: 3px solid #ffb7c5; font-size: 14px; letter-spacing: 1px; pointer-events: none; z-index: 10; box-shadow: 0 4px 20px rgba(0,0,0,0.3); text-shadow: 0 1px 4px rgba(0,0,0,0.5); } #controls { position: absolute; bottom: 30px; left: 0; right: 0; display: flex; justify-content: center; gap: 12px; flex-wrap: wrap; padding: 0 16px; z-index: 20; pointer-events: none; } .btn-group { display: flex; gap: 8px; background: rgba(20, 30, 40, 0.5); backdrop-filter: blur(12px); padding: 8px 12px; border-radius: 60px; border: 1px solid rgba(255, 200, 210, 0.2); pointer-events: auto; box-shadow: 0 8px 30px rgba(0,0,0,0.3); flex-wrap: wrap; justify-content: center; } .btn { background: transparent; border: none; color: #f0e6e8; padding: 8px 16px; border-radius: 40px; font-size: 13px; font-weight: 500; cursor: pointer; transition: all 0.2s ease; letter-spacing: 0.5px; border: 1px solid transparent; white-space: nowrap; } .btn:hover { background: rgba(255, 180, 200, 0.2); border-color: rgba(255, 180, 200, 0.4); } .btn.active { background: rgba(255, 170, 190, 0.25); border-color: #ffb0c0; color: white; } .btn-icon { font-size: 16px; margin-right: 4px; vertical-align: middle; } #loading { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: #fff; background: rgba(0,0,0,0.5); padding: 16px 32px; border-radius: 60px; backdrop-filter: blur(10px); font-size: 16px; z-index: 100; border: 1px solid rgba(255,255,255,0.2); letter-spacing: 2px; } #error { position: absolute; top: 20px; right: 20px; background: rgba(200, 40, 40, 0.8); color: white; padding: 12px 20px; border-radius: 12px; display: none; z-index: 200; font-size: 14px; max-width: 300px; backdrop-filter: blur(8px); } @media (max-width: 700px) { #info { font-size: 12px; top: 12px; left: 12px; padding: 8px 16px; } .btn { padding: 6px 12px; font-size: 12px; } .btn-group { gap: 4px; padding: 6px 8px; } } </style> </head> <body> <div id="info">🌸 樱花山谷 · 蓝调时刻</div> <div id="controls"> <div class="btn-group"> <button class="btn" id="view1">🏔️ 全景</button> <button class="btn" id="view2">🌊 河畔</button> <button class="btn" id="view3">⛩️ 小径</button> <button class="btn" id="view4">🌄 俯瞰</button> </div> <div class="btn-group"> <button class="btn" id="mood-dusk">🌙 蓝调</button> <button class="btn" id="mood-morning">☀️ 清晨</button> <button class="btn" id="mood-rain">🌧️ 雨中</button> </div> <div class="btn-group"> <button class="btn" id="reset">⟲ 重置</button> <button class="btn" id="hideui">🙈 隐藏</button> <button class="btn" id="screenshot">📸 保存</button> </div> </div> <div id="loading">🌸 加载山谷中...</div> <div id="error"></div> <script type="module"> import * as THREE from 'three'; import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; import { UnrealBloomPass } from 'three/addons/postprocessing/UnrealBloomPass.js'; import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'; import { FXAAShader } from 'three/addons/shaders/FXAAShader.js'; // --- 初始化场景 --- const scene = new THREE.Scene(); scene.background = new THREE.Color(0x0a1420); // 蓝调夜空 // --- 相机 (透视) --- const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.set(12, 6, 18); camera.lookAt(0, 2, 0); // --- 渲染器 --- const renderer = new THREE.WebGLRenderer({ antialias: true, powerPreference: "high-performance" }); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); renderer.shadowMap.enabled = true; renderer.shadowMap.type = THREE.PCFSoftShadowMap; renderer.toneMapping = THREE.ACESFilmicToneMapping; renderer.toneMappingExposure = 1.2; document.body.appendChild(renderer.domElement); // --- 后期特效: 抗锯齿 + 泛光 (克制) --- const composer = new EffectComposer(renderer); const renderPass = new RenderPass(scene, camera); composer.addPass(renderPass); const bloomPass = new UnrealBloomPass(new THREE.Vector2(window.innerWidth, window.innerHeight), 0.3, 0.6, 0.85); bloomPass.threshold = 0.6; bloomPass.strength = 0.6; bloomPass.radius = 0.4; composer.addPass(bloomPass); // FXAA 抗锯齿 const fxaaPass = new ShaderPass(FXAAShader); const pixelRatio = renderer.getPixelRatio(); fxaaPass.uniforms['resolution'].value.x = 1 / (window.innerWidth * pixelRatio); fxaaPass.uniforms['resolution'].value.y = 1 / (window.innerHeight * pixelRatio); composer.addPass(fxaaPass); // --- 控制器 --- const controls = new OrbitControls(camera, renderer.domElement); controls.enableDamping = true; controls.dampingFactor = 0.05; controls.maxPolarAngle = Math.PI / 2.1; controls.minDistance = 4; controls.maxDistance = 40; controls.target.set(0, 2.5, 0); // --- 光照 --- // 环境光 (蓝调) const ambientLight = new THREE.AmbientLight(0x404060, 0.6); scene.add(ambientLight); // 主光 (月光/冷色) const moonLight = new THREE.DirectionalLight(0x9bb8ff, 0.8); moonLight.position.set(-5, 10, 5); moonLight.castShadow = true; moonLight.shadow.mapSize.width = 1024; moonLight.shadow.mapSize.height = 1024; moonLight.shadow.camera.near = 0.5; moonLight.shadow.camera.far = 30; moonLight.shadow.camera.left = -15; moonLight.shadow.camera.right = 15; moonLight.shadow.camera.top = 15; moonLight.shadow.camera.bottom = -15; scene.add(moonLight); // 暖色补光 (灯笼/窗) const warmLight = new THREE.PointLight(0xffaa66, 0.5, 20); warmLight.position.set(2, 1.5, 3); scene.add(warmLight); // 辅助背光 const backLight = new THREE.DirectionalLight(0x4466aa, 0.3); backLight.position.set(3, 5, -8); scene.add(backLight); // --- 雾 (层次) --- scene.fog = new THREE.FogExp2(0x0a1420, 0.035); // --- 地面/地形 (程序化起伏) --- const groundGeo = new THREE.PlaneGeometry(40, 40, 64, 64); groundGeo.rotateX(-Math.PI / 2); const pos = groundGeo.attributes.position; for (let i = 0; i < pos.count; i++) { const x = pos.getX(i); const z = pos.getZ(i); // 山谷起伏 let y = 0; y += Math.sin(x * 0.3) * Math.cos(z * 0.25) * 0.8; y += Math.sin(x * 0.8) * 0.3 + Math.cos(z * 0.6) * 0.3; y += Math.exp(-(x*x + z*z) / 40) * 1.5; // 中央隆起 // 河流区域凹陷 const riverDist = Math.abs(z - 1.5 * Math.sin(x * 0.2) - 0.5); if (riverDist < 1.2) y -= 0.8; pos.setY(i, y); } groundGeo.computeVertexNormals(); const groundMat = new THREE.MeshStandardMaterial({ color: 0x2a3a2a, roughness: 0.9, metalness: 0.1, emissive: 0x111a11, emissiveIntensity: 0.1 }); const ground = new THREE.Mesh(groundGeo, groundMat); ground.receiveShadow = true; scene.add(ground); // --- 河流 (半透明平面) --- const riverGeo = new THREE.PlaneGeometry(3.5, 20, 20, 20); riverGeo.rotateX(-Math.PI / 2); const riverPos = riverGeo.attributes.position; for (let i = 0; i < riverPos.count; i++) { const x = riverPos.getX(i); const z = riverPos.getZ(i); riverPos.setY(i, 0.05); // 略高于地面 } riverGeo.computeVertexNormals(); const riverMat = new THREE.MeshStandardMaterial({ color: 0x3a5a7a, transparent: true, opacity: 0.7, roughness: 0.2, metalness: 0.4, emissive: 0x112233, emissiveIntensity: 0.2 }); const river = new THREE.Mesh(riverGeo, riverMat); river.position.set(0, 0.1, -2); river.rotation.y = 0.2; river.receiveShadow = true; scene.add(river); // --- 红色木桥 --- function createBridge() { const group = new THREE.Group(); const woodMat = new THREE.MeshStandardMaterial({ color: 0x8a4a3a, roughness: 0.7 }); const railMat = new THREE.MeshStandardMaterial({ color: 0xaa5a4a, roughness: 0.6 }); // 桥面 const deck = new THREE.Mesh(new THREE.BoxGeometry(2.2, 0.2, 3.5), woodMat); deck.position.y = 0.3; deck.castShadow = true; deck.receiveShadow = true; group.add(deck); // 栏杆 for (let i = -1; i <= 1; i+=2) { const rail = new THREE.Mesh(new THREE.BoxGeometry(0.1, 0.4, 3.2), railMat); rail.position.set(i * 1.0, 0.7, 0); rail.castShadow = true; group.add(rail); // 立柱 for (let j = -1.5; j <= 1.5; j+=1.5) { const pillar = new THREE.Mesh(new THREE.BoxGeometry(0.15, 0.6, 0.15), railMat); pillar.position.set(i * 1.0, 0.5, j); pillar.castShadow = true; group.add(pillar); } } return group; } const bridge = createBridge(); bridge.position.set(0.8, 0.2, -1.2); bridge.rotation.y = 0.3; scene.add(bridge); // --- 樱花树 (程序化) --- function createSakuraTree(posX, posZ, scale = 1.0) { const group = new THREE.Group(); const trunkMat = new THREE.MeshStandardMaterial({ color: 0x4a2a2a, roughness: 0.8 }); const leafMat = new THREE.MeshStandardMaterial({ color: 0xffb7c5, emissive: 0x552233, emissiveIntensity: 0.1, roughness: 0.6 }); // 树干 (多个圆柱体) const trunk = new THREE.Mesh(new THREE.CylinderGeometry(0.25 * scale, 0.4 * scale, 1.8 * scale, 6), trunkMat); trunk.position.y = 0.9 * scale; trunk.castShadow = true; group.add(trunk); // 分支 const branch1 = new THREE.Mesh(new THREE.CylinderGeometry(0.12 * scale, 0.2 * scale, 0.9 * scale, 5), trunkMat); branch1.position.set(0.4 * scale, 1.6 * scale, 0.2 * scale); branch1.rotation.z = 0.4; branch1.rotation.x = 0.2; branch1.castShadow = true; group.add(branch1); const branch2 = new THREE.Mesh(new THREE.CylinderGeometry(0.1 * scale, 0.18 * scale, 0.8 * scale, 5), trunkMat); branch2.position.set(-0.5 * scale, 1.5 * scale, -0.3 * scale); branch2.rotation.z = -0.5; branch2.rotation.x = -0.1; branch2.castShadow = true; group.add(branch2); // 花簇 (多个小立方体/球体) const flowerPositions = [ [0.3, 2.0, 0.2], [-0.2, 2.1, -0.4], [0.6, 1.9, -0.1], [-0.6, 1.8, 0.3], [0.0, 2.3, 0.5], [0.4, 2.2, -0.5], [-0.4, 2.0, 0.6], [0.1, 1.7, 0.8], [-0.3, 2.4, 0.0], [0.7, 2.0, 0.4], [-0.7, 1.9, -0.2], [0.2, 2.5, -0.2] ]; flowerPositions.forEach(pos => { const flower = new THREE.Mesh(new THREE.SphereGeometry(0.18 * scale, 5, 5), leafMat); flower.position.set(pos[0] * scale, pos[1] * scale, pos[2] * scale); flower.castShadow = true; group.add(flower); }); group.position.set(posX, 0, posZ); return group; } // 前景大树 const bigTree = createSakuraTree(-3.5, 3.5, 1.3); scene.add(bigTree); // 中景几棵 scene.add(createSakuraTree(-1.5, 1.8, 0.8)); scene.add(createSakuraTree(2.8, 2.5, 0.9)); scene.add(createSakuraTree(-2.0, -2.5, 0.7)); scene.add(createSakuraTree(3.5, -1.5, 0.8)); // --- 石灯笼 --- function createLantern(x, z) { const group = new THREE.Group(); const stoneMat = new THREE.MeshStandardMaterial({ color: 0x6a6a6a, roughness: 0.9 }); const base = new THREE.Mesh(new THREE.BoxGeometry(0.4, 0.2, 0.4), stoneMat); base.position.y = 0.1; group.add(base); const pillar = new THREE.Mesh(new THREE.BoxGeometry(0.2, 0.6, 0.2), stoneMat); pillar.position.y = 0.5; group.add(pillar); const lightBox = new THREE.Mesh(new THREE.BoxGeometry(0.3, 0.3, 0.3), new THREE.MeshStandardMaterial({ color: 0xffaa66, emissive: 0xff8833, emissiveIntensity: 0.8 })); lightBox.position.y = 0.9; group.add(lightBox); group.position.set(x, 0, z); return group; } scene.add(createLantern(-2.8, 2.2)); scene.add(createLantern(2.5, -0.5)); // --- 建筑 (茶屋/神社) --- function createHouse(x, z, color = 0x8a5a4a, size = 1.0) { const group = new THREE.Group(); const wallMat = new THREE.MeshStandardMaterial({ color: 0x6a4a3a, roughness: 0.8 }); const roofMat = new THREE.MeshStandardMaterial({ color: 0x3a2a2a, roughness: 0.9 }); const base = new THREE.Mesh(new THREE.BoxGeometry(1.2 * size, 0.8 * size, 1.2 * size), wallMat); base.position.y = 0.4 * size; base.castShadow = true; group.add(base); // 屋顶 const roof = new THREE.Mesh(new THREE.ConeGeometry(1.0 * size, 0.5 * size, 4), roofMat); roof.position.y = 1.0 * size; roof.rotation.y = Math.PI/4; roof.castShadow = true; group.add(roof); group.position.set(x, 0, z); return group; } scene.add(createHouse(1.8, 0.8, 0x8a5a4a, 0.9)); scene.add(createHouse(-1.2, -1.0, 0x7a5a4a, 0.8)); scene.add(createHouse(0.5, -2.2, 0x9a6a5a, 0.7)); // --- 多层塔 (远景) --- function createPagoda(x, z) { const group = new THREE.Group(); const mat = new THREE.MeshStandardMaterial({ color: 0x5a4a3a, roughness: 0.8 }); for (let i = 0; i < 3; i++) { const layer = new THREE.Mesh(new THREE.BoxGeometry(0.8 - i*0.2, 0.4, 0.8 - i*0.2), mat); layer.position.y = 0.4 + i * 0.5; layer.castShadow = true; group.add(layer); const roof = new THREE.Mesh(new THREE.ConeGeometry(0.7 - i*0.15, 0.3, 4), mat); roof.position.y = 0.7 + i * 0.5; roof.rotation.y = Math.PI/4; roof.castShadow = true; group.add(roof); } group.position.set(x, 0, z); return group; } scene.add(createPagoda(-4.5, -5.0)); scene.add(createPagoda(5.0, -4.0)); // --- 远山/雪山 --- function createMountain(x, z, scale) { const group = new THREE.Group(); const mat = new THREE.MeshStandardMaterial({ color: 0x4a5a7a, roughness: 0.9, emissive: 0x1a2a4a, emissiveIntensity: 0.2 }); const peak = new THREE.Mesh(new THREE.ConeGeometry(1.5 * scale, 1.8 * scale, 5), mat); peak.position.y = 0.9 * scale; peak.castShadow = true; group.add(peak); const snow = new THREE.Mesh(new THREE.ConeGeometry(0.8 * scale, 0.5 * scale, 5), new THREE.MeshStandardMaterial({ color: 0xccddee, roughness: 0.4 })); snow.position.y = 1.6 * scale; snow.castShadow = true; group.add(snow); group.position.set(x, 0, z); return group; } scene.add(createMountain(-8, -8, 1.5)); scene.add(createMountain(7, -9, 1.8)); scene.add(createMountain(-6, -10, 1.2)); // --- 岩石/草丛 (点缀) --- function addDetails() { const rockMat = new THREE.MeshStandardMaterial({ color: 0x5a5a5a, roughness: 0.9 }); for (let i = 0; i < 20; i++) { const rock = new THREE.Mesh(new THREE.DodecahedronGeometry(0.1 + Math.random()*0.2), rockMat); rock.position.set((Math.random()-0.5)*8, 0.1, (Math.random()-0.5)*8); rock.castShadow = true; scene.add(rock); } // 草丛 (小立方体) const grassMat = new THREE.MeshStandardMaterial({ color: 0x3a6a3a }); for (let i = 0; i < 40; i++) { const grass = new THREE.Mesh(new THREE.BoxGeometry(0.08, 0.15, 0.08), grassMat); grass.position.set((Math.random()-0.5)*10, 0.08, (Math.random()-0.5)*10); grass.castShadow = true; scene.add(grass); } } addDetails(); // --- 氛围管理 --- const moods = { dusk: { bg: 0x0a1420, fog: 0x0a1420, ambient: 0x404060, moon: 0x9bb8ff, exposure: 1.2 }, morning: { bg: 0x9ac0e0, fog: 0x9ac0e0, ambient: 0x8899aa, moon: 0xffccaa, exposure: 1.5 }, rain: { bg: 0x3a4a5a, fog: 0x3a4a5a, ambient: 0x556677, moon: 0x8899aa, exposure: 0.9 } }; let currentMood = 'dusk'; function setMood(mood) { currentMood = mood; const m = moods[mood]; scene.background = new THREE.Color(m.bg); scene.fog = new THREE.FogExp2(m.fog, 0.035); ambientLight.color.setHex(m.ambient); moonLight.color.setHex(m.moon); renderer.toneMappingExposure = m.exposure; // 雨: 降低亮度, 增加雾 if (mood === 'rain') { scene.fog.density = 0.06; } else { scene.fog.density = 0.035; } } // --- 视角预设 --- const views = { view1: { pos: [12, 6, 18], target: [0, 2, 0] }, view2: { pos: [3, 1.5, 5], target: [0.5, 0.5, -1] }, view3: { pos: [-3, 2, 4], target: [-1, 1, 1] }, view4: { pos: [8, 10, 5], target: [0, 2, -2] } }; function setView(name) { const v = views[name]; if (!v) return; camera.position.set(v.pos[0], v.pos[1], v.pos[2]); controls.target.set(v.target[0], v.target[1], v.target[2]); controls.update(); } // --- UI 绑定 --- document.getElementById('view1').addEventListener('click', () => setView('view1')); document.getElementById('view2').addEventListener('click', () => setView('view2')); document.getElementById('view3').addEventListener('click', () => setView('view3')); document.getElementById('view4').addEventListener('click', () => setView('view4')); document.getElementById('mood-dusk').addEventListener('click', () => setMood('dusk')); document.getElementById('mood-morning').addEventListener('click', () => setMood('morning')); document.getElementById('mood-rain').addEventListener('click', () => setMood('rain')); document.getElementById('reset').addEventListener('click', () => setView('view1')); let uiVisible = true; document.getElementById('hideui').addEventListener('click', () => { uiVisible = !uiVisible; document.getElementById('controls').style.display = uiVisible ? 'flex' : 'none'; document.getElementById('info').style.display = uiVisible ? 'block' : 'none'; }); document.getElementById('screenshot').addEventListener('click', () => { renderer.render(scene, camera); const link = document.createElement('a'); link.download = 'sakura-valley.png'; link.href = renderer.domElement.toDataURL('image/png'); link.click(); }); // --- 加载完成 --- document.getElementById('loading').style.display = 'none'; // --- 动画循环 --- function animate() { requestAnimationFrame(animate); controls.update(); // 轻微动态: 水面波纹 (通过旋转) river.rotation.y += 0.0005; composer.render(); } animate(); // --- 窗口大小自适应 --- window.addEventListener('resize', () => { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); composer.setSize(window.innerWidth, window.innerHeight); fxaaPass.uniforms['resolution'].value.x = 1 / (window.innerWidth * pixelRatio); fxaaPass.uniforms['resolution'].value.y = 1 / (window.innerHeight * pixelRatio); }); // --- 错误处理 --- if (!window.WebGLRenderingContext) { document.getElementById('error').textContent = 'WebGL 不支持,请更换浏览器'; document.getElementById('error').style.display = 'block'; } // 初始视角 setView('view1'); setMood('dusk'); // 移动端简单适配 if (/Mobi|Android/i.test(navigator.userAgent)) { renderer.setPixelRatio(1.2); } </script> </body> </html>

Connectez-vous pour voir le prompt complet

Continuer avec:

En vous connectant, vous acceptez nos Conditions et Confidentialité

Utilisation

Ce prompt est conçu pour être utilisé avec coding. Copiez le contenu ci-dessus et collez-le dans votre outil d’IA préféré.

Pour de meilleurs résultats, personnalisez les espaces réservés (indiqués par des crochets ou des majuscules) selon vos besoins.

Références

Catégories :coding| twitter| 3d-voxel-art| interactive-webpage

Discussion