ThreeJS Shader的效果樣例網格平面和網格球體(一)

来源:https://www.cnblogs.com/codeOnMar/p/18233666
-Advertisement-
Play Games

本文中效果主要採用ThreeJS 中的著色器(Shader)以及結合ShaderMaterial實現的。 主要用到的內置方法有: step:是一個階躍函數,它將一個浮點數與一個閾值進行比較,並返回一個階躍值; 比如step(edge, x), 如果 x 小於等於 edge,則返回 0.0, 如果 x ...


本文中效果主要採用ThreeJS 中的著色器(Shader)以及結合ShaderMaterial實現的。

主要用到的內置方法有:

step:是一個階躍函數,它將一個浮點數與一個閾值進行比較,並返回一個階躍值;    比如step(edge, x), 如果 x 小於等於 edge,則返回 0.0, 如果 x 大於 edge ,則返回 1.0。 fract:用於獲取浮點數的小數部分。它返回輸入值的小數部分,即去除整數部分後的部分。比如fract(1.5),返回0.5;

一、網格平面

const vertex = '\
    varying vec3 vPos;\
    void main() {\
      vPos = position;\
      gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4( position, 1.0 ); \
    }\
  ';
  const frag = '\
    varying vec3 vPos;\
    void main() {\
      vec3 mask1 = vec3(step(0.5, fract(vPos.x * 2.0)));\
      vec3 mask2 = vec3(step(0.5, fract(vPos.y * 2.0)));\
      vec3 mask3 = vec3(step(0.5, fract(vPos.z * 2.0)));\
      vec3 color = abs(mask1 - mask2);\
      gl_FragColor = vec4(color, 1.0);\
    }\
  ';

 原理:如果設置平面的大小為2,那麼坐標軸X點的範圍為-1.0 ~ 1.0,已X坐標為示例,數據變化形式如下圖 

  

    如上圖可以將數據分為4個部分,X軸和Y軸同理:

      1) 0~0.25的數據經過fract和step函數處理後數據變為0;

      2)   0.25~0.5的數據經過fract和step函數處理後數據變為1;

      3) 0.5~0.75的數據經過處理變為0;

      4) 0.75~1.0的數據經過處理變為1;

     最後將生成的向量X軸-Y軸數據可以繪製成如下圖:

  

  這樣就生成了第一象限的圖形,第二、三、四象限結果同上。

二、網格狀的球體 

   

本列中涉及到GLSL的幾個內置函數:

dot:兩個向量的點積,可以獲得向量的夾角

asin: 反三角函數,獲得弧度值

1. 第一個圖就是要實現的最終效果,一個網格狀的球體,實現原理主要可以分為分別計算經度方向的線圈和緯度方向的線圈。

2. 與平面網格計算顏色值相同,將兩個顏色值相減即可得到一個網格球體

3. 如何實現緯度方向的線圈?

          

  實現邏輯:將球體沿球心縱向切一刀生成一個圓形橫截面M,將圓分成弧度相等的N個圓弧,然後再間隔開賦予不同的顏色就可以形成圖一的效果。

const vertex = '\
    varying vec3 vPos;\
    void main() {\
      vPos = position;\
      gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4( position, 1.0 ); \
    }\
  ';
  // 獲取UV點對應的單位向量B
  // 獲取Z軸方向的單位向量A
  // 計算向量B和向量A的夾角
  // 通過degree將夾角的弧度轉換成角度,除以要拆分的條數latBeta,通過配合fract和step即可獲取間隔的0、1值
  // 最後生成間隔的黑白顏色值
  const frag = '\
    uniform float latBeta;\
    varying vec3 vPos;\
    void main() {\
      vec3 latEveryVec = normalize(vPos);\
      vec3 latBaseVec = normalize(vec3(vPos.x, 0, vPos.z));\
      float latAngle = asin(dot(latBaseVec, latEveryVec));\
      vec3 latColor = vec3(step(0.5, fract(degrees(latAngle) / latBeta)));\
      gl_FragColor = vec4(latColor, 1.0);\
    }\
  ';

 

4. 如何實現經度方向的線圈?

    

 實現邏輯:與第三步生成緯度方向的線圈類似,將球體沿球心橫向切一刀生成一個圓形橫截面M,將圓分成弧度相等的N個圓弧,然後再間隔開賦予不同的顏色就可以形成圖一的效果。

 

const vertex = '\
    varying vec3 vPos;\
    void main() {\
      vPos = position;\
      gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4( position, 1.0 ); \
    }\
  ';
  // 獲取UV點對應的單位向量B
  // 獲取X軸正方向的單位向量A
  // 計算向量B和向量A的夾角
  // 通過degree將夾角的弧度轉換成角度,除以要拆分的條數lonBeta,通過配合fract和step即可獲取間隔的0、1值
  // 最後生成間隔的黑白顏色值
  const frag = '\
    uniform float lonBeta;\
    varying vec3 vPos;\
    void main() {\
      vec3 lonEveryVec = normalize(vec3(vPos.x, 0.0, vPos.z));\
      vec3 lonBaseVec = vec3(0.0, 0.0, 1.0);\
      float lonAngle = asin(dot(lonBaseVec, lonEveryVec));\
      vec3 lonColor = vec3(step(0.5, fract(degrees(lonAngle) / lonBeta)));\
      gl_FragColor = vec4(lonColor, 1.0);\
    }\
  ';

 

完整代碼如下:

const vertex = '\
    varying vec3 vPos;\
    void main() {\
      vPos = position;\
      gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4( position, 1.0 ); \
    }\
  ';
  const frag = '\
    uniform float latBeta;\
    uniform float lonBeta;\
    varying vec3 vPos;\
    void main() {\
      vec3 latEveryVec = normalize(vPos);\
      vec3 latBaseVec = normalize(vec3(vPos.x, 0, vPos.z));\
      float latAngle = asin(dot(latBaseVec, latEveryVec));\
      vec3 latColor = vec3(step(0.5, fract(degrees(latAngle) / latBeta)));\
      \
      vec3 lonEveryVec = normalize(vec3(vPos.x, 0.0, vPos.z));\
      vec3 lonBaseVec = vec3(0.0, 0.0, 1.0);\
      float lonAngle = asin(dot(lonBaseVec, lonEveryVec));\
      vec3 lonColor = vec3(step(0.5, fract(degrees(lonAngle) / lonBeta)));\
      vec3 color = abs(latColor - lonColor);\
      gl_FragColor = vec4(color, 1.0);\
    }\
  ';

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ‍ 寫在開頭 點贊 + 收藏 學會 引言 眾所周知,進度條是程式員大大模擬的程式運行進度,一般會在某些數值卡住不動,引起99%懸案。但是背後的原理你真的清楚嗎,其實進度條真的是勻速運動的! 先來看看效果 接下來開始實現 創建一個矩形,然後摺疊起來,完成! 創建一個容器,用於寬度限 ...
  • title: 使用 useNuxtData 進行高效的數據獲取與管理 date: 2024/7/22 updated: 2024/7/22 author: cmdragon excerpt: 深入講解了Nuxt 3中useNuxtData組合函數的應用,演示瞭如何通過此函數訪問緩存數據,實現組件間數 ...
  • 在寫vue3編譯原理揭秘電子書的時候,發現有不少粉絲還傻傻分不清楚什麼是編譯時?什麼是運行時?這篇文章我們來讓你徹底搞清楚編譯時和運行時的區別。 ...
  • title: Nuxt 使用指南:掌握 useNuxtApp 和運行時上下文 date: 2024/7/21 updated: 2024/7/21 author: cmdragon excerpt: 摘要:“Nuxt 使用指南:掌握 useNuxtApp 和運行時上下文”介紹了Nuxt 3中useN ...
  • TCP(傳輸控制協議)的三次握手是建立可靠連接的關鍵步驟,其設計目的是確保通信雙方都準備好,並且避免重覆的連接初始化。三次握手並不是隨意設定的,而是有其重要的技術理由。 1. 防止重覆的連接初始化 假設只使用兩次握手,會存在以下問題: 舊的重覆SYN包問題:如果網路中的一個舊的SYN包(因為網路延遲 ...
  • title: 使用 useLazyFetch 進行非同步數據獲取 date: 2024/7/20 updated: 2024/7/20 author: cmdragon excerpt: 摘要:“使用 useLazyFetch 進行非同步數據獲取”介紹了在Nuxt開發中利用useLazyFetch進行異 ...
  • ‍ 寫在開頭 點贊 + 收藏 學會 前言 JavaScript 中的相等運算符無疑是新手開發者最容易混淆的知識點之一。 ==和 這兩個運算符的細微差別往往會在代碼中造成一些令人困惑的行為 在本文中,我們將深入探討這兩個相等運算符的工作原理,比較它們的特點和局限性 讓我們開始吧! ...
  • 我是一個很懶的人,很少寫博客。為什麼?因為技術發展太快了,剛學習記錄下來過段時間來看看,發現全都過時了。太浪費感情了。 曾經我也是一個軟粉,一個.Net開發者,同學都入坑Android、Java踩著時代的紅利拿高薪的時候。我卻始終愛著微軟。一直到微軟徹底拋棄Windows Phone10的時候我才死 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...