- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想知道是否可以利用WebGL进行任何异步调用?
我研究了Spec v1和Spec v2,他们什么都没提及。在V2中,有一种WebGL查询机制,我认为这不是我想要的。
在网络上进行搜索并没有确定的定义。有此示例,尚不清楚同步版本和异步版本如何不同。 http://toji.github.io/shader-perf/
最终,我希望能够异步实现所有这些功能:
readPixels
texSubImage2D和texImage2D
着色器编译
程序链接
画???
有一个glFinish操作,其文档显示:“直到所有以前调用的GL命令的效果完成,才返回。”对我来说,这意味着可以通过调用Finish()等待异步操作?
网络上的一些帖子建议,调用getError()也会强制一些同步性,这并不是每次调用后都希望做的事情。
最佳答案
这取决于您对异步的定义。
在Chrome中(Firefox可能现在也这样做吗?不确定)。 Chrome浏览器通过JavaScript单独运行所有GPU代码。这意味着您的命令正在异步运行。甚至OpenGL本身也被设计为异步的。函数(WebGL / OpenGL)将命令插入命令缓冲区。这些由其他线程/进程执行。您告诉OpenGL“嘿,我有新命令要执行!”通过调用gl.flush
。它异步执行这些命令。如果不调用gl.flush
,则在发出太多命令时会定期为您调用。假设您已调用画布的任何渲染命令(gl.drawXXX,gl.clear),当前JavaScript事件退出时也会调用该方法。
从这个意义上说,关于WebGL的一切都是异步的。如果您不查询某些内容(gl.getXXX,gl.readXXX),则表示正在处理(绘制)与JavaScript不同步的内容。 WebGL使您可以在与CPU分开运行之后访问GPU。
了解这种在Chrome中利用它的方法是通过提交着色器来异步编译着色器
for each shader
s = gl.createShader()
gl.shaderSource(...);
gl.compileShader(...);
gl.attachShader(...);
gl.linkProgram(...)
gl.flush()
texImage2D
是同步的注释。同样,这取决于您对异步的定义。添加命令及其数据需要花费时间。像
gl.enable(gl.DEPTH_TEST)
这样的命令只需添加2-8个字节。像
gl.texImage2D(..., width = 1024, height = 1024, RGBA, UNSIGNED_BYTE)
这样的命令必须添加4meg!。一旦上传了4meg,其余的都是异步的,但是上传需要时间。这两个命令是相同的,只是添加2-8个字节比添加4meg所需的时间少得多。
gl.texImage2D
和相关命令必须完成大量工作。一种是他们必须遵守
UNPACK_FLIP_Y_WEBGL
和
UNPACK_PREMULTIPLY_ALPHA_WEBGL
,因此他们需要复制多个数据来翻转或预乘它。其次,如果向他们传递视频,画布或图像,则它们可能必须进行大量转换,甚至从源中重新解析图像,尤其是根据
UNPACK_COLORSPACE_CONVERSION_WEBGL
。这是否以某种异步方式发生取决于浏览器。由于您无权直接访问图像/视频/画布,因此浏览器可能会执行所有异步操作,但必须以一种或另一种方式完成所有工作。
ImageBitmap
API。像大多数Web API一样,它的规格不足,但是您的想法是先执行
fetch
(异步)。然后,您请求创建一个
ImageBitmap
并为其提供颜色转换,翻转,预乘alpha的选项。这也会异步发生。然后,将结果传递给
gl.texImage2D
,希望浏览器能够在进入最后一步之前完成所有繁重的工作。
// 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>
关于webgl - WebGL:异步操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51710067/
我正在努力做到这一点 在我的操作中从数据库获取对象列表(确定) 在 JSP 上打印(确定) 此列表作为 JSP 中的可编辑表出现。我想修改然后将其提交回同一操作以将其保存在我的数据库中(失败。当我使用
我有以下形式的 Linq to Entities 查询: var x = from a in SomeData where ... some conditions ... select
我有以下查询。 var query = Repository.Query() .Where(p => !p.IsDeleted && p.Article.ArticleSections.Cou
我正在编写一个应用程序包,其中包含一个主类,其中主方法与GUI类分开,GUI类包含一个带有jtabbedpane的jframe,它有两个选项卡,第一个选项卡包含一个jtable,称为jtable1,第
以下代码产生错误 The nested query is not supported. Operation1='Case' Operation2='Collect' 问题是我做错了什么?我该如何解决?
我已经为 HA redis 集群(2 个副本、1 个主节点、3 个哨兵)设置了本地 docker 环境。只有哨兵暴露端口(10021、10022、10023)。 我使用的是 stackexchange
我正在 Desk.com 中构建一个“集成 URL”,它使用 Shopify Liquid 模板过滤器语法。对于开始日期为 7 天前而结束日期为现在的查询,此 URL 需要包含“开始日期”和“结束日期
你一定想过。然而情况却不理想,python中只能使用类似于 i++/i--等操作。 python中的自增操作 下面代码几乎是所有程序员在python中进行自增(减)操作的常用
我需要在每个使用 github 操作的手动构建中显示分支。例如:https://gyazo.com/2131bf83b0df1e2157480e5be842d4fb 我应该显示分支而不是一个。 最佳答
我有一个关于 Perl qr 运算符的问题: #!/usr/bin/perl -w &mysplit("a:b:c", /:/); sub mysplit { my($str, $patt
我已经使用 ArgoUML 创建了一个 ERD(实体关系图),我希望在一个类中创建两个操作,它们都具有 void 返回类型。但是,我只能创建一个返回 void 类型的操作。 例如: 我能够将 book
Github 操作仍处于测试阶段并且很新,但我希望有人可以提供帮助。我认为可以在主分支和拉取请求上运行 github 操作,如下所示: on: pull_request push: b
我正在尝试创建一个 Twilio 工作流来调用电话并记录用户所说的内容。为此,我正在使用 Record,但我不确定要在 action 参数中放置什么。 尽管我知道 Twilio 会发送有关调用该 UR
我不确定这是否可行,但值得一试。我正在使用模板缓冲区来减少使用此算法的延迟渲染器中光体积的过度绘制(当相机位于体积之外时): 使用廉价的着色器,将深度测试设置为 LEQUAL 绘制背面,将它们标记在模
有没有聪明的方法来复制 和 重命名 文件通过 GitHub 操作? 我想将一些自述文件复制到 /docs文件夹(:= 同一个 repo,不是远程的!),它们将根据它们的 frontmatter 重命名
我有一个 .csv 文件,其中第一列包含用户名。它们采用 FirstName LastName 的形式。我想获取 FirstName 并将 LastName 的第一个字符添加到它上面,然后删除空格。然
Sitecore 根据 Sitecore 树中定义的项目名称生成 URL, http://samplewebsite/Pages/Sample Page 但我们的客户有兴趣降低所有 URL(页面/示例
我正在尝试进行一些计算,但是一旦我输入金额,它就会完成。我只是希望通过单击按钮而不是自动发生这种情况。 到目前为止我做了什么: Angular JS - programming-fr
我的公司创建了一种在环境之间移动文件的复杂方法,现在我们希望将某些构建的 JS 文件(已转换和缩小)从一个 github 存储库移动到另一个。使用 github 操作可以实现这一点吗? 最佳答案 最简
在我的代码中,我创建了一个 JSONArray 对象。并向 JSONArray 对象添加了两个 JSONObject。我使用的是 json-simple-1.1.jar。我的代码是 package j
我是一名优秀的程序员,十分优秀!