Data structures 如何在sampler2D中使用循环进行迭代

Data structures 如何在sampler2D中使用循环进行迭代,data-structures,glsl,webgl,Data Structures,Glsl,Webgl,我有一些数据是用浮点纹理2k乘2k编码的。数据是经度、纬度、时间和日期,如R、G、B、A。这些都是标准化的,但现在这不是问题。如果我想的话,我可以稍后对它们进行反规范化 我现在需要的是遍历整个纹理,找到碎片坐标中的经度和纬度。我假设整个地图集都有标准化的坐标,它映射了整个openGL上下文。除了坐标外,我会用时间和日期过滤数据,但这是一个很容易做到的if条件。因为我拥有的像素坐标不会精确地映射到那个坐标,所以我现在将使用一个小的delta值来解决这个问题,并且我将使用该delta值来预计算靠近那

我有一些数据是用浮点纹理2k乘2k编码的。数据是经度、纬度、时间和日期,如R、G、B、A。这些都是标准化的,但现在这不是问题。如果我想的话,我可以稍后对它们进行反规范化

我现在需要的是遍历整个纹理,找到碎片坐标中的经度和纬度。我假设整个地图集都有标准化的坐标,它映射了整个openGL上下文。除了坐标外,我会用时间和日期过滤数据,但这是一个很容易做到的if条件。因为我拥有的像素坐标不会精确地映射到那个坐标,所以我现在将使用一个小的delta值来解决这个问题,并且我将使用该delta值来预计算靠近那个坐标的其他点

现在,我在iGPU上出现了一些驱动程序崩溃(应该是内存不足或类似的情况),即使我想在2中为嵌套循环添加一些内容,或者即使我使用了丢弃

我现在的代码是 注意f_time是时间的过滤器,现在我有一个滑块,以便与值进行一些交互

精密中泵浮子; 精密中泵

const int maxTextureSize = 2048;
varying vec2 v_texCoord;
uniform sampler2D u_texture;

uniform float f_time; 
uniform ivec2 textureDimensions;

void main(void) {
    float delta = 0.001;// now bigger delta just to make it work then we tune it

    // compute 1 pixel in texture coordinates.
    vec2 onePixel = vec2(1.0, 1.0) / float(textureDimensions.x);
    vec2 position = ( gl_FragCoord.xy /  float(textureDimensions.x) );

    vec4 color =  texture2D(u_texture, v_texCoord);
    vec4 outColor = vec4(0.0);

    float dist_x = distance( color.r, gl_FragCoord.x);
    float dist_y = distance( color.g, gl_FragCoord.y);
    //float dist_x = distance( color.g, gl_PointCoord.s);
    //float dist_y = distance( color.b, gl_PointCoord.t);
    for(int i = 0; i < maxTextureSize; i++){
        if(i < textureDimensions.x ){
            break;
        }

        for(int j = 0; j <  maxTextureSize ; j++){
                if(j < textureDimensions.y ){
                    break;
                }
             // Where i am stuck now how to get the texture coordinate and test it with fragment shader
                // the precomputation
            vec4 pixel= texture2D(u_texture,vec2(i,j));
            if(pixel.r > f_time){
                    outColor = vec4(1.0, 1.0, 1.0, 1.0);
                    // for now just break, no delta calculation to sum this point with others so that 
                    // we will have an approximation of other points into that pixel
                        break;
                }
            }
    }

    // this works   
    if(color.t > f_time){
        //gl_FragColor = color;//;vec4(1.0, 1.0, 1.0, 1.0);
    }

    gl_FragColor = outColor;
}
const int maxTextureSize=2048;
可变矢量2 v_texCoord;
均匀的二维u_纹理;
均匀浮动f_时间;
均匀的纹理尺寸;
真空总管(真空){
float delta=0.001;//现在更大的delta只是为了让它工作,然后我们调整它
//计算纹理坐标中的1个像素。
vec2 onePixel=vec2(1.0,1.0)/float(textureDimensions.x);
vec2位置=(gl_FragCoord.xy/float(textureDimensions.x));
vec4颜色=纹理2D(u_纹理,v_纹理坐标);
vec4-outColor=vec4(0.0);
浮动距离x=距离(color.r,gl\u FragCoord.x);
float dist_y=距离(color.g,gl_FragCoord.y);
//float dist_x=距离(color.g,gl_PointCoord.s);
//float dist_y=距离(color.b,gl_PointCoord.t);
对于(int i=0;if_时间){
outColor=vec4(1.0,1.0,1.0,1.0);
//现在只需中断,没有增量计算来与其他点求和,以便
//我们将有一个其他点到该像素的近似值
打破
}
}
}
//这很有效
if(color.t>f_时间){
//gl_FragColor=color;//;vec4(1.0,1.0,1.0,1.0);
}
gl_FragColor=色彩;
}

您试图做的事情根本不可行

您尝试访问纹理的次数最多可达400万次,全部在单个片段着色器调用中

现代GPU通常检测无限循环条件的方式是通过查看着色器运行的时间,然后在着色器运行“太长”时将其杀死,该时间通常足够长。您的代码可以进行多达400万次纹理访问,几乎肯定会触发这种情况

这通常会导致GPU复位

一般来说,在纹理中找到与某个片段相关联的位置的方法是直接这样做。也就是说,在屏幕片段位置(
gl_FragCoord
)和纹理中的纹理之间创建1:1的对应关系。这样,纹理不需要包含X/Y坐标,每个片段着色器都可以访问用于该特定调用的数据

您试图做的似乎是将一个大表(四百万个元素)传递给GPU,然后让GPU处理它。值的顺序(通常)不相关;任何值都可能修改任何像素。某些像素没有应用值,而其他像素可能应用了多个值

这是串行程序员的思维,而不是并行思维。在CPU上编写代码的方法是遍历表中的每个元素,查看它的位置,并为每个像素生成结果

在并行算法中,不是这样工作的。每次调用都需要能够立即在应用于它的表中找到数据。您不应该在表格中搜索数据。尤其不是线性搜索

您需要从片段着色器的角度来考虑这一点

在数据表中,对于屏幕上的每个位置,都有一个适用于该屏幕位置的数据值列表。对的您需要做的是使该列表直接可用于每个片段着色器调用。由于每个片段的列表的大小不是恒定的,所以需要使用链表而不是固定大小的数组

要执行此操作,请构建渲染目标大小的纹理。纹理中的每个texel指定此片段需要处理的第一个元素在数据表中的位置。这为每个片段着色器调用提供了其第一个元素的位置。由于某些片段着色器可能没有应用到它们的数据,因此需要留出一些特殊的纹理坐标值来表示“无”

数据表中的数据由时间和日期组成,但不是“经度/纬度”,而是纹理中应用于该片段着色器的下一个纹理的纹理坐标。这就是在着色器中创建链接列表的方式。数据表中的每个位置都指定要处理的下一个位置

如果该位置是要处理的最后一个数据,则该位置将是以前的“无”值

您还应该使用或保存数据ta