图形学之纹理后续/WebGL多纹理处理

背景 【图形学之纹理后续/WebGL多纹理处理】本篇收录于《数据可视化和图形学》专栏

之前介绍纹理相关的理论及简单使用 有需要可以参考上文 , 在上文基础进行多纹理实践(更多是帮助群内小伙伴提前脱坑!!!!)
本篇大纲
  1. 多纹理渲染实现思路
  2. 多纹理渲染coding(几种场景)
1. 多纹理渲染实现思路
多纹理渲染更多是指 gl_FragColor采取混合纹理 texture2D * texture2D的关系。本篇初衷为了帮助群里小伙伴的进阶坎坷路~会提到多vertex(纹理)渲染 然后坐标重叠的需求。
  1. 定义vertexArray(本文示例为2point)
  2. 定义textureArray
  3. 创建缓冲区(此处注意多渲染节点公用缓冲区情况)
  4. 按部就班依此注册shader.绑定数据,渲染。
多纹理渲染coding(几种场景)
第一种 gl_FragColor采取混合纹理 texture2D * texture2D
图形学之纹理后续/WebGL多纹理处理
文章图片
shader部分没什么难度...
// vertex attribute vec2 a_position; //坐标 attribute vec2 a_texCoord; //纹理uniform vec2 u_resolution; varying vec2 v_texCoord; void main() { //坐标转换像素->1.0,0.0... vec2 zeroToOne = a_position / u_resolution; vec2 zeroToTwo = zeroToOne * 2.0; vec2 clipSpace = zeroToTwo - 1.0; gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1); // 纹理 给fragment使用 v_texCoord = a_texCoord; }// fragment uniform sampler2D u_image0; // 纹理 uniform sampler2D u_image1; // 来自vertex shader varying vec2 v_texCoord; void main() { vec4 color0 = texture2D(u_image0, v_texCoord); vec4 color1 = texture2D(u_image1, v_texCoord); gl_FragColor = color0 * color1; // 可以理解为混合纹理 }

JavaScript 也很简单 创建节点坐标/纹理/shader&数据连接/渲染 搞定!
// 此处示意代码 完整代码上传github var texcoordBuffer = gl.createBuffer(); //纹理 gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer); // bufferData ... for(...images length){ // 循环遍历 gl.bindTexture(gl.TEXTURE_2D, texture); } var positionBuffer = gl.createBuffer(); //节点坐标此处绘制TRIANGLES 三角形 gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); // bufferData // 缓冲区分配给attribute变量 gl.vertexAttribPointer( texcoordLocation, size, type, normalize, stride, offset); gl.vertexAttribPointer( positionLocation, size, type, normalize, stride, offset); // 开启attribute变量 gl.enableVertexAttribArray(positionLocation); gl.enableVertexAttribArray(texcoordLocation); // 纹理!!!!激活纹理单元 gl.activeTexture(gl.TEXTURE0); //给定的纹理绑定到目标(vertex) gl.bindTexture(gl.TEXTURE_2D, textures[0]); // 绘制!!! 大功告成 gl.drawArrays(gl.TRIANGLES, 0, 6);

第二种 多个节点纹理(其实就是坐标重叠 后者覆盖前者...)
图形学之纹理后续/WebGL多纹理处理
文章图片
shader部分也没什么难度(没什么改变)...
// vertex attribute vec2 a_position; attribute vec2 a_texCoord; attribute lowp float textureIndex; uniform vec2 u_resolution; varying vec2 v_texCoord; varying lowp float indexPicker; void main() { vec2 zeroToOne = a_position / u_resolution; vec2 zeroToTwo = zeroToOne * 2.0; vec2 clipSpace = zeroToTwo - 1.0; gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1); v_texCoord = a_texCoord; indexPicker = textureIndex; // 控制fragment shader选哪一个纹理 }// fragment precision mediump float; // 纹理 uniform sampler2D u_image[2]; // the texCoords passed in from the vertex shader. varying vec2 v_texCoord; varying lowp float indexPicker; void main() { if (indexPicker < 0.5) { gl_FragColor = texture2D(u_image[0], v_texCoord); } else { gl_FragColor = texture2D(u_image[1], v_texCoord); } }

JavaScript 也很简单 创建节点坐标/纹理/shader&数据连接/渲染 搞定!
// 此处示意代码 完整代码上传github var texcoordBuffer = gl.createBuffer(); //纹理 gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer); // bufferData ... for(...images length){ // 循环遍历 gl.bindTexture(gl.TEXTURE_2D, texture); } // 注意vertex!!!!! 此处与上文不同 var positionBuffer = gl.createBuffer(); //节点坐标此处绘制TRIANGLES 三角形 gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); // bufferData // 缓冲区分配给attribute变量 gl.vertexAttribPointer( texcoordLocation, size, type, normalize, stride, offset); gl.vertexAttribPointer( positionLocation, size, type, normalize, stride, offset); // 开启attribute变量 gl.enableVertexAttribArray(positionLocation); gl.enableVertexAttribArray(texcoordLocation); // 纹理!!!!激活纹理单元 gl.activeTexture(gl.TEXTURE0); //给定的纹理绑定到目标(vertex) gl.bindTexture(gl.TEXTURE_2D, textures[0]); // 绘制!!! 大功告成 gl.drawArrays(gl.TRIANGLES, 0, vertextArray.length/2); // 绘制多个(三角形组合)正方形

!!!!注意 群里小伙伴留意代码中注释 (解决你的疑惑)
1.webgl-utils.js webgl相关函数封装工具库
完整代码示例 [请点击git仓库查看代码示例]
texture.html
texture1.html
2D渲染方面你可能需要了解的有
  1. 纹理缓存
  2. 纹理压缩
  3. 2D/2D纹理优化
  4. 渲染优化...
最后
最后强烈希望大家学习相关理论知识; 理论可能日常用到的地方很少,但是它能决定你走多远。(有的人问难怎么办,勤于练习吧) 写作速度我感觉我又行了,哈哈哈... 最近会持续更新(因为在自研自己的渲染引擎。唉 一言难尽。。。抱歉啦)

    推荐阅读