three实现天文学家的三维城堡代码
代码语言:html
所属分类:三维
代码描述:three实现天文学家的三维城堡代码
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
:root { color-scheme: dark; }
* { box-sizing: border-box; }
html, body { width: 100%; height: 100%; margin: 0; overflow: hidden; background: #080b11; }
body { font-family: Inter, ui-sans-serif, system-ui, sans-serif; }
#scene { position: fixed; inset: 0; }
canvas { display: block; width: 100%; height: 100%; }
.hint {
position: fixed;
left: 50%;
bottom: 18px;
z-index: 2;
transform: translateX(-50%);
color: rgba(190, 202, 211, .58);
font-size: 8px;
letter-spacing: .14em;
text-transform: uppercase;
white-space: nowrap;
pointer-events: none;
}
.vignette {
position: fixed;
inset: 0;
z-index: 1;
background: radial-gradient(circle at 50% 42%, transparent 48%, rgba(0, 0, 0, .42) 115%);
pointer-events: none;
}
@media (max-width: 640px) {
.hint { bottom: 12px; font-size: 7px; }
}
</style>
<script type="importmap">
{"imports":{"three":"https://cdn.jsdelivr.net/npm/three@0.174.0/build/three.module.js","three/addons/":"https://cdn.jsdelivr.net/npm/three@0.174.0/examples/jsm/"}}
</script>
</head>
<body>
<div id="scene"></div>
<div class="hint">Drag to orbit · Scroll or pinch to zoom</div>
<div class="vignette"></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 { OutputPass } from "three/addons/postprocessing/OutputPass.js";
const container = document.getElementById("scene");
const reducedMotion = matchMedia("(prefers-reduced-motion: reduce)").matches;
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x080b11);
scene.fog = new THREE.Fog(0x080b11, 25, 48);
const renderer = new THREE.WebGLRenderer({ antialias: true, powerPreference: "high-performance" });
renderer.setPixelRatio(Math.min(devicePixelRatio, 1.75));
renderer.setSize(innerWidth, innerHeight);
renderer.outputColorSpace = THREE.SRGBColorSpace;
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 1.06;
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.domElement.setAttribute("role", "img");
renderer.domElement.setAttribute("aria-label", "Interactive isolated model of the Astral Tide Citadel on a flat plane.");
container.appendChild(renderer.domElement);
const camera = new THREE.PerspectiveCamera(innerWidth / innerHeight < .72 ? 56 : 38, innerWidth / innerHeight, .1, 100);
camera.position.set(16.4, 9.4, 19.2);
const controls = new OrbitControls(camera, renderer.domElement);
controls.target.set(0, 3.35, -1.35);
controls.enableDamping = true;
controls.dampingFactor = .055;
controls.minDistance = 8;
controls.maxDistance = 38;
controls.maxPolarAngle = Math.PI * .49;
controls.update();
const composer = new EffectComposer(renderer);
composer.addPass(new RenderPass(scene, camera));
composer.addPass(new UnrealBloomPass(new THREE.Vector2(innerWidth, innerHeight), .34, .55, .86));
composer.addPass(new OutputPass());
let randomSeed = 92741;
function random() {
randomSeed = (randomSeed * 1664525 + 1013904223) >>> 0;
return randomSeed / 4294967296;
}
function range(min, max) { return min + (max - min) * random(); }
function setShadow(object, cast = true, receive = true) {
object.castShadow = cast;
object.receiveShadow = receive;
return object;
}
function addMesh(parent, geometry, material, x = 0, y = 0, z = 0, rx = 0, ry = 0, rz = 0) {
const object = setShadow(new THREE.Mesh(geometry, material));
object.position.set(x, y, z);
object.rotation.set(rx, ry, rz);
parent.add(object);
return object;
}
function makeBrickTexture(base, mortar, accent) {
const canvas = document.createElement("canvas");
canvas.width = canvas.height = 512;
const context = canvas.getContext("2d");
context.fillStyle = mortar;
context.fillRect(0, 0, 512, 512);
const rows = 12;
const height = 512 / rows;
for (let row = 0; row < rows; row++) {
const offset = row % 2 ? -30 : 0;
for (let x = offset; x < 530; x += 63) {
const light = range(-12, 13);
context.fillStyle = `rgb(${Math.max(0, parseInt(base.slice(1, 3), 16) + light)},${Math.max(0, parseInt(base.slice(3, 5), 16) + light)},${Math.max(0, parseInt(base.slice(5, 7), 16) + light)})`;
context.fillRect(x + 2, row * height + 2, 59, height - 4);
context.fillStyle = accent;
context.globalAlpha = .13;
context.fillRect(x + 4, row * height + 4, 54, 3);
context.globalAlpha = 1;
}
}
const texture = new THREE.CanvasTexture(canvas);
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set(3.4, 3.4);
texture.color.........完整代码请登录后点击上方下载按钮下载查看















网友评论0