豐田凱美瑞廢舊車載電池回收妙計:為美國黃石國家公園供電

近日,豐田汽車與美國黃石國家公園合作,推出零排放能源系統,將凱美瑞混合動力車的廢舊電池用於國家公園設施供電,不僅延長了車載電池的使用壽命,同時節約能源,降低污染。  

(圖片來源:cnbeta)   此零排放能源系統主要由凱美瑞廢舊電池與一個太陽能系統構成,以滿足美國黃石國家公園Lamar Buffalo Ranch園區內五棟建築的日常用電需求。其日常電能主要由太陽能供電系統提供。當該系統進行能源補充的時候,凱美瑞的208塊廢舊鎳氫電池組便開始工作,互為補充。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

南投搬家公司費用需注意的眉眉角角,別等搬了再說!

新北清潔公司,居家、辦公、裝潢細清專業服務

深圳電動車熱:東部公交今年將投放565輛純電動車

5月13日,深圳市坪山新區召開新區公交業務座談會,東部公交公司計畫在2015年投放565輛純電動車輛,並將於近期採取公開招標的方式選定車輛更新解決方案。   東部公交公司在坪山新區內運營的公交線路有61條,運力1043台。坪山新區的500米公交網站覆蓋率為92%,公交線路基本覆蓋至坪山新區每個社區。   而目前,東部公交公司在坪山新區運營的新能源線路共16條,運力309輛,占東部公交新能源總運力的35%,其中純電動大巴150輛,混合動力大巴159輛。   2014年東部公交公司在坪山新區投放了134輛純電動大巴。根據坪山新區內運營的線路現狀,東部公交將繼續加大在坪山新區投放新能源車輛的力度,計畫2015年內在坪山新區投放70輛新能源車輛。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※想知道最厲害的網頁設計公司"嚨底家"!

※幫你省時又省力,新北清潔一流服務好口碑

※別再煩惱如何寫文案,掌握八大原則!

易到用車APP上線數千輛新能源車 最低5元人民幣即可搭乘

日前,易到用車啟動了「E-Car計畫」,將陸續在北京、上海、廣州、深圳上線數千輛新能源車型,打造新能源出行平台;與此同時易到用車還宣佈將與普天新能源、龐大集團、騰勢等品牌展開深度合作,共同打造新能源出行聯盟,共建新能源城市。   屆時,易到用車App將上線開通「新能源」車型選項。此次加入易到「E-Car計畫」的車型包括混合動力的雙擎普銳斯、沃爾沃S60L、北汽EV系列以及特斯拉,用戶可通過易到用車App,在「新能源」車型中按需選擇,價格最低5元人民幣(下同)起步,0元/分鐘,0.99元/公里。   易到方面介紹,作為聯盟計畫的一部分,易到用車將與普天合作,在未來共同建設1000個充電樁設施,也同時尋找更多合作夥伴,提供場地共同建樁,而且充電樁建好後,將面向社會全面開放使用。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

新北清潔公司,居家、辦公、裝潢細清專業服務

※推薦評價好的iphone維修中心

加速電動車佈局!首爾3年內增設10萬個充電站

為了加速電動車(electric vehicles)普及率,南韓政府宣佈將主導建設名為「EV-Line」的行動充電站,在首都首爾地區擴增10萬個充電設施;此計畫預計在2018年完工,由當地業者Power Cube和KT南韓電信承包建設業務。充電站將包括停車場、公園、住宅區等各式建築物內。   Power Cube董事表示,首爾當地有8成民眾都住在公寓,而非獨棟房屋,因此家用車都停在公用停車廠。每一個「EV-Line」充電站每小時約可充3.3 KW電量,要充飽整台車約需耗費6至8小時。有些充電站則可提供每小時8KW電量,雖可以縮短一半以上的充電時間,但充電站內的安全考慮成為最大考驗。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

南投搬家費用,距離,噸數怎麼算?達人教你簡易估價知識!

※教你寫出一流的銷售文案?

※超省錢租車方案

澳洲野火危機蔓延 維省紅色警戒危險霧霾罩雪梨

摘錄自2019年11月21日中央通訊社雪梨報導

澳洲消防人員今天(21日)在全國各地與近200處野火搏鬥之際,當局對維多利亞省(Victoria)部分地區發布紅色警戒,雪梨則是連續第3天籠罩在危險霧霾中。

路透社報導,維多利亞省氣溫料將突破攝氏40度,官員下令全面實施禁火令,並警告居住在高度危險地區的民眾隨時準備撤離。

紅色警戒是防範野火的最高級警戒,意味可能陷入最嚴重危機,一旦起火,火勢便會迅速蔓延,情況難以捉摸甚至可能失控。

野火連日來肆虐澳洲多省,令許多社區居民身處險境。截至本月為止,烈焰已奪走至少4條人命,燒毀面積約100萬公頃的農地和灌木林,並摧毀400多戶家園。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司"嚨底家"!

新北清潔公司,居家、辦公、裝潢細清專業服務

發電致空污傷身 研究:改用再生能源衝擊降8成

摘錄自2019年11月19日中央通訊社綜合報導

專家今天(19日)表示,若跟經濟高度仰賴化石燃料的現況相比,若絕大多數能源取自太陽能與風力發電,到本世紀中以前,發電產生的空氣污染對人體衝擊可減少多達80%。

世界衛生組織(WHO)估計,全球每年有420萬人因空氣污染早死,而空污多半源自燃燒化石燃料來發電。

波茨坦氣候變遷衝擊研究所的模型預測,依現行能源業趨勢,全球人類到2050年以前將因空污失去600萬年總壽命,若未來30年再生能源主導發電業,則可把這項數據減少至100萬年左右。

另外,這份報告也探討綠能發電在本世紀中之前對於環境和生態的影響。研究團隊發現,儘管生物能源(bioenergy,以生物來源為材料製造的再生能源)具備低碳排潛力,卻會對環境帶來重大影響。事實上若以千瓦小時計算,生物能源要跟太陽能板生產等量能源,所需土地是太陽能板的100倍左右。

波茨坦氣候變遷衝擊研究所的土地利用管理部門負責人卜普(Alexander Popp)說:「土地對地球而言是有限資源。…由於全球人口持續增長,同時需要電力和食物,土地與糧食體系面臨的壓力也會增加。」

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

南投搬家費用,距離,噸數怎麼算?達人教你簡易估價知識!

※教你寫出一流的銷售文案?

對抗暖化鼓舞世人 瑞典環保少女獲兒童和平獎

摘錄自2019年11月21日中央通訊社海牙報導

瑞典環保少女童貝里因對抗氣候變遷付出努力,鼓舞數百萬同儕為氣候問題發聲,今天(21日)獲頒國際兒童和平獎(International Children’s Peace Prize)。

年僅16歲的童貝里無法親自出席位於海牙的頒獎典禮,因為她11月中離開美國轉赴歐洲,正搭著小船穿越大西洋,準備參加將在馬德里舉辦的聯合國氣候高峰會。但童貝里還是發布訊息表示,她「非常感謝,並且很榮幸獲得這個獎」。

童貝里去年在國際暴紅,她發起「為氣候罷課」(School Strike for the Climate)的抗議活動,帶動數以萬計世界各地青年學子響應。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

南投搬家前需注意的眉眉角角,別等搬了再說!

新北清潔公司,居家、辦公、裝潢細清專業服務

人為噪音是全球污染源 研究:軟體動物也受害

摘錄自2019年11月20日中央通訊社報導

一份20日公布的研究報告指出,人為噪音應被視同「全球主要污染源」,參與研究的英國女皇大學(Queen’s University Belfast)科學家刊登在英國皇家學會(Royal Society)生物學通訊(Biology Letters)的文章指出:「我們發現噪音可影響許多種兩棲和節肢動物、鳥類、魚類、哺乳類、軟體動物和爬蟲類。」

這份研究顯示,人為噪音充斥人類生活環境,來源包括都市人口密集區的交通工具和工業設施、飛機和船艇,例如船艇的螺旋槳運轉聲可對鯨類的聲納傳播造成干擾,並因此導致迷失方向的鯨群大規模擱淺。

針對多項個別研究進行整合分析,科學家孔克(Hansjoerg Kunc)和施密特(Rouven Schmidt)得出結論:多數物種對噪音有反應,並非只有少數物種對噪音特別敏感。孔克警告,人為噪音整體而言仍嚴重干擾自然環境。研究人員也提到,人為噪音污染和動物對噪音污染的反應必須放在生態系統的整體脈絡中檢視,尤其是在研議保育措施時。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※想知道最厲害的網頁設計公司"嚨底家"!

※幫你省時又省力,新北清潔一流服務好口碑

※別再煩惱如何寫文案,掌握八大原則!

Electron: 如何以 Vue.js, Vuetify 開始應用

  • Electron: 使用 JavaScript, HTML 和 CSS 等 Web 技術創建原生程序的框架
  • Vue.js: Web 前端用於構建用戶界面的漸進式框架
  • Vuetify: Vue.js 的 Material Design 組件框架

看完以上介紹,也明白了本文要做的事:用 Vue.js 與 Vuetify 組件,基於 Electron 來創建原生桌面應用。

  • 環境準備
    • Visual Studio Code
    • Node.js
    • Yarn
    • Vue CLI
  • 創建 Vue.js 應用
  • 添加 Vuetify 組件
  • 添加 Electron 構建
  • 發布 Electron 應用
  • 參考
  • 結語

環境準備

Visual Studio Code

建議使用的 VS Code 編輯代碼,下載地址: https://code.visualstudio.com/ 。

同時可安裝如下些擴展:

  • ESLint: 代碼檢查
  • Prettier – Code formatter: 代碼格式化
  • Vetur: Vue 代碼工具
  • Vue 2 Snippets: Vue 代碼提示(可選)

查看 VS Code 版本:

$ code -v
1.46.1
cd9ea6488829f560dc949a8b2fb789f3cdc05f5d
x64

Node.js

Node.js 開發環境,下載地址: https://nodejs.org/en/download/ 。

建議選擇 Latest LTS Version ,因為 Electron v9 仍舊使用的 Node.js v12 。

查看 Node, NPM 版本:

$ node -v
v12.18.1

$ npm -v
6.14.5

Yarn

Yarn 包管理工具,相比 NPM 而言: Fast, Reliable, Secure 。

GitHub: https://github.com/yarnpkg/yarn

全局安裝 Yarn :

npm config set registry https://registry.npm.taobao.org
npm install -g yarn

查看 Yarn 版本:

$ yarn -v
1.22.4

Vue CLI

Vue CLI 是 Vue.js 開發的標準工具。

GitHub: https://github.com/vuejs/vue-cli

全局安裝 Vue CLI :

yarn global add @vue/cli

查看 Vue CLI 版本:

$ vue -V
@vue/cli 4.4.6

創建 Vue.js 應用

vue create my-app

跟隨引導進行工程配置,如下:

Vue CLI v4.4.6
? Please pick a preset: Manually select features
? Check the features needed for your project: Babel, TS, Router, Vuex, Linter
? Use class-style component syntax? Yes
? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? Yes
? Use history mode for router? (Requires proper server setup for index fallback in production) Yes
? Pick a linter / formatter config: Prettier
? Pick additional lint features: Lint on save
? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated config files
? Save this as a preset for future projects? No
? Pick the package manager to use when installing dependencies: Yarn

~/.vuerc 會保存一些可復用的 preset :

$ cat ~/.vuerc
{
  "useTaobaoRegistry": true,
  "packageManager": "yarn"
}

運行應用:

cd my-app
yarn serve

瀏覽器打開 http://localhost:8080/

添加 Vuetify 組件

Vuetify 是 Vue.js 的 Material Design 組件庫。也可以換用其他的,如 Element 等。

GitHub: https://github.com/vuetifyjs/vuetify

添加 Vuetify :

cd my-app
vue add vuetify

preset 選擇 Default

? Choose a preset: Default (recommended)

添加完成后,編輯下 tsconfig.json

{
  "compilerOptions": {
    ...
    "types": [
-      "webpack-env"
+      "webpack-env",
+      "vuetify"
    ],
    ...
  },
  ...
}

運行應用:

yarn serve

瀏覽器打開 http://localhost:8080/

編輯 tsconfig.json 是為了修正如下錯誤

ERROR in /Users/John/Codes/ikuokuo/start-electron/my-app/src/plugins/vuetify.ts(2,21):
2:21 Could not find a declaration file for module 'vuetify/lib'. '/Users/John/Codes/ikuokuo/start-electron/my-app/node_modules/vuetify/lib/index.js' implicitly has an 'any' type.
  Try `npm install @types/vuetify` if it exists or add a new declaration (.d.ts) file containing `declare module 'vuetify/lib';`
    1 | import Vue from "vue";
  > 2 | import Vuetify from "vuetify/lib";
      |                     ^
    3 |
    4 | Vue.use(Vuetify);
    5 |

添加 Electron 構建

如果你可以建一個網站,你就可以建一個桌面應用程序。 Electron 負責將 Web 構建成原生桌面應用。

而將 Vue.js 應用構建成 Electron 應用,現在用 Vue CLI Plugin Electron Builder 即可。

首先,指明下 node 版本:

yarn add @types/node@12 --dev

之後,添加 Electron Builder :

cd my-app
vue add electron-builder

Electron 版本選擇 9.0.0

? Choose Electron Version ^9.0.0

添加完成后,編輯下 src/router/index.ts

...
const router = new VueRouter({
-  mode: "history",
+  mode: process.env.IS_ELECTRON ? "hash" : "history",
  base: process.env.BASE_URL,
  routes
});

export default router;

運行應用:

yarn electron:serve

現在是桌面窗口了:

命令定義在了 package.json

{
  ...
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint",
    "electron:build": "vue-cli-service electron:build",
    "electron:serve": "vue-cli-service electron:serve",
    "postinstall": "electron-builder install-app-deps",
    "postuninstall": "electron-builder install-app-deps"
  },
  ...
}

yarn 執行即可,如下:

$ yarn lint
yarn run v1.22.4
$ vue-cli-service lint
 DONE  No lint errors found!
  Done in 3.17s.

yarn add @types/node@12 --dev 是為了修正如下錯誤

ERROR in /Users/John/Codes/ikuokuo/start-electron/my-app/node_modules/electron/electron.d.ts(1659,31):
1659:31 Cannot extend an interface 'NodeJS.EventEmitter'. Did you mean 'implements'?
...

編輯 src/router/index.ts 是為了修正如下警告

 WARN  It is detected that you are using Vue Router. If you are using history mode, you must push the default route when the root component is loaded. Learn more at https://goo.gl/GM1xZG .

發布 Electron 應用

Vue 應用了 Electron Builder 插件,所以直接用此工具即可。

GitHub: https://github.com/electron-userland/electron-builder

yarn electron:build 編譯發布:

# 淘寶鏡像,國內下載 Electron 更快
export ELECTRON_MIRROR="https://cdn.npm.taobao.org/dist/electron/"

# macOS 下禁用簽名。若要簽名,見最後參考
export CSC_IDENTITY_AUTO_DISCOVERY=false

cd my-app
yarn electron:build

dist_electron/ 下即是發布內容。

例如 macOS 可見打包好的 dmg

雙擊 dmg 試用或安裝:

若要修改發布格式或內容,見 Electron Builder 文檔: https://www.electron.build/ 。

export CSC_IDENTITY_AUTO_DISCOVERY=false 是為了避免如下錯誤

...
  • signing         file=dist_electron/mac/my-app.app identityName=gdb_codesign identityHash=BC899AF362F80B3FDB39F966A1601E2AFAFA100B provisioningProfile=none
(node:10223) UnhandledPromiseRejectionWarning: Error: Command failed: codesign --sign BC899AF362F80B3FDB39F966A1601E2AFAFA100B --force --timestamp --options runtime --entitlements /Users/John/Workspace/Codes/start-electron/my-app/node_modules/app-builder-lib/templates/entitlements.mac.plist /Users/John/Workspace/Codes/start-electron/my-app/dist_electron/mac/my-app.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Helpers/chrome_crashpad_handler
error: The specified item could not be found in the keychain.
...
(node:10223) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:10223) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

參考

  • electron-app
  • start-electron
  • Electron
    • Application Distribution
  • Electron Builder
    • Code Signing
    • Notarize app for macOS

結語

Go coding!

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

新北清潔公司,居家、辦公、裝潢細清專業服務

GraphicsLab Project 之 Screen Space Planar Reflection

作者:i_dovelemon

日期:2020-06-23

主題:Screen Space Planar Reflection, Compute Shader

引言

        前段時間,同事發來一篇講述特化版本的 Screen Space Reflection 實現 Planar Reflection 的文章。出於好奇,實驗了下,看看效果如何。如下是目前實現出來的基礎版本的效果:

 原理

        對於上圖來說, Water Plane 表示水面,上半部分為實際場景的山體,下半部分為以水面為鏡像進行反射之後的山體效果。

        對於山體上某一個點(圖中白色點)來說,它對應的鏡像點為黃色點。

        我們可以從 Screen Position 以及 Depth Texture 信息,計算出來白點的世界坐標位置 WorldPosition

        然後可以以 Water Plane 所在的平面對該 WorldPosition 作鏡像操作,得到 ReflectionPosition

        得到 ReflectionPosition 之後,我們就能夠計算出來 ReflectionPostion 所對應的屏幕坐標 Reflection Screen Position

        根據前面的操作,我們就可以知道,此時 Reflection Screen Position 所反射的顏色即為 Screen Positon 所表示的顏色。

        基礎原理十分簡單,但是實際實現的時候,會發現有很多問題。接下里一一講述。

問題

閃爍

        根據上面的原理,可以想到,有多個像素可能會被反射到相同的位置,如下圖所示:

         這樣由於 GPU 執行順序的不確定性,就會導致畫面出現閃爍,如下所示:

        針對這樣的問題,我們實際需要的反射點是最近的反射點。可以考慮使用 HLSL 中提供的 InterlockedMin/InterlockedMax (參考[1],[2]) 之類的指令,在寫入數據時進行大小比較,從而實現保存最近反射點的功能。

        前面的指令雖然能夠實現大小比較,以此進行排序。但是根據前面的描述,我們實際保存的是反射點的顏色。沒有辦法只根據顏色進行排序,所以我們需要保存其他便於排序的信息,這裏選擇使用反射點的 Screen Position。並且按照如下方式進行編碼,從而實現獲取最近反射點的效果:

                        uint2 SrcPosPixel = uint2(DepthPos.x, DepthPos.y);
                        uint2 ReflPosPixel = ReflPosUV * uint2(ReflectWidth, ReflectHeight);

                        int Hash = SrcPosPixel.y << 16 | SrcPosPixel.x;
                        int dotCare = 0;
                        InterlockedMin(HashResult[ReflPosPixel], Hash, dotCare);

Encode and Sort

孔洞

        根據先前算法的描述,我們知道,我們先要根據 Depth 信息和 Screen Position 信息計算出 World Positon,然後鏡像之後,在轉化為新的屏幕坐標。在這一系列操作中,由於數值計算的不精確性,導致有些地方沒有存儲到有效的反射點位置信息,從而導致最終显示時畫面上有孔洞的情況,如下圖所示:

        幸運的是,從結果看這些孔洞並不會聚集在一起,形成大塊的黑塊。對於這種情況,我們只要在生成反射貼圖的時候,檢測到沒有保存有效位置信息時,遍歷下周圍的像素,尋找到一個擁有有效像素的值即可解決這個問題,如下代碼所示:

        uint Hash = HashTexture[id.xy].x;
        if (Hash == 0x0FFFFFFF)
            Hash = HashTexture[uint2(id.x, id.y + 1)].x;
        if (Hash == 0x0FFFFFFF)
            Hash = HashTexture[uint2(id.x, id.y - 1)].x;
        if (Hash == 0x0FFFFFFF)
            Hash = HashTexture[uint2(id.x + 1, id.y)].x;
        if (Hash == 0x0FFFFFFF)
            Hash = HashTexture[uint2(id.x - 1, id.y)].x;

        if (Hash != 0x0FFFFFFF)
        {
            uint x = Hash & 0xFFFF;
            uint y = Hash >> 16;
            ReflectionTexture[id.xy] = ColorTexture[uint2(x, y)];
        }
        else
        {
            ReflectionTexture[id.xy] = float4(0.0f, 0.0f, 0.0f, 0.0f);
        }

Hole

        如下是修正孔洞之後的效果:

實現

        本文的代碼是使用 Unity 實現的,實現起來比較簡單。比較坑的地方在於 Unity 裏面獲取 Projection Matrix 要通過 GL.GetGPUProjectionMatrix (文獻[3]) 轉化一下才能變成傳遞到 GPU 上用於渲染的投影矩陣。如下是功能核心的 Compute Shader 代碼:

// Each #kernel tells which function to compile; you can have many kernels
#pragma enable_d3d11_debug_symbols
#pragma kernel SSPRClear_Main
#pragma kernel SSPRHash_Main
#pragma kernel SSPRResolve_Main

//-----------------------------------------------------------------
float4x4 VPMatrix;
float4x4 InvVPMatrix;
uint Width;
uint Height;
uint ReflectWidth;
uint ReflectHeight;

//--------------------------------------------------------------------
RWTexture2D<int> ClearHashTexture;

[numthreads(8, 8, 1)]
void SSPRClear_Main(uint3 id : SV_DispatchThreadID)
{
    if (id.x < ReflectWidth && id.y < ReflectHeight)
    {
        ClearHashTexture[id.xy] = 0x0FFFFFFF;
    }
}

//---------------------------------------------------------------
Texture2D<float> DepthTex;
RWTexture2D<int> HashResult;

#define DownSampleFactor (1)

float3 Unproject(float3 clip)
{
    float4 clipW = float4(clip, 1.0f);
    clipW = mul(InvVPMatrix, clipW);
    clipW.xyz = clipW.xyz / clipW.w;
    return clipW.xyz;
}

float2 Project(float3 world)
{
    float4 worldW = float4(world, 1.0f);
    worldW = mul(VPMatrix, worldW);
    worldW.xy = worldW.xy / worldW.w;
    worldW.xy = (worldW.xy + float2(1.0f, 1.0f)) / 2.0f;
    return worldW.xy;
}

[numthreads(8, 8, 1)]
void SSPRHash_Main(uint3 id : SV_DispatchThreadID)
{
    for (uint i = 0; i < DownSampleFactor; i++)
    {
        for (uint j = 0; j < DownSampleFactor; j++)
        {
            uint2 DepthPos = uint2(id.x * DownSampleFactor + i, id.y * DownSampleFactor + j);
            if (DepthPos.x < Width && DepthPos.y < Height)
            {
                float depth = DepthTex.Load(int3(DepthPos.x, DepthPos.y, 0)).x;

                if (depth > 0.0f)
                {
                    float2 uv = (DepthPos.xy * 1.0f) / float2(Width, Height);
                    uv = uv * 2.0f - float2(1.0f, 1.0f);
                    uv.y = -uv.y;

                    float3 PosWS = Unproject(float3(uv, depth));

                    if (PosWS.y > 0.0f)
                    {
                        float3 ReflPosWS = float3(PosWS.x, -PosWS.y, PosWS.z);
                        float2 ReflPosUV = Project(ReflPosWS);

                        uint2 SrcPosPixel = uint2(DepthPos.x, DepthPos.y);
                        uint2 ReflPosPixel = ReflPosUV * uint2(ReflectWidth, ReflectHeight);

                        int Hash = SrcPosPixel.y << 16 | SrcPosPixel.x;
                        int dotCare = 0;
                        InterlockedMin(HashResult[ReflPosPixel], Hash, dotCare);
                    }
                }
            }
        }
    }
}

//------------------------------------------------------------------------------
Texture2D<int> HashTexture;
Texture2D<float4> ColorTexture;
RWTexture2D<float4> ReflectionTexture;

[numthreads(8, 8, 1)]
void SSPRResolve_Main(uint3 id : SV_DispatchThreadID)
{
    if (id.x < ReflectWidth && id.y < ReflectHeight)
    {
        uint Hash = HashTexture[id.xy].x;
        if (Hash == 0x0FFFFFFF)
            Hash = HashTexture[uint2(id.x, id.y + 1)].x;
        if (Hash == 0x0FFFFFFF)
            Hash = HashTexture[uint2(id.x, id.y - 1)].x;
        if (Hash == 0x0FFFFFFF)
            Hash = HashTexture[uint2(id.x + 1, id.y)].x;
        if (Hash == 0x0FFFFFFF)
            Hash = HashTexture[uint2(id.x - 1, id.y)].x;

        if (Hash != 0x0FFFFFFF)
        {
            uint x = Hash & 0xFFFF;
            uint y = Hash >> 16;
            ReflectionTexture[id.xy] = ColorTexture[uint2(x, y)];
        }
        else
        {
            ReflectionTexture[id.xy] = float4(0.0f, 0.0f, 0.0f, 0.0f);
        }
    }
}

ScreenSpacePlanarReflection

結論

        本文只是探索這個方法的可能性,更加複雜的實現,更加高效的優化可以參考文獻[4][5],這也是本文主要參考的對象。

        相比於傳統的繪製場景兩邊的方法來說,這個方案的性能更加高效,同時也沒有 SSR 那樣的高需求。在條件滿足的情況下,使用該方案能夠帶來顯著的效果提升,推薦可以嘗試。

        完整代碼在這裏:https://github.com/idovelemon/UnityProj/tree/master/ScreenSpacePlanarReflection

參考文獻

[1] HLSL-InterlockedMax

[2] HLSL-InterlockedMin

[3] GL.GetGPUProjectionMatrix

[4] Screen Space Planar Reflection

[5] Optimized Pixel Projected Reflections for Planar Reflectors

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

※幫你省時又省力,新北清潔一流服務好口碑

※別再煩惱如何寫文案,掌握八大原則!