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