diff --git a/dist/index.html b/dist/index.html index d2702d4da..0b7765778 100644 --- a/dist/index.html +++ b/dist/index.html @@ -21,6 +21,7 @@ + diff --git a/package.json b/package.json index 8428f1f84..81271a01d 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "@pixiv/three-vrm": "^2.1.1", "@pixiv/three-vrm-animation": "^2.1.1", "@pixiv/three-vrm-springbone": "^2.1.1", + "postprocessing": "^6.35.2", "three": "^0.162.0" } } diff --git a/src/index.ts b/src/index.ts index 2c2ef3737..41ef2b08d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,18 +3,19 @@ import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader" import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'; import { VRMLoaderPlugin } from "@pixiv/three-vrm"; import { createVRMAnimationClip, VRMAnimationLoaderPlugin } from "@pixiv/three-vrm-animation"; - -import { Color, DirectionalLight, Fog, HemisphereLight } from 'three'; -import { GridHelper, Mesh, MeshLambertMaterial, BoxGeometry, Vector3 } from 'three'; - +import { GridHelper, Mesh, MeshLambertMaterial, BoxGeometry, Vector3, Vector2, Color, DirectionalLight, Fog, HemisphereLight, HalfFloatType } from 'three'; import { VRMSpringBoneManager, VRMSpringBoneJoint, VRMSpringBoneJointHelper } from '@pixiv/three-vrm-springbone'; - import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader"; +//import { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer'; +//import { UnrealBloomPass } from 'three/examples/jsm/postprocessing/UnrealBloomPass'; +//import { RenderPass } from "three/examples/jsm/postprocessing/RenderPass"; +import { BloomEffect, EffectComposer, EffectPass, RenderPass } from "postprocessing"; window.addEventListener("DOMContentLoaded", () => { // vrma let motion_enable = false; + let head = null; // progress // https://sbcode.net/threejs/progress-indicator @@ -24,27 +25,33 @@ window.addEventListener("DOMContentLoaded", () => { const canvas = document.getElementById("canvas"); if (canvas == null) return; const scene = new THREE.Scene(); + //const camera = new THREE.PerspectiveCamera( 70, canvas.clientWidth/canvas.clientHeight, 0.1, 2000); const camera = new THREE.PerspectiveCamera( 70, canvas.clientWidth/canvas.clientHeight, 0.1, 2000); - camera.position.set(0, 1, -1.5) + camera.position.set(0, 1.5, -1.5) camera.rotation.set(0.0, Math.PI, 0.0) camera.lookAt(new THREE.Vector3(0, 0, 0)); // https://threejs.org/docs/#api/en/constants/Renderer - const renderer = new THREE.WebGLRenderer({antialias: true, alpha: true}); + const renderer = new THREE.WebGLRenderer({ + alpha: true, + powerPreference: "high-performance", + antialias: true, + stencil: false, + //depth: false + }); renderer.setPixelRatio(window.devicePixelRatio); renderer.setSize(canvas.clientWidth, canvas.clientHeight); - renderer.setClearColor(0x7fbfff, 1.0); - renderer.shadowMap.enabled = true; renderer.outputColorSpace = THREE.SRGBColorSpace; renderer.toneMapping = THREE.ReinhardToneMapping; renderer.toneMapping = THREE.NeutralToneMapping; canvas.appendChild(renderer.domElement); renderer.toneMappingExposure = 1.5; - - //renderer.toneMapping = THREE.ACESFilmicToneMapping; + renderer.setClearColor(0xffffff, 1.0); const light = new THREE.DirectionalLight(0xffffff, Math.PI); light.position.set(1.0, 1.0, 1.0); + //light.intensity = -0.8; + //renderer.setClearColor(0x000000, 1.0); scene.add(light); let currentVrm: any = undefined; @@ -63,11 +70,8 @@ window.addEventListener("DOMContentLoaded", () => { const percentComplete = (xhr.loaded / xhr.total) * 100 progressBar.value = percentComplete === Infinity ? 100 : percentComplete }, - (progress) => console.log( - "Loading model...", - 100.0 * (progress.loaded / progress.total), "%" - ), - (error) => console.error(error) + (progress) => console.log( "Loading model...", 100.0 * (progress.loaded / progress.total), "%" ), + (error) => console.error(error) ); } @@ -119,9 +123,10 @@ window.addEventListener("DOMContentLoaded", () => { controls.target.set( 0.0, 1.0, 0.0 ); function floor_default(){ - scene.background = new THREE.Color( 0xffffff ); + scene.background = new THREE.Color(0xffffff); const directionalLight = new THREE.DirectionalLight(0xffffff); directionalLight.position.set(1, 1, 1); + scene.add(directionalLight); const ambientLight = new THREE.AmbientLight(0x333333); scene.add(ambientLight); @@ -144,9 +149,13 @@ window.addEventListener("DOMContentLoaded", () => { scene.fog?.color.set(0xffffff); } - scene.background = new THREE.Color( 0xffffff ); + //scene.background = new THREE.Color(0xffffff); const directionalLight = new THREE.DirectionalLight(0xffffff); directionalLight.position.set(1, 1, 1); + //directionalLight.castShadow = true; + //directionalLight.shadow.radius = 3.0; + //renderer.shadowMap.enabled = true; + //directionalLight.intensity = 0.3; scene.add(directionalLight); const ambientLight = new THREE.AmbientLight(0x333333); scene.add(ambientLight); @@ -168,20 +177,12 @@ window.addEventListener("DOMContentLoaded", () => { camera.updateProjectionMatrix(); } - function animate() { - controls.update(); - const delta = clock.getDelta(); - if (currentMixer) { - currentMixer.update(delta); - } - if (currentVrm) { - currentVrm.update(delta); - } - requestAnimationFrame(animate); - scene.rotation.y += 0.005; - renderer.render(scene, camera); - } - animate(); + // https://github.com/pmndrs/postprocessing + let composer = new EffectComposer(renderer, { + frameBufferType: HalfFloatType + }); + composer.addPass(new RenderPass(scene, camera)); + composer.addPass(new EffectPass(camera, new BloomEffect())); function random_happy() { // https://github.com/vrm-c/vrm-specification/blob/master/specification/VRMC_vrm-1.0/expressions.ja.md @@ -191,11 +192,10 @@ window.addEventListener("DOMContentLoaded", () => { function random_head() { // https://github.com/vrm-c/vrm-specification/blob/master/specification/VRMC_vrm-1.0/lookAt.ja.md currentVrm.lookAt.target = camera; - currentVrm.VRMLookAtBoneApplier = camera; - currentVrm.VRMLookAtExpressionApplier = camera; - + //currentVrm.VRMLookAtBoneApplier = camera; + //currentVrm.VRMLookAtExpressionApplier = camera; // https://github.com/vrm-c/vrm-specification/blob/master/specification/VRMC_vrm-1.0/humanoid.ja.md - const head = currentVrm.humanoid.getRawBoneNode("head"); + head = currentVrm.humanoid.getRawBoneNode("head"); head.target = camera; } @@ -226,21 +226,84 @@ window.addEventListener("DOMContentLoaded", () => { }); } - let light_enable = true; + let light_enable = 0; + let light_max = 4; function light_s(){ - if (light_enable == true) { - light_enable = false; - renderer.toneMapping = THREE.ACESFilmicToneMapping; - light.intensity = -0.5; + if (light_enable >= light_max) { + light_enable = 0; + } + console.log(light_enable); + switch (light_enable) { + case 0: + renderer.toneMapping = THREE.ACESFilmicToneMapping; + light.intensity = -0.8; + renderer.setClearColor(0x000000); scene.background = new THREE.Color(0x000000); scene.fog = new Fog(0x000000, 3, 20); - } else { - light_enable = true; + break; + case 1: + renderer.toneMapping = THREE.NeutralToneMapping; + light.intensity = 1; + scene.background = new THREE.Color(0xffffff); + renderer.setClearColor(0xffffff); + scene.fog = new Fog(0xffffff, 3, 20); + break; + case 2: + renderer.toneMapping = THREE.ReinhardToneMapping; + break; + case 3: + renderer.toneMapping = THREE.ReinhardToneMapping; + renderer.toneMapping = THREE.NeutralToneMapping; + renderer.physicallyCorrectLights = true; + light.intensity = 2; + break; + } + light_enable++; + } + + const el_user = document.querySelector('#btn-user') as HTMLInputElement | null; + if(el_user != null) { + el_user.addEventListener('click', function(){ + user_s(); + }); + } + + let user_enable = 0; + let user_max = 2; + let anime_id; + function user_s(){ + if (user_enable >= user_max) { + user_enable = 0; + } + console.log(user_enable); + switch (user_enable) { + case 0: + load("/vrma/ai_eya.vrm"); + scene.remove(currentVrm.scene); + light.intensity = -0.8; + renderer.setClearColor(0x000000); + scene.remove(grid); + scene.background = new THREE.Color(0x000000); + scene.fog = new Fog(0x000000, 3, 20); + requestAnimationFrame(function render() { + anime_id = requestAnimationFrame(render); + composer.render(); + }); + break; + case 1: + cancelAnimationFrame(anime_id); + scene.add(grid); + load("/vrma/ai.vrm"); + scene.remove(currentVrm.scene); renderer.toneMapping = THREE.NeutralToneMapping; light.intensity = 1; scene.background = new THREE.Color(0xffffff); + renderer.setClearColor(0xffffff); scene.fog = new Fog(0xffffff, 3, 20); + break; } + user_enable++; + } const el_hdr = document.querySelector('#btn-sandar') as HTMLInputElement | null; @@ -344,4 +407,19 @@ window.addEventListener("DOMContentLoaded", () => { }, 10000); }, 15000); + animate(); + function animate() { + controls.update(); + const delta = clock.getDelta(); + if (currentMixer) { + currentMixer.update(delta); + } + if (currentVrm) { + currentVrm.update(delta); + } + requestAnimationFrame(animate); + scene.rotation.y += 0.005; + renderer.render(scene, camera); + } + })