背景
本篇收录于《前端读书会》专栏
上文介绍了纹理相干的内容,并应用WebGL进行了2d的实现,明天连续上节课的内容对于纹理的3D实现 也算是汲取了MDN-Tutorial的模式,感觉这样的学习轨道 也算是初衷(每次简明扼要的讲图形学的实践我怕我和你都保持不上来)目前来说最好的形式了,对于WebGL的学习还是图形学的学习都能有一个意识。话不多说开始明天的内容(大部分是code的解说 尽可能疾速过完一些根底的API...第一步成为一个API工程师)
上文介绍了纹理相干的内容,有须要能够参考上文
本篇纲要
- 2D与3D的区别?绘制思路?
- coding (WebGL中简略应用纹理)
coding局部引入webgl-utils(方面一些useprogram,linkProgram的简写 无太大魔力)&martix(矩阵的一些生成/计算..)工具类库
1.2d与3d的区别
首先咱们都晓得2D只是一个立体 3D能够了解为是6个立体,那么本篇文章最次要解决如何给增加5个立体就好(当然增加会随同着一些问题,没关系 一步步的来)
本篇会对于上文的一些反馈进行改过 例如code 正文太少。。ok 我尽量多写点
WebGl coding 首先回顾一下步骤
- shader
- 创立program
- 解决坐标还有纹理相干
- 获取并绑定坐标信息
- 绘制draw
看着是如此简略 那么接下来咱们一起来写一下
coding
coding开始之前先看看成果
缺一个gif图 今天找个有电脑的中央补充一下。
1. shader
有敌人反馈shader局部要关照老手, 那么我逐行加下正文介绍下。当然更多细节信息还是得去看看相干材料呢。 我讲的不好(-- 次要是懒癌患者)
// vertex shader // attribute变量 只能作用于顶点着色器 vec4 是矢量 a_position 一个变量名attribute vec4 a_position;// attribute变量 只能作用于顶点着色器 vec4 是矢量 a_position 一个变量名attribute vec2 a_texcoord;// uniform变量(全局) 能够在顶点和片元应用(如果俩个着色命名同名 可进行共享) mat4 是矩阵 u_matrix变量名uniform mat4 u_matrix;// varying变量(全局) 目标就是为了给片元传输数据 vec2 矢量 v_texcoord变量名varying vec2 v_texcoord;// main相似主执行函数 然而是必须的 C/C++用法相似void main() { // gl_Position 顶点坐标 gl_Position = u_matrix * a_position; // 将纹理坐标传给片断着色器 v_texcoord = a_texcoord;}// fragment shader // 精度限定 mediump中度精度 float数据类型 对了SL语言中是辨别整型和浮点型的哦~precision mediump float;// varying变量(全局) 接管传输过去的数据 vec2 矢量 v_texcoord变量名varying vec2 v_texcoord;// uniform变量(只读 全局) sampler2D纹理 u_texture变量名uniform sampler2D u_texture;// 主执行函数void main() { // gl_FragColor 色彩信息 此处是纹理 texture2D是取样器纹理 v_texcoord纹理坐标 看js代码交叉了解 gl_FragColor = texture2D(u_texture, v_texcoord);}
我这个正文写的 我都拜服。哈哈 不懂记得留言。我都让你们问,你们也不问。要晓得不会就问没什么不好意思的 学会了那是本人的 弱小本人升职加薪 加油
2. 创立program
// 用到了webgl-Utils 其实就是useVertex 和useFragment 而后linkProgram...var program = webglUtils.createProgramFromScripts(gl, ["vertex-shader-3d", "fragment-shader-3d"]);
3. 解决坐标还有纹理相干
// 顶点坐标 产生了变换 6个面 var positions = new Float32Array( [ -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, ]);// 解决图片跨域问题 当然形式很多你也能够绘制canvas2d 而后创立纹理 canvas在规范上反对了图片跨域 有趣味能够查查function requestCORSIfNotSameOrigin(img, url) { if ((new URL(url, window.location.href)).origin !== window.location.origin) { img.crossOrigin = ""; }}// 加载图片 并在load实现绑定纹理function loadImageAndCreateTextureInfo(url) { var tex = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, tex); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([0, 0, 255, 255])); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); var textureInfo = { width: 1, height: 1, texture: tex, }; var img = new Image(); img.addEventListener('load', function() { textureInfo.width = img.width; textureInfo.height = img.height; gl.bindTexture(gl.TEXTURE_2D, textureInfo.texture); // 调用 texImage2D() 把曾经加载的图片图形数据写到纹理 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img); }); requestCORSIfNotSameOrigin(img, url); img.src = url; return textureInfo; } var texInfo = loadImageAndCreateTextureInfo('https://webglfundamentals.org/webgl/resources/leaves.jpg');
4. 获取并绑定坐标信息
var positionLocation = gl.getAttribLocation(program, "a_position"); var texcoordLocation = gl.getAttribLocation(program, "a_texcoord"); var matrixLocation = gl.getUniformLocation(program, "u_matrix"); var textureLocation = gl.getUniformLocation(program, "u_texture"); var positionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); setGeometry(gl); var texcoordBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer); setTexcoords(gl); var texture = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texture); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([0, 0, 255, 255]));
5. 应用program并提供buffer取数据 而后绘制
gl.vertexAttribPointer( positionLocation, size, type, normalize, stride, offset);// 启用texcoord属性gl.enableVertexAttribArray(texcoordLocation);// 绑定texcoord buffer.gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer);....gl.drawArrays(gl.TRIANGLES, 0, 6 * 6);
ok, 成果就这样实现了.为了大家的练习, 阐明一下须要留神的中央是下面的代码 纹理是采纳了一个纹理 如果要改多个图片能够采取多个纹理。也能够合并成一个纹理 通过坐标信息进行调节。
全副代码请去github下载并应用
最初
最初强烈心愿大家学习相干理论知识;实践可能日常用到的中央很少,然而它能决定你走多远。(有的人问难怎么办,勤于练习吧),写作速度呢 该专栏我减速(一周1-2篇) 其余专栏(1篇) 计算机图形学相干的基础知识都会带一遍。而后后续次要写数据可视化方向。
下一篇写点什么呢? 集体筹备把MDN-Tutorial局部的内容结个尾。而后开始正式的可视化环节(能够介绍几个大家罕用的库 2D 3D的都能够,大家看看有什么好用的库须要我一起过一下的呢)。或者大家提提意见!