Opengl es 一个片段可以访问WebGL GLSL中的所有纹理像素值吗?(不仅仅是它自己的TexCoord)

Opengl es 一个片段可以访问WebGL GLSL中的所有纹理像素值吗?(不仅仅是它自己的TexCoord),opengl-es,glsl,webgl,fragment-shader,compute-shader,Opengl Es,Glsl,Webgl,Fragment Shader,Compute Shader,让我们假设我正在使用WebGL和GLSL制作一个计算着色器 在这个着色器中,每个片段(或像素)都希望查看纹理上的每个像素,然后决定它自己的颜色 通常一个片段从一些纹理中采样它提供的纹理坐标(UV值),但我想从单个纹理中为单个片段有效地采样所有UV值 这可能吗 这可能吗 当然是这样,因为每个纹理访问都需要大量GPU指令周期,所以在中止之前,片段着色器可能会在每个片段上花费多少周期,这很可能会受到严格限制 这可能吗 当然是这样,因为每个纹理访问都需要大量的GPU指令周期,所以在片段着色器中止之前,您

让我们假设我正在使用WebGL和GLSL制作一个计算着色器

在这个着色器中,每个片段(或像素)都希望查看纹理上的每个像素,然后决定它自己的颜色

通常一个片段从一些纹理中采样它提供的纹理坐标(UV值),但我想从单个纹理中为单个片段有效地采样所有UV值

这可能吗

这可能吗

当然是这样,因为每个纹理访问都需要大量GPU指令周期,所以在中止之前,片段着色器可能会在每个片段上花费多少周期,这很可能会受到严格限制

这可能吗


当然是这样,因为每个纹理访问都需要大量的GPU指令周期,所以在片段着色器中止之前,您很可能会遇到片段着色器在每个片段上可能花费的周期数的硬限制。

编辑:我能够从128x128纹理中的每个像素采样,但移动到256x256会导致Chrome失败。这意味着在一次绘制调用中,每个像素可以从同一纹理中采样大约16384个不同的像素。非常有用的机器学习

注意:在256x256(65536像素)下,可能有一个非平方幂为2的纹理来支持更高的像素采样数,但我只使用方形纹理,因此没有进行测试。

void main() {
    vec4 tcol = vec4(0, 0, 0, 0);
    for (float x = 0.0; x < PIXELS_WIDE; x++) 
        for (float y = 0.0; y < PIXELS_TALL; y++) 
            tcol += texture2D(tex0, vec2(x / PIXELS_WIDE, y / PIXELS_TALL));
    tcol /= 100.;
    gl_FragColor = tcol;
}

编辑:我能够从128x128纹理中的每个像素进行采样,但移动到256x256会导致Chrome失败。这意味着在一次绘制调用中,每个像素可以从同一纹理中采样大约16384个不同的像素。非常有用的机器学习

注意:在256x256(65536像素)下,可能有一个非平方幂为2的纹理来支持更高的像素采样数,但我只使用方形纹理,因此没有进行测试。

void main() {
    vec4 tcol = vec4(0, 0, 0, 0);
    for (float x = 0.0; x < PIXELS_WIDE; x++) 
        for (float y = 0.0; y < PIXELS_TALL; y++) 
            tcol += texture2D(tex0, vec2(x / PIXELS_WIDE, y / PIXELS_TALL));
    tcol /= 100.;
    gl_FragColor = tcol;
}

合法的,我有一种强烈的感觉,那就是太多指令错误(或者在展开如此大小的for循环时出现类似的错误)。目前是否存在超越限制的情况?根据法律,我强烈感觉可能是太多指令错误(或者在展开如此大小的for循环时出现类似错误)。目前是否存在超越限制的方法?我发现自己经常这样说,但取决于您试图做什么,mipmap可能会有所帮助。它们有效地将纹理转化为树状数据结构,您可以通过从更高的LOD(GL中的更高->更低分辨率)获取有关更大的纹理块的信息。对于机器学习中的某些事情,您可能实际上不需要知道每个值,您可以有效地将数据聚类到mipmap lod的层次结构中。现代GL中有更有效的方法,但对于WebGL来说,mipmaps是一种非常漂亮的、普遍支持的数据结构。100000次基本上是在GPU上完成的。操作系统和/或浏览器将杀死WebGL,因为GPU不可抢占。如果你想做那么多的工作,你需要把它分开。而且你的texcoord计算是错误的。它应该是
vec2((x+0.5)/像素宽,(y+0.5)/像素高)
。如果没有+0.5,则计算像素之间的精确点。取决于GPU和其他东西,你会得到一个或另一个像素。参见:同样,在你的100000次通行证上。加速的一个方法是将问题分解成块。一个现代的GPU有超过2000个内核,所以它可以并行处理2000件事情,但你必须给它并行处理。绘制单个像素是一件事。画2000像素就是要做2000件事。例如,计算1000个像素的和,然后对1000个结果求和,将使GPU有机会并行化1000倍,而计算一个像素,即1000000个像素的和,将不会并行化任何东西。我发现我自己说了很多,但取决于你想做什么,mipmap可能会有所帮助。它们有效地将纹理转化为树状数据结构,您可以通过从更高的LOD(GL中的更高->更低分辨率)获取有关更大的纹理块的信息。对于机器学习中的某些事情,您可能实际上不需要知道每个值,您可以有效地将数据聚类到mipmap lod的层次结构中。现代GL中有更有效的方法,但对于WebGL来说,mipmaps是一种非常漂亮的、普遍支持的数据结构。100000次基本上是在GPU上完成的。操作系统和/或浏览器将杀死WebGL,因为GPU不可抢占。如果你想做那么多的工作,你需要把它分开。而且你的texcoord计算是错误的。它应该是
vec2((x+0.5)/像素宽,(y+0.5)/像素高)
。如果没有+0.5,则计算像素之间的精确点。取决于GPU和其他东西,你会得到一个或另一个像素。参见:同样,在你的100000次通行证上。加速的一个方法是将问题分解成块。一个现代的GPU有超过2000个内核,所以它可以并行处理2000件事情,但你必须给它并行处理。绘制单个像素是一件事。画2000像素就是要做2000件事。例如,计算每1000个像素的1000个和,然后将得到的1000个结果相加,GPU将有机会并行化1000x,而计算1000000个像素的和的一个像素将不会并行化任何东西。
void main() {
    float reg = 0.0;
    for (int i = 0; i < 1000; i++) {
        reg += 0.1 / 255.0;
    }
    gl_FragColor = vec4(reg, 0, 0, 1);
}
void main() {
    float reg = 0.0;
    for (int i = 0; i < 10000; i++) {
        reg += 0.01 / 255.0;
    }
    gl_FragColor = vec4(reg, 0, 0, 1);
}
void main() {
    float reg = 0.0;
    for (int i = 0; i < 100000; i++) {
        reg += 0.001 / 255.0;
    }
    gl_FragColor = vec4(reg, 0, 0, 1);
}
GL_INVALID_ENUM : glBindFramebuffer: target was GL_READ_FRAMEBUFFER_ANGLE 
GL_INVALID_ENUM : glBindFramebuffer: target was GL_DRAW_FRAMEBUFFER_ANGLE 
WebGL: CONTEXT_LOST_WEBGL: loseContext: context lost