首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有mipmap级别的glFramebufferTexture2D on webgl2

具有mipmap级别的glFramebufferTexture2D on webgl2
EN

Stack Overflow用户
提问于 2019-03-02 12:04:28
回答 1查看 877关注 0票数 1

使用ES3.0派生的webGL2,我认为我们可以使用mipmap级别作为以下的最后一个参数:

代码语言:javascript
复制
void glFramebufferTexture2D(GLenum target,
GLenum attachment,
GLenum textarget,
GLuint texture,
GLint level);

现在,从Khronos ES3.0官方文档中可以看出,mipmap级别应该正常工作:

级别:指定要附加的纹理的mipmap级别。

相反,它说它必须是0

级别:指定要附加的纹理图像的mipmap级别,必须为0。

现在,我无法从WebGL2.0上下文中找到关于glFramebufferTexture2D的任何文档,但是mozilla声明mipmap层必须为0,如ES2.0中的:Mozilla WebGL文档

级别:指定要附加的纹理图像的mipmap级别的GLint。一定是0。

我认为该页面引用了WebGL1上下文,但其中提到了WebGL2特性,而且我在WebGL2文档中找不到glFramebufferTexture2D。

因此,是否有一种方法可以在WebGL2.0上的框架缓冲区目标上使用mipmap级别?

(我看过分层图像,但WebGL2.0没有AFAIK分层呈现)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-03-02 13:33:27

是否有一种方法可以在WebGL2.0的框架缓冲区目标上使用mipmap级别

我会在这里结束答案,但我想我想知道你真的尝试了什么,但它不起作用吗?您必须创建一个WebGL2上下文来使用mipmap级别作为框架缓冲区附件,但如果不是这样的话,它可以工作。在WebGL1上,这是行不通的。

代码语言:javascript
复制
function main() {
  const gl = document.querySelector('canvas').getContext('webgl2');
  if (!gl) {
    return alert('need webgl2');
  }
  
  const vs = `#version 300 es
  void main() {
    // just draw an 8x8 pixel point in the center of the target
    // this shader needs/uses no attributes
    gl_Position = vec4(0, 0, 0, 1);
    gl_PointSize = 8.0;
  }
  `;
  const fsColor = `#version 300 es
  precision mediump float;
  uniform vec4 color;
  out vec4 outColor;
  void main() {
    outColor = color;
  }
  `;
  const fsTexture = `#version 300 es
  precision mediump float;
  uniform sampler2D tex;
  out vec4 outColor;
  void main() {
    // this shader needs no texcoords since we just
    // use gl_PoitnCoord provided by rendering a point with gl.POINTS
    // bias lets select the mip level so no need for 
    // some fancier shader just to show that it's working.        
    float bias = gl_PointCoord.x * gl_PointCoord.y * 4.0;
    outColor = texture(tex, gl_PointCoord.xy, bias);
  }
  `;
  
  // compile shaders, link into programs, look up attrib/uniform locations
  const colorProgramInfo = twgl.createProgramInfo(gl, [vs, fsColor]);
  const textureProgramInfo = twgl.createProgramInfo(gl, [vs, fsTexture]);
  
  const tex = gl.createTexture();
  gl.bindTexture(gl.TEXTURE_2D, tex);
  const levels = 4;
  const width = 8;
  const height = 8;
  gl.texStorage2D(gl.TEXTURE_2D, levels, gl.RGBA8, width, height);
  
  // make a framebuffer for each mip level
  const fbs = [];
  for (let level = 0; level < levels; ++level) {
    const fb = gl.createFramebuffer();
    fbs.push(fb);
    gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
    gl.framebufferTexture2D(
        gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
        gl.TEXTURE_2D, tex, level);
  }
  
  // render a different color to each level
  const colors = [
    [1, 0, 0, 1],  // red
    [0, 1, 0, 1],  // green
    [0, 0, 1, 1],  // blue
    [1, 1, 0, 1],  // yellow
  ];
  gl.useProgram(colorProgramInfo.program);
  for (let level = 0; level < levels; ++level) {
    gl.bindFramebuffer(gl.FRAMEBUFFER, fbs[level]);
    const size = width >> level;
    gl.viewport(0, 0, size, size);
    twgl.setUniforms(colorProgramInfo, { color: colors[level] });
    const offset = 0;
    const count = 1;
    gl.drawArrays(gl.POINTS, offset, count);  // draw 1 point
  }
  
  // draw the texture's mips to the canvas
  gl.bindFramebuffer(gl.FRAMEBUFFER, null);
  gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
  gl.useProgram(textureProgramInfo.program);
  // no need to bind the texture it's already bound
  // no need to set the uniform it defaults to 0
  gl.drawArrays(gl.POINT, 0, 1);  // draw 1 point
}
main();
代码语言:javascript
复制
<script src="https://twgljs.org/dist/4.x/twgl-full.min.js"></script>
<canvas width="8" height="8" style="width: 128px; height: 128px;"></canvas>

您还可以将TEXTURE_2D_ARRAY纹理呈现给各层。

代码语言:javascript
复制
function main() {
  const gl = document.querySelector('canvas').getContext('webgl2');
  if (!gl) {
    return alert('need webgl2');
  }
  
  const vs = `#version 300 es
  void main() {
    // just draw an 8x8 pixel point in the center of the target
    // this shader needs/uses no attributes
    gl_Position = vec4(0, 0, 0, 1);
    gl_PointSize = 8.0;
  }
  `;
  const fsColor = `#version 300 es
  precision mediump float;
  uniform vec4 color;
  out vec4 outColor;
  void main() {
    outColor = color;
  }
  `;
  const fsTexture = `#version 300 es
  precision mediump float;
  uniform mediump sampler2DArray tex;
  out vec4 outColor;
  void main() {
    // this shader needs no texcoords since we just
    // use gl_PoitnCoord provided by rendering a point with gl.POINTS
    float layer = gl_PointCoord.x * gl_PointCoord.y * 4.0;
    outColor = texture(tex, vec3(gl_PointCoord.xy, layer));
  }
  `;
  
  // compile shaders, link into programs, look up attrib/uniform locations
  const colorProgramInfo = twgl.createProgramInfo(gl, [vs, fsColor]);
  const textureProgramInfo = twgl.createProgramInfo(gl, [vs, fsTexture]);
  
  const tex = gl.createTexture();
  gl.bindTexture(gl.TEXTURE_2D_ARRAY, tex);
  const levels = 1;
  const width = 8;
  const height = 8;
  const layers = 4;
  gl.texStorage3D(gl.TEXTURE_2D_ARRAY, levels, gl.RGBA8, width, height, layers);
  // only use level 0 (of course we could render to levels in layers as well)
  gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  
  // make a framebuffer for each layer
  const fbs = [];
  for (let layer = 0; layer < layers; ++layer) {
    const fb = gl.createFramebuffer();
    fbs.push(fb);
    gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
    const level = 0;  
    gl.framebufferTextureLayer(
        gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
        tex, level, layer);
  }
  
  // render a different color to each layer
  const colors = [
    [1, 0, 0, 1],  // red
    [0, 1, 0, 1],  // green
    [0, 0, 1, 1],  // blue
    [1, 1, 0, 1],  // yellow
  ];
  gl.useProgram(colorProgramInfo.program);
  for (let layer = 0; layer < layers; ++layer) {
    gl.bindFramebuffer(gl.FRAMEBUFFER, fbs[layer]);
    gl.viewport(0, 0, width, height);
    twgl.setUniforms(colorProgramInfo, { color: colors[layer] });
    const offset = 0;
    const count = 1;
    gl.drawArrays(gl.POINTS, offset, count);  // draw 1 point
  }
  
  // draw the texture's mips to the canvas
  gl.bindFramebuffer(gl.FRAMEBUFFER, null);
  gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
  gl.useProgram(textureProgramInfo.program);
  // no need to bind the texture it's already bound
  // no need to set the uniform it defaults to 0
  gl.drawArrays(gl.POINT, 0, 1);  // draw 1 point
}
main();
代码语言:javascript
复制
<script src="https://twgljs.org/dist/4.x/twgl-full.min.js"></script>
<canvas width="8" height="8" style="width: 128px; height: 128px; image-rendering: pixelated;"></canvas>

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54958323

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档