03 传递贴图给着色器
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了03 传递贴图给着色器相关的知识,希望对你有一定的参考价值。
WebGL很容易把图片传递给着色器程序当作贴图。下面是一些需要注意的地方:
1、贴图图片长宽像素必须是2的幂,例如16、32、64、128、256,否则贴图无法显示。
2、WebGL只能绘制三角形。为了避免重复,顶点数组里只给了正方形四个顶点的坐标。然后索引数组里说明第0、1、2三个顶点组成一个三角形、0、2、3三个顶点组成一个三角形。索引数组的每个面是有顺序的,遵循右手定则,四指弯向三个顶点的方法,那么拇指将指向面的方向。
3、uv坐标表示每个顶点对应贴图上的位置。(0.0, 0.0)是贴图左下角,x轴向右,y轴向上,x轴和y轴的最大值为1.例如(1.0, 0.0)表示右下角,(1.0, 1.0)表示右上角,(0.0, 1.0)表示右上角。
1 <!DOCTYPE html> 2 3 <html lang="zh-CN"> 4 5 <head> 6 <meta charset="UTF-8" /> 7 <title>03_传递贴图给着色器</title> 8 9 <!-- 顶点着色器 --> 10 <script id="shader-vs" type="x-shader/x-vertex"> 11 attribute vec3 aVertexPosition; 12 attribute vec2 aTextureCoord; 13 varying vec2 vTextureCoord; 14 15 void main(void) { 16 gl_Position = vec4(aVertexPosition, 1.0); 17 vTextureCoord = aTextureCoord; 18 } 19 </script> 20 21 <!-- 片源着色器 --> 22 <script id="shader-fs" type="x-shader/x-fragment"> 23 precision mediump float; 24 varying vec2 vTextureCoord; 25 uniform sampler2D uSampler; 26 27 void main(void) { 28 gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t)); 29 } 30 </script> 31 32 <script type="text/javascript"> 33 var start = function () { 34 // 上下文环境 35 var canvas = document.getElementById("mycanvas"); 36 var gl = canvas.getContext("experimental-webgl"); 37 gl.viewportWidth = canvas.width; 38 gl.viewportHeight = canvas.height; 39 gl.viewport(0, 0, gl.viewportWidth, gl.viewportWidth); 40 gl.clearColor(0.0, 0.0, 0.0, 1.0); 41 gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 42 gl.enable(gl.DEPTH_TEST); 43 44 // 顶点着色器 45 var shader = gl.createShader(gl.VERTEX_SHADER); 46 gl.shaderSource(shader, document.getElementById(‘shader-vs‘).innerHTML); 47 gl.compileShader(shader); 48 var vertexShader = shader; 49 50 // 片源着色器 51 var shader = gl.createShader(gl.FRAGMENT_SHADER); 52 gl.shaderSource(shader, document.getElementById(‘shader-fs‘).innerHTML); 53 gl.compileShader(shader); 54 var fragmentShader = shader; 55 56 // 着色器程序 57 var shaderProgram = gl.createProgram(); 58 gl.attachShader(shaderProgram, vertexShader); 59 gl.attachShader(shaderProgram, fragmentShader); 60 gl.linkProgram(shaderProgram); 61 gl.useProgram(shaderProgram); 62 63 // 获取参数地址 64 var vertexPositionAttr = gl.getAttribLocation(shaderProgram, ‘aVertexPosition‘); 65 gl.enableVertexAttribArray(vertexPositionAttr); 66 var textureCoordAttr = gl.getAttribLocation(shaderProgram, ‘aTextureCoord‘); 67 gl.enableVertexAttribArray(textureCoordAttr); 68 var samplerUniform = gl.getUniformLocation(shaderProgram, ‘uSampler‘); 69 70 // 顶点 71 var vertices = [ 72 -0.5, -0.5, 0.0, 73 0.5, -0.5, 0.0, 74 0.5, 0.5, 0.0, 75 -0.5, 0.5, 0.0 76 ]; 77 var vertexPositionBuffer = gl.createBuffer(); 78 gl.bindBuffer(gl.ARRAY_BUFFER, vertexPositionBuffer); 79 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); 80 81 // 索引 82 var vertexIndices = [ 83 0, 1, 2, 84 0, 2, 3 85 ]; 86 var vertexIndexBuffer = gl.createBuffer(); 87 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vertexIndexBuffer); 88 gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(vertexIndices), gl.STATIC_DRAW); 89 90 // uv坐标 91 var textureCoords = [ 92 0.0, 0.0, 93 1.0, 0.0, 94 1.0, 1.0, 95 0.0, 1.0 96 ]; 97 var vertexTextureCoordBuffer = gl.createBuffer(); 98 gl.bindBuffer(gl.ARRAY_BUFFER, vertexTextureCoordBuffer); 99 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoords), gl.STATIC_DRAW); 100 101 // 贴图 102 var texture = gl.createTexture(); 103 texture.image = new Image(); 104 texture.image.onload = function () { 105 gl.bindTexture(gl.TEXTURE_2D, texture); 106 gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); 107 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.image); 108 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 109 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 110 gl.bindTexture(gl.TEXTURE_2D, null); 111 112 } 113 texture.image.src = "nehe.gif"; 114 115 var render = function () { // 渲染循环 116 gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 117 118 // 顶点 119 gl.bindBuffer(gl.ARRAY_BUFFER, vertexPositionBuffer); 120 gl.vertexAttribPointer(vertexPositionAttr, 3, gl.FLOAT, false, 0, 0); 121 122 // uv坐标 123 gl.bindBuffer(gl.ARRAY_BUFFER, vertexTextureCoordBuffer); 124 gl.vertexAttribPointer(textureCoordAttr, 2, gl.FLOAT, false, 0, 0); 125 126 // 贴图 127 gl.activeTexture(gl.TEXTURE0); 128 gl.bindTexture(gl.TEXTURE_2D, texture); 129 gl.uniform1i(samplerUniform, 0); 130 131 // 画图 132 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vertexIndexBuffer); 133 gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0); 134 requestAnimationFrame(render); 135 } 136 render(); 137 } 138 </script> 139 </head> 140 141 <body onload="start();"> 142 <canvas id="mycanvas" style="border: none;" width="500" height="500"></canvas> 143 </body> 144 145 </html>
效果图:
参考资料:
Lessen 5 引入纹理贴图:http://www.hiwebgl.com/?p=201
以上是关于03 传递贴图给着色器的主要内容,如果未能解决你的问题,请参考以下文章