WebGL:异步操作?

2024-01-10

我想知道是否有任何可以利用的 WebGL 异步调用?

我查看了 Spec v1 和 Spec v2,他们没有提及任何内容。在 V2 中,有一个 WebGL 查询机制,我认为这不是我正在寻找的。

在网络上搜索并没有得到任何明确的信息。有这个例子,不清楚同步和异步版本有何不同。http://toji.github.io/shader-perf/ http://toji.github.io/shader-perf/

最终我希望能够异步完成其中一些:

  • 读取像素
  • texSubImage2D 和 texImage2D
  • 着色器编译
  • 程序链接
  • draw???

有一个 glFinish 操作,其文档说:“在所有先前调用的 GL 命令的效果完成之前不会返回。”。对我来说,这意味着可以通过调用 Finish() 来等待异步操作?

网络上的一些帖子表明,调用 getError() 也会强制一些同步性,并且并不是每次调用后都要做的事情。


这取决于您对异步的定义。

在 Chrome 中(Firefox 现在也可能这样做?不确定)。 Chrome 在独立于 JavaScript 的进程中运行所有 GPU 代码。这意味着您的命令正在异步运行。甚至 OpenGL 本身也被设计为异步的。函数 (WebGL/OpenGL) 将命令插入命令缓冲区。这些是由其他线程/进程执行的。你告诉 OpenGL“嘿,我有新命令要你执行!”通过致电gl.flush。它异步执行这些命令。如果你不打电话gl.flush当发出太多命令时,它会定期为您调用。当当前 JavaScript 事件退出时,它也会被调用,假设您对画布调用了任何渲染命令(gl.drawXXX、gl.clear)。

从这个意义上说,WebGL 的一切都是异步的。如果您不查询某些内容(gl.getXXX、gl.readXXX),那么这些内容的处理(绘制)与您的 JavaScript 不同步。在与 CPU 分开运行之后,WebGL 使您可以访问 GPU。

了解在 Chrome 中利用它的一种方法是通过提交着色器来异步编译着色器

for each shader
  s = gl.createShader()
  gl.shaderSource(...);
  gl.compileShader(...);
  gl.attachShader(...);
gl.linkProgram(...)
gl.flush()

GPU 进程现在将编译您的着色器。因此,比如说,250 毫秒后,您才开始询问是否成功并查询位置,然后,如果编译和链接着色器的时间少于 250 毫秒,则所有操作都是异步发生的。

在 WebGL2 中,至少有一个更清晰的异步操作,即遮挡查询,其中 WebGL2 可以告诉您一组绘制调用绘制了多少像素。如果没有绘制,则您的绘制被遮挡。为了得到答案,你需要定期检查答案是否准备好。通常,您会检查下一帧,事实上 WebGL 规范要求答案在下一帧之前才可用。

否则,目前(2018 年 8 月)没有明确的异步 API。

Update

汉克穆迪在评论中提到texImage2D是同步的。再说一遍,它取决于你对异步的定义。添加命令及其数据需要时间。像这样的命令gl.enable(gl.DEPTH_TEST)只需要添加2-8个字节。像这样的命令gl.texImage2D(..., width = 1024, height = 1024, RGBA, UNSIGNED_BYTE)必须添加4兆!上传 4meg 后,其余部分都是异步的,但上传需要时间。这两个命令都是一样的,只是添加 2-8 个字节比添加 4meg 花费的时间要少得多。

更清楚的是,在上传 4 兆之后,许多其他事情都会异步发生。司机被称为 4 兆。驱动程序复制该 4meg。驱动程序安排稍后使用该 4meg,因为如果纹理已在使用中,它无法立即上传数据。或者它会立即将其上传到新区域,然后在实际使用该新数据的绘制调用之前交换纹理所指向的内容。其他驱动程序只是复制数据并存储它,然后等待纹理在绘制调用中使用以实际更新纹理。这是因为 texImage2D 具有疯狂的语义,您可以按任何顺序上传不同大小的 mip,因此驱动程序在绘制时间之前无法知道 GPU 内存中实际需要什么,因为它不知道您要调用 texIamge2D 的顺序。本段中提到的所有这些内容都是异步发生的。

但这确实带来了更多信息。

gl.texImage2D相关命令必须完成大量工作。一是他们必须尊重UNPACK_FLIP_Y_WEBGL and UNPACK_PREMULTIPLY_ALPHA_WEBGL因此他们需要复制多个兆数据来翻转或预乘它。其次,如果您向他们传递视频、画布或图像,他们可能必须进行大量转换,甚至从源重新解析图像,特别是考虑到UNPACK_COLORSPACE_CONVERSION_WEBGL。这是否以类似异步的方式发生取决于浏览器。由于您无法直接访问图像/视频/画布,因此浏览器可以异步执行所有这些操作,但以某种方式所有工作都必须发生。

为了让大部分工作异步进行ImageBitmap添加了 API。与大多数 Web API 一样,它的具体说明不明确,但我们的想法是您首先做一个fetch(这是异步的)。然后您请求创建一个ImageBitmap并为其提供颜色转换、翻转、预乘 alpha 等选项。这也是异步发生的。然后您将结果传递给gl.texImage2D希望浏览器能够在完成最后一步之前完成所有繁重的部分。

Example:

// note: mode: 'cors' is because we are loading
// from a different domain

async function main() {
  const response = await fetch('https://i.imgur.com/TSiyiJv.jpg', {mode: 'cors'})
  if (!response.ok) {
    return console.error('response not ok?');
  }
  const blob = await response.blob();
  const bitmap = await createImageBitmap(blob, {
    premultiplyAlpha: 'none',
    colorSpaceConversion: 'none',
  });

  const gl = document.querySelector("canvas").getContext("webgl");

  const tex = gl.createTexture();
  gl.bindTexture(gl.TEXTURE_2D, tex);
  {
    const level = 0;
    const internalFormat = gl.RGBA;
    const format = gl.RGBA;
    const type = gl.UNSIGNED_BYTE;
    gl.texImage2D(gl.TEXTURE_2D, level, internalFormat,
                  format, type, bitmap);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  }

  const vs = `
  uniform mat4 u_worldViewProjection;
  attribute vec4 position;
  attribute vec2 texcoord;
  varying vec2 v_texCoord;

  void main() {
    v_texCoord = texcoord;
    gl_Position = u_worldViewProjection * position;
  }
  `;
  const fs = `
  precision mediump float;
  varying vec2 v_texCoord;
  uniform sampler2D u_tex;
  void main() {
    gl_FragColor = texture2D(u_tex, v_texCoord);
  }
  `;

  const m4 = twgl.m4;
  const programInfo = twgl.createProgramInfo(gl, [vs, fs]);
  const bufferInfo = twgl.primitives.createCubeBufferInfo(gl, 2);
  const uniforms = {
    u_tex: tex,
  };

  function render(time) {
    time *= 0.001;
    twgl.resizeCanvasToDisplaySize(gl.canvas);
    gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);

    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    gl.enable(gl.DEPTH_TEST);

    const fov = 30 * Math.PI / 180;
    const aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
    const zNear = 0.5;
    const zFar = 10;
    const projection = m4.perspective(fov, aspect, zNear, zFar);
    const eye = [1, 4, -6];
    const target = [0, 0, 0];
    const up = [0, 1, 0];

    const camera = m4.lookAt(eye, target, up);
    const view = m4.inverse(camera);
    const viewProjection = m4.multiply(projection, view);
    const world = m4.rotationY(time);

    uniforms.u_worldViewProjection = m4.multiply(viewProjection, world);

    gl.useProgram(programInfo.program);
    twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);
    twgl.setUniforms(programInfo, uniforms);
    gl.drawElements(gl.TRIANGLES, bufferInfo.numElements, gl.UNSIGNED_SHORT, 0);

    requestAnimationFrame(render);
  }
  requestAnimationFrame(render);
}
main();
body { margin: 0; }
canvas { width: 100vw; height: 100vh; display: block; }
<script src="https://twgljs.org/dist/4.x/twgl-full.min.js"></script>
<canvas></canvas>

不幸的是,截至 2018 年 8 月,这仅适用于 Chrome。火狐浏览器错误就在这里 https://bugzilla.mozilla.org/show_bug.cgi?id=1335594。其他浏览器我不知道。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WebGL:异步操作? 的相关文章

  • 如何快速发现复杂场景中某个点是否被遮挡?

    我有一个复杂的 3D 场景 需要根据 3D 坐标在其上显示 HTML 元素 我只是简单地覆盖了一个div标签放在顶部并使用 CSS 定位 但是 当 3D 坐标被模型遮挡时 或者以另一种方式表述 当它在相机中不可见时 时 我还需要部分隐藏它
  • Webgl:写入 gl_FragDepth 的替代方法

    在WebGL中 是否可以写入片段的深度值或以其他方式控制片段的深度值 据我所知 gl FragDepth 不存在于 webgl 1 x 中 但我想知道是否有其他方法 扩展 浏览器特定支持等 来做到这一点 我想要归档的是让光线追踪对象与使用通
  • 如何在 UWP 上的 Xamarin.Forms WebView 中启用 WebGL?

    我是 Xamarin Forms 新手 尝试在 Windows 10 x64 v1803 计算机上使用 UWP 使用 WebView 但我不知道如何让它与 WebGL 一起使用 使用 WebGL 的网站要么显示一条消息 您的视频卡不支持 W
  • 将 webGL html 转换为 SVG

    我正在使用 R 以及 Misc3d 和 rpanel 库 在 webGL 中创建 3D 图像 然后我需要通过 Latex 将图像嵌入到 PDF 中 3D 图像渲染良好并且看起来很棒 但我想我需要将 webGL HTML 文件转换为 SVG
  • 防止片段着色器中的循环展开

    我正在使用最新版本的 Chrome 和 Firefox 为 WebGL GLSL ES 1 0 编写一个片段着色器 并且编写了一个迭代算法 首先 我发现循环的长度是非常有限的 文档说它必须在编译时是可猜测的 这意味着它必须是一个常量或非常接
  • Three.js中是否有一个容器类型对象来转换一组孩子?

    Three js 中是否有一个容器或节点对象 可以将多个网格添加为子对象 以便它们可以一起转换 一个不可见的容器 允许对组中的所有子对象执行转换 thanks Example http mrdoob github com three js
  • OpenGL 和 WebGL 的 Alpha 渲染差异

    I m rendering the same scene using the same exact C code once to native OpenGL on windows and once using Emscripten to W
  • 在 Three.js 中使用 CanvasRenderer 绘制线条比 WebGLRenderer 更平滑

    我一直遇到一个问题 即 Three js 的 CanvasRenderer 渲染线比 WebGLRenderer 平滑得多 WebGLRenderer 似乎没有应用抗锯齿功能 当我从 中获取 Three js 画布 线条 随机示例时http
  • 在 webgl 中制作 2d HUD 的推荐方法

    对于 fps 性能很重要的 webgl 游戏 制作 2D HUD 最有效的方法是什么 我可以想到 3 个选项 但我不清楚每个选项的性能成本是多少 以及哪个选项最有效 那么以下 3 个选项之间的相对性能成本是多少 答 使用正交相机以 3D 形
  • 如何使用 HTML5 Canvas 作为 WebGL 纹理

    我想要 为情况 i 设置统一值 将案例 i 的计算着色器渲染为 HTML5
  • 如何在 Three.js 中使用反射?

    我想在带有 Three js 的 WebGL 页面中拥有一个反射立方体表面 它应该类似于手机显示屏 反射一些光 但它仍然必须是黑色的 我创建了一个反射立方体 以及反射球体 的示例 并附有详细的注释 现场版本位于 http stemkoski
  • 在 Fabric.js 中真正旋转等边三角形的中心

    使用 Fabric js 我无法真正围绕其中心点旋转三角形 或者至少我认为应该是中心点 我创建了一个jsFiddle http jsfiddle net UW8Be 这表明 三角形很简单 我用了originX center 原点Y 也是如此
  • 如何快速将一个float打包为4个字节?

    我一直在寻找一种在 WebGL 纹理上存储浮动的方法 我找到了一些解决方案 http aras p info blog 2009 07 30 encoding floats to rgba the final 在互联网上 但那些只处理 0
  • Hello world WebGL 并行性示例

    围绕 WebGL 似乎有许多用于运行并行处理的抽象 例如 https github com MaiaVictor WebMonkeys https github com MaiaVictor WebMonkeys https github
  • 将 WebGL 应用程序部署为本机 iOS 或 Android 应用程序?

    有谁知道如何将 WebGL 应用程序部署为本机 iOS 或 Android 应用程序 商业中间件是可以接受的 但开放项目会更好 谢谢 作为 Joris 答案的延伸 这似乎是基于内森 德弗里斯的作品 http atnan com blog 2
  • 开始使用 Three.js 中的行进立方体

    我是 Three js 的新手 正在寻找教程来帮助我开始了解如何在 Three js 中使用 Marching Cubes 到目前为止 我在 Three js 中看到的一些使用它的项目对我来说有点复杂 所以一个简单的教程会很好 谢谢 像您一
  • WebGL - 如何传递无符号字节顶点属性颜色值?

    我的顶点由具有以下结构的数组组成 Position colour float float float byte byte byte byte 传递顶点位置没有问题 gl bindBuffer gl ARRAY BUFFER this vbo
  • 三-mtl-loader 错误:THREE.MeshPhongMaterial:.shading 已被删除 -> 对象不可见

    昨天我问了这个问题 未捕获的类型错误 THREE MTLLoader 不是构造函数 2 0 https stackoverflow com questions 47741644 uncaught typeerror three mtlloa
  • 三.js环境光意想不到的效果

    在下面的代码中 我渲染了一些立方体并使用点光源和环境光照亮它们 然而 当设置为 0xffffff 时 AmbientLight 会将侧面的颜色更改为白色 无论其指定的颜色如何 奇怪的是 点光源按预期工作 我怎样才能使环境光表现得像点光 因为
  • 从 Android 模拟器使用 WebView WebGL

    据我了解 WebGL 仅在 Android Lollipop 中的 WebView 更新 Play 商店中的 WebView 组件 和较新版本 无需 Play 商店更新 中受支持 但是 我有一个使用 Android 7 1 1 的模拟器 并

随机推荐

  • 读取 Hadoop ArrayWritable 中包装的值

    我是 Hadoop 和 Java 的新手 我的映射器输出文本和 Arraywritable 我在读取 ArrayWritable 值时遇到问题 Unbale 将 get 值转换为整数 附上映射器和减速器代码 有人可以帮我纠正我的减速器代码以
  • 计算 PHP 数组中的日期

    我有这个数组 Array 0 gt Array x gt 2016 04 19 1 gt Array x gt 2016 05 25 2 gt Array x gt 2016 05 26 3 gt Array x gt 2016 05 27
  • std::tuple 用于不可复制和不可移动的对象

    我有一门删除了复制和移动向量的课程 struct A A int a data a A std cout lt lt A lt lt this lt lt lt lt data lt lt std endl A A const obj de
  • Maven SCR 插件 - 不生成 OSGI-INF 文件夹

    我的 SCR 插件无法正常工作 我已经尽可能多地进行了搜索 但只找到了与我需要使用的结构不相似的示例 下面是 POM 的片段 这些几乎是 CQ 项目原型生成的默认值 所有依赖项都在那里 所以可能不是这样 这是构建的输出 SLF4J Fail
  • CodeIgniter 2.x 会话和 Internet Explorer

    我在网上阅读了大量有关 CodeIgniter 及其会话和 Internet Explorer 问题的文章 其中很多内容似乎都以会话名称为中心 名称中没有下划线 这些文章似乎都是针对 CI 1 x 的 CI还存在这个问题吗 我尝试删除下划线
  • 英特尔伽利略裸机 UART

    我想编写一些 hello world 程序裸机申请于英特尔伽利略木板 当然 使用 UEFI 打印文本 到 UART 1 效果很好 但我想 手动 访问 UART 而不需要 UEFI 的任何帮助 在 QEMU 中我的代码运行良好 h file
  • 如何将 Spark 数据帧转换为 Polars 数据帧?

    我想知道如何将 Spark 数据帧转换为 Polars 数据帧 假设我在 PySpark 上有这段代码 df spark sql select from tmp 我可以使用以下命令轻松地将其转换为 pandas 数据框 toPandas 极
  • 使用ionic 4,尝试在应用程序使用硬件后退按钮按下事件关闭之前向用户发出退出警报消息

    在我的最初阶段 我试图给出 退出应用程序 是 否 当用户从登录页面或主页 登录后 按下硬件后退按钮时发出警报 我面临的问题是 当我按下后退按钮时 退出警报消息会出现在每个页面上 而不仅仅是在登录或主页上 此外 无论我是否按警报框中的 否 选
  • 如何删除除包含 TRUNCATE - INSERT 的行之外的所有行

    我创建了一个脚本 将所有 PL SQL 文件格式化为一个具有值对的简单文件 它很难解释 我认为如果您只查看该文件会更容易 PROCEDURE VALIDA CAMBIO GPR TRUNCATE TMP MOD PVA INSERT TMP
  • Cocos2d 2.0 - 左下角有 3 个数字

    我的 Cocos2D 2 0 项目屏幕左下角有 3 个数字 82 0 016 60 0 60 可能是 FPS 那么其他两个呢 我记得以前的 Cocos 版本只有 FPS 数字 有什么线索吗 谢谢 82 lt number of draw c
  • 将平面 Python 字典转换为字典列表

    我有一本以下格式的字典 我不知道我将收到的行数或项目数 line 0 item1 a line 0 item2 34 line 1 item1 sd line 1 item2 2 line 1 item3 fg line 2 item1 f
  • 带 twitter bootstrap 的全宽布局

    我正在尝试完成类似于此的布局 http dribbble com shots 829195 Slate attachments 86422 http dribbble com shots 829195 Slate attachments 8
  • BI 与 Django?

    有没有办法使用 Django 开发 Bi 商业智能 解决方案 因此 应该可以使用多个数据源来定义模型 有人用过 Django 体验过 BI 吗 怎么可能行得通呢 我不确定您对 BI 的定义是什么 也不知道为什么您认为 BI 解决方案需要多个
  • 来自具有可变帧速率的图像的视频

    我想从静止图像创建视频 但我没有使用静态 FPS 而是为每个图像都有一个特定的时间戳 图像在时间上的间隔并不完全均匀 我该怎么做呢 我当前的代码 具有静态 FPS 如下 import cv2 import os image folder U
  • 绘制超平面线性SVM python

    我正在尝试绘制使用 LinearSVC 和 sklearn 训练的模型的超平面 请注意 我正在使用自然语言 在拟合模型之前 我使用 CountVectorizer 和 TfidfTransformer 提取了特征 这里是分类器 from s
  • 限制每分钟、每个方法、每个 IP 对 WCF 服务的调用

    我想限制任何不同 IP 对 WCF 服务上特定方法的调用次数x按时间范围调用y 例如 如果 IP10 0 1 1调用方法register在某一分钟内超过 5 次 称之为分钟 x 当它尝试在那分钟内第六次调用该方法时 它会被阻塞 直到分钟 x
  • 如何检查内部服务是否已在运行相同的服务?

    我有一项被许多应用程序使用的服务 开发人员只需启动该服务即可完成其工作 如果 AppA AppB 和 AppC 启动服务 我会收到重复的服务 重复并没有那么糟糕 事实上应该有重复的服务 但是当且仅当没有重复的服务已经在做相同的工作时 服务才
  • 绘图未通过闪亮仪表板侧边栏上的输入进行渲染

    几天来我一直在开发一个应用程序shiny图书馆 现在我想用shinydashboard包裹 问题是 当我在侧边栏中设置输入时 我的绘图没有显示 渲染 在我希望显示的选项卡中 仅使用闪亮的包 我设置了以下代码 没有菜单侧边栏 如闪亮仪表板中所
  • html5验证表单标签

    标签元素的 for 属性必须引用表单控件 老实说 我不明白标记有什么问题 我浏览了很多 W3 的网站 但就是找不到 Help HTML
  • WebGL:异步操作?

    我想知道是否有任何可以利用的 WebGL 异步调用 我查看了 Spec v1 和 Spec v2 他们没有提及任何内容 在 V2 中 有一个 WebGL 查询机制 我认为这不是我正在寻找的 在网络上搜索并没有得到任何明确的信息 有这个例子