簡體   English   中英

GLSL:內存耗盡

[英]GLSL: memory exhausted

我正在使用約100種不同的2048 x 2048像素紋理的WebGL場景。 我正在渲染點基元,每個點都有一個紋理索引和紋理uv偏移,這些偏移指示應該在該點上使用的給定紋理的區域。

最初,我嘗試將每個點的紋理索引作為varying值傳遞,然后嘗試使用該索引位置從sampler2D數組中提取給定的紋理。 但是,這產生了一個錯誤,即人們只能使用“恆定整數表達式”來獲取sampler2D數組值,因此,現在我使用一個粗糙的條件分配每個點的紋理索引:

/**
* 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 x 2048,因此無法將ghem增大。

如果不想將自己局限於WebGL2,則必須將渲染分為具有不同紋理集的多個繪制調用。

還應考慮擁有100個8位RGBA 2048x2048紋理會占用1.6 GB的VRAM。 通過WEBGL_compressed_texture_s3tc進行紋理壓縮可以將壓縮WEBGL_compressed_texture_s3tc降低8倍或4倍,具體取決於所需的alpha精度。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM