three实现三维下雨天便利店场景代码

代码语言:html

所属分类:其他

代码由qwen-4 ai生成,可能有错误,仅供参考:点击查看提示词

代码描述:three实现三维下雨天便利店场景代码

代码标签: three 三维 下雨 天 便利店 场景 代码

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>雨夜便利店 · 街角ジオラマ</title>
<style>
  html,body{margin:0;padding:0;height:100%;overflow:hidden;
    background:radial-gradient(120% 90% at 30% 18%, #2c2650 0%, #171430 48%, #0b0a1a 100%);}
  canvas{display:block;opacity:0;transition:opacity 1.6s ease;cursor:grab;}
  canvas:active{cursor:grabbing;}
  #vig{position:fixed;inset:0;pointer-events:none;
    background:radial-gradient(ellipse at 50% 42%, transparent 50%, rgba(6,5,18,.45) 100%);}
  #fb{position:fixed;inset:0;display:none;place-items:center;color:#8f8ab8;
    font:14px/1.8 "Hiragino Sans","Noto Sans JP",sans-serif;letter-spacing:.2em;text-align:center;}
</style>
</head>
<body>
<div id="vig"></div>
<div id="fb">この端末では WebGL を利用できません<br>请使用支持 WebGL 的浏览器查看</div>

<script type="importmap">
{ "imports": {
  "three": "https://cdn.jsdelivr.net/npm/three@0.160.0/build/three.module.js",
  "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/"
} }
</script>

<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 { OutputPass } from 'three/addons/postprocessing/OutputPass.js';

try { main(); } catch(e){ console.error(e); document.getElementById('fb').style.display='grid'; }

function main(){
/* ================= 基础:渲染器 / 相机 / 灯光 ================= */
const TAU = Math.PI*2, rand=(a,b)=>a+Math.random()*(b-a);
const reduced = matchMedia('(prefers-reduced-motion: reduce)').matches;

const renderer = new THREE.WebGLRenderer({antialias:true, powerPreference:'high-performance'});
renderer.setPixelRatio(Math.min(devicePixelRatio||1, 2));
renderer.setSize(innerWidth, innerHeight);
renderer.outputColorSpace = THREE.SRGBColorSpace;
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 1.12;
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.shadowMap.autoUpdate = false;           // 静态场景:阴影只烘焙一次
document.body.appendChild(renderer.domElement);
renderer.domElement.addEventListener('contextmenu', e=>e.preventDefault());

const scene = new THREE.Scene();
scene.background = new THREE.Color(0x0d0b1e);
scene.fog = new THREE.FogExp2(0x0e0c20, 0.013);

const camera = new THREE.PerspectiveCamera(38, innerWidth/innerHeight, 0.1, 150);
const HOME_POS = new THREE.Vector3(11.6, 8.4, 12.6);
const HOME_TGT = new THREE.Vector3(-0.2, 1.05, -0.3);

const controls = new OrbitControls(camera, renderer.domElement);
controls.target.copy(HOME_TGT);
controls.enableDamping = true; controls.dampingFactor = 0.06;
controls.enablePan = false;
controls.rotateSpeed = 0.55; controls.zoomSpeed = 0.8;
controls.minDistance = 6.5; controls.maxDistance = 30;
controls.minPolarAngle = 0.12; controls.maxPolarAngle = 1.42;
controls.autoRotate = false; controls.autoRotateSpeed = 0.55;
controls.enabled = false;

/* 灯光:冷月主光 + 品红轮廓光 + 暖色点光 */
scene.add(new THREE.HemisphereLight(0x8a93c8, 0x241d3e, 0.85));
const moon = new THREE.DirectionalLight(0x9fb4ff, 1.15);
moon.position.set(-11, 16, 9); moon.castShadow = true;
moon.shadow.mapSize.set(2048, 2048);
Object.assign(moon.shadow.camera, {left:-12, right:12, top:12, bottom:-12, near:2, far:45});
moon.shadow.bias = -0.0004; moon.shadow.normalBias = 0.03;
scene.add(moon);
const rim = new THREE.DirectionalLight(0xc06ad8, 0.7); rim.position.set(9, 6, -11); scene.add(rim);

function point(x,y,z,c,i,d){ const l=new THREE.PointLight(c,i,d,2); l.position.set(x,y,z); scene.add(l); return l; }
const lampLight = point(-5.55, 3.5, 1.15, 0xffb066, 22, 9);
const shopLight = point(-1.4, 2.5, -3.6, 0xffd9a0, 18, 7);
point(-3.95, 1.25, -0.15, 0xff8a70, 5, 3.6);
point( 2.15, 2.3, -5.3, 0x9fd8ff, 3.2, 3.6);
point(-1.6, 3.05, -0.4, 0xf2f4ff, 4, 4);

/* ================= 工具:材质 / 几何 / 描边 ================= */
const world = new THREE.Group(); scene.add(world);

function gradMap(steps){
  const t = new THREE.DataTexture(new Uint8Array(steps), steps.length, 1, THREE.RedFormat);
  t.minFilter = t.magFilter = THREE.NearestFilter; t.needsUpdate = true; return t;
}
const G3 = gradMap([90,170,255]), G4 = gradMap([70,130,195,255]);
const tmCache = new Map();
function TM(color){ if(!tmCache.has(color)) tmCache.set(color, new THREE.MeshToonMaterial({color, gradientMap:G3})); return tmCache.get(color); }
function TM4(color){ return new THREE.MeshToonMaterial({color, gradientMap:G4}); }
function BM(color, k=1){ const m=new THREE.MeshBasicMaterial(); m.color=new THREE.Color(color).multiplyScalar(k); return m; }

const geoCache = new Map();
function boxGeo(w,h,d){ const k=`b${w},${h},${d}`; if(!geoCache.has(k)) geoCache.set(k,new THREE.BoxGeometry(w,h,d)); return geoCache.get(k); }
function cylGeo(rt,rb,h,s=14){ const k=`c${rt},${rb},${h},${s}`; if(!geoCache.has(k)) geoCache.set(k,new THREE.CylinderGeometry(rt,rb,h,s)); return geoCache.get(k); }

const OUTMAT = new THREE.MeshBasicMaterial({color:0x141126, side:THREE.BackSide});
function outline(m, t=0.018){
  const g=m.geometry; if(!g.boundingBox) g.computeBoundingBox();
  const s=g.boundingBox.getSize(new THREE.Vector3());
  const o=new THREE.Mesh(g, OUTMAT);
  o.scale.set(s.x>1e-3?1+2*t/s.x:1, s.y>1e-3?1+2*t/s.y:1, s.z>1e-3?1+2*t/s.z:1);
  o.castShadow=o.receiveShadow=false; m.add(o); return m;
}
funct.........完整代码请登录后点击上方下载按钮下载查看

网友评论0