UNPKG

webvr-dom

Version:

A shim to support DOM rendering for VR devices

1 lines 7.99 kB
!function(e){"function"==typeof define&&define.amd?define("webvr-dom",[],e):"object"==typeof module&&module&&"object"==typeof module.exports?module.exports=e:e(this.window,this.document)}(function(e,t){function r(e,t){this.el=e,this.options=t;var r=this.getHTML(),i=this.getStyles();return this.drawImage({html:r,styles:i}),this}function i(r,i){this.el=r,this.options=i;var n=t.createElement("canvas");n.id="webvr-dom",n.width=1280,n.height=800,n.style.position="absolute",n.style.top=0,n.style.width="100%",n.style.height="100%",n.style.zIndex=9999,n.crossOrigin="anonymous",this.el.appendChild(n);var a;return e.WebGLRenderingContext?a=n.getContext("webgl"):e.location="http://get.webgl.org",a?(this.gl=a,void 0):o("WebGL context not available")}function o(e){console.log(e)}function n(){var e=Array.prototype.slice.call(arguments),t={};for(var r in e){var i=e[r];for(var o in i)i[o]&&i[o].constructor&&i[o].constructor===Object?(t[o]=t[o]||{},t[o]=arguments.callee(t[o],i[o])):t[o]=i[o]}return t}e.requestAnimationFrame=e.requestAnimationFrame||e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame||e.msRequestAnimationFrame;var a=e.URL||e.webkitURL||e,s={"distortion.fs":"precision highp float; uniform sampler2D texture; uniform vec2 LensCenter; uniform vec2 ScreenCenter; uniform vec2 Scale; uniform vec2 ScaleIn; uniform vec4 HmdWarpParam; varying vec2 oTexCoord; vec2 HmdWarp(vec2 in01) { vec2 theta = (in01 - LensCenter) * ScaleIn; float rSq = theta.x * theta.x + theta.y * theta.y; vec2 rvector = theta * (HmdWarpParam.x + HmdWarpParam.y * rSq + HmdWarpParam.z * rSq * rSq + HmdWarpParam.w * rSq * rSq * rSq); return LensCenter + Scale * rvector; } void main() { vec2 tc = HmdWarp(oTexCoord); if (any(bvec2(clamp(tc,ScreenCenter-vec2(0.25,0.5), ScreenCenter+vec2(0.25,0.5)) - tc))) { gl_FragColor = vec4(vec3(0.0), 1.0); return; } gl_FragColor = texture2D(texture, tc); } ","distortion.vs":"attribute vec2 coord; varying vec2 oTexCoord; void main() { oTexCoord = coord; gl_Position = vec4((coord-vec2(0.5))*2.0, 0.0, 1.0); } ","texture.fs":"precision highp float; uniform sampler2D texture; varying vec2 texCoord; void main() { gl_FragColor = texture2D(texture, texCoord); } ","texture.vs":"attribute vec2 pos; attribute vec2 coord; uniform vec2 offset; varying vec2 texCoord; void main() { texCoord = coord; gl_Position = vec4(pos + offset, 0.0, 1.0); } "},c={update:!0};r.prototype.getHTML=function(){var e=this.el.innerHTML;return e=e.replace(/<!--[\s\S]*?-->/gi,""),e=e.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,"")},r.prototype.getStyles=function(){var e="";return e},r.prototype.drawImage=function(e){var r=this,i='<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%"><foreignObject width="100%" height="100%"><div xmlns="http://www.w3.org/1999/xhtml">'+e.html+"</div>"+"</foreignObject>"+"</svg>",o=new Blob([i],{type:"image/svg+xml;charset=utf-8"}),n=a.createObjectURL(o);img=new Image,img.crossOrigin="anonymous",img.crossOrigin="http://profile.ak.fbcdn.net/crossdomain.xml",img.width=1280,img.height=800,img.onload=function(){var e=t.createElement("canvas");e.id="dom",e.width=1280,e.height=800,e.crossOrigin="anonymous";var i=e.getContext("2d");i.drawImage(img,0,0),a.revokeObjectURL(n);var o=new CustomEvent("render",{detail:null});r.el.dispatchEvent(o)},img.src=n},i.prototype.draw=function(e){var r=(t.getElementById("webvr-dom"),this.gl);this.left={source:null,texture:this.initTexture(r)},this.right={source:null,texture:this.initTexture(r)},this.left.source=e,this.right.source=e,this.position=this.initPosition(),this.distortion=this.initDistortion(),this.update()},i.prototype.createShader=function(e,t,r){var i=e.createShader(r);return e.shaderSource(i,t),e.compileShader(i),i},i.prototype.createProgram=function(e,t,r){var i=e.createProgram(),o=this.createShader(e,t,e.VERTEX_SHADER),n=this.createShader(e,r,e.FRAGMENT_SHADER);return e.attachShader(i,o),e.attachShader(i,n),e.linkProgram(i),i},i.prototype.initTexture=function(e){var t=e.createTexture();return e.bindTexture(e.TEXTURE_2D,t),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),t},i.prototype.initPosition=function(){var e=this.gl,t=e.createBuffer();e.bindBuffer(e.ARRAY_BUFFER,t);var r=[-1,-1,0,0,0,-1,1,0,-1,1,0,1,0,1,1,1];e.bufferData(e.ARRAY_BUFFER,new Float32Array(r),e.STATIC_DRAW);var i=s["texture.vs"],o=s["texture.fs"],n=this.createProgram(e,i,o);return e.useProgram(n),n.vertexPosAttrib=e.getAttribLocation(n,"pos"),e.enableVertexAttribArray(n.vertexPosAttrib),e.vertexAttribPointer(n.vertexPosAttrib,2,e.FLOAT,!1,16,0),n.vertexCoordAttrib=e.getAttribLocation(n,"coord"),e.enableVertexAttribArray(n.vertexCoordAttrib),e.vertexAttribPointer(n.vertexCoordAttrib,2,e.FLOAT,!1,16,8),e.uniform1i(e.getUniformLocation(n,"texture"),0),n},i.prototype.initDistortion=function(){var e=this.gl,t=e.createFramebuffer();e.bindFramebuffer(e.FRAMEBUFFER,t);var r=e.createTexture();e.bindTexture(e.TEXTURE_2D,r),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE);var i=1280,o=800;e.texImage2D(e.TEXTURE_2D,0,e.RGBA,i,o,0,e.RGBA,e.UNSIGNED_BYTE,null),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,r,0);var n=s["distortion.vs"],a=s["distortion.fs"],c=this.createProgram(e,n,a);return e.useProgram(c),c.vertexCoordAttrib=e.getAttribLocation(c,"coord"),e.enableVertexAttribArray(c.vertexCoordAttrib),e.vertexAttribPointer(c.vertexCoordAttrib,2,e.FLOAT,!1,16,8),e.uniform1i(e.getUniformLocation(c,"texture"),0),{buffer:t,texture:r,program:c}},i.prototype.updateEye=function(e,t){e.bindTexture(e.TEXTURE_2D,t.texture),e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL,!0),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,t.source)},i.prototype.update=function(){var e=this.gl,t=this.position,r=this.distortion;this.updateEye(e,this.left),this.updateEye(e,this.right),e.bindFramebuffer(e.FRAMEBUFFER,r.buffer),e.useProgram(t),e.uniform2f(e.getUniformLocation(t,"offset"),0,0),e.bindTexture(e.TEXTURE_2D,this.left.texture),e.drawArrays(e.TRIANGLE_STRIP,0,4),e.uniform2f(e.getUniformLocation(t,"offset"),1,0),e.bindTexture(e.TEXTURE_2D,this.right.texture),e.drawArrays(e.TRIANGLE_STRIP,0,4),e.bindFramebuffer(e.FRAMEBUFFER,null),e.clear(e.COLOR_BUFFER_BIT),e.useProgram(r.program),e.bindTexture(e.TEXTURE_2D,r.texture),e.uniform2f(e.getUniformLocation(r.program,"Scale"),.1469278,.2350845),e.uniform2f(e.getUniformLocation(r.program,"ScaleIn"),4,2.5),e.uniform4f(e.getUniformLocation(r.program,"HmdWarpParam"),1,.22,.24,0),e.enable(e.SCISSOR_TEST),e.scissor(0,0,640,800),e.uniform2f(e.getUniformLocation(r.program,"LensCenter"),.2863248,.5),e.uniform2f(e.getUniformLocation(r.program,"ScreenCenter"),.25,.5),e.drawArrays(e.TRIANGLE_STRIP,0,4),e.scissor(640,0,640,800),e.uniform2f(e.getUniformLocation(r.program,"LensCenter"),.7136753,.5),e.uniform2f(e.getUniformLocation(r.program,"ScreenCenter"),.75,.5),e.drawArrays(e.TRIANGLE_STRIP,0,4),e.disable(e.SCISSOR_TEST)};var u=function(e){e=e||{},this.el=e.el||t.getElementsByTagName("body")[0],delete e.el,this.options=n({},c,e);var o=this;this.raster=new r(this.el,this.options),this.shader=new i(this.el,this.options),this.el.addEventListener("render",function(e){o.hideDOM(),o.shader.draw(e.detail)},!1)};u.prototype.update=function(){this.shader.update(),requestAnimationFrame(this.update.bind(this))},u.prototype.hideDOM=function(){for(var e=this.el,t=0;t<this.el.childNodes.length;t++){var r=e.childNodes[t];if(1===r.nodeType){var i=r.tagName.toLowerCase();"script"==i||"canvas"==i&&"webvr-dom"==r.id||(r.style.visibility="hidden")}}},e.VRDOM=e.VRDOM||function(e){new u(e)}});