国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

快速上手WebGL,代碼+圖解手把手教你使用WebGL一步步實現(xiàn)熱力圖

這篇具有很好參考價值的文章主要介紹了快速上手WebGL,代碼+圖解手把手教你使用WebGL一步步實現(xiàn)熱力圖。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

前言

大家好,我是南木元元,熱衷分享有趣實用的文章。

熱力圖

項目中需要繪制熱力圖,熱力圖其實就是數(shù)值大小用顏色來進(jìn)行區(qū)分,每個點的數(shù)值需根據(jù)顏色映射表(調(diào)色板)映射為指定顏色。需要3個數(shù)值字段,可繪制在平行坐標(biāo)系中(2個數(shù)值字段分別確定x、y軸,1個數(shù)值字段確定著色)。效果如下:
webgl-heatmap,# webgl,webgl
其實就是對每個點賦予指定顏色,echarts和canvas都很容易實現(xiàn)熱力圖(使用createImageData)的效果,由于之前學(xué)習(xí)過WebGL,于是就想著用webgl來實現(xiàn)熱力圖的效果。

  • 如何使用webgl來進(jìn)行繪制呢?

熱力圖是由一個個彩色的點構(gòu)成,所以,只需要思考如何使用webgl繪制出一個個彩色的點,那么就自然能形成熱力圖的效果。而webgl中有頂點著色器和片元著色器,一個用于計算頂點位置,一個用于計算顏色值,所以,關(guān)鍵就是把數(shù)據(jù)傳個這兩個著色器。

WebGL繪制多個點

緩沖區(qū)對象

webgl中繪制一個點很方便,代碼如下:

  //頂點著色器
  const VERTEX_SHADER_SOURCE = `
    void main() {
      gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
      gl_PointSize = 10.0;
    }  
  `
  //片元著色器
  const FRAGMENT_SHADER_SOURCE = `
    void main() {
      gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
    }   
  `
  //創(chuàng)建著色器
  const program = initShader(gl, VERTEX_SHADER_SOURCE, FRAGMENT_SHADER_SOURCE)
  gl.drawArrays(gl.POINTS, 0, 1)

如果想同時繪制多個點,就需要用到它所提供的緩沖區(qū)對象,它可以一次性向頂點著色器傳入多個頂點的數(shù)據(jù)。

attribute變量

attribute用來存儲頂點著色器中每個頂點的輸入,包括頂點位置坐標(biāo)、紋理坐標(biāo)和顏色等信息,但是只能用于頂點著色器。
緩沖是程序發(fā)送給GPU的數(shù)據(jù),attribute用來從緩沖中獲取所需數(shù)據(jù),并將它提供給頂點著色器。

使用緩沖區(qū)

緩沖區(qū)對象是WebGL中的一塊存儲區(qū),可以在緩沖區(qū)對象中保存想要繪制的所有頂點數(shù)據(jù)。先創(chuàng)建一個緩沖區(qū),然后向其中寫入頂點數(shù)據(jù),就能一次性向頂點著色其傳入多個頂點的attribute變量的數(shù)據(jù)。
webgl-heatmap,# webgl,webgl

首先需要定義所有要向緩沖區(qū)對象寫入的數(shù)據(jù)。

const vertices = new Float32Array([
  -0.5, 0.5,
  -0.5, -0.5,
  0.5, 0.5
])

然后使用使用緩沖區(qū)對象向頂點著色器傳入多個頂點的數(shù)據(jù),主要有五步:
1.創(chuàng)建緩沖區(qū)對象

const vertexBuffer = gl.createBuffer();

2.綁定緩沖區(qū)對象

gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);

3.向緩沖區(qū)對象中寫入數(shù)據(jù)

gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

4.將緩沖區(qū)對象分配給一個attribute變量

gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);

5.激活attribute變量

gl.enableVertexAttribArray(a_Position);
  • 使用緩沖區(qū)代碼
// 獲取attribute變量位置
const a_Position = gl.getAttribLocation(gl.program, 'a_Position');
if (a_Position < 0) {
  console.log('Failed to get the storage location of a_Position');
  return;
}
// 向緩沖區(qū)對象寫入的數(shù)據(jù)
const vertices = new Float32Array([
  -0.5, 0.5,
  -0.5, -0.5,
  0.5, 0.5
])
const vertexBuffer = gl.createBuffer();//創(chuàng)建緩沖區(qū)對象
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);// 綁定緩沖區(qū)對象到gl.ARRAY_BUFFER上,gl.ARRAY_BUFFER表示緩沖區(qū)對象中包含了頂點數(shù)據(jù)
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);// 將數(shù)據(jù)寫入緩沖區(qū)對象,gl.STATIC_DRAW代表只向緩沖區(qū)寫入一次數(shù)據(jù)
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0); // 調(diào)用頂點緩沖,將緩沖數(shù)據(jù)傳給a_Position
gl.enableVertexAttribArray(a_Position);// 激活a_Position使用緩沖數(shù)組

  • 著色器代碼

在著色器內(nèi),一般命名以gl_開頭的變量是著色器的內(nèi)置變量。變量聲明一般包含<存儲限定符><數(shù)據(jù)類型><變量名稱>,下面代碼中,attribute表示存儲限定符,vec是數(shù)據(jù)類型,a_Position為變量名稱。

const vs_source = `
  attribute vec4 a_Position;
  void main() {
    gl_Position = a_Position;
    gl_PointSize = 10.0;
  }
`;
// 片元著色器
const fs_source = `
  void main() {
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
  }
`;
  • 完整代碼
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>webgl繪制多個點</title>
</head>

<body>
  <canvas id="canvas" width="400" height="400"></canvas>
  <script>
    // 頂點著色器
    const vs_source = `
      attribute vec4 a_Position;
      void main() {
        gl_Position = a_Position;
        gl_PointSize = 10.0;
      }
    `;
    // 片元著色器
    const fs_source = `
      void main() {
        gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
      }
    `;
    const canvas = document.getElementById('canvas');
    const gl = canvas.getContext('webgl');
  
    function initShader() {
      // 創(chuàng)建shader
      const vs_shader = gl.createShader(gl.VERTEX_SHADER);
      gl.shaderSource(vs_shader, vs_source);
      gl.compileShader(vs_shader);
      if (!gl.getShaderParameter(vs_shader, gl.COMPILE_STATUS)) {
        const error = gl.getShaderInfoLog(vs_shader);
        console.log('Failed to compile vs_shader:' + error);
        gl.deleteShader(vs_shader);
        return;
      }
      const fs_shader = gl.createShader(gl.FRAGMENT_SHADER);
      gl.shaderSource(fs_shader, fs_source);
      gl.compileShader(fs_shader);
      if (!gl.getShaderParameter(fs_shader, gl.COMPILE_STATUS)) {
        const error = gl.getShaderInfoLog(fs_shader);
        console.log('Failed to compile fs_shader:' + error);
        gl.deleteShader(fs_shader);
        return;
      }
  
      // 創(chuàng)建program
      const program = gl.createProgram();
      gl.attachShader(program, vs_shader);
      gl.attachShader(program, fs_shader);
      gl.linkProgram(program);
      if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
        const error = gl.getProgramInfoLog(program);
        console.log('無法鏈接程序?qū)ο螅? + error);
        gl.deleteProgram(program);
        gl.deleteShader(fs_shader);
        gl.deleteShader(vs_shader);
        return;
      }
      gl.useProgram(program);
      gl.program = program;

      // 獲取attribute變量位置
      const a_Position = gl.getAttribLocation(gl.program, 'a_Position');
      if (a_Position < 0) {
        console.log('Failed to get the storage location of a_Position');
        return;
      }
      // 向緩沖區(qū)對象寫入的數(shù)據(jù)
      const vertices = new Float32Array([
        -0.5, 0.5,
        -0.5, -0.5,
        0.5, 0.5
      ])
      const vertexBuffer = gl.createBuffer();//創(chuàng)建緩沖區(qū)對象
      gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);// 綁定緩沖區(qū)對象到gl.ARRAY_BUFFER上,gl.ARRAY_BUFFER表示緩沖區(qū)對象中包含了頂點數(shù)據(jù)
      gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);// 將數(shù)據(jù)寫入緩沖區(qū)對象,gl.STATIC_DRAW代表只向緩沖區(qū)寫入一次數(shù)據(jù)
      gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0); // 調(diào)用頂點緩沖,將緩沖數(shù)據(jù)傳給a_Position
      gl.enableVertexAttribArray(a_Position);// 激活a_Position使用緩沖數(shù)組
    }
  
    initShader();
    
    gl.clearColor(0.0, 0.0, 0.0, 1.0);
    gl.clear(gl.COLOR_BUFFER_BIT);
    gl.drawArrays(gl.POINTS, 0, 3);//繪制3個點
  </script>
</body>
</html>
  • 效果

webgl-heatmap,# webgl,webgl

WebGL繪制多個彩色點

接下來就是彩色點的繪制,需要傳入每個點的顏色數(shù)據(jù)。

varying 可變量

varying一般同時存在頂點著色器和片元著色器中,它的作用是從頂點著色器向片元著色器傳輸數(shù)據(jù)。

// 頂點著色器
const vs_source = `
  attribute vec4 a_Position;
  attribute float a_PointSize;
  attribute vec4 a_Color;
  varying vec4 v_Color;
  void main() {
    gl_Position = a_Position;
    gl_PointSize = a_PointSize;
    v_Color = a_Color;
  }
`;
// 片元著色器
const fs_source = `
  precision mediump float;
  varying vec4 v_Color;
  void main() {
    gl_FragColor = v_Color;
  }
`;

上面,頂點著色器通過a_Position、a_PointSize分別接收并設(shè)置頂點的位置和大小,通過a_Color從程序獲取顏色并通過v_Color傳遞給片元著色器。
片元著色器,首先設(shè)置了float為中等精度,然后通過v_Color接收來自頂點著色器的顏色并將其設(shè)置給內(nèi)置變量gl_FragColor,其中通過內(nèi)置變量gl_FragColor來確定頂點像素顏色。

讀取緩沖區(qū)

緩沖區(qū)數(shù)據(jù),7個為一組,前兩個數(shù)據(jù)代表頂點位置,第3個代碼頂點大小,第4-7個就代表頂點的顏色。

const vertices = new Float32Array([
  -0.5, 0.5, 10.0, 1.0, 0.0, 0.0, 1.0,
  -0.5, -0.5, 20.0, 0.0, 1.0, 0.0, 1.0,
  0.5, 0.5, 30.0, 0.0, 0.0, 1.0, 1.0
])
  • 如何讀取出相應(yīng)的頂點位置、大小以及顏色數(shù)據(jù)?

gl.vertexAttribPointer()可以指定讀取緩沖的規(guī)則。
webgl-heatmap,# webgl,webgl
設(shè)置緩沖讀取規(guī)則和啟用緩沖對象

//設(shè)置緩沖讀取規(guī)則
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, SIZE * 7, 0); // 將緩沖數(shù)據(jù)中一組7個數(shù)據(jù)中的前2個數(shù)據(jù)傳給a_Position
gl.vertexAttribPointer(a_PointSize, 1, gl.FLOAT, false, SIZE * 7, SIZE * 2); // 將緩沖數(shù)據(jù)中一組7個數(shù)據(jù)中的第3(偏移2個數(shù)據(jù)取1一個)個數(shù)據(jù)傳給a_PointSize
gl.vertexAttribPointer(a_Color, 4, gl.FLOAT, false, SIZE * 7, SIZE * 3); //將緩沖數(shù)據(jù)中一組7個數(shù)據(jù)中的第4-7(偏移3個數(shù)據(jù)取4個)個數(shù)據(jù)傳給a_Color
//啟用緩沖對象
gl.enableVertexAttribArray(a_Position);// 激活a_Position使用緩沖數(shù)組
gl.enableVertexAttribArray(a_PointSize);// 激活a_Position使用緩沖數(shù)組
gl.enableVertexAttribArray(a_Color);// 激活a_Color使用緩沖數(shù)組
  • 效果

繪制出了3個不同大小、不同顏色的點。
webgl-heatmap,# webgl,webgl

熱力圖的繪制

接下來熱力圖的繪制就很簡單了,只將每個點的位置信息和顏色值使用緩沖區(qū)傳給著色器就可以。
可以如下來定義緩沖數(shù)據(jù),6個為一組,前2個代表位置,后4個代表顏色(每個點的顏色是根據(jù)顏色映射表進(jìn)行計算得到的)。

const vertices = new Float32Array([
  -0.5, 0.5, 1.0, 0.0, 0.0, 1.0,
  -0.5, -0.5,  0.0, 1.0, 0.0, 1.0,
  0.5, 0.5,  0.0, 0.0, 1.0, 1.0
  ......
])

結(jié)語

??如果此文對你有幫助的話,歡迎??關(guān)注、??點贊、?收藏、??評論,支持一下博主~文章來源地址http://www.zghlxwxcb.cn/news/detail-799576.html

到了這里,關(guān)于快速上手WebGL,代碼+圖解手把手教你使用WebGL一步步實現(xiàn)熱力圖的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【榮耀帳號服務(wù)】手把手教你快速web接入

    【榮耀帳號服務(wù)】手把手教你快速web接入

    榮耀帳號開放服務(wù)基于OAuth2.0,Web應(yīng)用可以獲取用戶授權(quán)憑證, 實現(xiàn)授權(quán)登錄功能, 可以實現(xiàn)瀏覽器Web授權(quán)登錄接入或者手機H5授權(quán)登錄接入榮耀帳號。 1) 用戶在應(yīng)用網(wǎng)站上選擇榮耀帳號登錄 2) 應(yīng)用服務(wù)器構(gòu)造 /oauth2/v3/authorize 鏈接, 向榮耀帳號服務(wù)器發(fā)起授權(quán)請求 3) 榮耀帳號

    2024年02月10日
    瀏覽(20)
  • 手機怎么掃描照片成電子版?手把手教你快速搞定

    手機怎么掃描照片成電子版?手把手教你快速搞定

    手機怎么把照片給掃描成電子版呢?大家在辦公的過程中,經(jīng)常會使用或者是收到紙質(zhì)版的文件或合同,正常情況下使用當(dāng)然是沒問題,但當(dāng)我們在外身邊沒有電腦,而這時需要把手頭上的紙質(zhì)版文件給轉(zhuǎn)換成電子版給客戶發(fā)過去,這時候怎么辦呢?其實我們只需要利用好自

    2024年02月13日
    瀏覽(29)
  • 手把手教你用代碼畫架構(gòu)圖

    作者:京東物流?覃玉杰 本文將給大家介紹一種簡潔明了軟件架構(gòu)可視化模型——C4模型,并手把手教大家如何使用 代碼 繪制出精美的C4架構(gòu)圖。 閱讀本文之后,讀者畫的架構(gòu)圖將會是這樣的: 注:該圖例僅作繪圖示例使用,不確保其完整性、可行性。 C4是軟件架構(gòu)可視化

    2024年02月04日
    瀏覽(29)
  • SDXL 1.0出圖效果直逼Midjourney!手把手教你快速體驗!

    SDXL 1.0出圖效果直逼Midjourney!手把手教你快速體驗!

    最近,Stability AI正式推出了全新的SDXL 1.0版本。經(jīng)過我的實際測試,與之前的1.5版本相比,XL的效果有了巨大的提升,可以說是全方位的超越。不僅在理解提示詞方面表現(xiàn)出色,而且圖片的構(gòu)圖、顏色渲染和畫面細(xì)膩程度都有了很大的進(jìn)步,實際出圖效果堪比Midjourney。此外,

    2024年02月14日
    瀏覽(31)
  • 手把手教你如何快速定位bug,如何編寫測試用例,快來觀摩......

    手把手教你如何快速定位bug,如何編寫測試用例,快來觀摩......

    手把手教你如何快速定位bug,如何編寫測試用例,快來觀摩......手把手教你如何快速定位bug,如何編寫測試用例,快來觀摩......作為一名測試人員如果連常見的系統(tǒng)問題都不知道如何分析,頻繁將前端人員問題指派給后端人員,后端人員問題指派給前端人員,那么在團(tuán)隊里你在開發(fā)

    2024年01月20日
    瀏覽(23)
  • 手把手教你:gitee的注冊以及代碼的提交(上)

    手把手教你:gitee的注冊以及代碼的提交(上)

    個人主頁(找往期文章包括但不限于本期文章中不懂的知識點):我要學(xué)編程(?_?)-CSDN博客 目錄 gitee的介紹? gitee的注冊 提交代碼到gitee 安裝git和圖形化界面工具? 在gitee上創(chuàng)建遠(yuǎn)程倉庫。 clone遠(yuǎn)程倉庫到本地電腦 git的三板斧? add commit? push ? 首先,我們得了解什么是git

    2024年02月22日
    瀏覽(30)
  • 手把手教你通過PaddleHub快速實現(xiàn)輸入中/英文本生成圖像(Stable Diffusion)

    手把手教你通過PaddleHub快速實現(xiàn)輸入中/英文本生成圖像(Stable Diffusion)

    近來,基于Diffusion的文圖生成模型比較火,用戶輸入一句話,模型就可以生成一副對應(yīng)的圖像,還是很有意思的。本文記錄了通過PaddleHub快速實現(xiàn)上述任務(wù)的過程,以供參考。 1、安裝PaddlePaddle PaddleHub底層依賴于百度自研的開源框架PaddlePaddle,可以根據(jù)官方提供的方式來快速

    2024年01月17日
    瀏覽(23)
  • 手把手教你快速在生產(chǎn)環(huán)境搭建Doris集群附集群啟停管理腳本

    手把手教你快速在生產(chǎn)環(huán)境搭建Doris集群附集群啟停管理腳本

    組件分布規(guī)劃 節(jié)點 node4 node5 node6 node7 node8 Node9 Node10 Node11 服務(wù) FE(follower) BE FE(follower) BE FE(follower) BE FE(observer) BE BE Broker BE Broker BE BE Ip 192.168.22.34 192.168.22.35 192.168.22.36 192.168.22.37 192.168.22.20 192.168.22.16 192.168.22.17 192.168.22.18 根據(jù)自己集群的軟硬件配置,選擇合適的版本

    2024年02月02日
    瀏覽(28)
  • 手把手教你使用phpstudy本地快速搭建網(wǎng)站,并外網(wǎng)訪問【無公網(wǎng)IP】

    手把手教你使用phpstudy本地快速搭建網(wǎng)站,并外網(wǎng)訪問【無公網(wǎng)IP】

    本教程為快速在本地環(huán)境下搭建web網(wǎng)站,同時實現(xiàn)可在外網(wǎng)環(huán)境下訪問??! 使用工具 phpstudy(本地搭建web網(wǎng)站) cpolar內(nèi)網(wǎng)穿透(將網(wǎng)站發(fā)布到公網(wǎng)可訪問) 1. 本地搭建web網(wǎng)站 1.1 下載phpstudy后解壓并安裝 官網(wǎng)下載:https://www.xp.cn/download.html 安裝后的效果,如圖: 點擊,一鍵

    2024年02月08日
    瀏覽(30)
  • 手把手教你SAM(segment anything)官方代碼本地調(diào)用

    手把手教你SAM(segment anything)官方代碼本地調(diào)用

    更新一下如何下載官方本地github代碼并在本地進(jìn)行調(diào)用,更新的比較晚,截止發(fā)布前已經(jīng)有28.1k的star了。接下來教大家如何分割一切! ? 首先我們可以下載SAM在官方的代碼鏈接:https://github.com/facebookresearch/segment-anything 下載好之后需要配置一下SAM需要的環(huán)境,用pycharm打開配置

    2024年02月05日
    瀏覽(31)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包