一个片段可以访问WebGL GLSL中的所有纹理像素值吗? (不仅仅是它自己的TexCoord) [英] Can one fragment access all texture pixel values in WebGL GLSL? (Not just it's own TexCoord)

查看:106
本文介绍了一个片段可以访问WebGL GLSL中的所有纹理像素值吗? (不仅仅是它自己的TexCoord)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假装我正在使用WebGL和GLSL制作计算着色器.

在此着色器中,每个片段(或像素)都希望查看纹理上的每个像素,然后确定其自身的颜色.

通常,一个片段采样会从一些纹理中提供纹理坐标(UV值),但是我想针对单个片段从单个纹理中有效地采样所有UV值.

这可能吗?

解决方案

我能够对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;
}

在Chrome中,我能够执行以下循环:

100次通过(有效):

void main() {
    float reg = 0.0;
    for (int i = 0; i < 100; i++) {
        reg += 1.0 / 255.0;
    }
    gl_FragColor = vec4(reg, 0, 0, 1);
}

1000次通过(有效):

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);
}

10000次通过(有效):

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);
}

100万次通过(将床打开):

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

Let's pretend I'm making a compute shader using WebGL and GLSL.

In this shader, each fragment (or pixel) would like to look at every pixel on a texture, then decide on it's own color.

Normally a fragment samples it's provided texture coordinate (UV value) from a few textures, but I want to sample effectively all UV values from a single texture for a single fragment.

Is this possible?

解决方案

EDIT: I was able to sample from each pixel in a 128x128 texture, but moving to 256x256 causes Chrome to fail. Meaning each pixel can sample roughly 16384 different pixels from the same texture in one draw call. Very useful for machine learning!

Note: There may be an unsquare power of 2 texture to support a higher pixel sample count under 256x256 (65536 pixels), but I only use square textures so this wasn't tested.

GIST OF SOURCE CODE

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;
}

In Chrome I was able to execute the following loops:

100 Passes (Works):

void main() {
    float reg = 0.0;
    for (int i = 0; i < 100; i++) {
        reg += 1.0 / 255.0;
    }
    gl_FragColor = vec4(reg, 0, 0, 1);
}

1 000 Passes (Works):

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);
}

10 000 Passes (Works):

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);
}

100 000 Passes (Shits the bed):

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

这篇关于一个片段可以访问WebGL GLSL中的所有纹理像素值吗? (不仅仅是它自己的TexCoord)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆