Graphics rect=viewElement.getBoundingClientRect(); 如果(rect.bottomgl.canvas.clientHeight|| rect.rightgl.canvas.clientWidth){ return;//它在屏幕外 } 变量宽度=rect.right-rect.left; 变量高度=rect.bottom-rect.top; var left=rect.left; var bottom=gl.canvas.clientHeight-rect.bottom-1; 总图视口(左、下、宽、高); gl.剪刀(左、下、宽、高); 如果(显示渲染区域){ 总账清除(总账颜色缓冲位); } var projection=m4.透视图(30*Math.PI/180,宽度/高度,0.5100); m4.乘法(投影、视图、视图投影); var uni=对象制服; var world=统一世界; m4.身份(世界); m4.旋转(世界,时间*obj.Y速度,世界); m4.rotateZ(世界,时间*obj.zSpeed,世界); m4.转置(m4.反转(世界,uni.u_世界反转转换),uni.u_世界反转转换); m4.乘法(视图投影、uni.u_世界、uni.u_世界视图投影); 总账使用程序(obj.programInfo.program); //调用gl.bindBuffer、gl.enableVertexAttributeArray、gl.VertexAttributePointer twgl.setBuffersAndAttributes(总帐,obj.programInfo,obj.bufferInfo); //调用gl.bindTexture、gl.activeTexture、gl.uniformXXX twgl.设置制服(对象程序信息,uni); //调用gl.DrawArray或gl.drawElements twgl.drawBufferInfo(总帐,对象bufferInfo); }); } 如果(true){// var renderContinuously=函数(时间){ 渲染(时间); requestAnimationFrame(连续渲染); } requestAnimationFrame(连续渲染); }否则{ var请求id; var renderRequest=函数(时间){ 渲染(时间); requestId=未定义; } //如果动画 var queueRender=函数(){ 如果(!requestId){ requestId=requestAnimationFrame(renderRequest); } } addEventListener('resize',queueRender); addEventListener('scroll',queueRender); queueRender(); } *{ 框大小:边框框; -moz框大小:边框框; } 身体{ 字体系列:monospace; 保证金:0; } #c{ 位置:绝对位置; 排名:0; 宽度:100vw; 高度:100vh; } #外{ 宽度:100%; z指数:2; 位置:绝对位置; 顶部:0px; } #内容{ 保证金:自动; 填料:2米; } #b{ 宽度:100%; 文本对齐:居中; } .清单项目{ 边框:1px纯黑; 边缘:2米; 填充:1em; 宽度:200px; 显示:内联块; } .列表项.视图{ 宽度:100px; 高度:100px; 浮动:左; 利润率:0.1米1米0; } .列表项.说明{ 左:2米; } @仅介质屏幕和(最大宽度:500px){ #内容{ 宽度:100%; } .清单项目{ 边缘:0.5em; } .列表项.说明{ 左侧填充:0em; } } 项目清单 这是一个很好的例子。 均匀mat4 u_世界视图投影; 统一vec3 u_lightWorldPos; 统一mat4 u_世界; 一致mat4 u_逆; 均匀mat4-u_-world逆变换; 属性向量4 a_位置; 属性向量3 a_normal; 属性向量2 a_texcoord; 可变vec4 v_位置; 可变矢量2 v_texCoord; 可变vec3 v_正常; 可变vec3 v_表面光源; 可变vec3 v_表面视图; void main(){ v_texCoord=a_texCoord; v_位置=(u_世界视图投影*a_位置); v_normal=(u_WorldInverseTransfose*vec4(a_normal,0)).xyz; v_surfaceToLight=u_lightWorldPos-(u_world*a_位置).xyz; v_surfaceToView=(u_viewInverse[3]-(u_world*a_position)).xyz; gl_位置=v_位置; } 精密中泵浮子; 可变vec4 v_位置; 可变矢量2 v_texCoord; 可变vec3 v_正常; 可变vec3 v_表面光源; 可变vec3 v_表面视图; 均匀的vec4 u_亮色; 均匀vec4 u_扩散膜; 均匀二维u_扩散; 均匀vec4 u_镜面反射; 均匀的浮光; 均匀浮动u_镜面反射因子; vec4点亮(浮子l、浮子h、浮子m){ 返回向量4(1.0, abs(l),//最大值(l,0.0), (l>0.0)?功率(最大(0.0,h),米):0.0, 1.0); } void main(){ vec4 diffuseColor=纹理2D(u_diffuse,v_texCoord)*u_diffuseMult; vec3 a_normal=正常化(v_normal); vec3 SURFACHETOLIGHT=规格化(v_SURFACHETOLIGHT); vec3 surfaceToView=规格化(v_surfaceToView); vec3半矢量=规格化(surfaceToLight+surfaceToView); vec4 litR=发光(点(正常,表面光), 点(a_法线,半向量),u_亮度; vec4 outColor=vec4(( u_lightColor*(漫反射色*litR.y+ u_镜面反射*litR.z*u_镜面反射因子)).rgb, 扩散色(a); gl_FragColor=色彩; }

Graphics rect=viewElement.getBoundingClientRect(); 如果(rect.bottomgl.canvas.clientHeight|| rect.rightgl.canvas.clientWidth){ return;//它在屏幕外 } 变量宽度=rect.right-rect.left; 变量高度=rect.bottom-rect.top; var left=rect.left; var bottom=gl.canvas.clientHeight-rect.bottom-1; 总图视口(左、下、宽、高); gl.剪刀(左、下、宽、高); 如果(显示渲染区域){ 总账清除(总账颜色缓冲位); } var projection=m4.透视图(30*Math.PI/180,宽度/高度,0.5100); m4.乘法(投影、视图、视图投影); var uni=对象制服; var world=统一世界; m4.身份(世界); m4.旋转(世界,时间*obj.Y速度,世界); m4.rotateZ(世界,时间*obj.zSpeed,世界); m4.转置(m4.反转(世界,uni.u_世界反转转换),uni.u_世界反转转换); m4.乘法(视图投影、uni.u_世界、uni.u_世界视图投影); 总账使用程序(obj.programInfo.program); //调用gl.bindBuffer、gl.enableVertexAttributeArray、gl.VertexAttributePointer twgl.setBuffersAndAttributes(总帐,obj.programInfo,obj.bufferInfo); //调用gl.bindTexture、gl.activeTexture、gl.uniformXXX twgl.设置制服(对象程序信息,uni); //调用gl.DrawArray或gl.drawElements twgl.drawBufferInfo(总帐,对象bufferInfo); }); } 如果(true){// var renderContinuously=函数(时间){ 渲染(时间); requestAnimationFrame(连续渲染); } requestAnimationFrame(连续渲染); }否则{ var请求id; var renderRequest=函数(时间){ 渲染(时间); requestId=未定义; } //如果动画 var queueRender=函数(){ 如果(!requestId){ requestId=requestAnimationFrame(renderRequest); } } addEventListener('resize',queueRender); addEventListener('scroll',queueRender); queueRender(); } *{ 框大小:边框框; -moz框大小:边框框; } 身体{ 字体系列:monospace; 保证金:0; } #c{ 位置:绝对位置; 排名:0; 宽度:100vw; 高度:100vh; } #外{ 宽度:100%; z指数:2; 位置:绝对位置; 顶部:0px; } #内容{ 保证金:自动; 填料:2米; } #b{ 宽度:100%; 文本对齐:居中; } .清单项目{ 边框:1px纯黑; 边缘:2米; 填充:1em; 宽度:200px; 显示:内联块; } .列表项.视图{ 宽度:100px; 高度:100px; 浮动:左; 利润率:0.1米1米0; } .列表项.说明{ 左:2米; } @仅介质屏幕和(最大宽度:500px){ #内容{ 宽度:100%; } .清单项目{ 边缘:0.5em; } .列表项.说明{ 左侧填充:0em; } } 项目清单 这是一个很好的例子。 均匀mat4 u_世界视图投影; 统一vec3 u_lightWorldPos; 统一mat4 u_世界; 一致mat4 u_逆; 均匀mat4-u_-world逆变换; 属性向量4 a_位置; 属性向量3 a_normal; 属性向量2 a_texcoord; 可变vec4 v_位置; 可变矢量2 v_texCoord; 可变vec3 v_正常; 可变vec3 v_表面光源; 可变vec3 v_表面视图; void main(){ v_texCoord=a_texCoord; v_位置=(u_世界视图投影*a_位置); v_normal=(u_WorldInverseTransfose*vec4(a_normal,0)).xyz; v_surfaceToLight=u_lightWorldPos-(u_world*a_位置).xyz; v_surfaceToView=(u_viewInverse[3]-(u_world*a_position)).xyz; gl_位置=v_位置; } 精密中泵浮子; 可变vec4 v_位置; 可变矢量2 v_texCoord; 可变vec3 v_正常; 可变vec3 v_表面光源; 可变vec3 v_表面视图; 均匀的vec4 u_亮色; 均匀vec4 u_扩散膜; 均匀二维u_扩散; 均匀vec4 u_镜面反射; 均匀的浮光; 均匀浮动u_镜面反射因子; vec4点亮(浮子l、浮子h、浮子m){ 返回向量4(1.0, abs(l),//最大值(l,0.0), (l>0.0)?功率(最大(0.0,h),米):0.0, 1.0); } void main(){ vec4 diffuseColor=纹理2D(u_diffuse,v_texCoord)*u_diffuseMult; vec3 a_normal=正常化(v_normal); vec3 SURFACHETOLIGHT=规格化(v_SURFACHETOLIGHT); vec3 surfaceToView=规格化(v_surfaceToView); vec3半矢量=规格化(surfaceToLight+surfaceToView); vec4 litR=发光(点(正常,表面光), 点(a_法线,半向量),u_亮度; vec4 outColor=vec4(( u_lightColor*(漫反射色*litR.y+ u_镜面反射*litR.z*u_镜面反射因子)).rgb, 扩散色(a); gl_FragColor=色彩; },graphics,three.js,webgl,Graphics,Three.js,Webgl,不清楚为什么您认为需要多个webgl上下文。我猜是因为你想要这样的清单 1. [img] description description 2. [img] description description 3. [img] description description gl.canvas.style.transform = `translateY(${window.scrollY}px)`; 还是什么 一些想法 使一个画布足够大以

不清楚为什么您认为需要多个webgl上下文。我猜是因为你想要这样的清单

1. [img] description
         description

2. [img] description
         description

3. [img] description
         description
  gl.canvas.style.transform = `translateY(${window.scrollY}px)`;
还是什么

一些想法

  • 使一个画布足够大以容纳屏幕,设置其CSS,使其不会与页面的其余部分一起滚动。绘制与任何其他HTML对齐的模型,这些HTML可以滚动

  • 制作屏幕外webgl画布,并使用canvas2d元素进行显示

    对于每个模型,渲染模型,然后调用

    someCanvas2DContextForElementN.drawImage(webGLcanvasElement, ...);
    
  • 鉴于可能只有很少几张画布可见,您只需更新这些画布即可。事实上,回收它们可能是个好主意。我
    // get the element that is a place holder for where we want to
    // draw the object
    var viewElement = obj.viewElement;
    
    // get its position relative to the page's viewport
    var rect = viewElement.getBoundingClientRect();
    
    // check if it's offscreen. If so skip it
    if (rect.bottom < 0 || rect.top  > gl.canvas.clientHeight ||
        rect.right  < 0 || rect.left > gl.canvas.clientWidth) {
      return;  // it's off screen
    }
    
    // set the viewport
    var width  = rect.right - rect.left;
    var height = rect.bottom - rect.top;
    var left   = rect.left;
    var bottom = gl.canvas.clientHeight - rect.bottom - 1;
    
    gl.viewport(left, bottom, width, height);
    gl.scissor(left, bottom, width, height);
    
      gl.canvas.style.transform = `translateY(${window.scrollY}px)`;