温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

WebGL颜色与纹理怎么使用

发布时间:2023-04-19 15:33:17 来源:亿速云 阅读:124 作者:iii 栏目:开发技术

这篇“WebGL颜色与纹理怎么使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“WebGL颜色与纹理怎么使用”文章吧。

颜色

三角形颜色

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

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变量,这样就绘制出了一个彩色的三角形。

纹理

什么是纹理?

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

术语:贴图或是纹理映射

  • 准备好需要映射到物体上的纹理图像,例如PNGBMPDDSHDR

  • 给几何图形配置的纹理映射方式

  • 加载纹理图像,并进行配置,以在WebGL中使用

  • 在片元着色器中将相应的纹素从纹理中抽取出来,并将纹素中的颜色通过片元进行绘制

纹理坐标

纹理坐标是纹理图像上的坐标,通过纹理坐标可以在纹理图像上获取纹素颜色,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轴正方向,所以导致图片是倒立的。

解决方案

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

  • 在图片的onload方法中:webgl.pixelStorei(webgl.UNPACK_FLIP_Y_WEBGL, 1)

  • 在片元着色器中gl_FragColor = texture2D(u_texture, vec2(v_texcoord.x, 1.0 - v_texcoord.y));

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

纹理图像

实现过程

  • 顶点着色器中点的坐标绘制区域

  • 纹理坐标用来装图片

  • 通过纹理映射texture2D将区域换上“皮肤”

着色器设置

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() 设置纹理图片的参数

参数:

  • TEXTURE_WRAP_TCLAMP_TO_EDGE: 设置纹理 S/T 轴方向上的边缘环绕方式为 CLAMP_TO_EDGE,即在超出边缘的部分使用纹理边缘的像素颜色填充.

  • TEXTURE_MIN_FILTER、LINEAR: 设置纹理的缩小过滤方式为 LINEAR,即当纹理需要被缩小时,使用线性过滤的方式得到缩小后的像素颜色值.

texImage2D 加载纹理图片

  • 第一个参数是纹理类型

  • 第二个参数是细节级别

  • 第三个参数是纹理格式

  • 第四个参数也是纹理格式

  • 第五个参数是纹理数据的类型

  • 最后一个参数是要加载的纹理图片

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

uniform1i()

  • location:表示要传递给哪个 uniform 变量的位置

  • value:表示要传递的整数值

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

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

以上就是关于“WebGL颜色与纹理怎么使用”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注亿速云行业资讯频道。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI