无法获得使用图像的WebGL2纹理的有效示例

时间:2018-10-26 03:38:08

标签: webgl2

我环顾四周,找不到一个简单的示例来展示使用多个图像映射到任何几何图形的3D纹理。

我找到了以下示例:

1)http://webglsamples.org/WebGL2Samples/#texture_3d 2)https://webgl2fundamentals.org/webgl/lessons/webgl-data-textures.html

在第一个示例中,我无法使用图像作为数据源来使其工作。在第二个示例中,它不使用3D纹理。

如果有显示3D纹理将多个图像(例如JPG)映射到平面上的示例,那将非常有帮助

1 个答案:

答案 0 :(得分:1)

这是一个小样本。它为图像使用dataURLs,但是只要它们都是相同的尺寸,它们就可以像普通图像一样容易。如果它们的尺寸不同,则必须对其进行缩放,以使其处于脱机状态或通过画布或其他方式。

否则,样本将不设置任何制服,因为制服的默认值为0。它仅使用gl.POINTSgl_PointSizegl_PointCoord作为坐标绘制一个点,因此没有缓冲区或所需的属性

const imageURLs = [
  "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAUVBMVEX/BgD/////9vb/6ur/29v/fnz/a2n/VlP/Qz7/MSr/HxL/y8r/urn/kpH/p6YAWFkAbG0ARUUANDQA29wAy8wAursAp6gAk5QAgIEAJCQAFRVoLfwBAAAAW0lEQVQY04XGRw6FMBTF0Pt7oQXSs/+FEp5nTDiSJet2ovuJHmitMXqi1spoMFvHaTysh9Fo7hYzG02dc5PrGb1QSmH0Rs6Z0QcpJUZfxBgZ/RBCYPSH957RpR17cQhbwmkrjgAAAABJRU5ErkJggg==",
  "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAUVBMVEWH/wD////7//bT/6PK/42//3e2/2Ks/0mi/y/1/+nu/9rl/8nd/7dqAN9jAM6a/wiR/wAhAEYZADURACUKABVZAL1QAKpHAJY9AII0AG4qAFrKpkVwAAAAXElEQVQY04XGNwKAMBADQZFzsMHx/w/lgmlomEJaVB+oPzCJm2hhZpeQxEKstToEKzHG6BA0r5wzH9pXSokPXRFjlEevQggaGIT3flAYmXNuLHCQveDGSbaCG78ep3wInxKnersAAAAASUVORK5CYII=",
  "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAS1BMVEUA/v/7//+k//9k/v/p//+P//95/v+4///a///J//9N/v80/v8Y/v/NAAC8AACpAAA1AAAlAABGAADeAACCAABtAAAVAACVAABZAABgJ6tzAAAAW0lEQVQY043IRw7AIAxE0UnvQEiB+580Y1tskk2exPgLVC/fj1bdZIVR7EoTE4UQbAiDiJGPQ6iLnLMcdOYiDfTmJA00RUpJDmby3tsQFnLO2RBWsSlNmIPw0wP2LQdICCV9sQAAAABJRU5ErkJggg==",
  "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAUVBMVEWDAP/////69v/06v+fOf+XIf+OAP/s2v/kyv/Spf/IkP/cuP+9e/9TqQBJlAC0Zv+pUP9AgQAjRgA2bQArWQAaNQASJABt3QBlzQBdvAALFQBmRdTVAAAAYklEQVQY04XGWRaFIAwD0LzBGQUUZdj/Qi2x/vjjPW0SfB7wfcBPlVLY6C6H4EBPe8WFqVqJE0MVglzgxCi2TV6igjHGe68hYK1dblbAOTffnMBf5ZzZaFRKiY1WxRjZeHUCx08IxkTd/o4AAAAASUVORK5CYII=",
];

const vs = `#version 300 es
void main() {
  gl_Position = vec4(0, 0, 0, 1);
  gl_PointSize = 150.0;
}
`

const fs = `#version 300 es
precision mediump float;
uniform mediump sampler3D tex;
out vec4 outColor;
void main() {
  vec3 uvw = vec3(gl_PointCoord.xy, gl_PointCoord.x * gl_PointCoord.y);
  outColor = texture(tex, uvw);
}
`;

function main() {
  const gl = document.querySelector('canvas').getContext("webgl2");
  if (!gl) { return console.log; ("need webgl2"); }
  
  const program = twgl.createProgram(gl, [vs, fs]);
  
  const tex = gl.createTexture();
  gl.bindTexture(gl.TEXTURE_3D, tex);
  gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  // we either need to preallocate the space OR we need to wait for 
  // one texture to download to find out the size. All the sizes have
  // to be the same as all slices are required to have the same dimensions
  
  // I happen to know all the images are 16x16 so
  const levels = 1;
  const internalFormat = gl.RGBA8;
  const width = 16;
  const height = 16;
  const depth = imageURLs.length;
  gl.texStorage3D(gl.TEXTURE_3D, levels, internalFormat, width, height, depth);
  
  // load the images
  imageURLs.forEach((url, ndx) => {
    const img = new Image();
    document.body.appendChild(img);  // so we can see the images;
    img.onload = () => {
      gl.bindTexture(gl.TEXTURE_3D, tex);
      
      const level = 0;
      const x = 0;
      const y = 0;
      const z = ndx;
      const depth = 1
      gl.texSubImage3D(
           gl.TEXTURE_3D, level, 
           x, y, z, width, height, depth, 
           gl.RGBA, gl.UNSIGNED_BYTE, img);

      // render each time an image comes in. This means
      // the first render will be missing 3 layers or rather
      // the'll be blank (0,0,0,0). We could wait for all images
      // to load instead.
      render();
    };
    img.src = url;
  });

  function render() {
    gl.useProgram(program);
    gl.drawArrays(gl.POINTS, 0, 1);  // 1 point
  }
}
main();
canvas {
  margin: .25em;
  border: 1px solid black;
}
img {
  margin: .25em;
  border: 1px solid black;
  width: 64px;
  height: 64px;
  image-rendering: pixelated;
}
<canvas></canvas>
<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>