2

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

 2 years ago
source link: https://segmentfault.com/a/1190000040809960
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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

本篇收录于《数据可视化和图形学》专栏

之前介绍纹理相关的理论及简单使用 有需要可以参考上文 , 在上文基础进行多纹理实践(更多是帮助群内小伙伴提前脱坑!!!!)

  1. 多纹理渲染实现思路
  2. 多纹理渲染coding(几种场景)

1. 多纹理渲染实现思路

多纹理渲染更多是指 gl_FragColor采取混合纹理 texture2D * texture2D的关系。本篇初衷为了帮助群里小伙伴的进阶坎坷路~会提到多vertex(纹理)渲染 然后坐标重叠的需求。

  1. 定义vertexArray(本文示例为2point)
  2. 定义textureArray
  3. 创建缓冲区(此处注意多渲染节点公用缓冲区情况)
  4. 按部就班依此注册shader.绑定数据,渲染。

多纹理渲染coding(几种场景)

第一种 gl_FragColor采取混合纹理 texture2D * texture2D
image.png

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);

第二种 多个节点纹理(其实就是坐标重叠 后者覆盖前者...)
image.png

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); // 绘制多个(三角形组合)正方形

!!!!注意 群里小伙伴留意代码中注释 (解决你的疑惑)

image.png

1.webgl-utils.js webgl相关函数封装工具库

完整代码示例 [请点击git仓库查看代码示例]
texture.html

texture1.html

2D渲染方面你可能需要了解的有

  1. 2D/2D纹理优化
  2. 渲染优化...

最后强烈希望大家学习相关理论知识;理论可能日常用到的地方很少,但是它能决定你走多远。(有的人问难怎么办,勤于练习吧) 写作速度我感觉我又行了,哈哈哈... 最近会持续更新(因为在自研自己的渲染引擎。唉 一言难尽。。。抱歉啦)


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK