首页 > 其他分享 >[WebGL] sampler2DArray demo 多纹理渲染

[WebGL] sampler2DArray demo 多纹理渲染

时间:2023-10-24 12:01:54浏览次数:42  
标签:demo WebGL sampler2DArray 纹理 height width RGBA imgs gl

背景

之前尝试过利用多个纹理单元,再基于传入给 shader 的 vertexBuffer 信息决定选 1 号纹理单元还是 2 号纹理单元。
虽然理论上,这个方式确实行得通,但是一次 drawcall 绘制多个纹理,本来目的是为了提高绘制性能,而实际上却无法提高性能,甚至还有反作用。
因为有说法是 shader 分支会降低 GPU 性能,详见:https://blog.csdn.net/qq_31788759/article/details/107248224

那么,是否还有其他批量绘制不同纹理的方式呢?

WebGL 2 sampler2DArray

WebGL 2 带来了一个新的数据结构:sampler2DArray。这个东西,还是占用一个纹理单元,但传入的不是一个纹理,而是一个纹理数组。
关键 shader 代码:

#version 300 es
precision mediump float;
precision mediump sampler2DArray;

// our texture
uniform sampler2DArray u_image;
// the texCoords passed in from the vertex shader.
in vec3 v_texCoord;
// we need to declare an output for the fragment shader
out vec4 outColor;

void main() {
    outColor = texture(u_image, v_texCoord); // 这里从一般的 vec2 变成了 vec3,第三个元素是纹理 index
}
</script>

相对于普通的 2d 纹理渲染,最关键的是 JS 如何传递纹理到 GPU。这里关键是类型 gl.TEXTURE_2D 变成 gl.TEXTURE_2D_ARRAY,texImage2D 变成 texImage3D。
有两种方式传递纹理:

  • 可以把多个纹理合并到一个大图,一次性推送;
  • 也可以先预申请空间,再用 texSubImage3D 逐个推送。
    关键 JS 代码:

    var canvas = document.createElement('canvas');
    canvas.width = imgs[0].width;
    canvas.height = imgs[0].height * imgs.length;
    var ctx = canvas.getContext('2d');
    for (let i = 0; i < imgs.length; i++) {
      ctx.drawImage(imgs[i], 0, imgs[0].height * i);
    }
    var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    var pixels = new Uint8Array(imageData.data.buffer);
    gl.texImage3D(
      gl.TEXTURE_2D_ARRAY,
      0, // level 暂时不知道什么地方会用到
      gl.RGBA, // internalFormat
      imgs[0].width, // width
      imgs[0].height, // height
      imgs.length, // depth 多少个纹理
      0, // border
      gl.RGBA, // format
      gl.UNSIGNED_BYTE, // type
      pixels
    );

    // 利用 texImage3D 设定空间,再用 texSubImage3D 设置图片。texImage3D 创建空间时,宽高设定很重要,后续的尺寸不能超过这个尺寸。如果后续尺寸比这个小,会导致渲染时图片偏小,也很好理解,因为 subImage 传递的只是左上角一小部分的图片,其他面积为空白。
    gl.texImage3D(
      gl.TEXTURE_2D_ARRAY,
      0, // level 暂时不知道什么地方会用到
      gl.RGBA, // internalFormat
      imgs[0].width, // width
      imgs[0].height, // height
      imgs.length, // depth 多少个纹理
      0, // border
      gl.RGBA, // format
      gl.UNSIGNED_BYTE, // type
      null
    );
    /**
     * 用 texStorage3D 搭配 texSubImage3D 也可以。但这里需要时 RGBA8 不是 RGBA。
     * 因为选项里边没有 RGBA https://developer.mozilla.org/en-US/docs/Web/API/WebGL2RenderingContext/texStorage3D
     * 另外,这里不是指输入图片的格式,是指把图片转为什么格式存储。
     * texImage3D 的 gl.RGBA 默认情况下跟 gl.RGBA8 一致
     */
    // gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, imgs[0].width, imgs[0].height,3);
    gl.texSubImage3D(
      gl.TEXTURE_2D_ARRAY,
      0, // level 暂时不知道什么地方会用到
      0, // x offset
      0, // y offset
      0, // z offset 不能超过前边预留的 depth
      imgs[0].width, // width
      imgs[0].height, // height
      1, // depth 多少个纹理
      gl.RGBA, // format
      gl.UNSIGNED_BYTE, // type
      imgs[0]
    );
    gl.texSubImage3D(
      gl.TEXTURE_2D_ARRAY,
      0, // level 暂时不知道什么地方会用到
      0,
      0,
      1,
      imgs[0].width, // width
      imgs[0].height, // height
      1, // depth 多少个纹理
      gl.RGBA, // format
      gl.UNSIGNED_BYTE, // type
      imgs[1]
    );
    gl.texSubImage3D(
      gl.TEXTURE_2D_ARRAY,
      0, // level 暂时不知道什么地方会用到
      0,
      0,
      2,
      imgs[0].width, // width
      imgs[0].height, // height
      1, // depth 多少个纹理
      gl.RGBA, // format
      gl.UNSIGNED_BYTE, // type
      imgs[2]
    );


详细代码请见:https://github.com/kenkozheng/HTML5_research/tree/master/WebGL/sampler2DArray

参考资料

https://www.nxrte.com/jishu/19240.html
https://juejin.cn/post/6844903846678888461
https://developer.mozilla.org/en-US/docs/Web/API/WebGL2RenderingContext/texImage3D
https://github.com/WebGLSamples/WebGL2Samples/blob/master/samples/texture_2d_array.html

标签:demo,WebGL,sampler2DArray,纹理,height,width,RGBA,imgs,gl
From: https://www.cnblogs.com/kenkofox/p/17784404.html

相关文章

  • Hello-FPGA CoaXPress 2.0 FPGA HOST IP Core PCIe Demo User Manual
     目录1说明42设备连接73VIVADOFPGA工程84调试说明9图1‑1资料目录4图1‑2VIVADO工程目录结构5图1‑3VS软件工程目录5图1‑4CXPHOSTPCIeBlockDesign5图1‑5VS工程6图1‑6CXPcamera6图1‑7KC705搭载Hello-FPGACoaXPress2.0FMC子......
  • 【已应用】落地项目中使用的JdbcTemplate-包含application.properties配置 【JdbcTemp
    JdbcTemplatedemo2:是某落地项目中使用的JdbcTemplate。是来检测JdbcTemplate合规性。包含JdbcTemplate封装、sql操作、application.properties数据连接配置等。GitLab项目地址:liuguiqing/JdbcTemplateDemo2·GitLab相关截图:   ......
  • JdbcTemplate基础【项目demo】【基础知识】【简单明了,一眼就会】
    jdbcTemplateDemo以便更好的应用。注意:实际大型项目中service层为复杂的逻辑处理,请自行编写。JdbcTemplate例子源码(含sql):http://www.shicishu.com/down/JdbcTemplate_Demo.rar第一部分:层级关系说明:1、controller层:对外接口层。(一般调用service层。)2、service层:逻辑处理层、(审核......
  • Struct ForDemo03
    packagecom.chen.struct;publicclassForDemo03{publicstaticvoidmain(String[]args){//练习2:用while或for循环输出1-1000之间能被5整除的数,并且每行输出3个for(inti=0;i<100;i++){if(i%5==0){System.out.p......
  • Struct ForDemo01
    packagecom.chen.struct;importjava.util.Scanner;publicclassForDemo01{publicstaticvoidmain(String[]args){inta=1;//初始化条件while(a<100){//条件判断System.out.println(a);//循环体a+=2;//迭代}......
  • Struct ForDemo05
    packagecom.chen.struct;publicclassForDemo05{publicstaticvoidmain(String[]args){int[]numbers={10,20,30,40,50};for(inti=0;i<5;i++){System.out.println(numbers[i]);}System.out.println("=......
  • Struct ForDemo04
    packagecom.chen.struct;publicclassForDemo04{publicstaticvoidmain(String[]args){//打印九九乘法表//1.先打印第一列//2.把固定的1在用一个循环包起来//3.去掉重复项,i=j;//调整样式for(inti=1;i<=9;i......
  • Method Demo02
    packagecom.chen.method;publicclassDemo02{publicstaticvoidmain(String[]args){doublesum=sum(1.0,1.0);System.out.println(sum);}//比大小publicstaticdoublesum(doublea,doubleb){doubleresult=0;......
  • Method Demo01
    packagecom.chen.method;publicclassDemo01{//main方法publicstaticvoidmain(String[]args){intsum=add(1,2,3);System.out.println(sum);//test();}//加法publicstaticintadd(inta,intb){returna+......
  • SpringMVC自定义处理返回值demo和异步处理模式DeferredResult demo
    搭建自定义返回值处理器demo新建springboot项目修改pom.xml<!--新增依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><gro......