WebGL入门教程(五)-webgl纹理

前面文章:

WebGL入门教程(一)-初识webgl

WebGL入门教程(二)-webgl绘制三角形

WebGL入门教程(三)-webgl动画

WebGL入门教程(四)-webgl颜色

这里就须要用到纹理映射,他就是将一张真实图片贴到一个几何图像表面。html

纹理图像:映射的这个图像称为纹理图像;web

纹素:组成纹理图像的像素称为纹素;canvas

纹理坐标:是纹理图像上的坐标,经过纹理坐标能够在纹理图像上获取纹素颜色;浏览器

 

效果图:异步

操做步骤:post

  1.建立HTML5 canvas动画

  2.获取画布 canvas 的 IDwebgl

  3.获取WebGLurl

  4.编译着色器,合并程序spa

  5.使用缓冲区对象向顶点传入多个顶点数据

  6.建立纹理,加载纹理图像,配置属性,在webgl中使用它;

  7.加载纹理图像,配置属性,在webgl中使用它;

以上1~3参考:http://www.cnblogs.com/bsman/p/6128447.html

  4.编译着色器

 //顶点着色器程序
    var VSHADER_SOURCE =
        "attribute vec4 a_Position;" +
        "attribute vec2 a_TextCoord;" + // 接受纹理坐标
        "varying vec2 v_TexCoord;" +    // 传递纹理坐标
        "void main() {" +
            //设置坐标
        "gl_Position = a_Position; " +  // 设置坐标
            //设置纹素
        "v_TexCoord = a_TextCoord; " +  // 设置纹理坐标
        "} ";

    //片元着色器
    var FSHADER_SOURCE =
        "precision mediump float;" +  //须要声明浮点数精度,不然报错No precision specified for (float)
        "uniform sampler2D u_Sampler;" + // 取样器
        "varying vec2 v_TexCoord;" +  // 接受纹理坐标
        "void main() {" +
            //设置颜色
        "gl_FragColor = texture2D(u_Sampler, v_TexCoord);" +  // 设置颜色
        "}";

 解释:在顶点着色器中为每一个顶点指定纹理坐标,而后在片元着色器中根据每一个片元的纹理坐标从纹理图像中抽取纹素颜色

  5.使用缓冲区对象向顶点传入多个顶点数据

function initBuffers(gl, shaderProgram) {
    //顶点坐标和颜色
    var vertices = new Float32Array([
        -0.5,  0.5,   0.0, 1.0,
        -0.5, -0.5,   0.0, 0.0,
        0.5,  0.5,   1.0, 1.0,
        0.5, -0.5,   1.0, 0.0
    ]);
    var n = 4;//点的个数
    //建立缓冲区对象
    var vertexBuffer = gl.createBuffer();

    //将缓冲区对象绑定到目标
    gl.bindBuffer(gl.ARRAY_BUFFER,vertexBuffer);
    //向缓冲区写入数据
    gl.bufferData(gl.ARRAY_BUFFER,vertices,gl.STATIC_DRAW);

    var FSIZE = vertices.BYTES_PER_ELEMENT;

    //获取坐标点
    var a_Position = gl.getAttribLocation(shaderProgram, "a_Position");
    //将缓冲区对象分配给a_Position变量
    gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, FSIZE*4, 0);
    //链接a_Position变量与分配给它的缓冲区对象
    gl.enableVertexAttribArray(a_Position);

    //获取Color坐标点
    var a_TextCoord = gl.getAttribLocation(shaderProgram, "a_TextCoord");
    //将缓冲区对象分配给a_Position变量
    gl.vertexAttribPointer(a_TextCoord, 2, gl.FLOAT, false, FSIZE*4, FSIZE*2);
    //链接a_Position变量与分配给它的缓冲区对象
    gl.enableVertexAttribArray(a_TextCoord);
    return n;
}

 6.初始建立纹理,建立image对象

function initTexture(gl, shaderProgram, n){
    //建立纹理对象
    var texture = gl.createTexture();
    //获取u_Sampler的存储位置
    var u_Sampler = gl.getUniformLocation(shaderProgram, 'u_Sampler');

    //建立image对象
    var image = new Image();

    //加载纹理
    image.onload = function(){ loadTexture(gl, n, texture, u_Sampler, image); };
    // 浏览器开始加载图片 注意:必定是2^mx2^n尺寸的图片
    image.src = "../TexturedQuad/shan.jpg";
    return true;

}
u_Sampler表明从纹理图像中获取纹理颜色
gl.createTexture();建立纹理对象以存储纹理对象;gl.TEXTURE0~gl.TEXTURE7是管理纹理图像的8个纹理单元
注意:这样图片的尺寸必定是2^mx2^n尺寸的图片,否则会报错 WebGL: drawArrays: texture bound to texture unit 0 is not renderable.
浏览器异步加载图片

 7.加载纹理图像,配置属性,在webgl中使用它;

function loadTexture(gl, n, texture, u_Sampler,image){

    //1.对纹理图像进行Y轴反转
    gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
    //2.开启0号纹理单元
    gl.activeTexture(gl.TEXTURE0);
    //3.向target绑定纹理对象
    gl.bindTexture(gl.TEXTURE_2D, texture);

    //4.配置纹理参数
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
    //5.配置纹理图像
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image);

    //6.将0号纹理图像传递给着色器
    gl.uniform1i(u_Sampler, 0);
    // 清空 <canvas>
    gl.clear(gl.COLOR_BUFFER_BIT);

    //绘制矩形
    gl.drawArrays(gl.TRIANGLE_STRIP, 0, n);

}

7.1对纹理图像进行Y轴反转,由于WebGL纹理坐标系统的t轴(分为t轴和s轴)的方向和图片的坐标系统Y轴方向相反。所以将Y轴进行反转。

 gl.pixelStorei 第一个参数:有两个,一个UNPACK_FLIP_Y_WEBGL表明对Y轴反转,默认为false;一个UNPACK_PREMULTIPLY_ALPHA_WEBGL表明将图像   RGB颜色值得每个份量乘以A,默认值为false;

7.2开启0号纹理单元

WebGL经过纹理单元的机制来同时使用多个纹理,gl.TEXTURE0~gl.TEXTURE7是管理纹理图像的8个纹理单元

7.3绑定纹理对象

gl.bindTexture两个参数

第一个参数:有两个选择TEXTURE_2D表明二维纹理,TEXTURE_CUBE_MAP 立方体纹理;

第二个参数:表示绑定的纹理单元

7.4配置纹理参数

gl.texParameteri三个参数

第一个参数:有两个选择TEXTURE_2D表明二维纹理,TEXTURE_CUBE_MAP 立方体纹理;

第二个参数:有4个纹理参数

                1.TEXTURE_MAX_FILTER:放大方法   默认:gl.LINEAR

                2.TEXTURE_MIN_FILTER:缩小方法    默认:gl.NEAREST_MIPMAP_LINEAR

                3.TEXTURE_WRAP_S: 水平填充方法   默认:gl.REPEAT

                4.TEXTURE_WRAP_T:   垂直填充方法   默认:gl.REPEAT

第三个参数:

gl.LINEAR:使用距离新像素中心最近的四个像素的颜色值得加权值平均(图片质量好,可是开销大)

gl.NEAREST_MIPMAP_LINEAR:使用原纹理上的距离映射后像素中心最近的那个像素的颜色值做为新像素的值

gl.REPEAT:平铺式的重复纹理

gl.REPEAT:镜像对称式的重复纹理

gl.REPEAT:使用纹理图像边缘值

7.5配置纹理图像

gl.texImage2D有六个参数

第一个参数:有两个选择TEXTURE_2D表明二维纹理,TEXTURE_CUBE_MAP 立方体纹理;

第二个参数:默认为0,涉及到三维再说

第三个参数:图像的内部格式

               有:gl.RGB(红绿蓝)、gl.RGBA(红绿蓝透明度)、gl.ALPHA(0.0,0.0,0.0,透明度)、gl.LUMINANCE(L、L、L、1L:流明)、

       gl.LUMINANCE_ALPHA(L、L、L,透明度)、

       流明:表示咱们感知到的物体表面的亮度,等于红绿蓝颜色份量值的加权平均来计算流明

第四个参数:纹理的数据格式,必须与第三个参数相同

第五个参数:纹理数据格式 UNSIGNED_BYTE:表示无符号整形,每个颜色份量占据1字节

                                 UNSIGNED_SHORT_5_6_5:表示RGB,每个份量分别占据占据5,6,5比特

                                 UNSIGNED_SHORT_4_4_4_4:表示RGBA,每个份量分别占据占据4,4,4,4比特

                                 UNSIGNED_SHORT_5_5_5_1:表示RGBA,每个份量分别占据占据5比特,A份量占据1比特

第六个参数:纹理图像的image对象

7.6将0号纹理图像传递给着色器

uniform1i(u_Sampler, 0);这里和上面的片元着色器"gl_FragColor = texture2D(u_Sampler, v_TexCoord);" + // 设置颜色,有联系

其中:sampler2D绑定到gl.TEXTURE_2D上,samplerCube绑定到gl.TEXTURE_CUBE_MAP上

相关文章
相关标签/搜索