three做个三维体素微缩建筑工地沙盘场景动画模拟代码
代码语言:html
所属分类:其他
代码由glm-5.3-flash ai生成,可能有错误,仅供参考:点击查看提示词
代码描述:三维体素微缩建筑工地沙盘场景动画模拟
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>体素工地 · 微缩沙盘</title>
<style>
html,body{margin:0;height:100%;overflow:hidden;background:#0c0d12;font-family:ui-monospace,Consolas,Menlo,monospace}
canvas{display:block}
#ui{position:fixed;inset:0;pointer-events:none;color:#cfd6dd}
#title{position:absolute;top:26px;left:50%;transform:translateX(-50%);letter-spacing:.35em;font-size:15px;
color:#e8e2d4;text-shadow:0 2px 10px #000;animation:fade 9s forwards}
@keyframes fade{0%{opacity:0}12%{opacity:1}75%{opacity:1}100%{opacity:.15}}
#hud{position:absolute;top:14px;right:16px;font-size:12px;line-height:1.7;text-align:right;
background:rgba(10,12,18,.55);border:1px solid rgba(255,255,255,.12);border-radius:6px;padding:8px 12px;backdrop-filter:blur(4px)}
#tips{position:absolute;left:16px;bottom:14px;font-size:12px;line-height:1.8;color:#9aa5ae;
background:rgba(10,12,18,.5);border:1px solid rgba(255,255,255,.1);border-radius:6px;padding:8px 12px}
#tips b{color:#e8c86a;font-weight:600}
</style>
<script type="importmap">
{"imports":{"three":"https://cdn.jsdelivr.net/npm/three@0.160.0/build/three.module.js"}}
</script>
</head>
<body>
<div id="ui">
<div id="title">VOXEL WORKS · 体素工地微缩沙盘</div>
<div id="hud"></div>
<div id="tips"><b>拖拽</b> 环视 · <b>滚轮</b> 缩放 · <b>点击桌面旋钮</b> 调速/昼夜/尘土 · <b>空格</b> 暴雨</div>
</div>
<script type="module">
import * as THREE from 'three';
/* ================= 基础 ================= */
const renderer=new THREE.WebGLRenderer({antialias:true});
renderer.setPixelRatio(Math.min(devicePixelRatio,2));
renderer.setSize(innerWidth,innerHeight);
renderer.shadowMap.enabled=true;
renderer.shadowMap.type=THREE.PCFSoftShadowMap;
renderer.outputColorSpace=THREE.SRGBColorSpace;
renderer.toneMapping=THREE.ACESFilmicToneMapping;
document.body.prepend(renderer.domElement);
const scene=new THREE.Scene();
renderer.setClearColor(0x0b0c11);
scene.fog=new THREE.Fog(0x10131c,55,150);
const camera=new THREE.PerspectiveCamera(45,innerWidth/innerHeight,.1,300);
addEventListener('resize',()=>{camera.aspect=innerWidth/innerHeight;camera.updateProjectionMatrix();renderer.setSize(innerWidth,innerHeight);});
/* 确定性随机(保证布局稳定) */
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}}
const R=mulberry32(20240915); const rnd=()=>R();
/* ================= 工具:体素合并器 ================= */
const FACES=[ // 每面 4 角(CCW 外向)+ 法线
[[1,1,-1],[1,1,1],[1,-1,1],[1,-1,-1],[1,0,0]],
[[-1,1,1],[-1,1,-1],[-1,-1,-1],[-1,-1,1],[-1,0,0]],
[[1,1,-1],[-1,1,-1],[-1,1,1],[1,1,1],[0,1,0]],
[[1,-1,1],[-1,-1,1],[-1,-1,-1],[1,-1,-1],[0,-1,0]],
[[-1,1,-1],[1,1,-1],[1,-1,-1],[-1,-1,-1],[0,0,-1]],
[[1,1,1],[-1,1,1],[-1,-1,1],[1,-1,1],[0,0,1]]];
const UVK=[[0,0],[1,0],[1,1],[0,1]];
const _v=new THREE.Vector3();
function boxesGeo(list){
const pos=[],nor=[],col=[],uv=[],idx=[];let vi=0;const c=new THREE.Color();
for(const p of list){
c.set(p.c); const j=p.j||0;
if(j){const f=1+(rnd()*2-1)*j;c.r=Math.min(1,c.r*f);c.g=Math.min(1,c.g*f);c.b=Math.min(1,c.b*f);}
const hx=p.sx/2,hy=p.sy/2,hz=p.sz/2,q=p.q;
for(const f of FACES){
for(let k=0;k<4;k++){
let X=f[k][0]*hx,Y=f[k][1]*hy,Z=f[k][2]*hz,Nx=f[4][0],Ny=f[4][1],Nz=f[4][2];
if(q){_v.set(X,Y,Z).applyQuaternion(q);X=_v.x;Y=_v.y;Z=_v.z;_v.set(Nx,Ny,Nz).applyQuaternion(q);Nx=_v.x;Ny=_v.y;Nz=_v.z;}
pos.push(X+p.x,Y+p.y,Z+p.z);nor.push(Nx,Ny,Nz);col.push(c.r,c.g,c.b);uv.push(UVK[k][0],UVK[k][1]);
}
idx.push(vi,vi+1,vi+2,vi,vi+2,vi+3);vi+=4;
}
}
const g=new THREE.BufferGeometry();
g.setAttribute('position',new THREE.Float32BufferAttribute(pos,3));
g.setAttribute('normal',new THREE.Float32BufferAttribute(nor,3));
g.setAttribute('color',new THREE.Float32BufferAttribute(col,3));
g.setAttribute('uv',new THREE.Float32BufferAttribute(uv,2));
g.setIndex(idx);return g;
}
const _Y=new THREE.Vector3(0,1,0),_d=new THREE.Vector3(),_qt=new THREE.Quaternion();
function bar(list,ax,ay,az,bx,by,bz,th,hex,j){ // 任意两点间的杆件
_d.set(bx-ax,by-ay,bz-az);const len=_d.length();_d.normalize();
const q=new THREE.Quaternion().setFromUnitVectors(_Y,_d);
list.push({x:(ax+bx)/2,y:(ay+by)/2,z:(az+bz)/2,sx:th,sy:len,sz:th,q,c:new THREE.Color(hex),j:j??0.05});
}
/* ================= 贴图 ================= */
function noiseTex(){
const cv=document.createElement('canvas');cv.width=cv.height=64;const g=cv.getContext('2d');
const im=g.createImageData(64,64);
for(let i=0;i<4096;i++){const v=226+Math.floor(rnd()*29);im.data[i*4]=im.data[i*4+1]=im.data[i*4+2]=v;im.data[i*4+3]=255;}
g.putImageData(im,0,0);
const t=new THREE.CanvasTexture(cv);t.magFilter=THREE.NearestFilter;t.minFilter=THREE.NearestMipmapLinearFilter;t.colorSpace=THREE.SRGBColorSpace;return t;
}
function woodTex(){
const cv=document.createElement('canvas');cv.width=256;cv.height=256;const g=cv.getContext('2d');
g.fillStyle='#4a3220';g.fillRect(0,0,256,256);
for(let y=0;y<256;y++){const n=Math.sin(y*.35+Math.sin(y*.07)*3)*10+rnd()*14;
g.fillStyle=`rgb(${74+n|0},${50+n*.7|0},${32+n*.5|0})`;g.fillRect(0,y,256,1);}
for(let i=0;i<26;i++){g.strokeStyle='rgba(30,18,10,.35)';g.beginPath();
const y=rnd()*256;g.moveTo(0,y);g.bezierCurveTo(80,y+rnd()*14-7,170,y+rnd()*14-7,256,y+rnd()*10-5);g.stroke();}
const t=new THREE.CanvasTexture(cv);t.colorSpace=THREE.SRGBColorSpace;t.wrapS=t.wrapT=THREE.RepeatWrapping;t.repeat.set(3,2);return t;
}
function textTex(txt,bg,fg,w,h,fs){
const cv=document.createElement('canvas');cv.width=w;cv.height=h;const g=cv.getContext('2d');
g.fillStyle=bg;g.fillRect(0,0,w,h);g.strokeStyle=fg;g.lineWidth=4;g.strokeRect(6,6,w-12,h-12);
g.fillStyle=fg;g.fo.........完整代码请登录后点击上方下载按钮下载查看















网友评论0