oframe / ogl

Minimal WebGL Library
https://oframe.github.io/ogl/examples
3.71k stars 211 forks source link

WebXR hybrid renderer #216

Open munrocket opened 5 months ago

munrocket commented 5 months ago

Any chances that WebXR will be implemented? Can be a cool 3js alternative for simple UI.

CodyJasonBennett commented 4 months ago

Here's a WebXR example based on https://twitter.com/Cody_J_Bennett/status/1558040614352158722.

image

Show code: ```js import { Renderer, Camera, Geometry, Program, Mesh } from 'ogl' const renderer = new Renderer() const gl = renderer.gl document.body.appendChild(gl.canvas) const camera = new Camera(gl, { fov: 50 }) camera.position.z = 5 const geometry = new Geometry(gl, { position: { size: 3, data: new Float32Array([ 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, ]), }, normal: { size: 3, data: new Float32Array([ 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, ]), }, uv: { size: 2, data: new Float32Array([ 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, ]), }, index: { size: 1, data: new Uint16Array([ 0, 2, 1, 2, 3, 1, 4, 6, 5, 6, 7, 5, 8, 10, 9, 10, 11, 9, 12, 14, 13, 14, 15, 13, 16, 18, 17, 18, 19, 17, 20, 22, 21, 22, 23, 21, ]), }, }) const program = new Program(gl, { uniforms: { color: { value: [1, 0.4, 0.7] }, }, vertex: /* glsl */ `#version 300 es uniform mat3 normalMatrix; uniform mat4 projectionMatrix; uniform mat4 modelViewMatrix; in vec3 position; in vec3 normal; out vec3 vNormal; void main() { vNormal = normalMatrix * normal; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1); } `, fragment: /* glsl */ `#version 300 es precision lowp float; uniform vec3 color; in vec3 vNormal; out vec4 fColor; void main() { float lighting = dot(vNormal, normalize(vec3(10))); fColor = vec4(color + lighting * 0.1, 1); } `, }) const cube = new Mesh(gl, { geometry, program }) function onResize() { renderer.setSize(window.innerWidth, window.innerHeight) camera.perspective({ fov: 50, aspect: window.innerWidth / window.innerHeight }) } onResize() window.addEventListener('resize', onResize) renderer.autoClear = false const button = document.createElement('button') button.textContent = 'Enter VR' document.body.appendChild(button) let session = null let referenceSpace = null let baseLayer = null function render(time, frame) { session ? session.requestAnimationFrame(render) : window.requestAnimationFrame(render) if (frame) { gl.bindFramebuffer(gl.FRAMEBUFFER, baseLayer.framebuffer) gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT) const pose = frame.getViewerPose(referenceSpace) for (const view of pose.views) { const viewport = baseLayer.getViewport(view) renderer.setViewport(viewport.width, viewport.height, viewport.x, viewport.y) camera.matrix.set(...view.transform.matrix) camera.worldMatrixNeedsUpdate = true camera.projectionMatrix.set(...view.projectionMatrix) camera.updateMatrixWorld() renderer.render({ scene: cube, camera }) } } else { gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT) renderer.render({ scene: cube, camera }) } } requestAnimationFrame(render) await gl.makeXRCompatible() button.onclick = async () => { await navigator.xr.isSessionSupported('immersive-vr') session = await navigator.xr.requestSession('immersive-vr', { optionalFeatures: ['local-floor', 'bounded-floor', 'hand-tracking'], }) baseLayer = new XRWebGLLayer(session, gl) session.updateRenderState({ baseLayer }) referenceSpace = await session.requestReferenceSpace('local-floor') camera.matrixAutoUpdate = false } ```
munrocket commented 4 months ago

@CodyJasonBennett nice. Waiting in four examples!