Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 99久久精品免费视频,91色综合久久,97视频免费人人观看人人

          整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          基于HTML5的WebGIS實時客戶端設計

          基于HTML5的WebGIS實時客戶端設計

          : 在WebGIS的瀏覽器端存在繪圖效率差、不能直接支持矢量繪圖等問題。為提高客戶端的交互性和實時性,在解決瀏覽器不支持矢量繪圖和渲染速度慢、存儲空間小、傳輸速率慢這些問題的基礎上,結合HTML5中的Canvas、WebSocket、WebStorage技術,構建了WebGIS實時客戶端,有效地改善了客戶端存在的問題,改善用戶的體驗。

          0 引言

          WebGIS是GIS技術與Internet的結合體,是對網絡GIS的發展,它將GIS從一種使用計算機的處理地理信息的系統工具,變為一種網絡共享資源,提高了地理信息的使用效率,使地理信息的價值得以充分體現[1]。WebGIS的實現手段主要是基于Web技術的多級B/S體系結構,即瀏覽器、GIS服務器、數據庫等。B/S模式的構架簡化了客戶端系統的部署,降低了用戶使用難度,同時也極大提高了系統的可維護性[2]。但是這種被動的工作模式無法滿足用戶實時性的需求。對于WebGIS的架構研究,以前主要是對服務器端技術的改進,如使用CGI、Server API等服務端技術,但是這些技術對于服務器及網絡的要求較高。隨著客戶端技術的發展,Java Applet技術、Plug-in技術、Ajax技術的出現擴展了客戶端的功能,但是用戶需要預先安裝這些插件,安裝插件帶來了一定的安全隱患和不方便性。對比這兩種形式,使用HTML5的新技術實現的功能并不需要插件支持,且其本地存儲功能和高效率的雙向通信功能,還有動態快速繪圖功能的提出,使實時客戶端的實現成為可能。

          1 實時客戶端的WebGIS系統結構

          HTML5是W3C推出的新標準,其強大功能已經被大部分的瀏覽器支持,同時,相對于以前的版本,HTML5的改變不僅僅是使用更方便。第一,它新增了更具有語義化的標簽和使用更智能化的表單;第二,HTML5還新增了許多JavaScript API,如實時繪圖(Canvas和SVG)、離線存儲(WebStorage)、實時通信(WebSocket)API等,這些API為實現實時客戶端提供了可能。用HTML5來實現WebGIS有地圖無限縮放而圖不失真,地圖的顯示渲染效果逼真的優勢;且支持JavaScript腳本實現地圖的漫游、縮放、查詢等功能,這些功能都無需插件支持并可在不同平臺與設備上運行[3]。根據這些特性,本文在傳統架構的基礎上,構建了圖1所示的WebGIS實時客戶端。

          在客戶端這些模塊中使用HTML5和JavaScript技術,實現數據地圖的繪制、本地存儲、數據傳輸等功能,將部分簡單的功能交給客戶端完成,增加了WebGIS客戶端的交互能力,減少了服務器的傳輸壓力,也增加了數據傳輸的效率,實現了客戶端的實時性。

          2 WebGIS客戶端的具體設計

          2.1 數據實時更新與傳輸設計

          空間數據格式有柵格數據和矢量數據。柵格數據交互性能差,可用來展示空間數據,矢量數據交互性較好,可用來表示空間對象,但是客戶端不能直接支持矢量數據的二進制格式傳輸,所以數據在傳輸中就要進行格式編碼,目前使用的比較多的數據傳輸格式是GeoJSON(基于JSON數據格式的地理要素表示格式)。JSON(JavaScript Object Notation)是輕量級數據交換格式,適合于服務器與瀏覽器(通過JavaScript)交互[4],在瀏覽器端JSON能夠簡單快速地解析成可以被客戶端操作的JavaScript地理信息,不需要使用專門的文本解析API進行操作。空間數據傳輸大多使用Ajax的異步傳輸方式,但Ajax輪詢方式的時延較長,傳輸的實時性不高,因此將Ajax用于地圖數據的推送。實時性方面還是需要HTML5的WebSocket API實現。WebSocket使瀏覽器具有客戶機/服務器(C/S)模式下應用程序的實時通信能力[5]。WebSocket的優勢有:(1)為瀏覽器和服務器之間建立的更高效的雙向通信提供支持。其連接本質為TCP連接,因此瀏覽器通過JavaScript向服務器發出建立WebSocket連接的請求,onopen事件接收消息,連接建立以后,客戶端和服務器端就可通過TCP連接直接交換數據。(2)WebSocket有更為輕量級的Header,除了首次建立鏈接時需要發送頭部與普通Web鏈接類似的數據之外,連接建立后,相互溝通的Header就會很簡潔,大大減少了冗余的數據傳輸[6];通過新建WebSocket實例建立握手并完成與服務器的連接,建立好連接之后數據就可以以全雙工模式在客戶端與服務器之間進行雙向傳輸,并一直保持連接,直到用戶主動關閉[3]。圖2是傳統傳輸方式與WebSocket傳輸方式數據量的對比,從結果可以看出,當傳輸數據量增大時,WebSocket的效率更高。

          需要在服務器端安裝開源的WebSocket支持數據庫,如Node.js、LibWebSockets、PHP WebSocket Server等,以調用接口使用。具體傳輸過程是:GIS服務器從空間數據庫獲取數據,將空間數據解析成JSON的格式,然后發送到已經與WebSocket服務器連接的客戶端,客戶端WebSocket實例的onmessage事件接收數據并使用JSON.parse函數將JSON字符串解析成JavaScript對象,再根據對象的內容在WebGIS的地圖中解析顯示。WebSocket API一個顯著特點是,連接建立后,服務器可主動推送消息。支持WebSocket協議的服務端接受請求和處理WebSocket任務,在客戶端可用WebStorage存儲模塊緩存傳輸過來的數據,WebSocket的中間傳輸機制就實現了數據實時更新。

          2.2 客戶端空間數據緩存設計

          客戶端緩存功能主要是由WebStorage API來實現,WebStorage API是以Key-Value形式來進行數據的持久性存儲。傳統客戶端一般是使用Cookie存儲數據,但是它效率低,存儲空間小,不能滿足大量矢量數據的存儲。WebStorage提供的兩種存儲方式可以改善這個狀況,一種是SessionStorage,它是一種會話級別的存儲方式,存儲的數據只在當前頁面有效,當頁面關閉時,數據也會隨之刪除,據此SessionStorage可以用在矢量圖繪制的緩存方面,即讓SessionStorage自動緩存解析好的JSON格式的矢量層數據,當需要數據時直接從SessionStorage中提取JSON數據,這比從空間數據庫中獲取再解析效率明顯更高,數據顯示模塊可以直接從中獲取數據進行繪制。另一種方式是LocalStorage,它是一個跨多窗口且數據永久存儲的方式,只有使用清除函數clear、removeItem或手動刪除數據時數據才會從瀏覽器中清除,同時它的數據可以在同源的窗口或標簽共享使用。因此它可以用來永久存儲空間分析后的數據或服務器發送的數據和用戶數據,下次用戶打開瀏覽器可直接使用這些數據。圖3是具體矢量數據本地存儲過程。將數據緩存到本地,不用與服務器發生交互,客戶端存儲的數據可以由JavaScript訪問。

          WebStorage存儲技術和WebSocket技術可結合使用并與JavaScript一起實現數據的實時更新,減輕服務器壓力。用戶發送數據請求后,WebSocket建立連接,將得到的數據解析后存儲在WebStorage預先定義好的空間中,等待用戶提取。對于常須更新地圖數據的操作采用這種預先存儲的方式,可以加快數據的渲染效率。為了提高圖3的實時更新效果,可以設定異步存儲機制,過程如下:(1)創建并初始化WebStorage對象,設置緩存區大小(緩存區分段);(2)用戶發出消息,觸發onopen事件;(3)為WebSocket對象的信息添加偵聽器;(4)服務器調用received函數處理事件;(5)客戶端接收服務器發送的消息,觸發緩存判斷函數,判斷緩存大小,如果超出,設置緩存片段的編號,對象異步sends數據請求服務器處理;(6)服務器將片段編號入隊(服務端設置),直到傳輸完成,清除編號。這種傳輸方式將進一步減少網絡流量,減少服務器的負載,提升傳輸效率。

          2.3 數據顯示設計

          HTML5現提供了Canvas API,它可以解決傳統開發瀏覽器支持度差、跨平臺性不強和繪制矢量圖形需要插件的問題,通過JavaScript在瀏覽器不依賴任何插件的情況下高效地繪制動態圖形[7],避免了安裝插件帶來安全風險。

          2.3.1 繪制方法

          Canvas API使用比較簡單,像其他HTML標簽一樣,只需在HTML5的頁面中添加一個<canvas>元素即可。Canvas繪圖首先要獲得上下文(context),因為Canvas自己本身并沒有繪圖能力,所以所有的繪圖工作要由JavaScript完成。它的工作過程為:先定義Canvas元素的id,然后通過getElementById函數找到自己前面創建好的Canvas元素,最后用JavaScript調用繪圖API接口得到上下文繪圖環境后就可在畫布上繪制任何的圖形了。但Canvas只支持一種基本圖形——矩形,想使用Canvas繪制其他的圖形,就要使用其提供的路徑(Path)繪制函數[8],使用beginPath開始繪制,使用moveTo、lineTo繪制直線,繪制完畢后調用fill、stroke進行填充或者設置邊框,最后調用closePath結束圖形繪制。Canvas在矢量數據方面是像素級管理,Canvas的路徑操作能充分滿足矢量數據中的點要素、線要素、面要素以及符號的表達要求。

          2.3.2 數據顯示過程

          用Canvas與JavaScript技術實現地圖實時繪制。地理實體對象可以根據OGC的簡單要素規范和GIS界的研究將其分為:點狀實體、線狀實體、面狀實體、標注實體和柵格實體[3]。Canvas可直接使用這些實體,對于柵格實體,可以用JavaScript對象表示,通過API drawImage直接在HTML5 Canvas中繪制。矢量實體的地理要素從GeoJSON文本轉化為JavaScript對象,根據該對象的信息,調用坐標轉換對象,將坐標轉換成Canvas元素里的屏幕坐標來對應顯示要素。實現實時繪圖的流程為:(1)服務器從數據庫獲取數據;(2)數據進行JSON格式解析;(3)瀏覽器加載地圖,調用Canvas畫布及函數實現繪圖和地圖的顯示;(4)地圖操作由自定義腳本實現地圖渲染。Canvas在客戶端展現地理數據的靈活性與互操作性要優于傳統的切片技術,并且在地圖加載速度方面有明顯的優勢[8],因此將Canvas和WebStorage結合起來,可以提高實時性能,將要顯示或者要存儲的數據先經過緩存,再進行顯示或存儲,這種機制效率明顯更高。圖4說明了從數據推送到顯示的流程。

          3 客戶端整體過程

          Canvas實現實時繪圖和快速渲染,WebSocket API在通信方面提供了支持。WebStorage提供了客戶端的本地存儲技術,以地圖放大操作為例,用戶提交請求,數據獲取函數可以從SessionStorage中獲取數據,然后將緩存的數據轉換成JavaScript對象,最后通過Canvas直接添加在地圖中,同時,緩存中的數據不斷更新。WebSocket的雙向通信機制和WebStorage的異步存儲機制加速了數據交換效率,空間數據庫也通過WebGIS服務器,在實時通信的基礎上,將數據以JSON文本格式傳輸到客戶端,存入SessionStorage中,窗口關閉后,所有數據存入LocalStorage,供用戶下次直接使用。這種方式的效率很明顯會比從服務器獲取數據的方式高,實時性要好,如需要執行其他的交互操作,也可以基于這種方式實現。

          4 結論

          隨著Web技術的發展,客戶端的交互性和實時性要求不斷提升,據此,本文將HTML5的新特性與JavaScript技術結合,在WebSocket雙向通信機制和WebStorage緩存機制實現異步存儲提供的數據支撐,Canvas能實現動態繪圖和快速渲染的基礎上,提出了一種實時性更強的WebGIS客戶端,為建立實時的WebGIS客戶端提供了一種方案。HTML5中的新技術雖然強大,還是有需要加強的地方,WebStorage讓數據能夠緩存在本地,但是由于是存儲在本地,數據容易泄漏,安全性還有欠缺。未來WebGIS的發展會隨著數據量的增大實現云平臺化,資源更龐大,數據更易共享,用戶使用起來也會更方便。

          參考文獻

          [1] 孟令奎,史文中,張鵬林,等.網絡地理信息系統原理與技術[M].北京:科學出版社,2010.

          [2] 李博霏,李欣,李艷明.基于瀏覽器的地理信息服務客戶端技術研究[J].計算機工程與設計,2011(9):3031-3035.

          [3] 龍云.基于HTML5的WebGIS研究[D].贛州:江西理工大學,2013.

          [4] CROCKFORD D. The application/json media type for JavaScript Object Notation(JSON)[EB/OL]. [2006-07]. http://tools.ietf.org/html/rfc4627.

          [5] 徐卓揆.基于HTML5、Ajax和Web Service的WebGIS研究[J].測繪科學,2012,37(1):145-147.

          [6] 魏進鋒,孫春華.應用HTML5的WebSocket實現BiDirection數據交換[EB/OL].[2012-12-28](2015-02-25).http://www.ibm.com/developerworks/cn/web/1112_weijf_websocket/.

          [7] 王曉.基于HTML5的矢量地圖發布關鍵技術研究[D].南京:南京師范大學,2011.

          [8] 梁春雨,李新通.使用HTML5 Canvas構建基于GeoJSON的輕量級WebGIS[J].計算機科學與應用,2012(2):189-196.

          數據可視化中,使用頻率最高的展現方式肯定是地圖可視化。基本上現有的大屏都是以地圖作為主視圖來呈現的,沒有一幅地圖放到大屏中央,已經不好意思給同行、媒體界通告自己企業數據分析有多牛了。


          怎么將地理數據處理得更好,怎么把地圖設計出更好的視覺效果也一直是我們研究的方向。億信ABI作為億信華辰自主研發的一款全能型數據分析產品,具備強大的數據地圖功能,內置世界地圖、五大洲地圖、中國地圖,囊括各省、市區縣地圖,每個地圖都有flash、圖片和html5三種格式,還能實現鉆取、聯動等功能。

          下面帶大家一起來看一下億信ABI中地圖可視化的那些事兒。

          渲染地圖

          渲染地圖適合展示數據在地理區塊空間的分布狀況,用顏色來區分數值大小。隨意切換全國任意省市地圖方便快捷,還可以通過事件聯動其他組件和下鉆。


          標點地圖

          標點地圖主要用于展示地理區域內的空間分布,非常適合展示一組或多組數據在地理空間的分布狀況,數據的地理屬性確定點位置,數據大小則通過點的顏色來體現,通常會配以色帶來映射顏色的取值范圍和大小關系。


          流向地圖

          一般是用于數據中具有兩個維度的地理信息,用于展示數據的流入&流出情況。其經常使用的場景包括:世界范圍或者全國范圍內的人口遷移,不同地區飛機/船舶/高鐵等交通航線的繁忙程度和流向情況,不同地區包裹的寄出量或收貨量等。


          Flash地圖

          億信ABI中的Flash地圖只需要電腦安裝有Flash插件即可使用,非常方便。通過簡單的組件拖拽以及屬性設置,就可以動態地在地圖上顯示屬性信息,可以自定義Flash地圖的區塊顏色、注記、鏈接、音效等。不僅如此Flash地圖是基于矢量結構儲存,可以做到無極縮放、無縫連接的同時,圖像質量并無損失,展示效果非凡。


          GIS地圖

          億信ABI中內置有集成百度地圖、天地圖、arcgis地圖三大主流地圖的應用接口,可以一鍵與多種分析手段相結合,將ABI中強大的報表分析引擎與GIS應用強強聯合,實現動態參數、顏色渲染、地圖標點分布、地圖鉆取、預警分析等會多重效果。


          3D地圖

          在需要按照地區分析數據時,更直觀的展示數據我們可以使用3D地圖,數值大小映射到柱形圖的顏色和大小上,能夠一目了然看出各個地區數據的分布,展示出來更加直觀,增加地圖的立體感,還可以360度旋轉噢~如下圖所示:


          有了億信ABI內置的地圖組件,你只需要拖拉拽,不需要寫代碼,簡單、快捷的實現地圖可視化。

          薦:使用NSDT 編輯器快速搭建3D應用場景


          建 模 和 3D 地形

          大多數 3D 對象是 使用建模工具創建,這是有充分理由的。創建復雜對象 (如飛機甚至建筑物)很難在代碼中完成。建模工具 幾乎總是有意義的,但也有例外!其中之一可能是案例 就像飛行拱廊島連綿起伏的丘陵一樣。我們最終使用了 我們發現更簡單,甚至可能更直觀的技術:一個 高度圖。

          高度圖是一種 使用常規二維圖像來描述 像島嶼或其他地形一樣的表面。這是一種非常常見的使用方式 高程數據,不僅在游戲中,而且在地理信息系統中 制圖師和地質學家使用的 (GIS)。

          幫助您獲得想法 有關其工作原理,請查看此交互式演示中的高度圖。嘗試繪圖 ,然后檢出生成的地形。

          高度圖背后的概念 很簡單。在上圖所示的圖像中,純黑色是 “地板”和純白色是最高峰。介于兩者之間的灰度顏色 表示相應的高程。這為我們提供了 256 個海拔高度,這 是我們游戲的大量細節。實際應用程序可能會使用完整的 色譜可存儲更多層次的細節(2564=4,294,967,296 級 詳細信息(如果包含 Alpha 通道)。

          高度圖有幾個 與傳統多邊形網格相比的優勢:

          一、高度圖很多 更緊湊。僅存儲最重要的數據(高程)。它 需要以編程方式轉換為 3D 對象,但這是 經典交易:您現在節省空間,稍后通過計算付款。通過存儲 數據即圖像,您將獲得另一個空間優勢:您可以利用標準 圖像壓縮技術并使數據變小(相比之下)!

          其次,高度圖是一個 生成、可視化和編輯地形的便捷方式。非常直觀 當你看到一個。感覺有點像看地圖。這被證明是 對飛行街機特別有用。我們設計和編輯了我們的島嶼 在 Photoshop 中!這使得根據需要進行小調整變得非常簡單。 例如,當我們想確保跑道完全平坦時, 我們只是確保以單一顏色在該區域上繪畫。

          您可以看到高度圖 下面的飛行拱廊。看看你是否能發現我們為 跑道和村莊。

          飛行街機島的高度圖。它是在Photoshop中創建的,它基于著名的太平洋島鏈中的“大島”。有什么猜測嗎?

          在解碼高度貼圖后映射到生成的 3D 網格上的紋理。更多內容見下文。

          解碼高度圖

          我們用Babylon.js建造了飛行拱廊,Babylon給了我們一個漂亮的 從高度圖到 3D 的簡單路徑。Babylon提供了一個 API 來生成 來自高度圖圖像的網格幾何體:

          ar ground=BABYLON.Mesh.CreateGroundFromHeightMap(

          'your-mesh-name',

          '/path/to/heightmap.png',

          100, // width of the ground mesh (x axis)
          100, // depth of the ground mesh (z axis)

          40, // number of subdivisions

          0, // min height

          50, // max height

          scene,

          false, // updateable?

          null // callback when mesh is ready
          );`

          細節量是 由該細分的財產決定。需要注意的是, 參數是指高度圖兩側的細分數量 圖像,而不是單元格總數。所以稍微增加這個數字可以 對網格中的頂點總數有很大影響。

          • 20 個細分=400 細胞
          • 50 個細分=2,500 細胞
          • 100 個細分=10,000 細胞
          • 500 個細分=250,000 細胞
          • 1,000 個細分=1,000,000 細胞

          在下一節中,我們將 了解如何為地面設置紋理,但在嘗試使用高度貼圖時 創建時,查看線框很有用。這是應用簡單代碼 線框紋理,因此很容易看到高度圖數據是如何轉換為的 網格的頂點:

          // simple wireframe material

          var material=new BABYLON.StandardMaterial('ground-material', scene);

          material.wireframe=true;

          ground.material=material;`

          創建紋理細節

          一旦我們有一個模型,映射一個 質地相對簡單。對于飛行街機,我們簡單地創建了一個 非常大的圖像,與我們的高度圖中的島嶼相匹配。圖像得到 延伸到地形的輪廓上,所以紋理和高度圖 保持相關性。這真的很容易想象,再一次,所有 制作工作是在Photoshop中完成的。

          原始紋理圖像是 創建于 4096x4096。那可是挺大的!(我們最終將尺寸減小了 為了保持下載合理,級別到2048x2048,但所有 使用全尺寸圖像進行開發。這是來自 原始紋理。

          原始島嶼紋理的全像素示例。整個城鎮只有大約300平方像素。

          這些矩形表示 島上城鎮的建筑。我們很快注意到 我們可以在地形和 其他 3D 模型。即使使用我們巨大的島嶼紋理,區別在于 令人分心的明顯!

          為了解決這個問題,我們“混合” 以隨機噪聲的形式進入地形紋理的附加細節。您可以 請參閱下面的之前和之后。注意額外的噪點如何增強外觀 地形細節。

          我們創建了一個自定義著色器 添加噪音。著色器為您提供了對 WebGL 3D 場景的渲染,這是著色器如何 有用。

          WebGL著色器由兩個組成 主要部分:頂點和片段著色器。頂點的主要目標 著色器是將頂點映射到渲染幀中的某個位置。片段(或 像素)著色器控制像素的結果顏色。

          著色器是用 稱為GLSL(圖形庫著色器語言)的高級語言,它 類似于C。此代碼在 GPU 上執行。深入了解如何 著色器工作,請參閱此處 有關如何為 Babylon.js 創建自己的自定義著色器的教程,或參閱此圖形著色器編碼初學者指南。

          頂點著色器

          我們不會改變我們的 紋理映射到地面網格體,因此我們的頂點著色器非常簡單。 它只是計算標準映射并分配目標位置。

          precision mediump float;
          // Attributes
          attribute vec3 position;
          attribute vec3 normal;
          attribute vec2 uv;
          // Uniforms
          uniform mat4 worldViewProjection;
          // Varying
          varying vec4 vPosition;
          varying vec3 vNormal;
          varying vec2 vUV;
          void main() {
          vec4 p=vec4( position, 1.0 );
          vPosition=p;
          vNormal=normal;
          vUV=uv;
          gl_Position=worldViewProjection * p;
          }

          碎片著色器

          我們的片段著色器有點 更復雜。它結合了兩個不同的圖像:基礎圖像和混合圖像。 基礎圖像映射到整個地面網格。在飛行街機中,這個 是島嶼的彩色圖像。混合圖像是使用的小噪點圖像 在近距離為地面提供一些紋理和細節。著色器 組合每個圖像中的值以創建跨 島。

          飛行的最后一課 街機發生在有霧的日子,所以我們的像素著色器的另一個任務是 調整顏色以模擬霧。調整基于頂點的距離 來自相機,遠處像素被“遮擋”得更厲害 在霧中。您將在函數中看到此距離計算 在主著色器代碼上方。calcFogFactor

          // #ifdef GL_ES
          precision highp float;
          // #endif
          uniform mat4 worldView;
          varying vec4 vPosition;
          varying vec3 vNormal;
          varying vec2 vUV;
          // Refs
          uniform sampler2D baseSampler;
          uniform sampler2D blendSampler;
          uniform float blendScaleU;
          uniform float blendScaleV;
          // #define FOGMODE_NONE 0.
          // #define FOGMODE_EXP 1.
          // #define FOGMODE_EXP2 2.
          // #define FOGMODE_LINEAR 3.
          // #define E 2.71828
          uniform vec4 vFogInfos;
          uniform vec3 vFogColor;
          float calcFogFactor() {
          // gets distance from camera to vertex
          float fogDistance=gl_FragCoord.z / gl_FragCoord.w;
          float fogCoeff=1.0;
          float fogStart=vFogInfos.y;
          float fogEnd=vFogInfos.z;
          float fogDensity=vFogInfos.w;
          if (FOGMODE_LINEAR==vFogInfos.x) {
          fogCoeff=(fogEnd - fogDistance) / (fogEnd - fogStart);
          }
          else if (FOGMODE_EXP==vFogInfos.x) {
          fogCoeff=1.0 / pow(E, fogDistance * fogDensity);
          }
          else if (FOGMODE_EXP2==vFogInfos.x) {
          fogCoeff=1.0 / pow(E, fogDistance * fogDistance * fogDensity * fogDensity);
          }
          return clamp(fogCoeff, 0.0, 1.0);
          }
          void main(void) {
          vec4 baseColor=texture2D(baseSampler, vUV);
          vec2 blendUV=vec2(vUV.x * blendScaleU, vUV.y * blendScaleV);
          vec4 blendColor=texture2D(blendSampler, blendUV);
          // multiply type blending mode
          vec4 color=baseColor * blendColor;
          // factor in fog color
          float fog=calcFogFactor();
          color.rgb=fog * color.rgb + (1.0 - fog) * vFogColor;
          gl_FragColor=color;
          }

          我們定制的最后一件作品 Blend shader 是 Babylon 使用的 JavaScript 代碼。主要目的 此代碼用于準備傳遞給頂點和像素著色器的參數。

          function BlendMaterial(name, scene, options) {
          this.name=name;
          this.id=name;
          this.options=options;
          this.blendScaleU=options.blendScaleU || 1;
          this.blendScaleV=options.blendScaleV || 1;
          this._scene=scene;
          scene.materials.push(this);
          var assets=options.assetManager;
          var textureTask=assets.addTextureTask('blend-material-base-task', options.baseImage);
          textureTask.onSuccess=_.bind(function(task) {

              this.baseTexture=task.texture;
              this.baseTexture.uScale=1;
              this.baseTexture.vScale=1;
              if (options.baseHasAlpha) {
                  this.baseTexture.hasAlpha=true;
              }
          }, this);
          textureTask=assets.addTextureTask('blend-material-blend-task', options.blendImage);
          textureTask.onSuccess=_.bind(function(task) {
              this.blendTexture=task.texture;
              this.blendTexture.wrapU=BABYLON.Texture.MIRROR_ADDRESSMODE;
              this.blendTexture.wrapV=BABYLON.Texture.MIRROR_ADDRESSMODE;
          }, this);
          

          }
          BlendMaterial.prototype=Object.create(BABYLON.Material.prototype);
          BlendMaterial.prototype.needAlphaBlending=function () {
          return (this.options.baseHasAlpha===true);
          };
          BlendMaterial.prototype.needAlphaTesting=function () {
          return false;
          };
          BlendMaterial.prototype.isReady=function (mesh) {
          var engine=this._scene.getEngine();
          // make sure textures are ready
          if (!this.baseTexture || !this.blendTexture) {
          return false;
          }
          if (!this._effect) {
          this._effect=engine.createEffect(
          // shader name
          "blend",
          // attributes describing topology of vertices
          [ "position", "normal", "uv" ],
          // uniforms (external variables) defined by the shaders
          [ "worldViewProjection", "world", "blendScaleU", "blendScaleV", "vFogInfos", "vFogColor" ],
          // samplers (objects used to read textures)
          [ "baseSampler", "blendSampler" ],
          // optional define string
          "");
          }
          if (!this._effect.isReady()) {
          return false;
          }
          return true;
          };
          BlendMaterial.prototype.bind=function (world, mesh) {
          var scene=this._scene;
          this._effect.setFloat4("vFogInfos", scene.fogMode, scene.fogStart, scene.fogEnd, scene.fogDensity);
          this._effect.setColor3("vFogColor", scene.fogColor);
          this._effect.setMatrix("world", world);
          this._effect.setMatrix("worldViewProjection", world.multiply(scene.getTransformMatrix()));
          // Textures
          this._effect.setTexture("baseSampler", this.baseTexture);
          this._effect.setTexture("blendSampler", this.blendTexture);
          this._effect.setFloat("blendScaleU", this.blendScaleU);
          this._effect.setFloat("blendScaleV", this.blendScaleV);
          };
          BlendMaterial.prototype.dispose=function () {
          if (this.baseTexture) {
          this.baseTexture.dispose();
          }
          if (this.blendTexture) {
          this.blendTexture.dispose();
          }
          this.baseDispose();
          };

          Babylon.js使它變得容易 創建基于著色器的自定義材質。我們的混合材料相對簡單, 但它確實對島嶼的外觀產生了很大的影響,當 飛機低空飛到地面。著色器將 GPU 的強大功能帶到 瀏覽器,擴展可應用于 3D 的創意效果類型 場景。在我們的案例中,這是畫龍點名!

          原文鏈接:使用 WebGL 為 HTML5 游戲創建逼真的地形


          主站蜘蛛池模板: 亚洲一区二区三区在线| 日韩精品一区二区三区毛片| 久久久无码精品人妻一区| 国产成人无码精品一区在线观看| 亚洲一区免费观看| 国产色综合一区二区三区| 美女视频一区二区三区| 精品无人乱码一区二区三区| 91福利国产在线观一区二区| 一区二区三区中文字幕| 国产在线观看精品一区二区三区91| 精品无码AV一区二区三区不卡| 国产亚洲无线码一区二区| 精品亚洲综合在线第一区| 中文字幕一区二区三区在线播放 | 人妻精品无码一区二区三区| 无码人妻精品一区二区三区久久| 久久综合一区二区无码| 国产成人一区在线不卡| 三上悠亚国产精品一区| 亚洲一区爱区精品无码| 亚洲AV午夜福利精品一区二区| 国产内射在线激情一区| 无码少妇一区二区| 麻豆国产一区二区在线观看| 91国偷自产一区二区三区| 精品无码人妻一区二区三区18| 无码少妇A片一区二区三区| 怡红院美国分院一区二区| 国产在线一区二区三区av| 亚洲国产成人久久一区WWW | 免费无码一区二区三区蜜桃| 少妇无码AV无码一区| 精品一区二区三区四区| 91成人爽a毛片一区二区| 久久青青草原一区二区| 国产精品一区在线观看你懂的| 亚洲国产综合无码一区| 韩国福利影视一区二区三区| 成人免费一区二区三区在线观看| 国产精品免费大片一区二区|