1. 程式人生 > >72 - three.js 筆記 - 通過 Reflector.js 建立鏡面反射

72 - three.js 筆記 - 通過 Reflector.js 建立鏡面反射

類似境面反射可以使用CubeCamera但是CubeCamera更適用於建立物體自身對環境的反射,但是如果想要建立一面鏡子的話使用CubeCamera會難除錯所反射物體的位置,而且鏡面中的物體不會隨著控制器的縮放而變動。
使用Reflector.js可以很容易的建立一面鏡子,並且鏡子中的物件會依據發光體的縮放而縮放,而且可以除錯鏡子的發光色,類似墨鏡的效果。

1、示例

示例
http://ithanmang.com/threeJs/home/201809/20180907/02-reflector-mirror.html
效果
這裡寫圖片描述

2、使用步驟

2.1、引入js檔案

和建立鏡頭炫光 Lensflare

一樣需要單獨引入

<!-- 匯入 Reflector.js -->
<script src="../../libs/examples/js/objects/Reflector.js"></script>
2.2、建立鏡子形狀
 let planeGeometry = new THREE.PlaneBufferGeometry(10, 10);

此處建立了一個矩形的平面

2.3、配置鏡子引數
let options = {

     clipBias: 0.03,
     textureWidth: window.innerWidth * window.devicePixelRatio,
     textureHeight
: window.innerHeight * window.devicePixelRatio, color: 0x889999, recursion: 1 };
2.4、建立鏡子並加入場景
let mirror = new THREE.Reflector(planeGeometry, options);
scene.add(mirror);

3、示例程式碼

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link
rel="icon" href="../../../three.png">
<title>通過 Reflector 建立反光鏡</title> <style> body { margin: 0; overflow: hidden; /* 溢位隱藏 */ } #loading { position: fixed; top: 50%; left: 50%; color: #FFFFFF; font-size: 20px; margin-top: -30px; margin-left: -40px; } </style> <script src="../../libs/build/three-r93.js"></script> <script src="../../libs/examples/js/Detector.js"></script> <script src="../../libs/examples/js/libs/dat.gui.min.js"></script> <script src="../../libs/examples/js/libs/stats.min.js"></script> <script src="../../libs/examples/js/controls/OrbitControls.js"></script> <!-- 匯入 Reflector.js --> <script src="../../libs/examples/js/objects/Reflector.js"></script> </head> <body> <p id="loading">loading......</p> <script> let scene, camera, renderer, controls, guiControls; let stats = initStats(); /* 場景 */ function initScene() { scene = new THREE.Scene(); scene.background = new THREE.CubeTextureLoader().setPath('../../textures/cube/Bridge2/') .load([ 'posx.jpg', 'negx.jpg', 'posy.jpg', 'negy.jpg', 'posz.jpg', 'negz.jpg' ]); } /* 相機 */ function initCamera() { camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 10000); camera.position.set(-10, 2, 20); camera.lookAt(new THREE.Vector3(0, 0, 0)); } /* 渲染器 */ function initRender() { renderer = new THREE.WebGLRenderer({antialias: true}); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); } /* 燈光 */ function initLight() { scene.add(new THREE.AmbientLight(0x0c0c0c)); let spotLight1 = new THREE.SpotLight(0xffffff); spotLight1.position.set(-400, -400, -400); let spotLight2 = new THREE.SpotLight(0xffffff); spotLight2.position.set(400, 400, 400); scene.add(spotLight1); scene.add(spotLight2); } /* 控制器 */ function initControls() { /* 地圖控制元件 */ controls = new THREE.OrbitControls(camera, renderer.domElement); /* 屬性引數 */ } /* 除錯外掛 */ function initGui() { guiControls = new function () { }; let gui = new dat.GUI(); } /* 場景中的內容 */ let mesh; function initContent() { let loader = new THREE.JSONLoader(); loader.load('../../models/json/uv-standard.json', function (geometry) { let material = new THREE.MeshBasicMaterial(); let texture = new THREE.TextureLoader().load('../../textures/uv/ash_uvgrid01.jpg'); material.map = texture; mesh = new THREE.Mesh(geometry, material); mesh.translateZ(5); scene.add(mesh); removeLoading(); }); let planeGeometry = new THREE.PlaneBufferGeometry(10, 10); let options = { clipBias: 0.03, textureWidth: window.innerWidth * window.devicePixelRatio, textureHeight: window.innerHeight * window.devicePixelRatio, color: 0x889999, recursion: 1 }; let mirror = new THREE.Reflector(planeGeometry, options); scene.add(mirror); } /* 移除載入元素 */ function removeLoading() { document.getElementById('loading').style.display = 'none'; } /* 效能外掛 */ function initStats() { let stats = new Stats(); document.body.appendChild(stats.domElement); return stats; } /* 視窗變動觸發 */ function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); } /* 資料更新 */ function update() { stats.update(); controls.update(); if (mesh) { mesh.rotateX(0.01); mesh.rotateY(0.01); mesh.rotateZ(0.01); } } /* 初始化 */ function init() { initScene(); initCamera(); initRender(); initLight(); initControls(); initContent(); initGui(); /* 監聽事件 */ window.addEventListener('resize', onWindowResize, false); } /* 迴圈渲染 */ function animate() { requestAnimationFrame(animate); renderer.render(scene, camera); update(); } /* 初始載入 */ (function () { console.log("three init start..."); init(); animate(); console.log("three init end..."); })(); </script> </body> </html>