<!DOCTYPE html> <html> <body> <div class="player"> <canvas></canvas> <video src="https://threejs.org/examples/textures/MaryOculus.webm" loop autoplay crossOrigin="" controls="false" style="display: none;"></video> </div> <canvas id="texture-canvas" width="500" height="100" style="display: none;"></canvas> <label>Bug enabled: <input id="toggle-bug" type="checkbox"></label> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.js" integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU=" crossorigin="anonymous"></script> <script type="module"> import * as THREE from 'https://cdnjs.cloudflare.com/ajax/libs/three.js/93/three.module.js'; import { WEBVR } from 'https://threejs.org/examples/jsm/vr/WebVR.js'; // Just a hello world canvas that will be used as a texture const textureCanvas = $('#texture-canvas').get(0); const ctx = textureCanvas.getContext('2d'); ctx.fillStyle = 'white'; ctx.fillRect(0, 0, textureCanvas.width, textureCanvas.height); ctx.fillStyle = 'black'; ctx.font = '30px Arial'; ctx.fillText('Hello world', 20, 60); // Listen change on the checkbox to enable/disable the bug let bugEnabled = false; $('#toggle-bug').on('change', e => { bugEnabled = $(e.target).prop('checked'); }).click(); const _update = THREE.VideoTexture.prototype.update; THREE.VideoTexture.prototype.update = function() { if (bugEnabled) _update.call(this); }; // The player class that contain a video and an "UI" from a canvas texture class Player { constructor() { const $player = $('div.player'); const videoElement = $player.find('video').get(0); this.scene = new THREE.Scene(); this.camera = new THREE.PerspectiveCamera( 70, 0.5, .1, 1000 ); this.renderer = new THREE.WebGLRenderer({ canvas: $player.find('canvas').get(0) }); this.scene.add(this.camera); this.scene.background = new THREE.Color( 'green' ); this.renderer.setPixelRatio( window.devicePixelRatio ); this.renderer.vr.enabled = true; this.addUI(textureCanvas); this.addEnterVRButton(videoElement); this.addVideo(videoElement); window.addEventListener('vrdisplayconnect', () => this.renderer.vr.setDevice(e.display)); this.renderer.setAnimationLoop(() => this.renderer.render(this.scene, this.camera)); } addEnterVRButton(videoElement) { const enterVRButton = $(document.body.appendChild(WEBVR.createButton(this.renderer))); console.log(videoElement, videoElement.play); enterVRButton.on('click', () => videoElement.play()); } addVideo(videoElement) { const geometry = new THREE.SphereGeometry(1000, 32, 32); const texture = new THREE.VideoTexture(videoElement); geometry.scale( -1, 1, 1 ); texture.minFilter = THREE.LinearFilter; texture.magFilter = THREE.LinearFilter; texture.wrapS = THREE.ClampToEdgeWrapping; texture.wrapT = THREE.ClampToEdgeWrapping; texture.format = THREE.RGBFormat; this.scene.add(new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({map: texture}))); } addUI(canvas) { const geometry = new THREE.PlaneGeometry(50, 10); const texture = new THREE.CanvasTexture(canvas); const material = new THREE.MeshBasicMaterial({ map: texture }); const mesh = new THREE.Mesh(geometry, material); mesh.position.set(0, 0, -100); texture.minFilter = THREE.LinearFilter; texture.magFilter = THREE.LinearFilter; texture.wrapS = THREE.ClampToEdgeWrapping; texture.wrapT = THREE.ClampToEdgeWrapping; texture.format = THREE.RGBFormat; texture.generateMipmaps = false; this.scene.add(mesh); } } new Player(); </script> </body> </html>