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

WebGL 顏色與紋理使用介紹

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

引言

基于之前的知識(shí),這里主要是

  • 將頂點(diǎn)的其他數(shù)據(jù)--如顏色等-傳入頂點(diǎn)著色器
  • 圖元光柵化--在頂點(diǎn)著色器和片元著色器之間的從圖形到片元的轉(zhuǎn)化
  • 將紋理映射到圖形或三維對(duì)象的表面上

顏色

三角形顏色

在之前的例子中,我們繪制了三角形的圖形,并給它填充了顏色,如果想要顏色是漸變的,則可以把顏色和頂點(diǎn)類似在不同的頂點(diǎn)上設(shè)置不同的顏色向量值。

著色器中

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屬性,這樣可以再去設(shè)置不同頂點(diǎn)上對(duì)應(yīng)的顏色值

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, // 右下角,藍(lán)色
]
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);

在這里有兩個(gè)大的步驟

  • 圖形裝配過(guò)程:將頂點(diǎn)坐標(biāo)構(gòu)成幾何圖形
  • 光柵化過(guò)程:將圖形轉(zhuǎn)化成片元

在光柵化結(jié)束后,程序開始逐個(gè)的片元調(diào)用片元著色器, 那么在這三個(gè)點(diǎn)之間的顏色,WebGL系統(tǒng)用這3個(gè)頂點(diǎn)的顏色內(nèi)插出來(lái)的,這個(gè)過(guò)程被稱為內(nèi)插過(guò)程

具體解析: 在頂點(diǎn)著色器中,三角形的3個(gè)頂點(diǎn)的顏色賦給varying變量v_Color,然后片元著色器中的varying變量v_Color就接收到了內(nèi)插之后的片元顏色,在片元著色器中,我們把片元的顏色賦值給gl_FragColor變量,這樣就繪制出了一個(gè)彩色的三角形。

紋理

什么是紋理?

可以形象的理解成某個(gè)物體的“皮膚”,而這個(gè)“皮膚”可以看成是一張圖片,而這張圖片中每一個(gè)點(diǎn)是一個(gè)片元(紋素),每個(gè)片元上涂上合適的顏色。

術(shù)語(yǔ):貼圖或是紋理映射

  • 準(zhǔn)備好需要映射到物體上的紋理圖像,例如PNGBMP、DDS、HDR
  • 給幾何圖形配置的紋理映射方式
  • 加載紋理圖像,并進(jìn)行配置,以在WebGL中使用
  • 在片元著色器中將相應(yīng)的紋素從紋理中抽取出來(lái),并將紋素中的顏色通過(guò)片元進(jìn)行繪制

紋理坐標(biāo)

紋理坐標(biāo)是紋理圖像上的坐標(biāo),通過(guò)紋理坐標(biāo)可以在紋理圖像上獲取紋素顏色,WebGL系統(tǒng)中紋理坐標(biāo)是二維的,簡(jiǎn)稱st坐標(biāo)系統(tǒng)

注意:紋理坐標(biāo)和區(qū)域坐標(biāo)的關(guān)系

const vertices = [
  // 頂點(diǎn)坐標(biāo)           // 紋理坐標(biāo)
  -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  // 左下角
];

這樣你在腦海中就有一個(gè)概念了,頂點(diǎn)坐標(biāo)和紋理坐標(biāo)的關(guān)系映射。 當(dāng)我們?cè)趨^(qū)域內(nèi)繪制了紋理圖像,你會(huì)發(fā)現(xiàn),這個(gè)圖片和原來(lái)的圖片是旋轉(zhuǎn)了90°,這個(gè)又涉及到了一個(gè)概念:圖片坐標(biāo)

特別說(shuō)明: 圖片坐標(biāo)

以左上角為原點(diǎn),向右為x軸正方向,向下為y軸正方向。也就是說(shuō),對(duì)于一個(gè)像素點(diǎn)(x,y),x表示橫坐標(biāo),y表示縱坐標(biāo),坐標(biāo)軸的方向如下圖所示:

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

WebGL中的坐標(biāo)向上為y軸正方向,所以導(dǎo)致圖片是倒立的。

解決方案

先把解決辦法給出來(lái)吧,兩張方式,選取一種即可

  • 在圖片的onload方法中:webgl.pixelStorei(webgl.UNPACK_FLIP_Y_WEBGL, 1)
  • 在片元著色器中gl_FragColor = texture2D(u_texture, vec2(v_texcoord.x, 1.0 - v_texcoord.y));

其目的都是對(duì)紋理圖像進(jìn)行Y軸(T軸)的反轉(zhuǎn)

紋理圖像

類似于蒙版效果

實(shí)現(xiàn)過(guò)程

  • 頂點(diǎn)著色器中點(diǎn)的坐標(biāo)繪制區(qū)域
  • 紋理坐標(biāo)用來(lái)裝圖片
  • 通過(guò)紋理映射texture2D將區(qū)域換上“皮膚”

著色器設(shè)置

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類型的變量來(lái)訪問(wèn)紋理數(shù)據(jù)

看看核心的方法

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() 設(shè)置紋理圖片的參數(shù)

參數(shù):

  • TEXTURE_WRAP_T、CLAMP_TO_EDGE: 設(shè)置紋理 S/T 軸方向上的邊緣環(huán)繞方式為 CLAMP_TO_EDGE,即在超出邊緣的部分使用紋理邊緣的像素顏色填充.
  • TEXTURE_MIN_FILTER、LINEAR: 設(shè)置紋理的縮小過(guò)濾方式為 LINEAR,即當(dāng)紋理需要被縮小時(shí),使用線性過(guò)濾的方式得到縮小后的像素顏色值.

texImage2D 加載紋理圖片

  • 第一個(gè)參數(shù)是紋理類型
  • 第二個(gè)參數(shù)是細(xì)節(jié)級(jí)別
  • 第三個(gè)參數(shù)是紋理格式
  • 第四個(gè)參數(shù)也是紋理格式
  • 第五個(gè)參數(shù)是紋理數(shù)據(jù)的類型
  • 最后一個(gè)參數(shù)是要加載的紋理圖片

這里使用了 RGBA 格式,表示紅、綠、藍(lán)和透明度,使用 UNSIGNED_BYTE 數(shù)據(jù)類型,表示每個(gè)顏色分量使用一個(gè)字節(jié)存儲(chǔ)

uniform1i()

  • location:表示要傳遞給哪個(gè) uniform 變量的位置
  • value:表示要傳遞的整數(shù)值

注意哦! 這里的value可不能隨便個(gè)整數(shù)

在WebGL中,紋理單元編號(hào)從0開始,最多可以使用16個(gè)紋理單元。因此,如果你想使用第一個(gè)紋理單元,就需要將value設(shè)置為0;如果你想使用第二個(gè)紋理單元,就需要將value設(shè)置為1

本想把多重紋理放在這一篇,但發(fā)現(xiàn)篇幅會(huì)很長(zhǎng),所以放在了下一篇,主要實(shí)現(xiàn)多個(gè)圖片的疊加,當(dāng)然是在紋理層面上的疊加了。

我們可以先看看效果

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

相關(guān)文章

  • 淺談Javascript事件模擬

    淺談Javascript事件模擬

    事件是用來(lái)描述網(wǎng)頁(yè)中某一特定有趣時(shí)刻的,眾所周知事件通常是在由用戶和瀏覽器進(jìn)行交互時(shí)觸發(fā),其實(shí)不然,通過(guò)Javascript可以在任何時(shí)間觸發(fā)特定的事件,并且這些事件與瀏覽器創(chuàng)建的事件是相同的
    2012-06-06
  • echarts中g(shù)rid圖表的位置配置詳解

    echarts中g(shù)rid圖表的位置配置詳解

    ECharts是一個(gè)純JavaScript圖表庫(kù),底層依賴于輕量級(jí)的Canvas類庫(kù)ZRender,下面這篇文章主要給大家介紹了關(guān)于echarts中g(shù)rid圖表的位置配置的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-04-04
  • JavaScript中清空數(shù)組的方法總結(jié)

    JavaScript中清空數(shù)組的方法總結(jié)

    本文給大家總結(jié)了三種js清空數(shù)組的方法,每種方法都與眾不同,非常不錯(cuò),具有參考借鑒價(jià)值,感興趣的朋友一起看看吧
    2016-12-12
  • javascript打印大全(打印頁(yè)面設(shè)置/打印預(yù)覽代碼)

    javascript打印大全(打印頁(yè)面設(shè)置/打印預(yù)覽代碼)

    打印頁(yè)面設(shè)置,打印頁(yè)面預(yù)覽在打印過(guò)程中經(jīng)常會(huì)遇到,網(wǎng)上搜集整理了一些實(shí)用的打印方法與大家分享,感興趣的朋友可以了解下哈
    2013-03-03
  • Js,alert出現(xiàn)亂碼問(wèn)題的解決方法

    Js,alert出現(xiàn)亂碼問(wèn)題的解決方法

    Js,alert出現(xiàn)亂碼問(wèn)題的解決方法,需要的朋友可以參考一下
    2013-06-06
  • JS判斷點(diǎn)是否在線段上的代碼

    JS判斷點(diǎn)是否在線段上的代碼

    這篇文章主要介紹了JS判斷點(diǎn)是否在線段上的相關(guān)資料,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2023-11-11
  • XHTML-Strict 內(nèi)允許出現(xiàn)的標(biāo)簽

    XHTML-Strict 內(nèi)允許出現(xiàn)的標(biāo)簽

    XHTML-Strict 內(nèi)允許出現(xiàn)的標(biāo)簽...
    2006-12-12
  • JavaScript無(wú)阻塞加載和defer、async詳解

    JavaScript無(wú)阻塞加載和defer、async詳解

    JS具有阻塞特性,當(dāng)瀏覽器在執(zhí)行js代碼時(shí),不能同時(shí)做其它事情,所有瀏覽器在下載JS的時(shí)候,會(huì)阻止一切其他活動(dòng),比如其他資源的下載,內(nèi)容的呈現(xiàn)等等。至到JS下載、解析、執(zhí)行完畢后才開始繼續(xù)并行下載其他資源并呈現(xiàn)內(nèi)容。
    2017-02-02
  • javascript簡(jiǎn)化代碼 A=alert w=document.writeln

    javascript簡(jiǎn)化代碼 A=alert w=document.writeln

    建議不要這樣寫代碼,考慮以后的修改才是最重要的,代碼分層.多把一個(gè)功能寫成一個(gè)js代碼或一個(gè)類,然后提供接口,這種寫法代碼會(huì)更多,速度也更慢,但人人都推薦這樣寫,是因?yàn)檫@樣子維護(hù)方便.而程序不可能一次性寫得完美的,永遠(yuǎn)都可以改進(jìn)
    2008-02-02
  • javascript合并表格單元格實(shí)例代碼

    javascript合并表格單元格實(shí)例代碼

    這篇文章主要介紹了javascript合并表格單元格實(shí)例代碼,在某些應(yīng)用中需要?jiǎng)討B(tài)的合并單元格,感興趣的朋友可以參考一下
    2016-01-01

最新評(píng)論