threejs打造一个书桌三维效果代码

代码语言:html

所属分类:三维

代码描述:threejs打造一个书桌三维效果代码,摆满纸张和瓶子

代码标签: 书桌 三维 效果

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

<!DOCTYPE html>
<html lang="en" >

<head>

  <meta charset="UTF-8">

  
<style>
body {
  margin: 0;
  height: 100vh;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #000;
}
</style>




</head>

<body >

  
      <script type="module">
import * as THREE from "https://threejs.org/build/three.module.js";
import { OrbitControls } from "https://threejs.org/examples/jsm/controls/OrbitControls.js";

let camera, scene, renderer;
const uniforms = {
  t: { value: 0 } };


const { PI, cos, sin } = Math;
const TAU = 2 * PI;
const HALF_PI = PI / 2;

const map = (value, sMin, sMax, dMin, dMax) => {
  return dMin + (value - sMin) / (sMax - sMin) * (dMax - dMin);
};
const textrue = path => new THREE.TextureLoader().load(path);

const vec = (x = 0, y = 0, z = 0) => new THREE.Vector3(x, y, z);

const range = (n, m = 0) =>
Array(n).
fill(m).
map((i, j) => i + j);

const polar = (ang, r = 1) => [r * cos(ang), r * sin(ang)];

const group = () => new THREE.Group();

const shaderMaterials = getShaderMaterialSet(uniforms);
function init() {
  scene = new THREE.Scene();

  renderer = new THREE.WebGLRenderer({ antialias: true });
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);

  camera = new THREE.PerspectiveCamera(
  60,
  window.innerWidth / window.innerHeight,
  1,
  1000);

  camera.position.set(
  1.5733694630638464,
  64.24498103358587,
  100.84717514499769);

  camera.rotation.x = -0.5672196272222528;
  camera.rotation.y = 0.013157534983447959;
  camera.rotation.z = 0.008381607123176699;

  const controls = new OrbitControls(camera, renderer.domElement);

  addResizeHandler(renderer, camera);

  const envMapTexture = new THREE.TextureLoader().load(
  "//repo.bfw.wiki/bfwrepo/image/5d6539385ad28.png",
  () => {
    const rt = new THREE.WebGLCubeRenderTarget(envMapTexture.image.height);
    rt.fromEquirectangularTexture(renderer, envMapTexture);
    addObjects(scene, rt);
  });

  render();
}

function addObjects(scene, textureEnv) {
  createPot(scene, -40, 0, 10, textureEnv, shaderMaterials.pot);
  createGlassContainer({
    scene,
    texture: textureEnv,
    curve: beaker1,
    itemScale: 0.3,
    position: vec(-22, 0, -20),
    customLiquidMaterial: shaderMaterials.beaker });

  createGlassContainer({
    scene,
    texture: textureEnv,
    curve: beaker2,
    itemScale: 0.2,
    position: vec(-10, 0, -20),
    customLiquidMaterial: shaderMaterials.beaker });


  createTable(scene, textureEnv);

  createPapers(scene);
  createWineGlass(scene, textureEnv, vec(25, 20, 0), shaderMaterials.bottle);
  createBottle(scene, textureEnv, vec(20, 6.8, -10), shaderMaterials.bottle);
  createDish(scene, textureEnv);
}

function createPotBody(scene, x, y, z, textureEnv) {
  const geometry = new THREE.SphereBufferGeometry(
  10,
  36,
  36,
  0,
  TAU,
  PI * 0.3,
  PI * 0.5);


  const t = textrue(
  "//repo.bfw.wiki/bfwrepo/image/6000db65e38b3.png");


  t.wrapS = THREE.RepeatWrapping;
  t.wrapT = THREE.RepeatWrapping;
  const material = new THREE.MeshBasicMaterial({
    map: t,
    envMap: textureEnv.texture,
    side: THREE.DoubleSide });


  const sphere = new THREE.Mesh(geometry, material);
  sphere.position.set(x, y, z);
  scene.add(sphere);
}

function createPotTop(scene, x, y, z, textureEnv) {
  const geometry = new THREE.TorusBufferGeometry(7.8, 0.7, 16, 100);

  const t = textrue(
  "//repo.bfw.wiki/bfwrepo/image/6000db65e38b3.png");


  t.wrapS = THREE.RepeatWrapping;
  t.wrapT = THREE.RepeatWrapping;
  t.repeat.set(10, 1);
  const material = new THREE.MeshBasicMaterial({
    map: t,
    envMap: textureEnv.texture,
    side: THREE.DoubleSide });


  const mesh = new THREE.Mesh(geometry, material);
  mesh.rotation.x = HALF_PI;
  mesh.position.set(x, y, z);
  scene.add(mesh);
}

function potLiquidFunc(v, u, target) {
  const ang = map(u, 0, 1, 0.001, TAU);
  const r = map(v, 0, 1, 0.001, 8);
  const [x, z] = polar(ang, r);

  const y = 0;

  target.set(x, y, z);
}

function createPotLiquid(scene, x, y, z, potLiquidMaterial) {
  const geometry = new THREE.ParametricBufferGeometry(potLiquidFunc, 15, 25);
  const mesh = new THREE.Mesh(geometry, potLiquidMaterial);
  mesh.position.set(x, y, z);
  scene.add(mesh);
}

function createPot(scene, x, y, z, textureEnv, potLiquidMaterial) {
  const g = group();
  g.position.set(x, y, z);
  g.scale.set(1.4, 1.2, 1.2);
  createPotBody(g, 0, 8, 0, textureEnv);
  createPotTop(g, 0, 14, 0, textureEnv);
  createPotLiquid(g, 0, 12, 0, potLiquidMaterial);
  scene.add(g);
}

function createWineGlass(scene, textureEnv, position, customLiquidMaterial) {
  const g = group();
  createGlassContainer({
    scene: g,
    texture: textureEnv,
    curve: curveWineGlassBottom,
    itemScale: 1,
    position: vec(0, -20, 0),
    customLiquidMaterial,
    noTop: true,
    noLiquid: true });

  createGlassContainer({
    scene: g,
    texture: textureEnv,
    curve: curveWineGlassTop,
    itemScale: 1,
    position: vec(0, -20, 0),
    customLiquidMaterial,
    noTop: true,
    filled: 0.8 });

  g.position.copy(position);
  scene.add(g);
}

function createBottleTop(scene, textureEnv) {
  const geometry = new THREE.SphereBufferGeometry(4, 32, 32);

  const t = textrue(
  "//repo.bfw.wiki/bfwrepo/image/6000db65e38b3.png");


  t.wrapS = THREE.RepeatWrapping;
  t.wrapT = THREE.RepeatWrapping;
  const material = new THREE.MeshBasicMaterial({
    map: t,
    envMap: textureEnv.texture,
    side: THREE.DoubleSide });


  const sphere = new THREE.Mesh(geometry, material);
  sphere.position.y = 40;
  scene.add(sphere);
}

function createBottle(scene, textureEnv, position, customLiquidMaterial) {
  const g = group();
  createGlassContainer({
    scene: g,
    texture: textureEnv,
    curve: curveBottle,
    itemScale: 4,
    position: vec(0, -20, 0),
    customLiquidMaterial,
    noTop: true,
    noLiquid: false });

  createBottleTop(g, textureEnv);

  g.scale.set(0.34, 0.34, 0.34);
  g.position.copy(position);
  scene.add(g);
}

function createDishTop(scene) {
  const geometry = new THREE.PlaneBufferGeometry(37, 37, 32);
  const plane = new THREE.Mesh(geometry, shaderMaterials.dish);
  plane.rotation.x = HALF_PI;
  plane.position.y = 8.2;
  scene.add(plane);
}

function createDish(scene, textureEnv) {
  const g = group();
  createGlassContainer({
    scene: g,
    texture: textureEnv,
    curve: curveDish,
    itemScale: 0.2,
    filled: 0.6,
    noLiquid: true,
    position: vec(0, 0, 0) });

  createDishTop(g);
  g.scale.set(0.4, 0.4, 0.4);
  g.position.set(35, 0, 15);
  scene.add(g);
}

function createBoxGeometry(scene, material, dimensions, position) {
  const geometry = new THREE.BoxBufferGeometry(...dimensions);
  const mesh = new THREE.Mesh(geometry, material);
  mesh.position.copy(position);
  scene.add(mesh);
}
function createTable(scene, textureEnv) {
  const g = group();
  const material = new THREE.MeshBasicMaterial({
    map: textrue("//repo.bfw.wiki/bfwrepo/image/5e4350528640e.png"),
    side: THREE.DoubleSide,
    envMap: textureEnv.texture });

  createBoxGeometry(g, material, [120, 5, 60], vec(0, 0, 0));
  createBoxGeometry(g, material, [5, 40, 60], vec(-50, -22.5, 0));
  createBoxGeometry(g, material, [5, 40, 60], vec(50, -22.5, 0));
  g.position.y = -3;
  scene.add(g);
}

function createGlassContainer({
  scene,
  texture,
  position = vec(0, 0, 0),
  curve,
  itemScale = 1,
  insideScale = 0.9,
  filled = 0.5,
  customLiquidMaterial,
  noTop,
  noLiquid })
{
  const points = curve();
  const g = group();
  g.position.copy(position);
  g.scale.set(itemScale, itemScale, itemScale);
  if (!noLiquid) {
    createGlassContainerLiquid(
    g,
    points,
    filled,
    insideScale,
    customLiquidMaterial);

  }
  createGlassContainerBody(g, texture, points);
  if (!noTop) {
    createGlassContaineTop(g, texture, points);
  }
  g.rotation.y = PI;
  scene.add(g);
  return g;
}

function createGlassContainerBody(scene, texture, points) {
  const geometry = new THREE.LatheGeometry(points, 32);
  const material = new THREE.MeshBasicMaterial({
    color: 0xefb08c,
    side: THREE.DoubleSide,
    envMap: texture.texture,
    transparent: true,
    opacity: 0.5 });

  const lathe = new THREE.Mesh(geometry, material);
  scene.add(lathe);
}

function createGlassContaineTop(scene, texture, points) {
  const r = points[0].x;
  const y = points[0].y;
  const geometry = new THREE.TorusBufferGeometry(r, 0.6, 16, 100);
  const material = new THREE.MeshBasicMaterial({
    color: 0xefb08c,
    side: THREE.DoubleSide,
    envMap: texture.texture,
    transparent: true,
    opacity: 0.8 });

  const mesh = new THREE.Mesh(geometry, material);
  mesh.rotation.x = HALF_PI;
  mesh.position.y = y;
  scene.add(mesh);
}

function getSurfacePoints(xe, ye) {
  return range(50).map(i => {
    const x = map(i, 0, 50, 0.01, xe);
    const y = map(i, 0, 50, ye + 0.1, ye);
    return vec(x, y, 0);
  });
}

function createGlassContainerLiquid(
scene,
points,
filledPrecentage,
scale,
customLiquidMaterial)
{
  const yMax = points[0].y;
  const yCutoff = map(filledPrecentage, 0, 1, 0, yMax);
  const selectedPoints = points.filter(({ x, y, z }) => y < yCutoff);

  const topAdded = [
  ...getSurfacePoints(selectedPoints[0].x, selectedPoints[0].y),
  ...selectedPoints];


  const geometry = new THREE.LatheGeometry(topAdded, 32);

  const mesh = new THREE.Mesh(geometry, customLiquidMaterial);

  mesh.scale.set(scale, 1, scale);
  scene.add(mesh);
}

function createPaper(scene, geometry, texturePath, rotZ, position) {
  const material = new THREE.MeshBasicMaterial({ map: textrue(texturePath) });
  const plane = new THREE.Mesh(geometry, material);
  plane.rotation.x = -HALF_PI;
  plane.rotation.z = rotZ;
  plane.position.copy(position);
  scene.add(plane);
}

function createPapers(.........完整代码请登录后点击上方下载按钮下载查看

网友评论0