Hello world WebGL 并行性示例

2024-04-21

围绕 WebGL 似乎有许多用于运行并行处理的抽象,例如:

  • https://github.com/MaiaVictor/WebMonkeys https://github.com/MaiaVictor/WebMonkeys
  • https://github.com/gpujs/gpu.js https://github.com/gpujs/gpu.js
  • https://github.com/turbo/js https://github.com/turbo/js

但我很难理解简单而完整的并行示例在 WebGL 的普通 GLSL 代码中是什么样子。我对 WebGL 没有太多经验,但我知道有片段和顶点着色器 https://stackoverflow.com/questions/4421261/vertex-shader-vs-fragment-shader以及如何将它们从 JavaScript 加载到 WebGL 上下文中。我不知道如何使用着色器或哪个着色器应该进行并行处理。

我想知道是否可以演示一个简单的 hello world 示例并行加法运算,本质上是使用 GLSL / WebGL 着色器的并行形式,但是应该这样做。

var array = []
var size = 10000
while(size--) array.push(0)

for (var i = 0, n = 10000; i < n; i++) {
  array[i] += 10
}

我想我基本上不明白:

  1. 如果 WebGL 运行一切自动并行。
  2. 或者,如果并行运行的事物数量有上限,那么如果您有 10,000 个事物,但只有 1000 个并行运行,那么它将依次并行执行 1,000 个事物 10 次。
  3. 或者,如果您必须手动指定所需的并行度。
  4. 如果并行性进入片段着色器或顶点着色器,或两者。
  5. 如何实际实现并行示例。

首先,WebGL 仅栅格化点、线和三角形 https://webglfundamentals.org/webgl/lessons/webgl-how-it-works.html。使用WebGL进行非光栅化(GPGPU https://en.wikipedia.org/wiki/General-purpose_computing_on_graphics_processing_units)基本上是要认识到 WebGL 的输入是来自数组和输出的数据,像素的 2D 矩形实际上也只是一个 2D 数组,因此通过创造性地提供非图形数据并创造性地光栅化该数据,您可以执行非图形操作数学。

WebGL 在两个方面是并行的。

  1. 它运行在不同的处理器(GPU)上,而它正在计算一些东西,而你的CPU可以自由地做其他事情。

  2. GPU 本身是并行计算的。一个很好的例子,如果您光栅化一个具有 100 个像素的三角形,GPU 可以并行处理每个像素,直到 GPU 的极限。无需深入挖掘,NVidia 1080 GPU 看起来有 2560 个核心,因此假设它们不是专门的,并且假设最好的情况其中一个可以并行计算 2560 个事物。

举个例子,所有 WebGL 应用程序都按照上面的 (1) 和 (2) 点使用并行处理,而无需执行任何特殊操作。

虽然就地添加 10 到 10000 个元素并不是 WebGL 所擅长的,因为 WebGL 无法在一次操作期间读取和写入相同的数据。换句话说,你的例子需要是

const size = 10000;
const srcArray = [];
const dstArray = [];
for (let i = 0; i < size; ++i) {
 srcArray[i] = 0;
}

for (var i = 0, i < size; ++i) {
  dstArray[i] = srcArray[i] + 10;
}

就像任何编程语言一样,有不止一种方法可以实现这一点。最快的可能是将所有值复制到纹理中,然后光栅化到另一个纹理中,从第一个纹理查找并将 +10 写入目标。但是,有一个问题。与 GPU 之间的数据传输速度很慢,因此您需要权衡在 GPU 上执行工作是否有利。

另一个就像您无法读取和写入同一数组的限制一样,您也无法随机访问目标数组。 GPU 正在光栅化一条线、点或三角形。它绘制三角形的速度最快,但这意味着它决定以什么顺序写入哪些像素,因此您的问题也必须遵守这些限制。您可以使用点作为随机选择目的地的方法,但渲染点比渲染三角形慢得多。

请注意,“计算着色器”(尚未成为 WebGL 的一部分)为 GPU 添加了随机访问写入功能。

Example:

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

const vs = `
attribute vec4 position;
attribute vec2 texcoord;

varying vec2 v_texcoord;

void main() {
  gl_Position = position;
  v_texcoord = texcoord;
}
`;

const fs = `
precision highp float;
uniform sampler2D u_srcData;
uniform float u_add;

varying vec2 v_texcoord;

void main() {
  vec4 value = texture2D(u_srcData, v_texcoord);
  
  // We can't choose the destination here. 
  // It has already been decided by however
  // we asked WebGL to rasterize.
  gl_FragColor = value + u_add;
}
`;

// calls gl.createShader, gl.shaderSource,
// gl.compileShader, gl.createProgram, 
// gl.attachShaders, gl.linkProgram,
// gl.getAttributeLocation, gl.getUniformLocation
const programInfo = twgl.createProgramInfo(gl, [vs, fs]);


const size = 10000;
// Uint8Array values default to 0
const srcData = new Uint8Array(size);
// let's use slight more interesting numbers
for (let i = 0; i < size; ++i) {
  srcData[i] = i % 200;
}

// Put that data in a texture. NOTE: Textures
// are (generally) 2 dimensional and have a limit
// on their dimensions. That means you can't make
// a 1000000 by 1 texture. Most GPUs limit from
// between 2048 to 16384.
// In our case we're doing 10000 so we could use
// a 100x100 texture. Except that WebGL can
// process 4 values at a time (red, green, blue, alpha)
// so a 50x50 will give us 10000 values
const srcTex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, srcTex);
const level = 0;
const width = Math.sqrt(size / 4);
if (width % 1 !== 0) {
  // we need some other technique to fit
  // our data into a texture.
  alert('size does not have integer square root');
}
const height = width;
const border = 0;
const internalFormat = gl.RGBA;
const format = gl.RGBA;
const type = gl.UNSIGNED_BYTE;
gl.texImage2D(
  gl.TEXTURE_2D, level, internalFormat,
  width, height, border, format, type, srcData);
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_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
  
// create a destination texture
const dstTex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, dstTex);
gl.texImage2D(
  gl.TEXTURE_2D, level, internalFormat,
  width, height, border, format, type, null);

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_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);

// make a framebuffer so we can render to the
// destination texture
const fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
// and attach the destination texture
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, dstTex, level);

// calls gl.createBuffer, gl.bindBuffer, gl.bufferData
// to put a 2 unit quad (2 triangles) into
// a buffer with matching texture coords
// to process the entire quad
const bufferInfo = twgl.createBufferInfoFromArrays(gl, {
  position: {
    data: [
      -1, -1,
       1, -1,
      -1,  1,
      -1,  1,
       1, -1,
       1,  1,
    ],
    numComponents: 2,
  },
  texcoord: [
     0, 0,
     1, 0,
     0, 1,
     0, 1,
     1, 0, 
     1, 1,
  ],
});

gl.useProgram(programInfo.program);

// calls gl.bindBuffer, gl.enableVertexAttribArray, gl.vertexAttribPointer
twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);

// calls gl.activeTexture, gl.bindTexture, gl.uniformXXX
twgl.setUniforms(programInfo, {
  u_add: 10 / 255,  // because we're using Uint8
  u_srcData: srcTex,
});

// set the viewport to match the destination size
gl.viewport(0, 0, width, height);

// draw the quad (2 triangles)
const offset = 0;
const numVertices = 6;
gl.drawArrays(gl.TRIANGLES, offset, numVertices);

// pull out the result
const dstData = new Uint8Array(size);
gl.readPixels(0, 0, width, height, format, type, dstData);

console.log(dstData);
<script src="https://twgljs.org/dist/4.x/twgl-full.min.js"></script>

制造通用数学处理器需要做更多的工作。

Issues:

纹理是 2D 数组,WebGL 仅光栅化点、线和三角形,因此处理适合矩形的数据比处理不适合矩形的数据容易得多。换句话说,如果有 10001 个值,则没有矩形可以容纳整数个单位。最好填充数据并忽略末尾部分。换句话说,100x101 纹理将有 10100 个值。所以忽略最后 99 个值即可。

上面的示例使用 8 位 4 通道纹理。使用 8 位 1 通道纹理会更容易(数学更少),但效率也较低,因为 WebGL 每个操作可以处理 4 个值。

因为它使用 8 位纹理,所以只能存储从 0 到 255 的整数值。我们可以将纹理切换为 32 位浮点纹理。浮点纹理是 WebGL 的可选功能(您需要启用扩展并检查它们是否成功)。光栅化为浮点纹理也是一个可选功能。截至 2018 年,大多数移动 GPU 不支持渲染为浮点纹理,因此如果您希望代码在这些 GPU 上运行,您必须找到创造性的方法将结果编码为它们支持的格式。

寻址源数据需要数学从一维索引转换为二维纹理坐标。在上面的示例中,由于我们直接从 srcData 转换为 dstData 1 到 1,因此不需要数学运算。如果您需要跳转 srcData 您需要提供数学

WebGL1

vec2 texcoordFromIndex(int ndx) {
  int column = int(mod(float(ndx),float(widthOfTexture)));
  int row = ndx / widthOfTexture;
  return (vec2(column, row) + 0.5) / vec2(widthOfTexture, heighOfTexture);
}

vec2 texcoord = texcoordFromIndex(someIndex);
vec4 value = texture2D(someTexture, texcoord);

WebGL2

ivec2 texcoordFromIndex(someIndex) {
  int column = ndx % widthOfTexture;
  int row = ndx / widthOfTexture;
  return ivec2(column, row);
}

int level = 0;
ivec2 texcoord = texcoordFromIndex(someIndex);
vec4 value = texelFetch(someTexture, texcoord, level);

假设我们要对每 2 个数字求和。我们可能会做这样的事情

const gl = document.createElement("canvas").getContext("webgl2");

const vs = `
#version 300 es
in vec4 position;

void main() {
  gl_Position = position;
}
`;

const fs = `
#version 300 es
precision highp float;
uniform sampler2D u_srcData;

uniform ivec2 u_destSize;  // x = width, y = height

out vec4 outColor;

ivec2 texcoordFromIndex(int ndx, ivec2 size) {
  int column = ndx % size.x;
  int row = ndx / size.x;
  return ivec2(column, row);
}

void main() {
  // compute index of destination
  ivec2 dstPixel = ivec2(gl_FragCoord.xy);
  int dstNdx = dstPixel.y * u_destSize.x + dstPixel.x; 

  ivec2 srcSize = textureSize(u_srcData, 0);

  int srcNdx = dstNdx * 2;
  ivec2 uv1 = texcoordFromIndex(srcNdx, srcSize);
  ivec2 uv2 = texcoordFromIndex(srcNdx + 1, srcSize);

  float value1 = texelFetch(u_srcData, uv1, 0).r;
  float value2 = texelFetch(u_srcData, uv2, 0).r;
  
  outColor = vec4(value1 + value2);
}
`;

// calls gl.createShader, gl.shaderSource,
// gl.compileShader, gl.createProgram, 
// gl.attachShaders, gl.linkProgram,
// gl.getAttributeLocation, gl.getUniformLocation
const programInfo = twgl.createProgramInfo(gl, [vs, fs]);


const size = 10000;
// Uint8Array values default to 0
const srcData = new Uint8Array(size);
// let's use slight more interesting numbers
for (let i = 0; i < size; ++i) {
  srcData[i] = i % 99;
}

const srcTex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, srcTex);
const level = 0;
const srcWidth = Math.sqrt(size / 4);
if (srcWidth % 1 !== 0) {
  // we need some other technique to fit
  // our data into a texture.
  alert('size does not have integer square root');
}
const srcHeight = srcWidth;
const border = 0;
const internalFormat = gl.R8;
const format = gl.RED;
const type = gl.UNSIGNED_BYTE;
gl.texImage2D(
  gl.TEXTURE_2D, level, internalFormat,
  srcWidth, srcHeight, border, format, type, srcData);
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_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
  
// create a destination texture
const dstTex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, dstTex);
const dstWidth = srcWidth;
const dstHeight = srcHeight / 2;
// should check srcHeight is evenly
// divisible by 2
gl.texImage2D(
  gl.TEXTURE_2D, level, internalFormat,
  dstWidth, dstHeight, border, format, type, null);

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_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);

// make a framebuffer so we can render to the
// destination texture
const fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
// and attach the destination texture
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, dstTex, level);

// calls gl.createBuffer, gl.bindBuffer, gl.bufferData
// to put a 2 unit quad (2 triangles) into
// a buffer
const bufferInfo = twgl.createBufferInfoFromArrays(gl, {
  position: {
    data: [
      -1, -1,
       1, -1,
      -1,  1,
      -1,  1,
       1, -1,
       1,  1,
    ],
    numComponents: 2,
  },
});

gl.useProgram(programInfo.program);

// calls gl.bindBuffer, gl.enableVertexAttribArray, gl.vertexAttribPointer
twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);

// calls gl.activeTexture, gl.bindTexture, gl.uniformXXX
twgl.setUniforms(programInfo, {
  u_srcData: srcTex,
  u_srcSize: [srcWidth, srcHeight],
  u_dstSize: [dstWidth, dstHeight],
});

// set the viewport to match the destination size
gl.viewport(0, 0, dstWidth, dstHeight);

// draw the quad (2 triangles)
const offset = 0;
const numVertices = 6;
gl.drawArrays(gl.TRIANGLES, offset, numVertices);

// pull out the result
const dstData = new Uint8Array(size / 2);
gl.readPixels(0, 0, dstWidth, dstHeight, format, type, dstData);

console.log(dstData);
<script src="https://twgljs.org/dist/4.x/twgl-full.min.js"></script>

请注意,上面的示例使用 WebGL2。为什么?因为 WebGL2 支持渲染为 R8 格式纹理,这使得数学变得很容易。每个像素一个值,而不是像前面的示例那样每个像素 4 个值。当然,这也意味着它会更慢,但让它使用 4 个值确实会使计算索引的数学变得复杂,或者可能需要重新排列源数据以更好地匹配。例如,代替价值指数0, 1, 2, 3, 4, 5, 6, 7, 8, ...如果将每 2 个值进行排列,则对它们求和会更容易0, 2, 4, 6, 1, 3, 5, 7, 8 ....这样一次拉出 4 个,然后添加下一组 4 个,值就会对齐。另一种方法是使用 2 个源纹理,将所有偶数索引值放入一个纹理中,将奇数索引值放入另一个纹理中。

WebGL1 提供 LUMINANCE 和 ALPHA 纹理,它们也是一个通道,但是否可以渲染它们是一项可选功能,而在 WebGL2 中渲染到 R8 纹理是一项必需功能。

WebGL2 还提供了一种称为“变换反馈”的功能。这使您可以将顶点着色器的输出写入缓冲区。它的优点是您只需设置要处理的顶点数(不需要目标数据是矩形)。这也意味着您可以输出浮点值(它不像渲染纹理那样是可选的)。我相信(尽管我没有测试过)它比渲染纹理要慢。

既然你是 WebGL 的新手,我可能会建议你这些教程 http://webglfundamentals.org.

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

Hello world WebGL 并行性示例 的相关文章

  • Webgl 的 getAttribLocation 奇怪地返回 -1

    我已经设法隔离此代码中的问题 var gl main web function gl document getElementById canvas getContext experimental webgl gl WebGLDebugUti
  • “webgl”和“实验性 webgl”之间的区别

    有些网站说您应该按以下方式初始化 webgl var gl c getContext webgl c getContext experimental webgl if gl alert This browser doesn t suppor
  • 纯 WebGL 虚线

    我正在尝试使用纯 webgl 创建一条虚线 我知道已经有一个问题了 也许我很蠢 但我不知道如何让它发挥作用 我理解这个概念 但我不知道如何获取着色器中沿路径的距离 之前的答案有以下一行 varying float LengthSoFar l
  • 使用画布(三.js)覆盖画布(WebGL)

    我有两块画布 第一个应该是背景 其内容通过原始 WebGL 3D 渲染 第二个画布应该覆盖第一个画布 并且主要是透明的 它的内容通过 Three js 3D 内容 呈现 不幸的是 第二个画布不是绘制在第一个画布的上面 而是绘制在它的旁边 如
  • IE9 是否支持 WebGL 和/或 WebSockets? [关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions IE9 是
  • 如何快速发现复杂场景中某个点是否被遮挡?

    我有一个复杂的 3D 场景 需要根据 3D 坐标在其上显示 HTML 元素 我只是简单地覆盖了一个div标签放在顶部并使用 CSS 定位 但是 当 3D 坐标被模型遮挡时 或者以另一种方式表述 当它在相机中不可见时 时 我还需要部分隐藏它
  • 为 webgl 中的每个对象使用不同的顶点和片段着色器

    我在 webgl 中有一个包含多个对象的场景 对于每个对象 我想使用不同的顶点和片段着色器 我的第一个问题是 是否可以为每个对象都有一个着色器 我知道在 opengl 中这是可能的 这是与我的想法类似的伪代码 任何例子将不胜感激 glena
  • canvas 与 openGL 的功能是什么?

    我知道如果你向 openGL 发送静态且很少变化的纹理 例如像图块一样 openGL 会产生奇迹 但当你有不断变化的精灵时就不行了 是否有可能纯粹从画布上创建类似绑架这样的游戏 它的性能如何 可以使用画布创建诸如绑架之类的游戏 但最终您将在
  • JavaScript WebGL RGBA 数组到屏幕?

    我正在尝试将 RGBA 格式的像素渲染到 WebGL 画布 我有这个画布
  • Webgl 没有渲染我的圆圈

    我正在尝试学习如何使用 Webgl 并且已经学会了如何绘制三角形 正方形和直线 我在 webgl 中创建圈子时遇到问题 var InitDemo function var canvas document getElementById cir
  • 背面剔除的法线变换

    从本课开始 WebGL 3D 透视 https webglfundamentals org webgl lessons webgl 3d perspective html我正在尝试实现没有魔法的背面剔除 我正在动态计算对象空间中的面法线 之
  • 将 webGL html 转换为 SVG

    我正在使用 R 以及 Misc3d 和 rpanel 库 在 webGL 中创建 3D 图像 然后我需要通过 Latex 将图像嵌入到 PDF 中 3D 图像渲染良好并且看起来很棒 但我想我需要将 webGL HTML 文件转换为 SVG
  • 如何在三个js渲染的Canvas中添加canvas的结束标签?

    三个js总是向页面添加没有结束标签的canvas元素 这背后有什么具体原因吗 我想在此画布元素上添加结束标签 Example page http threejs org examples webgl animation cloth insp
  • 三个 js - 克隆着色器并更改统一值

    我正在努力创建一个着色器来生成带有阴影的地形 我的出发点是克隆兰伯特着色器并使用 ShaderMaterial 最终用我自己的脚本对其进行自定义 标准方法效果很好 var material new MeshLambertMaterial m
  • Three.js 使用 WebRTC 并应用 Shader

    我不知道如何将着色器应用于具有视频纹理的 Three js 对象 我一直在使用 webRTC 和 Three js 并使用标准材质成功将视频纹理映射到网格上 var material new THREE MeshBasicMaterial
  • 如何在 Three.js 中使用反射?

    我想在带有 Three js 的 WebGL 页面中拥有一个反射立方体表面 它应该类似于手机显示屏 反射一些光 但它仍然必须是黑色的 我创建了一个反射立方体 以及反射球体 的示例 并附有详细的注释 现场版本位于 http stemkoski
  • 如何从 dxf 文件解析 nurbs 曲面?或者你知道用于解析它的库(对于js,如果存在或任何其他语言)?

    我正在尝试解析 autocad nurbs 曲面并使用 JavaScript 中的 webGL 进行三角测量绘制 我已经在寻找 bjnortier 的 dxf 解析器 它支持大多数实体 如直线 圆弧 3Dface 折线 lwpolyline
  • 如何在 WebGL 中创建合适的圆角矩形?

    我试图实现答案这个问题 https stackoverflow com questions 43970170 bordered rounded rectangle in glsl但似乎有点问题 如果您打开他们的 ShaderToys 并尝试
  • OpenGL:多个顶点的单个顶点属性?

    我有一个接受以下属性的顶点着色器 a posCoord 顶点位置 a texCoord 纹理坐标 传递给片段着色器 a alpha 透明度因子 传递给片段着色器 我正在渲染的对象都是 广告牌 一对直角三角形组成一个矩形 我正在使用一次调用g
  • 上传统一块的正确顺序是什么?

    在示例页面中https www lighthouse3d com tutorials glsl tutorial uniform b locks https www lighthouse3d com tutorials glsl tutor

随机推荐

  • 是否可以直接从文件加载镶木地板表?

    如果我有一个二进制数据文件 可以转换为 csv 格式 有什么方法可以直接从中加载镶木地板表吗 许多教程显示将 csv 文件加载到文本表 然后从文本表加载到镶木地板表 从效率的角度来看 是否可以像我已有的那样直接从二进制文件加载镶木地板表 理
  • Android html5 输入 type="password" 和数字键盘

    我的任务是为 Android 和 iOS 设计一个网页 您应该在其中输入您的信用卡信息 我无法获取在 Android 中打开数字键盘的安全代码字段 这是我距离最近的一次 它适用于 iOS 但不适用于 Android
  • 用三种颜色的渐变填充面板

    我正在做一个项目 我必须使用 C 做一种颜色选择器 所以我决定在 Win Forms 应用程序中建立一个具有此背景的面板 背景应具有 RGB 三种颜色的渐变 红色 0 255 蓝色 0 255 和绿色 0 但我找不到任何关于我应该为此使用什
  • 模板组件启动器内的离子标签组件未渲染

    我克隆了stencil component starter from https github com ionic team stencil component starter https github com ionic team ste
  • Android 上未原生找到 RNFirebase 核心模块

    我正在尝试在 Android 平台上运行现有的 React Native 应用程序 但收到如下图所示的错误 我已经执行了下面提到的所有步骤http invertase link android http invertase link and
  • Ionic2 - 如果超时则取消 Api 请求

    在我的应用程序中 我通过表单保存数据并调用 Api 进行相同的操作 为了检查它们的互联网连接是否缓慢 我在 ionic2 中使用超时 如下所示 savedata let headers new Headers headers set Con
  • 创建较慢的过渡。 TransitionManager.beginDelayedTransition();太快了

    我正在创建一个过渡 当单击按钮时 将执行以下方法 该方法改变了图像视图的大小和位置 并将其淡出 我在用TransitionManager beginDelayedTransition is too fast 放慢转变速度 但它仍然进展得太快
  • 为动态图像生成 CSS 精灵

    我有一个网页 其中包含大约 20 50 个动态图像 从非静态源提供的图像 这些图像通过基于请求 URL 的 servlet 提供 这会导致每个图像生成一个请求 从而导致性能下降 如果这些图像是静态的 我将创建一个 CSS 精灵并用一个请求替
  • 直线和水平线在断点处连接的分段回归

    我想做一个带有一个断点的分段线性回归 其中回归线的第二半有slope 0 有一些关于如何进行分段线性回归的示例 例如here https stackoverflow com questions 15874214 piecewise func
  • 如果我在 grails 中使用 groovy sql 类,它是否使用 grails 连接池?

    来自 sql 文档中的以下示例 如果我使用这两种方法之一在 Grails 服务类中创建 sql 实例 它会使用 Grails 连接池吗 它会参与任何交易功能吗 我需要自己关闭连接吗 还是会自动回到池子里 def db url jdbc hs
  • 如何在C中将RGB转换为HSL?

    如何在 C C 中将 RGB 转换为 HSL Note This is a short self answer I posted it here so people can find it quickly with a search 翻译代
  • 我可以在 asp.net 4.0 站点中托管 .net 2.0 虚拟目录吗?

    我们在 2 0 网站中运行 NET 4 0 虚拟目录没有任何问题 但相反的方式却给我们带来了一些问题 这是可以理解的 但是有没有办法解决这个问题呢 它们使用不同的应用程序池运行 我们可以让虚拟目录跳过网站的 web config 并直接转到
  • 从提升的进程正常执行进程

    是否有某种方法可以从提升的方式以非提升的方式启动流程 我的设置以提升的方式启动 当它完成时 它只会启动主应用程序 由于设置被提升 主进程也会被提升 这是不可取的 对此最好的解决方案是什么 这是一个问题 Vista Win7 似乎没有 API
  • Horizo​​ntalScrollView:带有 getView() 的 CustomAdapter 不会像 ListView 那样重用 ConvertViews

    在我过去的一个项目中 我实现了 时间选择器轮播 它基于一个HorizontalScrollView 用户可以在滚动该视图时选择时间 时间值是根据 X 偏移计算的HorizontalScrollView 我想在 github 上分享这个项目
  • 为什么我在访问最终局部变量时会出现 Java 中的 InstantiationException?

    我正在玩一些代码来制作 类似闭包 的构造 顺便说一句 不起作用 一切看起来都很好 但是当我尝试访问代码中的最终局部变量时 出现异常InstantiationException被抛出 如果我通过完全删除局部变量或使其成为类属性来删除对局部变量
  • 修复 iOS7 上主体背景随页面滚动的问题

    我使用以下 CSS 来创建固定的主体背景 除了新的 iOS7 之外 它几乎可以在所有浏览器上运行良好 后者的背景不再固定 它随页面滚动 知道如何解决这个问题吗 body background color 000 background ima
  • Coldfusion SQL 插入循环

    遇到一个问题 我想我可以看看是否有人对如何解决它有任何想法 基本上 我在单个变量下传递多个值 并且我想使用循环来提取每个单独的值并同时插入它 例如 ischecked 是我用来传入设备值的变量 如果我要选择两个设备 按提交并将变量 form
  • std::valarray 的运算符* 有什么问题?

    考虑以下 MCVE 其中我有两个值数组 其中w是两次v 在这里尝试一下 https godbolt org z JkXPNN include
  • 语音识别减少可能的搜索结果

    我开始使用 android sl4a 和 python 进行语音识别 到目前为止 它运行良好 我的用户应该用他的声音输入 0 到 9 之间的数字 有没有办法告诉android只搜索这些数字 从而减少识别时间 可能还有错误 不可以 您无法更改
  • Hello world WebGL 并行性示例

    围绕 WebGL 似乎有许多用于运行并行处理的抽象 例如 https github com MaiaVictor WebMonkeys https github com MaiaVictor WebMonkeys https github