rgbd 0.0.9 → 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/rgbd.js +86 -85
- package/package.json +1 -1
package/dist/rgbd.js
CHANGED
|
@@ -1,86 +1,87 @@
|
|
|
1
|
-
const
|
|
2
|
-
precision mediump float;
|
|
3
|
-
precision mediump int;
|
|
4
|
-
|
|
5
|
-
uniform sampler2D u_depthImage;
|
|
6
|
-
uniform mat4 u_projMat;
|
|
7
|
-
uniform mat4 u_viewMat;
|
|
8
|
-
uniform vec2 u_imageSize;
|
|
9
|
-
uniform float u_focal;
|
|
10
|
-
uniform float u_depthMin;
|
|
11
|
-
uniform float u_depthMax;
|
|
12
|
-
uniform ivec2 u_grid;
|
|
13
|
-
|
|
14
|
-
out vec2 v_uv;
|
|
15
|
-
|
|
16
|
-
void main()
|
|
17
|
-
{
|
|
18
|
-
int vid = gl_VertexID;
|
|
19
|
-
int quad = vid / 6;
|
|
20
|
-
int v = vid - quad * 6;
|
|
21
|
-
|
|
22
|
-
int widthGrid = u_grid.x;
|
|
23
|
-
int heightGrid = u_grid.y;
|
|
24
|
-
|
|
25
|
-
int x = quad % widthGrid;
|
|
26
|
-
int y = quad / widthGrid;
|
|
27
|
-
|
|
28
|
-
float fx = float(x) / float(widthGrid);
|
|
29
|
-
float fy = float(y) / float(heightGrid);
|
|
30
|
-
float fx1 = float(x + 1) / float(widthGrid);
|
|
31
|
-
float fy1 = float(y + 1) / float(heightGrid);
|
|
32
|
-
|
|
33
|
-
vec2 uv00 = vec2(fx , 1.0 - fy);
|
|
34
|
-
vec2 uv10 = vec2(fx1, 1.0 - fy);
|
|
35
|
-
vec2 uv01 = vec2(fx , 1.0 - fy1);
|
|
36
|
-
vec2 uv11 = vec2(fx1, 1.0 - fy1);
|
|
37
|
-
|
|
38
|
-
vec2 uv;
|
|
39
|
-
if (v == 0) uv = uv00;
|
|
40
|
-
else if (v == 1) uv = uv10;
|
|
41
|
-
else if (v == 2) uv = uv01;
|
|
42
|
-
else if (v == 3) uv = uv10;
|
|
43
|
-
else if (v == 4) uv = uv11;
|
|
44
|
-
else uv = uv01;
|
|
1
|
+
const x=typeof window<"u"&&typeof HTMLElement<"u"&&typeof document<"u";let d,m,p;if(!x)d=class{},m=class{},p=class{};else{const S=`#version 300 es
|
|
45
2
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
`,this._shadowRoot.appendChild(e),this._canvas=document.createElement("canvas"),this._canvas.style.width="100%",this._canvas.style.height="100%",this._canvas.style.objectFit="contain",this._canvas.setAttribute("role","img"),this._canvas.setAttribute("aria-label","3D image"),t.appendChild(this._canvas),this._onResizeHandler=this._onResize.bind(this),this._onMouseMoveHandler=this._onMouseMove.bind(this),this._onMouseLeaveHandler=this._onMouseLeave.bind(this),this._onRenderHandler=this._onRender.bind(this)}connectedCallback(){this._readParams();let t;try{this._init(),t=!1}catch{t=!0}window.addEventListener("resize",this._onResizeHandler),window.addEventListener("mousemove",this._onMouseMoveHandler),document.addEventListener("mouseleave",this._onMouseLeaveHandler),this._loadSources(),t?this._createFallback():(this._onResize(),this._running=!0,this._lastTime=performance.now(),this._animFrame=requestAnimationFrame(this._onRenderHandler))}disconnectedCallback(){this._running=!1,cancelAnimationFrame(this._animFrame),window.removeEventListener("resize",this._onResizeHandler),this._canvas.removeEventListener("pointermove",this._onMouseMoveHandler),this._canvas.removeEventListener("pointerleave",this._onMouseLeaveHandler);try{if(this._gl){const t=this._gl;this._shaderProgram&&t.deleteProgram(this._shaderProgram);for(let e in this._textures)t.deleteTexture(this._textures[e])}}catch{}}setViewMatrix(t){this._userViewMat=t&&t.length===16?new Float32Array(t):null}setProjectionMatrix(t){this._userProjMat=t&&t.length===16?new Float32Array(t):null}get width(){return this._getSourceWidth(this._colorSource)}get height(){return this._getSourceHeight(this._colorSource)}_init(){const t=this._canvas.getContext("webgl2",{antialias:!0,alpha:!1});if(!t)throw new Error("WebGL not supported");this._gl=t;const e=this._createProgram(t,g,v);if(!e)return;this._shaderProgram=e,t.useProgram(e);const o=this._createTexture(t),i=this._createTexture(t);this._textures.color=o,this._textures.depth=i,this._updateTexture("color",this._colorSource),this._updateTexture("depth",this._depthSource);const r=t.getUniformLocation(e,"u_colorImage"),a=t.getUniformLocation(e,"u_depthImage");t.uniform1i(r,0),t.uniform1i(a,1),this._uniforms={uProjection:t.getUniformLocation(e,"u_projMat"),uView:t.getUniformLocation(e,"u_viewMat"),uImageSize:t.getUniformLocation(e,"u_imageSize"),uFocal:t.getUniformLocation(e,"u_focal"),uDepthMin:t.getUniformLocation(e,"u_depthMin"),uDepthMax:t.getUniformLocation(e,"u_depthMax"),uGridSegs:t.getUniformLocation(e,"u_grid"),uTargetRes:t.getUniformLocation(e,"u_targetRes"),uDiscardCutoff:t.getUniformLocation(e,"u_discardCutoff")}}_onRender(t){if(!this._running||!this._gl)return;const e=this._gl,o=t-this._lastTime;this._lastTime=t,this._updateTexturesIfNeeded(),e.clearColor(...this._params.BACKGROUND_COLOR,1),e.clear(e.COLOR_BUFFER_BIT|e.DEPTH_BUFFER_BIT),e.enable(e.DEPTH_TEST),this._mouse.hovered||(this._mouse.x=Math.sin(t*this._params.BOOMERANG_SPEED),this._mouse.y=Math.sin(t*this._params.BOOMERANG_SPEED*.5+Math.PI));const i=this._mouse.x*this._params.CAM_MAX_THETA+Math.PI,r=-this._mouse.y*this._params.CAM_MAX_PHI,a=this._mouse.hovered?this._params.CAM_RADIUS*.8:this._params.CAM_RADIUS;this._anim.theta=this._animate(i,this._anim.theta,o),this._anim.phi=this._animate(r,this._anim.phi,o),this._anim.radius=this._animate(a,this._anim.radius,o);const c=this._canvas.width/this._canvas.height,h=Math.max(1,Math.floor(this._params.GRID_SIZE)),n=Math.max(1,Math.round(h/c)),s=this._getSourceWidth(this._colorSource),u=this._getSourceHeight(this._colorSource);e.uniform2f(this._uniforms.uImageSize,s,u),e.uniform1f(this._uniforms.uFocal,this._params.FOCAL_LENGTH),e.uniform1f(this._uniforms.uDepthMin,this._params.DEPTH_MIN),e.uniform1f(this._uniforms.uDepthMax,this._params.DEPTH_MAX),e.uniform2i(this._uniforms.uGridSegs,h,n),e.uniform2f(this._uniforms.uTargetRes,this._canvas.width,this._canvas.height),e.uniform1f(this._uniforms.uDiscardCutoff,this._params.DISCARD_CUTOFF);const _=[this._anim.radius*Math.cos(this._anim.phi)*Math.sin(this._anim.theta),this._anim.radius*Math.sin(this._anim.phi),this._params.CAM_RADIUS+this._anim.radius*Math.cos(this._anim.phi)*Math.cos(this._anim.theta)],d=[0,0,this._params.CAM_RADIUS],p=[0,-1,0],f=this._userViewMat||new Float32Array(this._lookAt(_,d,p)),S=this._userProjMat||new Float32Array(this._perspective(this._params.CAM_FOV,c,.1,100));e.uniformMatrix4fv(this._uniforms.uView,!1,f),e.uniformMatrix4fv(this._uniforms.uProjection,!1,S),e.drawArrays(e.TRIANGLES,0,h*n*6),this._animFrame=requestAnimationFrame(this._onRenderHandler)}_onMouseMove(t){const e=this._canvas.getBoundingClientRect();this._mouse.hovered=!0,this._mouse.x=(t.clientX-e.left)/e.width*2-1,this._mouse.y=(t.clientY-e.top)/e.height*2-1}_onMouseLeave(){this._mouse.hovered=!1}_onResize(){const t=window.devicePixelRatio||1,e=this._canvas.parentElement;if(!e)return;const o=e.clientWidth,i=e.clientHeight;let r=this._getSourceWidth(this._colorSource)||1,a=this._getSourceHeight(this._colorSource)||1;const c=r/a;let h=o,n=h/c;n>i&&(n=i,h=n*c);const s=Math.max(1,Math.floor(h*t)),u=Math.max(1,Math.floor(n*t));this._canvas.width=s,this._canvas.height=u,this._gl&&this._gl.viewport(0,0,s,u)}_readParams(){const t=this._params;if(this.hasAttribute("grid-size")&&(t.GRID_SIZE=parseInt(this.getAttribute("grid-size"))??t.GRID_SIZE),this.hasAttribute("focal-length")&&(t.FOCAL_LENGTH=parseFloat(this.getAttribute("focal-length"))??t.FOCAL_LENGTH),this.hasAttribute("depth-min")&&(t.DEPTH_MIN=parseFloat(this.getAttribute("depth-min"))??t.DEPTH_MIN),this.hasAttribute("depth-max")&&(t.DEPTH_MAX=parseFloat(this.getAttribute("depth-max"))??t.DEPTH_MAX),this.hasAttribute("discard-cutoff")&&(t.DISCARD_CUTOFF=parseFloat(this.getAttribute("discard-cutoff"))??t.DISCARD_CUTOFF),this.hasAttribute("cam-radius")&&(t.CAM_RADIUS=parseFloat(this.getAttribute("cam-radius"))??t.CAM_RADIUS),this.hasAttribute("cam-max-theta")&&(t.CAM_MAX_THETA=parseFloat(this.getAttribute("cam-max-theta"))??t.CAM_MAX_THETA),this.hasAttribute("cam-max-phi")&&(t.CAM_MAX_PHI=parseFloat(this.getAttribute("cam-max-phi"))??t.CAM_MAX_PHI),this.hasAttribute("cam-fov")&&(t.CAM_FOV=parseFloat(this.getAttribute("cam-fov"))??t.CAM_FOV),this.hasAttribute("cam-smoothness")&&(t.CAM_SMOOTHNESS=parseFloat(this.getAttribute("cam-smoothness"))??t.CAM_SMOOTHNESS),this.hasAttribute("boomerang-speed")&&(t.BOOMERANG_SPEED=parseFloat(this.getAttribute("boomerang-speed"))??t.BOOMERANG_SPEED),this.hasAttribute("background-color"))try{const e=this.getAttribute("background-color").split(",").map(Number);e.length===3&&(t.BACKGROUND_COLOR=e)}catch{}}_createShader(t,e,o){const i=t.createShader(e);return t.shaderSource(i,o),t.compileShader(i),t.getShaderParameter(i,t.COMPILE_STATUS)?i:(console.error(t.getShaderInfoLog(i)),t.deleteShader(i),null)}_createProgram(t,e,o){const i=this._createShader(t,t.VERTEX_SHADER,e),r=this._createShader(t,t.FRAGMENT_SHADER,o);if(!i||!r)return null;const a=t.createProgram();return t.attachShader(a,i),t.attachShader(a,r),t.linkProgram(a),t.getProgramParameter(a,t.LINK_STATUS)?(t.deleteShader(i),t.deleteShader(r),a):(console.error(t.getProgramInfoLog(a)),t.deleteProgram(a),null)}_createTexture(t){const e=t.createTexture();return t.bindTexture(t.TEXTURE_2D,e),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.LINEAR),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.LINEAR),e}_updateTexture(t,e){if(!this._gl)return;const o=this._gl,i=this._textures[t];if(o.activeTexture(t==="color"?o.TEXTURE0:o.TEXTURE1),o.bindTexture(o.TEXTURE_2D,i),!this._isSourceReady(e)){o.texImage2D(o.TEXTURE_2D,0,o.RGBA,1,1,0,o.RGBA,o.UNSIGNED_BYTE,new Uint8Array([0,0,0,0]));return}try{o.pixelStorei(o.UNPACK_FLIP_Y_WEBGL,!1),o.texImage2D(o.TEXTURE_2D,0,o.RGBA,o.RGBA,o.UNSIGNED_BYTE,e)}catch{}}_perspective(t,e,o,i){const r=1/Math.tan(t/2);return[r/e,0,0,0,0,r,0,0,0,0,(i+o)/(o-i),-1,0,0,2*i*o/(o-i),0]}_lookAt(t,e,o){function i(s){const u=Math.hypot(...s)||1;return s.map(_=>_/u)}function r(s,u){return[s[1]*u[2]-s[2]*u[1],s[2]*u[0]-s[0]*u[2],s[0]*u[1]-s[1]*u[0]]}function a(s,u){return s.map((_,d)=>_-u[d])}const c=i(a(t,e)),h=i(r(o,c)),n=r(c,h);return[h[0],n[0],c[0],0,h[1],n[1],c[1],0,h[2],n[2],c[2],0,-(h[0]*t[0]+h[1]*t[1]+h[2]*t[2]),-(n[0]*t[0]+n[1]*t[1]+n[2]*t[2]),-(c[0]*t[0]+c[1]*t[1]+c[2]*t[2]),1]}_animate(t,e,o){const i=(1-this._params.CAM_SMOOTHNESS)*o/16.67,r=Math.sign(t-e);return e+=(t-e)*i,Math.sign(t-e)!==r&&(e=t),e}_loadSources(){throw new Error("Must implement _loadSources")}_createFallback(){throw new Error("Must implement _createFallback")}_updateTexturesIfNeeded(){}_isSourceReady(t){throw new Error("Must implement _isSourceReady")}_getSourceWidth(t){throw new Error("Must implement _getSourceWidth")}_getSourceHeight(t){throw new Error("Must implement _getSourceHeight")}}class A extends m{static get observedAttributes(){return["color-src","depth-src","color-id","depth-id","grid-size","focal-length","depth-min","depth-max","discard-cutoff","cam-radius","cam-max-theta","cam-max-phi","cam-fov","cam-smoothness","boomerang-speed","background-color"]}constructor(){super(),this._colorSource=new Image,this._depthSource=new Image,this._colorSource.crossOrigin="anonymous",this._depthSource.crossOrigin="anonymous"}attributeChangedCallback(t,e,o){if(e!==o)if(t==="color-src")this._colorSource.src=o||"";else if(t==="depth-src")this._depthSource.src=o||"";else if(t==="color-id"){const i=document.getElementById(o);i instanceof HTMLImageElement&&(this._colorSource=i,i.complete?this._updateTexture("color",i):i.addEventListener("load",()=>this._updateTexture("color",i)))}else if(t==="depth-id"){const i=document.getElementById(o);i instanceof HTMLImageElement&&(this._depthSource=i,i.complete?this._updateTexture("depth",i):i.addEventListener("load",()=>this._updateTexture("depth",i)))}else this._readParams()}_loadSources(){const t=this.getAttribute("color-id"),e=this.getAttribute("depth-id"),o=this.getAttribute("color-src"),i=this.getAttribute("depth-src");if(t){const r=document.getElementById(t);r instanceof HTMLImageElement&&r.complete?(this._colorSource=r,this._updateTexture("color",this._colorSource)):r&&(r.addEventListener("load",()=>this._updateTexture("color",r)),this._colorSource=r)}else o&&(this._colorSource.src=o,this._colorSource.onload=()=>this._updateTexture("color",this._colorSource));if(e){const r=document.getElementById(e);r instanceof HTMLImageElement&&r.complete?(this._depthSource=r,this._updateTexture("depth",this._depthSource)):r&&(r.addEventListener("load",()=>this._updateTexture("depth",r)),this._depthSource=r)}else i&&(this._depthSource.src=i,this._depthSource.onload=()=>this._updateTexture("depth",this._depthSource))}_createFallback(){this.getAttribute("color-id")&&(this._colorSource=this._colorSource.cloneNode(),this._colorSource.id+="_threedad-img"),this._colorSource.style.display="block",this._colorSource.classList.add("cover-img"),this._canvas.parentElement.appendChild(this._colorSource)}_isSourceReady(t){return t&&t.complete&&t.naturalWidth>0}_getSourceWidth(t){return t?t.width:1}_getSourceHeight(t){return t?t.height:1}}class E extends m{static get observedAttributes(){return["color-src","depth-src","color-id","depth-id","grid-size","focal-length","depth-min","depth-max","discard-cutoff","cam-radius","cam-max-theta","cam-max-phi","cam-fov","cam-smoothness","boomerang-speed","background-color","autoplay","loop","muted"]}constructor(){super(),this._colorSource=document.createElement("video"),this._depthSource=document.createElement("video"),this._colorSource.crossOrigin="anonymous",this._depthSource.crossOrigin="anonymous",this._colorSource.playsInline=!0,this._depthSource.playsInline=!0,this._colorSource.muted=!0,this._depthSource.muted=!0}attributeChangedCallback(t,e,o){if(e!==o)if(t==="color-src")this._colorSource.src=o||"";else if(t==="depth-src")this._depthSource.src=o||"";else if(t==="color-id"){const i=document.getElementById(o);i instanceof HTMLVideoElement&&(this._colorSource=i,i.readyState>=i.HAVE_CURRENT_DATA?this._updateTexture("color",i):i.addEventListener("loadeddata",()=>this._updateTexture("color",i)))}else if(t==="depth-id"){const i=document.getElementById(o);i instanceof HTMLVideoElement&&(this._depthSource=i,i.readyState>=i.HAVE_CURRENT_DATA?this._updateTexture("depth",i):i.addEventListener("loadeddata",()=>this._updateTexture("depth",i)))}else t==="autoplay"?(this._colorSource.autoplay=this.hasAttribute("autoplay"),this._depthSource.autoplay=this.hasAttribute("autoplay")):t==="loop"?(this._colorSource.loop=this.hasAttribute("loop"),this._depthSource.loop=this.hasAttribute("loop")):t==="muted"?(this._colorSource.muted=this.hasAttribute("muted"),this._depthSource.muted=this.hasAttribute("muted")):this._readParams()}play(){return Promise.all([this._colorSource?.play(),this._depthSource?.play()])}pause(){this._colorSource?.pause(),this._depthSource?.pause()}get paused(){return this._colorSource?this._colorSource.paused:!0}get currentTime(){return this._colorSource?this._colorSource.currentTime:0}set currentTime(t){console.log(t),this._colorSource&&(this._colorSource.currentTime=t),this._depthSource&&(this._depthSource.currentTime=t)}_loadSources(){const t=this.getAttribute("color-id"),e=this.getAttribute("depth-id"),o=this.getAttribute("color-src"),i=this.getAttribute("depth-src");if(this.hasAttribute("autoplay")&&(this._colorSource.autoplay=!0,this._depthSource.autoplay=!0),this.hasAttribute("loop")&&(this._colorSource.loop=!0,this._depthSource.loop=!0),this.hasAttribute("muted")&&(this._colorSource.muted=!0,this._depthSource.muted=!0),t){const r=document.getElementById(t);r instanceof HTMLVideoElement&&(this._colorSource=r)}else o&&(this._colorSource.src=o);if(e){const r=document.getElementById(e);r instanceof HTMLVideoElement&&(this._depthSource=r)}else i&&(this._depthSource.src=i);this.hasAttribute("autoplay")?this.play().then(()=>{this._onResize()}):this.play().then(()=>{this.pause(),this._onResize()})}_createFallback(){this.getAttribute("color-id")&&(this._colorSource=this._colorSource.cloneNode(!0),this._colorSource.id+="_threedad-video"),this._colorSource.style.display="block",this._colorSource.classList.add("cover-video"),this._colorSource.controls=!0,this._canvas.parentElement.appendChild(this._colorSource)}_updateTexturesIfNeeded(){this._isSourceReady(this._colorSource)&&this._updateTexture("color",this._colorSource),this._isSourceReady(this._depthSource)&&this._updateTexture("depth",this._depthSource),Math.abs(this._colorSource.currentTime-this._depthSource.currentTime)>.01&&(this._depthSource.currentTime=this._colorSource.currentTime,this._colorSource.paused!==this._depthSource.paused&&(this._colorSource.paused?this._depthSource.pause():this._depthSource.play()))}_isSourceReady(t){return t&&t.readyState>=t.HAVE_CURRENT_DATA}_getSourceWidth(t){return t?t.videoWidth:1}_getSourceHeight(t){return t?t.videoHeight:1}}typeof window<"u"&&typeof customElements<"u"&&(customElements.define("rgbd-img",A),customElements.define("rgbd-video",E));
|
|
3
|
+
precision mediump float;
|
|
4
|
+
precision mediump int;
|
|
5
|
+
|
|
6
|
+
uniform sampler2D u_depthImage;
|
|
7
|
+
uniform mat4 u_projMat;
|
|
8
|
+
uniform mat4 u_viewMat;
|
|
9
|
+
uniform vec2 u_imageSize;
|
|
10
|
+
uniform float u_focal;
|
|
11
|
+
uniform float u_depthMin;
|
|
12
|
+
uniform float u_depthMax;
|
|
13
|
+
uniform ivec2 u_grid;
|
|
14
|
+
|
|
15
|
+
out vec2 v_uv;
|
|
16
|
+
|
|
17
|
+
void main()
|
|
18
|
+
{
|
|
19
|
+
int vid = gl_VertexID;
|
|
20
|
+
int quad = vid / 6;
|
|
21
|
+
int v = vid - quad * 6;
|
|
22
|
+
|
|
23
|
+
int widthGrid = u_grid.x;
|
|
24
|
+
int heightGrid = u_grid.y;
|
|
25
|
+
|
|
26
|
+
int x = quad % widthGrid;
|
|
27
|
+
int y = quad / widthGrid;
|
|
28
|
+
|
|
29
|
+
float fx = float(x) / float(widthGrid);
|
|
30
|
+
float fy = float(y) / float(heightGrid);
|
|
31
|
+
float fx1 = float(x + 1) / float(widthGrid);
|
|
32
|
+
float fy1 = float(y + 1) / float(heightGrid);
|
|
33
|
+
|
|
34
|
+
vec2 uv00 = vec2(fx , 1.0 - fy);
|
|
35
|
+
vec2 uv10 = vec2(fx1, 1.0 - fy);
|
|
36
|
+
vec2 uv01 = vec2(fx , 1.0 - fy1);
|
|
37
|
+
vec2 uv11 = vec2(fx1, 1.0 - fy1);
|
|
38
|
+
|
|
39
|
+
vec2 uv;
|
|
40
|
+
if (v == 0) uv = uv00;
|
|
41
|
+
else if (v == 1) uv = uv10;
|
|
42
|
+
else if (v == 2) uv = uv01;
|
|
43
|
+
else if (v == 3) uv = uv10;
|
|
44
|
+
else if (v == 4) uv = uv11;
|
|
45
|
+
else uv = uv01;
|
|
46
|
+
|
|
47
|
+
float depth = texture(u_depthImage, uv).r;
|
|
48
|
+
float z = mix(u_depthMin, u_depthMax, depth);
|
|
49
|
+
|
|
50
|
+
vec2 pixelPos = uv * u_imageSize;
|
|
51
|
+
vec2 pos = (pixelPos - u_imageSize * 0.5) * z / u_focal;
|
|
52
|
+
|
|
53
|
+
v_uv = uv;
|
|
54
|
+
gl_Position = u_projMat * u_viewMat * vec4(pos.x, pos.y, z, 1.0);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
`,g=`#version 300 es
|
|
58
|
+
|
|
59
|
+
precision mediump float;
|
|
60
|
+
|
|
61
|
+
in vec2 v_uv;
|
|
62
|
+
|
|
63
|
+
out vec4 fragColor;
|
|
64
|
+
|
|
65
|
+
uniform sampler2D u_colorImage;
|
|
66
|
+
uniform sampler2D u_depthImage;
|
|
67
|
+
|
|
68
|
+
uniform vec2 u_targetRes;
|
|
69
|
+
uniform float u_discardCutoff;
|
|
70
|
+
|
|
71
|
+
void main()
|
|
72
|
+
{
|
|
73
|
+
float deriv = min(
|
|
74
|
+
length(dFdx(v_uv) * u_targetRes),
|
|
75
|
+
length(dFdy(v_uv) * u_targetRes)
|
|
76
|
+
);
|
|
77
|
+
if(deriv < u_discardCutoff)
|
|
78
|
+
discard;
|
|
79
|
+
|
|
80
|
+
fragColor = texture(u_colorImage, v_uv);
|
|
81
|
+
}
|
|
82
|
+
`;class v extends HTMLElement{constructor(){super(),this._params={GRID_SIZE:1e3,FOCAL_LENGTH:1200,DEPTH_MIN:.1,DEPTH_MAX:10,DISCARD_CUTOFF:0,CAM_RADIUS:1.5,CAM_MAX_THETA:Math.PI/40,CAM_MAX_PHI:Math.PI/64,CAM_FOV:Math.PI/4,CAM_SMOOTHNESS:.9,BOOMERANG_SPEED:.001,BACKGROUND_COLOR:[0,0,0]},this._shadowRoot=null,this._canvas=null,this._colorSource=null,this._depthSource=null,this._gl=null,this._shaderProgram=null,this._textures={},this._uniforms=null,this._mouse={x:0,y:0,hovered:!1},this._anim={theta:Math.PI,phi:0,radius:this._params.CAM_RADIUS},this._lastTime=0,this._animFrame=null,this._running=!1,this._userViewMat=null,this._userProjMat=null,this._onResizeHandler=null,this._onMouseMoveHandler=null,this._onMouseLeaveHandler=null,this._onRenderHandler=null,this._shadowRoot=this.attachShadow({mode:"open"});const t=document.createElement("div");t.style.position="relative",t.style.width="100%",t.style.height="100%",t.style.display="flex",t.style.alignItems="center",t.style.justifyContent="center",t.style.background="black",this._shadowRoot.appendChild(t);const e=document.createElement("style");e.textContent=`
|
|
83
|
+
:host { display: inline-block; width: 300px; height: 200px; }
|
|
84
|
+
:host([fullbleed]) { display:block; width:100%; height:100%; }
|
|
85
|
+
canvas { touch-action: none; }
|
|
86
|
+
.cover-img, .cover-video { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: contain; pointer-events: none; }
|
|
87
|
+
`,this._shadowRoot.appendChild(e),this._canvas=document.createElement("canvas"),this._canvas.style.width="100%",this._canvas.style.height="100%",this._canvas.style.objectFit="contain",this._canvas.setAttribute("role","img"),this._canvas.setAttribute("aria-label","3D image"),t.appendChild(this._canvas),this._onResizeHandler=this._onResize.bind(this),this._onMouseMoveHandler=this._onMouseMove.bind(this),this._onMouseLeaveHandler=this._onMouseLeave.bind(this),this._onRenderHandler=this._onRender.bind(this)}connectedCallback(){this._readParams();let t;try{this._init(),t=!1}catch{t=!0}window.addEventListener("resize",this._onResizeHandler),window.addEventListener("mousemove",this._onMouseMoveHandler),document.addEventListener("mouseleave",this._onMouseLeaveHandler),this._loadSources(),t?this._createFallback():(this._onResize(),this._running=!0,this._lastTime=performance.now(),this._animFrame=requestAnimationFrame(this._onRenderHandler))}disconnectedCallback(){this._running=!1,cancelAnimationFrame(this._animFrame),window.removeEventListener("resize",this._onResizeHandler),this._canvas.removeEventListener("pointermove",this._onMouseMoveHandler),this._canvas.removeEventListener("pointerleave",this._onMouseLeaveHandler);try{if(this._gl){const t=this._gl;this._shaderProgram&&t.deleteProgram(this._shaderProgram);for(let e in this._textures)t.deleteTexture(this._textures[e])}}catch{}}setViewMatrix(t){this._userViewMat=t&&t.length===16?new Float32Array(t):null}setProjectionMatrix(t){this._userProjMat=t&&t.length===16?new Float32Array(t):null}get width(){return this._getSourceWidth(this._colorSource)}get height(){return this._getSourceHeight(this._colorSource)}_init(){const t=this._canvas.getContext("webgl2",{antialias:!0,alpha:!1});if(!t)throw new Error("WebGL not supported");this._gl=t;const e=this._createProgram(t,S,g);if(!e)return;this._shaderProgram=e,t.useProgram(e);const o=this._createTexture(t),i=this._createTexture(t);this._textures.color=o,this._textures.depth=i,this._updateTexture("color",this._colorSource),this._updateTexture("depth",this._depthSource);const r=t.getUniformLocation(e,"u_colorImage"),a=t.getUniformLocation(e,"u_depthImage");t.uniform1i(r,0),t.uniform1i(a,1),this._uniforms={uProjection:t.getUniformLocation(e,"u_projMat"),uView:t.getUniformLocation(e,"u_viewMat"),uImageSize:t.getUniformLocation(e,"u_imageSize"),uFocal:t.getUniformLocation(e,"u_focal"),uDepthMin:t.getUniformLocation(e,"u_depthMin"),uDepthMax:t.getUniformLocation(e,"u_depthMax"),uGridSegs:t.getUniformLocation(e,"u_grid"),uTargetRes:t.getUniformLocation(e,"u_targetRes"),uDiscardCutoff:t.getUniformLocation(e,"u_discardCutoff")}}_onRender(t){if(!this._running||!this._gl)return;const e=this._gl,o=t-this._lastTime;this._lastTime=t,this._updateTexturesIfNeeded(),e.clearColor(...this._params.BACKGROUND_COLOR,1),e.clear(e.COLOR_BUFFER_BIT|e.DEPTH_BUFFER_BIT),e.enable(e.DEPTH_TEST),this._mouse.hovered||(this._mouse.x=Math.sin(t*this._params.BOOMERANG_SPEED),this._mouse.y=Math.sin(t*this._params.BOOMERANG_SPEED*.5+Math.PI));const i=this._mouse.x*this._params.CAM_MAX_THETA+Math.PI,r=-this._mouse.y*this._params.CAM_MAX_PHI,a=this._mouse.hovered?this._params.CAM_RADIUS*.8:this._params.CAM_RADIUS;this._anim.theta=this._animate(i,this._anim.theta,o),this._anim.phi=this._animate(r,this._anim.phi,o),this._anim.radius=this._animate(a,this._anim.radius,o);const u=this._canvas.width/this._canvas.height,h=Math.max(1,Math.floor(this._params.GRID_SIZE)),n=Math.max(1,Math.round(h/u)),s=this._getSourceWidth(this._colorSource),c=this._getSourceHeight(this._colorSource);e.uniform2f(this._uniforms.uImageSize,s,c),e.uniform1f(this._uniforms.uFocal,this._params.FOCAL_LENGTH),e.uniform1f(this._uniforms.uDepthMin,this._params.DEPTH_MIN),e.uniform1f(this._uniforms.uDepthMax,this._params.DEPTH_MAX),e.uniform2i(this._uniforms.uGridSegs,h,n),e.uniform2f(this._uniforms.uTargetRes,this._canvas.width,this._canvas.height),e.uniform1f(this._uniforms.uDiscardCutoff,this._params.DISCARD_CUTOFF);const _=[this._anim.radius*Math.cos(this._anim.phi)*Math.sin(this._anim.theta),this._anim.radius*Math.sin(this._anim.phi),this._params.CAM_RADIUS+this._anim.radius*Math.cos(this._anim.phi)*Math.cos(this._anim.theta)],l=[0,0,this._params.CAM_RADIUS],T=[0,-1,0],M=this._userViewMat||new Float32Array(this._lookAt(_,l,T)),R=this._userProjMat||new Float32Array(this._perspective(this._params.CAM_FOV,u,.1,100));e.uniformMatrix4fv(this._uniforms.uView,!1,M),e.uniformMatrix4fv(this._uniforms.uProjection,!1,R),e.drawArrays(e.TRIANGLES,0,h*n*6),this._animFrame=requestAnimationFrame(this._onRenderHandler)}_onMouseMove(t){const e=this._canvas.getBoundingClientRect();this._mouse.hovered=!0,this._mouse.x=(t.clientX-e.left)/e.width*2-1,this._mouse.y=(t.clientY-e.top)/e.height*2-1}_onMouseLeave(){this._mouse.hovered=!1}_onResize(){const t=window.devicePixelRatio||1,e=this._canvas.parentElement;if(!e)return;const o=e.clientWidth,i=e.clientHeight;let r=this._getSourceWidth(this._colorSource)||1,a=this._getSourceHeight(this._colorSource)||1;const u=r/a;let h=o,n=h/u;n>i&&(n=i,h=n*u);const s=Math.max(1,Math.floor(h*t)),c=Math.max(1,Math.floor(n*t));this._canvas.width=s,this._canvas.height=c,this._gl&&this._gl.viewport(0,0,s,c)}_readParams(){const t=this._params;if(this.hasAttribute("grid-size")&&(t.GRID_SIZE=parseInt(this.getAttribute("grid-size"))??t.GRID_SIZE),this.hasAttribute("focal-length")&&(t.FOCAL_LENGTH=parseFloat(this.getAttribute("focal-length"))??t.FOCAL_LENGTH),this.hasAttribute("depth-min")&&(t.DEPTH_MIN=parseFloat(this.getAttribute("depth-min"))??t.DEPTH_MIN),this.hasAttribute("depth-max")&&(t.DEPTH_MAX=parseFloat(this.getAttribute("depth-max"))??t.DEPTH_MAX),this.hasAttribute("discard-cutoff")&&(t.DISCARD_CUTOFF=parseFloat(this.getAttribute("discard-cutoff"))??t.DISCARD_CUTOFF),this.hasAttribute("cam-radius")&&(t.CAM_RADIUS=parseFloat(this.getAttribute("cam-radius"))??t.CAM_RADIUS),this.hasAttribute("cam-max-theta")&&(t.CAM_MAX_THETA=parseFloat(this.getAttribute("cam-max-theta"))??t.CAM_MAX_THETA),this.hasAttribute("cam-max-phi")&&(t.CAM_MAX_PHI=parseFloat(this.getAttribute("cam-max-phi"))??t.CAM_MAX_PHI),this.hasAttribute("cam-fov")&&(t.CAM_FOV=parseFloat(this.getAttribute("cam-fov"))??t.CAM_FOV),this.hasAttribute("cam-smoothness")&&(t.CAM_SMOOTHNESS=parseFloat(this.getAttribute("cam-smoothness"))??t.CAM_SMOOTHNESS),this.hasAttribute("boomerang-speed")&&(t.BOOMERANG_SPEED=parseFloat(this.getAttribute("boomerang-speed"))??t.BOOMERANG_SPEED),this.hasAttribute("background-color"))try{const e=this.getAttribute("background-color").split(",").map(Number);e.length===3&&(t.BACKGROUND_COLOR=e)}catch{}}_createShader(t,e,o){const i=t.createShader(e);return t.shaderSource(i,o),t.compileShader(i),t.getShaderParameter(i,t.COMPILE_STATUS)?i:(console.error(t.getShaderInfoLog(i)),t.deleteShader(i),null)}_createProgram(t,e,o){const i=this._createShader(t,t.VERTEX_SHADER,e),r=this._createShader(t,t.FRAGMENT_SHADER,o);if(!i||!r)return null;const a=t.createProgram();return t.attachShader(a,i),t.attachShader(a,r),t.linkProgram(a),t.getProgramParameter(a,t.LINK_STATUS)?(t.deleteShader(i),t.deleteShader(r),a):(console.error(t.getProgramInfoLog(a)),t.deleteProgram(a),null)}_createTexture(t){const e=t.createTexture();return t.bindTexture(t.TEXTURE_2D,e),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.LINEAR),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.LINEAR),e}_updateTexture(t,e){if(!this._gl)return;const o=this._gl,i=this._textures[t];if(o.activeTexture(t==="color"?o.TEXTURE0:o.TEXTURE1),o.bindTexture(o.TEXTURE_2D,i),!this._isSourceReady(e)){o.texImage2D(o.TEXTURE_2D,0,o.RGBA,1,1,0,o.RGBA,o.UNSIGNED_BYTE,new Uint8Array([0,0,0,0]));return}try{o.pixelStorei(o.UNPACK_FLIP_Y_WEBGL,!1),o.texImage2D(o.TEXTURE_2D,0,o.RGBA,o.RGBA,o.UNSIGNED_BYTE,e)}catch{}}_perspective(t,e,o,i){const r=1/Math.tan(t/2);return[r/e,0,0,0,0,r,0,0,0,0,(i+o)/(o-i),-1,0,0,2*i*o/(o-i),0]}_lookAt(t,e,o){function i(s){const c=Math.hypot(...s)||1;return s.map(_=>_/c)}function r(s,c){return[s[1]*c[2]-s[2]*c[1],s[2]*c[0]-s[0]*c[2],s[0]*c[1]-s[1]*c[0]]}function a(s,c){return s.map((_,l)=>_-c[l])}const u=i(a(t,e)),h=i(r(o,u)),n=r(u,h);return[h[0],n[0],u[0],0,h[1],n[1],u[1],0,h[2],n[2],u[2],0,-(h[0]*t[0]+h[1]*t[1]+h[2]*t[2]),-(n[0]*t[0]+n[1]*t[1]+n[2]*t[2]),-(u[0]*t[0]+u[1]*t[1]+u[2]*t[2]),1]}_animate(t,e,o){const i=(1-this._params.CAM_SMOOTHNESS)*o/16.67,r=Math.sign(t-e);return e+=(t-e)*i,Math.sign(t-e)!==r&&(e=t),e}_loadSources(){throw new Error("Must implement _loadSources")}_createFallback(){throw new Error("Must implement _createFallback")}_updateTexturesIfNeeded(){}_isSourceReady(t){throw new Error("Must implement _isSourceReady")}_getSourceWidth(t){throw new Error("Must implement _getSourceWidth")}_getSourceHeight(t){throw new Error("Must implement _getSourceHeight")}}d=v;class A extends d{static get observedAttributes(){return["color-src","depth-src","color-id","depth-id","grid-size","focal-length","depth-min","depth-max","discard-cutoff","cam-radius","cam-max-theta","cam-max-phi","cam-fov","cam-smoothness","boomerang-speed","background-color"]}constructor(){super(),this._colorSource=new Image,this._depthSource=new Image,this._colorSource.crossOrigin="anonymous",this._depthSource.crossOrigin="anonymous"}attributeChangedCallback(t,e,o){if(e!==o)if(t==="color-src")this._colorSource.src=o||"";else if(t==="depth-src")this._depthSource.src=o||"";else if(t==="color-id"){const i=document.getElementById(o);i instanceof HTMLImageElement&&(this._colorSource=i,i.complete?this._updateTexture("color",i):i.addEventListener("load",()=>this._updateTexture("color",i)))}else if(t==="depth-id"){const i=document.getElementById(o);i instanceof HTMLImageElement&&(this._depthSource=i,i.complete?this._updateTexture("depth",i):i.addEventListener("load",()=>this._updateTexture("depth",i)))}else this._readParams()}_loadSources(){const t=this.getAttribute("color-id"),e=this.getAttribute("depth-id"),o=this.getAttribute("color-src"),i=this.getAttribute("depth-src");if(t){const r=document.getElementById(t);r instanceof HTMLImageElement&&r.complete?(this._colorSource=r,this._updateTexture("color",this._colorSource)):r&&(r.addEventListener("load",()=>this._updateTexture("color",r)),this._colorSource=r)}else o&&(this._colorSource.src=o,this._colorSource.onload=()=>this._updateTexture("color",this._colorSource));if(e){const r=document.getElementById(e);r instanceof HTMLImageElement&&r.complete?(this._depthSource=r,this._updateTexture("depth",this._depthSource)):r&&(r.addEventListener("load",()=>this._updateTexture("depth",r)),this._depthSource=r)}else i&&(this._depthSource.src=i,this._depthSource.onload=()=>this._updateTexture("depth",this._depthSource))}_createFallback(){this.getAttribute("color-id")&&(this._colorSource=this._colorSource.cloneNode(),this._colorSource.id+="_threedad-img"),this._colorSource.style.display="block",this._colorSource.classList.add("cover-img"),this._canvas.parentElement.appendChild(this._colorSource)}_isSourceReady(t){return t&&t.complete&&t.naturalWidth>0}_getSourceWidth(t){return t?t.width:1}_getSourceHeight(t){return t?t.height:1}}m=A;class E extends d{static get observedAttributes(){return["color-src","depth-src","color-id","depth-id","grid-size","focal-length","depth-min","depth-max","discard-cutoff","cam-radius","cam-max-theta","cam-max-phi","cam-fov","cam-smoothness","boomerang-speed","background-color","autoplay","loop","muted"]}constructor(){super(),this._colorSource=document.createElement("video"),this._depthSource=document.createElement("video"),this._colorSource.crossOrigin="anonymous",this._depthSource.crossOrigin="anonymous",this._colorSource.playsInline=!0,this._depthSource.playsInline=!0,this._colorSource.muted=!0,this._depthSource.muted=!0}attributeChangedCallback(t,e,o){if(e!==o)if(t==="color-src")this._colorSource.src=o||"";else if(t==="depth-src")this._depthSource.src=o||"";else if(t==="color-id"){const i=document.getElementById(o);i instanceof HTMLVideoElement&&(this._colorSource=i,i.readyState>=i.HAVE_CURRENT_DATA?this._updateTexture("color",i):i.addEventListener("loadeddata",()=>this._updateTexture("color",i)))}else if(t==="depth-id"){const i=document.getElementById(o);i instanceof HTMLVideoElement&&(this._depthSource=i,i.readyState>=i.HAVE_CURRENT_DATA?this._updateTexture("depth",i):i.addEventListener("loadeddata",()=>this._updateTexture("depth",i)))}else t==="autoplay"?(this._colorSource.autoplay=this.hasAttribute("autoplay"),this._depthSource.autoplay=this.hasAttribute("autoplay")):t==="loop"?(this._colorSource.loop=this.hasAttribute("loop"),this._depthSource.loop=this.hasAttribute("loop")):t==="muted"?(this._colorSource.muted=this.hasAttribute("muted"),this._depthSource.muted=this.hasAttribute("muted")):this._readParams()}play(){return Promise.all([this._colorSource?.play(),this._depthSource?.play()])}pause(){this._colorSource?.pause(),this._depthSource?.pause()}get paused(){return this._colorSource?this._colorSource.paused:!0}get currentTime(){return this._colorSource?this._colorSource.currentTime:0}set currentTime(t){console.log(t),this._colorSource&&(this._colorSource.currentTime=t),this._depthSource&&(this._depthSource.currentTime=t)}_loadSources(){const t=this.getAttribute("color-id"),e=this.getAttribute("depth-id"),o=this.getAttribute("color-src"),i=this.getAttribute("depth-src");if(this.hasAttribute("autoplay")&&(this._colorSource.autoplay=!0,this._depthSource.autoplay=!0),this.hasAttribute("loop")&&(this._colorSource.loop=!0,this._depthSource.loop=!0),this.hasAttribute("muted")&&(this._colorSource.muted=!0,this._depthSource.muted=!0),t){const r=document.getElementById(t);r instanceof HTMLVideoElement&&(this._colorSource=r)}else o&&(this._colorSource.src=o);if(e){const r=document.getElementById(e);r instanceof HTMLVideoElement&&(this._depthSource=r)}else i&&(this._depthSource.src=i);this.hasAttribute("autoplay")?this.play().then(()=>{this._onResize()}):this.play().then(()=>{this.pause(),this._onResize()})}_createFallback(){this.getAttribute("color-id")&&(this._colorSource=this._colorSource.cloneNode(!0),this._colorSource.id+="_threedad-video"),this._colorSource.style.display="block",this._colorSource.classList.add("cover-video"),this._colorSource.controls=!0,this._canvas.parentElement.appendChild(this._colorSource)}_updateTexturesIfNeeded(){this._isSourceReady(this._colorSource)&&this._updateTexture("color",this._colorSource),this._isSourceReady(this._depthSource)&&this._updateTexture("depth",this._depthSource),Math.abs(this._colorSource.currentTime-this._depthSource.currentTime)>.01&&(this._depthSource.currentTime=this._colorSource.currentTime,this._colorSource.paused!==this._depthSource.paused&&(this._colorSource.paused?this._depthSource.pause():this._depthSource.play()))}_isSourceReady(t){return t&&t.readyState>=t.HAVE_CURRENT_DATA}_getSourceWidth(t){return t?t.videoWidth:1}_getSourceHeight(t){return t?t.videoHeight:1}}p=E,customElements.define("rgbd-img",m),customElements.define("rgbd-video",p)}
|