2015-05-26 3 views
0

Я пытаюсь использовать WEBGL_draw_buffers с OES_texture_float, который работает. Однако при использовании двух целей рендеринга с другим типом это не работает на моей машине Windows (amd). Тем не менее, он работает на моей Linux-машине (драйвер с открытым исходным кодом Radeon).Webgl: цветные вложения с различными форматами не работают на окнах

Так фреймбуфера со следующими приложениями цвета не работает на окнах:

крепежных 0: RGB * байты без знака

вложение 1: RGB * поплавок

но следующее макет не работает:

приложение 0: rgb * float

вложение 1: RGB * поплавок

Я написал небольшую тестовую программу, которая иллюстрирует проблему:

<!DOCTYPE html> 
 
<html> 
 

 
<head> 
 
</head> 
 

 
<body> 
 
    <script type="text/javascript"> 
 
    var canvas = document.createElement('canvas'); 
 
    var gl = canvas.getContext("webgl"); 
 

 
    var WEBGL_draw_buffers = gl.getExtension("WEBGL_draw_buffers") || gl.getExtension("GL_EXT_draw_buffers") || gl.getExtension("EXT_draw_buffers"); 
 
    gl.getExtension("OES_texture_float"); 
 
    gl.getExtension("WEBGL_depth_texture"); 
 

 

 

 
    var result = ""; 
 
    result += "UNSIGNED_BYTE, FLOAT: " + test(gl.UNSIGNED_BYTE, gl.FLOAT) + "<br />"; 
 
    result += "FLOAT, FLOAT: " + test(gl.FLOAT, gl.FLOAT); 
 

 
    var div = document.createElement('div'); 
 
    div.innerHTML = result; 
 
    document.body.appendChild(div); 
 

 

 
    function setParams() { 
 
     gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 
 
     gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 
 
     gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); 
 
     gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); 
 
    } 
 

 
    function test(type1, type2) { 
 
     var w = 2, h = 2; 
 

 
     var t1 = gl.createTexture(); 
 
     gl.bindTexture(gl.TEXTURE_2D, t1); 
 
     setParams(); 
 
     gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, w, h, 0, gl.RGB, type1, null); 
 

 

 
     var t2 = gl.createTexture(); 
 
     gl.bindTexture(gl.TEXTURE_2D, t2); 
 
     setParams(); 
 
     gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, w, h, 0, gl.RGB, type2, null); 
 

 

 
     var framebuffer = gl.createFramebuffer(); 
 
     gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); 
 

 
     WEBGL_draw_buffers.drawBuffersWEBGL([WEBGL_draw_buffers.COLOR_ATTACHMENT0_WEBGL, WEBGL_draw_buffers.COLOR_ATTACHMENT1_WEBGL]); 
 

 

 
     gl.framebufferTexture2D(gl.FRAMEBUFFER, WEBGL_draw_buffers.COLOR_ATTACHMENT0_WEBGL, gl.TEXTURE_2D, t1, 0); 
 
     gl.framebufferTexture2D(gl.FRAMEBUFFER, WEBGL_draw_buffers.COLOR_ATTACHMENT1_WEBGL, gl.TEXTURE_2D, t2, 0); 
 

 
     var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER); 
 

 

 
     gl.bindFramebuffer(gl.FRAMEBUFFER, null); 
 

 

 
     switch (status) { 
 
     case gl.FRAMEBUFFER_COMPLETE: 
 
      return "FRAMEBUFFER_COMPLETE"; 
 
     case gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT: 
 
      return "FRAMEBUFFER_INCOMPLETE_ATTACHMENT"; 
 
     case gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: 
 
      return "FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"; 
 
     case gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS: 
 
      return "FRAMEBUFFER_INCOMPLETE_DIMENSIONS"; 
 
     case gl.FRAMEBUFFER_UNSUPPORTED: 
 
      return "FRAMEBUFFER_UNSUPPORTED"; 
 
     default: 
 
      return "Error: " + status; 
 
     } 
 
    } 
 
    </script> 
 
</body> 
 

 
</html>

На окнах это выходы:

UNSIGNED_BYTE, FLOAT: FRAMEBUFFER_UNSUPPORTED 
FLOAT, FLOAT: FRAMEBUFFER_COMPLETE 

и на linux эти выходы:

UNSIGNED_BYTE, FLOAT: FRAMEBUFFER_COMPLETE 
FLOAT, FLOAT: FRAMEBUFFER_COMPLETE 

Хотелось бы знать почему. Обратите внимание, что мои результаты одинаковы в firefox и chrome.

Обновление: когда использование angle отключено в Windows, оно будет вести себя точно так же, как Linux.

ответ

0

Я ответил на Reddit, но я скопирую сюда же:

Насколько я понимаю, это «правильный», что водитель отклонить несколько цветовых буферов, которые не имеют одинаковое число битовых плоскостей для всех цветов (см https://www.khronos.org/registry/gles/extensions/EXT/EXT_draw_buffers.txt выпуска 5), а также в соответствии с разделом 4.0 спецификации OpenGLES2: «все цветовые буфера, прикрепленные к объекту фреймбуфера приложений, созданные должны иметь одинаковое количество битовых плоскостей»

я прочитал, что, как и все цвета, прикрепленные к выходу фрагмента, должны иметь одинаковую глубину бита, что не так, если у некоторых есть 8 бит (беззнаковый байт) и другие 32 (float).

Возможно, что драйвер Linux не соответствует строго спецификации или реализует расширение, которое смягчает это ограничение. Другими словами, вы не можете полагаться на драйвер, поддерживающий несколько цветовых выходов разной битовой глубины.

0

Для использования WebGL требуется только 3 комбинации приложений.

From the spec

следующих комбинаций фреймбуфера вложений объектов, когда все вложения крепления фреймбуфера завершена, не равен нулю, и имеют одинаковую ширину и высоту, должны привести к фреймбуфером быть фреймбуфера полным:

  • COLOR_ATTACHMENT0 = RGBA/UNSIGNED_BYTE текстуры
  • COLOR_ATTACHMENT0 = RGBA/UNSIGNED_BYTE текстуры + DEPTH_ATTACHMENT = DEPTH_COMPONENT16 renderbuffer
  • COLOR_ATTACHMENT0 = RGBA/UNSIGNED_BYTE текстуры + DEPTH_STENCIL_ATTACHMENT = DEPTH_STENCIL renderbuffer

Расширение WEBGL_draw_buffers добавляет несколько больше. From that spec.

Если: цветные вложения фреймбуфер являются все текстуры, наделенные формате RGBA и типа UNSIGNED_BYTE и фреймбуфера имеет либо:

  • Нет глубины или трафарета крепления

  • Действительный DEPTH или DEPTH_STENCIL

Тогда вызов checkFramebufferStatus против этого фреймбуфера не должен возвращать FRAMEBUFFER_UNSUPPORTED. (Другими словами, реализация должна поддерживать использование RGBA/UNSIGNED_BYTE текстур в виде цветных вложений, а также либо DEPTH или DEPTH_STENCIL вложение.)

Прикрепление п последовательных цветовых вложения, начиная с COLOR_ATTACHMENT0_WEBGL, где п между 1 и MAX_DRAW_BUFFERS_WEBGL, не должен возвращать FRAMEBUFFER_UNSUPPORTED из вызова checkFramebufferStatus.Другими словами, если MAX_DRAW_BUFFERS_WEBGL равно 4, то реализация должна поддерживать следующие комбинации цветовых вложений:

  • COLOR_ATTACHMENT0_WEBGL = RGBA/UNSIGNED_BYTE

  • COLOR_ATTACHMENT0_WEBGL = RGBA/UNSIGNED_BYTE COLOR_ATTACHMENT1_WEBGL = RGBA/UNSIGNED_BYTE

  • COLOR_ATTACHMENT0_WEBGL = RGBA/UNSIGNED_BYTE COLOR_ATTACHMENT1_WEBGL = RGBA/UNSIGNED_BYTE COLOR_ATTACHMENT2_WEBGL = RGBA/UNSIGNE D_BYTE

  • COLOR_ATTACHMENT0_WEBGL = RGBA/UNSIGNED_BYTE COLOR_ATTACHMENT1_WEBGL = RGBA/UNSIGNED_BYTE COLOR_ATTACHMENT2_WEBGL = RGBA/UNSIGNED_BYTE COLOR_ATTACHMENT3_WEBGL = RGBA/UNSIGNED_BYTE

ВСЕ другие комбинации зависят драйвера.

Как @Kimixa упоминает комбинации списков спецификаций, которые не будут работать, но, наоборот, спецификация также говорит, какие комбинации работают на 100% зависимой от драйвера. Фактически в OpenGL ES 2.0 даже те, о которых говорилось выше, не обязаны работать. WebGL добавил это требование поверх OpenGL ES 2.0

Это также одна из причин, почему WEBGL_draw_buffers не включен на некоторых графических процессорах. Chrome проверяет все необходимые комбинации при первом запуске WebGL. Если драйвер не возвращает FRAMEBUFFER_COMPLETE для каждой необходимой комбинации, то Chrome не разрешает расширение WEBGL_draw_buffers.

За исключением необходимых комбинаций, единственный способ узнать, будет ли работать определенная комбинация, - установить их, а затем проверить с помощью gl.checkFramebufferStatus.

Смежные вопросы