three.jsのexampleをローカル環境で実装する方法

html

1<!DOCTYPE html>2<html lang="en">3 <head>4 <title>three.js webgl - postprocessing - depth-of-field</title>5 <meta charset="utf-8" />6 <meta7 name="viewport"8 content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"9 />10 <link type="text/css" rel="stylesheet" href="main.css" />11 </head>12 13 <body>14 <div id="info">15 <a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - webgl depth-of-field with bokeh example<br/>16 shader by <a href="http://artmartinsh.blogspot.com/2010/02/glsl-lens-blur-filter-with-bokeh.html">Martins Upitis</a>17 </div>18 <script type="importmap">19 {20 "imports": {21 "three": "https://unpkg.com/three@0.152.2/build/three.module.js",22 "three/addons/": "https://unpkg.com/three@0.152.2/examples/jsm/"23 }24 }25 </script>26 27 <script type="module">28 import * as THREE from "three";29 30 import Stats from "three/addons/libs/stats.module.js";31 import { GUI } from "three/addons/libs/lil-gui.module.min.js";32 import { EffectComposer } from "three/addons/postprocessing/EffectComposer.js";33 import { RenderPass } from "three/addons/postprocessing/RenderPass.js";34 import { BokehPass } from "three/addons/postprocessing/BokehPass.js";35 import { OutputPass } from "three/addons/postprocessing/OutputPass.js";36 37 let camera,38 scene,39 renderer,40 stats,41 singleMaterial,42 zmaterial,43 parameters,44 nobjects,45 cubeMaterial;46 47 let mouseX = 0,48 mouseY = 0;49 50 let windowHalfX = window.innerWidth / 2;51 let windowHalfY = window.innerHeight / 2;52 53 let width = window.innerWidth;54 let height = window.innerHeight;55 56 const materials = [],57 objects = [];58 59 const postprocessing = {};60 61 init();62 animate();63 64 function init() {65 const container = document.createElement("div");66 document.body.appendChild(container);67 68 camera = new THREE.PerspectiveCamera(70, width / height, 1, 3000);69 camera.position.z = 200;70 71 scene = new THREE.Scene();72 73 renderer = new THREE.WebGLRenderer();74 renderer.setPixelRatio(window.devicePixelRatio);75 renderer.setSize(width, height);76 container.appendChild(renderer.domElement);77 78 const path = "textures/cube/SwedishRoyalCastle/";79 const format = ".jpg";80 const urls = [81 path + "px" + format,82 path + "nx" + format,83 path + "py" + format,84 path + "ny" + format,85 path + "pz" + format,86 path + "nz" + format,87 ];88 89 const textureCube = new THREE.CubeTextureLoader().load(urls);90 91 parameters = { color: 0xff4900, envMap: textureCube };92 cubeMaterial = new THREE.MeshBasicMaterial(parameters);93 94 singleMaterial = false;95 96 if (singleMaterial) zmaterial = [cubeMaterial];97 98 const geo = new THREE.SphereGeometry(1, 20, 10);99 100 const xgrid = 14,101 ygrid = 9,102 zgrid = 14;103 104 nobjects = xgrid * ygrid * zgrid;105 106 const s = 60;107 let count = 0;108 109 for (let i = 0; i < xgrid; i++) {110 for (let j = 0; j < ygrid; j++) {111 for (let k = 0; k < zgrid; k++) {112 let mesh;113 114 if (singleMaterial) {115 mesh = new THREE.Mesh(geo, zmaterial);116 } else {117 mesh = new THREE.Mesh(118 geo,119 new THREE.MeshBasicMaterial(parameters)120 );121 materials[count] = mesh.material;122 }123 124 const x = 200 * (i - xgrid / 2);125 const y = 200 * (j - ygrid / 2);126 const z = 200 * (k - zgrid / 2);127 128 mesh.position.set(x, y, z);129 mesh.scale.set(s, s, s);130 131 mesh.matrixAutoUpdate = false;132 mesh.updateMatrix();133 134 scene.add(mesh);135 objects.push(mesh);136 137 count++;138 }139 }140 }141 142 initPostprocessing();143 144 renderer.autoClear = false;145 146 stats = new Stats();147 container.appendChild(stats.dom);148 149 container.style.touchAction = "none";150 container.addEventListener("pointermove", onPointerMove);151 152 window.addEventListener("resize", onWindowResize);153 154 const effectController = {155 focus: 500.0,156 aperture: 5,157 maxblur: 0.01,158 };159 160 const matChanger = function () {161 postprocessing.bokeh.uniforms["focus"].value = effectController.focus;162 postprocessing.bokeh.uniforms["aperture"].value =163 effectController.aperture * 0.00001;164 postprocessing.bokeh.uniforms["maxblur"].value =165 effectController.maxblur;166 };167 168 const gui = new GUI();169 gui 170 .add(effectController, "focus", 10.0, 3000.0, 10)171 .onChange(matChanger);172 gui.add(effectController, "aperture", 0, 10, 0.1).onChange(matChanger);173 gui 174 .add(effectController, "maxblur", 0.0, 0.01, 0.001)175 .onChange(matChanger);176 gui.close();177 178 matChanger();179 }180 181 function onPointerMove(event) {182 if (event.isPrimary === false) return;183 184 mouseX = event.clientX - windowHalfX;185 mouseY = event.clientY - windowHalfY;186 }187 188 function onWindowResize() {189 windowHalfX = window.innerWidth / 2;190 windowHalfY = window.innerHeight / 2;191 192 width = window.innerWidth;193 height = window.innerHeight;194 195 camera.aspect = width / height;196 camera.updateProjectionMatrix();197 198 renderer.setSize(width, height);199 postprocessing.composer.setSize(width, height);200 }201 202 function initPostprocessing() {203 const renderPass = new RenderPass(scene, camera);204 205 const bokehPass = new BokehPass(scene, camera, {206 focus: 1.0,207 aperture: 0.025,208 maxblur: 0.01,209 });210 211 const outputPass = new OutputPass();212 213 const composer = new EffectComposer(renderer);214 215 composer.addPass(renderPass);216 composer.addPass(bokehPass);217 composer.addPass(outputPass);218 219 postprocessing.composer = composer;220 postprocessing.bokeh = bokehPass;221 }222 223 function animate() {224 requestAnimationFrame(animate, renderer.domElement);225 226 stats.begin();227 render();228 stats.end();229 }230 231 function render() {232 const time = Date.now() * 0.00005;233 234 camera.position.x += (mouseX - camera.position.x) * 0.036;235 camera.position.y += (-mouseY - camera.position.y) * 0.036;236 camera.lookAt(scene.position);237 if (!singleMaterial) {238 for (let i = 0; i < nobjects; i++) {239 const h = ((360 * (i / nobjects + time)) % 360) / 360;240 materials[i].color.setHSL(h, 1, 0.5);241 }242 }243 postprocessing.composer.render(0.1);244 }245 </script>246 247 </body>248</html>249

コメントを投稿

0 コメント