標籤: 網站設計

  • NVIDIA 終於出招,RTX 3060 限制挖礦算力減半,並推出挖礦專用 GPU 系列

    NVIDIA 終於出招,RTX 3060 限制挖礦算力減半,並推出挖礦專用 GPU 系列

    從去年到現在,雖然 NVIDIA 有不斷釋出會想辦法提升顯示卡產量的消息,但加密貨幣價格持續上漲,即便產能真的有增加,依舊滿足不了挖礦市場,進而影響真正想買的遊戲玩家。為此,隨著 RTX 3060 確定會在 2 月 25 日上市,NVIDIA 也終於正式出招,將透過驅動程式來限制 RTX 3060 的以太幣挖礦算力,並宣佈推出專為挖礦打造的 NVIDIA CMP HX GPU 系列,沒意外 RTX 3060 應該會好買很多。

    RTX 3060 將限制挖礦算力減半,並推出挖礦專用 GPU 系列

    稍早 NVIDIA 宣布,RTX 3060 的驅動程式如果檢測到使用者正在進行 ETH 以太幣挖礦行為的特定屬性時,就會把挖礦算力限制在 50% 左右,也就是直接減半。

    至於減半之後會剩下多少算力,NVIDIA 就沒有特別提到,不過既然少這麼多,礦主當然就不會想買這張顯示卡,也因此可大幅提升遊戲玩家買到的可能性。

    根據 tom’s Hardware 實測數據,RTX 3060 Ti 的以太幣挖礦算力大約在 60.7MH/s,換算挖礦效率後,是目前最好的一張顯卡,達到 0.524 MHps/w(點我閱讀以太幣各顯卡挖礦算力的詳細介紹文章):

    有些人可能會問,那已經開賣的 RTX 30 系列顯卡會不會採取同樣作法?基本上應該不會,因為就算推出也沒用,礦工不要更新驅動程式就好,也可能會有法律上的問題。

    當然,NVIDIA 不會就這麼放棄龐大的挖礦市場,他們也同步推出專為挖礦打造的 CMP HX GPU 系列,共有四款:「30HX、40HX、50HX 與 90HX」,跟一般顯卡不同在,這系列取消了影像輸出介面,並優化採礦算力與效率。

    下圖是官方提供的以太幣挖礦算力數據,最好的 90HX 可達到 86 MH/s、50HX 為 65MH/s、40HX 為 36MH/s、30HX 則是 26MH/s:

    30HX 與 40HX 預計 Q1 就會推出,50HX、90HX 則要等到 Q2,皆時也會交由合作夥伴進行生產,如:華碩、憾訊等等,價格部分就還不知道,但應該會比現行的顯示卡還要便宜。

    資料來源:NVIDIA

    國外網咖受疫情影響生意慘淡,開始轉型成加密貨幣挖礦中心

    您也許會喜歡:

    【推爆】終身$0月租 打電話只要1元/分

    立達合法徵信社-讓您安心的選擇

    【其他文章推薦】

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

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

    ※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

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

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

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

  • Apple TV 正式登上 Chromecast with Google TV 電視棒

    Apple TV 正式登上 Chromecast with Google TV 電視棒

    眼看這宣佈已經是去年的事了,但 Chromecast with Google TV 加入 Apple TV app 總算也在今天成為現實 — 其實原本預計也是說年初,所以也不算是遲來,但相信大家真的期待了相當久,小編也因為這點在考慮是否要入手新世代帶有遙控器的 Google TV 電視棒。繼續閱讀 Apple TV 正式登上 Chromecast with Google TV 電視棒報導內文。

    ▲圖片來源:Google

    Apple TV 正式登上 Chromecast with Google TV 電視棒

    如果沒打算購入要價至少近 5 千起跳的 Apple TV 電視盒(還是 HD 版本的),卻又想要享受慵懶在客廳隨手一開遙控器,就能欣賞 Apple TV+ 各式影集的體驗的話。先前可能就只有花更多錢更換其他搭載 Apple TV app 的智慧電視才能實現。

    不過去年底當 Google 正式宣佈 Apple TV app 將會登上 Chromecast with Google TV 的消息後,就瞬間將在電視上看蘋果原創串流影視服務的門檻再度降低。而在預告之後,這樣的功能更新也正式到來 — 說真的,即便是用 iPad 或 iPhone 連線投放到電視上的 Lightning 數位 AV 轉接器,也要 NT$1,490 啊… 唯一的問題大概就剩下台灣 Google 官方還沒正式引進,還得要靠代購才能入手的這點了。

    根據 Google 官方部落格的資訊,可支援觀看 Apple TV+ 的 Apple TV app,現在已經可以在新款 Chromecast with Google TV 內的 For you 標籤頁找到,還能支援將影集存入 Google TV 觀看列表的功能;其他支援 Google TV 的智慧電視,也確認將會在未來數個月內提供。

    最新一代的 Chromecast 產品,除了外型改為橢圓外,還新增了可一鍵執行 Google Assistant 語音命令的便利遙控器。能播放最高 4K HDR 60fps 的影片,也可以執行 Android TV 應用商店支援的應用乃至於遊戲。以其 US$50 的定價(約新台幣 1,400),卻可以支援包括 Netflix、YouTube、HBO Max 以及這次新增的 Apple TV+,的確使其成為相當高 CP 值的電視棒選擇。

    首個支援的產品則是最新直接提供遙控器的 Chromecast with Google TV — 想知道它好不好用的,可以參考我們的 Chromecast with Google TV 開箱體驗(傳送門)。

    本篇圖片 / 引用來源

    延伸閱讀:

    歷久彌新的慢時尚「萬秀的洗衣店」在 Today at Apple 分享穿搭美照創作心得

    效率至上輕薄有型!NIID FINO IV 隨身型動包開箱體驗

    您也許會喜歡:

    【推爆】終身$0月租 打電話只要1元/分

    立達合法徵信社-讓您安心的選擇

    【其他文章推薦】

    台北網頁設計公司這麼多該如何選擇?

    ※智慧手機時代的來臨,RWD網頁設計為架站首選

    ※評比南投搬家公司費用收費行情懶人包大公開

    ※回頭車貨運收費標準

    網頁設計最專業,超強功能平台可客製化

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

  • 防熊出沒 日本神奈川縣抓到熊先教怕人再野放

    摘錄自2020年11月10日中央社報導

    日本今年(2020年)熊出沒事件頻傳,半年來上萬件,不過神奈川縣的熊出沒卻逆勢大減,原因之一是實施「學習野放」策略,讓熊學會「怕人」再放歸山林。

    讀賣新聞報導,與日本全國熊出沒大增的情況相反,神奈川縣內的熊出沒件數今年大減,原因之一是日本多處橡實歉收,熊因為缺乏食物而往人居處覓食,但神奈川縣內主要的熊棲息地,今年橡實豐收。另一個理由就是神奈川縣推動的「學習野放」策略奏效。

    從2006年起,神奈川縣內若是抓到熊,會讓熊聞辣椒味、聽鞭炮聲等,讓熊接觸討厭的氣味與聲音、懂得害怕人後進行野放,到去年為止,共野放了28頭熊。

    生物多樣性
    國際新聞
    日本
    神奈川縣
    人熊衝突
    野放
    人與動物衝突事件簿

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

    【其他文章推薦】

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

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

    ※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

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

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

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

  • 緬甸發現新物種「波巴葉猴」 僅剩250隻瀕臨絕種

    摘錄自2020年11月11日自由時報報導

    科學家發現一種生活在緬甸中部森林的靈長類新物種「波巴葉猴」(Popa langur,暫譯),但這種體型輕巧的樹棲動物目前數量極少,已瀕臨滅絕。

    《法新社》報導,週三發表於《Zoologic Research》期刊的一份詳細研究報告指出,研究員透過森林中採集的糞便和倫敦自然歷史博物館收藏的標本,發現波巴葉猴是一個新物種,已存在至少100萬年。其腹部呈灰棕色和白色,手和腕毛髮為黑色,尾巴將近1公尺比身體還長,重約8公斤。但是,波巴葉猴目前野外只剩下200至250隻,大約100隻生活在波巴山,因此專家建議,將這種食葉動物列為極危物種(Critically Endangered)。

    研究發現,由於農地擴張、非法和不可持續性的林業開採,導致這種帶有「白眼圈」的猴子受到狩獵、棲息地喪失、退化等各方面的威脅。FFI緬甸計畫的靈長類動物學家Ngwe Lwin說,迫切需要進行其他野外調查和保護措施。

    生物多樣性
    國際新聞
    緬甸
    瀕危物種
    猴子

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

    【其他文章推薦】

    台北網頁設計公司這麼多該如何選擇?

    ※智慧手機時代的來臨,RWD網頁設計為架站首選

    ※評比南投搬家公司費用收費行情懶人包大公開

    ※回頭車貨運收費標準

    網頁設計最專業,超強功能平台可客製化

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

  • DirectX11 With Windows SDK–31 陰影映射

    DirectX11 With Windows SDK–31 陰影映射

    前言

    陰影既暗示着光源相對於觀察者的位置關係,也從側面傳達了場景中各物體之間的相對位置。本章將起底最基礎的陰影映射算法,而像複雜如級聯陰影映射這樣的技術,也是在陰影映射的基礎上發展而來的。

    學習目標:

    1. 掌握基本的陰影映射算法
    2. 熟悉投影紋理貼圖的工作原理
    3. 了解陰影圖走樣的問題並學習修正該問題的常用策略

    DirectX11 With Windows SDK完整目錄

    Github項目源碼

    歡迎加入QQ群: 727623616 可以一起探討DX11,以及有什麼問題也可以在這裏彙報。

    核心思想

    陰影映射技術的核心思想其實不複雜。對於場景中的一點,如果該點能夠被攝像機觀察到,卻不能被光源定義的虛擬攝像機所觀察到,那麼場景中的這一點則可以被判定為光源所照射不到的陰影區域。

    以下圖為例,眼睛觀察到地面上最左邊的一點,並且從光源處觀察也能看到該點。因此該點不會產生陰影。

    再看下面的圖,眼睛可以觀察到地面上中間那一點,但是從光源處觀察不能看到該點。因此該點會產生陰影。

    具體落實下來應該怎麼做呢?對於點光源來說,由於它的光是朝所有方向四射散開的,但為了方便,我們可以像攝像機那樣選取視錐體區域(使用一個觀察矩陣 + 透視投影矩陣來定義),然後經過正常的變換后就能計算出光源到區域內物體的深度值;而對於平行光(方向光)來說,我們可以採用正交投影的方式來選取一個長方體區域(使用一個觀察矩陣 + 正交投影矩陣定義)。和一般的渲染流程不同的是,我們只需要記錄深度值到深度緩衝區,而不需要將顏色繪製到後備緩衝區。

    陰影貼圖

    陰影貼圖技術也是一種變相的“渲染到紋理”技術。它以光源的視角來渲染場景深度信息,即在光源處有一個虛擬攝像機,它將觀察到的物體的深度信息保存到深度緩衝區中。這樣我們就可以知道那些離光源最近的像素片元信息,同時這些點自然是不在陰影範圍之中。

    通常該技術需要用到一個深度/模板緩衝區、一個與之對應的視口、針對該深度/模板緩衝區的着色器資源視圖(SRV)和深度/模板視圖(DSV),而用於陰影貼圖的那個深度/模板緩衝區也被稱為陰影貼圖

    光源的投影

    在考慮點光源的投影和方向光的投影時可能會有些困難,但這兩個問題其實可以轉化成虛擬攝像機的透視投影和正交投影。

    對於透視投影來說,其實我們也已經非常熟悉了。在這種做法下我們只考慮虛擬攝像機的視錐體區域(即儘管點光源是朝任意方向照射的,但我們只看點光源往該視錐體範圍內照射的區域),然後對物體慣例進行世界變換、以光源為視角的觀察變換、光源的透視投影變換,這樣物體就被變換到了以光源為視角的NDC空間。

    而對於正交投影而言,我們也是一樣的做法。正交投影的視景體是一個軸對齊於觀察坐標系的長方體。儘管我們不好描述一個方向光的光源,但為了方便,我們把光源定義在視景體xOy切面中心所處的那條直線上。這樣我們就只需要給出視景體的寬度、高度、近平面、遠平面信息就可以構造出一個正交投影矩陣了。

    我們可以看到,正交投影的投影線均平行於觀察空間的z軸。

    正交投影矩陣在第四章變換已經講過,就不再贅述。

    投影紋理坐標

    投影紋理貼圖技術能夠將紋理投射到任意形狀的幾何體上,又因為其原理與投影機的工作方式比較相似,由此得名。例如下圖中,右邊的骷髏頭紋理被投射到左邊場景中的多個幾何體上。

    投影紋理貼圖的關鍵在於為每個像素生成對應的投影紋理坐標,從視覺上給人一種紋理被投射到幾何體上的感覺。

    下圖是光源觀察的視野,其中點p是待渲染的一點,而紋理坐標(u, v)則指定了應當被投射到3D點p上的紋素,並且坐標(u, v)與投影到屏幕上的NDC坐標有特定聯繫。我們可以將投影紋理坐標的生成過程分為如下步驟:

    1. 將3D空間中一點p投影到光源的投影窗口,並將其變換到NDC空間。
    2. 將投影坐標從NDC空間變換到紋理空間,以此將它們轉換為紋理坐標

    而步驟2中的變換過程則取決於下面的坐標變換:

    \[u=0.5x+0.5\\ v=-0.5y+0.5 \]

    即從x, y∈[-1, 1]映射到u, v∈[0, 1]。(y軸和v軸是相反的)

    這種線性變換可以用矩陣表示:

    \[\mathbf{T}=\begin{bmatrix} 0.5 & 0 & 0 & 0 \\ 0 & -0.5 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0.5 & 0.5 & 0 & 1 \\ \end{bmatrix}\\ \begin{bmatrix} x & y & 0 & 1 \end{bmatrix}\mathbf{T}=\begin{bmatrix} u & v & 0 & 1 \end{bmatrix} \]

    那麼物體上的一點p從局部坐標繫到最終的紋理坐標點t的變換過程為:

    \[\mathbf{p}\mathbf{W_{Obj}}\mathbf{V_{Light}}\mathbf{P_{Light}}\mathbf{T}=\mathbf{t} \]

    這裏補上了世界變換矩陣,是因為這一步容易在後面的代碼實踐中被漏掉。但此時的t還需要經過透視除法,才是我們最終需要的紋理坐標。

    HLSL代碼

    下面的HLSL代碼展示了頂點着色器計算投影紋理坐標的過程:

    // 頂點着色器
    VertexPosHWNormalTexShadowPosH VS(VertexPosNormalTex vIn)
    {
        VertexPosHWNormalTexShadowPosH vOut;
        
        matrix viewProj = mul(g_View, g_Proj);
        vector posW = mul(float4(vIn.PosL, 1.0f), g_World);
    
        vOut.PosW = posW.xyz;
        
        // ...
        
        // 把頂點變換到光源的投影空間
        vOut.ShadowPosH = mul(posW, g_ShadowTransform);
        return vOut;
    }
    
    // 像素着色器
    float4 PS(VertexPosHWNormalTexShadowPosH pIn) : SV_Target
    {
        // 透視除法
        pIn.ShadowPosH.xyz /= pIn.ShadowPosH.w;
        
        // NDC空間中的深度值
        float depth = pIn.ShadowPosH.z;
        
        // 通過投影紋理坐標來對紋理採樣
        // 採樣出的r分量即為光源觀察該點時的深度值
        float4 c = g_ShadowMap.Sample(g_Sam, pIn.ShadowPosH.xy);
        
        // ...
    }
    
    

    視錐體之外的點

    在渲染管線中,位於視錐體之外的幾何體是要被裁剪掉的。但是,在我們以光源設置的視角投影幾何體而為之生成投影紋理坐標時,並不需要執行裁剪操作——只需要簡單投影頂點即可。因此,位於視錐體之外的幾何體頂點會得到[0, 1]區間之外的投影紋理坐標。然後具體的採樣行為則需要依賴於我們設置的採樣器。

    一般來說,我們並不希望對位於視錐體外的幾何體頂點進行貼圖,因為這並沒有任何意義。考慮到可視深度在NDC空間的最大值為1.0f,我們可以採用邊界深度值為1.0f的邊框尋址模式

    另一種做法則是結合聚光燈的策略,使聚光燈照射範圍之外的部分不受光照,亦即不在陰影的計算範圍內。

    透視除法與投影的其他問題

    來到正交投影,因為我們依然是要計算出NDC坐標,對於NDC空間範圍外的點,我們依然可以採用上面的尋址模式策略,但聚光燈的策略就不適用了。

    此外,正交投影無需進行透視除法,因為正交投影后的坐標w值總是1.0f。但保留透視除法可以讓我們的這套着色器可以同時工作在正交投影和透視投影上。如果沒有透視除法,則只能在正交投影中工作。

    算法思路

    1. 從光源的視角將場景深度以“渲染到紋理”的形式繪製到名為陰影貼圖的深度緩衝區中
    2. 從玩家攝像機的視角渲染場景,計算出該點在光源視角下NDC坐標,其中z值為深度值,記為d(p)
    3. 上面算出的NDC坐標的xy分量變換為陰影貼圖的紋理坐標uv,然後進行深度值採樣,得到s(p)
    4. 當d(p) > s(p)時, 像素p位於陰影範圍之內;自然相反地,當d(p) <= s(p)時,像素p位於陰影範圍之外(至於為什麼還有<,後面會提到)

    改進TextureRender

    既然陰影貼圖和RTT有着許多相似的地方,那何不把它也放到TextureRender裏面共用呢?只要添加一個開關控制該RTT是否用作陰影貼圖即可。

    class TextureRender
    {
    public:
        template<class T>
        using ComPtr = Microsoft::WRL::ComPtr<T>;
    
        TextureRender() = default;
        ~TextureRender() = default;
        // 不允許拷貝,允許移動
        TextureRender(const TextureRender&) = delete;
        TextureRender& operator=(const TextureRender&) = delete;
        TextureRender(TextureRender&&) = default;
        TextureRender& operator=(TextureRender&&) = default;
    
    
        HRESULT InitResource(ID3D11Device* device,
            int texWidth,
            int texHeight,
            bool shadowMap = false,
            bool generateMips = false);
    
        // 開始對當前紋理進行渲染
        // 陰影貼圖無需提供背景色
        void Begin(ID3D11DeviceContext* deviceContext, const FLOAT backgroundColor[4]);
        // 結束對當前紋理的渲染,還原狀態
        void End(ID3D11DeviceContext * deviceContext);
        // 獲取渲染好的紋理的着色器資源視圖
        // 陰影貼圖返回的是深度緩衝區
        // 引用數不增加,僅用於傳參
        ID3D11ShaderResourceView* GetOutputTexture();
    
        // 設置調試對象名
        void SetDebugObjectName(const std::string& name);
    
    private:
        ComPtr<ID3D11ShaderResourceView>        m_pOutputTextureSRV;          // 輸出的紋理(或陰影貼圖)對應的着色器資源視圖
        ComPtr<ID3D11RenderTargetView>          m_pOutputTextureRTV;          // 輸出的紋理對應的渲染目標視圖
        ComPtr<ID3D11DepthStencilView>          m_pOutputTextureDSV;          // 輸出紋理所用的深度/模板視圖(或陰影貼圖)
        D3D11_VIEWPORT                          m_OutputViewPort = {};        // 輸出所用的視口
    
        ComPtr<ID3D11RenderTargetView>          m_pCacheRTV;                  // 臨時緩存的後備緩衝區
        ComPtr<ID3D11DepthStencilView>          m_pCacheDSV;                  // 臨時緩存的深度/模板緩衝區
        D3D11_VIEWPORT                          m_CacheViewPort = {};         // 臨時緩存的視口
    
        bool                                    m_GenerateMips = false;       // 是否生成mipmap鏈
        bool                                    m_ShadowMap = false;          // 是否為陰影貼圖
    
    };
    

    在作為RTT時,需要創建紋理與它的SRV和RTV、深度/模板緩衝區和它的DSV、視口

    而作為陰影貼圖時,需要創建深度緩衝區與它的SRV和DSV、視口

    下面的代碼只關注創建陰影貼圖的部分:

    HRESULT TextureRender::InitResource(ID3D11Device* device, int texWidth, int texHeight, bool shadowMap, bool generateMips)
    {
        // 防止重複初始化造成內存泄漏
        m_pOutputTextureSRV.Reset();
        m_pOutputTextureRTV.Reset();
        m_pOutputTextureDSV.Reset();
        m_pCacheRTV.Reset();
        m_pCacheDSV.Reset();
    
        m_ShadowMap = shadowMap;
        m_GenerateMips = false;
        HRESULT hr;
        
        // ...
        
        // ******************
        // 創建與紋理等寬高的深度/模板緩衝區或陰影貼圖,以及對應的視圖
        //
        CD3D11_TEXTURE2D_DESC texDesc((m_ShadowMap ? DXGI_FORMAT_R24G8_TYPELESS : DXGI_FORMAT_D24_UNORM_S8_UINT),
            texWidth, texHeight, 1, 1,
            D3D11_BIND_DEPTH_STENCIL | (m_ShadowMap ? D3D11_BIND_SHADER_RESOURCE : 0));
    
        ComPtr<ID3D11Texture2D> depthTex;
        hr = device->CreateTexture2D(&texDesc, nullptr, depthTex.GetAddressOf());
        if (FAILED(hr))
            return hr;
    
        CD3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc(depthTex.Get(), D3D11_DSV_DIMENSION_TEXTURE2D, DXGI_FORMAT_D24_UNORM_S8_UINT);
    
        hr = device->CreateDepthStencilView(depthTex.Get(), &dsvDesc,
            m_pOutputTextureDSV.GetAddressOf());
        if (FAILED(hr))
            return hr;
    
        if (m_ShadowMap)
        {
            // 陰影貼圖的SRV
            CD3D11_SHADER_RESOURCE_VIEW_DESC srvDesc(depthTex.Get(), D3D11_SRV_DIMENSION_TEXTURE2D, DXGI_FORMAT_R24_UNORM_X8_TYPELESS);
    
            hr = device->CreateShaderResourceView(depthTex.Get(), &srvDesc,
                m_pOutputTextureSRV.GetAddressOf());
            if (FAILED(hr))
                return hr;
        }
    
        // ******************
        // 初始化視口
        //
        m_OutputViewPort.TopLeftX = 0.0f;
        m_OutputViewPort.TopLeftY = 0.0f;
        m_OutputViewPort.Width = static_cast<float>(texWidth);
        m_OutputViewPort.Height = static_cast<float>(texHeight);
        m_OutputViewPort.MinDepth = 0.0f;
        m_OutputViewPort.MaxDepth = 1.0f;
    
        return S_OK;
    }
    
    

    需要注意的是,在創建深度緩衝區時,如果還想為他創建SRV,就不能將DXGI格式定義成DXGI_FORMAT_D24_UNORM_S8_UINT這些帶D的類型,而應該是DXGI_FORMAT_R24G8_TYPELESS

    然後在創建陰影貼圖的SRV時,則需要指定為DXGI_FORMAT_R24_UNORM_X8_TYPELESS

    開始陰影貼圖的渲染前,不需要設置RTV,只需要綁定DSV。

    void TextureRender::Begin(ID3D11DeviceContext* deviceContext, const FLOAT backgroundColor[4])
    {
        // 緩存渲染目標和深度模板視圖
        deviceContext->OMGetRenderTargets(1, m_pCacheRTV.GetAddressOf(), m_pCacheDSV.GetAddressOf());
        // 緩存視口
        UINT num_Viewports = 1;
        deviceContext->RSGetViewports(&num_Viewports, &m_CacheViewPort);
    
        // 清空緩衝區
        // ... 
        deviceContext->ClearDepthStencilView(m_pOutputTextureDSV.Get(), D3D11_CLEAR_DEPTH | (m_ShadowMap ? 0 : D3D11_CLEAR_STENCIL), 1.0f, 0);
        
        // 設置渲染目標和深度模板視圖
        deviceContext->OMSetRenderTargets((m_ShadowMap ? 0 : 1), 
            (m_ShadowMap ? nullptr : m_pOutputTextureRTV.GetAddressOf()), 
            m_pOutputTextureDSV.Get());
        // 設置視口
        deviceContext->RSSetViewports(1, &m_OutputViewPort);
    }
    

    渲染完成后,和往常一樣還原即可。

    偏移與走樣

    陰影圖存儲的是距離光源最近的可視像素深度值,但是它的分辨率有限,導致每一個陰影圖紋素都要表示場景中的一片區域。因此,陰影圖只是以光源視角針對場景深度進行的離散採樣,這將會導致所謂的陰影粉刺等圖像走樣問題。如下圖所示(注意圖中地面上光影之間輪流交替的“階梯狀”條紋):

    而下圖則簡單展示了為什麼會發生陰影粉刺這種現象。由於陰影圖的分辨率有限,所以每個陰影圖紋素要對應於長江中的一塊區域(而不是點對點的關係,一個坡面代表陰影圖中一個紋素的對應範圍)。從觀察點E查看場景中的兩個點p1與p2,它們分別對應於兩個不同的屏幕像素。但是,從光源的觀察角度來看,它們卻都有着相同的陰影圖紋素(即s(p1)=s(p2)=s,由於分辨率的原因)。當我們在執行陰影圖檢測時,會得到d(p1) > s 及 d(p2) <= s這兩個測試結果,這樣一來,p1將會被繪製為如同它在陰影中的顏色,p2將被渲染為好似它在陰影之外的顏色,從而導致陰影粉刺。

    因此,我們可以通過偏移陰影圖中的深度值來防止出現錯誤的陰影效果。此時我們就可以保證d(p1) <= s 及 d(p2) <= s。但是尋找合適的深度偏移需要反覆嘗試。

    偏移量過大會導致名為peter-panning(彼得·潘,即小飛俠,他曾在一次逃跑時弄丟了自己的影子)的失真效果,使得陰影看起來與物體相分離。

    然而,並沒有哪一種固定的偏移量可以正確地運用於所有幾何體的陰影繪製。特別是下圖那種(從光源的角度來看)有着極大斜率的三角形,這時候就需要選取更大的偏移量。但是,如果試圖通過一個過大的深度偏移量來處理所有的斜邊,則又會造成peter-panning問題。

    因此,我們繪製陰影的方式就是先以光源視角度量多邊形斜面的斜率,併為斜率較大的多邊形應用更大的偏移量。而圖形硬件內部對此有相關技術的支持,我們通過名為斜率縮放偏移的光柵化狀態屬性就能夠輕鬆實現。

    typedef struct D3D11_RASTERIZER_DESC {
        // ...
        INT             DepthBias;
        FLOAT           DepthBiasClamp;
        FLOAT           SlopeScaledDepthBias;
        BOOL            DepthClipEnable;
        // ...
    } D3D11_RASTERIZER_DESC;
    
    1. DepthBias:一個固定的應用偏移量。
    2. DepthBiasClamp:所允許的最大深度偏移量。以此來設置深度偏移量的上限。不難想象,及其陡峭的傾斜度會導致斜率縮放偏移量過大,從而造成peter-panning失真
    3. SlopeScaledDepthBias:根據多邊形的斜率來控制偏移程度的縮放因子。

    注意,在將場景渲染至陰影貼圖時,便會應用該斜率縮放偏移量。這是由於我們希望以光源的視角基於多邊形的斜率而進行偏移操作,從而避免陰影失真。因此,我們就會對陰影圖中的數值進行偏移計算(即由硬件將像素的深度值與偏移值相加)。在本Demo中採用的具體數值如下:

    // [出自MSDN]
    // 如果當前的深度緩衝區採用UNORM格式並且綁定在輸出合併階段,或深度緩衝區還沒有被綁定
    // 則偏移量的計算過程如下:
    //
    // Bias = (float)DepthBias * r + SlopeScaledDepthBias * MaxDepthSlope;
    //
    // 這裏的r是在深度緩衝區格式轉換為float32類型后,其深度值可取到大於0的最小可表示的值
    // MaxDepthSlope則是像素在水平方向和豎直方向上的深度斜率的最大值
    // [結束MSDN引用]
    //
    // 對於一個24位的深度緩衝區來說, r = 1 / 2^24
    //
    // 例如:DepthBias = 100000 ==> 實際的DepthBias = 100000/2^24 = .006
    //
    // 本Demo中的方向光始終與地面法線呈45度夾角,故取斜率為1.0f
    // 以下數據極其依賴於實際場景,因此我們需要對特定場景反覆嘗試才能找到最合適
    rsDesc.DepthBias = 100000;
    rsDesc.DepthBiasClamp = 0.0f;
    rsDesc.SlopeScaledDepthBias = 1.0f
    

    注意:深度偏移發生在光柵化期間(裁剪之後),因此不會對幾何體裁剪造成影響。

    RenderStates中我們添加了這樣一個光柵化狀態:

    // 深度偏移模式
    rasterizerDesc.FillMode = D3D11_FILL_SOLID;
    rasterizerDesc.CullMode = D3D11_CULL_BACK;
    rasterizerDesc.FrontCounterClockwise = false;
    rasterizerDesc.DepthClipEnable = true;
    rasterizerDesc.DepthBias = 100000;
    rasterizerDesc.DepthBiasClamp = 0.0f;
    rasterizerDesc.SlopeScaledDepthBias = 1.0f;
    HR(device->CreateRasterizerState(&rasterizerDesc, RSDepth.GetAddressOf()));
    

    MSDN文檔Depth Bias講述了該技術相關的全部規則,並且介紹了如何使用浮點深度緩衝區進行工作。

    百分比漸近過濾(PCF)

    在使用投影紋理坐標(u, v)對陰影圖進行採樣時,往往不會命中陰影圖中紋素的準確位置,而是通常位於陰影圖中的4個紋素之間。然而,我們不應該對深度值採用雙線性插值法,因為4個紋素之間的深度值不一定滿足線性過渡,插值出來的深度值跟實際的深度值有偏差,這樣可能會導致把像素錯誤標入陰影中這樣的錯誤結果(因此我們也不能為陰影圖生成mipmap)。

    出於這樣的原因,我們應該對採樣的結果進行插值,而不是對深度值進行插值。這種做法稱為——百分比漸近過濾。即我們以點過濾(MIN_MAG_MIP_POINT)的方式在坐標(u, v)、(u+△x, v)、(u, v+△x)、(u+△x, v+△x)處對紋理進行採樣,其中△x=1/SHADOW_MAP_SIZE(除以的是引用貼圖的寬高)。由於是點採樣,這4個採樣點分別命中的是圍繞坐標(u, v)最近的4個陰影圖紋素s0、s1、s2、s3,如下圖所示。

    接下來,我們會對這些採集的深度值進行陰影圖檢測,並對測試的結果展開雙線性插值。

    static const float SMAP_SIZE = 2048.0f;
    static const float SMAP_DX = 1.0f / SMAP_SIZE;
    
    // ...
    
    //
    // 採樣操作
    //
    
    // 對陰影圖進行採樣以獲取離光源最近的深度值
    float s0 = g_ShadowMap.Sample(g_SamShadow, tex.xy).r;
    float s1 = g_ShadowMap.Sample(g_SamShadow, tex.xy + float2(SMAP_DX, 0)).r;
    float s2 = g_ShadowMap.Sample(g_SamShadow, tex.xy + float2(0, SMAP_DX)).r;
    float s3 = g_ShadowMap.Sample(g_SamShadow, tex.xy + float2(SMAP_DX, SMAP_DX)).r;
    
    // 該像素的深度值是否小於等於陰影圖中的深度值
    float r0 = (depth <= s0);
    float r1 = (depth <= s1);
    float r2 = (depth <= s2);
    float r3 = (depth <= s3);
    
    //
    // 雙線性插值操作
    //
    
    // 變換到紋素空間
    float2 texelPos = SMAP_SIZE * tex.xy;
    
    // 確定插值係數(frac()返回浮點數的小數部分)
    float2 t = frac(texelPos);
    
    // 對比較結果進行雙線性插值
    return lerp(lerp(r0, r1, t.x), lerp(r2, r3, t.x), t.y);
    
    

    若採用這種計算方法,則一個像素就可能局部處於陰影之中,而不是非0即1.例如,若有4個樣本,三個在陰影中,一個在陰影外,那麼該像素有75%處於陰影之中。這就讓陰影內外的像素之間有了更加平滑的過渡,而不是稜角分明。

    但這種過濾方法產生的陰影看起來仍然非常生硬,且鋸齒失真問題的最終處理效果還是不能令人十分滿意。PCF的主要缺點是需要4個紋理樣本,而紋理採樣本身就是現代GPU代價較高的操作之一,因為存儲器的帶寬與延遲並沒有隨着GPU計算能力的劇增而得到相近程度的巨大改良。幸運的是,Direct3D 11+版本的圖形硬件對PCF技術已經有了內部支持,上面的一大堆代碼可以用SampleCmpLevelZero函數來替代。

    float percentage = g_ShadowMap.SampleCmpLevelZero(g_SamShadow, shadowPosH.xy, depth).r;
    

    方法中的LevelZero部分意味着它只能在最高的mipmap層級中進行採樣。另外,該方法使用的並非一般的採樣器對象,而是比較採樣器。這使得硬件能夠執行陰影圖的比較測試,並且需要在過濾採樣結果之前完成。對於PCF技術來說,我們需要使用的是D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT過濾器,並將比較函數設置為LESS_EQUAL(由於對深度值進行了偏移,所以也要用到LESS比較函數)。

    函數中傳入的depth將會出現在比較運算符的左邊,即:

    depth <= sampleDepth
    

    RenderStates中我們添加了這樣一個採樣器:

    ComPtr<ID3D11SamplerState> RenderStates::SSShadow = nullptr;
    
    // 採樣器狀態:深度比較與Border模式
    ZeroMemory(&sampDesc, sizeof(sampDesc));
    sampDesc.Filter = D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT;
    sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_BORDER;
    sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_BORDER;
    sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_BORDER;
    sampDesc.ComparisonFunc = D3D11_COMPARISON_LESS_EQUAL;
    sampDesc.BorderColor[0] = { 1.0f };
    sampDesc.MinLOD = 0;
    sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
    HR(device->CreateSamplerState(&sampDesc, SSShadow.GetAddressOf()));
    

    注意:根據SDK文檔所述,只有R32_FLOAT_X8X24_TYPELESSR32_FLOATR24_UNORM_X8_TYPELESSR16_UNORM格式才能用於比較過濾器。

    在PCF的基礎上進行均值濾波

    到目前為止,我們在本節中一直使用的是4-tap PCF核(輸入4個樣本來執行的PCF)。PCF核越大,陰影的邊緣輪廓也就越豐滿、越平滑,當然,花費在SampleCmpLevelZero函數上的開銷也就越大。在本Demo中,我們是按3×3正方形的均值濾波方式來執行PCF。由於每次調用SampleCmpLevelZero函數實際所執行的都是4-tap PCF,所以一共採樣了36次,其中有4×4個獨立採樣點。此外,採用過大的濾波核還會導致之前所述的陰影粉刺問題,但本章不打算講述,有興趣可以回到龍書閱讀(過大的PCF核)。

    顯然,PCF技術一般來說只需在陰影的邊緣進行,因為陰影內外兩部分並不涉及混合操作(只有陰影邊緣才是漸變的)。基於此,只要能對陰影邊緣的PCF設計相應的處理方案就好了。但這種做法一般要求我們所用的PCF核足夠大(5×5及更大)時才划算(因為動態分支也有開銷)。不過最終是要效率還是要畫質還是取決於你自己。

    注意:實際工程中所用的PCF核不一定是方形的過濾柵格。不少文獻也指出,隨機的拾取點也可以作為PCF核。

    考慮到在做比較時,如果處於陰影外的值為1,在陰影內的值為0,在採用SampleCmpLevelZero和均值濾波后,我們用範圍值0~1來表示處於陰影外的程度。隨着值的增加,該點也變得越亮。我們可以使用下面的函數來計算3×3正方形的均值濾波下的陰影因子:

    float CalcShadowFactor(SamplerComparisonState samShadow, Texture2D shadowMap, float4 shadowPosH)
    {
    	// 透視除法
        shadowPosH.xyz /= shadowPosH.w;
    	
    	// NDC空間的深度值
        float depth = shadowPosH.z;
    
    	// 紋素在紋理坐標下的寬高
        const float dx = SMAP_DX;
    
        float percentLit = 0.0f;
        const float2 offsets[9] =
        {
            float2(-dx, -dx), float2(0.0f, -dx), float2(dx, -dx),
    		float2(-dx, 0.0f), float2(0.0f, 0.0f), float2(dx, 0.0f),
    		float2(-dx, +dx), float2(0.0f, +dx), float2(dx, +dx)
        };
                          
    	[unroll]
        for (int i = 0; i < 9; ++i)
        {
            percentLit += shadowMap.SampleCmpLevelZero(samShadow,
    			shadowPosH.xy + offsets[i], depth).r;
        }
        
        return percentLit /= 9.0f;
    }
    

    然後在我們的光照模型中,只有第一個方向光才參与到陰影的計算,並且陰影因子將與直接光照(漫反射和鏡面反射光)項相乘。

    // ...
    float shadow[5] = { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f };
     
    // 僅第一個方向光用於計算陰影
    shadow[0] = CalcShadowFactor(g_SamShadow, g_ShadowMap, pIn.ShadowPosH);
        
    [unroll]
    for (i = 0; i < 5; ++i)
    {
        ComputeDirectionalLight(g_Material, g_DirLight[i], pIn.NormalW, toEyeW, A, D, S);
        ambient += A;
        diffuse += shadow[i] * D;
        spec += shadow[i] * S;
    }
    
    // ...
    

    由於環境光是間接光,所以陰影因子不受影響。並且,陰影因子也不會對來自環境映射的反射光構成影響。

    C++端代碼實現

    EffectHelper的引入

    本章開始的代碼引入了EffectHelper來管理着色器所需的資源(我們可以無需手動創建並交給它來託管),並應用在了所有的Effect類當中。除了IEffect接口類,目前還引入了IEffectTransform接口類來統一變換的設置。隨着抽象類的增加,像GameObject這樣的類就可以對IEffect接口類對象查詢是否有某一特定接口類或具體類來執行額外的複雜操作。

    此外,SkyRender類也因此有了輕微的變動。具體想了解還是去源碼翻閱,這裏不展開。

    構建陰影貼圖與更新

    首先我們要在GameApp::InitResource中創建一副2048×2048的陰影貼圖:

    m_pShadowMap = std::make_unique<TextureRender>();
    HR(m_pShadowMap->InitResource(m_pd3dDevice.Get(), 2048, 2048, true));
    

    在本Demo中,光照方向每幀都在變動,我們希望讓投影立方體與光照所屬的變換軸對齊,並且中心能夠坐落在原點。因此在GameApp::UpdateScene可以這麼做:

    //
    // 投影區域為正方體,以原點為中心,以方向光為+Z朝向
    //
    XMMATRIX LightView = XMMatrixLookAtLH(dirVec * 20.0f * (-2.0f), g_XMZero, g_XMIdentityR1);
    m_pShadowEffect->SetViewMatrix(LightView);
    
    // 將NDC空間 [-1, +1]^2 變換到紋理坐標空間 [0, 1]^2
    static XMMATRIX T(
        0.5f, 0.0f, 0.0f, 0.0f,
        0.0f, -0.5f, 0.0f, 0.0f,
        0.0f, 0.0f, 1.0f, 0.0f,
        0.5f, 0.5f, 0.0f, 1.0f);
    // S = V * P * T
    m_pBasicEffect->SetShadowTransformMatrix(LightView * XMMatrixOrthographicLH(40.0f, 40.0f, 20.0f, 60.0f) * T);
    

    至於繪製部分,本Demo將和陰影有聯繫的場景對象放入了另一個重載函數DrawScene中(具體實現不在這給出),總體情況如下:

    void GameApp::DrawScene()
    {
        // ...
    
        // ******************
        // 繪製到陰影貼圖
    
        m_pShadowMap->Begin(m_pd3dImmediateContext.Get(), nullptr);
        {
            DrawScene(true);
        }
        m_pShadowMap->End(m_pd3dImmediateContext.Get());
    
        // ******************
        // 正常繪製場景
        m_pBasicEffect->SetTextureShadowMap(m_pShadowMap->GetOutputTexture());
        DrawScene(false, m_EnableNormalMap);
    
        // 繪製天空盒
        m_pDesert->Draw(m_pd3dImmediateContext.Get(), *m_pSkyEffect, *m_pCamera);
    
        // 解除深度緩衝區綁定
        m_pBasicEffect->SetTextureShadowMap(nullptr);
        m_pBasicEffect->Apply(m_pd3dImmediateContext.Get());
    
        // ...
    
    }
    

    演示

    本Demo提供了5種斜率下的方向光,對應主鍵盤数字鍵1-5,Q鍵開關法線貼圖,E鍵開關陰影貼圖的显示,G鍵切換陰影貼圖的显示模式。

    透明物體的陰影繪製

    但我們的例程還沒有處理透明物體的陰影繪製。如果我們直接在場景中繪製一顆樹(貼圖存在Alpha值為0的部分),可以看到下圖的陰影並不正確:

    因此,我們需要在繪製陰影貼圖的時候增加一個像素着色器用以進行Alpha裁剪,把Alpha值低於0.1的紋素給剔除掉,不要讓其寫入到陰影貼圖:

    Texture2D g_DiffuseMap : register(t0);
    SamplerState g_Sam : register(s0);
    
    struct VertexPosHTex
    {
        float4 PosH : SV_POSITION;
        float2 Tex : TEXCOORD;
    };
    
    // 這僅僅用於Alpha幾何裁剪,以保證陰影的显示正確。
    // 對於不需要進行紋理採樣操作的幾何體可以直接將像素
    // 着色器設為nullptr
    void PS(VertexPosHTex pIn)
    {
        float4 diffuse = g_DiffuseMap.Sample(g_Sam, pIn.Tex);
        
        // 不要將透明像素寫入深度貼圖
        clip(diffuse.a - 0.1f);
    }
    
    

    我們只在繪製樹的時候使用帶有像素着色器的版本,其餘物體照常繪製。並且因為我們的BasicEffect默認繪製就帶有Alpha裁剪,無需做這部分改動。最終效果如下:

    練習題

    1. 嘗試4096×4096、1024×1024、512×512、256×256這幾種不同分辨率的陰影貼圖
    2. 嘗試以單次點採樣陰影檢測來修改本演示程序(即不採用PCF)。我們將欣賞到硬陰影與鋸齒狀的陰影邊緣
    3. 關閉斜率縮放偏移來觀察陰影粉刺
    4. 將斜率縮放偏移值放大10倍,觀察peter panning失真的效果
    5. 實現單點光源下的陰影(必要時可以考慮像CubeMap那樣使用6個正方形貼圖)
    6. 修改項目代碼,把繪製房屋改成繪製上圖中的樹(模型已給出),要求陰影显示正確

    DirectX11 With Windows SDK完整目錄

    Github項目源碼

    歡迎加入QQ群: 727623616 可以一起探討DX11,以及有什麼問題也可以在這裏彙報。

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

    【其他文章推薦】

    台北網頁設計公司這麼多該如何選擇?

    ※智慧手機時代的來臨,RWD網頁設計為架站首選

    ※評比南投搬家公司費用收費行情懶人包大公開

    ※回頭車貨運收費標準

    網頁設計最專業,超強功能平台可客製化

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

  • (數據科學學習手札86)全平台支持的pandas運算加速神器

    (數據科學學習手札86)全平台支持的pandas運算加速神器

    本文示例代碼已上傳至我的Github倉庫https://github.com/CNFeffery/DataScienceStudyNotes

    1 簡介

      隨着其功能的不斷優化與擴充,pandas已然成為數據分析領域最受歡迎的工具之一,但其仍然有着一個不容忽視的短板——難以快速處理大型數據集,這是由於pandas中的工作流往往是建立在單進程的基礎上,使得其只能利用單個處理器核心來實現各種計算操作,這就使得pandas在處理百萬級、千萬級甚至更大數據量時,出現了明顯的性能瓶頸。

      本文要介紹的工具modin就是一個致力於在改變代碼量最少的前提下,調用起多核計算資源,對pandas的計算過程進行并行化改造的Python庫,並且隨着其近期的一系列內容更新,modin基於Dask開始對Windows系統同樣進行了支持,使得我們只需要改變一行代碼,就可以在所有平台上獲得部分pandas功能可觀的計算效率提升。

    圖1

    2 基於modin的pandas運算加速

      modin支持WindowsLinux以及Mac系統,其中LinuxMac平台版本的modin工作時可基於并行運算框架RayDask,而Windows平台版本目前只支持Dask作為計算後端(因為Ray沒有Win版本),安裝起來十分方便,可以用如下3種命令來安裝具有不同後端的modin

    pip install modin[dask] # 安裝dask後端
    pip install modin[ray] # 安裝ray後端(windows不支持)
    pip install modin[all] # 推薦方式,自動安裝當前系統支持的所有後端
    

      本文在Win10系統上演示modin的功能,執行命令:

    pip install modin[all]
    

      成功安裝modin+dask之後,在使用modin時,只需要將我們習慣的import pandas as pd變更為import modin.pandas as pd即可,接下來我們來看一下在一些常見功能上,pandasVSmodin性能差異情況,首先我們分別使用pandasmodin讀入一個大小為1.1G的csv文件esea_master_dmg_demos.part1.csv,來自kaggle(https://www.kaggle.com/skihikingkevin/csgo-matchmaking-damage/data),記錄了關於熱門遊戲CS:GO的一些玩家行為數據,因為體積過大,請感興趣的讀者朋友自行去下載:

    圖2

      為了區分他們,在導入時暫時將modin.pandas命名為mpd

    圖3

      可以看到因為是Win平台,所以使用的計算後端為Dask,首先我們來分別讀入文件查看耗時:

    圖4

      藉助jupyter notebook記錄計算時間的插件,可以看到原生的pandas耗時14.8秒,而modin只用了5.32秒,接着我們再來試試concat操作:

    圖5

      可以看到在pandas花了8.78秒才完成任務的情況下,modin僅用了0.174秒,取得了驚人的效率提升。接下來我們再來執行常見的檢查每列缺失情況的任務:

    圖6

      這時耗時差距雖然不如concat操作時那麼巨大,也是比較可觀的,但是modin畢竟是一個處理快速開發迭代階段的工具,其針對pandas的并行化改造尚未覆蓋全部的功能,譬如分組聚合功能。對於這部分功能,modin會在執行代碼時檢查自己是否支持,對於尚未支持的功能modin會自動切換到pandas單核後端來執行運算,但由於modin中組織數據的形式與pandas不相同,所以中間需要經歷轉換:

    圖7

      這種時候modin的運算反而會比pandas慢很多:

    圖8

      因此我對modin持有的態度是在處理大型數據集時,部分應用場景可以用其替換pandas,即其已經完成可靠并行化改造的pandas功能,你可以在官網對應界面(https://modin.readthedocs.io/en/latest/supported_apis/index.html )查看其已經支持及尚未良好支持的功能,,因為modin還處於快速開發階段,很多目前無法支持的功能也許未來不久就會被加入modin

    圖9

      以上就是本文的全部內容,如有疑問歡迎在評論區與我討論。

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

    【其他文章推薦】

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

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

    ※Google地圖已可更新顯示潭子電動車充電站設置地點!!

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

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

    網頁設計最專業,超強功能平台可客製化

    ※回頭車貨運收費標準

  • FAO:5月全球糧食供應鏈恐中斷 A股農業族群飆

    摘錄自2020年3月31日聯合報報導

    聯合國糧農組織(FAO)日前稱,受全球疫情影響,全球糧食供應鏈將於4月至5月中斷。而俄國、越南等國家為保證糧食供給,已宣布停止出口。A股農業族群今(31)日走強,金健米業再度飆漲停,京糧控股大漲8%,傲農生物、農發種業、萬向德農紛紛拉升。

    金融網報導,其中,柬埔寨首相宣布受新冠肺炎疫情影響,將自4月5日起禁止部分大米出口。埃及自3月28日起未來3個月內停止各種豆類產品的出口;哈薩克斯坦禁止出口小麥麵粉、紅蘿蔔、糖和馬鈴薯;越南暫停簽署新的大米出口合約;俄國將每周評估情況,再決定是否實施出口禁令。

    聯合國糧農組織(FAO)日前稱,受全球疫情影響,全球糧食供應鏈將於4月至5月中斷。而俄國、越南等國家為保證糧食供給,已宣布停止出口。

    永續發展
    土地利用
    國際新聞
    糧食

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

    【其他文章推薦】

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

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

    ※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

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

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

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

  • 新冠病毒有味可尋? 英國計劃訓練狗狗嗅出感染者

    摘錄自2020年4月9日香港01 報導

    新冠病毒(COVID-19)疫情持續,英國慈善組織「醫療偵測犬」(Medical Detection Dogs)與倫敦衞生與熱帶醫學院(London School of Hygiene and Tropical Medicine)及杜倫大學(University of Durham)合作,研究能否利用狗檢測新冠病毒。

    該組織表示,狗是世上最強大的生物探測器之一,能檢測出毒品、爆炸品和食物的氣味,且早已被利用在公共衛生範疇。主席葛斯特博士(Dr. Claire Guest)稱,原則上,一定數量的病毒會改變感染者身上氣味,狗能嗅出當中分別,以識別患者甚至沒有徵狀的感染者;現在研究人員正在尋找方法,讓狗狗可以在安全情況下,嗅出病人身上病毒的氣味;如果研究成功,這種快捷準確且非入侵性的檢測方法,可以大大減輕國民保健服務(NHS)的負擔。

    研究人員表示,經訓練的狗約可於六星期內投入檢測病毒工作,預計一隻可在1小時內平均檢測約250人,長遠而言,這些狗日後更可在機場或其他出入境關口為旅客檢測,以預防新一波的疫情爆發。

    生活環境
    國際新聞
    英國
    武漢肺炎
    公共衛生
    動物福利

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

    【其他文章推薦】

    台北網頁設計公司這麼多該如何選擇?

    ※智慧手機時代的來臨,RWD網頁設計為架站首選

    ※評比南投搬家公司費用收費行情懶人包大公開

    ※回頭車貨運收費標準

    網頁設計最專業,超強功能平台可客製化

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

  • Google 密碼檢查工具將下放至舊系統,提供老手機更強化的安全性

    Google 密碼檢查工具將下放至舊系統,提供老手機更強化的安全性

    Google 在近日宣布為 Android 推出著重於安全性的新功能,其中最重要的就是把過去於電腦版 Chrome 中推出的密碼檢查工具推廣到 Android 設備上,並且擴大下放到運行舊版 Android 系統的設備上,為用戶密碼提供跨越設備的安全把關。

    Google 密碼檢查工具將下放至舊系統,提供老手機更強化的安全性

    在過去,人們為了方便、好記,於是往往用最便利的方式來設定密碼,像是 Abc123、123456 等,66% 的美國人承認在多網站上使用同樣的較弱密碼,相信台灣很多人也是如此,使用這些共用密碼的帳戶也成為更容易受到攻擊的目標,因為只需攻破一個就能於擁有多個,每天也有很多新的數據外洩新聞讓人心惶惶。

    在密碼成為過去式之前,Google 在 Google 帳戶與 Chrome 瀏覽器中推出了密碼檢查工具來幫助用戶檢查記憶於其中的密碼,而現在Google 更將這項功能推廣到 Android 上,在保護 Google 帳戶之餘進而更快速、輕鬆地使用自動填入來登入各種應用程式與服務。這項工具將會提供給搭載 Android 9 以上的設備,當你使用 Google 在手機應用中輸入密碼時,系統會根據已經洩漏的密碼清單(就是可能已經被竊取併發布在網路上的密碼)來進行檢查,告訴用戶該密碼是否在之前已經遭到外洩,並且引導用戶以正確的步驟來處理密碼問題。

    除此之外,Google 還為 Android 推出另外五種功能,包含排程發送訊息,幫助盲人與難以查看螢幕的人士所設計的新版本 Talkback,更多免持的 Google 語音助理操作以及更多 Android Auto 新功能等,大家可以密切期待這些新功能的到來。

    ◎資料來源:Google

    您也許會喜歡:

    【推爆】終身$0月租 打電話只要1元/分

    立達合法徵信社-讓您安心的選擇

    【其他文章推薦】

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

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

    ※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

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

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

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

  • 小嬰兒三更半夜找爸爸 Alexa:已經將爸爸放到購物車了

    小嬰兒三更半夜找爸爸 Alexa:已經將爸爸放到購物車了

    雖然在台灣比較少見,但是亞馬遜所推出的數位語音助理「Alexa」除了可以幫你啟動各種家電外,同時也可以幫你從亞馬遜的商場上搜尋你要的東西,並且放入購物車中。而近日就有國外的小孩,三更半夜吵著想要找爸爸,沒想到意外的將「爸爸」放到購物車中。

    根據《每日星報》報導指出,一位媽媽近日在TikTok上上傳一段影片,影片的內容是他們家的嬰兒監視器,只見影片中小寶寶從嬰兒床上爬起來,對著一旁的數位助理Alexa說「Alexa,我需要爸爸!」

    Alexa在聆聽了男童充滿童言童語的請求後,竟然是直接回應說「我應該加入什麼?」顯然的Alexa把男童的請求,聽成了某種購物的需求。而男童聽到Alexa的回應後,再一次的表示「爸爸」。沒想到Alexa竟然回應男童「好的!已經將爸爸放入購物車中,請問還需要什麼嗎?」面對Alexa的回應,男童也瞬間呆滯。

    由於男童與Alexa之間的對話實在過於暴笑,影片從18日上傳後,至今已經有370多萬次觀看,也吸引不少網友留言。小編原本還想說,如果Alexa在聽到男童的需求後,就打電話給爸爸那就真的非常厲害了。但是現在,小編更好奇的是,Alexa到底放了哪家商店提供的「爸爸」在購物車中呢?

    您也許會喜歡:

    【推爆】終身$0月租 打電話只要1元/分

    立達合法徵信社-讓您安心的選擇

    【其他文章推薦】

    台北網頁設計公司這麼多該如何選擇?

    ※智慧手機時代的來臨,RWD網頁設計為架站首選

    ※評比南投搬家公司費用收費行情懶人包大公開

    ※回頭車貨運收費標準

    網頁設計最專業,超強功能平台可客製化

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