three实现三维海边便利店场景代码

代码语言:html

所属分类:其他

代码由minimax-m3.1-flash ai生成,可能有错误,仅供参考:点击查看提示词

代码描述:三维海边便利店场景

代码标签: three 三维 海边 便利店 场景 代码

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

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
<title>海风便利店 · 盛夏黄昏微缩</title>
<style>
  html,body{margin:0;padding:0;height:100%;overflow:hidden;background:#0d1226;}
  canvas{display:block;width:100%;height:100%;touch-action:none;}
</style>
</head>
<body>
<script type="importmap">
{"imports":{"three":"https://unpkg.com/three@0.160.0/build/three.module.js","three/addons/":"https://unpkg.com/three@0.160.0/examples/jsm/"}}
</script>
<script type="module">
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

/* ============================================================
   海风便利店 —— 盛夏黄昏 · 三渲二卡通微缩景观
   第三人称环绕视角 / 无 UI / 全程序化生成
   ============================================================ */

const TAU = Math.PI * 2;
const clamp = (v,a,b)=>Math.min(b,Math.max(a,v));
const ANIMS = [];
function mulberry32(a){return function(){a|=0;a=a+0x6D2B79F5|0;let t=Math.imul(a^a>>>15,1|a);t=t+Math.imul(t^t>>>7,61|t)^t;return((t^t>>>14)>>>0)/4294967296;}}

/* ---------------- renderer / scene / camera ---------------- */
const renderer = new THREE.WebGLRenderer({antialias:true, alpha:false, powerPreference:'high-performance'});
renderer.setPixelRatio(Math.min(window.devicePixelRatio||1, 2));
renderer.setSize(innerWidth, innerHeight);
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.outputColorSpace = THREE.SRGBColorSpace;
renderer.toneMapping = THREE.NoToneMapping;
document.body.appendChild(renderer.domElement);

const scene = new THREE.Scene();
scene.fog = new THREE.Fog(0x5f7aa6, 55, 140);

const camera = new THREE.PerspectiveCamera(34, innerWidth/innerHeight, 0.1, 400);
camera.position.set(19.5, 15.0, 21.0);

const controls = new OrbitControls(camera, renderer.domElement);
controls.target.set(0.2, 1.0, 0.4);
controls.enableDamping = true;
controls.dampingFactor = 0.045;
controls.minDistance = 9;
controls.maxDistance = 58;
controls.minPolarAngle = 0.18;
controls.maxPolarAngle = 1.46;
controls.autoRotate = true;
controls.autoRotateSpeed = 0.32;
controls.panSpeed = 0.6;
controls.rotateSpeed = 0.62;
controls.zoomSpeed = 0.8;

/* ---------------- toon gradient (banded lighting) ---------------- */
const GRAD = (()=>{
  const d = new Uint8Array([
    62,62,62,255,  126,126,126,255,  190,190,190,255,  255,255,255,255
  ]);
  const t = new THREE.DataTexture(d,4,1,THREE.RGBAFormat);
  t.minFilter = THREE.NearestFilter; t.magFilter = THREE.NearestFilter;
  t.generateMipmaps = false; t.needsUpdate = true;
  return t;
})();

/* ---------------- palette ---------------- */
const C = {
  cream:0xfdf6e8, white:0xffffff, mint:0x93d9c6, seafoam:0xc6ece0,
  coral:0xff8f70, peach:0xffc9a6, salmon:0xf7a58c, rose:0xf7b7c8,
  teal:0x3aa3c2, deep:0x24607e, navy:0x2c3b63, indigo:0x41528a,
  sand:0xead8b6, sandDark:0xd8bf95, wetSand:0xcdb894,
  asphalt:0x4e5360, asphaltLt:0x5a606d,
  concrete:0xdad6ca, concreteDk:0xc4c0b4, curb:0xe8e5dc,
  wood:0xcb9d6d, woodDk:0x9d7048, woodLt:0xe0bd90,
  metal:0xbcc5cf, metalDk:0x707a86, rubber:0x3a3d44,
  yellow:0xffd166, pink:0xffaec8, blue:0x74abe0, green:0x9ed3a6,
  purple:0xb8a2de, orange:0xffab5e, red:0xe4593f, ink:0x2a2340,
  skyH:0xffb083, skyM:0xff96a4, skyT:0x7d8ed6, skyZ:0x27356e
};

/* ---------------- material helpers ---------------- */
const matCache = new Map();
function mkey(color,o){
  let k = String(color);
  for(const key of Object.keys(o||{})){
    const v=o[key];
    k += '|'+key+':'+(v && v.isTexture ? ('T'+v.uuid) : (v && v.isMaterial ? ('M'+v.uuid) : String(v)));
  }
  return k;
}
function mk(cls,color,o,extra){
  o = o || {};
  const opts = Object.assign({}, extra||{}, o);
  delete opts._u;
  if(o._u) return new cls(Object.assign({color},opts));
  const k = cls.name+'|'+mkey(color,o);
  let m = matCache.get(k);
  if(!m){ m = new cls(Object.assign({color},opts)); matCache.set(k,m); }
  return m;
}
const toon  = (color,o) => mk(THREE.MeshToonMaterial,  color,o,{gradientMap:GRAD});
const phong = (color,o) => mk(THREE.MeshPhongMaterial,color,o,{});
const basic = (color,o) => mk(THREE.MeshBasicMaterial,color,o,{});

const MAT = {
  base:      toon(0xf2e6d2),
  baseSide:  toon(0xe8dcc8),
  asphalt:   toon(C.asphalt),
  asphaltLt: toon(C.asphaltLt),
  concrete:  toon(C.concrete),
  concreteDk:toon(C.concreteDk),
  curb:      toon(C.curb),
  line:      toon(0xf4f2e8),
  sand:      toon(C.sand),
  wetSand:   phong(C.wetSand,{shininess:52,specular:0x9fb6d8}),
  cream:     toon(C.cream),
  white:     toon(C.white),
  mint:      toon(C.mint),
  seafoam:   toon(C.seafoam),
  coral:     toon(C.coral),
  peach:     toon(C.peach),
  rose:      toon(C.rose),
  teal:      toon(C.teal),
  deep:      toon(C.deep),
  navy:      toon(C.navy),
  indigo:    toon(C.indigo),
  wood:      toon(C.wood),
  woodDk:    toon(C.woodDk),
  woodLt:    toon(C.woodLt),
  metal:     toon(0xd4dfe9),
  metalDk:   toon(0x99a5b5),
  rubber:    toon(C.rubber),
  yellow:    toon(C.yellow),
  pink:      toon(C.pink),
  blue:      toon(C.blue),
  green:     toon(C.green),
  purple:    toon(C.purple),
  orange:    toon(C.orange),
  red:       toon(C.red),
  ink:       toon(C.ink),
  glass:     phong(0xd6f0f8,{transparent:true,opacity:0.11,shininess:120,specular:0xffffff,side:THREE.DoubleSide,depthWrite:false}),
  glassDark: phong(0x9fc6d8,{transparent:true,opacity:0.30,shininess:120,specular:0xffffff,side:THREE.DoubleSide,depthWrite:false}),
  warmGlow:  basic(0xfff0d4,{_u:true}),
  lampGlow:  basic(0xffe4b0),
  neonMint:  basic(0xa9ffe6),
  neonPink:  basic(0xffb6d9),
  neonBlue:  basic(0xa8d8ff)
};

/* ---------------- outline (inverted hull) ---------------- */
const OUTLINE_COLOR = new THREE.Color(0x241e38);
function outline(target, thickness=0.022, color=OUTLINE_COLOR){
  const m = new THREE.ShaderMaterial({
    uniforms:{ t:{value:thickness}, c:{value:new THREE.Color(color)} },
    vertexShader:'uniform float t; void main(){ vec3 p=position+normal*t; gl_Position=projectionMatrix*modelViewMatrix*vec4(p,1.0); }',
    fragmentShader:'uniform vec3 c; void main(){ gl_FragColor=vec4(c,1.0); }',
    side:THREE.BackSide
  });
  const o = new THREE.Mesh(target.geometry, m);
  o.renderOrder = -1;
  target.add(o);
  return o;
}

/* ---------------- geometry helpers ---------------- */
function M(geo, mat, x=0,y=0,z=0, o={}){
  const m = new THREE.Mesh(geo, mat);
  m.position.set(x,y,z);
  if(o.cast) m.castShadow = true;
  if(o.recv) m.receiveShadow = true;
  if(o.rot) m.rotation.set(o.rot[0]||0,o.rot[1]||0,o.rot[2]||0);
  if(o.noPick) m.userData.noPick = true;
  return m;
}
function box(w,h,d,mat,x,y,z,o){ return M(new THREE.BoxGeometry(w,h,d),mat,x,y,z,o); }
function cyl(rt,rb,h,mat,x,y,z,o,seg=18){ return M(new THREE.CylinderGeometry(rt,rb,h,seg),mat,x,y,z,o); }
function sph(r,mat,x,y,z,o,seg=14){ return M(new THREE.SphereGeometry(r,seg,Math.max(6,seg>>1)),mat,x,y,z,o); }
function tor(r,t,mat,x,y,z,o,seg=16,rad=8){ return M(new THREE.TorusGeometry(r,t,rad,seg),mat,x,y,z,o); }
function plane(w,h,mat,x,y,z,o,rot){ const m=M(new THREE.PlaneGeometry(w,h),mat,x,y,z,o); if(rot)m.rotation.x=rot[0]; if(rot&&rot[1]!==undefined)m.rotation.y=rot[1]; if(rot&&rot[2]!==undefined)m.rotation.z=rot[2]; return m; }
function grp(x=0,y=0,z=0){ const g=new THREE.Group(); g.position.set(x,y,z); return g; }
function tube(a,b,r,mat,seg=8){
  const va=new THREE.Vector3(a[0],a[1],a[2]), vb=new THREE.Vector3(b[0],b[1],b[2]);
  const dir=vb.clone().sub(va); const len=dir.length();
  const m=new THREE.Mesh(new THREE.CylinderGeometry(r,r,len,seg),mat);
  m.position.copy(va).add(vb).multiplyScalar(0.5);
  m.quaternion.setFromUnitVectors(new THREE.Vector3(0,1,0), dir.normalize());
  m.castShadow = true;
  return m;
}

/* ---------------- canvas texture factory ---------------- */
function cvs(w,h,draw){
  const c=document.createElement('canvas'); c.width=w; c.height=h;
  const ctx=c.getContext('2d'); draw(ctx,w,h);
  const t=new THREE.CanvasTexture(c);
  t.colorSpace=THREE.SRGBColorSpace;
  t.anisotropy=8;
  return t;
}
function noiseTex(base, speck, count=2600, size=512, contrast=0.06){
  return cvs(size,size,(ctx,w,h)=>{
    ctx.fillStyle=base; ctx.fillRect(0,0,w,h);
    const r=mulberry32(7);
    for(let i=0;i<count;i++){
      const x=r()*w, y=r()*h, s=r()*2.6+0.6;
      const a=(r()*2-1)*contrast;
      ctx.fillStyle = speck;
      ctx.globalAlpha = Math.abs(a)*3.2;
      ctx.beginPath(); ctx.arc(x,y,s,0,TAU); ctx.fill();
    }
    ctx.globalAlpha=1;
    // subtle horizontal streaks
    for(let i=0;i<40;i++){
      ctx.globalAlpha=0.03;
      ctx.fillStyle= speck;
      ctx.fillRect(0, r()*h, w, 1+r()*2);
    }
    ctx.globalAlpha=1;
  });
}

/* ------.........完整代码请登录后点击上方下载按钮下载查看

网友评论0