384 三角面3.02 × 1.44 × 0.85 m
在代码中使用
在编辑器中改编stone-wall.js · 207 行
自包含的 ES 模块,仅依赖 three。调用工厂函数,然后把返回的 group 添加到场景中。
/**
* Stone Wall — Codels 3D model library
* License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
* Triangles: 384 · Size (W × H × D): 3.02 × 1.44 × 0.85 m
*
* Usage:
* import { createStoneWall } from './stone-wall.js';
*
* const model = createStoneWall();
* model.position.set(0, 0, 0);
* scene.add(model);
*/
import * as THREE from 'three';
const deg = THREE.MathUtils.degToRad;
// Deterministic vertex displacement (organic low-poly look).
function jitter(geometry, amount, seed) {
const pos = geometry.attributes.position;
const h = (a, b, c, s) => {
let x = Math.imul(a, 73856093) ^ Math.imul(b, 19349663) ^ Math.imul(c, 83492791) ^ Math.imul(s, 2654435761);
x = Math.imul(x ^ (x >>> 16), 2246822507);
x = Math.imul(x ^ (x >>> 13), 3266489909);
return ((x ^ (x >>> 16)) >>> 0) / 4294967295 - 0.5;
};
for (let i = 0; i < pos.count; i++) {
const x = pos.getX(i), y = pos.getY(i), z = pos.getZ(i);
const qx = Math.round(x * 1000), qy = Math.round(y * 1000), qz = Math.round(z * 1000);
pos.setXYZ(i, x + h(qx, qy, qz, seed) * 2 * amount, y + h(qx, qy, qz, seed + 1) * 2 * amount, z + h(qx, qy, qz, seed + 2) * 2 * amount);
}
pos.needsUpdate = true;
geometry.computeVertexNormals();
return geometry;
}
export function createStoneWall() {
const root = new THREE.Group();
root.name = 'StoneWall';
// Materials
const stoneMat = new THREE.MeshStandardMaterial({ name: 'stone', color: 0x8e887d, roughness: 0.95, flatShading: true });
const stone2Mat = new THREE.MeshStandardMaterial({ name: 'stone2', color: 0x7a756c, roughness: 0.95, flatShading: true });
const mortarMat = new THREE.MeshStandardMaterial({ name: 'mortar', color: 0x4e4b45, roughness: 1, flatShading: true });
const mossMat = new THREE.MeshStandardMaterial({ name: 'moss', color: 0x5b7a37, roughness: 1, flatShading: true });
// Parts
const core = new THREE.Mesh(new THREE.BoxGeometry(2.93, 1.25, 0.512), mortarMat);
core.name = 'core';
core.position.set(0, 0.625, 0);
root.add(core);
const block = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.6803, 0.2925, 0.6125), 0.02, 1), stoneMat);
block.name = 'block';
block.position.set(-1.1473, 0.1588, 0);
block.rotation.set(0, deg(0.0989), deg(0.5632));
root.add(block);
const block2 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.5819, 0.2925, 0.6369), 0.02, 2), stoneMat);
block2.name = 'block';
block2.position.set(-0.4912, 0.1588, 0);
block2.rotation.set(0, deg(-1.0618), deg(0.3352));
root.add(block2);
const block3 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.711, 0.2925, 0.6018), 0.02, 3), stone2Mat);
block3.name = 'block';
block3.position.set(0.1802, 0.1588, 0);
block3.rotation.set(0, deg(1.096), deg(-0.1499));
root.add(block3);
const block4 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.4758, 0.2925, 0.5978), 0.02, 4), stoneMat);
block4.name = 'block';
block4.position.set(0.7986, 0.1588, 0);
block4.rotation.set(0, deg(0.743), deg(-0.3041));
root.add(block4);
const block5 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.4259, 0.2925, 0.612), 0.02, 5), stoneMat);
block5.name = 'block';
block5.position.set(1.2745, 0.1588, 0);
block5.rotation.set(0, deg(-0.6807), deg(-0.191));
root.add(block5);
const block6 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.2176, 0.2925, 0.6107), 0.02, 6), stone2Mat);
block6.name = 'block';
block6.position.set(-1.3787, 0.4763, 0);
block6.rotation.set(0, deg(-1.1099), deg(0.5614));
root.add(block6);
const block7 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.4632, 0.2925, 0.5839), 0.02, 7), stoneMat);
block7.name = 'block';
block7.position.set(-1.0133, 0.4763, 0);
block7.rotation.set(0, deg(-0.049), deg(-0.0029));
root.add(block7);
const block8 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.6826, 0.2925, 0.595), 0.02, 8), stoneMat);
block8.name = 'block';
block8.position.set(-0.4154, 0.4763, 0);
block8.rotation.set(0, deg(-0.1016), deg(0.0866));
root.add(block8);
const block9 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.463, 0.2925, 0.5935), 0.02, 9), stoneMat);
block9.name = 'block';
block9.position.set(0.1824, 0.4763, 0);
block9.rotation.set(0, deg(0.1023), deg(-0.3771));
root.add(block9);
const block10 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.7284, 0.2925, 0.6248), 0.02, 10), stone2Mat);
block10.name = 'block';
block10.position.set(0.8031, 0.4763, 0);
block10.rotation.set(0, deg(-1.1092), deg(-0.4251));
root.add(block10);
const block11 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.2952, 0.2925, 0.612), 0.02, 11), stoneMat);
block11.name = 'block';
block11.position.set(1.3399, 0.4763, 0);
block11.rotation.set(0, deg(-0.7598), deg(0.1005));
root.add(block11);
const block12 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.4629, 0.2925, 0.6057), 0.02, 12), stoneMat);
block12.name = 'block';
block12.position.set(-1.2561, 0.7938, 0);
block12.rotation.set(0, deg(0.6504), deg(-0.1738));
root.add(block12);
const block13 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.7103, 0.2925, 0.5877), 0.02, 13), stone2Mat);
block13.name = 'block';
block13.position.set(-0.6445, 0.7938, 0);
block13.rotation.set(0, deg(0.1548), deg(0.6535));
root.add(block13);
const block14 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.7416, 0.2925, 0.6179), 0.02, 14), stoneMat);
block14.name = 'block';
block14.position.set(0.1064, 0.7938, 0);
block14.rotation.set(0, deg(-0.5181), deg(0.161));
root.add(block14);
const block15 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.5061, 0.2925, 0.6184), 0.02, 15), stone2Mat);
block15.name = 'block';
block15.position.set(0.7553, 0.7938, 0);
block15.rotation.set(0, deg(-0.5735), deg(0.6759));
root.add(block15);
const block16 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.4542, 0.2925, 0.612), 0.02, 16), stone2Mat);
block16.name = 'block';
block16.position.set(1.2604, 0.7938, 0);
block16.rotation.set(0, deg(-0.7038), deg(0.7416));
root.add(block16);
const block17 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.2483, 0.2925, 0.6257), 0.02, 17), stone2Mat);
block17.name = 'block';
block17.position.set(-1.3634, 1.1113, 0);
block17.rotation.set(0, deg(-0.2758), deg(0.1835));
root.add(block17);
const block18 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.5035, 0.2925, 0.6316), 0.02, 18), stoneMat);
block18.name = 'block';
block18.position.set(-0.9625, 1.1113, 0);
block18.rotation.set(0, deg(0.2628), deg(0.6122));
root.add(block18);
const block19 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.4123, 0.2925, 0.638), 0.02, 19), stone2Mat);
block19.name = 'block';
block19.position.set(-0.4796, 1.1113, 0);
block19.rotation.set(0, deg(0.0413), deg(-0.6989));
root.add(block19);
const block20 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.7444, 0.2925, 0.6186), 0.02, 20), stone2Mat);
block20.name = 'block';
block20.position.set(0.1238, 1.1113, 0);
block20.rotation.set(0, deg(0.1827), deg(-0.3459));
root.add(block20);
const block21 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.6327, 0.2925, 0.615), 0.02, 21), stone2Mat);
block21.name = 'block';
block21.position.set(0.8373, 1.1113, 0);
block21.rotation.set(0, deg(-0.5608), deg(0.5673));
root.add(block21);
const block22 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.3088, 0.2925, 0.612), 0.02, 22), stone2Mat);
block22.name = 'block';
block22.position.set(1.3331, 1.1113, 0);
block22.rotation.set(0, deg(1.1414), deg(-0.0016));
root.add(block22);
const capstone = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.875, 0.13, 0.712), 0.012, 23), stone2Mat);
capstone.name = 'capstone';
capstone.position.set(-1.0525, 1.335, 0.0089);
capstone.rotation.set(0, 0, deg(-0.0245));
root.add(capstone);
const capstone2 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.8076, 0.13, 0.712), 0.012, 24), stone2Mat);
capstone2.name = 'capstone';
capstone2.position.set(-0.1913, 1.335, -0.01);
capstone2.rotation.set(0, 0, deg(-0.3341));
root.add(capstone2);
const capstone3 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.6019, 0.13, 0.712), 0.012, 25), stone2Mat);
capstone3.name = 'capstone';
capstone3.position.set(0.5335, 1.335, 0.0138);
capstone3.rotation.set(0, 0, deg(0.5904));
root.add(capstone3);
const capstone4 = new THREE.Mesh(jitter(new THREE.BoxGeometry(0.6356, 0.13, 0.712), 0.012, 26), stone2Mat);
capstone4.name = 'capstone';
capstone4.position.set(1.1722, 1.335, -0.0122);
capstone4.rotation.set(0, 0, deg(0.0443));
root.add(capstone4);
const moss = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.2195, 0), 0.0263, 27), mossMat);
moss.name = 'moss';
moss.position.set(-0.0293, 1.3671, -0.0059);
moss.scale.set(1.4, 0.35, 1.1);
root.add(moss);
const moss2 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.1649, 0), 0.0198, 28), mossMat);
moss2.name = 'moss';
moss2.position.set(0.8754, 1.3753, -0.1108);
moss2.scale.set(1.4, 0.35, 1.1);
root.add(moss2);
const moss3 = new THREE.Mesh(jitter(new THREE.IcosahedronGeometry(0.2043, 0), 0.0245, 29), mossMat);
moss3.name = 'moss';
moss3.position.set(-0.4244, 0.1306, 0.326);
moss3.scale.set(1.3, 0.6, 0.8);
root.add(moss3);
root.traverse((o) => {
if (o.isMesh) {
o.castShadow = true;
o.receiveShadow = true;
}
});
return root;
}
export default createStoneWall;
评分与评论
0 条评论
暂无评论。分享一下你是如何使用这个模型的,或者有哪些可以改进的地方。
相关模型
同一分类或相似标签









