javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > WebGL  颜色纹理

WebGL 颜色与纹理使用介绍

作者:H_World

这篇文章主要为大家介绍了WebGL 颜色与纹理使用介绍,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

引言

基于之前的知识,这里主要是

颜色

三角形颜色

在之前的例子中,我们绘制了三角形的图形,并给它填充了颜色,如果想要颜色是渐变的,则可以把颜色和顶点类似在不同的顶点上设置不同的颜色向量值。

着色器中

const VSHADER_SOURCE = `
  attribute vec4 a_position;
  attribute vec4 aColor;
  varying vec4 vColor;
  void main(void){
    gl_Position=a_position;
    vColor = aColor;
  }
`
const FSHADER_SOURCE = `
  precision mediump float;
  varying vec4 vColor;
  void main() {
    gl_FragColor = vColor;
  }
`

定义了aColor属性,这样可以再去设置不同顶点上对应的颜色值

let aPsotion = webgl.getAttribLocation(webgl.program, "a_position")
let arr = [
  -0.5, 0.5, 0.0,   1.0, 0.0, 0.0, 1.0, // 左上角,红色
  -0.5, -0.5, 0.0,  0.0, 1.0, 0.0, 1.0, // 左下角,绿色
  0.5, -0.5, 0.0,   0.0, 0.0, 1.0, 1.0, // 右下角,蓝色
]
let vertexArr = new Float32Array(arr)
let trangleBuffer = webgl.createBuffer()
webgl.bindBuffer(webgl.ARRAY_BUFFER, trangleBuffer)
webgl.bufferData(webgl.ARRAY_BUFFER, vertexArr, webgl.STATIC_DRAW)
webgl.enableVertexAttribArray(aPsotion)
webgl.vertexAttribPointer(aPsotion, 3, webgl.FLOAT, false, 7 * Float32Array.BYTES_PER_ELEMENT, 0)
const colorAttributeLocation = webgl.getAttribLocation(webgl.program, "aColor");
webgl.vertexAttribPointer(colorAttributeLocation, 4, webgl.FLOAT, false, 7 * Float32Array.BYTES_PER_ELEMENT, 3 * Float32Array.BYTES_PER_ELEMENT);
webgl.enableVertexAttribArray(colorAttributeLocation);

在这里有两个大的步骤

在光栅化结束后,程序开始逐个的片元调用片元着色器, 那么在这三个点之间的颜色,WebGL系统用这3个顶点的颜色内插出来的,这个过程被称为内插过程

具体解析: 在顶点着色器中,三角形的3个顶点的颜色赋给varying变量v_Color,然后片元着色器中的varying变量v_Color就接收到了内插之后的片元颜色,在片元着色器中,我们把片元的颜色赋值给gl_FragColor变量,这样就绘制出了一个彩色的三角形。

纹理

什么是纹理?

可以形象的理解成某个物体的“皮肤”,而这个“皮肤”可以看成是一张图片,而这张图片中每一个点是一个片元(纹素),每个片元上涂上合适的颜色。

术语:贴图或是纹理映射

纹理坐标

纹理坐标是纹理图像上的坐标,通过纹理坐标可以在纹理图像上获取纹素颜色,WebGL系统中纹理坐标是二维的,简称st坐标系统

注意:纹理坐标和区域坐标的关系

const vertices = [
  // 顶点坐标           // 纹理坐标
  -0.5,  0.5, 0.0,     0.0, 1.0, // 左上角
   0.5,  0.5, 0.0,     1.0, 1.0, // 右上角
   0.5, -0.5, 0.0,     1.0, 0.0, // 右下角
  -0.5, -0.5, 0.0,     0.0, 0.0  // 左下角
];

这样你在脑海中就有一个概念了,顶点坐标和纹理坐标的关系映射。 当我们在区域内绘制了纹理图像,你会发现,这个图片和原来的图片是旋转了90°,这个又涉及到了一个概念:图片坐标

特别说明: 图片坐标

以左上角为原点,向右为x轴正方向,向下为y轴正方向。也就是说,对于一个像素点(x,y),x表示横坐标,y表示纵坐标,坐标轴的方向如下图所示:

(0,0)----------------> x
  |
  |
  |
  |
  v
  y

WebGL中的坐标向上为y轴正方向,所以导致图片是倒立的。

解决方案

先把解决办法给出来吧,两张方式,选取一种即可

其目的都是对纹理图像进行Y轴(T轴)的反转

纹理图像

类似于蒙版效果

实现过程

着色器设置

const VSHADER_SOURCE = `
  attribute vec2 a_position;
  varying vec2 v_texcoord;
  void main() {
    gl_Position = vec4(a_position, 0.0, 1.0);
    v_texcoord = a_position * 0.5 + 0.5;
  }
`
const FSHADER_SOURCE = `
  precision mediump float;
  uniform sampler2D u_texture;
  varying vec2 v_texcoord;
  void main() {
    gl_FragColor = texture2D(u_texture, vec2(v_texcoord.x, 1.0 - v_texcoord.y));
  }
`

着色器中使用sampler2D类型的变量来访问纹理数据

看看核心的方法

const texture = webgl.createTexture()
const image = new Image()
image.src = ''
texture.image = image
image.onload = function () {
  webgl.bindTexture(webgl.TEXTURE_2D, texture)
  webgl.texParameteri(
    webgl.TEXTURE_2D,
    webgl.TEXTURE_WRAP_S,
    webgl.CLAMP_TO_EDGE
  )
  webgl.texParameteri(
    webgl.TEXTURE_2D,
    webgl.TEXTURE_WRAP_T,
    webgl.CLAMP_TO_EDGE
  )
  webgl.texParameteri(
    webgl.TEXTURE_2D,
    webgl.TEXTURE_MIN_FILTER,
    webgl.LINEAR
  )
  webgl.texImage2D(
    webgl.TEXTURE_2D,
    0,
    webgl.RGBA,
    webgl.RGBA,
    webgl.UNSIGNED_BYTE,
    texture.image
  )
  const textureLoc = webgl.getUniformLocation(webgl.program, 'u_texture');
  webgl.uniform1i(textureLoc, 0);
  draw()
  webgl.drawArrays(webgl.TRIANGLE_STRIP, 0, 4);
}

texParameteri() 设置纹理图片的参数

参数:

texImage2D 加载纹理图片

这里使用了 RGBA 格式,表示红、绿、蓝和透明度,使用 UNSIGNED_BYTE 数据类型,表示每个颜色分量使用一个字节存储

uniform1i()

注意哦! 这里的value可不能随便个整数

在WebGL中,纹理单元编号从0开始,最多可以使用16个纹理单元。因此,如果你想使用第一个纹理单元,就需要将value设置为0;如果你想使用第二个纹理单元,就需要将value设置为1

本想把多重纹理放在这一篇,但发现篇幅会很长,所以放在了下一篇,主要实现多个图片的叠加,当然是在纹理层面上的叠加了。

我们可以先看看效果

以上就是WebGL 颜色与纹理使用介绍的详细内容,更多关于WebGL 颜色纹理的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文