Opengl es 内存耗尽

Opengl es 内存耗尽,opengl-es,three.js,glsl,webgl,Opengl Es,Three.js,Glsl,Webgl,我正在使用大约100种不同的2048 x 2048 px纹理处理WebGL场景。我正在渲染点基本体,每个点都有一个纹理索引和纹理uv偏移,指示应该在点上使用的给定纹理区域 最初,我尝试将每个点的纹理索引作为一个可变值传递,然后尝试使用该索引位置从sampler2D数组中提取给定纹理。但是,这产生了一个错误,即只能使用“常量整数表达式”获取sampler2D数组值,因此现在我使用粗糙的if条件来指定每个点的纹理索引: /** * The fragment shader's main() funct

我正在使用大约100种不同的2048 x 2048 px纹理处理WebGL场景。我正在渲染点基本体,每个点都有一个纹理索引和纹理uv偏移,指示应该在点上使用的给定纹理区域

最初,我尝试将每个点的纹理索引作为一个
可变
值传递,然后尝试使用该索引位置从
sampler2D
数组中提取给定纹理。但是,这产生了一个错误,即只能使用“常量整数表达式”获取
sampler2D
数组值,因此现在我使用粗糙的if条件来指定每个点的纹理索引:

/**
* The fragment shader's main() function must define `gl_FragColor`,
* which describes the pixel color of each pixel on the screen.
*
* To do so, we can use uniforms passed into the shader and varyings
* passed from the vertex shader.
*
* Attempting to read a varying not generated by the vertex shader will
* throw a warning but won't prevent shader compiling.
**/

// set float precision
precision highp float;

// repeat identifies the size of each image in an atlas
uniform vec2 repeat;

// textures contains an array of textures with length n textures
uniform sampler2D textures[42];

// identify the uv values as a varying attribute
varying vec2 vUv; // blueprint uv coords
varying vec2 vTexOffset; // instance uv offsets
varying float vTexture; // set index of each object's vertex

void main() {
  int textureIndex = int(floor(vTexture));

  vec2 uv = vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y );

  // The block below is automatically generated
  if (textureIndex == 0) {vec4 color = texture2D(textures[0], uv * repeat + vTexOffset ); }
  else if (textureIndex == 1) { vec4 color = texture2D(textures[1], uv * repeat + vTexOffset );  } 
  else if (textureIndex == 2) { vec4 color = texture2D(textures[2], uv * repeat + vTexOffset );  } 
  else if (textureIndex == 3) { vec4 color = texture2D(textures[3], uv * repeat + vTexOffset );  } 
  [ more lines of the same ... ]
  gl_FragColor = color;

}
如果纹理的数量很小,则效果很好。但是,如果纹理数量较大(例如40),此方法会引发:

错误:0:58:“[”:内存已耗尽

我已经试着阅读了关于这个错误的文章,但仍然不确定它的含义。我是否超过了GPU中的最大RAM?如果有人知道这个错误的含义,和/或我能做些什么来解决这个问题,我将非常感谢您提供的任何提示

更多详细信息:
要加载的所有纹理的总大小:58MB
浏览器:最近的Chrome

图形卡:AMD Radeon R9 M370X 2048 MB图形(库存2015 OSX卡)

碎片着色器可以访问的采样器数量有限制。可以通过
gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS)
获得。它保证至少为8个,通常为16或32个

为了避免这一限制,WebGL2中提供了纹理数组,这也允许使用任何变量对层进行索引。在WebGL1中,您唯一的选择是地图集,但由于到2048年,您的纹理已经达到2048,因此无法使ghem变得更大

如果不想将自己限制为WebGL2,则必须将渲染拆分为多个绘制调用,并设置不同的纹理


还考虑了100个8位RGBA2048×2048纹理使用了1.6千兆字节的VRAM。纹理压缩通过<代码> WebGLyStudioStuluxS3TC/<代码>可以减少8X或4X,这取决于您需要多少alpha精度。

< P> >一个片段着色器可以访问多少个限制。它可以通过<代码> G.GETPA获得。参数(gl.MAX\u TEXTURE\u IMAGE\u UNITS)。保证至少为8,通常为16或32

为了避免这一限制,WebGL2中提供了纹理数组,这也允许使用任何变量对层进行索引。在WebGL1中,您唯一的选择是地图集,但由于到2048年,您的纹理已经达到2048,因此无法使ghem变得更大

如果不想将自己限制为WebGL2,则必须将渲染拆分为多个绘制调用,并设置不同的纹理


还考虑有100个8位RGBA2048×2048纹理使用1.6千兆字节的VRAM。纹理压缩通过<代码> WebGLyStudioStuluxS3Tc<代码>可以减少8X或4X,这取决于您需要多少alpha精度。< /P> <代码> GL.GETPARCH(GL.Max TrimulyIGIMAGE单元)的值是什么??取样器不能再多了。在WebGL2中,你可以使用纹理数组,否则你必须使用地图集。VRAM也可能是一个问题-一个8位rgba 2048到2048的纹理是16MB,所以你总共需要1.6GB。谢谢@riv

gl.getParameter(gl.MAX\u texture\u IMAGE\u UNITS)
返回16。我想我需要将渲染分为不同的绘制调用……让@riv的精彩评论的一部分更加明确:您报告的“要加载的所有纹理的总大小”考虑了磁盘上的大小,这与您的问题完全无关。重要的是(GPU)中的大小内存。如果你真的需要显示100个2048x2048纹理,你可能需要研究纹理压缩。@Paul Jan谢谢你的注释。我知道,纹理压缩只是为了帮助I/o,还是可以减少GPU中的RAM占用?你知道处理大量纹理数据的其他技术吗?@duhaime纹理压缩确实减少了纹理的GPU内存占用,这正是它创建的目的。有关简明的介绍,请参阅。
gl.getParameter(gl.MAX\u texture\u IMAGE\u UNITS)的值是多少
?取样器不能再多了。在WebGL2中,你可以使用纹理数组,否则你必须使用地图集。VRAM也可能是一个问题-一个8位rgba 2048到2048的纹理是16MB,所以你总共需要1.6GB。谢谢@riv
gl.getParameter(gl.MAX\u texture\u IMAGE\u UNITS)
返回16。我想我需要将渲染分为不同的绘制调用……让@riv的精彩评论的一部分更加明确:您报告的“要加载的所有纹理的总大小”考虑了磁盘上的大小,这与您的问题完全无关。重要的是(GPU)中的大小内存。如果你真的需要显示100个2048x2048纹理,你可能需要研究纹理压缩。@Paul Jan谢谢你的注释。我知道,纹理压缩只是为了帮助I/o,还是可以减少GPU中的RAM占用?你知道处理大量纹理数据的其他技术吗?@duhaime纹理压缩确实减少了纹理的GPU内存占用,这正是它创建的目的。有关简明的介绍,请参阅。