欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

WebGL?多重紋理的使用介紹

 更新時(shí)間:2023年04月19日 14:21:23   作者:H_World  
這篇文章主要為大家介紹了WebGL 多重紋理的使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

引言

基于上篇的內(nèi)容,紋理中最小的單位是紋素,若干紋素組成一個(gè)紋理單元,每個(gè)紋理單元用一個(gè)number值來管理,那么我們來看看它是如何工作的。

激活

在使用紋理單元之前,得需要激活紋理單元

activeTexture()

參數(shù):

  • 指定準(zhǔn)備激活的紋理單元:webgl.TEXTURE0、webgl.TEXTURE1...最后的數(shù)字表示紋理單元的編號(hào)

綁定

這一步,需要告訴WebGL系統(tǒng)紋理對(duì)象使用的是何種類型的紋理,在對(duì)該對(duì)象的操作之前,需要先綁定該對(duì)象,這和之前的緩沖區(qū)對(duì)象的數(shù)據(jù)寫操作類似。

bindTexture(webgl.TEXTURE_2D, texture0)

參數(shù):

  • webgl.TEXTURE_2D: 二維紋理;webgl.TEXTURE_CUBE_MAP: 立方體紋理
  • texture0:需要綁定指定的紋理對(duì)象

該方法開啟紋理對(duì)象,以及將紋理對(duì)象texture0綁定到紋理單元webgl.TEXTURE0上,之后通過操作紋理單元去操作紋理對(duì)象。

配置

這兒主要是對(duì)紋理對(duì)象具體的信息操作了,例如紋理單元類型、尺寸、是否裁剪、紋理的展示方式(放大或縮小)等,下面我們?cè)僖灰环治觥?/p>

texParameteri(target, pname, param)

參數(shù):

  • target: webgl.TEXTURE_2D或webgl.TEXTURE_CUBE_MAP
  • pname: webgl.TEXTURE_MAG_FILTER紋理放大,例如16x16的紋理圖像映射到32x32的像素空間中;webgl.TEXTURE_MIN_FILTER紋理縮小, 應(yīng)用場(chǎng)景相反;webgl.TEXTURE_WRAP_S紋理水平軸(ST坐標(biāo)系統(tǒng))方向填充;webgl.TEXTURE_WRAP_T紋理T軸方向填充。
  • param: webgl.LINEAR線性變換,使用距離像素中心最近的四個(gè)點(diǎn),進(jìn)行線性平均加權(quán),然后作為新的顏色值; webgl.NEAREST最近的距離優(yōu)先,新的像素值取中心像素的值;CLAMP_TO_EDGE: 設(shè)置紋理 S/T 軸方向上的邊緣環(huán)繞方式為CLAMP_TO_EDGE,即在超出邊緣的部分使用紋理邊緣的像素顏色填充. webgl.REPEAT紋理重復(fù)補(bǔ)充;webgl.MIRRORED_REPEAT:紋理鏡像對(duì)稱式重復(fù)

會(huì)發(fā)現(xiàn)參數(shù)pname、param中的參數(shù)常量分類比較多,對(duì)應(yīng)的分類是

  • pname : TEXTURE_MAG_FILTER、TEXTURE_MIN_FILTER
  • param: NEAREST、LINEAR

  • pname : TEXTURE_WRAP_S、TEXTURE_WRAP_T
  • param: REPEAT、MIRRORED_REPEAT、CLAMP_TO_EDGE

分配

紋理對(duì)象信息配置好后,接著可以將紋理圖像分配給紋理對(duì)象

webgl.texImage2D(target, level, internalformat, format type, image)

參數(shù):

  • target: webgl.TEXTURE_2D或webgl.TEXTURE_CUBE_MAP
  • level: 指定紋理緩沖區(qū)中要加載的紋理級(jí)別,一般為 0
  • internalformat: 紋理對(duì)象內(nèi)部數(shù)據(jù)格式,通常使用webgl.RGBA
  • format: 紋理數(shù)據(jù)格式,必須與internalformat相同的值
  • type: 紋理數(shù)據(jù)類型
  • image: 紋理對(duì)象中image對(duì)象

其中的紋理數(shù)據(jù)類型有:

webgl.UNSIGNED_BYTE: 無符號(hào)整型,每個(gè)顏色分量占據(jù)1字節(jié)
webgl.UNSIGNED_SHORT_5_6_5:RGB
webgl.UNSIGNED_SHORT_4_4_4:RGBA
webgl.UNSIGNED_SHORT_5_5_5_1:RGBA

傳遞

經(jīng)過上面一系列準(zhǔn)備后,我們就可以把最終的紋理單元傳遞給片元著色器了,這兒就用到了方法 webgl.uniform1i(),上篇這個(gè)方法已經(jīng)說過了,就不再說明了。

主要看看片元著色器中是怎么做的

uniform sampler2D texture;
varying vec2 inUV;
vec4 color1=texture2D(texture, vec2(inUV.x, 1.0 - inUV.y));
gl_FragColor=color1;
  • 定義了一個(gè)可以在外部訪問的一種特殊的、專用于紋理對(duì)象的數(shù)據(jù)類型sampler2D,就是對(duì)應(yīng)的紋理單元類型webgl.TEXTURE_2D;如果是webgl.TEXTURE_CUBE_MAP呢,則是samplerCube.
  • 通過uniform1i方法,將紋理對(duì)象傳遞到了片元著色器中的texture變量
  • inUV接收頂點(diǎn)著色器中的頂點(diǎn)的紋理坐標(biāo),當(dāng)然這里的紋理坐標(biāo)是在外部設(shè)置的
  • texture2D()在片元著色器中根據(jù)紋理坐標(biāo)獲取紋理圖像上的紋素的顏色
  • 把獲取到的顏色賦值給片元著色器

經(jīng)過對(duì)紋理的加載、設(shè)置、映射,剩下的就是繪畫了。

webgl.drawArrays(webgl.TRIANGLE_STRIP, 0, 4)

好了,晦澀難懂的概念介紹完了,就把具體的代碼貼出來吧!

效果

代碼

著色器設(shè)置

const VSHADER_SOURCE = `
  attribute vec2 a_position;
  attribute vec2 outUV;
  varying vec2 inUV;
  void main(void){
    gl_Position=vec4(a_position, 0.0, 1.0);
    inUV=outUV;
  }
`
const FSHADER_SOURCE = `
  precision mediump float;
  uniform sampler2D texture;
  uniform sampler2D texture1;
  varying vec2 inUV;
  uniform float anim;
  void main(void){
    vec4 color1=texture2D(texture, vec2(inUV.x, 1.0 - inUV.y));
    vec4 color2=texture2D(texture1, vec2(inUV.x + anim, 1.0 - inUV.y));
    gl_FragColor=color1+color2;
  }
`

數(shù)據(jù)緩存區(qū)的設(shè)置

const initBuffer = async () => {
  let positions = [
    0.8, -0.8,
    -0.8, -0.8,
    0.8, 0.8,
    -0.8, 0.8,
  ]
  let pointPosition = new Float32Array(positions)
  let aPsotion = webgl.getAttribLocation(webgl.program, "a_position")
  let triangleBuffer = webgl.createBuffer()
  webgl.bindBuffer(webgl.ARRAY_BUFFER, triangleBuffer)
  webgl.bufferData(webgl.ARRAY_BUFFER, pointPosition, webgl.STATIC_DRAW)
  webgl.enableVertexAttribArray(aPsotion)
  webgl.vertexAttribPointer(aPsotion, 2, webgl.FLOAT, false, 0, 0)
  var texCoords = [
    1, 0,
    0, 0,
    1, 1,
    0, 1,
  ]
  const attribOutUV = webgl.getAttribLocation(webgl.program, "outUV")
  let texCoordBuffer = webgl.createBuffer()
  webgl.bindBuffer(webgl.ARRAY_BUFFER, texCoordBuffer)
  webgl.bufferData(webgl.ARRAY_BUFFER, new Float32Array(texCoords), webgl.STATIC_DRAW)
  webgl.enableVertexAttribArray(attribOutUV)
  webgl.vertexAttribPointer(attribOutUV, 2, webgl.FLOAT, false, 0, 0)
  uniformTexture = webgl.getUniformLocation(webgl.program, "texture")
  uniformTexture1 = webgl.getUniformLocation(webgl.program, "texture1")
  texture0 = await initTexture('/web-gl/landscape.png')
  texture1 = await initTexture("/web-gl/fog.png")
}

主要是設(shè)置頂點(diǎn)坐標(biāo)和紋理坐標(biāo)的數(shù)據(jù)

紋理對(duì)象的初始化

const initTexture = (imageSrc: string): Promise<WebGLTexture> => {
  return new Promise((resolve, reject) => {
    let textureHandle = webgl.createTexture()
    const image = new Image()
    image.onload = function () {
      webgl.bindTexture(webgl.TEXTURE_2D, textureHandle)
      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,
        image
      )
      resolve(textureHandle)
    }
    image.onerror = reject
    image.src = imageSrc
  })
}

這兒需要使用異步方法,因?yàn)樾枰趇mage.onload方法中返回設(shè)置信息數(shù)據(jù)后的紋理對(duì)象。 在 webgl 的紋理加載中,由于圖片是異步加載的,因此我們需要使用 Promise 來處理加載完畢后的回調(diào)函數(shù)。

繪制和動(dòng)態(tài)變化

const updateCount = () => {
  count = count + 0.001
  if (count >= 1.14) {
    count = -1.0
  }
}
const draw = () => {
  webgl.clearColor(0.0, 1.0, 1.0, 1.0)
  webgl.clear(webgl.COLOR_BUFFER_BIT | webgl.DEPTH_BUFFER_BIT)
  webgl.enable(webgl.DEPTH_TEST)
  //紋理變動(dòng)
  uniformAnim = webgl.getUniformLocation(webgl.program, "anim");
  updateCount()
  webgl.uniform1f(uniformAnim, count);
  webgl.activeTexture(webgl.TEXTURE0)
  webgl.bindTexture(webgl.TEXTURE_2D, texture0)
  webgl.uniform1i(uniformTexture, 0)
  webgl.activeTexture(webgl.TEXTURE1)
  webgl.bindTexture(webgl.TEXTURE_2D, texture1)
  webgl.uniform1i(uniformTexture1, 1)
  webgl.drawArrays(webgl.TRIANGLE_STRIP, 0, 4)
  requestAnimationFrame(draw)
}

具體的代碼就是這些了。

小結(jié)一下

到目前為止,我們已經(jīng)了解了頂點(diǎn)著色器、片元著色器、頂點(diǎn)緩沖區(qū)、矩陣?yán)L制和變換、紋理圖像、紋理疊加等,這樣我們已經(jīng)基本上對(duì)二維繪圖掌握了,一個(gè)面我們了解了,之后我們可能就去看看多個(gè)面的物體和場(chǎng)景。

那么就讓我們一起看看三維世界吧!

以上就是WebGL 多重紋理的詳細(xì)內(nèi)容,更多關(guān)于WebGL 多重紋理的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論